Version 248-rc4
This commit is contained in:
parent
22e7d02418
commit
45fafe9791
@ -1,123 +0,0 @@
|
|||||||
From 3552ac862497bdb5ea73639851bbfd114b795fa2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Thu, 11 Mar 2021 20:41:36 +0100
|
|
||||||
Subject: [PATCH] Revert "sd-event: make use of epoll_pwait2() for greater time
|
|
||||||
accuracy"
|
|
||||||
|
|
||||||
This reverts commit 798445ab84cff51bde7fcf936f0fb19c37cf858c.
|
|
||||||
|
|
||||||
Unfortunately this causes test-event to hang. 32 bit architectures seem
|
|
||||||
affected: i686 and arm32 in fedora koji. 32 bit build of test-event hangs
|
|
||||||
reliably under valgrind:
|
|
||||||
|
|
||||||
$ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig meson build-32 -Dc_args=-m32 -Dc_link_args=-m32 -Dcpp_args=-m32 -Dcpp_link_args=-m32 && ninja -C build-32 test-event && valgrind build/test-event
|
|
||||||
---
|
|
||||||
src/libsystemd/sd-event/sd-event.c | 73 ++++++------------------------
|
|
||||||
1 file changed, 14 insertions(+), 59 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
|
||||||
index 8ab9d419af..69d9c5e780 100644
|
|
||||||
--- a/src/libsystemd/sd-event/sd-event.c
|
|
||||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
|
||||||
@@ -3781,59 +3781,9 @@ pending:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int epoll_wait_usec(
|
|
||||||
- int fd,
|
|
||||||
- struct epoll_event *events,
|
|
||||||
- int maxevents,
|
|
||||||
- usec_t timeout) {
|
|
||||||
-
|
|
||||||
- static bool epoll_pwait2_absent = false;
|
|
||||||
- int r, msec;
|
|
||||||
-
|
|
||||||
- /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not */
|
|
||||||
-
|
|
||||||
- if (!epoll_pwait2_absent && timeout != USEC_INFINITY) {
|
|
||||||
- struct timespec ts;
|
|
||||||
-
|
|
||||||
- r = epoll_pwait2(fd,
|
|
||||||
- events,
|
|
||||||
- maxevents,
|
|
||||||
- timespec_store(&ts, timeout),
|
|
||||||
- NULL);
|
|
||||||
- if (r >= 0)
|
|
||||||
- return r;
|
|
||||||
- if (!ERRNO_IS_NOT_SUPPORTED(r) && !ERRNO_IS_PRIVILEGE(r))
|
|
||||||
- return -errno; /* Only fallback to old epoll_wait() if the syscall is masked or not
|
|
||||||
- * supported. */
|
|
||||||
-
|
|
||||||
- epoll_pwait2_absent = true;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (timeout == USEC_INFINITY)
|
|
||||||
- msec = -1;
|
|
||||||
- else {
|
|
||||||
- usec_t k;
|
|
||||||
-
|
|
||||||
- k = DIV_ROUND_UP(timeout, USEC_PER_MSEC);
|
|
||||||
- if (k >= INT_MAX)
|
|
||||||
- msec = INT_MAX; /* Saturate */
|
|
||||||
- else
|
|
||||||
- msec = (int) k;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- r = epoll_wait(fd,
|
|
||||||
- events,
|
|
||||||
- maxevents,
|
|
||||||
- msec);
|
|
||||||
- if (r < 0)
|
|
||||||
- return -errno;
|
|
||||||
-
|
|
||||||
- return r;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
|
||||||
size_t n_event_queue, m;
|
|
||||||
- int r;
|
|
||||||
+ int r, msec;
|
|
||||||
|
|
||||||
assert_return(e, -EINVAL);
|
|
||||||
assert_return(e = event_resolve(e), -ENOPKG);
|
|
||||||
@@ -3852,16 +3802,21 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
|
||||||
|
|
||||||
/* If we still have inotify data buffered, then query the other fds, but don't wait on it */
|
|
||||||
if (e->inotify_data_buffered)
|
|
||||||
- timeout = 0;
|
|
||||||
+ msec = 0;
|
|
||||||
+ else
|
|
||||||
+ msec = timeout == (uint64_t) -1 ? -1 : (int) DIV_ROUND_UP(timeout, USEC_PER_MSEC);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
- r = epoll_wait_usec(e->epoll_fd, e->event_queue, e->event_queue_allocated, timeout);
|
|
||||||
- if (r == -EINTR) {
|
|
||||||
- e->state = SD_EVENT_PENDING;
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- if (r < 0)
|
|
||||||
+ r = epoll_wait(e->epoll_fd, e->event_queue, e->event_queue_allocated, msec);
|
|
||||||
+ if (r < 0) {
|
|
||||||
+ if (errno == EINTR) {
|
|
||||||
+ e->state = SD_EVENT_PENDING;
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ r = -errno;
|
|
||||||
goto finish;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
m = (size_t) r;
|
|
||||||
|
|
||||||
@@ -3874,7 +3829,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
|
||||||
if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, e->event_queue_allocated + n_event_queue))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
- timeout = 0;
|
|
||||||
+ msec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
triple_timestamp_get(&e->timestamp);
|
|
||||||
--
|
|
||||||
2.30.1
|
|
||||||
|
|
@ -1,169 +0,0 @@
|
|||||||
From aee1d734a5034d47005a339ec5b2b39583795039 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Wed, 16 Dec 2020 15:56:44 +0100
|
|
||||||
Subject: [PATCH] test-login: skip consistency checks when logind is not active
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
There are two ways in swich sd_login_* functions acquire data:
|
|
||||||
some are derived from the cgroup path, but others use the data serialized
|
|
||||||
by logind.
|
|
||||||
|
|
||||||
When the tests are executed under Fedora's mock, without systemd-spawn
|
|
||||||
but instead in a traditional chroot, test-login gets confused:
|
|
||||||
the "outside" cgroup path is visible, so sd_pid_get_unit() and
|
|
||||||
sd_pid_get_session() work, but sd_session_is_active() and other functions
|
|
||||||
that need logind data fail.
|
|
||||||
|
|
||||||
Such a buildroot setup is fairly bad, but it can be encountered in the wild, so
|
|
||||||
let's just skip the tests in that case.
|
|
||||||
|
|
||||||
/* Information printed is from the live system */
|
|
||||||
sd_pid_get_unit(0, …) → "session-237.scope"
|
|
||||||
sd_pid_get_user_unit(0, …) → "n/a"
|
|
||||||
sd_pid_get_slice(0, …) → "user-1000.slice"
|
|
||||||
sd_pid_get_session(0, …) → "237"
|
|
||||||
sd_pid_get_owner_uid(0, …) → 1000
|
|
||||||
sd_pid_get_cgroup(0, …) → "/user.slice/user-1000.slice/session-237.scope"
|
|
||||||
sd_uid_get_display(1000, …) → "(null)"
|
|
||||||
sd_uid_get_sessions(1000, …) → [0] ""
|
|
||||||
sd_uid_get_seats(1000, …) → [0] ""
|
|
||||||
Assertion 'r >= 0' failed at src/libsystemd/sd-login/test-login.c:104, function test_login(). Aborting.
|
|
||||||
---
|
|
||||||
src/libsystemd/sd-login/test-login.c | 98 +++++++++++++++-------------
|
|
||||||
1 file changed, 52 insertions(+), 46 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
|
|
||||||
index 5b2ff93e1c..f762b8475b 100644
|
|
||||||
--- a/src/libsystemd/sd-login/test-login.c
|
|
||||||
+++ b/src/libsystemd/sd-login/test-login.c
|
|
||||||
@@ -112,68 +112,74 @@ static void test_login(void) {
|
|
||||||
|
|
||||||
if (session) {
|
|
||||||
r = sd_session_is_active(session);
|
|
||||||
- assert_se(r >= 0);
|
|
||||||
- log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
|
||||||
+ if (r == -ENXIO)
|
|
||||||
+ log_notice("sd_session_is_active failed with ENXIO, it seems logind is not running.");
|
|
||||||
+ else {
|
|
||||||
+ /* All those tests will fail with ENXIO, so let's skip them. */
|
|
||||||
|
|
||||||
- r = sd_session_is_remote(session);
|
|
||||||
- assert_se(r >= 0);
|
|
||||||
- log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
|
||||||
+ assert_se(r >= 0);
|
|
||||||
+ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
|
||||||
|
|
||||||
- r = sd_session_get_state(session, &state);
|
|
||||||
- assert_se(r == 0);
|
|
||||||
- log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
|
||||||
+ r = sd_session_is_remote(session);
|
|
||||||
+ assert_se(r >= 0);
|
|
||||||
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
|
||||||
|
|
||||||
- assert_se(sd_session_get_uid(session, &u) >= 0);
|
|
||||||
- log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
|
||||||
- assert_se(u == u2);
|
|
||||||
+ r = sd_session_get_state(session, &state);
|
|
||||||
+ assert_se(r == 0);
|
|
||||||
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
|
||||||
|
|
||||||
- assert_se(sd_session_get_type(session, &type) >= 0);
|
|
||||||
- log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
|
||||||
+ assert_se(sd_session_get_uid(session, &u) >= 0);
|
|
||||||
+ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
|
||||||
+ assert_se(u == u2);
|
|
||||||
|
|
||||||
- assert_se(sd_session_get_class(session, &class) >= 0);
|
|
||||||
- log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
|
||||||
+ assert_se(sd_session_get_type(session, &type) >= 0);
|
|
||||||
+ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
|
||||||
|
|
||||||
- r = sd_session_get_display(session, &display);
|
|
||||||
- assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
- log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
|
||||||
+ assert_se(sd_session_get_class(session, &class) >= 0);
|
|
||||||
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
|
||||||
|
|
||||||
- r = sd_session_get_remote_user(session, &remote_user);
|
|
||||||
- assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
- log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
|
||||||
- session, strna(remote_user));
|
|
||||||
+ r = sd_session_get_display(session, &display);
|
|
||||||
+ assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
|
||||||
|
|
||||||
- r = sd_session_get_remote_host(session, &remote_host);
|
|
||||||
- assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
- log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
|
||||||
- session, strna(remote_host));
|
|
||||||
+ r = sd_session_get_remote_user(session, &remote_user);
|
|
||||||
+ assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
|
||||||
+ session, strna(remote_user));
|
|
||||||
|
|
||||||
- r = sd_session_get_seat(session, &seat);
|
|
||||||
- if (r >= 0) {
|
|
||||||
- assert_se(seat);
|
|
||||||
+ r = sd_session_get_remote_host(session, &remote_host);
|
|
||||||
+ assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
|
||||||
+ session, strna(remote_host));
|
|
||||||
|
|
||||||
- log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
|
|
||||||
+ r = sd_session_get_seat(session, &seat);
|
|
||||||
+ if (r >= 0) {
|
|
||||||
+ assert_se(seat);
|
|
||||||
+
|
|
||||||
+ log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
- r = sd_seat_can_multi_session(seat);
|
|
||||||
+ r = sd_seat_can_multi_session(seat);
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
- assert_se(r == 1);
|
|
||||||
- log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
+ assert_se(r == 1);
|
|
||||||
+ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
|
|
||||||
- r = sd_seat_can_tty(seat);
|
|
||||||
- assert_se(r >= 0);
|
|
||||||
- log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
+ r = sd_seat_can_tty(seat);
|
|
||||||
+ assert_se(r >= 0);
|
|
||||||
+ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
|
|
||||||
- r = sd_seat_can_graphical(seat);
|
|
||||||
- assert_se(r >= 0);
|
|
||||||
- log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
- } else {
|
|
||||||
- log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
|
||||||
- assert_se(r == -ENODATA);
|
|
||||||
+ r = sd_seat_can_graphical(seat);
|
|
||||||
+ assert_se(r >= 0);
|
|
||||||
+ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
|
||||||
+ } else {
|
|
||||||
+ log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
|
||||||
+ assert_se(r == -ENODATA);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ assert_se(sd_uid_get_state(u, &state2) == 0);
|
|
||||||
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- assert_se(sd_uid_get_state(u, &state2) == 0);
|
|
||||||
- log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seat) {
|
|
||||||
@@ -214,7 +220,7 @@ static void test_login(void) {
|
|
||||||
assert_se(sd_get_seats(NULL) == r);
|
|
||||||
|
|
||||||
r = sd_seat_get_active(NULL, &t, NULL);
|
|
||||||
- assert_se(IN_SET(r, 0, -ENODATA));
|
|
||||||
+ assert_se(IN_SET(r, 0, -ENODATA, -ENXIO));
|
|
||||||
log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t));
|
|
||||||
free(t);
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
|||||||
From 2e9d763e7cbeb33954bbe3f96fd94de2cd62edf7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Thu, 12 Nov 2020 14:28:24 +0100
|
|
||||||
Subject: [PATCH] test-path-util: do not fail if the fd_is_mount_point check
|
|
||||||
fails
|
|
||||||
|
|
||||||
This test fails on i686 and ppc64le in koji:
|
|
||||||
/* test_path */
|
|
||||||
Assertion 'fd_is_mount_point(fd, "/", 0) > 0' failed at src/test/test-path-util.c:85, function test_path(). Aborting.
|
|
||||||
|
|
||||||
I guess some permission error is the most likely.
|
|
||||||
---
|
|
||||||
src/test/test-path-util.c | 23 +++++++++++++++++------
|
|
||||||
1 file changed, 17 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
|
|
||||||
index f4f8d0550b..be428334f3 100644
|
|
||||||
--- a/src/test/test-path-util.c
|
|
||||||
+++ b/src/test/test-path-util.c
|
|
||||||
@@ -40,8 +40,6 @@ static void test_path_simplify(const char *in, const char *out, const char *out_
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_path(void) {
|
|
||||||
- _cleanup_close_ int fd = -1;
|
|
||||||
-
|
|
||||||
log_info("/* %s */", __func__);
|
|
||||||
|
|
||||||
test_path_compare("/goo", "/goo", 0);
|
|
||||||
@@ -80,10 +78,6 @@ static void test_path(void) {
|
|
||||||
assert_se(streq(basename("/aa///file..."), "file..."));
|
|
||||||
assert_se(streq(basename("file.../"), ""));
|
|
||||||
|
|
||||||
- fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
|
|
||||||
- assert_se(fd >= 0);
|
|
||||||
- assert_se(fd_is_mount_point(fd, "/", 0) > 0);
|
|
||||||
-
|
|
||||||
test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
|
|
||||||
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
|
|
||||||
test_path_simplify("///", "/", "/");
|
|
||||||
@@ -120,6 +114,22 @@ static void test_path(void) {
|
|
||||||
assert_se(!path_equal_ptr(NULL, "/a"));
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void test_path_is_mountpoint(void) {
|
|
||||||
+ _cleanup_close_ int fd = -1;
|
|
||||||
+ int r;
|
|
||||||
+
|
|
||||||
+ log_info("/* %s */", __func__);
|
|
||||||
+
|
|
||||||
+ fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
|
|
||||||
+ assert_se(fd >= 0);
|
|
||||||
+
|
|
||||||
+ r = fd_is_mount_point(fd, "/", 0);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ log_warning_errno(r, "Failed to check if / is a mount point, ignoring: %m");
|
|
||||||
+ else
|
|
||||||
+ assert_se(r == 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void test_path_equal_root(void) {
|
|
||||||
/* Nail down the details of how path_equal("/", ...) works. */
|
|
||||||
|
|
||||||
@@ -714,6 +724,7 @@ int main(int argc, char **argv) {
|
|
||||||
|
|
||||||
test_print_paths();
|
|
||||||
test_path();
|
|
||||||
+ test_path_is_mountpoint();
|
|
||||||
test_path_equal_root();
|
|
||||||
test_find_executable_full();
|
|
||||||
test_find_executable(argv[0]);
|
|
@ -1,33 +0,0 @@
|
|||||||
From e8bca4ba55f855260eda684a16e8feb5f20b1deb Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Thu, 12 Nov 2020 15:06:12 +0100
|
|
||||||
Subject: [PATCH] test-path-util: ignore test failure
|
|
||||||
|
|
||||||
---
|
|
||||||
src/test/test-path-util.c | 7 +++++--
|
|
||||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
|
|
||||||
index be428334f3..207c659b8b 100644
|
|
||||||
--- a/src/test/test-path-util.c
|
|
||||||
+++ b/src/test/test-path-util.c
|
|
||||||
@@ -120,14 +120,17 @@ static void test_path_is_mountpoint(void) {
|
|
||||||
|
|
||||||
log_info("/* %s */", __func__);
|
|
||||||
|
|
||||||
+ (void) system("uname -a");
|
|
||||||
+ (void) system("mountpoint /");
|
|
||||||
+
|
|
||||||
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
|
|
||||||
assert_se(fd >= 0);
|
|
||||||
|
|
||||||
r = fd_is_mount_point(fd, "/", 0);
|
|
||||||
if (r < 0)
|
|
||||||
log_warning_errno(r, "Failed to check if / is a mount point, ignoring: %m");
|
|
||||||
- else
|
|
||||||
- assert_se(r == 1);
|
|
||||||
+ else if (r == 0)
|
|
||||||
+ log_warning("/ is not a mountpoint?");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_path_equal_root(void) {
|
|
495
18892.patch
495
18892.patch
@ -1,495 +0,0 @@
|
|||||||
From e0ae456a554d0fce250f9a009c561b97f20c41f8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 17:47:45 +0100
|
|
||||||
Subject: [PATCH 1/6] dns-query: export CNAME_MAX, so that we can use it in
|
|
||||||
other files, too
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Let's rename it a bit, to be more explanatory while exporting it.
|
|
||||||
|
|
||||||
(And let's bump the CNAME limit to 16 — 8 just sounded so little)
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-query.c | 3 +--
|
|
||||||
src/resolve/resolved-dns-query.h | 2 ++
|
|
||||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
|
|
||||||
index 7554d1e82f4..aa9d65d4a82 100644
|
|
||||||
--- a/src/resolve/resolved-dns-query.c
|
|
||||||
+++ b/src/resolve/resolved-dns-query.c
|
|
||||||
@@ -10,7 +10,6 @@
|
|
||||||
#include "resolved-etc-hosts.h"
|
|
||||||
#include "string-util.h"
|
|
||||||
|
|
||||||
-#define CNAME_MAX 8
|
|
||||||
#define QUERIES_MAX 2048
|
|
||||||
#define AUXILIARY_QUERIES_MAX 64
|
|
||||||
|
|
||||||
@@ -977,7 +976,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
|
|
||||||
assert(q);
|
|
||||||
|
|
||||||
q->n_cname_redirects++;
|
|
||||||
- if (q->n_cname_redirects > CNAME_MAX)
|
|
||||||
+ if (q->n_cname_redirects > CNAME_REDIRECT_MAX)
|
|
||||||
return -ELOOP;
|
|
||||||
|
|
||||||
r = dns_question_cname_redirect(q->question_idna, cname, &nq_idna);
|
|
||||||
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
|
|
||||||
index ea296167b61..5d12171b0a1 100644
|
|
||||||
--- a/src/resolve/resolved-dns-query.h
|
|
||||||
+++ b/src/resolve/resolved-dns-query.h
|
|
||||||
@@ -145,3 +145,5 @@ static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
|
|
||||||
dns_query_fully_confidential(q)) |
|
|
||||||
(q->answer_query_flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC));
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+#define CNAME_REDIRECT_MAX 16
|
|
||||||
|
|
||||||
From d29958261a3df80f5cf0e98b1cd307790a92b13b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 17:48:43 +0100
|
|
||||||
Subject: [PATCH 2/6] resolved: tighten checks in
|
|
||||||
dns_resource_record_get_cname_target()
|
|
||||||
|
|
||||||
Let's refuse to consider CNAME/DNAME replies matching for RR types where
|
|
||||||
that is not really conceptually allow (i.e. on CNAME/DNAME lookups
|
|
||||||
themselves).
|
|
||||||
|
|
||||||
(And add a similar check to dns_resource_key_match_cname_or_dname() too,
|
|
||||||
which implements a smilar match)
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-rr.c | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
|
|
||||||
index 823117e5c92..7e76e0c6cc0 100644
|
|
||||||
--- a/src/resolve/resolved-dns-rr.c
|
|
||||||
+++ b/src/resolve/resolved-dns-rr.c
|
|
||||||
@@ -244,6 +244,9 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
|
|
||||||
if (cname->class != key->class && key->class != DNS_CLASS_ANY)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
+ if (!dns_type_may_redirect(key->type))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
if (cname->type == DNS_TYPE_CNAME)
|
|
||||||
r = dns_name_equal(dns_resource_key_name(key), dns_resource_key_name(cname));
|
|
||||||
else if (cname->type == DNS_TYPE_DNAME)
|
|
||||||
@@ -1743,9 +1746,16 @@ int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord
|
|
||||||
assert(key);
|
|
||||||
assert(cname);
|
|
||||||
|
|
||||||
+ /* Checks if the RR `cname` is a CNAME/DNAME RR that matches the specified `key`. If so, returns the
|
|
||||||
+ * target domain. If not, returns -EUNATCH */
|
|
||||||
+
|
|
||||||
if (key->class != cname->key->class && key->class != DNS_CLASS_ANY)
|
|
||||||
return -EUNATCH;
|
|
||||||
|
|
||||||
+ if (!dns_type_may_redirect(key->type)) /* This key type is not subject to CNAME/DNAME redirection?
|
|
||||||
+ * Then let's refuse right-away */
|
|
||||||
+ return -EUNATCH;
|
|
||||||
+
|
|
||||||
if (cname->key->type == DNS_TYPE_CNAME) {
|
|
||||||
r = dns_name_equal(dns_resource_key_name(key),
|
|
||||||
dns_resource_key_name(cname->key));
|
|
||||||
|
|
||||||
From 4838dc4f2be1d29da9ce9a930c48717a4491d70e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 17:53:31 +0100
|
|
||||||
Subject: [PATCH 3/6] resolved: handle multiple CNAME redirects in a single
|
|
||||||
reply from upstream
|
|
||||||
|
|
||||||
www.netflix.com responds with a chain of CNAMEs in the same packet.
|
|
||||||
Let's handle that properly (so far we only followed CNAMEs a single step
|
|
||||||
when in the same packet)
|
|
||||||
|
|
||||||
Fixes: #18819
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-stub.c | 105 +++++++++++++++++---------------
|
|
||||||
1 file changed, 57 insertions(+), 48 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index c2734e57b9b..c3a28d390a4 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -162,79 +162,88 @@ static int dns_stub_collect_answer_by_question(
|
|
||||||
bool with_rrsig) { /* Add RRSIG RR matching each RR */
|
|
||||||
|
|
||||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *redirected_key = NULL;
|
|
||||||
+ unsigned n_cname_redirects = 0;
|
|
||||||
DnsAnswerItem *item;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(reply);
|
|
||||||
|
|
||||||
- /* Copies all RRs from 'answer' into 'reply', if they match 'question'. */
|
|
||||||
+ /* Copies all RRs from 'answer' into 'reply', if they match 'question'. There might be direct and
|
|
||||||
+ * indirect matches (i.e. via CNAME/DNAME). If they have an indirect one, remember where we need to
|
|
||||||
+ * go, and restart the loop */
|
|
||||||
+
|
|
||||||
+ for (;;) {
|
|
||||||
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *next_redirected_key = NULL;
|
|
||||||
+
|
|
||||||
+ DNS_ANSWER_FOREACH_ITEM(item, answer) {
|
|
||||||
+ DnsResourceKey *k = NULL;
|
|
||||||
+
|
|
||||||
+ if (redirected_key) {
|
|
||||||
+ /* There was a redirect in this packet, let's collect all matching RRs for the redirect */
|
|
||||||
+ r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+
|
|
||||||
+ k = redirected_key;
|
|
||||||
+ } else if (question) {
|
|
||||||
+ /* We have a question, let's see if this RR matches it */
|
|
||||||
+ r = dns_question_matches_rr(question, item->rr, NULL);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+
|
|
||||||
+ k = question->keys[0];
|
|
||||||
+ } else
|
|
||||||
+ r = 1; /* No question, everything matches */
|
|
||||||
|
|
||||||
- DNS_ANSWER_FOREACH_ITEM(item, answer) {
|
|
||||||
- if (question) {
|
|
||||||
- r = dns_question_matches_rr(question, item->rr, NULL);
|
|
||||||
- if (r < 0)
|
|
||||||
- return r;
|
|
||||||
if (r == 0) {
|
|
||||||
_cleanup_free_ char *target = NULL;
|
|
||||||
|
|
||||||
/* OK, so the RR doesn't directly match. Let's see if the RR is a matching
|
|
||||||
* CNAME or DNAME */
|
|
||||||
|
|
||||||
- r = dns_resource_record_get_cname_target(
|
|
||||||
- question->keys[0],
|
|
||||||
- item->rr,
|
|
||||||
- &target);
|
|
||||||
+ assert(k);
|
|
||||||
+
|
|
||||||
+ r = dns_resource_record_get_cname_target(k, item->rr, &target);
|
|
||||||
if (r == -EUNATCH)
|
|
||||||
continue; /* Not a CNAME/DNAME or doesn't match */
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
- dns_resource_key_unref(redirected_key);
|
|
||||||
+ /* Oh, wow, this is a redirect. Let's remember where this points, and store
|
|
||||||
+ * it in 'next_redirected_key'. Once we finished iterating through the rest
|
|
||||||
+ * of the RR's we'll start again, with the redirected RR key. */
|
|
||||||
+
|
|
||||||
+ n_cname_redirects++;
|
|
||||||
+ if (n_cname_redirects > CNAME_REDIRECT_MAX) /* don't loop forever */
|
|
||||||
+ return -ELOOP;
|
|
||||||
+
|
|
||||||
+ dns_resource_key_unref(next_redirected_key);
|
|
||||||
|
|
||||||
/* There can only be one CNAME per name, hence no point in storing more than one here */
|
|
||||||
- redirected_key = dns_resource_key_new(question->keys[0]->class, question->keys[0]->type, target);
|
|
||||||
- if (!redirected_key)
|
|
||||||
+ next_redirected_key = dns_resource_key_new(k->class, k->type, target);
|
|
||||||
+ if (!next_redirected_key)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
|
|
||||||
- /* Mask the section info, we want the primary answers to always go without section info, so
|
|
||||||
- * that it is added to the answer section when we synthesize a reply. */
|
|
||||||
+ /* Mask the section info, we want the primary answers to always go without section info, so
|
|
||||||
+ * that it is added to the answer section when we synthesize a reply. */
|
|
||||||
|
|
||||||
- r = reply_add_with_rrsig(
|
|
||||||
- reply,
|
|
||||||
- item->rr,
|
|
||||||
- item->ifindex,
|
|
||||||
- item->flags & ~DNS_ANSWER_MASK_SECTIONS,
|
|
||||||
- item->rrsig,
|
|
||||||
- with_rrsig);
|
|
||||||
- if (r < 0)
|
|
||||||
- return r;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (!redirected_key)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- /* This is a CNAME/DNAME answer. In this case also append where the redirections point to to the main
|
|
||||||
- * answer section */
|
|
||||||
-
|
|
||||||
- DNS_ANSWER_FOREACH_ITEM(item, answer) {
|
|
||||||
+ r = reply_add_with_rrsig(
|
|
||||||
+ reply,
|
|
||||||
+ item->rr,
|
|
||||||
+ item->ifindex,
|
|
||||||
+ item->flags & ~DNS_ANSWER_MASK_SECTIONS,
|
|
||||||
+ item->rrsig,
|
|
||||||
+ with_rrsig);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
|
|
||||||
- if (r < 0)
|
|
||||||
- return r;
|
|
||||||
- if (r == 0)
|
|
||||||
- continue;
|
|
||||||
+ if (!next_redirected_key)
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
- r = reply_add_with_rrsig(
|
|
||||||
- reply,
|
|
||||||
- item->rr,
|
|
||||||
- item->ifindex,
|
|
||||||
- item->flags & ~DNS_ANSWER_MASK_SECTIONS,
|
|
||||||
- item->rrsig,
|
|
||||||
- with_rrsig);
|
|
||||||
- if (r < 0)
|
|
||||||
- return r;
|
|
||||||
+ dns_resource_key_unref(redirected_key);
|
|
||||||
+ redirected_key = TAKE_PTR(next_redirected_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
From 39005e187095062718621880e5d8ad707ac8fe8f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 18:01:27 +0100
|
|
||||||
Subject: [PATCH 4/6] resolved: split out helper that checks whether we shall
|
|
||||||
reply with EDNS0 DO
|
|
||||||
|
|
||||||
Just some refactoring, no actual code changes.
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-stub.c | 22 ++++++++++++++--------
|
|
||||||
1 file changed, 14 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index c3a28d390a4..b4df5837aad 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -561,6 +561,19 @@ static int dns_stub_send(
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int dns_stub_reply_with_edns0_do(DnsQuery *q) {
|
|
||||||
+ assert(q);
|
|
||||||
+
|
|
||||||
+ /* Reply with DNSSEC DO set? Only if client supports it; and we did any DNSSEC verification
|
|
||||||
+ * ourselves, or consider the data fully authenticated because we generated it locally, or the client
|
|
||||||
+ * set cd */
|
|
||||||
+
|
|
||||||
+ return DNS_PACKET_DO(q->request_packet) &&
|
|
||||||
+ (q->answer_dnssec_result >= 0 || /* we did proper DNSSEC validation … */
|
|
||||||
+ dns_query_fully_authenticated(q) || /* … or we considered it authentic otherwise … */
|
|
||||||
+ DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int dns_stub_send_reply(
|
|
||||||
DnsQuery *q,
|
|
||||||
int rcode) {
|
|
||||||
@@ -571,14 +584,7 @@ static int dns_stub_send_reply(
|
|
||||||
|
|
||||||
assert(q);
|
|
||||||
|
|
||||||
- /* Reply with DNSSEC DO set? Only if client supports it; and we did any DNSSEC verification
|
|
||||||
- * ourselves, or consider the data fully authenticated because we generated it locally, or
|
|
||||||
- * the client set cd */
|
|
||||||
- edns0_do =
|
|
||||||
- DNS_PACKET_DO(q->request_packet) &&
|
|
||||||
- (q->answer_dnssec_result >= 0 || /* we did proper DNSSEC validation … */
|
|
||||||
- dns_query_fully_authenticated(q) || /* … or we considered it authentic otherwise … */
|
|
||||||
- DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
|
|
||||||
+ edns0_do = dns_stub_reply_with_edns0_do(q); /* let's check if we shall reply with EDNS0 DO? */
|
|
||||||
|
|
||||||
r = dns_stub_assign_sections(
|
|
||||||
q,
|
|
||||||
|
|
||||||
From b97fc57178932689bdcb9030e1e2bf299d49ce0b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 16:50:04 +0100
|
|
||||||
Subject: [PATCH 5/6] resolved: fully follow CNAMEs in the DNS stub after all
|
|
||||||
|
|
||||||
In 2f4d8e577ca7bc51fb054b8c2c8dd57c2e188a41 I argued that following
|
|
||||||
CNAMEs in the stub is not necessary anymore. However, I think it' better
|
|
||||||
to revert to the status quo ante and follow it after all, given it is
|
|
||||||
easy for us and makes sure our D-Bus/varlink replies are more similar to
|
|
||||||
our DNS stub replies that way, and we save clients potential roundtrips.
|
|
||||||
|
|
||||||
Hence, whenever we hit a CNAME/DNAME redirect, let's restart the query
|
|
||||||
like we do for the D-Bus/Varlink case, and collect replies as we go.
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-stub.c | 38 +++++++++++++++++++++++----------
|
|
||||||
1 file changed, 27 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index b4df5837aad..85c4eda469c 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -586,13 +586,6 @@ static int dns_stub_send_reply(
|
|
||||||
|
|
||||||
edns0_do = dns_stub_reply_with_edns0_do(q); /* let's check if we shall reply with EDNS0 DO? */
|
|
||||||
|
|
||||||
- r = dns_stub_assign_sections(
|
|
||||||
- q,
|
|
||||||
- q->request_packet->question,
|
|
||||||
- edns0_do);
|
|
||||||
- if (r < 0)
|
|
||||||
- return log_debug_errno(r, "Failed to assign sections: %m");
|
|
||||||
-
|
|
||||||
r = dns_stub_make_reply_packet(
|
|
||||||
&reply,
|
|
||||||
DNS_PACKET_PAYLOAD_SIZE_MAX(q->request_packet),
|
|
||||||
@@ -743,13 +736,37 @@ static void dns_stub_query_complete(DnsQuery *q) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Note that we don't bother with following CNAMEs here. We propagate the authoritative/additional
|
|
||||||
- * sections from the upstream answer however, hence if the upstream server collected that information
|
|
||||||
- * already we don't have to collect it ourselves anymore. */
|
|
||||||
+ /* Take all data from the current reply, and merge it into the three reply sections we are building
|
|
||||||
+ * up. We do this before processing CNAME redirects, so that we gradually build up our sections, and
|
|
||||||
+ * and keep adding all RRs in the CNAME chain. */
|
|
||||||
+ r = dns_stub_assign_sections(
|
|
||||||
+ q,
|
|
||||||
+ q->request_packet->question,
|
|
||||||
+ dns_stub_reply_with_edns0_do(q));
|
|
||||||
+ if (r < 0) {
|
|
||||||
+ log_debug_errno(r, "Failed to assign sections: %m");
|
|
||||||
+ dns_query_free(q);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
switch (q->state) {
|
|
||||||
|
|
||||||
case DNS_TRANSACTION_SUCCESS:
|
|
||||||
+ r = dns_query_process_cname(q);
|
|
||||||
+ if (r == -ELOOP) { /* CNAME loop, let's send what we already have */
|
|
||||||
+ log_debug_errno(r, "Detected CNAME loop, returning what we already have.");
|
|
||||||
+ (void) dns_stub_send_reply(q, q->answer_rcode);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (r < 0) {
|
|
||||||
+ log_debug_errno(r, "Failed to process CNAME: %m");
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (r == DNS_QUERY_RESTARTED)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ _fallthrough_;
|
|
||||||
+
|
|
||||||
case DNS_TRANSACTION_RCODE_FAILURE:
|
|
||||||
(void) dns_stub_send_reply(q, q->answer_rcode);
|
|
||||||
break;
|
|
||||||
@@ -888,7 +905,6 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
|
||||||
r = dns_query_new(m, &q, p->question, p->question, NULL, 0,
|
|
||||||
SD_RESOLVED_PROTOCOLS_ALL|
|
|
||||||
SD_RESOLVED_NO_SEARCH|
|
|
||||||
- SD_RESOLVED_NO_CNAME|
|
|
||||||
(DNS_PACKET_DO(p) ? SD_RESOLVED_REQUIRE_PRIMARY : 0)|
|
|
||||||
SD_RESOLVED_CLAMP_TTL);
|
|
||||||
if (r < 0) {
|
|
||||||
|
|
||||||
From 5d7da51ee1d27e86a0487a4b2abc3cfb0ed44c23 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Fri, 5 Mar 2021 18:20:59 +0100
|
|
||||||
Subject: [PATCH 6/6] resolved: when synthesizing stub replies from multiple
|
|
||||||
upstream packet, let's avoid RR duplicates
|
|
||||||
|
|
||||||
If we synthesize a stub reply from multiple upstream packet (i.e. a
|
|
||||||
series of CNAME/DNAME redirects), it might happen that we add the same
|
|
||||||
RR to a different reply section at a different CNAME/DNAME redirect
|
|
||||||
chain element. Let's clean this up once we are about to send the reply
|
|
||||||
message to the client: let's remove sections from "lower-priority"
|
|
||||||
sections when they are already listed in a "higher-priority" section.
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-answer.c | 25 +++++++++++++++++++++++++
|
|
||||||
src/resolve/resolved-dns-answer.h | 1 +
|
|
||||||
src/resolve/resolved-dns-stub.c | 20 ++++++++++++++++++++
|
|
||||||
3 files changed, 46 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
|
|
||||||
index ce3cbce308d..a667ab5ede4 100644
|
|
||||||
--- a/src/resolve/resolved-dns-answer.c
|
|
||||||
+++ b/src/resolve/resolved-dns-answer.c
|
|
||||||
@@ -640,6 +640,31 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int dns_answer_remove_by_answer_keys(DnsAnswer **a, DnsAnswer *b) {
|
|
||||||
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *prev = NULL;
|
|
||||||
+ DnsAnswerItem *item;
|
|
||||||
+ int r;
|
|
||||||
+
|
|
||||||
+ /* Removes all items from '*a' that have a matching key in 'b' */
|
|
||||||
+
|
|
||||||
+ DNS_ANSWER_FOREACH_ITEM(item, b) {
|
|
||||||
+
|
|
||||||
+ if (prev && dns_resource_key_equal(item->rr->key, prev)) /* Skip this one, we already looked at it */
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ r = dns_answer_remove_by_key(a, item->rr->key);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+
|
|
||||||
+ /* Let's remember this entry's RR key, to optimize the loop a bit: if we have an RRset with
|
|
||||||
+ * more than one item then we don't need to remove the key multiple times */
|
|
||||||
+ dns_resource_key_unref(prev);
|
|
||||||
+ prev = dns_resource_key_ref(item->rr->key);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int dns_answer_copy_by_key(
|
|
||||||
DnsAnswer **a,
|
|
||||||
DnsAnswer *source,
|
|
||||||
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
|
|
||||||
index c2fd0c078f4..7d19eee4e2b 100644
|
|
||||||
--- a/src/resolve/resolved-dns-answer.h
|
|
||||||
+++ b/src/resolve/resolved-dns-answer.h
|
|
||||||
@@ -68,6 +68,7 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, size_t n_free);
|
|
||||||
|
|
||||||
int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key);
|
|
||||||
int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rr);
|
|
||||||
+int dns_answer_remove_by_answer_keys(DnsAnswer **a, DnsAnswer *b);
|
|
||||||
|
|
||||||
int dns_answer_copy_by_key(DnsAnswer **a, DnsAnswer *source, const DnsResourceKey *key, DnsAnswerFlags or_flags, DnsResourceRecord *rrsig);
|
|
||||||
int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKey *key, DnsAnswerFlags or_flags, DnsResourceRecord *rrsig);
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index 85c4eda469c..8e781dd7389 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -574,6 +574,24 @@ static int dns_stub_reply_with_edns0_do(DnsQuery *q) {
|
|
||||||
DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void dns_stub_suppress_duplicate_section_rrs(DnsQuery *q) {
|
|
||||||
+ /* If we follow a CNAME/DNAME chain we might end up populating our sections with redundant RRs
|
|
||||||
+ * because we built up the sections from multiple reply packets (one from each CNAME/DNAME chain
|
|
||||||
+ * element). E.g. it could be that an RR that was included in the first reply's additional section
|
|
||||||
+ * ends up being relevant as main answer in a subsequent reply in the chain. Let's clean this up, and
|
|
||||||
+ * remove everything in the "higher priority" sections from the "lower priority" sections.
|
|
||||||
+ *
|
|
||||||
+ * Note that this removal matches by RR keys instead of the full RRs. This is because RRsets should
|
|
||||||
+ * always end up in one section fully or not at all, but never be split among sections.
|
|
||||||
+ *
|
|
||||||
+ * Specifically: we remove ANSWER section RRs from the AUTHORITATIVE and ADDITIONAL sections, as well
|
|
||||||
+ * as AUTHORITATIVE section RRs from the ADDITIONAL section. */
|
|
||||||
+
|
|
||||||
+ dns_answer_remove_by_answer_keys(&q->reply_authoritative, q->reply_answer);
|
|
||||||
+ dns_answer_remove_by_answer_keys(&q->reply_additional, q->reply_answer);
|
|
||||||
+ dns_answer_remove_by_answer_keys(&q->reply_additional, q->reply_authoritative);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int dns_stub_send_reply(
|
|
||||||
DnsQuery *q,
|
|
||||||
int rcode) {
|
|
||||||
@@ -594,6 +612,8 @@ static int dns_stub_send_reply(
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to build reply packet: %m");
|
|
||||||
|
|
||||||
+ dns_stub_suppress_duplicate_section_rrs(q);
|
|
||||||
+
|
|
||||||
r = dns_stub_add_reply_packet_body(
|
|
||||||
reply,
|
|
||||||
q->reply_answer,
|
|
154
18915.patch
154
18915.patch
@ -1,154 +0,0 @@
|
|||||||
From 8b0f54c9290564e8c27c9c8ac464cdcc2c659ad5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Sat, 6 Mar 2021 19:06:08 +0100
|
|
||||||
Subject: [PATCH 1/3] pid1: return varlink error on the right connection
|
|
||||||
|
|
||||||
---
|
|
||||||
src/core/core-varlink.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/core/core-varlink.c b/src/core/core-varlink.c
|
|
||||||
index d695106658b..b3df8cd893c 100644
|
|
||||||
--- a/src/core/core-varlink.c
|
|
||||||
+++ b/src/core/core-varlink.c
|
|
||||||
@@ -142,7 +142,7 @@ static int vl_method_subscribe_managed_oom_cgroups(
|
|
||||||
/* We only take one subscriber for this method so return an error if there's already an existing one.
|
|
||||||
* This shouldn't happen since systemd-oomd is the only client of this method. */
|
|
||||||
if (FLAGS_SET(flags, VARLINK_METHOD_MORE) && m->managed_oom_varlink_request)
|
|
||||||
- return varlink_error(m->managed_oom_varlink_request, VARLINK_ERROR_SUBSCRIPTION_TAKEN, NULL);
|
|
||||||
+ return varlink_error(link, VARLINK_ERROR_SUBSCRIPTION_TAKEN, NULL);
|
|
||||||
|
|
||||||
r = json_build(&arr, JSON_BUILD_EMPTY_ARRAY);
|
|
||||||
if (r < 0)
|
|
||||||
@@ -188,6 +188,7 @@ static int vl_method_subscribe_managed_oom_cgroups(
|
|
||||||
if (!FLAGS_SET(flags, VARLINK_METHOD_MORE))
|
|
||||||
return varlink_reply(link, v);
|
|
||||||
|
|
||||||
+ assert(!m->managed_oom_varlink_request);
|
|
||||||
m->managed_oom_varlink_request = varlink_ref(link);
|
|
||||||
return varlink_notify(m->managed_oom_varlink_request, v);
|
|
||||||
}
|
|
||||||
@@ -475,8 +476,7 @@ void manager_varlink_done(Manager *m) {
|
|
||||||
assert(m);
|
|
||||||
|
|
||||||
/* Send the final message if we still have a subscribe request open. */
|
|
||||||
- if (m->managed_oom_varlink_request)
|
|
||||||
- m->managed_oom_varlink_request = varlink_close_unref(m->managed_oom_varlink_request);
|
|
||||||
+ m->managed_oom_varlink_request = varlink_close_unref(m->managed_oom_varlink_request);
|
|
||||||
|
|
||||||
m->varlink_server = varlink_server_unref(m->varlink_server);
|
|
||||||
}
|
|
||||||
|
|
||||||
From 39ad3f1c092b5dffcbb4b1d12eb9ca407f010a3c Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Sun, 7 Mar 2021 16:42:35 +0100
|
|
||||||
Subject: [PATCH 2/3] varlink: avoid using dangling ref in
|
|
||||||
varlink_close_unref()
|
|
||||||
|
|
||||||
Fixes #18025, https://bugzilla.redhat.com/show_bug.cgi?id=1931034.
|
|
||||||
|
|
||||||
We drop the reference stored in Manager.managed_oom_varlink_request in two code paths:
|
|
||||||
vl_disconnect() which is installed as a disconnect callback, and in manager_varlink_done().
|
|
||||||
But we also make a disconnect from manager_varlink_done(). So we end up with the following
|
|
||||||
call stack:
|
|
||||||
|
|
||||||
(gdb) bt
|
|
||||||
0 vl_disconnect (s=0x112c7b0, link=0xea0070, userdata=0xe9bcc0) at ../src/core/core-varlink.c:414
|
|
||||||
1 0x00007f1366e9d5ac in varlink_detach_server (v=0xea0070) at ../src/shared/varlink.c:1210
|
|
||||||
2 0x00007f1366e9d664 in varlink_close (v=0xea0070) at ../src/shared/varlink.c:1228
|
|
||||||
3 0x00007f1366e9d6b5 in varlink_close_unref (v=0xea0070) at ../src/shared/varlink.c:1240
|
|
||||||
4 0x0000000000524629 in manager_varlink_done (m=0xe9bcc0) at ../src/core/core-varlink.c:479
|
|
||||||
5 0x000000000048ef7b in manager_free (m=0xe9bcc0) at ../src/core/manager.c:1357
|
|
||||||
6 0x000000000042602c in main (argc=5, argv=0x7fff439c43d8) at ../src/core/main.c:2909
|
|
||||||
|
|
||||||
When we enter vl_disconnect(), m->managed_oom_varlink_request.n_ref==1.
|
|
||||||
When we exit from vl_discconect(), m->managed_oom_varlink_request==NULL. But
|
|
||||||
varlink_close_unref() has a copy of the pointer in *v. When we continue executing
|
|
||||||
varlink_close_unref(), this pointer is dangling, and the call to varlink_unref()
|
|
||||||
is done with an invalid pointer.
|
|
||||||
---
|
|
||||||
src/shared/varlink.c | 33 +++++++++++++++++++++++++--------
|
|
||||||
1 file changed, 25 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
|
|
||||||
index 31128e02e06..6ed72075ba5 100644
|
|
||||||
--- a/src/shared/varlink.c
|
|
||||||
+++ b/src/shared/varlink.c
|
|
||||||
@@ -1206,8 +1206,9 @@ int varlink_close(Varlink *v) {
|
|
||||||
|
|
||||||
varlink_set_state(v, VARLINK_DISCONNECTED);
|
|
||||||
|
|
||||||
- /* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref
|
|
||||||
- * which would destroy us before we can call varlink_clear() */
|
|
||||||
+ /* Let's take a reference first, since varlink_detach_server() might drop the final ref from the
|
|
||||||
+ * disconnect callback, which would invalidate the pointer we are holding before we can call
|
|
||||||
+ * varlink_clear(). */
|
|
||||||
varlink_ref(v);
|
|
||||||
varlink_detach_server(v);
|
|
||||||
varlink_clear(v);
|
|
||||||
@@ -1220,17 +1221,33 @@ Varlink* varlink_close_unref(Varlink *v) {
|
|
||||||
if (!v)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- (void) varlink_close(v);
|
|
||||||
+ /* A reference is given to us to be destroyed. But when calling varlink_close(), a callback might
|
|
||||||
+ * also drop a reference. We allow this, and will hold a temporary reference to the object to make
|
|
||||||
+ * sure that the object still exists when control returns to us. If there's just one reference
|
|
||||||
+ * remaining after varlink_close(), even though there were at least two right before, we'll handle
|
|
||||||
+ * that gracefully instead of crashing.
|
|
||||||
+ *
|
|
||||||
+ * In other words, this call drops the donated reference, but if the internal call to varlink_close()
|
|
||||||
+ * dropped a reference to, we don't drop the reference afain. This allows the caller to say:
|
|
||||||
+ * global_object->varlink = varlink_close_unref(global_object->varlink);
|
|
||||||
+ * even though there is some callback which has access to global_object and may drop the reference
|
|
||||||
+ * stored in global_object->varlink. Without this step, the same code would have to be written as:
|
|
||||||
+ * Varlink *t = TAKE_PTR(global_object->varlink);
|
|
||||||
+ * varlink_close_unref(t);
|
|
||||||
+ */
|
|
||||||
+ /* n_ref >= 1 */
|
|
||||||
+ varlink_ref(v); /* n_ref >= 2 */
|
|
||||||
+ varlink_close(v); /* n_ref >= 1 */
|
|
||||||
+ if (v->n_ref > 1)
|
|
||||||
+ v->n_ref--; /* n_ref >= 1 */
|
|
||||||
return varlink_unref(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Varlink* varlink_flush_close_unref(Varlink *v) {
|
|
||||||
- if (!v)
|
|
||||||
- return NULL;
|
|
||||||
+ if (v)
|
|
||||||
+ varlink_flush(v);
|
|
||||||
|
|
||||||
- (void) varlink_flush(v);
|
|
||||||
- (void) varlink_close(v);
|
|
||||||
- return varlink_unref(v);
|
|
||||||
+ return varlink_close_unref(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
|
|
||||||
|
|
||||||
From a19c1a4baaa1dadc80885e3ad41f19a6c6c450fd Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
||||||
Date: Mon, 8 Mar 2021 09:21:25 +0100
|
|
||||||
Subject: [PATCH 3/3] oomd: "downgrade" level of message
|
|
||||||
|
|
||||||
PID1 already logs about the service being started, so this line isn't necessary
|
|
||||||
in normal use. Also, by the time it is emitted, the service has already
|
|
||||||
signalled readiness, so let's not say "starting" but "started".
|
|
||||||
---
|
|
||||||
src/oom/oomd.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/oom/oomd.c b/src/oom/oomd.c
|
|
||||||
index 674d53fdcfe..6e2a5889d1e 100644
|
|
||||||
--- a/src/oom/oomd.c
|
|
||||||
+++ b/src/oom/oomd.c
|
|
||||||
@@ -170,7 +170,7 @@ static int run(int argc, char *argv[]) {
|
|
||||||
|
|
||||||
notify_msg = notify_start(NOTIFY_READY, NOTIFY_STOPPING);
|
|
||||||
|
|
||||||
- log_info("systemd-oomd starting%s!", arg_dry_run ? " in dry run mode" : "");
|
|
||||||
+ log_debug("systemd-oomd started%s.", arg_dry_run ? " in dry run mode" : "");
|
|
||||||
|
|
||||||
r = sd_event_loop(m->event);
|
|
||||||
if (r < 0)
|
|
593
19009.patch
593
19009.patch
@ -1,593 +0,0 @@
|
|||||||
From 1499a0a99a0765b4b1b56f56d6712324e740911f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 20:47:28 +0100
|
|
||||||
Subject: [PATCH 01/12] resolved: add new helper dns_answer_min_ttl()
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-answer.c | 19 +++++++++++++++++++
|
|
||||||
src/resolve/resolved-dns-answer.h | 2 ++
|
|
||||||
2 files changed, 21 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
|
|
||||||
index a667ab5ede4..5fbff81c255 100644
|
|
||||||
--- a/src/resolve/resolved-dns-answer.c
|
|
||||||
+++ b/src/resolve/resolved-dns-answer.c
|
|
||||||
@@ -963,3 +963,22 @@ void dns_answer_randomize(DnsAnswer *a) {
|
|
||||||
SWAP_TWO(a->items[i], a->items[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+uint32_t dns_answer_min_ttl(DnsAnswer *a) {
|
|
||||||
+ uint32_t ttl = UINT32_MAX;
|
|
||||||
+ DnsResourceRecord *rr;
|
|
||||||
+
|
|
||||||
+ /* Return the smallest TTL of all RRs in this answer */
|
|
||||||
+
|
|
||||||
+ DNS_ANSWER_FOREACH(rr, a) {
|
|
||||||
+ /* Don't consider OPT (where the TTL field is used for other purposes than an actual TTL) */
|
|
||||||
+
|
|
||||||
+ if (dns_type_is_pseudo(rr->key->type) ||
|
|
||||||
+ dns_class_is_pseudo(rr->key->class))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ ttl = MIN(ttl, rr->ttl);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ttl;
|
|
||||||
+}
|
|
||||||
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
|
|
||||||
index 7d19eee4e2b..447da5d6cc3 100644
|
|
||||||
--- a/src/resolve/resolved-dns-answer.h
|
|
||||||
+++ b/src/resolve/resolved-dns-answer.h
|
|
||||||
@@ -87,6 +87,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f);
|
|
||||||
|
|
||||||
void dns_answer_randomize(DnsAnswer *a);
|
|
||||||
|
|
||||||
+uint32_t dns_answer_min_ttl(DnsAnswer *a);
|
|
||||||
+
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
|
|
||||||
|
|
||||||
#define _DNS_ANSWER_FOREACH(q, kk, a) \
|
|
||||||
|
|
||||||
From 3b7006cb44dd2860cb1b2e652e318d196dddf312 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 20:47:53 +0100
|
|
||||||
Subject: [PATCH 02/12] resolved: rebreak a few comments
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 19 +++++++------------
|
|
||||||
1 file changed, 7 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index 0bf320df880..23612a5c353 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -320,11 +320,9 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
|
|
||||||
|
|
||||||
ttl = MIN(rr->ttl, nsec_ttl);
|
|
||||||
if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
|
|
||||||
- /* If this is a SOA RR, and it is requested, clamp to
|
|
||||||
- * the SOA's minimum field. This is used when we do
|
|
||||||
- * negative caching, to determine the TTL for the
|
|
||||||
- * negative caching entry. See RFC 2308, Section
|
|
||||||
- * 5. */
|
|
||||||
+ /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
|
|
||||||
+ * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
|
|
||||||
+ * 2308, Section 5. */
|
|
||||||
|
|
||||||
if (ttl > rr->soa.minimum)
|
|
||||||
ttl = rr->soa.minimum;
|
|
||||||
@@ -337,8 +335,7 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
|
|
||||||
if (rr->expiry != USEC_INFINITY) {
|
|
||||||
usec_t left;
|
|
||||||
|
|
||||||
- /* Make use of the DNSSEC RRSIG expiry info, if we
|
|
||||||
- * have it */
|
|
||||||
+ /* Make use of the DNSSEC RRSIG expiry info, if we have it */
|
|
||||||
|
|
||||||
left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
|
|
||||||
if (u > left)
|
|
||||||
@@ -785,9 +782,8 @@ int dns_cache_put(
|
|
||||||
if (r > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- /* But not if it has a matching CNAME/DNAME (the negative
|
|
||||||
- * caching will be done on the canonical name, not on the
|
|
||||||
- * alias) */
|
|
||||||
+ /* But not if it has a matching CNAME/DNAME (the negative caching will be done on the canonical name,
|
|
||||||
+ * not on the alias) */
|
|
||||||
r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
goto fail;
|
|
||||||
@@ -803,8 +799,7 @@ int dns_cache_put(
|
|
||||||
if (r == 0 && !weird_rcode)
|
|
||||||
return 0;
|
|
||||||
if (r > 0) {
|
|
||||||
- /* Refuse using the SOA data if it is unsigned, but the key is
|
|
||||||
- * signed */
|
|
||||||
+ /* Refuse using the SOA data if it is unsigned, but the key is signed */
|
|
||||||
if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
|
|
||||||
(flags & DNS_ANSWER_AUTHENTICATED) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
From 77db3caee36d0241bf2153f56579a9fb952962f1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 20:48:18 +0100
|
|
||||||
Subject: [PATCH 03/12] resolved: use dns_answer_isempty() where appropriate
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index 23612a5c353..8edbd5fee94 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -693,7 +693,7 @@ int dns_cache_put(
|
|
||||||
* short time.) */
|
|
||||||
|
|
||||||
if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
|
|
||||||
- if (dns_answer_size(answer) <= 0) {
|
|
||||||
+ if (dns_answer_isempty(answer)) {
|
|
||||||
if (key) {
|
|
||||||
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
|
|
||||||
|
|
||||||
|
|
||||||
From b12058e8f96a9b490e2b1ce98f81ced182add577 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 20:48:35 +0100
|
|
||||||
Subject: [PATCH 04/12] resolved: fix indentation
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index 8edbd5fee94..09fb8e2c883 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -808,7 +808,7 @@ int dns_cache_put(
|
|
||||||
if (cache_mode == DNS_CACHE_MODE_NO_NEGATIVE) {
|
|
||||||
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
|
|
||||||
log_debug("Not caching negative entry for: %s, cache mode set to no-negative",
|
|
||||||
- dns_resource_key_to_string(key, key_str, sizeof key_str));
|
|
||||||
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
From f6d80c361d6a51972d4df264a190bf01ef7af624 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 21:15:30 +0100
|
|
||||||
Subject: [PATCH 05/12] resolved: drop unnecessary local variable
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index 09fb8e2c883..0f40e0e40f4 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -416,7 +416,7 @@ static int dns_cache_put_positive(
|
|
||||||
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
|
|
||||||
DnsCacheItem *existing;
|
|
||||||
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
|
|
||||||
- int r, k;
|
|
||||||
+ int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
assert(rr);
|
|
||||||
@@ -430,9 +430,9 @@ static int dns_cache_put_positive(
|
|
||||||
|
|
||||||
/* New TTL is 0? Delete this specific entry... */
|
|
||||||
if (rr->ttl <= 0) {
|
|
||||||
- k = dns_cache_remove_by_rr(c, rr);
|
|
||||||
+ r = dns_cache_remove_by_rr(c, rr);
|
|
||||||
log_debug("%s: %s",
|
|
||||||
- k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
|
|
||||||
+ r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
|
|
||||||
dns_resource_key_to_string(rr->key, key_str, sizeof key_str));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
From b974211acbe419170fc56a317a1d55d07c7cb686 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 21:18:32 +0100
|
|
||||||
Subject: [PATCH 06/12] resolved: take shortest TTL of all of RRs in answer as
|
|
||||||
cache lifetime
|
|
||||||
|
|
||||||
We nowadays cache full answer RRset combinations instead of just the
|
|
||||||
exact matching rrset. This means we should not cache RRs that are not
|
|
||||||
immediate answers to our question for longer then their own RRs. Or in
|
|
||||||
other words: let's determine the shortest TTL of all RRs in the whole
|
|
||||||
answer, and use that as cache lifetime.
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 60 +++++++++++++++++++++++---------
|
|
||||||
1 file changed, 44 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index 0f40e0e40f4..db2361ae363 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -312,13 +312,19 @@ static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t timestamp, bool use_soa_minimum) {
|
|
||||||
+static usec_t calculate_until(
|
|
||||||
+ DnsResourceRecord *rr,
|
|
||||||
+ uint32_t min_ttl,
|
|
||||||
+ uint32_t nsec_ttl,
|
|
||||||
+ usec_t timestamp,
|
|
||||||
+ bool use_soa_minimum) {
|
|
||||||
+
|
|
||||||
uint32_t ttl;
|
|
||||||
usec_t u;
|
|
||||||
|
|
||||||
assert(rr);
|
|
||||||
|
|
||||||
- ttl = MIN(rr->ttl, nsec_ttl);
|
|
||||||
+ ttl = MIN(min_ttl, nsec_ttl);
|
|
||||||
if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
|
|
||||||
/* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
|
|
||||||
* when we do negative caching, to determine the TTL for the negative caching entry. See RFC
|
|
||||||
@@ -351,6 +357,7 @@ static void dns_cache_item_update_positive(
|
|
||||||
DnsResourceRecord *rr,
|
|
||||||
DnsAnswer *answer,
|
|
||||||
DnsPacket *full_packet,
|
|
||||||
+ uint32_t min_ttl,
|
|
||||||
uint64_t query_flags,
|
|
||||||
bool shared_owner,
|
|
||||||
DnssecResult dnssec_result,
|
|
||||||
@@ -387,7 +394,7 @@ static void dns_cache_item_update_positive(
|
|
||||||
dns_packet_unref(i->full_packet);
|
|
||||||
i->full_packet = full_packet;
|
|
||||||
|
|
||||||
- i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
|
|
||||||
+ i->until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false);
|
|
||||||
i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
|
|
||||||
i->shared_owner = shared_owner;
|
|
||||||
i->dnssec_result = dnssec_result;
|
|
||||||
@@ -414,8 +421,9 @@ static int dns_cache_put_positive(
|
|
||||||
const union in_addr_union *owner_address) {
|
|
||||||
|
|
||||||
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
|
|
||||||
- DnsCacheItem *existing;
|
|
||||||
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
|
|
||||||
+ DnsCacheItem *existing;
|
|
||||||
+ uint32_t min_ttl;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
@@ -428,8 +436,15 @@ static int dns_cache_put_positive(
|
|
||||||
if (dns_type_is_pseudo(rr->key->type))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
+ /* Determine the minimal TTL of all RRs in the answer plus the one by the main RR we are supposed to
|
|
||||||
+ * cache. Since we cache whole answers to questions we should never return answers where only some
|
|
||||||
+ * RRs are still valid, hence find the lowest here */
|
|
||||||
+ min_ttl = dns_answer_min_ttl(answer);
|
|
||||||
+ if (rr)
|
|
||||||
+ min_ttl = MIN(min_ttl, rr->ttl);
|
|
||||||
+
|
|
||||||
/* New TTL is 0? Delete this specific entry... */
|
|
||||||
- if (rr->ttl <= 0) {
|
|
||||||
+ if (min_ttl <= 0) {
|
|
||||||
r = dns_cache_remove_by_rr(c, rr);
|
|
||||||
log_debug("%s: %s",
|
|
||||||
r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
|
|
||||||
@@ -446,6 +461,7 @@ static int dns_cache_put_positive(
|
|
||||||
rr,
|
|
||||||
answer,
|
|
||||||
full_packet,
|
|
||||||
+ min_ttl,
|
|
||||||
query_flags,
|
|
||||||
shared_owner,
|
|
||||||
dnssec_result,
|
|
||||||
@@ -473,7 +489,7 @@ static int dns_cache_put_positive(
|
|
||||||
.rr = dns_resource_record_ref(rr),
|
|
||||||
.answer = dns_answer_ref(answer),
|
|
||||||
.full_packet = dns_packet_ref(full_packet),
|
|
||||||
- .until = calculate_until(rr, UINT32_MAX, timestamp, false),
|
|
||||||
+ .until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false),
|
|
||||||
.query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
|
|
||||||
.shared_owner = shared_owner,
|
|
||||||
.dnssec_result = dnssec_result,
|
|
||||||
@@ -575,9 +591,12 @@ static int dns_cache_put_negative(
|
|
||||||
.full_packet = dns_packet_ref(full_packet),
|
|
||||||
};
|
|
||||||
|
|
||||||
+ /* Determine how long to cache this entry. In case we have some RRs in the answer use the lowest TTL
|
|
||||||
+ * of any of them. Typically that's the SOA's TTL, which is OK, but could possibly be lower because
|
|
||||||
+ * of some other RR. Let's better take the lowest option here than a needlessly high one */
|
|
||||||
i->until =
|
|
||||||
i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
|
|
||||||
- calculate_until(soa, nsec_ttl, timestamp, true);
|
|
||||||
+ calculate_until(soa, dns_answer_min_ttl(answer), nsec_ttl, timestamp, true);
|
|
||||||
|
|
||||||
if (i->type == DNS_CACHE_NXDOMAIN) {
|
|
||||||
/* NXDOMAIN entries should apply equally to all types, so we use ANY as
|
|
||||||
@@ -1046,21 +1065,30 @@ int dns_cache_lookup(
|
|
||||||
DnsAnswerItem *item;
|
|
||||||
|
|
||||||
DNS_ANSWER_FOREACH_ITEM(item, j->answer) {
|
|
||||||
- r = answer_add_clamp_ttl(&answer, item->rr, item->ifindex, item->flags, item->rrsig, query_flags, j->until, current);
|
|
||||||
+ r = answer_add_clamp_ttl(
|
|
||||||
+ &answer,
|
|
||||||
+ item->rr,
|
|
||||||
+ item->ifindex,
|
|
||||||
+ item->flags,
|
|
||||||
+ item->rrsig,
|
|
||||||
+ query_flags,
|
|
||||||
+ j->until,
|
|
||||||
+ current);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (j->rr) {
|
|
||||||
- r = answer_add_clamp_ttl(&answer,
|
|
||||||
- j->rr,
|
|
||||||
- j->ifindex,
|
|
||||||
- FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
|
|
||||||
- NULL,
|
|
||||||
- query_flags,
|
|
||||||
- j->until,
|
|
||||||
- current);
|
|
||||||
+ r = answer_add_clamp_ttl(
|
|
||||||
+ &answer,
|
|
||||||
+ j->rr,
|
|
||||||
+ j->ifindex,
|
|
||||||
+ FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
|
|
||||||
+ NULL,
|
|
||||||
+ query_flags,
|
|
||||||
+ j->until,
|
|
||||||
+ current);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
From a1acc6e332b05f6a5167bf9d0bc0657794e1342c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 21:18:52 +0100
|
|
||||||
Subject: [PATCH 07/12] resolved: let's tweak how we calculate TTL left
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
When responding from DNS cache, let's slightly tweak how the TTL is
|
|
||||||
lowered: as before let's round down when converting from our internal µs
|
|
||||||
to the external seconds. (This is preferable, since records should
|
|
||||||
better be cached too short instead of too long.) Let's avoid rounding
|
|
||||||
down to zero though, since that has special semantics in many cases (in
|
|
||||||
particular mDNS). Let's just use 1s in that case.
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-cache.c | 13 +++++++++++--
|
|
||||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
|
|
||||||
index db2361ae363..9b2e7115c0a 100644
|
|
||||||
--- a/src/resolve/resolved-dns-cache.c
|
|
||||||
+++ b/src/resolve/resolved-dns-cache.c
|
|
||||||
@@ -937,9 +937,18 @@ static int answer_add_clamp_ttl(
|
|
||||||
assert(rr);
|
|
||||||
|
|
||||||
if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
|
|
||||||
+ uint32_t left_ttl;
|
|
||||||
+
|
|
||||||
+ /* Let's determine how much time is left for this cache entry. Note that we round down, but
|
|
||||||
+ * clamp this to be 1s at minimum, since we usually want records to remain cached better too
|
|
||||||
+ * short a time than too long a time, but otoh don't want to return 0 ever, since that has
|
|
||||||
+ * special semantics in various contexts — in particular in mDNS */
|
|
||||||
+
|
|
||||||
+ left_ttl = MAX(1U, LESS_BY(until, current) / USEC_PER_SEC);
|
|
||||||
+
|
|
||||||
patched = dns_resource_record_ref(rr);
|
|
||||||
|
|
||||||
- r = dns_resource_record_clamp_ttl(&patched, LESS_BY(until, current) / USEC_PER_SEC);
|
|
||||||
+ r = dns_resource_record_clamp_ttl(&patched, left_ttl);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
@@ -947,7 +956,7 @@ static int answer_add_clamp_ttl(
|
|
||||||
|
|
||||||
if (rrsig) {
|
|
||||||
patched_rrsig = dns_resource_record_ref(rrsig);
|
|
||||||
- r = dns_resource_record_clamp_ttl(&patched_rrsig, LESS_BY(until, current) / USEC_PER_SEC);
|
|
||||||
+ r = dns_resource_record_clamp_ttl(&patched_rrsig, left_ttl);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
|
|
||||||
From c4d98c3acc5901fad4a9a8e2ecd7cf9ad7b8ecb0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 21:36:42 +0100
|
|
||||||
Subject: [PATCH 08/12] resolved: use DNS_ANSWER_MASK_SECTIONS where
|
|
||||||
appropriate
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-stub.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index 8e781dd7389..f8d4767e536 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -275,7 +275,7 @@ static int dns_stub_collect_answer_by_section(
|
|
||||||
dns_type_is_dnssec(item->rr->key->type))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
|
|
||||||
+ if (((item->flags ^ section) & DNS_ANSWER_MASK_SECTIONS) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
r = reply_add_with_rrsig(
|
|
||||||
|
|
||||||
From 567aa5c87b4a177cd4a6ef3ed8d6814839a4ffd8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 22:14:43 +0100
|
|
||||||
Subject: [PATCH 09/12] resolved: show TTLs in answer dump
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-answer.c | 5 ++---
|
|
||||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
|
|
||||||
index 5fbff81c255..a032ac157e0 100644
|
|
||||||
--- a/src/resolve/resolved-dns-answer.c
|
|
||||||
+++ b/src/resolve/resolved-dns-answer.c
|
|
||||||
@@ -879,9 +879,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fputs(t, f);
|
|
||||||
-
|
|
||||||
- if (item->ifindex != 0 || item->rrsig || item->flags != 0)
|
|
||||||
- fputs("\t;", f);
|
|
||||||
+ fputs("\t;", f);
|
|
||||||
+ fprintf(f, " ttl=%" PRIu32, item->rr->ttl);
|
|
||||||
|
|
||||||
if (item->ifindex != 0)
|
|
||||||
fprintf(f, " ifindex=%i", item->ifindex);
|
|
||||||
|
|
||||||
From 1414b67e0d9515c23221cecbb5323d45ea2020b1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 22:15:06 +0100
|
|
||||||
Subject: [PATCH 10/12] resolved: add helper for dumping DnsQuestion, similar
|
|
||||||
to what we have for DnsAnswer
|
|
||||||
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-question.c | 18 ++++++++++++++++++
|
|
||||||
src/resolve/resolved-dns-question.h | 2 ++
|
|
||||||
2 files changed, 20 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
|
|
||||||
index 047170899db..ef409326304 100644
|
|
||||||
--- a/src/resolve/resolved-dns-question.c
|
|
||||||
+++ b/src/resolve/resolved-dns-question.c
|
|
||||||
@@ -445,3 +445,21 @@ int dns_question_new_service(
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * This function is not used in the code base, but is useful when debugging. Do not delete.
|
|
||||||
+ */
|
|
||||||
+void dns_question_dump(DnsQuestion *question, FILE *f) {
|
|
||||||
+ DnsResourceKey *k;
|
|
||||||
+
|
|
||||||
+ if (!f)
|
|
||||||
+ f = stdout;
|
|
||||||
+
|
|
||||||
+ DNS_QUESTION_FOREACH(k, question) {
|
|
||||||
+ char buf[DNS_RESOURCE_KEY_STRING_MAX];
|
|
||||||
+
|
|
||||||
+ fputc('\t', f);
|
|
||||||
+ fputs(dns_resource_key_to_string(k, buf, sizeof(buf)), f);
|
|
||||||
+ fputc('\n', f);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
|
|
||||||
index a6444b0baf9..8f9a84c82d9 100644
|
|
||||||
--- a/src/resolve/resolved-dns-question.h
|
|
||||||
+++ b/src/resolve/resolved-dns-question.h
|
|
||||||
@@ -33,6 +33,8 @@ int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
|
|
||||||
|
|
||||||
int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret);
|
|
||||||
|
|
||||||
+void dns_question_dump(DnsQuestion *q, FILE *f);
|
|
||||||
+
|
|
||||||
const char *dns_question_first_name(DnsQuestion *q);
|
|
||||||
|
|
||||||
static inline size_t dns_question_size(DnsQuestion *q) {
|
|
||||||
|
|
||||||
From a7c0291c104cdd9d5ae2fe3c5855273bbadae13e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 22:15:18 +0100
|
|
||||||
Subject: [PATCH 11/12] resolved: match CNAME replies to right question
|
|
||||||
|
|
||||||
Previously by mistake we'd always match every single reply we get in a
|
|
||||||
CNAME chain to the original question from the stub client. That's
|
|
||||||
broken, we need to test it against the CNAME query we are currently
|
|
||||||
looking at.
|
|
||||||
|
|
||||||
The effect of this incorrect matching was that we'd assign the RRs to
|
|
||||||
the wrong section since we'd assume they'd be auxiliary answers instead
|
|
||||||
of primary answers.
|
|
||||||
|
|
||||||
Fixes: #18972
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-stub.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
|
|
||||||
index f8d4767e536..b6d14b9305e 100644
|
|
||||||
--- a/src/resolve/resolved-dns-stub.c
|
|
||||||
+++ b/src/resolve/resolved-dns-stub.c
|
|
||||||
@@ -761,7 +761,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
|
|
||||||
* and keep adding all RRs in the CNAME chain. */
|
|
||||||
r = dns_stub_assign_sections(
|
|
||||||
q,
|
|
||||||
- q->request_packet->question,
|
|
||||||
+ dns_query_question_for_protocol(q, DNS_PROTOCOL_DNS),
|
|
||||||
dns_stub_reply_with_edns0_do(q));
|
|
||||||
if (r < 0) {
|
|
||||||
log_debug_errno(r, "Failed to assign sections: %m");
|
|
||||||
|
|
||||||
From b1eea703e01da1e280e179fb119449436a0c9b8e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lennart Poettering <lennart@poettering.net>
|
|
||||||
Date: Mon, 15 Mar 2021 23:26:46 +0100
|
|
||||||
Subject: [PATCH 12/12] resolved: don't flush answer RRs on CNAME redirect too
|
|
||||||
early
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
When doing a CNAME/DNAME redirect let's first check if the answer we
|
|
||||||
already have fully answers the redirected question already. If so, let's
|
|
||||||
use that. If not, let's properly restart things.
|
|
||||||
|
|
||||||
This simply removes one call to dns_answer_reset() that was placed too
|
|
||||||
early: instead of resetting when we detect a CNAME/DNAME redirect, do so
|
|
||||||
only after checking if the answer we already have doesn't match the
|
|
||||||
reply, and then decide to *actually* follow it. Or in other words: rely
|
|
||||||
on the dns_answer_reset() call in dns_query_go() which we'll call to
|
|
||||||
actually begin with the redirected question.
|
|
||||||
|
|
||||||
This fixes an optimization path which was broken back in 7820b320eaa608748f66f8105621640cf80e483a.
|
|
||||||
|
|
||||||
(This doesn't really matter as much as one might think, since our cache
|
|
||||||
stepped in anyway and answered the questions before going back to the
|
|
||||||
network. However, this adds noise if RRs with very short TTLs are cached
|
|
||||||
– which some CDNs do – and is of course relavant when people turn off
|
|
||||||
the local cache.)
|
|
||||||
---
|
|
||||||
src/resolve/resolved-dns-query.c | 7 ++++---
|
|
||||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
|
|
||||||
index aa9d65d4a82..e4386c402ac 100644
|
|
||||||
--- a/src/resolve/resolved-dns-query.c
|
|
||||||
+++ b/src/resolve/resolved-dns-query.c
|
|
||||||
@@ -1019,7 +1019,9 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
|
|
||||||
q->question_utf8 = TAKE_PTR(nq_utf8);
|
|
||||||
|
|
||||||
dns_query_unref_candidates(q);
|
|
||||||
- dns_query_reset_answer(q);
|
|
||||||
+
|
|
||||||
+ /* Note that we do *not* reset the answer here, because the answer we previously got might already
|
|
||||||
+ * include everything we need, let's check that first */
|
|
||||||
|
|
||||||
q->state = DNS_TRANSACTION_NULL;
|
|
||||||
|
|
||||||
@@ -1069,8 +1071,7 @@ int dns_query_process_cname(DnsQuery *q) {
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
- /* Let's see if the answer can already answer the new
|
|
||||||
- * redirected question */
|
|
||||||
+ /* Let's see if the answer can already answer the new redirected question */
|
|
||||||
r = dns_query_process_cname(q);
|
|
||||||
if (r != DNS_QUERY_NOMATCH)
|
|
||||||
return r;
|
|
@ -1,102 +0,0 @@
|
|||||||
From 9cc6a94790eecfc808335b759355a4005d66f6e3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Jonathan G. Underwood" <jonathan.underwood@gmail.com>
|
|
||||||
Date: Tue, 22 Dec 2020 20:04:52 +0000
|
|
||||||
Subject: [PATCH] cryptsetup: add support for workqueue options
|
|
||||||
|
|
||||||
This commit adds support for disabling the read and write
|
|
||||||
workqueues with the new crypttab options no-read-workqueue
|
|
||||||
and no-write-workqueue. These correspond to the cryptsetup
|
|
||||||
options --perf-no_read_workqueue and --perf-no_write_workqueue
|
|
||||||
respectively.
|
|
||||||
---
|
|
||||||
man/crypttab.xml | 19 +++++++++++++++++++
|
|
||||||
src/cryptsetup/cryptsetup.c | 12 ++++++++++++
|
|
||||||
src/shared/cryptsetup-util.h | 8 ++++++++
|
|
||||||
3 files changed, 39 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/man/crypttab.xml b/man/crypttab.xml
|
|
||||||
index 2062a5b8e70..72fe2e692da 100644
|
|
||||||
--- a/man/crypttab.xml
|
|
||||||
+++ b/man/crypttab.xml
|
|
||||||
@@ -342,6 +342,25 @@
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term><option>no-read-workqueue</option></term>
|
|
||||||
+
|
|
||||||
+ <listitem><para>Bypass dm-crypt internal workqueue and process read requests synchronously. The
|
|
||||||
+ default is to queue these requests and process them asynchronously.</para>
|
|
||||||
+
|
|
||||||
+ <para>This requires kernel 5.9 or newer.</para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term><option>no-write-workqueue</option></term>
|
|
||||||
+
|
|
||||||
+ <listitem><para>Bypass dm-crypt internal workqueue and process write requests synchronously. The
|
|
||||||
+ default is to queue these requests and process them asynchronously.</para>
|
|
||||||
+
|
|
||||||
+ <para>This requires kernel 5.9 or newer.</para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>skip=</option></term>
|
|
||||||
|
|
||||||
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
|
|
||||||
index 7b21a7457a1..65cbd1aec83 100644
|
|
||||||
--- a/src/cryptsetup/cryptsetup.c
|
|
||||||
+++ b/src/cryptsetup/cryptsetup.c
|
|
||||||
@@ -60,6 +60,8 @@ static bool arg_verify = false;
|
|
||||||
static bool arg_discards = false;
|
|
||||||
static bool arg_same_cpu_crypt = false;
|
|
||||||
static bool arg_submit_from_crypt_cpus = false;
|
|
||||||
+static bool arg_no_read_workqueue = false;
|
|
||||||
+static bool arg_no_write_workqueue = false;
|
|
||||||
static bool arg_tcrypt_hidden = false;
|
|
||||||
static bool arg_tcrypt_system = false;
|
|
||||||
static bool arg_tcrypt_veracrypt = false;
|
|
||||||
@@ -236,6 +238,10 @@ static int parse_one_option(const char *option) {
|
|
||||||
arg_same_cpu_crypt = true;
|
|
||||||
else if (streq(option, "submit-from-crypt-cpus"))
|
|
||||||
arg_submit_from_crypt_cpus = true;
|
|
||||||
+ else if (streq(option, "no-read-workqueue"))
|
|
||||||
+ arg_no_read_workqueue = true;
|
|
||||||
+ else if (streq(option, "no-write-workqueue"))
|
|
||||||
+ arg_no_write_workqueue = true;
|
|
||||||
else if (streq(option, "luks"))
|
|
||||||
arg_type = ANY_LUKS;
|
|
||||||
/* since cryptsetup 2.3.0 (Feb 2020) */
|
|
||||||
@@ -1352,6 +1358,12 @@ static uint32_t determine_flags(void) {
|
|
||||||
if (arg_submit_from_crypt_cpus)
|
|
||||||
flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
|
||||||
|
|
||||||
+ if (arg_no_read_workqueue)
|
|
||||||
+ flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
|
|
||||||
+
|
|
||||||
+ if (arg_no_write_workqueue)
|
|
||||||
+ flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
|
|
||||||
+
|
|
||||||
#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
|
|
||||||
/* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
|
|
||||||
/* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
|
|
||||||
diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h
|
|
||||||
index fa2d2f65f3c..afac5cd46bd 100644
|
|
||||||
--- a/src/shared/cryptsetup-util.h
|
|
||||||
+++ b/src/shared/cryptsetup-util.h
|
|
||||||
@@ -7,6 +7,14 @@
|
|
||||||
#if HAVE_LIBCRYPTSETUP
|
|
||||||
#include <libcryptsetup.h>
|
|
||||||
|
|
||||||
+/* These next two are defined in libcryptsetup.h from cryptsetup version 2.3.4 forwards. */
|
|
||||||
+#ifndef CRYPT_ACTIVATE_NO_READ_WORKQUEUE
|
|
||||||
+#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
|
|
||||||
+#endif
|
|
||||||
+#ifndef CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE
|
|
||||||
+#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
extern int (*sym_crypt_activate_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size, uint32_t flags);
|
|
||||||
#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
|
|
||||||
extern int (*sym_crypt_activate_by_signed_key)(struct crypt_device *cd, const char *name, const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size, uint32_t flags);
|
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (systemd-248-rc3.tar.gz) = f9c2f47a6ee817a47c7efb7d3de5330e245e144ae1bf488722807888c884179c44f4fefd031cf2963678f1d752568876de057db53acfe874674de4072f78d084
|
SHA512 (systemd-248-rc4.tar.gz) = 022e8aabdc84c45ea06928c7b373c13f99d78fd808d9c07d3cd79dae5a2356f70d012eafbc749a588ddfcc2b1d0155f65f33ee240c4f15190d16f784803ffeac
|
||||||
|
13
systemd.spec
13
systemd.spec
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
Name: systemd
|
Name: systemd
|
||||||
Url: https://www.freedesktop.org/wiki/Software/systemd
|
Url: https://www.freedesktop.org/wiki/Software/systemd
|
||||||
Version: 248~rc3
|
Version: 248~rc4
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
# For a breakdown of the licensing, see README
|
# For a breakdown of the licensing, see README
|
||||||
License: LGPLv2+ and MIT and GPLv2+
|
License: LGPLv2+ and MIT and GPLv2+
|
||||||
Summary: System and Service Manager
|
Summary: System and Service Manager
|
||||||
@ -71,10 +71,6 @@ GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
# Backports of patches from upstream (0000–0499)
|
# Backports of patches from upstream (0000–0499)
|
||||||
Patch0001: 0001-Revert-sd-event-make-use-of-epoll_pwait2-for-greater.patch
|
|
||||||
# https://github.com/systemd/systemd/pull/19009
|
|
||||||
# Fixes more CNAME issues in stub resolver (#1933433)
|
|
||||||
Patch0002: 19009.patch
|
|
||||||
|
|
||||||
# Downstream-only patches (5000–9999)
|
# Downstream-only patches (5000–9999)
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1738828
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1738828
|
||||||
@ -950,6 +946,11 @@ getent passwd systemd-network &>/dev/null || useradd -r -u 192 -l -g systemd-net
|
|||||||
%files standalone-sysusers -f .file-list-standalone-sysusers
|
%files standalone-sysusers -f .file-list-standalone-sysusers
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Mar 18 2021 Yu Watanabe <yuwatana@redhat.com> - 248~rc4-1
|
||||||
|
- Latest upstream prerelease, see
|
||||||
|
https://github.com/systemd/systemd/blob/v248-rc4/NEWS.
|
||||||
|
- A bunch of documentation updates, and correctness fixes.
|
||||||
|
|
||||||
* Tue Mar 16 2021 Adam Williamson <awilliam@redhat.com> - 248~rc3-2
|
* Tue Mar 16 2021 Adam Williamson <awilliam@redhat.com> - 248~rc3-2
|
||||||
- Backport PR #19009 to fix CNAME redirect resolving some more (#1933433)
|
- Backport PR #19009 to fix CNAME redirect resolving some more (#1933433)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user