]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-manager.c
man: document what SIGUSR1 and SIGUSR2 do to resolved
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
index b32bad456b7f65ecc4ff4a23d58eac19d1037c53..6cf75f918338d0fc401e698f5396049d863a3967 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
 #include "random-util.h"
 #include "resolved-bus.h"
 #include "resolved-conf.h"
+#include "resolved-etc-hosts.h"
 #include "resolved-llmnr.h"
 #include "resolved-manager.h"
-#include "resolved-resolv-conf.h"
 #include "resolved-mdns.h"
+#include "resolved-resolv-conf.h"
 #include "socket-util.h"
 #include "string-table.h"
 #include "string-util.h"
@@ -205,7 +204,7 @@ static int manager_rtnl_listen(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = sd_netlink_attach_event(m->rtnl, m->event, 0);
+        r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
         if (r < 0)
                 return r;
 
@@ -285,9 +284,7 @@ static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *
                         log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
         }
 
-        r = manager_write_resolv_conf(m);
-        if (r < 0)
-                log_warning_errno(r, "Could not update resolv.conf: %m");
+        (void) manager_write_resolv_conf(m);
 
         return 0;
 }
@@ -313,6 +310,12 @@ static int manager_network_monitor_listen(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
+        if (r < 0)
+                return r;
+
+        (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
+
         return 0;
 }
 
@@ -420,6 +423,8 @@ static int manager_watch_hostname(Manager *m) {
                         return log_error_errno(r, "Failed to add hostname event source: %m");
         }
 
+        (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
+
         r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
         if (r < 0) {
                 log_info("Defaulting to hostname 'linux'.");
@@ -461,6 +466,21 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si
         return 0;
 }
 
+static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+        Manager *m = userdata;
+        DnsScope *scope;
+
+        assert(s);
+        assert(si);
+        assert(m);
+
+        LIST_FOREACH(scopes, scope, m->dns_scopes)
+                dns_cache_flush(&scope->cache);
+
+        log_info("Flushed all caches.");
+        return 0;
+}
+
 int manager_new(Manager **ret) {
         _cleanup_(manager_freep) Manager *m = NULL;
         int r;
@@ -478,9 +498,10 @@ int manager_new(Manager **ret) {
 
         m->llmnr_support = RESOLVE_SUPPORT_YES;
         m->mdns_support = RESOLVE_SUPPORT_NO;
-        m->dnssec_mode = DNSSEC_NO;
+        m->dnssec_mode = DEFAULT_DNSSEC_MODE;
         m->read_resolv_conf = true;
         m->need_builtin_fallbacks = true;
+        m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
 
         r = dns_trust_anchor_load(&m->trust_anchor);
         if (r < 0)
@@ -520,6 +541,7 @@ int manager_new(Manager **ret) {
                 return r;
 
         (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
+        (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
 
         *ret = m;
         m = NULL;
@@ -578,6 +600,7 @@ Manager *manager_free(Manager *m) {
         sd_bus_unref(m->bus);
 
         sd_event_source_unref(m->sigusr1_event_source);
+        sd_event_source_unref(m->sigusr2_event_source);
 
         sd_event_unref(m->event);
 
@@ -590,6 +613,7 @@ Manager *manager_free(Manager *m) {
         free(m->mdns_hostname);
 
         dns_trust_anchor_flush(&m->trust_anchor);
+        manager_etc_hosts_flush(m);
 
         free(m);
 
@@ -608,18 +632,16 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
         struct msghdr mh = {};
         struct cmsghdr *cmsg;
         struct iovec iov;
-        int ms = 0, r;
-        ssize_t l;
+        ssize_t ms, l;
+        int r;
 
         assert(m);
         assert(fd >= 0);
         assert(ret);
 
-        r = ioctl(fd, FIONREAD, &ms);
-        if (r < 0)
-                return -errno;
+        ms = next_datagram_size_fd(fd);
         if (ms < 0)
-                return -EIO;
+                return ms;
 
         r = dns_packet_new(&p, protocol, ms);
         if (r < 0)
@@ -636,6 +658,8 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
         mh.msg_controllen = sizeof(control);
 
         l = recvmsg(fd, &mh, 0);
+        if (l == 0)
+                return 0;
         if (l < 0) {
                 if (errno == EAGAIN || errno == EINTR)
                         return 0;
@@ -643,9 +667,6 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
                 return -errno;
         }
 
-        if (l <= 0)
-                return -EIO;
-
         assert(!(mh.msg_flags & MSG_CTRUNC));
         assert(!(mh.msg_flags & MSG_TRUNC));
 
@@ -897,7 +918,7 @@ int manager_send(Manager *m, int fd, int ifindex, int family, const union in_add
 
         if (family == AF_INET)
                 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
-        else if (family == AF_INET6)
+        if (family == AF_INET6)
                 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
 
         return -EAFNOSUPPORT;
@@ -1169,3 +1190,64 @@ int manager_compile_search_domains(Manager *m, OrderedSet **domains) {
 
         return 0;
 }
+
+DnssecMode manager_get_dnssec_mode(Manager *m) {
+        assert(m);
+
+        if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
+                return m->dnssec_mode;
+
+        return DNSSEC_NO;
+}
+
+bool manager_dnssec_supported(Manager *m) {
+        DnsServer *server;
+        Iterator i;
+        Link *l;
+
+        assert(m);
+
+        if (manager_get_dnssec_mode(m) == DNSSEC_NO)
+                return false;
+
+        server = manager_get_dns_server(m);
+        if (server && !dns_server_dnssec_supported(server))
+                return false;
+
+        HASHMAP_FOREACH(l, m->links, i)
+                if (!link_dnssec_supported(l))
+                        return false;
+
+        return true;
+}
+
+void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
+
+        assert(verdict >= 0);
+        assert(verdict < _DNSSEC_VERDICT_MAX);
+
+        if (log_get_max_level() >= LOG_DEBUG) {
+                char s[DNS_RESOURCE_KEY_STRING_MAX];
+
+                log_debug("Found verdict for lookup %s: %s",
+                          dns_resource_key_to_string(key, s, sizeof s),
+                          dnssec_verdict_to_string(verdict));
+        }
+
+        m->n_dnssec_verdict[verdict]++;
+}
+
+bool manager_routable(Manager *m, int family) {
+        Iterator i;
+        Link *l;
+
+        assert(m);
+
+        /* Returns true if the host has at least one interface with a routable address of the specified type */
+
+        HASHMAP_FOREACH(l, m->links, i)
+                if (link_relevant(l, family, false))
+                        return true;
+
+        return false;
+}