From: Lennart Poettering Date: Tue, 14 Jul 2026 21:58:34 +0000 (+0200) Subject: resolved: fix spurious BrowseServices add/remove flapping with ifindex=0 (#42982) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e6acf0bab7d64966438538ec90fb320171432cd1;p=thirdparty%2Fsystemd.git resolved: fix spurious BrowseServices add/remove flapping with ifindex=0 (#42982) ## Problem A `BrowseServices` subscription with `"ifindex":0` (browse all interfaces) receives a continuous flap of `added`/`removed` events for a service that is still present — within a second, and with no goodbye packet involved. ## Root cause For `ifindex==0`, `mdns_browser_revisit_cache()` looked up each mDNS scope's cache separately and called `mdns_manage_services_answer()` **once per scope**. That function derives `removed` events by diffing the browser's *global* discovered-service list (all interfaces, filtered only by owner family) against the single answer it's handed. So with ≥2 mDNS-relevant interfaces of the same family, a service present on interface A isn't in interface B's answer and is spuriously removed while B is reconciled, then re-added on the next revisit tick. ## Fix Accumulate the pruned cache answers from every matching mDNS scope into one combined `DnsAnswer` and reconcile **once**, so removals diff the global list against the union across interfaces. Items are merged with `dns_answer_add_full()` (not `dns_answer_extend()`, which defaults each item's `until` to `USEC_INFINITY` and would skew the RFC 6762 §5.2 TTL-maintenance schedule). The single-interface (`ifindex>0`) path is unchanged. ## Test `TEST-89-RESOLVED-MDNS.sh` gains `testcase_browse_ifindex_zero_no_flap`: it adds a service-less dummy mDNS link to guarantee ≥2 same-family scopes (the flap precondition), browses `ifindex=0`, waits for discovery, then asserts **zero** `removed` events while every publisher stays up. The subscription uses `varlinkctl --timeout=infinity`, since it sits idle after discovery and the default 45s idle timeout would sever it (and the assertion) mid-observation. ## Testing status Builds clean; `shellcheck -x` clean. First CI round: `TEST-89` (including this testcase) passed on all mkosi platforms; the failing jobs all traced to unrelated flakes/infra. --- e6acf0bab7d64966438538ec90fb320171432cd1