From 27ea9761acbad0685410c5c68971b77db431fde6 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Mon, 31 Aug 2026 20:22:54 +0200 Subject: [PATCH] resolved: split out dnssd_registered_service_unregister() helper Move the logic that sends goodbye messages, removes a registered DNS-SD service's RRs from all mDNS zones and frees the service out of bus_dnssd_method_unregister() into a new helper. While at it, add the nowadays customary parameter comments and ", ignoring" log message suffix to the moved code. No functional change. This is preparation for unregistering services when the D-Bus client that registered them disconnects: that path needs the full teardown as well, not just dnssd_registered_service_free(), which would leave the service's RRs published in the per-link mDNS zones. --- src/resolve/resolved-dnssd-bus.c | 34 +---------------------- src/resolve/resolved-dnssd.c | 47 ++++++++++++++++++++++++++++++++ src/resolve/resolved-dnssd.h | 1 + 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c index 17eab683b7..8d648fe8b7 100644 --- a/src/resolve/resolved-dnssd-bus.c +++ b/src/resolve/resolved-dnssd-bus.c @@ -6,18 +6,14 @@ #include "bus-object.h" #include "bus-polkit.h" #include "hashmap.h" -#include "log.h" -#include "resolved-dns-scope.h" #include "resolved-dnssd.h" #include "resolved-dnssd-bus.h" -#include "resolved-link.h" #include "resolved-manager.h" #include "strv.h" int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error) { DnssdRegisteredService *s = ASSERT_PTR(userdata); Manager *m; - Link *l; int r; assert(message); @@ -38,35 +34,7 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_ if (r == 0) return 1; /* Polkit will call us back */ - HASHMAP_FOREACH(l, m->links) { - if (l->mdns_ipv4_scope) { - r = dns_scope_announce(l->mdns_ipv4_scope, true); - if (r < 0) - log_warning_errno(r, "Failed to send goodbye messages in IPv4 scope: %m"); - - dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->ptr_rr); - dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->sub_ptr_rr); - dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->srv_rr); - LIST_FOREACH(items, txt_data, s->txt_data_items) - dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, txt_data->rr); - } - - if (l->mdns_ipv6_scope) { - r = dns_scope_announce(l->mdns_ipv6_scope, true); - if (r < 0) - log_warning_errno(r, "Failed to send goodbye messages in IPv6 scope: %m"); - - dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->ptr_rr); - dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->sub_ptr_rr); - dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->srv_rr); - LIST_FOREACH(items, txt_data, s->txt_data_items) - dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, txt_data->rr); - } - } - - dnssd_registered_service_free(s); - - manager_refresh_rrs(m); + dnssd_registered_service_unregister(s); return sd_bus_reply_method_return(message, NULL); } diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index 498f975f39..39cb67fefe 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -11,10 +11,13 @@ #include "extract-word.h" #include "hashmap.h" #include "hexdecoct.h" +#include "log.h" #include "path-util.h" #include "resolved-conf.h" +#include "resolved-dns-scope.h" #include "resolved-dns-zone.h" #include "resolved-dnssd.h" +#include "resolved-link.h" #include "resolved-manager.h" #include "specifier.h" #include "string-util.h" @@ -68,6 +71,50 @@ DnssdRegisteredService *dnssd_registered_service_free(DnssdRegisteredService *se return mfree(service); } +void dnssd_registered_service_unregister(DnssdRegisteredService *service) { + Link *l; + int r; + + assert(service); + + Manager *m = ASSERT_PTR(service->manager); + + /* Takes the service out of service: sends goodbye messages for it, removes its RRs from all mDNS + * zones, and drops it from the manager. Note that this also frees the passed object. */ + + HASHMAP_FOREACH(l, m->links) { + if (l->mdns_ipv4_scope) { + r = dns_scope_announce(l->mdns_ipv4_scope, /* goodbye= */ true); + if (r < 0) + log_warning_errno(r, "Failed to send goodbye messages in IPv4 scope, ignoring: %m"); + + dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, service->ptr_rr); + dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, service->sub_ptr_rr); + dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, service->srv_rr); + LIST_FOREACH(items, txt_data, service->txt_data_items) + dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, txt_data->rr); + } + + if (l->mdns_ipv6_scope) { + r = dns_scope_announce(l->mdns_ipv6_scope, /* goodbye= */ true); + if (r < 0) + log_warning_errno(r, "Failed to send goodbye messages in IPv6 scope, ignoring: %m"); + + dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, service->ptr_rr); + dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, service->sub_ptr_rr); + dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, service->srv_rr); + LIST_FOREACH(items, txt_data, service->txt_data_items) + dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, txt_data->rr); + } + } + + /* This drops the service from the manager's hashmap, hence the subsequent refresh will not simply + * add its RRs back. */ + dnssd_registered_service_free(service); + + manager_refresh_rrs(m); +} + void dnssd_registered_service_clear_on_reload(Hashmap *services) { DnssdRegisteredService *service; diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h index aa5a80b0bd..d931b88a49 100644 --- a/src/resolve/resolved-dnssd.h +++ b/src/resolve/resolved-dnssd.h @@ -47,6 +47,7 @@ typedef struct DnssdRegisteredService { } DnssdRegisteredService; DnssdRegisteredService *dnssd_registered_service_free(DnssdRegisteredService *service); +void dnssd_registered_service_unregister(DnssdRegisteredService *service); DnssdTxtData *dnssd_txtdata_free(DnssdTxtData *txt_data); DnssdTxtData *dnssd_txtdata_free_all(DnssdTxtData *txt_data); void dnssd_registered_service_clear_on_reload(Hashmap *services);