]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-transaction.c
tree-wide: make ++/-- usage consistent WRT spacing
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
CommitLineData
ec2c5e43
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2014 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
beef6a5f
LP
20#include <sd-messages.h>
21
ec2c5e43 22#include "af-list.h"
b5efdb8a 23#include "alloc-util.h"
f52e61da 24#include "dns-domain.h"
7cc6ed7b 25#include "errno-list.h"
3ffd4af2
LP
26#include "fd-util.h"
27#include "random-util.h"
7778dfff 28#include "resolved-dns-cache.h"
3ffd4af2
LP
29#include "resolved-dns-transaction.h"
30#include "resolved-llmnr.h"
8b43440b 31#include "string-table.h"
ec2c5e43 32
b214dc0f
LP
33#define TRANSACTIONS_MAX 4096
34
c61d2b44
LP
35static void dns_transaction_reset_answer(DnsTransaction *t) {
36 assert(t);
37
38 t->received = dns_packet_unref(t->received);
39 t->answer = dns_answer_unref(t->answer);
40 t->answer_rcode = 0;
41 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
42 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
43 t->answer_authenticated = false;
d3760be0 44 t->answer_nsec_ttl = (uint32_t) -1;
7cc6ed7b 45 t->answer_errno = 0;
c61d2b44
LP
46}
47
c5b4f861
LP
48static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
49 DnsTransaction *z;
50
51 assert(t);
52
53 while ((z = set_steal_first(t->dnssec_transactions))) {
54 set_remove(z->notify_transactions, t);
55 dns_transaction_gc(z);
56 }
57}
58
f32f0e57
LP
59static void dns_transaction_close_connection(DnsTransaction *t) {
60 assert(t);
61
62 t->stream = dns_stream_free(t->stream);
63 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
64 t->dns_udp_fd = safe_close(t->dns_udp_fd);
65}
66
f535705a 67static void dns_transaction_stop_timeout(DnsTransaction *t) {
97cc656c
LP
68 assert(t);
69
70 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
97cc656c
LP
71}
72
ec2c5e43 73DnsTransaction* dns_transaction_free(DnsTransaction *t) {
801ad6a6 74 DnsQueryCandidate *c;
ec2c5e43 75 DnsZoneItem *i;
547973de 76 DnsTransaction *z;
ec2c5e43
LP
77
78 if (!t)
79 return NULL;
80
51e399bc
LP
81 log_debug("Freeing transaction %" PRIu16 ".", t->id);
82
f32f0e57 83 dns_transaction_close_connection(t);
f535705a 84 dns_transaction_stop_timeout(t);
ec2c5e43 85
ec2c5e43 86 dns_packet_unref(t->sent);
c61d2b44 87 dns_transaction_reset_answer(t);
ec2c5e43 88
8300ba21 89 dns_server_unref(t->server);
ec2c5e43
LP
90
91 if (t->scope) {
f9ebb22a
LP
92 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
93 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
ec2c5e43
LP
94
95 if (t->id != 0)
96 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
97 }
98
547973de 99 while ((c = set_steal_first(t->notify_query_candidates)))
801ad6a6 100 set_remove(c->transactions, t);
547973de 101 set_free(t->notify_query_candidates);
801ad6a6 102
547973de 103 while ((i = set_steal_first(t->notify_zone_items)))
ec2c5e43 104 i->probe_transaction = NULL;
547973de
LP
105 set_free(t->notify_zone_items);
106
107 while ((z = set_steal_first(t->notify_transactions)))
108 set_remove(z->dnssec_transactions, t);
109 set_free(t->notify_transactions);
110
c5b4f861 111 dns_transaction_flush_dnssec_transactions(t);
547973de
LP
112 set_free(t->dnssec_transactions);
113
114 dns_answer_unref(t->validated_keys);
97cc656c 115 dns_resource_key_unref(t->key);
97cc656c 116
ec2c5e43
LP
117 free(t);
118 return NULL;
119}
120
121DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
122
51e399bc 123bool dns_transaction_gc(DnsTransaction *t) {
ec2c5e43
LP
124 assert(t);
125
126 if (t->block_gc > 0)
51e399bc 127 return true;
ec2c5e43 128
547973de
LP
129 if (set_isempty(t->notify_query_candidates) &&
130 set_isempty(t->notify_zone_items) &&
51e399bc 131 set_isempty(t->notify_transactions)) {
ec2c5e43 132 dns_transaction_free(t);
51e399bc
LP
133 return false;
134 }
135
136 return true;
ec2c5e43
LP
137}
138
4dd15077
LP
139static uint16_t pick_new_id(Manager *m) {
140 uint16_t new_id;
141
142 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
143 * transactions, and it's much lower than the space of IDs. */
144
145 assert_cc(TRANSACTIONS_MAX < 0xFFFF);
146
147 do
148 random_bytes(&new_id, sizeof(new_id));
149 while (new_id == 0 ||
150 hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
151
152 return new_id;
153}
154
f52e61da 155int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
ec2c5e43
LP
156 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
157 int r;
158
159 assert(ret);
160 assert(s);
f52e61da 161 assert(key);
ec2c5e43 162
9eae2bf3 163 /* Don't allow looking up invalid or pseudo RRs */
c463eb78 164 if (!dns_type_is_valid_query(key->type))
9eae2bf3 165 return -EINVAL;
d0129ddb
LP
166 if (dns_type_is_obsolete(key->type))
167 return -EOPNOTSUPP;
9eae2bf3
LP
168
169 /* We only support the IN class */
c463eb78 170 if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
9eae2bf3
LP
171 return -EOPNOTSUPP;
172
b214dc0f
LP
173 if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
174 return -EBUSY;
175
d5099efc 176 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
ec2c5e43
LP
177 if (r < 0)
178 return r;
179
f9ebb22a 180 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
da0c630e
LP
181 if (r < 0)
182 return r;
183
ec2c5e43
LP
184 t = new0(DnsTransaction, 1);
185 if (!t)
186 return -ENOMEM;
187
4667e00a 188 t->dns_udp_fd = -1;
c3bc53e6 189 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
019036a4 190 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
d3760be0 191 t->answer_nsec_ttl = (uint32_t) -1;
f52e61da 192 t->key = dns_resource_key_ref(key);
274b8748 193 t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
ec2c5e43 194
4dd15077 195 t->id = pick_new_id(s->manager);
ec2c5e43
LP
196
197 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
198 if (r < 0) {
199 t->id = 0;
200 return r;
201 }
202
f9ebb22a 203 r = hashmap_replace(s->transactions_by_key, t->key, t);
da0c630e
LP
204 if (r < 0) {
205 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
206 return r;
207 }
208
f9ebb22a 209 LIST_PREPEND(transactions_by_scope, s->transactions, t);
ec2c5e43
LP
210 t->scope = s;
211
313cefa1 212 s->manager->n_transactions_total++;
a150ff5e 213
ec2c5e43
LP
214 if (ret)
215 *ret = t;
216
217 t = NULL;
218
219 return 0;
220}
221
4dd15077
LP
222static void dns_transaction_shuffle_id(DnsTransaction *t) {
223 uint16_t new_id;
224 assert(t);
225
226 /* Pick a new ID for this transaction. */
227
228 new_id = pick_new_id(t->scope->manager);
229 assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
230
231 log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
232 t->id = new_id;
233
234 /* Make sure we generate a new packet with the new ID */
235 t->sent = dns_packet_unref(t->sent);
236}
237
ec2c5e43 238static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
2fb3034c 239 _cleanup_free_ char *pretty = NULL;
202b76ae 240 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
ec2c5e43 241 DnsZoneItem *z;
ec2c5e43
LP
242
243 assert(t);
244 assert(p);
245
246 if (manager_our_packet(t->scope->manager, p) != 0)
247 return;
248
2fb3034c
LP
249 in_addr_to_string(p->family, &p->sender, &pretty);
250
a5784c49
LP
251 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
252 t->id,
202b76ae 253 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
ec2c5e43
LP
254 dns_protocol_to_string(t->scope->protocol),
255 t->scope->link ? t->scope->link->name : "*",
202b76ae 256 af_to_name_short(t->scope->family),
2fb3034c 257 pretty);
ec2c5e43 258
a4076574
LP
259 /* RFC 4795, Section 4.1 says that the peer with the
260 * lexicographically smaller IP address loses */
4d91eec4
LP
261 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
262 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
a4076574
LP
263 return;
264 }
265
4d91eec4 266 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
a4076574 267
ec2c5e43 268 t->block_gc++;
547973de 269 while ((z = set_first(t->notify_zone_items))) {
3ef64445
LP
270 /* First, make sure the zone item drops the reference
271 * to us */
272 dns_zone_item_probe_stop(z);
273
274 /* Secondly, report this as conflict, so that we might
275 * look for a different hostname */
ec2c5e43 276 dns_zone_item_conflict(z);
3ef64445 277 }
ec2c5e43
LP
278 t->block_gc--;
279
280 dns_transaction_gc(t);
281}
282
283void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
801ad6a6 284 DnsQueryCandidate *c;
ec2c5e43 285 DnsZoneItem *z;
547973de 286 DnsTransaction *d;
ec2c5e43 287 Iterator i;
7cc6ed7b 288 const char *st;
202b76ae 289 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
ec2c5e43
LP
290
291 assert(t);
547973de 292 assert(!DNS_TRANSACTION_IS_LIVE(state));
e56187ca 293
202b76ae
ZJS
294 if (state == DNS_TRANSACTION_DNSSEC_FAILED) {
295 dns_resource_key_to_string(t->key, key_str, sizeof key_str);
296
f61dfddb 297 log_struct(LOG_NOTICE,
beef6a5f 298 LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_FAILURE),
202b76ae 299 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", key_str, dnssec_result_to_string(t->answer_dnssec_result)),
f61dfddb 300 "DNS_TRANSACTION=%" PRIu16, t->id,
202b76ae 301 "DNS_QUESTION=%s", key_str,
f61dfddb 302 "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
1e02e182
LP
303 "DNS_SERVER=%s", dns_server_string(t->server),
304 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level),
f61dfddb 305 NULL);
202b76ae 306 }
f61dfddb 307
ec2c5e43
LP
308 /* Note that this call might invalidate the query. Callers
309 * should hence not attempt to access the query or transaction
310 * after calling this function. */
311
7cc6ed7b
LP
312 if (state == DNS_TRANSACTION_ERRNO)
313 st = errno_to_name(t->answer_errno);
314 else
315 st = dns_transaction_state_to_string(state);
316
a5784c49
LP
317 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
318 t->id,
202b76ae 319 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
ec2c5e43
LP
320 dns_protocol_to_string(t->scope->protocol),
321 t->scope->link ? t->scope->link->name : "*",
202b76ae 322 af_to_name_short(t->scope->family),
7cc6ed7b 323 st,
a5784c49
LP
324 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
325 t->answer_authenticated ? "authenticated" : "unsigned");
ec2c5e43
LP
326
327 t->state = state;
328
f32f0e57 329 dns_transaction_close_connection(t);
f535705a 330 dns_transaction_stop_timeout(t);
ec2c5e43
LP
331
332 /* Notify all queries that are interested, but make sure the
333 * transaction isn't freed while we are still looking at it */
334 t->block_gc++;
f7014757 335
547973de
LP
336 SET_FOREACH(c, t->notify_query_candidates, i)
337 dns_query_candidate_notify(c);
338 SET_FOREACH(z, t->notify_zone_items, i)
339 dns_zone_item_notify(z);
ec2c5e43 340
f7014757
LP
341 if (!set_isempty(t->notify_transactions)) {
342 DnsTransaction **nt;
343 unsigned j, n = 0;
344
345 /* We need to be careful when notifying other
346 * transactions, as that might destroy other
347 * transactions in our list. Hence, in order to be
348 * able to safely iterate through the list of
349 * transactions, take a GC lock on all of them
350 * first. Then, in a second loop, notify them, but
351 * first unlock that specific transaction. */
352
353 nt = newa(DnsTransaction*, set_size(t->notify_transactions));
354 SET_FOREACH(d, t->notify_transactions, i) {
355 nt[n++] = d;
356 d->block_gc++;
357 }
358
359 assert(n == set_size(t->notify_transactions));
360
361 for (j = 0; j < n; j++) {
362 if (set_contains(t->notify_transactions, nt[j]))
363 dns_transaction_notify(nt[j], t);
364
365 nt[j]->block_gc--;
366 dns_transaction_gc(nt[j]);
367 }
368 }
369
370 t->block_gc--;
ec2c5e43
LP
371 dns_transaction_gc(t);
372}
373
519ef046
LP
374static int dns_transaction_pick_server(DnsTransaction *t) {
375 DnsServer *server;
376
377 assert(t);
378 assert(t->scope->protocol == DNS_PROTOCOL_DNS);
379
380 server = dns_scope_get_dns_server(t->scope);
381 if (!server)
382 return -ESRCH;
383
274b8748 384 t->current_feature_level = dns_server_possible_feature_level(server);
519ef046
LP
385
386 if (server == t->server)
387 return 0;
388
389 dns_server_unref(t->server);
390 t->server = dns_server_ref(server);
391
392 return 1;
393}
394
8d10d620
LP
395static void dns_transaction_retry(DnsTransaction *t) {
396 int r;
397
398 assert(t);
399
400 log_debug("Retrying transaction %" PRIu16 ".", t->id);
401
402 /* Before we try again, switch to a new server. */
403 dns_scope_next_dns_server(t->scope);
404
405 r = dns_transaction_go(t);
7cc6ed7b
LP
406 if (r < 0) {
407 t->answer_errno = -r;
408 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
409 }
8d10d620
LP
410}
411
c02cf2f4
LP
412static int dns_transaction_maybe_restart(DnsTransaction *t) {
413 assert(t);
414
415 if (!t->server)
416 return 0;
417
418 if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
419 return 0;
420
421 /* The server's current feature level is lower than when we sent the original query. We learnt something from
422 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
423 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
424 OPT RR or DO bit. One of these cases is documented here, for example:
425 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
426
4dd15077
LP
427 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
428 dns_transaction_shuffle_id(t);
c02cf2f4
LP
429 return dns_transaction_go(t);
430}
431
ec2c5e43
LP
432static int on_stream_complete(DnsStream *s, int error) {
433 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
434 DnsTransaction *t;
435
436 assert(s);
437 assert(s->transaction);
438
439 /* Copy the data we care about out of the stream before we
440 * destroy it. */
441 t = s->transaction;
442 p = dns_packet_ref(s->read_packet);
443
444 t->stream = dns_stream_free(t->stream);
445
a1a3f73a
LP
446 if (ERRNO_IS_DISCONNECT(error)) {
447 usec_t usec;
448
0791110f
LP
449 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
450 /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
451 * question on this scope. */
452 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
453 return 0;
454 }
455
92ec902a 456 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
a1a3f73a 457 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
274b8748 458 dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level, usec - t->start_usec);
a1a3f73a
LP
459
460 dns_transaction_retry(t);
ac720200
LP
461 return 0;
462 }
ec2c5e43 463 if (error != 0) {
7cc6ed7b
LP
464 t->answer_errno = error;
465 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
ec2c5e43
LP
466 return 0;
467 }
468
a4076574 469 if (dns_packet_validate_reply(p) <= 0) {
a20b9592 470 log_debug("Invalid TCP reply packet.");
a4076574
LP
471 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
472 return 0;
473 }
474
475 dns_scope_check_conflicts(t->scope, p);
476
ec2c5e43
LP
477 t->block_gc++;
478 dns_transaction_process_reply(t, p);
479 t->block_gc--;
480
519ef046
LP
481 /* If the response wasn't useful, then complete the transition
482 * now. After all, we are the worst feature set now with TCP
483 * sockets, and there's really no point in retrying. */
ec2c5e43
LP
484 if (t->state == DNS_TRANSACTION_PENDING)
485 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
598f44bd
LP
486 else
487 dns_transaction_gc(t);
ec2c5e43
LP
488
489 return 0;
490}
491
492static int dns_transaction_open_tcp(DnsTransaction *t) {
493 _cleanup_close_ int fd = -1;
494 int r;
495
496 assert(t);
497
519ef046 498 dns_transaction_close_connection(t);
ec2c5e43 499
106784eb 500 switch (t->scope->protocol) {
519ef046 501
106784eb 502 case DNS_PROTOCOL_DNS:
519ef046
LP
503 r = dns_transaction_pick_server(t);
504 if (r < 0)
505 return r;
506
92ec902a 507 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
91adc4db
LP
508 return -EOPNOTSUPP;
509
274b8748 510 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
519ef046
LP
511 if (r < 0)
512 return r;
513
514 fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, 53);
106784eb 515 break;
ec2c5e43 516
106784eb 517 case DNS_PROTOCOL_LLMNR:
a8f6397f 518 /* When we already received a reply to this (but it was truncated), send to its sender address */
ec2c5e43 519 if (t->received)
519ef046 520 fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port);
ec2c5e43
LP
521 else {
522 union in_addr_union address;
a7f7d1bd 523 int family = AF_UNSPEC;
ec2c5e43
LP
524
525 /* Otherwise, try to talk to the owner of a
526 * the IP address, in case this is a reverse
527 * PTR lookup */
f52e61da 528
1c02e7ba 529 r = dns_name_address(dns_resource_key_name(t->key), &family, &address);
ec2c5e43
LP
530 if (r < 0)
531 return r;
532 if (r == 0)
533 return -EINVAL;
9e08a6e0 534 if (family != t->scope->family)
9318cdd3 535 return -ESRCH;
ec2c5e43 536
519ef046 537 fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT);
ec2c5e43 538 }
106784eb
DM
539
540 break;
541
542 default:
ec2c5e43 543 return -EAFNOSUPPORT;
106784eb 544 }
ec2c5e43
LP
545
546 if (fd < 0)
547 return fd;
548
549 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
550 if (r < 0)
551 return r;
ec2c5e43
LP
552 fd = -1;
553
554 r = dns_stream_write_packet(t->stream, t->sent);
555 if (r < 0) {
556 t->stream = dns_stream_free(t->stream);
557 return r;
558 }
559
ec2c5e43
LP
560 t->stream->complete = on_stream_complete;
561 t->stream->transaction = t;
562
563 /* The interface index is difficult to determine if we are
564 * connecting to the local host, hence fill this in right away
565 * instead of determining it from the socket */
566 if (t->scope->link)
567 t->stream->ifindex = t->scope->link->ifindex;
568
519ef046
LP
569 dns_transaction_reset_answer(t);
570
cbe4216d
LP
571 t->tried_stream = true;
572
ec2c5e43
LP
573 return 0;
574}
575
547973de 576static void dns_transaction_cache_answer(DnsTransaction *t) {
547973de
LP
577 assert(t);
578
579 /* For mDNS we cache whenever we get the packet, rather than
580 * in each transaction. */
581 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
582 return;
583
584 /* We never cache if this packet is from the local host, under
585 * the assumption that a locally running DNS server would
586 * cache this anyway, and probably knows better when to flush
587 * the cache then we could. */
588 if (!DNS_PACKET_SHALL_CACHE(t->received))
589 return;
590
547973de
LP
591 dns_cache_put(&t->scope->cache,
592 t->key,
593 t->answer_rcode,
594 t->answer,
547973de 595 t->answer_authenticated,
d3760be0 596 t->answer_nsec_ttl,
547973de
LP
597 0,
598 t->received->family,
599 &t->received->sender);
600}
601
105e1512
LP
602static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
603 DnsTransaction *dt;
604 Iterator i;
605
606 assert(t);
607
608 SET_FOREACH(dt, t->dnssec_transactions, i)
609 if (DNS_TRANSACTION_IS_LIVE(dt->state))
610 return true;
611
612 return false;
613}
614
942eb2e7
LP
615static int dns_transaction_dnssec_ready(DnsTransaction *t) {
616 DnsTransaction *dt;
617 Iterator i;
618
619 assert(t);
620
621 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
622 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
623
624 SET_FOREACH(dt, t->dnssec_transactions, i) {
625
626 switch (dt->state) {
627
628 case DNS_TRANSACTION_NULL:
629 case DNS_TRANSACTION_PENDING:
630 case DNS_TRANSACTION_VALIDATING:
631 /* Still ongoing */
632 return 0;
633
634 case DNS_TRANSACTION_RCODE_FAILURE:
635 if (dt->answer_rcode != DNS_RCODE_NXDOMAIN) {
636 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
637 goto fail;
638 }
639
640 /* Fall-through: NXDOMAIN is good enough for us. This is because some DNS servers erronously
641 * return NXDOMAIN for empty non-terminals (Akamai...), and we need to handle that nicely, when
642 * asking for parent SOA or similar RRs to make unsigned proofs. */
643
644 case DNS_TRANSACTION_SUCCESS:
645 /* All good. */
646 break;
647
648 case DNS_TRANSACTION_DNSSEC_FAILED:
649 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
650 * validationr result */
651
652 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
653 t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
654 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
655 return 0;
656
657
658 default:
659 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
660 goto fail;
661 }
662 }
663
664 /* All is ready, we can go and validate */
665 return 1;
666
667fail:
668 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
669 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
670 return 0;
671}
672
547973de
LP
673static void dns_transaction_process_dnssec(DnsTransaction *t) {
674 int r;
675
676 assert(t);
677
678 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
942eb2e7 679 r = dns_transaction_dnssec_ready(t);
7cc6ed7b
LP
680 if (r < 0)
681 goto fail;
942eb2e7 682 if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
547973de
LP
683 return;
684
c02cf2f4
LP
685 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
686 * restart the lookup immediately. */
687 r = dns_transaction_maybe_restart(t);
7cc6ed7b
LP
688 if (r < 0)
689 goto fail;
c02cf2f4
LP
690 if (r > 0) /* Transaction got restarted... */
691 return;
692
547973de
LP
693 /* All our auxiliary DNSSEC transactions are complete now. Try
694 * to validate our RRset now. */
695 r = dns_transaction_validate_dnssec(t);
fcfaff12
LP
696 if (r == -EBADMSG) {
697 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
698 return;
699 }
7cc6ed7b
LP
700 if (r < 0)
701 goto fail;
547973de 702
b652d4a2
LP
703 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
704 t->scope->dnssec_mode == DNSSEC_YES) {
705 /* We are not in automatic downgrade mode, and the
706 * server is bad, refuse operation. */
707 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
708 return;
709 }
710
019036a4 711 if (!IN_SET(t->answer_dnssec_result,
b652d4a2
LP
712 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
713 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
714 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
715 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
547973de
LP
716 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
717 return;
718 }
719
1e02e182
LP
720 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER)
721 dns_server_warn_downgrade(t->server);
722
547973de
LP
723 dns_transaction_cache_answer(t);
724
725 if (t->answer_rcode == DNS_RCODE_SUCCESS)
726 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
727 else
3bbdc31d 728 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
7cc6ed7b
LP
729
730 return;
731
732fail:
733 t->answer_errno = -r;
734 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
547973de
LP
735}
736
eac7cda2
LP
737static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
738 int r;
739
740 assert(t);
741
742 /* Checks whether the answer is positive, i.e. either a direct
743 * answer to the question, or a CNAME/DNAME for it */
744
745 r = dns_answer_match_key(t->answer, t->key, flags);
746 if (r != 0)
747 return r;
748
749 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
750 if (r != 0)
751 return r;
752
753 return false;
754}
755
756static int dns_transaction_fix_rcode(DnsTransaction *t) {
757 int r;
758
759 assert(t);
760
761 /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
762 * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
763 * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
764 * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
765 * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
766 * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
767 * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
768 * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
769 * incomplete CNAME/DNAME chain.
770 *
771 * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
772 * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
773 * lookup. */
774
775 if (t->answer_rcode != DNS_RCODE_NXDOMAIN)
776 return 0;
777
778 r = dns_transaction_has_positive_answer(t, NULL);
779 if (r <= 0)
780 return r;
781
782 t->answer_rcode = DNS_RCODE_SUCCESS;
783 return 0;
784}
785
ec2c5e43 786void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
9df3ba6c 787 usec_t ts;
ec2c5e43
LP
788 int r;
789
790 assert(t);
791 assert(p);
9df3ba6c
TG
792 assert(t->scope);
793 assert(t->scope->manager);
ec2c5e43 794
5a7e41a3
LP
795 if (t->state != DNS_TRANSACTION_PENDING)
796 return;
797
ec2c5e43
LP
798 /* Note that this call might invalidate the query. Callers
799 * should hence not attempt to access the query or transaction
800 * after calling this function. */
801
b5efcf29
LP
802 log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
803
106784eb 804 switch (t->scope->protocol) {
b5efcf29 805
106784eb 806 case DNS_PROTOCOL_LLMNR:
ec2c5e43
LP
807 assert(t->scope->link);
808
809 /* For LLMNR we will not accept any packets from other
810 * interfaces */
811
812 if (p->ifindex != t->scope->link->ifindex)
813 return;
814
815 if (p->family != t->scope->family)
816 return;
817
818 /* Tentative packets are not full responses but still
819 * useful for identifying uniqueness conflicts during
820 * probing. */
8b757a38 821 if (DNS_PACKET_LLMNR_T(p)) {
ec2c5e43
LP
822 dns_transaction_tentative(t, p);
823 return;
824 }
106784eb
DM
825
826 break;
827
4e5bf5e1
DM
828 case DNS_PROTOCOL_MDNS:
829 assert(t->scope->link);
830
831 /* For mDNS we will not accept any packets from other interfaces */
832 if (p->ifindex != t->scope->link->ifindex)
833 return;
834
835 if (p->family != t->scope->family)
836 return;
837
838 break;
839
106784eb 840 case DNS_PROTOCOL_DNS:
8ad182a1
LP
841 /* Note that we do not need to verify the
842 * addresses/port numbers of incoming traffic, as we
843 * invoked connect() on our UDP socket in which case
844 * the kernel already does the needed verification for
845 * us. */
106784eb
DM
846 break;
847
848 default:
9c56a6f3 849 assert_not_reached("Invalid DNS protocol.");
ec2c5e43
LP
850 }
851
ec2c5e43
LP
852 if (t->received != p) {
853 dns_packet_unref(t->received);
854 t->received = dns_packet_ref(p);
855 }
856
c3bc53e6
LP
857 t->answer_source = DNS_TRANSACTION_NETWORK;
858
ec2c5e43
LP
859 if (p->ipproto == IPPROTO_TCP) {
860 if (DNS_PACKET_TC(p)) {
861 /* Truncated via TCP? Somebody must be fucking with us */
862 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
863 return;
864 }
865
866 if (DNS_PACKET_ID(p) != t->id) {
867 /* Not the reply to our query? Somebody must be fucking with us */
868 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
869 return;
870 }
871 }
872
38a03f06 873 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
9df3ba6c
TG
874
875 switch (t->scope->protocol) {
8af5b883 876
9df3ba6c
TG
877 case DNS_PROTOCOL_DNS:
878 assert(t->server);
879
4e0b8b17
TG
880 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
881
8af5b883 882 /* Request failed, immediately try again with reduced features */
4e0b8b17
TG
883 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
884
274b8748 885 dns_server_packet_failed(t->server, t->current_feature_level);
8d10d620 886 dns_transaction_retry(t);
4e0b8b17 887 return;
6bb2c085 888 } else if (DNS_PACKET_TC(p))
274b8748 889 dns_server_packet_truncated(t->server, t->current_feature_level);
9df3ba6c
TG
890
891 break;
8af5b883 892
9df3ba6c
TG
893 case DNS_PROTOCOL_LLMNR:
894 case DNS_PROTOCOL_MDNS:
895 dns_scope_packet_received(t->scope, ts - t->start_usec);
9df3ba6c 896 break;
8af5b883 897
9df3ba6c 898 default:
8af5b883 899 assert_not_reached("Invalid DNS protocol.");
9df3ba6c
TG
900 }
901
ec2c5e43 902 if (DNS_PACKET_TC(p)) {
547493c5
DM
903
904 /* Truncated packets for mDNS are not allowed. Give up immediately. */
905 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
906 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
907 return;
908 }
909
f757cd85
LP
910 log_debug("Reply truncated, retrying via TCP.");
911
ec2c5e43
LP
912 /* Response was truncated, let's try again with good old TCP */
913 r = dns_transaction_open_tcp(t);
914 if (r == -ESRCH) {
915 /* No servers found? Damn! */
916 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
917 return;
918 }
91adc4db
LP
919 if (r == -EOPNOTSUPP) {
920 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
921 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
922 return;
923 }
ec2c5e43 924 if (r < 0) {
8af5b883 925 /* On LLMNR, if we cannot connect to the host,
ec2c5e43 926 * we immediately give up */
7cc6ed7b
LP
927 if (t->scope->protocol != DNS_PROTOCOL_DNS)
928 goto fail;
ec2c5e43
LP
929
930 /* On DNS, couldn't send? Try immediately again, with a new server */
8d10d620 931 dns_transaction_retry(t);
ec2c5e43 932 }
2a6658ef
LP
933
934 return;
ec2c5e43
LP
935 }
936
de54e62b 937 /* After the superficial checks, actually parse the message. */
ec2c5e43
LP
938 r = dns_packet_extract(p);
939 if (r < 0) {
940 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
941 return;
942 }
943
de54e62b 944 /* Report that the OPT RR was missing */
ed9717fc
LP
945 if (t->server) {
946 if (!p->opt)
947 dns_server_packet_bad_opt(t->server, t->current_feature_level);
948
949 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, ts - t->start_usec, p->size);
950 }
de54e62b 951
c02cf2f4
LP
952 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
953 r = dns_transaction_maybe_restart(t);
7cc6ed7b
LP
954 if (r < 0)
955 goto fail;
c02cf2f4
LP
956 if (r > 0) /* Transaction got restarted... */
957 return;
958
b5efcf29
LP
959 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
960
547493c5 961 /* Only consider responses with equivalent query section to the request */
8af5b883 962 r = dns_packet_is_reply_for(p, t->key);
7cc6ed7b
LP
963 if (r < 0)
964 goto fail;
8af5b883 965 if (r == 0) {
547493c5
DM
966 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
967 return;
968 }
29815b6c 969
547493c5
DM
970 /* Install the answer as answer to the transaction */
971 dns_answer_unref(t->answer);
972 t->answer = dns_answer_ref(p->answer);
973 t->answer_rcode = DNS_PACKET_RCODE(p);
919c2ae0 974 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
105e1512 975 t->answer_authenticated = false;
79e24931 976
eac7cda2
LP
977 r = dns_transaction_fix_rcode(t);
978 if (r < 0)
979 goto fail;
980
51e399bc
LP
981 /* Block GC while starting requests for additional DNSSEC RRs */
982 t->block_gc++;
547973de 983 r = dns_transaction_request_dnssec_keys(t);
51e399bc
LP
984 t->block_gc--;
985
986 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
987 if (!dns_transaction_gc(t))
988 return;
989
990 /* Requesting additional keys might have resulted in
991 * this transaction to fail, since the auxiliary
992 * request failed for some reason. If so, we are not
993 * in pending state anymore, and we should exit
994 * quickly. */
995 if (t->state != DNS_TRANSACTION_PENDING)
996 return;
7cc6ed7b
LP
997 if (r < 0)
998 goto fail;
547973de
LP
999 if (r > 0) {
1000 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1001 t->state = DNS_TRANSACTION_VALIDATING;
f535705a
LP
1002 dns_transaction_close_connection(t);
1003 dns_transaction_stop_timeout(t);
547973de
LP
1004 return;
1005 }
547493c5 1006 }
ec2c5e43 1007
547973de 1008 dns_transaction_process_dnssec(t);
7cc6ed7b
LP
1009 return;
1010
1011fail:
1012 t->answer_errno = -r;
1013 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
ec2c5e43
LP
1014}
1015
c19ffd9f
TG
1016static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1017 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1018 DnsTransaction *t = userdata;
1019 int r;
1020
1021 assert(t);
1022 assert(t->scope);
1023
1024 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
7e1851e3
LP
1025 if (ERRNO_IS_DISCONNECT(-r)) {
1026 usec_t usec;
c19ffd9f 1027
7e1851e3
LP
1028 /* UDP connection failure get reported via ICMP and then are possible delivered to us on the next
1029 * recvmsg(). Treat this like a lost packet. */
1030
92ec902a 1031 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
7e1851e3 1032 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
274b8748 1033 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
7e1851e3
LP
1034
1035 dns_transaction_retry(t);
1036 return 0;
1037 }
1038 if (r < 0) {
7cc6ed7b
LP
1039 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
1040 t->answer_errno = -r;
7e1851e3
LP
1041 return 0;
1042 }
1043
1044 r = dns_packet_validate_reply(p);
1045 if (r < 0) {
1046 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
1047 return 0;
1048 }
1049 if (r == 0) {
e09f605e 1050 log_debug("Received inappropriate DNS packet as response, ignoring.");
7e1851e3
LP
1051 return 0;
1052 }
1053
1054 if (DNS_PACKET_ID(p) != t->id) {
e09f605e 1055 log_debug("Received packet with incorrect transaction ID, ignoring.");
7e1851e3
LP
1056 return 0;
1057 }
c19ffd9f 1058
7e1851e3 1059 dns_transaction_process_reply(t, p);
c19ffd9f
TG
1060 return 0;
1061}
1062
49cce12d 1063static int dns_transaction_emit_udp(DnsTransaction *t) {
c19ffd9f
TG
1064 int r;
1065
1066 assert(t);
c19ffd9f 1067
519ef046 1068 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
c19ffd9f 1069
519ef046 1070 r = dns_transaction_pick_server(t);
471d40d9
TG
1071 if (r < 0)
1072 return r;
c19ffd9f 1073
274b8748 1074 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP)
519ef046
LP
1075 return -EAGAIN;
1076
92ec902a 1077 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
91adc4db
LP
1078 return -EOPNOTSUPP;
1079
519ef046
LP
1080 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1081 int fd;
1082
1083 dns_transaction_close_connection(t);
c19ffd9f 1084
519ef046
LP
1085 fd = dns_scope_socket_udp(t->scope, t->server, 53);
1086 if (fd < 0)
1087 return fd;
1088
1089 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1090 if (r < 0) {
1091 safe_close(fd);
1092 return r;
1093 }
1094
aa4a9deb 1095 (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
519ef046
LP
1096 t->dns_udp_fd = fd;
1097 }
1098
274b8748 1099 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
519ef046
LP
1100 if (r < 0)
1101 return r;
1102 } else
1103 dns_transaction_close_connection(t);
1104
1105 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
471d40d9
TG
1106 if (r < 0)
1107 return r;
c19ffd9f 1108
519ef046 1109 dns_transaction_reset_answer(t);
be808ea0 1110
471d40d9 1111 return 0;
c19ffd9f
TG
1112}
1113
ec2c5e43
LP
1114static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1115 DnsTransaction *t = userdata;
ec2c5e43
LP
1116
1117 assert(s);
1118 assert(t);
1119
ef7ce6df
DM
1120 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
1121 /* Timeout reached? Increase the timeout for the server used */
1122 switch (t->scope->protocol) {
49cce12d 1123
ef7ce6df
DM
1124 case DNS_PROTOCOL_DNS:
1125 assert(t->server);
274b8748 1126 dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
ef7ce6df 1127 break;
49cce12d 1128
ef7ce6df
DM
1129 case DNS_PROTOCOL_LLMNR:
1130 case DNS_PROTOCOL_MDNS:
1131 dns_scope_packet_lost(t->scope, usec - t->start_usec);
ef7ce6df 1132 break;
49cce12d 1133
ef7ce6df
DM
1134 default:
1135 assert_not_reached("Invalid DNS protocol.");
1136 }
1137
1138 if (t->initial_jitter_scheduled)
1139 t->initial_jitter_elapsed = true;
be808ea0
TG
1140 }
1141
423659ab
LP
1142 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1143
8d10d620 1144 dns_transaction_retry(t);
ec2c5e43
LP
1145 return 0;
1146}
1147
9df3ba6c
TG
1148static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1149 assert(t);
1150 assert(t->scope);
1151
1152 switch (t->scope->protocol) {
49cce12d 1153
9df3ba6c
TG
1154 case DNS_PROTOCOL_DNS:
1155 assert(t->server);
9df3ba6c 1156 return t->server->resend_timeout;
49cce12d 1157
9df3ba6c 1158 case DNS_PROTOCOL_MDNS:
11a27c2e
DM
1159 assert(t->n_attempts > 0);
1160 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
49cce12d 1161
11a27c2e 1162 case DNS_PROTOCOL_LLMNR:
9df3ba6c 1163 return t->scope->resend_timeout;
49cce12d 1164
9df3ba6c
TG
1165 default:
1166 assert_not_reached("Invalid DNS protocol.");
1167 }
1168}
1169
c842ff24 1170static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
ec2c5e43
LP
1171 int r;
1172
1173 assert(t);
1174
f535705a 1175 dns_transaction_stop_timeout(t);
ec2c5e43 1176
edbcc1fd
LP
1177 r = dns_scope_network_good(t->scope);
1178 if (r < 0)
1179 return r;
1180 if (r == 0) {
1181 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
1182 return 0;
1183 }
1184
ec2c5e43
LP
1185 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1186 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1187 return 0;
1188 }
1189
cbe4216d 1190 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
ec2c5e43
LP
1191 /* If we already tried via a stream, then we don't
1192 * retry on LLMNR. See RFC 4795, Section 2.7. */
1193 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1194 return 0;
1195 }
1196
1197 t->n_attempts++;
9df3ba6c 1198 t->start_usec = ts;
c61d2b44
LP
1199
1200 dns_transaction_reset_answer(t);
c5b4f861 1201 dns_transaction_flush_dnssec_transactions(t);
ec2c5e43 1202
0d2cd476
LP
1203 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1204 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
8e54f5d9 1205 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, t->key, &t->answer);
0d2cd476
LP
1206 if (r < 0)
1207 return r;
1208 if (r > 0) {
1209 t->answer_rcode = DNS_RCODE_SUCCESS;
1210 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
931851e8 1211 t->answer_authenticated = true;
0d2cd476
LP
1212 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1213 return 0;
1214 }
b2b796b8 1215
1c02e7ba 1216 if (dns_name_is_root(dns_resource_key_name(t->key)) &&
b2b796b8
LP
1217 t->key->type == DNS_TYPE_DS) {
1218
1219 /* Hmm, this is a request for the root DS? A
1220 * DS RR doesn't exist in the root zone, and
1221 * if our trust anchor didn't know it either,
1222 * this means we cannot do any DNSSEC logic
1223 * anymore. */
1224
1ed8c0fb 1225 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
b2b796b8
LP
1226 /* We are in downgrade mode. In this
1227 * case, synthesize an unsigned empty
1228 * response, so that the any lookup
1229 * depending on this one can continue
1230 * assuming there was no DS, and hence
1231 * the root zone was unsigned. */
1232
1233 t->answer_rcode = DNS_RCODE_SUCCESS;
1234 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1235 t->answer_authenticated = false;
1236 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1237 } else
1238 /* If we are not in downgrade mode,
1239 * then fail the lookup, because we
1240 * cannot reasonably answer it. There
1241 * might be DS RRs, but we don't know
1242 * them, and the DNS server won't tell
1243 * them to us (and even if it would,
202b76ae 1244 * we couldn't validate and trust them. */
b2b796b8
LP
1245 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1246
1247 return 0;
1248 }
0d2cd476
LP
1249 }
1250
1251 /* Check the zone, but only if this transaction is not used
d746bb3e 1252 * for probing or verifying a zone item. */
547973de 1253 if (set_isempty(t->notify_zone_items)) {
d746bb3e 1254
ae6a4bbf 1255 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
d746bb3e
LP
1256 if (r < 0)
1257 return r;
1258 if (r > 0) {
ae6a4bbf 1259 t->answer_rcode = DNS_RCODE_SUCCESS;
c3bc53e6 1260 t->answer_source = DNS_TRANSACTION_ZONE;
931851e8 1261 t->answer_authenticated = true;
d746bb3e
LP
1262 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1263 return 0;
1264 }
1265 }
1266
4d926a69
LP
1267 /* Check the cache, but only if this transaction is not used
1268 * for probing or verifying a zone item. */
547973de 1269 if (set_isempty(t->notify_zone_items)) {
2c27fbca 1270
4d926a69
LP
1271 /* Before trying the cache, let's make sure we figured out a
1272 * server to use. Should this cause a change of server this
1273 * might flush the cache. */
1274 dns_scope_get_dns_server(t->scope);
2c27fbca 1275
4d926a69
LP
1276 /* Let's then prune all outdated entries */
1277 dns_cache_prune(&t->scope->cache);
1278
931851e8 1279 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
4d926a69
LP
1280 if (r < 0)
1281 return r;
1282 if (r > 0) {
c3bc53e6 1283 t->answer_source = DNS_TRANSACTION_CACHE;
ae6a4bbf 1284 if (t->answer_rcode == DNS_RCODE_SUCCESS)
4d926a69
LP
1285 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1286 else
3bbdc31d 1287 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
4d926a69
LP
1288 return 0;
1289 }
ec2c5e43
LP
1290 }
1291
1effe965
DM
1292 return 1;
1293}
1294
0afa57e2
DM
1295static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1296
1297 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
7778dfff 1298 bool add_known_answers = false;
0afa57e2
DM
1299 DnsTransaction *other;
1300 unsigned qdcount;
1301 usec_t ts;
1302 int r;
1303
1304 assert(t);
1305 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1306
e5abebab 1307 /* Discard any previously prepared packet, so we can start over and coalesce again */
0afa57e2
DM
1308 t->sent = dns_packet_unref(t->sent);
1309
1310 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1311 if (r < 0)
1312 return r;
1313
1314 r = dns_packet_append_key(p, t->key, NULL);
1315 if (r < 0)
1316 return r;
1317
1318 qdcount = 1;
1319
7778dfff
DM
1320 if (dns_key_is_shared(t->key))
1321 add_known_answers = true;
1322
0afa57e2
DM
1323 /*
1324 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1325 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1326 * in our current scope, and see whether their timing contraints allow them to be sent.
1327 */
1328
1329 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1330
1331 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1332
1333 /* Skip ourselves */
1334 if (other == t)
1335 continue;
1336
1337 if (other->state != DNS_TRANSACTION_PENDING)
1338 continue;
1339
1340 if (other->next_attempt_after > ts)
1341 continue;
1342
1343 if (qdcount >= UINT16_MAX)
1344 break;
1345
1346 r = dns_packet_append_key(p, other->key, NULL);
1347
1348 /*
1349 * If we can't stuff more questions into the packet, just give up.
1350 * One of the 'other' transactions will fire later and take care of the rest.
1351 */
1352 if (r == -EMSGSIZE)
1353 break;
1354
1355 if (r < 0)
1356 return r;
1357
c842ff24 1358 r = dns_transaction_prepare(other, ts);
0afa57e2
DM
1359 if (r <= 0)
1360 continue;
1361
1362 ts += transaction_get_resend_timeout(other);
1363
1364 r = sd_event_add_time(
1365 other->scope->manager->event,
1366 &other->timeout_event_source,
1367 clock_boottime_or_monotonic(),
1368 ts, 0,
1369 on_transaction_timeout, other);
1370 if (r < 0)
1371 return r;
1372
aa4a9deb
LP
1373 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1374
0afa57e2
DM
1375 other->state = DNS_TRANSACTION_PENDING;
1376 other->next_attempt_after = ts;
1377
313cefa1 1378 qdcount++;
7778dfff
DM
1379
1380 if (dns_key_is_shared(other->key))
1381 add_known_answers = true;
0afa57e2
DM
1382 }
1383
1384 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
0afa57e2 1385
7778dfff
DM
1386 /* Append known answer section if we're asking for any shared record */
1387 if (add_known_answers) {
1388 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1389 if (r < 0)
1390 return r;
1391 }
1392
0afa57e2
DM
1393 t->sent = p;
1394 p = NULL;
1395
1396 return 0;
1397}
1398
1399static int dns_transaction_make_packet(DnsTransaction *t) {
1400 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1401 int r;
1402
1403 assert(t);
1404
1405 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1406 return dns_transaction_make_packet_mdns(t);
1407
1408 if (t->sent)
1409 return 0;
1410
b652d4a2 1411 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
0afa57e2
DM
1412 if (r < 0)
1413 return r;
1414
0afa57e2
DM
1415 r = dns_packet_append_key(p, t->key, NULL);
1416 if (r < 0)
1417 return r;
1418
1419 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1420 DNS_PACKET_HEADER(p)->id = t->id;
1421
1422 t->sent = p;
1423 p = NULL;
1424
1425 return 0;
1426}
1427
1effe965
DM
1428int dns_transaction_go(DnsTransaction *t) {
1429 usec_t ts;
1430 int r;
202b76ae 1431 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
1effe965
DM
1432
1433 assert(t);
1434
1435 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
547973de 1436
c842ff24 1437 r = dns_transaction_prepare(t, ts);
1effe965
DM
1438 if (r <= 0)
1439 return r;
1440
202b76ae 1441 log_debug("Transaction %" PRIu16 " for <%s> scope %s on %s/%s.",
a5784c49 1442 t->id,
202b76ae 1443 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
a5784c49
LP
1444 dns_protocol_to_string(t->scope->protocol),
1445 t->scope->link ? t->scope->link->name : "*",
202b76ae 1446 af_to_name_short(t->scope->family));
1effe965 1447
ef7ce6df 1448 if (!t->initial_jitter_scheduled &&
ea12bcc7
DM
1449 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
1450 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
1451 usec_t jitter, accuracy;
6e068472
LP
1452
1453 /* RFC 4795 Section 2.7 suggests all queries should be
1454 * delayed by a random time from 0 to JITTER_INTERVAL. */
1455
ef7ce6df 1456 t->initial_jitter_scheduled = true;
6e068472
LP
1457
1458 random_bytes(&jitter, sizeof(jitter));
ea12bcc7
DM
1459
1460 switch (t->scope->protocol) {
519ef046 1461
ea12bcc7
DM
1462 case DNS_PROTOCOL_LLMNR:
1463 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1464 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1465 break;
519ef046 1466
ea12bcc7
DM
1467 case DNS_PROTOCOL_MDNS:
1468 jitter %= MDNS_JITTER_RANGE_USEC;
1469 jitter += MDNS_JITTER_MIN_USEC;
1470 accuracy = MDNS_JITTER_RANGE_USEC;
1471 break;
1472 default:
1473 assert_not_reached("bad protocol");
1474 }
6e068472
LP
1475
1476 r = sd_event_add_time(
1477 t->scope->manager->event,
1478 &t->timeout_event_source,
1479 clock_boottime_or_monotonic(),
ea12bcc7 1480 ts + jitter, accuracy,
6e068472
LP
1481 on_transaction_timeout, t);
1482 if (r < 0)
1483 return r;
1484
aa4a9deb
LP
1485 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1486
6e068472 1487 t->n_attempts = 0;
a9da14e1 1488 t->next_attempt_after = ts;
6e068472
LP
1489 t->state = DNS_TRANSACTION_PENDING;
1490
ea12bcc7 1491 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
6e068472
LP
1492 return 0;
1493 }
1494
ec2c5e43
LP
1495 /* Otherwise, we need to ask the network */
1496 r = dns_transaction_make_packet(t);
ec2c5e43
LP
1497 if (r < 0)
1498 return r;
1499
1500 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
1c02e7ba
ZJS
1501 (dns_name_endswith(dns_resource_key_name(t->key), "in-addr.arpa") > 0 ||
1502 dns_name_endswith(dns_resource_key_name(t->key), "ip6.arpa") > 0)) {
ec2c5e43
LP
1503
1504 /* RFC 4795, Section 2.4. says reverse lookups shall
1505 * always be made via TCP on LLMNR */
1506 r = dns_transaction_open_tcp(t);
1507 } else {
be808ea0
TG
1508 /* Try via UDP, and if that fails due to large size or lack of
1509 * support try via TCP */
49cce12d 1510 r = dns_transaction_emit_udp(t);
29ab0552
LP
1511 if (r == -EMSGSIZE)
1512 log_debug("Sending query via TCP since it is too large.");
034e8031
LP
1513 if (r == -EAGAIN)
1514 log_debug("Sending query via TCP since server doesn't support UDP.");
be808ea0 1515 if (r == -EMSGSIZE || r == -EAGAIN)
ec2c5e43
LP
1516 r = dns_transaction_open_tcp(t);
1517 }
be808ea0 1518
ec2c5e43
LP
1519 if (r == -ESRCH) {
1520 /* No servers to send this to? */
1521 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1522 return 0;
91adc4db
LP
1523 }
1524 if (r == -EOPNOTSUPP) {
1525 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1526 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1527 return 0;
1528 }
0791110f 1529 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(-r)) {
e94968ba 1530 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
0791110f
LP
1531 * answer this request with this protocol. */
1532 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
1533 return 0;
1534 }
91adc4db 1535 if (r < 0) {
7cc6ed7b
LP
1536 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1537 return r;
13b551ac 1538
ec2c5e43 1539 /* Couldn't send? Try immediately again, with a new server */
519ef046 1540 dns_scope_next_dns_server(t->scope);
ec2c5e43
LP
1541
1542 return dns_transaction_go(t);
1543 }
1544
a9da14e1
DM
1545 ts += transaction_get_resend_timeout(t);
1546
9a015429
LP
1547 r = sd_event_add_time(
1548 t->scope->manager->event,
1549 &t->timeout_event_source,
1550 clock_boottime_or_monotonic(),
a9da14e1 1551 ts, 0,
9a015429 1552 on_transaction_timeout, t);
ec2c5e43
LP
1553 if (r < 0)
1554 return r;
1555
aa4a9deb
LP
1556 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1557
ec2c5e43 1558 t->state = DNS_TRANSACTION_PENDING;
a9da14e1
DM
1559 t->next_attempt_after = ts;
1560
ec2c5e43
LP
1561 return 1;
1562}
1563
f2992dc1
LP
1564static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
1565 DnsTransaction *n;
1566 Iterator i;
1567 int r;
1568
1569 assert(t);
1570 assert(aux);
1571
1572 /* Try to find cyclic dependencies between transaction objects */
1573
1574 if (t == aux)
1575 return 1;
1576
3eb6aa00 1577 SET_FOREACH(n, aux->dnssec_transactions, i) {
f2992dc1
LP
1578 r = dns_transaction_find_cyclic(t, n);
1579 if (r != 0)
1580 return r;
1581 }
1582
3eb6aa00 1583 return 0;
f2992dc1
LP
1584}
1585
547973de
LP
1586static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1587 DnsTransaction *aux;
1588 int r;
1589
1590 assert(t);
1591 assert(ret);
1592 assert(key);
1593
1594 aux = dns_scope_find_transaction(t->scope, key, true);
1595 if (!aux) {
1596 r = dns_transaction_new(&aux, t->scope, key);
1597 if (r < 0)
1598 return r;
1599 } else {
1600 if (set_contains(t->dnssec_transactions, aux)) {
1601 *ret = aux;
1602 return 0;
1603 }
f2992dc1
LP
1604
1605 r = dns_transaction_find_cyclic(t, aux);
1606 if (r < 0)
1607 return r;
1608 if (r > 0) {
202b76ae
ZJS
1609 char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
1610
1611 log_debug("Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
f2992dc1 1612 aux->id,
202b76ae 1613 dns_resource_key_to_string(t->key, s, sizeof s),
f2992dc1 1614 t->id,
202b76ae
ZJS
1615 dns_resource_key_to_string(aux->key, saux, sizeof saux));
1616
f2992dc1
LP
1617 return -ELOOP;
1618 }
547973de
LP
1619 }
1620
1621 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1622 if (r < 0)
1623 goto gc;
1624
1625 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1626 if (r < 0)
1627 goto gc;
1628
1629 r = set_put(t->dnssec_transactions, aux);
1630 if (r < 0)
1631 goto gc;
1632
1633 r = set_put(aux->notify_transactions, t);
1634 if (r < 0) {
1635 (void) set_remove(t->dnssec_transactions, aux);
1636 goto gc;
1637 }
1638
1639 *ret = aux;
1640 return 1;
1641
1642gc:
1643 dns_transaction_gc(aux);
1644 return r;
1645}
1646
1647static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1648 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1649 DnsTransaction *aux;
1650 int r;
1651
1652 assert(t);
1653 assert(key);
1654
1655 /* Try to get the data from the trust anchor */
8e54f5d9 1656 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
547973de
LP
1657 if (r < 0)
1658 return r;
1659 if (r > 0) {
1660 r = dns_answer_extend(&t->validated_keys, a);
1661 if (r < 0)
1662 return r;
1663
1664 return 0;
1665 }
1666
1667 /* This didn't work, ask for it via the network/cache then. */
1668 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
f2992dc1
LP
1669 if (r == -ELOOP) /* This would result in a cyclic dependency */
1670 return 0;
547973de
LP
1671 if (r < 0)
1672 return r;
1673
1674 if (aux->state == DNS_TRANSACTION_NULL) {
1675 r = dns_transaction_go(aux);
1676 if (r < 0)
1677 return r;
1678 }
1679
f2992dc1 1680 return 1;
547973de
LP
1681}
1682
8a516214
LP
1683static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
1684 int r;
1685
1686 assert(t);
1687
c629ff58 1688 /* Check whether the specified name is in the NTA
8a516214
LP
1689 * database, either in the global one, or the link-local
1690 * one. */
1691
1692 r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
1693 if (r != 0)
1694 return r;
1695
1696 if (!t->scope->link)
1697 return 0;
1698
1699 return set_contains(t->scope->link->dnssec_negative_trust_anchors, name);
1700}
1701
105e1512
LP
1702static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1703 int r;
1704
1705 assert(t);
1706
1707 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1708 * RRs to prove it */
1709
1710 r = dns_transaction_has_positive_answer(t, NULL);
1711 if (r < 0)
1712 return r;
1713 if (r > 0)
1714 return false;
1715
8e54f5d9
LP
1716 /* Is this key explicitly listed as a negative trust anchor?
1717 * If so, it's nothing we need to care about */
1c02e7ba 1718 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
8e54f5d9
LP
1719 if (r < 0)
1720 return r;
1721 if (r > 0)
1722 return false;
1723
105e1512
LP
1724 /* The answer does not contain any RRs that match to the
1725 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1726 * included. If not, the answer is unsigned. */
1727
1728 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1729 if (r < 0)
1730 return r;
1731 if (r > 0)
1732 return false;
1733
1734 return true;
1735}
1736
1737static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1738 int r;
1739
1740 assert(t);
1741 assert(rr);
1742
1743 /* Check if the specified RR is the "primary" response,
1744 * i.e. either matches the question precisely or is a
4cb94977 1745 * CNAME/DNAME for it. */
105e1512
LP
1746
1747 r = dns_resource_key_match_rr(t->key, rr, NULL);
1748 if (r != 0)
1749 return r;
1750
4cb94977 1751 return dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
105e1512
LP
1752}
1753
92ec902a
LP
1754static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
1755 assert(t);
1756
1757 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
1758 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
1759
1760 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1761 return false;
1762
1763 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
1764 * be supported, hence return true. */
1765 if (!t->server)
1766 return true;
1767
274b8748 1768 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_DO)
92ec902a
LP
1769 return false;
1770
1771 return dns_server_dnssec_supported(t->server);
1772}
1773
1774static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
1775 DnsTransaction *dt;
1776 Iterator i;
1777
1778 assert(t);
1779
1780 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
1781
1782 if (!dns_transaction_dnssec_supported(t))
1783 return false;
1784
1785 SET_FOREACH(dt, t->dnssec_transactions, i)
1786 if (!dns_transaction_dnssec_supported(dt))
1787 return false;
1788
1789 return true;
1790}
1791
547973de
LP
1792int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
1793 DnsResourceRecord *rr;
105e1512 1794
547973de
LP
1795 int r;
1796
1797 assert(t);
1798
105e1512
LP
1799 /*
1800 * Retrieve all auxiliary RRs for the answer we got, so that
1801 * we can verify signatures or prove that RRs are rightfully
1802 * unsigned. Specifically:
1803 *
1804 * - For RRSIG we get the matching DNSKEY
1805 * - For DNSKEY we get the matching DS
1806 * - For unsigned SOA/NS we get the matching DS
b63fca62 1807 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
105e1512
LP
1808 * - For other unsigned RRs we get the matching SOA RR
1809 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1810 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1811 */
1812
b652d4a2 1813 if (t->scope->dnssec_mode == DNSSEC_NO)
547973de 1814 return 0;
92ec902a
LP
1815 if (t->answer_source != DNS_TRANSACTION_NETWORK)
1816 return 0; /* We only need to validate stuff from the network */
1817 if (!dns_transaction_dnssec_supported(t))
1818 return 0; /* If we can't do DNSSEC anyway there's no point in geting the auxiliary RRs */
b652d4a2 1819
547973de
LP
1820 DNS_ANSWER_FOREACH(rr, t->answer) {
1821
105e1512
LP
1822 if (dns_type_is_pseudo(rr->key->type))
1823 continue;
1824
8e54f5d9 1825 /* If this RR is in the negative trust anchor, we don't need to validate it. */
1c02e7ba 1826 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
1827 if (r < 0)
1828 return r;
1829 if (r > 0)
1830 continue;
1831
547973de
LP
1832 switch (rr->key->type) {
1833
1834 case DNS_TYPE_RRSIG: {
1835 /* For each RRSIG we request the matching DNSKEY */
1836 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1837
1838 /* If this RRSIG is about a DNSKEY RR and the
1839 * signer is the same as the owner, then we
1840 * already have the DNSKEY, and we don't have
1841 * to look for more. */
1842 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1c02e7ba 1843 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
547973de
LP
1844 if (r < 0)
1845 return r;
1846 if (r > 0)
1847 continue;
1848 }
1849
105e1512
LP
1850 /* If the signer is not a parent of our
1851 * original query, then this is about an
1852 * auxiliary RRset, but not anything we asked
1853 * for. In this case we aren't interested,
1854 * because we don't want to request additional
1855 * RRs for stuff we didn't really ask for, and
1856 * also to avoid request loops, where
1857 * additional RRs from one transaction result
1858 * in another transaction whose additonal RRs
1859 * point back to the original transaction, and
1860 * we deadlock. */
1c02e7ba 1861 r = dns_name_endswith(dns_resource_key_name(t->key), rr->rrsig.signer);
547973de
LP
1862 if (r < 0)
1863 return r;
1864 if (r == 0)
1865 continue;
1866
1867 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1868 if (!dnskey)
1869 return -ENOMEM;
1870
1c02e7ba
ZJS
1871 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
1872 t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
547973de
LP
1873 r = dns_transaction_request_dnssec_rr(t, dnskey);
1874 if (r < 0)
1875 return r;
1876 break;
1877 }
1878
1879 case DNS_TYPE_DNSKEY: {
1880 /* For each DNSKEY we request the matching DS */
1881 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1882
105e1512
LP
1883 /* If the DNSKEY we are looking at is not for
1884 * zone we are interested in, nor any of its
1885 * parents, we aren't interested, and don't
1886 * request it. After all, we don't want to end
1887 * up in request loops, and want to keep
1888 * additional traffic down. */
1889
1c02e7ba 1890 r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
105e1512
LP
1891 if (r < 0)
1892 return r;
1893 if (r == 0)
1894 continue;
1895
1c02e7ba 1896 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
547973de
LP
1897 if (!ds)
1898 return -ENOMEM;
1899
1c02e7ba
ZJS
1900 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
1901 t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
105e1512
LP
1902 r = dns_transaction_request_dnssec_rr(t, ds);
1903 if (r < 0)
1904 return r;
547973de 1905
105e1512
LP
1906 break;
1907 }
1908
105e1512
LP
1909 case DNS_TYPE_SOA:
1910 case DNS_TYPE_NS: {
1911 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1912
1913 /* For an unsigned SOA or NS, try to acquire
1914 * the matching DS RR, as we are at a zone cut
1915 * then, and whether a DS exists tells us
1916 * whether the zone is signed. Do so only if
1917 * this RR matches our original question,
1918 * however. */
1919
1920 r = dns_resource_key_match_rr(t->key, rr, NULL);
1921 if (r < 0)
1922 return r;
1923 if (r == 0)
1924 continue;
1925
1926 r = dnssec_has_rrsig(t->answer, rr->key);
1927 if (r < 0)
1928 return r;
1929 if (r > 0)
1930 continue;
1931
1c02e7ba 1932 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
105e1512
LP
1933 if (!ds)
1934 return -ENOMEM;
1935
1c02e7ba
ZJS
1936 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
1937 t->id, dns_resource_key_name(rr->key));
547973de
LP
1938 r = dns_transaction_request_dnssec_rr(t, ds);
1939 if (r < 0)
1940 return r;
1941
1942 break;
105e1512
LP
1943 }
1944
b63fca62 1945 case DNS_TYPE_DS:
105e1512
LP
1946 case DNS_TYPE_CNAME:
1947 case DNS_TYPE_DNAME: {
1948 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1949 const char *name;
1950
1951 /* CNAMEs and DNAMEs cannot be located at a
1952 * zone apex, hence ask for the parent SOA for
1953 * unsigned CNAME/DNAME RRs, maybe that's the
1954 * apex. But do all that only if this is
1955 * actually a response to our original
b63fca62
LP
1956 * question.
1957 *
1958 * Similar for DS RRs, which are signed when
1959 * the parent SOA is signed. */
105e1512
LP
1960
1961 r = dns_transaction_is_primary_response(t, rr);
1962 if (r < 0)
1963 return r;
1964 if (r == 0)
1965 continue;
1966
1967 r = dnssec_has_rrsig(t->answer, rr->key);
1968 if (r < 0)
1969 return r;
1970 if (r > 0)
1971 continue;
1972
43e6779a
LP
1973 r = dns_answer_has_dname_for_cname(t->answer, rr);
1974 if (r < 0)
1975 return r;
1976 if (r > 0)
1977 continue;
1978
1c02e7ba 1979 name = dns_resource_key_name(rr->key);
105e1512
LP
1980 r = dns_name_parent(&name);
1981 if (r < 0)
1982 return r;
1983 if (r == 0)
1984 continue;
1985
1986 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1987 if (!soa)
1988 return -ENOMEM;
1989
1c02e7ba
ZJS
1990 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
1991 t->id, dns_resource_key_name(rr->key));
105e1512
LP
1992 r = dns_transaction_request_dnssec_rr(t, soa);
1993 if (r < 0)
1994 return r;
1995
1996 break;
1997 }
1998
1999 default: {
2000 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2001
b63fca62
LP
2002 /* For other unsigned RRsets (including
2003 * NSEC/NSEC3!), look for proof the zone is
2004 * unsigned, by requesting the SOA RR of the
2005 * zone. However, do so only if they are
2006 * directly relevant to our original
105e1512
LP
2007 * question. */
2008
2009 r = dns_transaction_is_primary_response(t, rr);
2010 if (r < 0)
2011 return r;
2012 if (r == 0)
2013 continue;
2014
2015 r = dnssec_has_rrsig(t->answer, rr->key);
2016 if (r < 0)
2017 return r;
2018 if (r > 0)
2019 continue;
2020
1c02e7ba 2021 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
105e1512
LP
2022 if (!soa)
2023 return -ENOMEM;
2024
1c02e7ba
ZJS
2025 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
2026 t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
105e1512
LP
2027 r = dns_transaction_request_dnssec_rr(t, soa);
2028 if (r < 0)
2029 return r;
2030 break;
547973de
LP
2031 }}
2032 }
2033
105e1512
LP
2034 /* Above, we requested everything necessary to validate what
2035 * we got. Now, let's request what we need to validate what we
2036 * didn't get... */
2037
2038 r = dns_transaction_has_unsigned_negative_answer(t);
2039 if (r < 0)
2040 return r;
2041 if (r > 0) {
2042 const char *name;
2043
1c02e7ba 2044 name = dns_resource_key_name(t->key);
105e1512
LP
2045
2046 /* If this was a SOA or NS request, then this
2047 * indicates that we are not at a zone apex, hence ask
2048 * the parent name instead. If this was a DS request,
2049 * then it's signed when the parent zone is signed,
2050 * hence ask the parent in that case, too. */
2051
2052 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2053 r = dns_name_parent(&name);
2054 if (r < 0)
2055 return r;
2056 if (r > 0)
1c02e7ba
ZJS
2057 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).",
2058 t->id, dns_resource_key_name(t->key));
105e1512
LP
2059 else
2060 name = NULL;
2061 } else
1c02e7ba
ZJS
2062 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).",
2063 t->id, dns_resource_key_name(t->key));
105e1512
LP
2064
2065 if (name) {
2066 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2067
2068 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
2069 if (!soa)
2070 return -ENOMEM;
2071
2072 r = dns_transaction_request_dnssec_rr(t, soa);
2073 if (r < 0)
2074 return r;
2075 }
2076 }
2077
2078 return dns_transaction_dnssec_is_live(t);
547973de
LP
2079}
2080
2081void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
547973de 2082 assert(t);
547973de
LP
2083 assert(source);
2084
942eb2e7
LP
2085 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2086 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2087 the state is VALIDATING however, we should check if we are complete now. */
105e1512 2088
942eb2e7
LP
2089 if (t->state == DNS_TRANSACTION_VALIDATING)
2090 dns_transaction_process_dnssec(t);
547973de
LP
2091}
2092
105e1512
LP
2093static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2094 DnsResourceRecord *rr;
2095 int ifindex, r;
2096
2097 assert(t);
2098
2099 /* Add all DNSKEY RRs from the answer that are validated by DS
2100 * RRs from the list of validated keys to the list of
2101 * validated keys. */
2102
2103 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
2104
96bb7673 2105 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
105e1512
LP
2106 if (r < 0)
2107 return r;
2108 if (r == 0)
2109 continue;
2110
2111 /* If so, the DNSKEY is validated too. */
2112 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
2113 if (r < 0)
2114 return r;
2115 }
2116
2117 return 0;
2118}
2119
2120static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
56352fe9
LP
2121 int r;
2122
2123 assert(t);
2124 assert(rr);
2125
105e1512
LP
2126 /* Checks if the RR we are looking for must be signed with an
2127 * RRSIG. This is used for positive responses. */
24a5b982 2128
b652d4a2 2129 if (t->scope->dnssec_mode == DNSSEC_NO)
105e1512 2130 return false;
56352fe9 2131
105e1512
LP
2132 if (dns_type_is_pseudo(rr->key->type))
2133 return -EINVAL;
56352fe9 2134
1c02e7ba 2135 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
2136 if (r < 0)
2137 return r;
2138 if (r > 0)
2139 return false;
2140
105e1512 2141 switch (rr->key->type) {
56352fe9 2142
105e1512
LP
2143 case DNS_TYPE_RRSIG:
2144 /* RRSIGs are the signatures themselves, they need no signing. */
2145 return false;
2146
2147 case DNS_TYPE_SOA:
2148 case DNS_TYPE_NS: {
2149 DnsTransaction *dt;
2150 Iterator i;
2151
b63fca62 2152 /* For SOA or NS RRs we look for a matching DS transaction */
105e1512
LP
2153
2154 SET_FOREACH(dt, t->dnssec_transactions, i) {
2155
2156 if (dt->key->class != rr->key->class)
2157 continue;
2158 if (dt->key->type != DNS_TYPE_DS)
2159 continue;
2160
1c02e7ba 2161 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
105e1512
LP
2162 if (r < 0)
2163 return r;
2164 if (r == 0)
2165 continue;
2166
2167 /* We found a DS transactions for the SOA/NS
2168 * RRs we are looking at. If it discovered signed DS
2169 * RRs, then we need to be signed, too. */
2170
097a2517
TA
2171 if (!dt->answer_authenticated)
2172 return false;
105e1512 2173
097a2517 2174 return dns_answer_match_key(dt->answer, dt->key, NULL);
105e1512
LP
2175 }
2176
2177 /* We found nothing that proves this is safe to leave
2178 * this unauthenticated, hence ask inist on
2179 * authentication. */
2180 return true;
2181 }
2182
b63fca62 2183 case DNS_TYPE_DS:
105e1512
LP
2184 case DNS_TYPE_CNAME:
2185 case DNS_TYPE_DNAME: {
2186 const char *parent = NULL;
2187 DnsTransaction *dt;
2188 Iterator i;
2189
b63fca62
LP
2190 /*
2191 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2192 *
2193 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2194 */
105e1512
LP
2195
2196 SET_FOREACH(dt, t->dnssec_transactions, i) {
2197
2198 if (dt->key->class != rr->key->class)
2199 continue;
2200 if (dt->key->type != DNS_TYPE_SOA)
2201 continue;
2202
2203 if (!parent) {
1c02e7ba 2204 parent = dns_resource_key_name(rr->key);
105e1512
LP
2205 r = dns_name_parent(&parent);
2206 if (r < 0)
2207 return r;
2208 if (r == 0) {
b63fca62
LP
2209 if (rr->key->type == DNS_TYPE_DS)
2210 return true;
2211
105e1512
LP
2212 /* A CNAME/DNAME without a parent? That's sooo weird. */
2213 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2214 return -EBADMSG;
2215 }
2216 }
2217
1c02e7ba 2218 r = dns_name_equal(dns_resource_key_name(dt->key), parent);
105e1512
LP
2219 if (r < 0)
2220 return r;
2221 if (r == 0)
2222 continue;
2223
2224 return t->answer_authenticated;
2225 }
2226
2227 return true;
2228 }
2229
2230 default: {
2231 DnsTransaction *dt;
2232 Iterator i;
2233
b63fca62 2234 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
105e1512
LP
2235
2236 SET_FOREACH(dt, t->dnssec_transactions, i) {
2237
2238 if (dt->key->class != rr->key->class)
2239 continue;
2240 if (dt->key->type != DNS_TYPE_SOA)
2241 continue;
2242
1c02e7ba 2243 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
105e1512
LP
2244 if (r < 0)
2245 return r;
2246 if (r == 0)
2247 continue;
2248
2249 /* We found the transaction that was supposed to find
2250 * the SOA RR for us. It was successful, but found no
2251 * RR for us. This means we are not at a zone cut. In
2252 * this case, we require authentication if the SOA
2253 * lookup was authenticated too. */
2254 return t->answer_authenticated;
2255 }
2256
2257 return true;
2258 }}
56352fe9
LP
2259}
2260
d33b6cf3
LP
2261static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2262 DnsTransaction *dt;
2263 const char *tld;
2264 Iterator i;
2265 int r;
2266
2267 /* If DNSSEC downgrade mode is on, checks whether the
2268 * specified RR is one level below a TLD we have proven not to
2269 * exist. In such a case we assume that this is a private
2270 * domain, and permit it.
2271 *
2272 * This detects cases like the Fritz!Box router networks. Each
2273 * Fritz!Box router serves a private "fritz.box" zone, in the
2274 * non-existing TLD "box". Requests for the "fritz.box" domain
2275 * are served by the router itself, while requests for the
2276 * "box" domain will result in NXDOMAIN.
2277 *
2278 * Note that this logic is unable to detect cases where a
2279 * router serves a private DNS zone directly under
2280 * non-existing TLD. In such a case we cannot detect whether
2281 * the TLD is supposed to exist or not, as all requests we
2282 * make for it will be answered by the router's zone, and not
2283 * by the root zone. */
2284
2285 assert(t);
2286
2287 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2288 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2289
1c02e7ba 2290 tld = dns_resource_key_name(key);
d33b6cf3
LP
2291 r = dns_name_parent(&tld);
2292 if (r < 0)
2293 return r;
2294 if (r == 0)
2295 return false; /* Already the root domain */
2296
2297 if (!dns_name_is_single_label(tld))
2298 return false;
2299
2300 SET_FOREACH(dt, t->dnssec_transactions, i) {
2301
2302 if (dt->key->class != key->class)
2303 continue;
2304
1c02e7ba 2305 r = dns_name_equal(dns_resource_key_name(dt->key), tld);
d33b6cf3
LP
2306 if (r < 0)
2307 return r;
2308 if (r == 0)
2309 continue;
2310
2311 /* We found an auxiliary lookup we did for the TLD. If
2312 * that returned with NXDOMAIN, we know the TLD didn't
2313 * exist, and hence this might be a private zone. */
2314
2315 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2316 }
2317
2318 return false;
2319}
2320
105e1512
LP
2321static int dns_transaction_requires_nsec(DnsTransaction *t) {
2322 DnsTransaction *dt;
2323 const char *name;
2324 Iterator i;
2325 int r;
202b76ae 2326 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
56352fe9
LP
2327
2328 assert(t);
2329
105e1512
LP
2330 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2331 * this negative reply */
56352fe9 2332
b652d4a2 2333 if (t->scope->dnssec_mode == DNSSEC_NO)
105e1512 2334 return false;
56352fe9 2335
105e1512
LP
2336 if (dns_type_is_pseudo(t->key->type))
2337 return -EINVAL;
2338
1c02e7ba 2339 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
8e54f5d9
LP
2340 if (r < 0)
2341 return r;
2342 if (r > 0)
2343 return false;
2344
d33b6cf3
LP
2345 r = dns_transaction_in_private_tld(t, t->key);
2346 if (r < 0)
2347 return r;
2348 if (r > 0) {
2349 /* The lookup is from a TLD that is proven not to
2350 * exist, and we are in downgrade mode, hence ignore
2351 * that fact that we didn't get any NSEC RRs.*/
2352
202b76ae
ZJS
2353 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2354 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
d33b6cf3
LP
2355 return false;
2356 }
2357
1c02e7ba 2358 name = dns_resource_key_name(t->key);
105e1512
LP
2359
2360 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
2361
2362 /* We got a negative reply for this SOA/NS lookup? If
2363 * so, then we are not at a zone apex, and thus should
2364 * look at the result of the parent SOA lookup.
2365 *
2366 * We got a negative reply for this DS lookup? DS RRs
2367 * are signed when their parent zone is signed, hence
2368 * also check the parent SOA in this case. */
2369
2370 r = dns_name_parent(&name);
56352fe9
LP
2371 if (r < 0)
2372 return r;
2373 if (r == 0)
105e1512
LP
2374 return true;
2375 }
2376
2377 /* For all other RRs we check the SOA on the same level to see
2378 * if it's signed. */
2379
2380 SET_FOREACH(dt, t->dnssec_transactions, i) {
2381
2382 if (dt->key->class != t->key->class)
2383 continue;
2384 if (dt->key->type != DNS_TYPE_SOA)
56352fe9
LP
2385 continue;
2386
1c02e7ba 2387 r = dns_name_equal(dns_resource_key_name(dt->key), name);
56352fe9
LP
2388 if (r < 0)
2389 return r;
105e1512
LP
2390 if (r == 0)
2391 continue;
2392
2393 return dt->answer_authenticated;
56352fe9
LP
2394 }
2395
105e1512
LP
2396 /* If in doubt, require NSEC/NSEC3 */
2397 return true;
56352fe9
LP
2398}
2399
94aa7071
LP
2400static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2401 DnsResourceRecord *rrsig;
2402 bool found = false;
2403 int r;
2404
2405 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2406 * the specified RRset is authenticated (i.e. has a matching
2407 * DS RR). */
2408
1c02e7ba 2409 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
2410 if (r < 0)
2411 return r;
2412 if (r > 0)
2413 return false;
2414
94aa7071
LP
2415 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2416 DnsTransaction *dt;
2417 Iterator i;
2418
2419 r = dnssec_key_match_rrsig(rr->key, rrsig);
2420 if (r < 0)
2421 return r;
2422 if (r == 0)
2423 continue;
2424
2425 SET_FOREACH(dt, t->dnssec_transactions, i) {
2426
2427 if (dt->key->class != rr->key->class)
2428 continue;
2429
2430 if (dt->key->type == DNS_TYPE_DNSKEY) {
2431
1c02e7ba 2432 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
94aa7071
LP
2433 if (r < 0)
2434 return r;
2435 if (r == 0)
2436 continue;
2437
2438 /* OK, we found an auxiliary DNSKEY
2439 * lookup. If that lookup is
2440 * authenticated, report this. */
2441
2442 if (dt->answer_authenticated)
2443 return true;
2444
2445 found = true;
2446
2447 } else if (dt->key->type == DNS_TYPE_DS) {
2448
1c02e7ba 2449 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
94aa7071
LP
2450 if (r < 0)
2451 return r;
2452 if (r == 0)
2453 continue;
2454
2455 /* OK, we found an auxiliary DS
2456 * lookup. If that lookup is
2457 * authenticated and non-zero, we
2458 * won! */
2459
2460 if (!dt->answer_authenticated)
2461 return false;
2462
2463 return dns_answer_match_key(dt->answer, dt->key, NULL);
2464 }
2465 }
2466 }
2467
2468 return found ? false : -ENXIO;
2469}
2470
b652d4a2
LP
2471static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2472 assert(t);
2473 assert(rr);
2474
2475 /* We know that the root domain is signed, hence if it appears
2476 * not to be signed, there's a problem with the DNS server */
2477
2478 return rr->key->class == DNS_CLASS_IN &&
1c02e7ba 2479 dns_name_is_root(dns_resource_key_name(rr->key));
b652d4a2
LP
2480}
2481
0f87f3e8
LP
2482static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
2483 DnsResourceRecord *rr;
2484 int r;
2485
2486 assert(t);
2487
2488 /* Maybe warn the user that we encountered a revoked DNSKEY
2489 * for a key from our trust anchor. Note that we don't care
2490 * whether the DNSKEY can be authenticated or not. It's
2491 * sufficient if it is self-signed. */
2492
2493 DNS_ANSWER_FOREACH(rr, t->answer) {
d424da2a 2494 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
0f87f3e8
LP
2495 if (r < 0)
2496 return r;
2497 }
2498
2499 return 0;
2500}
2501
c9c72065
LP
2502static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
2503 bool changed;
2504 int r;
2505
2506 assert(t);
2507
2508 /* Removes all DNSKEY/DS objects from t->validated_keys that
2509 * our trust anchors database considers revoked. */
2510
2511 do {
2512 DnsResourceRecord *rr;
2513
2514 changed = false;
2515
2516 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
2517 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
2518 if (r < 0)
2519 return r;
2520 if (r > 0) {
2521 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
2522 if (r < 0)
2523 return r;
2524
2525 assert(r > 0);
2526 changed = true;
2527 break;
2528 }
2529 }
2530 } while (changed);
2531
2532 return 0;
2533}
2534
942eb2e7
LP
2535static int dns_transaction_copy_validated(DnsTransaction *t) {
2536 DnsTransaction *dt;
2537 Iterator i;
2538 int r;
2539
2540 assert(t);
2541
2542 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
2543
2544 SET_FOREACH(dt, t->dnssec_transactions, i) {
2545
2546 if (DNS_TRANSACTION_IS_LIVE(dt->state))
2547 continue;
2548
2549 if (!dt->answer_authenticated)
2550 continue;
2551
2552 r = dns_answer_extend(&t->validated_keys, dt->answer);
2553 if (r < 0)
2554 return r;
2555 }
2556
2557 return 0;
2558}
2559
c690b20a
ZJS
2560typedef enum {
2561 DNSSEC_PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
2562 DNSSEC_PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
2563 DNSSEC_PHASE_ALL, /* Phase #3, validate everything else */
2564} Phase;
2565
2566static int dnssec_validate_records(
2567 DnsTransaction *t,
2568 Phase phase,
2569 bool *have_nsec,
2570 DnsAnswer **validated) {
2571
547973de 2572 DnsResourceRecord *rr;
56352fe9 2573 int r;
547973de 2574
c690b20a 2575 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
547973de 2576
c690b20a
ZJS
2577 DNS_ANSWER_FOREACH(rr, t->answer) {
2578 DnsResourceRecord *rrsig = NULL;
2579 DnssecResult result;
547973de 2580
c690b20a
ZJS
2581 switch (rr->key->type) {
2582 case DNS_TYPE_RRSIG:
2583 continue;
547973de 2584
c690b20a
ZJS
2585 case DNS_TYPE_DNSKEY:
2586 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
2587 if (phase == DNSSEC_PHASE_NSEC)
2588 continue;
2589 break;
547973de 2590
c690b20a
ZJS
2591 case DNS_TYPE_NSEC:
2592 case DNS_TYPE_NSEC3:
2593 *have_nsec = true;
547973de 2594
c690b20a
ZJS
2595 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
2596 if (phase == DNSSEC_PHASE_DNSKEY)
2597 continue;
2598 break;
105e1512 2599
c690b20a
ZJS
2600 default:
2601 /* We validate all other RRs only in the ALL phases */
2602 if (phase != DNSSEC_PHASE_ALL)
2603 continue;
2604 }
b652d4a2 2605
c690b20a
ZJS
2606 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
2607 if (r < 0)
2608 return r;
547973de 2609
c690b20a 2610 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
0f87f3e8 2611
c690b20a 2612 if (result == DNSSEC_VALIDATED) {
942eb2e7 2613
c690b20a
ZJS
2614 if (rr->key->type == DNS_TYPE_DNSKEY) {
2615 /* If we just validated a DNSKEY RRset, then let's add these keys to
2616 * the set of validated keys for this transaction. */
547973de 2617
c690b20a
ZJS
2618 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2619 if (r < 0)
2620 return r;
c9c72065 2621
c690b20a
ZJS
2622 /* Some of the DNSKEYs we just added might already have been revoked,
2623 * remove them again in that case. */
2624 r = dns_transaction_invalidate_revoked_keys(t);
2625 if (r < 0)
2626 return r;
2627 }
547973de 2628
c690b20a
ZJS
2629 /* Add the validated RRset to the new list of validated
2630 * RRsets, and remove it from the unvalidated RRsets.
2631 * We mark the RRset as authenticated and cacheable. */
2632 r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2633 if (r < 0)
2634 return r;
547973de 2635
c690b20a 2636 manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
0c7bff0a 2637
c690b20a
ZJS
2638 /* Exit the loop, we dropped something from the answer, start from the beginning */
2639 return 1;
2640 }
547973de 2641
c690b20a
ZJS
2642 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
2643 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
2644 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
2645 if (phase != DNSSEC_PHASE_ALL)
2646 continue;
0c7bff0a 2647
c690b20a
ZJS
2648 if (result == DNSSEC_VALIDATED_WILDCARD) {
2649 bool authenticated = false;
2650 const char *source;
0c7bff0a 2651
c690b20a
ZJS
2652 /* This RRset validated, but as a wildcard. This means we need
2653 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists.*/
0c7bff0a 2654
c690b20a
ZJS
2655 /* First step, determine the source of synthesis */
2656 r = dns_resource_record_source(rrsig, &source);
2657 if (r < 0)
2658 return r;
0c7bff0a 2659
c690b20a 2660 r = dnssec_test_positive_wildcard(*validated,
1c02e7ba 2661 dns_resource_key_name(rr->key),
c690b20a
ZJS
2662 source,
2663 rrsig->rrsig.signer,
2664 &authenticated);
0c7bff0a 2665
c690b20a
ZJS
2666 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
2667 if (r == 0)
2668 result = DNSSEC_INVALID;
2669 else {
2670 r = dns_answer_move_by_key(validated, &t->answer, rr->key,
2671 authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
2672 if (r < 0)
2673 return r;
2674
2675 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
2676
2677 /* Exit the loop, we dropped something from the answer, start from the beginning */
2678 return 1;
0c7bff0a 2679 }
c690b20a 2680 }
0c7bff0a 2681
c690b20a
ZJS
2682 if (result == DNSSEC_NO_SIGNATURE) {
2683 r = dns_transaction_requires_rrsig(t, rr);
547973de
LP
2684 if (r < 0)
2685 return r;
c690b20a
ZJS
2686 if (r == 0) {
2687 /* Data does not require signing. In that case, just copy it over,
2688 * but remember that this is by no means authenticated.*/
2689 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2690 if (r < 0)
2691 return r;
2692
2693 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2694 return 1;
2695 }
547973de 2696
c690b20a
ZJS
2697 r = dns_transaction_known_signed(t, rr);
2698 if (r < 0)
2699 return r;
2700 if (r > 0) {
2701 /* This is an RR we know has to be signed. If it isn't this means
2702 * the server is not attaching RRSIGs, hence complain. */
547973de 2703
c690b20a 2704 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
547973de 2705
c690b20a 2706 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
547973de 2707
c690b20a 2708 /* Downgrading is OK? If so, just consider the information unsigned */
c9c72065 2709
c690b20a 2710 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
c9c72065
LP
2711 if (r < 0)
2712 return r;
547973de 2713
c690b20a
ZJS
2714 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2715 return 1;
2716 }
a150ff5e 2717
c690b20a
ZJS
2718 /* Otherwise, fail */
2719 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2720 return 0;
f3cf586d 2721 }
547973de 2722
c690b20a
ZJS
2723 r = dns_transaction_in_private_tld(t, rr->key);
2724 if (r < 0)
2725 return r;
2726 if (r > 0) {
202b76ae 2727 char s[DNS_RESOURCE_KEY_STRING_MAX];
b652d4a2 2728
c690b20a
ZJS
2729 /* The data is from a TLD that is proven not to exist, and we are in downgrade
2730 * mode, hence ignore the fact that this was not signed. */
0c7bff0a 2731
202b76ae
ZJS
2732 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
2733 dns_resource_key_to_string(rr->key, s, sizeof s));
0c7bff0a 2734
c690b20a 2735 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
0c7bff0a
LP
2736 if (r < 0)
2737 return r;
0c7bff0a 2738
c690b20a
ZJS
2739 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2740 return 1;
2741 }
2742 }
0c7bff0a 2743
c690b20a
ZJS
2744 if (IN_SET(result,
2745 DNSSEC_MISSING_KEY,
2746 DNSSEC_SIGNATURE_EXPIRED,
2747 DNSSEC_UNSUPPORTED_ALGORITHM)) {
0c7bff0a 2748
c690b20a
ZJS
2749 r = dns_transaction_dnskey_authenticated(t, rr);
2750 if (r < 0 && r != -ENXIO)
2751 return r;
2752 if (r == 0) {
2753 /* The DNSKEY transaction was not authenticated, this means there's
2754 * no DS for this, which means it's OK if no keys are found for this signature. */
0c7bff0a 2755
c690b20a 2756 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
f3cf586d
LP
2757 if (r < 0)
2758 return r;
b652d4a2 2759
c690b20a
ZJS
2760 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2761 return 1;
2762 }
2763 }
b652d4a2 2764
c690b20a
ZJS
2765 r = dns_transaction_is_primary_response(t, rr);
2766 if (r < 0)
2767 return r;
2768 if (r > 0) {
2769 /* Look for a matching DNAME for this CNAME */
2770 r = dns_answer_has_dname_for_cname(t->answer, rr);
2771 if (r < 0)
2772 return r;
2773 if (r == 0) {
2774 /* Also look among the stuff we already validated */
2775 r = dns_answer_has_dname_for_cname(*validated, rr);
f3cf586d
LP
2776 if (r < 0)
2777 return r;
c690b20a 2778 }
d33b6cf3 2779
c690b20a
ZJS
2780 if (r == 0) {
2781 if (IN_SET(result,
2782 DNSSEC_INVALID,
2783 DNSSEC_SIGNATURE_EXPIRED,
2784 DNSSEC_NO_SIGNATURE))
2785 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
2786 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
2787 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
2788
2789 /* This is a primary response to our question, and it failed validation.
2790 * That's fatal. */
2791 t->answer_dnssec_result = result;
2792 return 0;
2793 }
d33b6cf3 2794
c690b20a
ZJS
2795 /* This is a primary response, but we do have a DNAME RR
2796 * in the RR that can replay this CNAME, hence rely on
2797 * that, and we can remove the CNAME in favour of it. */
2798 }
d33b6cf3 2799
c690b20a
ZJS
2800 /* This is just some auxiliary data. Just remove the RRset and continue. */
2801 r = dns_answer_remove_by_key(&t->answer, rr->key);
2802 if (r < 0)
2803 return r;
d33b6cf3 2804
c690b20a
ZJS
2805 /* We dropped something from the answer, start from the beginning. */
2806 return 1;
2807 }
f3cf586d 2808
c690b20a
ZJS
2809 return 2; /* Finito. */
2810}
94aa7071 2811
c690b20a
ZJS
2812int dns_transaction_validate_dnssec(DnsTransaction *t) {
2813 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
2814 Phase phase;
2815 DnsAnswerFlags flags;
2816 int r;
202b76ae 2817 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
94aa7071 2818
c690b20a 2819 assert(t);
94aa7071 2820
c690b20a
ZJS
2821 /* We have now collected all DS and DNSKEY RRs in
2822 * t->validated_keys, let's see which RRs we can now
2823 * authenticate with that. */
94aa7071 2824
c690b20a
ZJS
2825 if (t->scope->dnssec_mode == DNSSEC_NO)
2826 return 0;
a150ff5e 2827
c690b20a
ZJS
2828 /* Already validated */
2829 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
2830 return 0;
105e1512 2831
c690b20a
ZJS
2832 /* Our own stuff needs no validation */
2833 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
2834 t->answer_dnssec_result = DNSSEC_VALIDATED;
2835 t->answer_authenticated = true;
2836 return 0;
2837 }
a150ff5e 2838
c690b20a
ZJS
2839 /* Cached stuff is not affected by validation. */
2840 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2841 return 0;
f3cf586d 2842
c690b20a
ZJS
2843 if (!dns_transaction_dnssec_supported_full(t)) {
2844 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
2845 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2846 log_debug("Not validating response for %" PRIu16 ", server lacks DNSSEC support.", t->id);
2847 return 0;
2848 }
f3cf586d 2849
202b76ae
ZJS
2850 log_debug("Validating response from transaction %" PRIu16 " (%s).",
2851 t->id,
2852 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
547973de 2853
c690b20a
ZJS
2854 /* First, see if this response contains any revoked trust
2855 * anchors we care about */
2856 r = dns_transaction_check_revoked_trust_anchors(t);
2857 if (r < 0)
2858 return r;
43e6779a 2859
c690b20a
ZJS
2860 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
2861 r = dns_transaction_copy_validated(t);
2862 if (r < 0)
2863 return r;
43e6779a 2864
c690b20a
ZJS
2865 /* Second, see if there are DNSKEYs we already know a
2866 * validated DS for. */
2867 r = dns_transaction_validate_dnskey_by_ds(t);
2868 if (r < 0)
2869 return r;
43e6779a 2870
c690b20a
ZJS
2871 /* Fourth, remove all DNSKEY and DS RRs again that our trust
2872 * anchor says are revoked. After all we might have marked
2873 * some keys revoked above, but they might still be lingering
2874 * in our validated_keys list. */
2875 r = dns_transaction_invalidate_revoked_keys(t);
2876 if (r < 0)
2877 return r;
f3cf586d 2878
c690b20a
ZJS
2879 phase = DNSSEC_PHASE_DNSKEY;
2880 for (;;) {
2881 bool have_nsec = false;
f3cf586d 2882
c690b20a
ZJS
2883 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
2884 if (r <= 0)
2885 return r;
547973de 2886
c690b20a
ZJS
2887 /* Try again as long as we managed to achieve something */
2888 if (r == 1)
547973de
LP
2889 continue;
2890
c690b20a 2891 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
0c7bff0a 2892 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
c690b20a 2893 phase = DNSSEC_PHASE_NSEC;
0c7bff0a
LP
2894 continue;
2895 }
2896
c690b20a
ZJS
2897 if (phase != DNSSEC_PHASE_ALL) {
2898 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
2899 * Note that in this third phase we start to remove RRs we couldn't validate. */
2900 phase = DNSSEC_PHASE_ALL;
56352fe9 2901 continue;
547973de
LP
2902 }
2903
56352fe9 2904 /* We're done */
547973de
LP
2905 break;
2906 }
2907
2908 dns_answer_unref(t->answer);
2909 t->answer = validated;
2910 validated = NULL;
2911
72667f08
LP
2912 /* At this point the answer only contains validated
2913 * RRsets. Now, let's see if it actually answers the question
2914 * we asked. If so, great! If it doesn't, then see if
2915 * NSEC/NSEC3 can prove this. */
105e1512 2916 r = dns_transaction_has_positive_answer(t, &flags);
72667f08 2917 if (r > 0) {
105e1512
LP
2918 /* Yes, it answers the question! */
2919
2920 if (flags & DNS_ANSWER_AUTHENTICATED) {
2921 /* The answer is fully authenticated, yay. */
019036a4 2922 t->answer_dnssec_result = DNSSEC_VALIDATED;
105e1512
LP
2923 t->answer_rcode = DNS_RCODE_SUCCESS;
2924 t->answer_authenticated = true;
2925 } else {
2926 /* The answer is not fully authenticated. */
019036a4 2927 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512
LP
2928 t->answer_authenticated = false;
2929 }
2930
72667f08
LP
2931 } else if (r == 0) {
2932 DnssecNsecResult nr;
ed29bfdc 2933 bool authenticated = false;
72667f08
LP
2934
2935 /* Bummer! Let's check NSEC/NSEC3 */
0c7bff0a 2936 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
72667f08
LP
2937 if (r < 0)
2938 return r;
2939
2940 switch (nr) {
2941
2942 case DNSSEC_NSEC_NXDOMAIN:
2943 /* NSEC proves the domain doesn't exist. Very good. */
202b76ae 2944 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 2945 t->answer_dnssec_result = DNSSEC_VALIDATED;
72667f08 2946 t->answer_rcode = DNS_RCODE_NXDOMAIN;
ed29bfdc 2947 t->answer_authenticated = authenticated;
7aa8ce98 2948
59c5b597 2949 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
72667f08
LP
2950 break;
2951
2952 case DNSSEC_NSEC_NODATA:
2953 /* NSEC proves that there's no data here, very good. */
202b76ae 2954 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 2955 t->answer_dnssec_result = DNSSEC_VALIDATED;
72667f08 2956 t->answer_rcode = DNS_RCODE_SUCCESS;
ed29bfdc 2957 t->answer_authenticated = authenticated;
7aa8ce98 2958
59c5b597 2959 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
72667f08
LP
2960 break;
2961
105e1512
LP
2962 case DNSSEC_NSEC_OPTOUT:
2963 /* NSEC3 says the data might not be signed */
202b76ae 2964 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 2965 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512 2966 t->answer_authenticated = false;
7aa8ce98 2967
59c5b597 2968 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
105e1512
LP
2969 break;
2970
72667f08
LP
2971 case DNSSEC_NSEC_NO_RR:
2972 /* No NSEC data? Bummer! */
105e1512
LP
2973
2974 r = dns_transaction_requires_nsec(t);
2975 if (r < 0)
2976 return r;
7aa8ce98 2977 if (r > 0) {
019036a4 2978 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
59c5b597 2979 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
7aa8ce98 2980 } else {
019036a4 2981 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512 2982 t->answer_authenticated = false;
59c5b597 2983 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
105e1512
LP
2984 }
2985
2986 break;
2987
2988 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2989 /* We don't know the NSEC3 algorithm used? */
019036a4 2990 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
59c5b597 2991 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, t->key);
72667f08
LP
2992 break;
2993
2994 case DNSSEC_NSEC_FOUND:
146035b3 2995 case DNSSEC_NSEC_CNAME:
72667f08 2996 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
019036a4 2997 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
59c5b597 2998 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
72667f08
LP
2999 break;
3000
3001 default:
3002 assert_not_reached("Unexpected NSEC result.");
3003 }
3004 }
3005
547973de
LP
3006 return 1;
3007}
3008
ec2c5e43
LP
3009static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
3010 [DNS_TRANSACTION_NULL] = "null",
3011 [DNS_TRANSACTION_PENDING] = "pending",
547973de 3012 [DNS_TRANSACTION_VALIDATING] = "validating",
3bbdc31d 3013 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
ec2c5e43
LP
3014 [DNS_TRANSACTION_SUCCESS] = "success",
3015 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
3016 [DNS_TRANSACTION_TIMEOUT] = "timeout",
3017 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
3018 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
7cc6ed7b 3019 [DNS_TRANSACTION_ERRNO] = "errno",
ec2c5e43 3020 [DNS_TRANSACTION_ABORTED] = "aborted",
547973de 3021 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
b2b796b8 3022 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
91adc4db 3023 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
edbcc1fd 3024 [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
0791110f 3025 [DNS_TRANSACTION_NOT_FOUND] = "not-found",
ec2c5e43
LP
3026};
3027DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
c3bc53e6
LP
3028
3029static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3030 [DNS_TRANSACTION_NETWORK] = "network",
3031 [DNS_TRANSACTION_CACHE] = "cache",
3032 [DNS_TRANSACTION_ZONE] = "zone",
0d2cd476 3033 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
c3bc53e6
LP
3034};
3035DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);