diff --git a/NEWS b/NEWS index 84998aa28a..9d4cde0f24 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,19 @@ CHANGES WITH 262: Feature Removals and Incompatible Changes: + * DNS-SD services registered via systemd-resolved's D-Bus method + org.freedesktop.resolve1.Manager.RegisterService() are now + unregistered automatically when the client that registered them + disconnects from the bus, as originally intended and matching the + behavior of the equivalent Avahi API. Due to a bug the client + tracking never worked, and such services used to stay registered + until systemd-resolved exited (but did not survive a restart of the + daemon either). Clients must now keep their bus connection open for + as long as the service shall remain registered; one-shot + registrations, e.g. via busctl or gdbus, will be withdrawn again as + soon as the tool exits. To register a DNS-SD service independently + of a client's lifetime, use *.dnssd files, see systemd.dnssd(5). + * Meson options '-Dlibiptc=' (deprecated in v259), '-Dlibidn=', '-Drc-local=', '-Dsysvinit-path=', and '-Dsysvrcnd-path=' (deprecated in v260) have been removed. diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml index a1240cbe80..bed947f33b 100644 --- a/man/org.freedesktop.resolve1.xml +++ b/man/org.freedesktop.resolve1.xml @@ -450,6 +450,18 @@ node /org/freedesktop/resolve1 { DNS-SD SRV record. Finally, it takes an array of TXT record data. It returns an object path which may be used as handle to the registered service. + The lifetime of a service registered via this method is bound to the D-Bus connection of the + client that registered it: when the client disconnects from the bus the service is automatically + unregistered and goodbye packets are sent out, as if UnregisterService() had been + called. Clients hence must keep their bus connection open for as long as the service shall remain + registered. The registration also does not survive systemd-resolved losing its + own bus connection, in which case tracking clients is not possible anymore and all services registered + via this method are unregistered. To register a DNS-SD service independently of a client's lifetime, + use *.dnssd files, see + systemd.dnssd5. Note + that prior to version 262, due to a bug, the client's connection was not tracked and services + registered via this method stayed registered until the daemon exited. + The UnregisterService() method undoes the effect of RegisterService() and deletes a DNS-SD service previously created via IPC again. diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 53092bd6d3..650259a8c0 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1894,8 +1894,8 @@ static int dnssd_registered_service_on_bus_track(sd_bus_track *t, void *userdata assert(t); - log_debug("Client of active request vanished, destroying DNS-SD service."); - dnssd_registered_service_free(s); + log_debug("Client of DNS-SD service '%s' vanished, unregistering.", s->id); + dnssd_registered_service_unregister(s); return 0; } @@ -2063,6 +2063,10 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, if (r < 0) return r; + /* The service is unregistered automatically when the client that registered it disconnects from the + * bus, hence keep the bus track object pinned for the lifetime of the service. */ + service->bus_track = TAKE_PTR(bus_track); + service->manager = m; r = hashmap_ensure_put(&m->dnssd_registered_services, &string_hash_ops, service->id, service); diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index 5617293cb7..1d9d8f6635 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -57,6 +57,8 @@ DnssdRegisteredService *dnssd_registered_service_free(DnssdRegisteredService *se if (service->manager) hashmap_remove(service->manager->dnssd_registered_services, service->id); + sd_bus_track_unref(service->bus_track); + dns_resource_record_unref(service->ptr_rr); dns_resource_record_unref(service->sub_ptr_rr); dns_resource_record_unref(service->srv_rr); diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h index d931b88a49..d19024e972 100644 --- a/src/resolve/resolved-dnssd.h +++ b/src/resolve/resolved-dnssd.h @@ -39,6 +39,10 @@ typedef struct DnssdRegisteredService { Manager *manager; + /* Tracks the D-Bus client that registered the service, so that it can be unregistered when the + * client disconnects from the bus. Only set for services registered via D-Bus. */ + sd_bus_track *bus_track; + /* Services registered via D-Bus are not removed on reload */ ResolveConfigSource config_source;