resolved-manager.c revision 2d8950384f3137aafcce22b29912b2b61e6d86fb
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering This file is part of systemd.
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering Copyright 2014 Tom Gundersen <teg@jklm.no>
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering (at your option) any later version.
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering systemd is distributed in the hope that it will be useful, but
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering Lesser General Public License for more details.
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
4ad490007b70e6ac18d3cb04fa2ed92eba1451faLennart Poetteringstatic int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering r = sd_netlink_message_get_type(mm, &type);
goto fail;
goto fail;
switch (type) {
case RTM_NEWLINK:{
bool is_new = !l;
goto fail;
goto fail;
r = link_update_monitor(l);
goto fail;
if (is_new)
case RTM_DELLINK:
link_free(l);
fail:
LinkAddress *a;
Link *l;
assert(m);
goto fail;
goto fail;
goto fail;
switch (family) {
case AF_INET:
goto fail;
case AF_INET6:
goto fail;
switch (type) {
case RTM_NEWADDR:
case RTM_DELADDR:
fail:
assert(m);
Iterator i;
Link *l;
assert(m);
r = link_update_monitor(l);
r = manager_write_resolv_conf(m);
assert(m);
if (fd < 0)
return fd;
if (events < 0)
return events;
h = gethostname_malloc();
return log_oom();
return -EINVAL;
return -EINVAL;
if (is_localhost(n)) {
return -EINVAL;
*llmnr_hostname = n;
n = NULL;
assert(m);
assert(m);
if (m->hostname_fd < 0) {
if (r == -EPERM)
if (!m->llmnr_hostname)
return log_oom();
if (!m->mdns_hostname)
return log_oom();
assert(s);
assert(m);
return log_oom();
if (fflush_and_check(f) < 0)
return log_oom();
return -ENOMEM;
m->read_resolv_conf = true;
m->need_builtin_fallbacks = true;
r = manager_parse_config_file(m);
r = manager_watch_hostname(m);
r = manager_network_monitor_listen(m);
r = manager_rtnl_listen(m);
r = manager_connect_bus(m);
*ret = m;
m = NULL;
assert(m);
r = manager_llmnr_start(m);
r = manager_mdns_start(m);
Link *l;
return NULL;
link_free(l);
while (m->dns_queries)
free(m);
return NULL;
} control;
int ms = 0, r;
ssize_t l;
assert(m);
return -errno;
if (ms < 0)
return -EIO;
return -errno;
return -EIO;
return -EAFNOSUPPORT;
case IPV6_PKTINFO: {
if (p->ifindex <= 0)
case IPV6_HOPLIMIT:
case IP_PKTINFO: {
if (p->ifindex <= 0)
case IP_TTL:
p->ifindex = 0;
if (p->ifindex <= 0)
*ret = p;
p = NULL;
return -errno;
return -ETIMEDOUT;
return -errno;
return -ETIMEDOUT;
log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
} control;
assert(m);
assert(p);
if (ifindex > 0) {
static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
} control;
assert(m);
assert(p);
if (ifindex > 0) {
int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
assert(m);
assert(p);
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));
return -EAFNOSUPPORT;
Link *l;
Iterator i;
if (l->mtu <= 0)
return mtu;
LinkAddress *a;
assert(m);
Iterator i;
Link *l;
assert(m);
link_add_rrs(l, true);
link_add_rrs(l, false);
uint64_t u, a;
assert(m);
assert(p);
while (p > m->llmnr_hostname) {
if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
random_bytes(&a, sizeof(a));
return -ENOMEM;
free(h);
log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
m->llmnr_hostname = h;
m->mdns_hostname = k;
LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
Iterator i;
Link *l;
assert(m);
LinkAddress *a;
return NULL;
assert(m);
assert(p);
Link *l;
assert(m);
assert(p);
return NULL;
switch (p->protocol) {
case DNS_PROTOCOL_LLMNR:
return l->llmnr_ipv4_scope;
return l->llmnr_ipv6_scope;
case DNS_PROTOCOL_MDNS:
return l->mdns_ipv4_scope;
return l->mdns_ipv6_scope;
return NULL;
DnsScope *s;
assert(m);
assert(m);
if (m->llmnr_hostname) {
if (m->mdns_hostname)
DnsServer *s;
Iterator i;
Link *l;
assert(m);
if (r == -EEXIST)
if (r == -EEXIST)
if (r == -EEXIST)
DnsSearchDomain *d;
Iterator i;
Link *l;
assert(m);
if (r == -EEXIST)
if (r == -EEXIST)
assert(m);
return m->dnssec_mode;
return DNSSEC_NO;
Iterator i;
Link *l;
assert(m);
if (!link_dnssec_supported(l))
log_debug("Found verdict for lookup %s: %s", s ? strstrip(s) : "n/a", dnssec_verdict_to_string(verdict));