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