]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dnssd: don't advertise subtype PTRs to the browsing domain
authorRonan Pigott <ronan@rjp.ie>
Tue, 19 Mar 2024 08:56:03 +0000 (01:56 -0700)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 19 Mar 2024 22:47:00 +0000 (22:47 +0000)
The RFC6763 § 9 recommendation is to advertise only the two-label
service names.

Fixes: 88123aa21c26 ("dnssd: support service subtypes")
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-scope.c

index ca30508ff4c456611e87a0c3f42d37cda4c46313..2739bed41a3e56515a9e8971c5ddee492f9a9829 100644 (file)
@@ -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;
 
index 8ad4009ebf73683c16849f57fe0766c69520f4fa..156fa01873564e465a253c0d7e184daec7029a05 100644 (file)
@@ -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);
index b1ae36e3909c96cd41e7b554213955e735c2a58c..17bc8231962c78ea07706c2b8bf81d1ff85f3fcc 100644 (file)
@@ -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)