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