-/*-*- 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"
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;
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;
}
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;
}
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'.");
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;
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)
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;
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);
free(m->mdns_hostname);
dns_trust_anchor_flush(&m->trust_anchor);
+ manager_etc_hosts_flush(m);
free(m);
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)
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;
return -errno;
}
- if (l <= 0)
- return -EIO;
-
assert(!(mh.msg_flags & MSG_CTRUNC));
assert(!(mh.msg_flags & MSG_TRUNC));
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;
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;
+}