From 5d5edcd3f4b85c08a5d3161b9db2d82982d4399f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 17:11:29 +0900 Subject: [PATCH 1/6] resolve: fix indentation --- 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 82f852a936..11710b8a48 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -1419,7 +1419,7 @@ int manager_dns_stub_start(Manager *m) { r == -EADDRINUSE ? "Another process is already listening on %s.\n" "Turning off local DNS stub support." : "Failed to listen on %s: %m.\n" - "Turning off local DNS stub support.", + "Turning off local DNS stub support.", busy_socket); manager_dns_stub_stop(m); break; From 450a4edfc385e03dba1fc7c03534a8bbc83835e8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 17:13:42 +0900 Subject: [PATCH 2/6] resolve: coding style fix --- src/resolve/resolved-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index d89d1dcbcd..490b57cdaf 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -829,7 +829,7 @@ int manager_start(Manager *m) { return 0; } -Manager *manager_free(Manager *m) { +Manager* manager_free(Manager *m) { Link *l; if (!m) From 872603b583814ddcd67a32c1d027589d4fba1885 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 17:45:11 +0900 Subject: [PATCH 3/6] resolve: several cleanups for manager_new() - mention the error is ignored in the log message, - drop redundant log message, as dnssd_load() logs on failure, - voidify manager_load_delegates(). --- src/resolve/resolved-manager.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 490b57cdaf..7d09851319 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -734,7 +734,7 @@ int manager_new(Manager **ret) { r = manager_parse_config_file(m); if (r < 0) - log_warning_errno(r, "Failed to parse configuration file: %m"); + log_warning_errno(r, "Failed to parse configuration file, ignoring: %m"); #if ENABLE_DNS_OVER_TLS r = dnstls_manager_init(m); @@ -756,11 +756,8 @@ int manager_new(Manager **ret) { if (r < 0) return r; - r = dnssd_load(m); - if (r < 0) - log_warning_errno(r, "Failed to load DNS-SD configuration files: %m"); - - manager_load_delegates(m); + (void) dnssd_load(m); + (void) manager_load_delegates(m); r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_GLOBAL, /* link= */ NULL, /* delegate= */ NULL, DNS_PROTOCOL_DNS, AF_UNSPEC); if (r < 0) From 9ed99b0793eac9d9af0be659dd084ddfaaef4fae Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 17:51:49 +0900 Subject: [PATCH 4/6] resolve: several cleanups for manager_dispatch_reload_signal() - set defaults after all existing configs and setups cleared, - mention failures are ignored in log messages, - drop one redundant log message, - do not return negative errno but exit event loop on critical failure. --- src/resolve/resolved-manager.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 7d09851319..7127cbfc12 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -650,44 +650,40 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa (void) notify_reloading(); - manager_set_defaults(m); - dns_server_unlink_on_reload(m->dns_servers); dns_server_unlink_on_reload(m->fallback_dns_servers); m->dns_extra_stub_listeners = ordered_set_free(m->dns_extra_stub_listeners); dnssd_service_clear_on_reload(m->dnssd_services); m->unicast_scope = dns_scope_free(m->unicast_scope); m->delegates = hashmap_free(m->delegates); - dns_trust_anchor_flush(&m->trust_anchor); + manager_set_defaults(m); + r = dns_trust_anchor_load(&m->trust_anchor); if (r < 0) - return r; + return sd_event_exit(sd_event_source_get_event(s), r); r = manager_parse_config_file(m); if (r < 0) - log_warning_errno(r, "Failed to parse config file on reload: %m"); + log_warning_errno(r, "Failed to parse configuration file on reload, ignoring: %m"); else log_info("Config file reloaded."); - r = dnssd_load(m); - if (r < 0) - log_warning_errno(r, "Failed to load DNS-SD configuration files: %m"); - - manager_load_delegates(m); + (void) dnssd_load(m); + (void) manager_load_delegates(m); /* The default scope configuration is influenced by the manager's configuration (modes, etc.), so * recreate it on reload. */ r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_GLOBAL, /* link= */ NULL, /* delegate= */ NULL, DNS_PROTOCOL_DNS, AF_UNSPEC); if (r < 0) - return r; + return sd_event_exit(sd_event_source_get_event(s), r); /* The configuration has changed, so reload the per-interface configuration too in order to take * into account any changes (e.g.: enable/disable DNSSEC). */ r = on_network_event(/* source= */ NULL, -EBADF, /* revents= */ 0, m); if (r < 0) - log_warning_errno(r, "Failed to update network information: %m"); + log_warning_errno(r, "Failed to update network information on reload, ignoring: %m"); /* We have new configuration, which means potentially new servers, so close all connections and drop * all caches, so that we can start fresh. */ From 752cdf5051d4de17864e7b2dbfec0023207a3d4e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 17:55:11 +0900 Subject: [PATCH 5/6] manager: also restart stub listner on reload Previously, the extra stub listners were stopped but new ones were not started. Also, the main stub listners were not restarted, hence the new settings were not applied. This fixes the above two issues. Note, to fix the issue, we need to keep CAP_NET_BIND_SERVICE capability to make it allow to bind stub listner later. Fixes #37843. --- src/resolve/resolved-manager.c | 5 +++++ src/resolve/resolved.c | 12 +++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 7127cbfc12..95f0cac49c 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -653,6 +653,7 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa dns_server_unlink_on_reload(m->dns_servers); dns_server_unlink_on_reload(m->fallback_dns_servers); m->dns_extra_stub_listeners = ordered_set_free(m->dns_extra_stub_listeners); + manager_dns_stub_stop(m); dnssd_service_clear_on_reload(m->dnssd_services); m->unicast_scope = dns_scope_free(m->unicast_scope); m->delegates = hashmap_free(m->delegates); @@ -691,6 +692,10 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa manager_flush_caches(m, LOG_INFO); manager_verify_all(m); + r = manager_dns_stub_start(m); + if (r < 0) + return sd_event_exit(sd_event_source_get_event(s), r); + (void) sd_notify(/* unset_environment= */ false, NOTIFY_READY_MESSAGE); return 0; } diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index 0676c4529f..ea3e6a689c 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -56,11 +56,10 @@ static int run(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Could not create runtime directory: %m"); - /* Drop privileges, but keep three caps. Note that we drop two of those too, later on (see below) */ + /* Drop privileges, but keep two caps. */ r = drop_privileges(uid, gid, - (UINT64_C(1) << CAP_NET_RAW)| /* needed for SO_BINDTODEVICE */ - (UINT64_C(1) << CAP_NET_BIND_SERVICE)| /* needed to bind on port 53 */ - (UINT64_C(1) << CAP_SETPCAP) /* needed in order to drop the caps later */); + (UINT64_C(1) << CAP_NET_RAW)| /* needed for SO_BINDTODEVICE */ + (UINT64_C(1) << CAP_NET_BIND_SERVICE)); /* needed to bind on port 53 */ if (r < 0) return log_error_errno(r, "Failed to drop privileges: %m"); } @@ -78,11 +77,6 @@ static int run(int argc, char *argv[]) { (void) manager_check_resolv_conf(m); - /* Let's drop the remaining caps now */ - r = capability_bounding_set_drop((UINT64_C(1) << CAP_NET_RAW), true); - if (r < 0) - return log_error_errno(r, "Failed to drop remaining caps: %m"); - notify_stop = notify_start(NOTIFY_READY_MESSAGE, NOTIFY_STOPPING_MESSAGE); r = sd_event_loop(m->event); From 888e3f435770568643fc97aa20b112ded94f33eb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Jun 2025 19:13:51 +0900 Subject: [PATCH 6/6] TEST-75-RESOLVED: add test case for reloading DNSStubListenerExtra= --- test/units/TEST-75-RESOLVED.sh | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 6570febe79..823e404e28 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -1003,16 +1003,39 @@ testcase_12_resolvectl2() { { echo "[Resolve]" echo "DNS=8.8.8.8" + echo "DNSStubListenerExtra=127.0.0.153" } >/run/systemd/resolved.conf.d/reload.conf resolvectl dns dns0 1.1.1.1 systemctl reload systemd-resolved.service resolvectl status - resolvectl dns dns0 | grep -qF "1.1.1.1" - # For some reason piping this last command to grep fails with: - # 'resolvectl[1378]: Failed to print table: Broken pipe' - # so use an intermediate file in /tmp/ - resolvectl >/tmp/output - grep -qF "DNS Servers: 8.8.8.8" /tmp/output + + run resolvectl dns dns0 + grep -qF "1.1.1.1" "$RUN_OUT" + + run resolvectl dns + grep -qF "8.8.8.8" "$RUN_OUT" + + run ss -4nl + grep -qF '127.0.0.153' "$RUN_OUT" + + { + echo "[Resolve]" + echo "DNS=8.8.4.4" + echo "DNSStubListenerExtra=127.0.0.154" + } >/run/systemd/resolved.conf.d/reload.conf + systemctl reload systemd-resolved.service + resolvectl status + + run resolvectl dns dns0 + grep -qF "1.1.1.1" "$RUN_OUT" + + run resolvectl dns + (! grep -qF "8.8.8.8" "$RUN_OUT") + grep -qF "8.8.4.4" "$RUN_OUT" + + run ss -4nl + (! grep -qF '127.0.0.153' "$RUN_OUT") + grep -qF '127.0.0.154' "$RUN_OUT" # Check if resolved exits cleanly. restart_resolved