resolved-dns-server.c revision 4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4
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"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "string-util.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering/* After how much time to repeat classic DNS requests */
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#define DNS_TIMEOUT_MIN_USEC (500 * USEC_PER_MSEC)
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/* The amount of time to wait before retrying with a full feature set */
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering#define DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC (6 * USEC_PER_HOUR)
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering#define DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC (5 * USEC_PER_MINUTE)
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/* The number of times we will attempt a certain feature set before degrading */
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering#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,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek DnsServerType type,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Link *l,
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering int family,
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering const union in_addr_union *in_addr) {
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering DnsServer *s;
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert((type == DNS_SERVER_LINK) == !!l);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(in_addr);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
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)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -E2BIG;
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering } else {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -E2BIG;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering s = new0(DnsServer, 1);
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering if (!s)
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz return -ENOMEM;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_ref = 1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->manager = m;
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack s->verified_features = _DNS_SERVER_FEATURE_LEVEL_INVALID;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->possible_features = DNS_SERVER_FEATURE_LEVEL_BEST;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek 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
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack case DNS_SERVER_LINK:
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack s->link = l;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_APPEND(servers, l->dns_servers, s);
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack l->n_dns_servers++;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
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++;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek break;
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer case DNS_SERVER_FALLBACK:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_APPEND(servers, m->fallback_dns_servers, s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek m->n_dns_servers++;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer default:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_not_reached("Unknown server type");
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew 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
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * we used so far was a fallback one? Then let's try to pick
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * the new one */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (type != DNS_SERVER_FALLBACK &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew 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
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek assert(s->n_ref > 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_ref --;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->n_ref > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer free(s);
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer return NULL;
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer}
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid dns_server_unlink(DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek 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
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek case DNS_SERVER_SYSTEM:
348ced909724a1331b85d57aede80a102a00e428Zbigniew 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;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek s->linked = false;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew 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
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering if (s->manager->current_dns_server == s)
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering manager_set_dns_server(s->manager, NULL);
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering dns_server_unref(s);
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering}
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);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt 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;
34c10968cbe3b5591b3c0ce225b8694edd9709d0Lennart Poettering
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);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt 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");
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt }
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) }
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
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) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt 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)
f7dc3ab9f43b67abcbd34062b9352ab42debec49Lennart Poettering 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;
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->manager);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek if (s->verified_usec == 0)
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew 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);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->verified_usec + s->features_grace_period_usec > ts)
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt 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 &&
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt 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));
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering } else if (s->possible_features <= s->verified_features)
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering s->possible_features = s->verified_features;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering else if (s->n_failed_attempts >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering s->possible_features > DNS_SERVER_FEATURE_LEVEL_WORST) {
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering _cleanup_free_ char *ip = NULL;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering 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;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering}
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poetteringstatic void dns_server_hash_func(const void *p, struct siphash *state) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek const DnsServer *s = p;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering assert(s);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek siphash24_compress(&s->family, sizeof(s->family), state);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew 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;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew 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));
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt}
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekconst struct hash_ops dns_server_hash_ops = {
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt .hash = dns_server_hash_func,
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek .compare = dns_server_compare_func
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek};
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid dns_server_unlink_all(DnsServer *first) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek DnsServer *next;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
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
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidtvoid dns_server_unlink_marked(DnsServer *first) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk DnsServer *next;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt if (!first)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt next = first->servers_next;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (first->marked)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering dns_server_unlink(first);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering dns_server_unlink_marked(next);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt}
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukvoid dns_server_mark_all(DnsServer *first) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!first)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering first->marked = true;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering dns_server_mark_all(first->servers_next);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering}
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart PoetteringDnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr) {
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering DnsServer *s;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering 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;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return NULL;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek}
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
dbd2a83fbf051fc51bdca3aa7536c78479488c5bLennart PoetteringDnsServer *manager_get_first_dns_server(Manager *m, DnsServerType t) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek assert(m);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek switch (t) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew 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:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
da927ba997d68401563b927f92e6e40e021a8e5cMichal SchmidtDnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (m->current_dns_server == s)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return s;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *ip = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek in_addr_to_string(s->family, &s->address, &ip);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek 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 }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (!found)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering manager_set_dns_server(m, m->fallback_dns_servers);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return m->current_dns_server;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering}
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringvoid manager_next_dns_server(Manager *m) {
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poettering 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;
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering
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;
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering }
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering
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);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
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",
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering};
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering