]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: create dns scopes for mDNS
authorDaniel Mack <daniel@zonque.org>
Sat, 11 Jul 2015 17:17:51 +0000 (13:17 -0400)
committerDaniel Mack <daniel@zonque.org>
Tue, 8 Dec 2015 15:41:45 +0000 (16:41 +0100)
Follow what LLMNR does, and create per-link DnsScope objects.

src/resolve/resolved-dns-scope.c
src/resolve/resolved-link.c
src/resolve/resolved-link.h
src/resolve/resolved-manager.c

index 10148cb08e3f3ce40ec4fb63b9dc26b50778b83f..eae903526b88f6489d7a353874f2894d94b6f2a2 100644 (file)
@@ -30,6 +30,7 @@
 #include "random-util.h"
 #include "resolved-dns-scope.h"
 #include "resolved-llmnr.h"
+#include "resolved-mdns.h"
 #include "socket-util.h"
 #include "strv.h"
 
@@ -164,7 +165,6 @@ int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
         union in_addr_union addr;
         int ifindex = 0, r;
         int family;
-        uint16_t port;
         uint32_t mtu;
         size_t saved_size = 0;
 
@@ -230,7 +230,6 @@ int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
                         return -EBUSY;
 
                 family = s->family;
-                port = LLMNR_PORT;
 
                 if (family == AF_INET) {
                         addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
@@ -243,7 +242,30 @@ int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
                 if (fd < 0)
                         return fd;
 
-                r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
+                r = manager_send(s->manager, fd, ifindex, family, &addr, LLMNR_PORT, p);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DNS_PROTOCOL_MDNS:
+                if (!ratelimit_test(&s->ratelimit))
+                        return -EBUSY;
+
+                family = s->family;
+
+                if (family == AF_INET) {
+                        addr.in = MDNS_MULTICAST_IPV4_ADDRESS;
+                        fd = manager_mdns_ipv4_fd(s->manager);
+                } else if (family == AF_INET6) {
+                        addr.in6 = MDNS_MULTICAST_IPV6_ADDRESS;
+                        fd = manager_mdns_ipv6_fd(s->manager);
+                } else
+                        return -EAFNOSUPPORT;
+                if (fd < 0)
+                        return fd;
+
+                r = manager_send(s->manager, fd, ifindex, family, &addr, MDNS_PORT, p);
                 if (r < 0)
                         return r;
 
index ddd9427dabdc2e37b2d6fce2af1ab422e97275ec..84100bd988e70bc0ad36320c4259c3a632ec2d4f 100644 (file)
@@ -77,6 +77,8 @@ Link *link_free(Link *l) {
         dns_scope_free(l->unicast_scope);
         dns_scope_free(l->llmnr_ipv4_scope);
         dns_scope_free(l->llmnr_ipv6_scope);
+        dns_scope_free(l->mdns_ipv4_scope);
+        dns_scope_free(l->mdns_ipv6_scope);
 
         free(l);
         return NULL;
@@ -118,6 +120,28 @@ static void link_allocate_scopes(Link *l) {
                 }
         } else
                 l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
+
+        if (link_relevant(l, AF_INET) &&
+            l->mdns_support != SUPPORT_NO &&
+            l->manager->mdns_support != SUPPORT_NO) {
+                if (!l->mdns_ipv4_scope) {
+                        r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to allocate mDNS IPv4 scope: %m");
+                }
+        } else
+                l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);
+
+        if (link_relevant(l, AF_INET6) &&
+            l->mdns_support != SUPPORT_NO &&
+            l->manager->mdns_support != SUPPORT_NO) {
+                if (!l->mdns_ipv6_scope) {
+                        r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to allocate mDNS IPv6 scope: %m");
+                }
+        } else
+                l->mdns_ipv6_scope = dns_scope_free(l->mdns_ipv6_scope);
 }
 
 void link_add_rrs(Link *l, bool force_remove) {
index 3093050c98abdf02c2deb38642c024ec81dba30a..a3b406bbc21134e7d62a9534a3f267ad14767d71 100644 (file)
@@ -72,6 +72,8 @@ struct Link {
         DnsScope *unicast_scope;
         DnsScope *llmnr_ipv4_scope;
         DnsScope *llmnr_ipv6_scope;
+        DnsScope *mdns_ipv4_scope;
+        DnsScope *mdns_ipv6_scope;
 
         char name[IF_NAMESIZE];
         uint32_t mtu;
index fc2fb4d47c79f4dc2e21e8af40bf22bae2923d49..a2677f442aec2ae1df726f8fb6cbbed3dc7094d8 100644 (file)
@@ -1031,11 +1031,25 @@ DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
         if (!l)
                 return NULL;
 
-        if (p->protocol == DNS_PROTOCOL_LLMNR) {
+        switch (p->protocol) {
+        case DNS_PROTOCOL_LLMNR:
                 if (p->family == AF_INET)
                         return l->llmnr_ipv4_scope;
                 else if (p->family == AF_INET6)
                         return l->llmnr_ipv6_scope;
+
+                break;
+
+        case DNS_PROTOCOL_MDNS:
+                if (p->family == AF_INET)
+                        return l->mdns_ipv4_scope;
+                else if (p->family == AF_INET6)
+                        return l->mdns_ipv6_scope;
+
+                break;
+
+        default:
+                break;
         }
 
         return NULL;