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.
This commit is contained in:
Stefan Agner
2026-09-01 14:29:04 +02:00
parent d1697c4ff8
commit 27ea9761ac
3 changed files with 49 additions and 33 deletions
+1 -33
View File
@@ -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);
}
+47
View File
@@ -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;
+1
View File
@@ -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);