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);