resolved: actually unregister DNS-SD services when the D-Bus client vanishes (#43578)
Since the D-Bus DNS-SD API was introduced in c3036641f0ed (v236), `RegisterService()` has created an `sd_bus_track` object to destroy the registered service when the registering client disconnects from the bus. However, the track object is a `_cleanup_(sd_bus_track_unrefp)` local in `bus_method_register_service()` that is never stored anywhere, so it is destroyed again as soon as the method handler returns. The vanish handler (`dnssd_registered_service_on_bus_track()`) has thus been dead code for the past ~8 years. The observable effect: services registered via D-Bus silently persist after the client disconnects — unowned, advertised until resolved exits, and impossible to re-register since the identifier stays taken (`DNSSD_SERVICE_EXISTS`). At the same time, the registration doesn't survive a resolved restart, so the current behavior is neither reliably ephemeral nor reliably persistent. Noticed while reviewing a project that (unknowingly relying on this bug) registers a service with a one-shot `gdbus call` and expects it to persist. This PR: 1. splits the goodbye/zone-removal logic out of `bus_dnssd_method_unregister()` into a helper — the vanish path needs the full teardown, not just `dnssd_registered_service_free()`, which would leave the service's RRs published in the per-link mDNS zones; 2. stores the track object in `DnssdRegisteredService`, making client tracking work as originally intended; 3. documents the lifetime semantics in `org.freedesktop.resolve1(5)` (matching the equivalent Avahi D-Bus API, whose entry groups are likewise bound to the client connection) and points to `*.dnssd` files for registrations independent of a client's lifetime; 4. adds a TEST-75 case covering the connection-bound lifetime. Note this is a behavioral change for fire-and-forget clients (one-shot `busctl`/`gdbus` invocations). Arguably those were never working reliably (registrations silently vanished on any resolved restart, and stale entries blocked re-registration), but if this is deemed too risky, the alternative would be to drop the dead tracking code and codify the persist-until-exit behavior instead — I'd argue tracking as originally intended is the better contract. Verification: code compiles; the new integration test is included.
This commit is contained in:
@@ -4,6 +4,19 @@ CHANGES WITH 262 in spe:
|
||||
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user