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