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