]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-server.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / resolve / resolved-dns-server.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
74b2466e
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
62cc1c55 21#include "sd-messages.h"
1e02e182 22
b5efdb8a 23#include "alloc-util.h"
74b2466e 24#include "resolved-dns-server.h"
b30bf55d 25#include "resolved-dns-stub.h"
f2f1dbe5 26#include "resolved-resolv-conf.h"
b5efdb8a 27#include "siphash24.h"
be808ea0 28#include "string-table.h"
f2f1dbe5 29#include "string-util.h"
74b2466e 30
9df3ba6c 31/* After how much time to repeat classic DNS requests */
74a3ed74 32#define DNS_TIMEOUT_MIN_USEC (750 * USEC_PER_MSEC)
9df3ba6c
TG
33#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC)
34
be808ea0
TG
35/* The amount of time to wait before retrying with a full feature set */
36#define DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC (6 * USEC_PER_HOUR)
37#define DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC (5 * USEC_PER_MINUTE)
38
39/* The number of times we will attempt a certain feature set before degrading */
40#define DNS_SERVER_FEATURE_RETRY_ATTEMPTS 3
41
74b2466e
LP
42int dns_server_new(
43 Manager *m,
44 DnsServer **ret,
4e945a6f 45 DnsServerType type,
74b2466e 46 Link *l,
0dd25fb9 47 int family,
2817157b
LP
48 const union in_addr_union *in_addr,
49 int ifindex) {
74b2466e 50
eed857b7 51 DnsServer *s;
74b2466e
LP
52
53 assert(m);
4e945a6f 54 assert((type == DNS_SERVER_LINK) == !!l);
74b2466e 55 assert(in_addr);
74b2466e 56
eed857b7
LP
57 if (!IN_SET(family, AF_INET, AF_INET6))
58 return -EAFNOSUPPORT;
59
60 if (l) {
61 if (l->n_dns_servers >= LINK_DNS_SERVERS_MAX)
62 return -E2BIG;
63 } else {
64 if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX)
65 return -E2BIG;
66 }
67
74b2466e
LP
68 s = new0(DnsServer, 1);
69 if (!s)
70 return -ENOMEM;
71
91b14d6f 72 s->n_ref = 1;
0b58db65 73 s->manager = m;
4e945a6f 74 s->type = type;
74b2466e
LP
75 s->family = family;
76 s->address = *in_addr;
2817157b 77 s->ifindex = ifindex;
59c0fd0e
LP
78
79 dns_server_reset_features(s);
74b2466e 80
0b58db65
LP
81 switch (type) {
82
83 case DNS_SERVER_LINK:
84 s->link = l;
eed857b7
LP
85 LIST_APPEND(servers, l->dns_servers, s);
86 l->n_dns_servers++;
0b58db65
LP
87 break;
88
89 case DNS_SERVER_SYSTEM:
eed857b7
LP
90 LIST_APPEND(servers, m->dns_servers, s);
91 m->n_dns_servers++;
0b58db65
LP
92 break;
93
94 case DNS_SERVER_FALLBACK:
eed857b7
LP
95 LIST_APPEND(servers, m->fallback_dns_servers, s);
96 m->n_dns_servers++;
0b58db65
LP
97 break;
98
99 default:
4e945a6f 100 assert_not_reached("Unknown server type");
0b58db65 101 }
74b2466e 102
0eac4623 103 s->linked = true;
74b2466e 104
4e945a6f
LP
105 /* A new DNS server that isn't fallback is added and the one
106 * we used so far was a fallback one? Then let's try to pick
107 * the new one */
108 if (type != DNS_SERVER_FALLBACK &&
3e684349
LP
109 m->current_dns_server &&
110 m->current_dns_server->type == DNS_SERVER_FALLBACK)
111 manager_set_dns_server(m, NULL);
4e945a6f 112
74b2466e
LP
113 if (ret)
114 *ret = s;
115
116 return 0;
117}
118
91b14d6f 119DnsServer* dns_server_ref(DnsServer *s) {
74b2466e
LP
120 if (!s)
121 return NULL;
122
91b14d6f 123 assert(s->n_ref > 0);
313cefa1 124 s->n_ref++;
cab5b059 125
91b14d6f
TG
126 return s;
127}
128
0eac4623 129DnsServer* dns_server_unref(DnsServer *s) {
91b14d6f
TG
130 if (!s)
131 return NULL;
3e684349 132
0eac4623 133 assert(s->n_ref > 0);
313cefa1 134 s->n_ref--;
91b14d6f 135
0eac4623
LP
136 if (s->n_ref > 0)
137 return NULL;
74b2466e 138
6cb08a89 139 free(s->server_string);
6b430fdb 140 return mfree(s);
74b2466e 141}
87f5a193 142
0eac4623
LP
143void dns_server_unlink(DnsServer *s) {
144 assert(s);
145 assert(s->manager);
91b14d6f 146
0eac4623
LP
147 /* This removes the specified server from the linked list of
148 * servers, but any server might still stay around if it has
149 * refs, for example from an ongoing transaction. */
91b14d6f 150
0eac4623
LP
151 if (!s->linked)
152 return;
91b14d6f 153
0eac4623
LP
154 switch (s->type) {
155
156 case DNS_SERVER_LINK:
157 assert(s->link);
eed857b7 158 assert(s->link->n_dns_servers > 0);
0eac4623 159 LIST_REMOVE(servers, s->link->dns_servers, s);
0e3e1aef 160 s->link->n_dns_servers--;
0eac4623
LP
161 break;
162
163 case DNS_SERVER_SYSTEM:
eed857b7 164 assert(s->manager->n_dns_servers > 0);
0eac4623 165 LIST_REMOVE(servers, s->manager->dns_servers, s);
eed857b7 166 s->manager->n_dns_servers--;
0eac4623
LP
167 break;
168
169 case DNS_SERVER_FALLBACK:
eed857b7 170 assert(s->manager->n_dns_servers > 0);
0eac4623 171 LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
eed857b7 172 s->manager->n_dns_servers--;
0eac4623
LP
173 break;
174 }
175
176 s->linked = false;
177
178 if (s->link && s->link->current_dns_server == s)
179 link_set_dns_server(s->link, NULL);
180
181 if (s->manager->current_dns_server == s)
182 manager_set_dns_server(s->manager, NULL);
183
184 dns_server_unref(s);
91b14d6f
TG
185}
186
0b58db65
LP
187void dns_server_move_back_and_unmark(DnsServer *s) {
188 DnsServer *tail;
189
190 assert(s);
191
192 if (!s->marked)
193 return;
194
195 s->marked = false;
196
197 if (!s->linked || !s->servers_next)
198 return;
199
200 /* Move us to the end of the list, so that the order is
201 * strictly kept, if we are not at the end anyway. */
202
203 switch (s->type) {
204
205 case DNS_SERVER_LINK:
206 assert(s->link);
207 LIST_FIND_TAIL(servers, s, tail);
208 LIST_REMOVE(servers, s->link->dns_servers, s);
209 LIST_INSERT_AFTER(servers, s->link->dns_servers, tail, s);
210 break;
211
212 case DNS_SERVER_SYSTEM:
213 LIST_FIND_TAIL(servers, s, tail);
214 LIST_REMOVE(servers, s->manager->dns_servers, s);
215 LIST_INSERT_AFTER(servers, s->manager->dns_servers, tail, s);
216 break;
217
218 case DNS_SERVER_FALLBACK:
219 LIST_FIND_TAIL(servers, s, tail);
220 LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
221 LIST_INSERT_AFTER(servers, s->manager->fallback_dns_servers, tail, s);
222 break;
223
224 default:
225 assert_not_reached("Unknown server type");
226 }
227}
228
6bb2c085 229static void dns_server_verified(DnsServer *s, DnsServerFeatureLevel level) {
9df3ba6c
TG
230 assert(s);
231
6bb2c085
LP
232 if (s->verified_feature_level > level)
233 return;
b652d4a2 234
6bb2c085 235 if (s->verified_feature_level != level) {
de54e62b
LP
236 log_debug("Verified we get a response at feature level %s from DNS server %s.",
237 dns_server_feature_level_to_string(level),
238 dns_server_string(s));
f4461e56 239 s->verified_feature_level = level;
be808ea0
TG
240 }
241
6bb2c085
LP
242 assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &s->verified_usec) >= 0);
243}
244
d001e0a3
LP
245static void dns_server_reset_counters(DnsServer *s) {
246 assert(s);
247
248 s->n_failed_udp = 0;
249 s->n_failed_tcp = 0;
250 s->packet_truncated = false;
251 s->verified_usec = 0;
252
253 /* Note that we do not reset s->packet_bad_opt and s->packet_rrsig_missing here. We reset them only when the
254 * grace period ends, but not when lowering the possible feature level, as a lower level feature level should
255 * not make RRSIGs appear or OPT appear, but rather make them disappear. If the reappear anyway, then that's
256 * indication for a differently broken OPT/RRSIG implementation, and we really don't want to support that
257 * either.
258 *
259 * This is particularly important to deal with certain Belkin routers which break OPT for certain lookups (A),
260 * but pass traffic through for others (AAAA). If we detect the broken behaviour on one lookup we should not
261 * reenable it for another, because we cannot validate things anyway, given that the RRSIG/OPT data will be
262 * incomplete. */
263}
264
6bb2c085
LP
265void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t rtt, size_t size) {
266 assert(s);
267
268 if (protocol == IPPROTO_UDP) {
269 if (s->possible_feature_level == level)
270 s->n_failed_udp = 0;
271
b6451358
LP
272 /* If the RRSIG data is missing, then we can only validate EDNS0 at max */
273 if (s->packet_rrsig_missing && level >= DNS_SERVER_FEATURE_LEVEL_DO)
274 level = DNS_SERVER_FEATURE_LEVEL_DO - 1;
275
276 /* If the OPT RR got lost, then we can only validate UDP at max */
277 if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
278 level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
279
280 /* Even if we successfully receive a reply to a request announcing support for large packets,
281 that does not mean we can necessarily receive large packets. */
6bb2c085 282 if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
b6451358 283 level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
6bb2c085
LP
284
285 } else if (protocol == IPPROTO_TCP) {
286
287 if (s->possible_feature_level == level)
288 s->n_failed_tcp = 0;
289
290 /* Successful TCP connections are only useful to verify the TCP feature level. */
b6451358 291 level = DNS_SERVER_FEATURE_LEVEL_TCP;
6bb2c085 292 }
84129d46 293
b6451358
LP
294 dns_server_verified(s, level);
295
d74fb368
TG
296 /* Remember the size of the largest UDP packet we received from a server,
297 we know that we can always announce support for packets with at least
298 this size. */
6bb2c085 299 if (protocol == IPPROTO_UDP && s->received_udp_packet_max < size)
d74fb368
TG
300 s->received_udp_packet_max = size;
301
be808ea0
TG
302 if (s->max_rtt < rtt) {
303 s->max_rtt = rtt;
efd46a69 304 s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
496ae8c8
KK
305 } else if (s->resend_timeout > rtt)
306 /* If we received the packet faster than the resend_timeout, bias
307 * the resend_timeout back to the rtt. */
308 s->resend_timeout = CLAMP((2 * s->resend_timeout + rtt) / 3, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
9df3ba6c
TG
309}
310
6bb2c085 311void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t usec) {
9df3ba6c 312 assert(s);
be808ea0
TG
313 assert(s->manager);
314
6bb2c085
LP
315 if (s->possible_feature_level == level) {
316 if (protocol == IPPROTO_UDP)
313cefa1 317 s->n_failed_udp++;
6bb2c085 318 else if (protocol == IPPROTO_TCP)
313cefa1 319 s->n_failed_tcp++;
6bb2c085 320 }
9df3ba6c 321
84129d46
LP
322 if (s->resend_timeout > usec)
323 return;
324
325 s->resend_timeout = MIN(s->resend_timeout * 2, DNS_TIMEOUT_MAX_USEC);
9df3ba6c
TG
326}
327
6bb2c085
LP
328void dns_server_packet_truncated(DnsServer *s, DnsServerFeatureLevel level) {
329 assert(s);
571370c1 330
6bb2c085
LP
331 /* Invoked whenever we get a packet with TC bit set. */
332
333 if (s->possible_feature_level != level)
571370c1
LP
334 return;
335
6bb2c085 336 s->packet_truncated = true;
4e0b8b17
TG
337}
338
de54e62b
LP
339void dns_server_packet_rrsig_missing(DnsServer *s, DnsServerFeatureLevel level) {
340 assert(s);
341
342 if (level < DNS_SERVER_FEATURE_LEVEL_DO)
343 return;
344
b6451358
LP
345 /* If the RRSIG RRs are missing, we have to downgrade what we previously verified */
346 if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO)
347 s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_DO-1;
348
de54e62b
LP
349 s->packet_rrsig_missing = true;
350}
351
352void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level) {
b652d4a2 353 assert(s);
b652d4a2 354
de54e62b
LP
355 if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0)
356 return;
b652d4a2 357
b6451358
LP
358 /* If the OPT RR got lost, we have to downgrade what we previously verified */
359 if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
360 s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0-1;
361
de54e62b 362 s->packet_bad_opt = true;
b652d4a2
LP
363}
364
d001e0a3
LP
365void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level) {
366 assert(s);
367
368 /* Invoked whenever we got a FORMERR, SERVFAIL or NOTIMP rcode from a server and downgrading the feature level
369 * for the transaction made it go away. In this case we immediately downgrade to the feature level that made
370 * things work. */
371
372 if (s->verified_feature_level > level)
373 s->verified_feature_level = level;
374
375 if (s->possible_feature_level > level) {
376 s->possible_feature_level = level;
377 dns_server_reset_counters(s);
378 }
379
380 log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", dns_server_string(s));
381}
382
be808ea0
TG
383static bool dns_server_grace_period_expired(DnsServer *s) {
384 usec_t ts;
385
386 assert(s);
387 assert(s->manager);
388
389 if (s->verified_usec == 0)
390 return false;
391
392 assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
393
394 if (s->verified_usec + s->features_grace_period_usec > ts)
395 return false;
396
397 s->features_grace_period_usec = MIN(s->features_grace_period_usec * 2, DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC);
398
399 return true;
400}
401
f4461e56 402DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
97277567
LP
403 DnsServerFeatureLevel best;
404
be808ea0
TG
405 assert(s);
406
97277567
LP
407 /* Determine the best feature level we care about. If DNSSEC mode is off there's no point in using anything
408 * better than EDNS0, hence don't even try. */
409 best = dns_server_get_dnssec_mode(s) == DNSSEC_NO ?
410 DNS_SERVER_FEATURE_LEVEL_EDNS0 :
411 DNS_SERVER_FEATURE_LEVEL_BEST;
412
413 /* Clamp the feature level the highest level we care about. The DNSSEC mode might have changed since the last
414 * time, hence let's downgrade if we are still at a higher level. */
415 if (s->possible_feature_level > best)
416 s->possible_feature_level = best;
417
418 if (s->possible_feature_level < best && dns_server_grace_period_expired(s)) {
be808ea0 419
97277567 420 s->possible_feature_level = best;
cc450722 421
01184277
LP
422 dns_server_reset_counters(s);
423
cc450722
LP
424 s->packet_bad_opt = false;
425 s->packet_rrsig_missing = false;
426
de54e62b 427 log_info("Grace period over, resuming full feature set (%s) for DNS server %s.",
6cb08a89
LP
428 dns_server_feature_level_to_string(s->possible_feature_level),
429 dns_server_string(s));
6bb2c085 430
ce7c8b20
LP
431 dns_server_flush_cache(s);
432
f4461e56
LP
433 } else if (s->possible_feature_level <= s->verified_feature_level)
434 s->possible_feature_level = s->verified_feature_level;
6bb2c085
LP
435 else {
436 DnsServerFeatureLevel p = s->possible_feature_level;
be808ea0 437
6bb2c085 438 if (s->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
de54e62b 439 s->possible_feature_level == DNS_SERVER_FEATURE_LEVEL_TCP) {
6a1a5eec 440
6bb2c085
LP
441 /* We are at the TCP (lowest) level, and we tried a couple of TCP connections, and it didn't
442 * work. Upgrade back to UDP again. */
de54e62b
LP
443 log_debug("Reached maximum number of failed TCP connection attempts, trying UDP again...");
444 s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP;
445
446 } else if (s->packet_bad_opt &&
447 s->possible_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0) {
448
449 /* A reply to one of our EDNS0 queries didn't carry a valid OPT RR, then downgrade to below
450 * EDNS0 levels. After all, some records generate different responses with and without OPT RR
451 * in the request. Example:
452 * https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
453
454 log_debug("Server doesn't support EDNS(0) properly, downgrading feature level...");
6a1a5eec 455 s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP;
be808ea0 456
de54e62b
LP
457 } else if (s->packet_rrsig_missing &&
458 s->possible_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO) {
6bb2c085 459
de54e62b
LP
460 /* RRSIG data was missing on a EDNS0 packet with DO bit set. This means the server doesn't
461 * augment responses with DNSSEC RRs. If so, let's better not ask the server for it anymore,
462 * after all some servers generate different replies depending if an OPT RR is in the query or
463 * not. */
464
465 log_debug("Detected server responses lack RRSIG records, downgrading feature level...");
466 s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0;
467
468 } else if (s->n_failed_udp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
12bf2331 469 s->possible_feature_level >= (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
de54e62b
LP
470
471 /* We lost too many UDP packets in a row, and are on a feature level of UDP or higher. If the
472 * packets are lost, maybe the server cannot parse them, hence downgrading sounds like a good
12bf2331
LP
473 * idea. We might downgrade all the way down to TCP this way.
474 *
475 * If strict DNSSEC mode is used we won't downgrade below DO level however, as packet loss
476 * might have many reasons, a broken DNSSEC implementation being only one reason. And if the
477 * user is strict on DNSSEC, then let's assume that DNSSEC is not the fault here. */
de54e62b
LP
478
479 log_debug("Lost too many UDP packets, downgrading feature level...");
480 s->possible_feature_level--;
481
de54e62b
LP
482 } else if (s->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
483 s->packet_truncated &&
12bf2331 484 s->possible_feature_level > (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
de54e62b
LP
485
486 /* We got too many TCP connection failures in a row, we had at least one truncated packet, and
487 * are on a feature level above UDP. By downgrading things and getting rid of DNSSEC or EDNS0
488 * data we hope to make the packet smaller, so that it still works via UDP given that TCP
489 * appears not to be a fallback. Note that if we are already at the lowest UDP level, we don't
490 * go further down, since that's TCP, and TCP failed too often after all. */
491
492 log_debug("Got too many failed TCP connection failures and truncated UDP packets, downgrading feature level...");
493 s->possible_feature_level--;
494 }
495
6bb2c085 496 if (p != s->possible_feature_level) {
6bb2c085
LP
497
498 /* We changed the feature level, reset the counting */
01184277 499 dns_server_reset_counters(s);
6bb2c085 500
de54e62b 501 log_warning("Using degraded feature set (%s) for DNS server %s.",
6cb08a89
LP
502 dns_server_feature_level_to_string(s->possible_feature_level),
503 dns_server_string(s));
6bb2c085 504 }
be808ea0
TG
505 }
506
f4461e56 507 return s->possible_feature_level;
be808ea0
TG
508}
509
519ef046
LP
510int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeatureLevel level) {
511 size_t packet_size;
512 bool edns_do;
513 int r;
514
515 assert(server);
516 assert(packet);
517 assert(packet->protocol == DNS_PROTOCOL_DNS);
518
519 /* Fix the OPT field in the packet to match our current feature level. */
520
521 r = dns_packet_truncate_opt(packet);
522 if (r < 0)
523 return r;
524
525 if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0)
526 return 0;
527
528 edns_do = level >= DNS_SERVER_FEATURE_LEVEL_DO;
529
530 if (level >= DNS_SERVER_FEATURE_LEVEL_LARGE)
531 packet_size = DNS_PACKET_UNICAST_SIZE_LARGE_MAX;
532 else
533 packet_size = server->received_udp_packet_max;
534
f2ed4c69 535 return dns_packet_append_opt(packet, packet_size, edns_do, 0, NULL);
519ef046
LP
536}
537
2817157b
LP
538int dns_server_ifindex(const DnsServer *s) {
539 assert(s);
540
541 /* The link ifindex always takes precedence */
542 if (s->link)
543 return s->link->ifindex;
544
545 if (s->ifindex > 0)
546 return s->ifindex;
547
548 return 0;
549}
550
6cb08a89
LP
551const char *dns_server_string(DnsServer *server) {
552 assert(server);
553
554 if (!server->server_string)
2817157b 555 (void) in_addr_ifindex_to_string(server->family, &server->address, dns_server_ifindex(server), &server->server_string);
6cb08a89
LP
556
557 return strna(server->server_string);
558}
559
92ec902a
LP
560bool dns_server_dnssec_supported(DnsServer *server) {
561 assert(server);
562
563 /* Returns whether the server supports DNSSEC according to what we know about it */
564
565 if (server->possible_feature_level < DNS_SERVER_FEATURE_LEVEL_DO)
566 return false;
567
de54e62b
LP
568 if (server->packet_bad_opt)
569 return false;
570
571 if (server->packet_rrsig_missing)
92ec902a
LP
572 return false;
573
574 /* DNSSEC servers need to support TCP properly (see RFC5966), if they don't, we assume DNSSEC is borked too */
575 if (server->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS)
576 return false;
577
578 return true;
579}
580
1e02e182
LP
581void dns_server_warn_downgrade(DnsServer *server) {
582 assert(server);
583
584 if (server->warned_downgrade)
585 return;
586
587 log_struct(LOG_NOTICE,
2b044526 588 "MESSAGE_ID=" SD_MESSAGE_DNSSEC_DOWNGRADE_STR,
1e02e182
LP
589 LOG_MESSAGE("Server %s does not support DNSSEC, downgrading to non-DNSSEC mode.", dns_server_string(server)),
590 "DNS_SERVER=%s", dns_server_string(server),
591 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(server->possible_feature_level),
592 NULL);
593
594 server->warned_downgrade = true;
595}
596
413b05cc 597bool dns_server_limited_domains(DnsServer *server) {
b9fe94ca
MP
598 DnsSearchDomain *domain;
599 bool domain_restricted = false;
600
601 /* Check if the server has route-only domains without ~., i. e. whether
602 * it should only be used for particular domains */
603 if (!server->link)
604 return false;
605
606 LIST_FOREACH(domains, domain, server->link->search_domains)
607 if (domain->route_only) {
608 domain_restricted = true;
609 /* ~. means "any domain", thus it is a global server */
413b05cc 610 if (dns_name_is_root(DNS_SEARCH_DOMAIN_NAME(domain)))
b9fe94ca
MP
611 return false;
612 }
613
614 return domain_restricted;
615}
616
b826ab58 617static void dns_server_hash_func(const void *p, struct siphash *state) {
87f5a193 618 const DnsServer *s = p;
87f5a193 619
b826ab58 620 assert(s);
87f5a193 621
b826ab58
TG
622 siphash24_compress(&s->family, sizeof(s->family), state);
623 siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state);
2817157b 624 siphash24_compress(&s->ifindex, sizeof(s->ifindex), state);
87f5a193
LP
625}
626
d5099efc 627static int dns_server_compare_func(const void *a, const void *b) {
87f5a193 628 const DnsServer *x = a, *y = b;
2817157b 629 int r;
87f5a193
LP
630
631 if (x->family < y->family)
632 return -1;
633 if (x->family > y->family)
634 return 1;
635
2817157b
LP
636 r = memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
637 if (r != 0)
638 return r;
639
640 if (x->ifindex < y->ifindex)
641 return -1;
642 if (x->ifindex > y->ifindex)
643 return 1;
644
645 return 0;
87f5a193 646}
d5099efc
MS
647
648const struct hash_ops dns_server_hash_ops = {
649 .hash = dns_server_hash_func,
650 .compare = dns_server_compare_func
651};
636e813d 652
4b95f179
LP
653void dns_server_unlink_all(DnsServer *first) {
654 DnsServer *next;
0eac4623 655
4b95f179
LP
656 if (!first)
657 return;
0eac4623 658
4b95f179
LP
659 next = first->servers_next;
660 dns_server_unlink(first);
636e813d 661
4b95f179 662 dns_server_unlink_all(next);
0eac4623
LP
663}
664
4b95f179
LP
665void dns_server_unlink_marked(DnsServer *first) {
666 DnsServer *next;
636e813d 667
4b95f179
LP
668 if (!first)
669 return;
636e813d 670
4b95f179 671 next = first->servers_next;
636e813d 672
4b95f179 673 if (first->marked)
0eac4623 674 dns_server_unlink(first);
636e813d 675
4b95f179
LP
676 dns_server_unlink_marked(next);
677}
636e813d 678
4b95f179
LP
679void dns_server_mark_all(DnsServer *first) {
680 if (!first)
681 return;
636e813d 682
4b95f179
LP
683 first->marked = true;
684 dns_server_mark_all(first->servers_next);
636e813d
LP
685}
686
2817157b 687DnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr, int ifindex) {
4b95f179 688 DnsServer *s;
636e813d 689
636e813d 690 LIST_FOREACH(servers, s, first)
2817157b 691 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0 && s->ifindex == ifindex)
4b95f179 692 return s;
f2f1dbe5 693
4b95f179
LP
694 return NULL;
695}
f2f1dbe5 696
4b95f179 697DnsServer *manager_get_first_dns_server(Manager *m, DnsServerType t) {
f2f1dbe5 698 assert(m);
f2f1dbe5 699
4b95f179 700 switch (t) {
f2f1dbe5 701
4b95f179
LP
702 case DNS_SERVER_SYSTEM:
703 return m->dns_servers;
f2f1dbe5 704
4b95f179
LP
705 case DNS_SERVER_FALLBACK:
706 return m->fallback_dns_servers;
707
708 default:
709 return NULL;
710 }
f2f1dbe5
LP
711}
712
713DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
714 assert(m);
715
716 if (m->current_dns_server == s)
717 return s;
718
6cb08a89 719 if (s)
db8e1324
LP
720 log_debug("Switching to %s DNS server %s.",
721 dns_server_type_to_string(s->type),
722 dns_server_string(s));
f2f1dbe5 723
0eac4623
LP
724 dns_server_unref(m->current_dns_server);
725 m->current_dns_server = dns_server_ref(s);
f2f1dbe5
LP
726
727 if (m->unicast_scope)
728 dns_cache_flush(&m->unicast_scope->cache);
729
730 return s;
731}
732
733DnsServer *manager_get_dns_server(Manager *m) {
734 Link *l;
735 assert(m);
736
737 /* Try to read updates resolv.conf */
738 manager_read_resolv_conf(m);
739
e3309036 740 /* If no DNS server was chosen so far, pick the first one */
f2f1dbe5
LP
741 if (!m->current_dns_server)
742 manager_set_dns_server(m, m->dns_servers);
743
744 if (!m->current_dns_server) {
745 bool found = false;
746 Iterator i;
747
748 /* No DNS servers configured, let's see if there are
749 * any on any links. If not, we use the fallback
750 * servers */
751
752 HASHMAP_FOREACH(l, m->links, i)
753 if (l->dns_servers) {
754 found = true;
755 break;
756 }
757
758 if (!found)
759 manager_set_dns_server(m, m->fallback_dns_servers);
760 }
761
762 return m->current_dns_server;
763}
764
765void manager_next_dns_server(Manager *m) {
766 assert(m);
767
768 /* If there's currently no DNS server set, then the next
769 * manager_get_dns_server() will find one */
770 if (!m->current_dns_server)
771 return;
772
0eac4623
LP
773 /* Change to the next one, but make sure to follow the linked
774 * list only if the server is still linked. */
775 if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
f2f1dbe5
LP
776 manager_set_dns_server(m, m->current_dns_server->servers_next);
777 return;
778 }
779
780 /* If there was no next one, then start from the beginning of
781 * the list */
782 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
783 manager_set_dns_server(m, m->fallback_dns_servers);
784 else
785 manager_set_dns_server(m, m->dns_servers);
786}
be808ea0 787
b30bf55d
LP
788bool dns_server_address_valid(int family, const union in_addr_union *sa) {
789
790 /* Refuses the 0 IP addresses as well as 127.0.0.53 (which is our own DNS stub) */
791
792 if (in_addr_is_null(family, sa))
793 return false;
794
795 if (family == AF_INET && sa->in.s_addr == htobe32(INADDR_DNS_STUB))
796 return false;
797
798 return true;
799}
800
12bf2331
LP
801DnssecMode dns_server_get_dnssec_mode(DnsServer *s) {
802 assert(s);
803
804 if (s->link)
805 return link_get_dnssec_mode(s->link);
806
807 return manager_get_dnssec_mode(s->manager);
808}
809
ce7c8b20
LP
810void dns_server_flush_cache(DnsServer *s) {
811 DnsServer *current;
812 DnsScope *scope;
813
814 assert(s);
815
816 /* Flush the cache of the scope this server belongs to */
817
818 current = s->link ? s->link->current_dns_server : s->manager->current_dns_server;
819 if (current != s)
820 return;
821
822 scope = s->link ? s->link->unicast_scope : s->manager->unicast_scope;
823 if (!scope)
824 return;
825
826 dns_cache_flush(&scope->cache);
827}
828
59c0fd0e
LP
829void dns_server_reset_features(DnsServer *s) {
830 assert(s);
831
832 s->max_rtt = 0;
833 s->resend_timeout = DNS_TIMEOUT_MIN_USEC;
834
835 s->verified_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
836 s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
837
838 s->received_udp_packet_max = DNS_PACKET_UNICAST_SIZE_MAX;
839
840 s->packet_bad_opt = false;
841 s->packet_rrsig_missing = false;
842
843 s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
844
845 s->warned_downgrade = false;
846
847 dns_server_reset_counters(s);
848}
849
850void dns_server_reset_features_all(DnsServer *s) {
851 DnsServer *i;
852
853 LIST_FOREACH(servers, i, s)
854 dns_server_reset_features(i);
855}
856
cf84484a
LP
857void dns_server_dump(DnsServer *s, FILE *f) {
858 assert(s);
859
860 if (!f)
861 f = stdout;
862
863 fputs("[Server ", f);
864 fputs(dns_server_string(s), f);
865 fputs(" type=", f);
866 fputs(dns_server_type_to_string(s->type), f);
867
868 if (s->type == DNS_SERVER_LINK) {
869 assert(s->link);
870
871 fputs(" interface=", f);
872 fputs(s->link->name, f);
873 }
874
875 fputs("]\n", f);
876
877 fputs("\tVerified feature level: ", f);
878 fputs(strna(dns_server_feature_level_to_string(s->verified_feature_level)), f);
879 fputc('\n', f);
880
881 fputs("\tPossible feature level: ", f);
882 fputs(strna(dns_server_feature_level_to_string(s->possible_feature_level)), f);
883 fputc('\n', f);
884
885 fputs("\tDNSSEC Mode: ", f);
886 fputs(strna(dnssec_mode_to_string(dns_server_get_dnssec_mode(s))), f);
887 fputc('\n', f);
888
889 fputs("\tCan do DNSSEC: ", f);
890 fputs(yes_no(dns_server_dnssec_supported(s)), f);
891 fputc('\n', f);
892
893 fprintf(f,
894 "\tMaximum UDP packet size received: %zu\n"
895 "\tFailed UDP attempts: %u\n"
896 "\tFailed TCP attempts: %u\n"
897 "\tSeen truncated packet: %s\n"
898 "\tSeen OPT RR getting lost: %s\n"
899 "\tSeen RRSIG RR missing: %s\n",
900 s->received_udp_packet_max,
901 s->n_failed_udp,
902 s->n_failed_tcp,
903 yes_no(s->packet_truncated),
904 yes_no(s->packet_bad_opt),
905 yes_no(s->packet_rrsig_missing));
906}
907
e3309036
ZJS
908static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
909 [DNS_SERVER_SYSTEM] = "system",
910 [DNS_SERVER_FALLBACK] = "fallback",
911 [DNS_SERVER_LINK] = "link",
912};
913DEFINE_STRING_TABLE_LOOKUP(dns_server_type, DnsServerType);
914
be808ea0
TG
915static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVEL_MAX] = {
916 [DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
917 [DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
9c5e12a4 918 [DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
7586f4d1 919 [DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
d74fb368 920 [DNS_SERVER_FEATURE_LEVEL_LARGE] = "UDP+EDNS0+DO+LARGE",
be808ea0
TG
921};
922DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);