From: Ronan Pigott Date: Tue, 19 Mar 2024 08:56:03 +0000 (-0700) Subject: dnssd: don't advertise subtype PTRs to the browsing domain X-Git-Tag: v256-rc1~472 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd40efc671e9bfbefb70e409afc2fab62948ae1f;p=thirdparty%2Fsystemd.git dnssd: don't advertise subtype PTRs to the browsing domain The RFC6763 § 9 recommendation is to advertise only the two-label service names. Fixes: 88123aa21c26 ("dnssd: support service subtypes") --- diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index ca30508ff4c..2739bed41a3 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -182,6 +182,23 @@ bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key) { dns_name_endswith(dns_resource_key_name(key), "_udp.local"); } +bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key) { + assert(key); + + /* Check if this is a PTR resource key used in Service Instance + * Enumeration as described in RFC6763 § 4.1, excluding selective + * service names described in RFC6763 § 7.1. */ + + if (key->type != DNS_TYPE_PTR) + return false; + + const char *name = dns_resource_key_name(key); + if (dns_name_parent(&name) <= 0) + return false; + + return dns_name_equal(name, "_tcp.local") || dns_name_equal(name, "_udp.local"); +} + int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) { int r; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 8ad4009ebf7..156fa018735 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -334,6 +334,7 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key); const char* dns_resource_key_name(const DnsResourceKey *key); bool dns_resource_key_is_address(const DnsResourceKey *key); bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key); +bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key); int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b); int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain); int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain); diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index b1ae36e3909..17bc8231962 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -1504,9 +1504,10 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) { continue; } - /* Collect service types for _services._dns-sd._udp.local RRs in a set */ + /* Collect service types for _services._dns-sd._udp.local RRs in a set. Only two-label names + * (not selective names) are considered according to RFC6763 § 9. */ if (!scope->announced && - dns_resource_key_is_dnssd_ptr(z->rr->key)) { + dns_resource_key_is_dnssd_two_label_ptr(z->rr->key)) { if (!set_contains(types, dns_resource_key_name(z->rr->key))) { r = set_ensure_put(&types, &dns_name_hash_ops, dns_resource_key_name(z->rr->key)); if (r < 0)