]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: Track per-service item ifindex in DnssdDiscoveredService
authorChristian Glombek <c.glombek@cosa.systems>
Sun, 22 Feb 2026 22:38:59 +0000 (23:38 +0100)
committerChristian Glombek <c.glombek@cosa.systems>
Sun, 22 Feb 2026 22:38:59 +0000 (23:38 +0100)
The interface where each service was discovered needs to be remembered
so it can be correctly reported when the service is later removed.

Previously, service removal would use sb->ifindex, losing the actual
interface information from the original discovery.

This change:
- Adds an ifindex field to DnssdDiscoveredService struct
- Stores the discovered interface index when adding new services,
  preferring the per-item ifindex from DnsAnswerItem over the service
  browser's ifindex
- Uses the stored ifindex when reporting service removal events

This ensures that service removal notifications include the correct
interface index where the service was originally discovered, matching
the behavior of the corresponding service addition notifications.

Assisted-by: Claude Opus 4.6 (Eclipse Theia IDE AI)
src/resolve/resolved-dns-browse-services.c
src/resolve/resolved-dns-browse-services.h

index 6c471976393f1220755f3252971c1130639abe4a..dbb21e6f0d3a7159f779cefbf05a21feb767e8f3 100644 (file)
@@ -155,7 +155,7 @@ static int mdns_maintenance_query(sd_event_source *s, uint64_t usec, void *userd
         return 0;
 }
 
-int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_family, usec_t until) {
+int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_family, int ifindex, usec_t until) {
         _cleanup_(dnssd_discovered_service_unrefp) DnssdDiscoveredService *s = NULL;
         int r;
 
@@ -173,6 +173,7 @@ int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_
                 .service_browser = sb,
                 .rr = dns_resource_record_copy(rr),
                 .family = owner_family,
+                .ifindex = ifindex,
                 .until = until,
                 .query = NULL,
                 .rr_ttl_state = DNS_RECORD_TTL_STATE_80_PERCENT,
@@ -326,6 +327,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
         DNS_ANSWER_FOREACH_ITEM(item, answer) {
                 _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
                 _cleanup_(sd_json_variant_unrefp) sd_json_variant *entry = NULL;
+                int ifindex;
 
                 if (dns_service_match_and_update(sb->dns_services, item->rr, owner_family, item->until))
                         continue;
@@ -349,7 +351,10 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                 if (!type)
                         continue;
 
-                r = dns_add_new_service(sb, item->rr, owner_family, item->until);
+                /* Prefer the per-item ifindex, fall back to the service browser's ifindex */
+                ifindex = item->ifindex > 0 ? item->ifindex : sb->ifindex;
+
+                r = dns_add_new_service(sb, item->rr, owner_family, ifindex, item->until);
                 if (r < 0) {
                         log_error_errno(r, "Failed to add new DNS service: %m");
                         goto finish;
@@ -360,7 +365,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                           strna(type),
                           strna(domain),
                           strna(af_to_ipv4_ipv6(owner_family)),
-                          sb->ifindex);
+                          ifindex);
 
                 r = sd_json_buildo(
                                 &entry,
@@ -375,7 +380,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                                                 !isempty(type), "type", SD_JSON_BUILD_STRING(type)),
                                 SD_JSON_BUILD_PAIR_CONDITION(
                                                 !isempty(domain), "domain", SD_JSON_BUILD_STRING(domain)),
-                                SD_JSON_BUILD_PAIR_INTEGER("ifindex", sb->ifindex));
+                                SD_JSON_BUILD_PAIR_INTEGER("ifindex", ifindex));
                 if (r < 0) {
                         log_error_errno(r, "Failed to build JSON for new service: %m");
                         goto finish;
@@ -392,6 +397,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
         LIST_FOREACH(dns_services, service, sb->dns_services) {
                 _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
                 _cleanup_(sd_json_variant_unrefp) sd_json_variant *entry = NULL;
+                int ifindex;
 
                 if (service->family != owner_family)
                         continue;
@@ -416,6 +422,9 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                         }
                 }
 
+                /* Capture ifindex before removing the service */
+                ifindex = service->ifindex;
+
                 dns_remove_service(sb, service);
 
                 log_debug("Remove from the list %s, %s, %s, %s, %d",
@@ -423,7 +432,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                           strna(type),
                           strna(domain),
                           strna(af_to_ipv4_ipv6(owner_family)),
-                          sb->ifindex);
+                          ifindex);
 
                 r = sd_json_buildo(
                                 &entry,
@@ -435,7 +444,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
                                 SD_JSON_BUILD_PAIR_STRING("name", name ?: ""),
                                 SD_JSON_BUILD_PAIR_STRING("type", type ?: ""),
                                 SD_JSON_BUILD_PAIR_STRING("domain", domain ?: ""),
-                                SD_JSON_BUILD_PAIR_INTEGER("ifindex", sb->ifindex));
+                                SD_JSON_BUILD_PAIR_INTEGER("ifindex", ifindex));
                 if (r < 0) {
                         log_error_errno(r, "Failed to build JSON for removed service: %m");
                         goto finish;
index 243d23cb2db829828860b5192c5de31c916f55f5..424b2855a5b750f5776551cb1b2f952a09872319 100644 (file)
@@ -30,6 +30,7 @@ struct DnssdDiscoveredService {
         sd_event_source *schedule_event;
         DnsResourceRecord *rr;
         int family;
+        int ifindex;
         usec_t until;
         DnsRecordTTLState rr_ttl_state;
         DnsQuery *query;
@@ -66,7 +67,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdDiscoveredService *, dnssd_discovered_service_u
 
 bool dns_service_match_and_update(DnssdDiscoveredService *services, DnsResourceRecord *rr, int owner_family, usec_t until);
 int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int owner_family);
-int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_family, usec_t until);
+int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_family, int ifindex, usec_t until);
 int mdns_service_update(DnssdDiscoveredService *service, DnsResourceRecord *rr, usec_t t, usec_t until);
 int mdns_browser_revisit_cache(DnsServiceBrowser *sb, int owner_family);
 int dns_subscribe_browse_service(