chiark / gitweb /
resolved: when sending fails, don't try connecting to the next DNS server if we actua...
[elogind.git] / src / resolve / resolved-manager.c
index 1b6dc8a4a3a685c7de188a0113a3d4f609db9faf..12883952b1eee1099a789e6679464e10d1e839c3 100644 (file)
@@ -77,6 +77,10 @@ static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userda
                 if (r < 0)
                         goto fail;
 
+                r = link_update_monitor(l);
+                if (r < 0)
+                        goto fail;
+
                 if (is_new)
                         log_debug("Found new link %i/%s", ifindex, l->name);
 
@@ -392,6 +396,63 @@ static int manager_watch_hostname(Manager *m) {
         return 0;
 }
 
+static void manager_llmnr_stop(Manager *m) {
+        assert(m);
+
+        m->llmnr_ipv4_udp_event_source = sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
+        m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
+
+        m->llmnr_ipv6_udp_event_source = sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
+        m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
+
+        m->llmnr_ipv4_tcp_event_source = sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
+        m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
+
+        m->llmnr_ipv6_tcp_event_source = sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
+        m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
+}
+
+static int manager_llmnr_start(Manager *m) {
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_support == SUPPORT_NO)
+                return 0;
+
+        r = manager_llmnr_ipv4_udp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        r = manager_llmnr_ipv6_udp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        r = manager_llmnr_ipv4_tcp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        r = manager_llmnr_ipv6_tcp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        return 0;
+
+eaddrinuse:
+        log_warning("There appears to be another LLMNR respondering running. Turning off LLMNR support.");
+        m->llmnr_support = SUPPORT_NO;
+        manager_llmnr_stop(m);
+        return 0;
+}
+
 int manager_new(Manager **ret) {
         _cleanup_(manager_freep) Manager *m = NULL;
         int r;
@@ -443,39 +504,35 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
-        r = manager_llmnr_ipv4_udp_fd(m);
-        if (r < 0)
-                return r;
-        r = manager_llmnr_ipv6_udp_fd(m);
-        if (r < 0)
-                return r;
-        r = manager_llmnr_ipv4_tcp_fd(m);
-        if (r < 0)
-                return r;
-        r = manager_llmnr_ipv6_tcp_fd(m);
-        if (r < 0)
-                return r;
-
         *ret = m;
         m = NULL;
 
         return 0;
 }
 
+int manager_start(Manager *m) {
+        int r;
+
+        assert(m);
+
+        r = manager_llmnr_start(m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 Manager *manager_free(Manager *m) {
         Link *l;
 
         if (!m)
                 return NULL;
 
-        while (m->dns_queries)
-                dns_query_free(m->dns_queries);
-
-        hashmap_free(m->dns_transactions);
-
         while ((l = hashmap_first(m->links)))
                link_free(l);
-        hashmap_free(m->links);
+
+        while (m->dns_queries)
+                dns_query_free(m->dns_queries);
 
         dns_scope_free(m->unicast_scope);
 
@@ -484,6 +541,9 @@ Manager *manager_free(Manager *m) {
         while (m->fallback_dns_servers)
                 dns_server_free(m->fallback_dns_servers);
 
+        hashmap_free(m->links);
+        hashmap_free(m->dns_transactions);
+
         sd_event_source_unref(m->network_event_source);
         sd_network_monitor_unref(m->network_monitor);
 
@@ -492,15 +552,7 @@ Manager *manager_free(Manager *m) {
         safe_close(m->dns_ipv4_fd);
         safe_close(m->dns_ipv6_fd);
 
-        sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
-        sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
-        safe_close(m->llmnr_ipv4_udp_fd);
-        safe_close(m->llmnr_ipv6_udp_fd);
-
-        sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
-        sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
-        safe_close(m->llmnr_ipv4_tcp_fd);
-        safe_close(m->llmnr_ipv6_tcp_fd);
+        manager_llmnr_stop(m);
 
         sd_event_source_unref(m->bus_retry_event_source);
         sd_bus_unref(m->bus);