]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-manager.c
resolved: fix error propagation
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
index 31f042e066b6be5125e89985ec82c82453c49254..b32bad456b7f65ecc4ff4a23d58eac19d1037c53 100644 (file)
@@ -40,6 +40,7 @@
 #include "resolved-llmnr.h"
 #include "resolved-manager.h"
 #include "resolved-resolv-conf.h"
+#include "resolved-mdns.h"
 #include "socket-util.h"
 #include "string-table.h"
 #include "string-util.h"
@@ -193,7 +194,7 @@ fail:
 }
 
 static int manager_rtnl_listen(Manager *m) {
-        _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
         sd_netlink_message *i;
         int r;
 
@@ -351,7 +352,7 @@ static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
                 return -EINVAL;
         }
 
-        r = dns_label_escape(label, r, &n);
+        r = dns_label_escape_new(label, r, &n);
         if (r < 0)
                 return log_error_errno(r, "Failed to escape host name: %m");
 
@@ -472,12 +473,23 @@ int manager_new(Manager **ret) {
 
         m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
         m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
+        m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
         m->hostname_fd = -1;
 
-        m->llmnr_support = SUPPORT_YES;
+        m->llmnr_support = RESOLVE_SUPPORT_YES;
+        m->mdns_support = RESOLVE_SUPPORT_NO;
+        m->dnssec_mode = DNSSEC_NO;
         m->read_resolv_conf = true;
         m->need_builtin_fallbacks = true;
 
+        r = dns_trust_anchor_load(&m->trust_anchor);
+        if (r < 0)
+                return r;
+
+        r = manager_parse_config_file(m);
+        if (r < 0)
+                return r;
+
         r = sd_event_default(&m->event);
         if (r < 0)
                 return r;
@@ -524,6 +536,10 @@ int manager_start(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = manager_mdns_start(m);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
@@ -555,6 +571,7 @@ Manager *manager_free(Manager *m) {
         sd_event_source_unref(m->rtnl_event_source);
 
         manager_llmnr_stop(m);
+        manager_mdns_stop(m);
 
         sd_bus_slot_unref(m->prepare_for_sleep_slot);
         sd_event_source_unref(m->bus_retry_event_source);
@@ -572,6 +589,8 @@ Manager *manager_free(Manager *m) {
         free(m->llmnr_hostname);
         free(m->mdns_hostname);
 
+        dns_trust_anchor_flush(&m->trust_anchor);
+
         free(m);
 
         return NULL;
@@ -759,7 +778,7 @@ static int write_loop(int fd, void *message, size_t length) {
 int manager_write(Manager *m, int fd, DnsPacket *p) {
         int r;
 
-        log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
+        log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
 
         r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
         if (r < 0)
@@ -874,7 +893,7 @@ int manager_send(Manager *m, int fd, int ifindex, int family, const union in_add
         assert(port > 0);
         assert(p);
 
-        log_debug("Sending %s packet with id %u on interface %i/%s", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
+        log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
 
         if (family == AF_INET)
                 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
@@ -1018,11 +1037,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;
@@ -1055,9 +1088,84 @@ int manager_is_own_hostname(Manager *m, const char *name) {
         return 0;
 }
 
-static const char* const support_table[_SUPPORT_MAX] = {
-        [SUPPORT_NO] = "no",
-        [SUPPORT_YES] = "yes",
-        [SUPPORT_RESOLVE] = "resolve",
-};
-DEFINE_STRING_TABLE_LOOKUP(support, Support);
+int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
+        DnsServer *s;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(m);
+        assert(dns);
+
+        r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
+        if (r < 0)
+                return r;
+
+        /* First add the system-wide servers and domains */
+        LIST_FOREACH(servers, s, m->dns_servers) {
+                r = ordered_set_put(*dns, s);
+                if (r == -EEXIST)
+                        continue;
+                if (r < 0)
+                        return r;
+        }
+
+        /* Then, add the per-link servers */
+        HASHMAP_FOREACH(l, m->links, i) {
+                LIST_FOREACH(servers, s, l->dns_servers) {
+                        r = ordered_set_put(*dns, s);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        /* If we found nothing, add the fallback servers */
+        if (ordered_set_isempty(*dns)) {
+                LIST_FOREACH(servers, s, m->fallback_dns_servers) {
+                        r = ordered_set_put(*dns, s);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+int manager_compile_search_domains(Manager *m, OrderedSet **domains) {
+        DnsSearchDomain *d;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(m);
+        assert(domains);
+
+        r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
+        if (r < 0)
+                return r;
+
+        LIST_FOREACH(domains, d, m->search_domains) {
+                r = ordered_set_put(*domains, d->name);
+                if (r == -EEXIST)
+                        continue;
+                if (r < 0)
+                        return r;
+        }
+
+        HASHMAP_FOREACH(l, m->links, i) {
+
+                LIST_FOREACH(domains, d, l->search_domains) {
+                        r = ordered_set_put(*domains, d->name);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}