resolved-dns-server.c revision 7586f4d172dd9c3ccc3126fc47dca9e49adec132
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/***
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek This file is part of systemd.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Copyright 2014 Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (at your option) any later version.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek***/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "alloc-util.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "resolved-dns-server.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "resolved-resolv-conf.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "siphash24.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "string-table.h"
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk#include "string-util.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/* After how much time to repeat classic DNS requests */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#define DNS_TIMEOUT_MIN_USEC (500 * USEC_PER_MSEC)
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC)
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering/* The amount of time to wait before retrying with a full feature set */
a5c32cff1f56afe6f0c6c70d91a88a7a8238b2d7Harald Hoyer#define DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC (6 * USEC_PER_HOUR)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#define DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC (5 * USEC_PER_MINUTE)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/* The number of times we will attempt a certain feature set before degrading */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#define DNS_SERVER_FEATURE_RETRY_ATTEMPTS 3
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint dns_server_new(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Manager *m,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek DnsServer **ret,
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering DnsServerType type,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Link *l,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int family,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const union in_addr_union *in_addr) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek DnsServer *s;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert((type == DNS_SERVER_LINK) == !!l);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(in_addr);
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!IN_SET(family, AF_INET, AF_INET6))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -EAFNOSUPPORT;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (l) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (l->n_dns_servers >= LINK_DNS_SERVERS_MAX)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -E2BIG;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -E2BIG;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s = new0(DnsServer, 1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return -ENOMEM;
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering s->n_ref = 1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->manager = m;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->verified_features = _DNS_SERVER_FEATURE_LEVEL_INVALID;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->possible_features = DNS_SERVER_FEATURE_LEVEL_BEST;
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->type = type;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->family = family;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->address = *in_addr;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->resend_timeout = DNS_TIMEOUT_MIN_USEC;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (type) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_LINK:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->link = l;
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack LIST_APPEND(servers, l->dns_servers, s);
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack l->n_dns_servers++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_SYSTEM:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_APPEND(servers, m->dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek m->n_dns_servers++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek case DNS_SERVER_FALLBACK:
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek LIST_APPEND(servers, m->fallback_dns_servers, s);
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer m->n_dns_servers++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek default:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_not_reached("Unknown server type");
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek s->linked = true;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* A new DNS server that isn't fallback is added and the one
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * we used so far was a fallback one? Then let's try to pick
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * the new one */
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (type != DNS_SERVER_FALLBACK &&
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek m->current_dns_server &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek m->current_dns_server->type == DNS_SERVER_FALLBACK)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek manager_set_dns_server(m, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (ret)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek *ret = s;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDnsServer* dns_server_ref(DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->n_ref > 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_ref ++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return s;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDnsServer* dns_server_unref(DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->n_ref > 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_ref --;
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->n_ref > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer}
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimervoid dns_server_unlink(DnsServer *s) {
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* This removes the specified server from the linked list of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * servers, but any server might still stay around if it has
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * refs, for example from an ongoing transaction. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s->linked)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (s->type) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_LINK:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->link);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->link->n_dns_servers > 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_REMOVE(servers, s->link->dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_SYSTEM:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager->n_dns_servers > 0);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek LIST_REMOVE(servers, s->manager->dns_servers, s);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek s->manager->n_dns_servers--;
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek break;
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek case DNS_SERVER_FALLBACK:
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek assert(s->manager->n_dns_servers > 0);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek s->manager->n_dns_servers--;
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek break;
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek }
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->linked = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (s->link && s->link->current_dns_server == s)
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek link_set_dns_server(s->link, NULL);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (s->manager->current_dns_server == s)
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek manager_set_dns_server(s->manager, NULL);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek dns_server_unref(s);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek}
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmekvoid dns_server_move_back_and_unmark(DnsServer *s) {
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek DnsServer *tail;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek assert(s);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (!s->marked)
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->marked = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s->linked || !s->servers_next)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Move us to the end of the list, so that the order is
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * strictly kept, if we are not at the end anyway. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (s->type) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_LINK:
4608af4333d0f7f5f8e3bc632801b04ef07d246dLennart Poettering assert(s->link);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FIND_TAIL(servers, s, tail);
4608af4333d0f7f5f8e3bc632801b04ef07d246dLennart Poettering LIST_REMOVE(servers, s->link->dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_INSERT_AFTER(servers, s->link->dns_servers, tail, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_SYSTEM:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FIND_TAIL(servers, s, tail);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_REMOVE(servers, s->manager->dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_INSERT_AFTER(servers, s->manager->dns_servers, tail, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_FALLBACK:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FIND_TAIL(servers, s, tail);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_INSERT_AFTER(servers, s->manager->fallback_dns_servers, tail, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek default:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_not_reached("Unknown server type");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid dns_server_packet_received(DnsServer *s, DnsServerFeatureLevel features, usec_t rtt) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
23ad4dd8844c582929115a11ed2830a1371568d6Jan Alexander Steffens (heftig)
23ad4dd8844c582929115a11ed2830a1371568d6Jan Alexander Steffens (heftig) if (s->verified_features < features) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->verified_features = features;
23ad4dd8844c582929115a11ed2830a1371568d6Jan Alexander Steffens (heftig) assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &s->verified_usec) >= 0);
23ad4dd8844c582929115a11ed2830a1371568d6Jan Alexander Steffens (heftig) }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->possible_features == features)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_failed_attempts = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->max_rtt < rtt) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->max_rtt = rtt;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->resend_timeout = MIN(MAX(DNS_TIMEOUT_MIN_USEC, s->max_rtt * 2), DNS_TIMEOUT_MAX_USEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid dns_server_packet_lost(DnsServer *s, DnsServerFeatureLevel features, usec_t usec) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager);
ed375bebf46c1251f4baa170b39ee93761dbdb19Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->possible_features == features)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_failed_attempts ++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->resend_timeout > usec)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->resend_timeout = MIN(s->resend_timeout * 2, DNS_TIMEOUT_MAX_USEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid dns_server_packet_failed(DnsServer *s, DnsServerFeatureLevel features) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->possible_features != features)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_failed_attempts = (unsigned) -1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool dns_server_grace_period_expired(DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek usec_t ts;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->verified_usec == 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->verified_usec + s->features_grace_period_usec > ts)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->features_grace_period_usec = MIN(s->features_grace_period_usec * 2, DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return true;
cbd671772c9ce053a7050ddd29de170eb9efac7eZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDnsServerFeatureLevel dns_server_possible_features(DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->possible_features != DNS_SERVER_FEATURE_LEVEL_BEST &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek dns_server_grace_period_expired(s)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *ip = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->possible_features = DNS_SERVER_FEATURE_LEVEL_BEST;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_failed_attempts = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->verified_usec = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek in_addr_to_string(s->family, &s->address, &ip);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Grace period over, resuming full feature set for DNS server %s", strna(ip));
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek } else if (s->possible_features <= s->verified_features)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek s->possible_features = s->verified_features;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek else if (s->n_failed_attempts >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek s->possible_features > DNS_SERVER_FEATURE_LEVEL_WORST) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *ip = NULL;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek s->possible_features --;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek s->n_failed_attempts = 0;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek s->verified_usec = 0;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek in_addr_to_string(s->family, &s->address, &ip);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek log_warning("Using degraded feature set (%s) for DNS server %s",
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek dns_server_feature_level_to_string(s->possible_features), strna(ip));
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek }
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return s->possible_features;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek}
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekstatic void dns_server_hash_func(const void *p, struct siphash *state) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek const DnsServer *s = p;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek siphash24_compress(&s->family, sizeof(s->family), state);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int dns_server_compare_func(const void *a, const void *b) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const DnsServer *x = a, *y = b;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if (x->family < y->family)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (x->family > y->family)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return 1;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek}
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekconst struct hash_ops dns_server_hash_ops = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek .hash = dns_server_hash_func,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek .compare = dns_server_compare_func
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek};
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukvoid dns_server_unlink_all(DnsServer *first) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk DnsServer *next;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!first)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk next = first->servers_next;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk dns_server_unlink(first);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk dns_server_unlink_all(next);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk}
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukvoid dns_server_unlink_marked(DnsServer *first) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk DnsServer *next;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!first)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering next = first->servers_next;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (first->marked)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering dns_server_unlink(first);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk dns_server_unlink_marked(next);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk}
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmekvoid dns_server_mark_all(DnsServer *first) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (!first)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek first->marked = true;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek dns_server_mark_all(first->servers_next);
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek}
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-SzmekDnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek DnsServer *s;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek LIST_FOREACH(servers, s, first)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return s;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDnsServer *manager_get_first_dns_server(Manager *m, DnsServerType t) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (t) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_SYSTEM:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return m->dns_servers;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case DNS_SERVER_FALLBACK:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return m->fallback_dns_servers;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek default:
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return NULL;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (m->current_dns_server == s)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return s;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (s) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering _cleanup_free_ char *ip = NULL;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering in_addr_to_string(s->family, &s->address, &ip);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering log_info("Switching to system DNS server %s.", strna(ip));
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering dns_server_unref(m->current_dns_server);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering m->current_dns_server = dns_server_ref(s);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (m->unicast_scope)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering dns_cache_flush(&m->unicast_scope->cache);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return s;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering}
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart PoetteringDnsServer *manager_get_dns_server(Manager *m) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering Link *l;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering assert(m);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering /* Try to read updates resolv.conf */
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering manager_read_resolv_conf(m);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering /* If no DNS server was chose so far, pick the first one */
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (!m->current_dns_server)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering manager_set_dns_server(m, m->dns_servers);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (!m->current_dns_server) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering bool found = false;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering Iterator i;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering /* No DNS servers configured, let's see if there are
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering * any on any links. If not, we use the fallback
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering * servers */
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering HASHMAP_FOREACH(l, m->links, i)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (l->dns_servers) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering found = true;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering break;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!found)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek manager_set_dns_server(m, m->fallback_dns_servers);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return m->current_dns_server;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid manager_next_dns_server(Manager *m) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If there's currently no DNS server set, then the next
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * manager_get_dns_server() will find one */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!m->current_dns_server)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Change to the next one, but make sure to follow the linked
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * list only if the server is still linked. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek manager_set_dns_server(m, m->current_dns_server->servers_next);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If there was no next one, then start from the beginning of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * the list */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek manager_set_dns_server(m, m->fallback_dns_servers);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek manager_set_dns_server(m, m->dns_servers);
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVEL_MAX] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek};
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-SzmekDEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek