]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
Merge pull request #28233 from mrc0mmand/append-to-corrupted-journals
[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 a 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 t->scope->manager->stale_retention_usec);
828 }
829
830 static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
831 DnsTransaction *dt;
832
833 assert(t);
834
835 SET_FOREACH(dt, t->dnssec_transactions)
836 if (DNS_TRANSACTION_IS_LIVE(dt->state))
837 return true;
838
839 return false;
840 }
841
842 static int dns_transaction_dnssec_ready(DnsTransaction *t) {
843 DnsTransaction *dt;
844 int r;
845
846 assert(t);
847
848 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
849 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
850
851 SET_FOREACH(dt, t->dnssec_transactions) {
852
853 switch (dt->state) {
854
855 case DNS_TRANSACTION_NULL:
856 case DNS_TRANSACTION_PENDING:
857 case DNS_TRANSACTION_VALIDATING:
858 /* Still ongoing */
859 return 0;
860
861 case DNS_TRANSACTION_RCODE_FAILURE:
862 if (!IN_SET(dt->answer_rcode, DNS_RCODE_NXDOMAIN, DNS_RCODE_SERVFAIL)) {
863 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", FORMAT_DNS_RCODE(dt->answer_rcode));
864 goto fail;
865 }
866
867 /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
868 * erroneously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
869 * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
870 * RRs to make unsigned proofs. */
871
872 case DNS_TRANSACTION_SUCCESS:
873 /* All good. */
874 break;
875
876 case DNS_TRANSACTION_DNSSEC_FAILED:
877 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
878 * validation result */
879
880 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
881 t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
882 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
883 return 0;
884
885 default:
886 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
887 goto fail;
888 }
889 }
890
891 /* All is ready, we can go and validate */
892 return 1;
893
894 fail:
895 /* Some auxiliary DNSSEC transaction failed for some reason. Maybe we learned something about the
896 * server due to this failure, and the feature level is now different? Let's see and restart the
897 * transaction if so. If not, let's propagate the auxiliary failure.
898 *
899 * This is particularly relevant if an auxiliary request figured out that DNSSEC doesn't work, and we
900 * are in permissive DNSSEC mode, and thus should restart things without DNSSEC magic. */
901 r = dns_transaction_maybe_restart(t);
902 if (r < 0)
903 return r;
904 if (r > 0)
905 return 0; /* don't validate just yet, we restarted things */
906
907 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
908 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
909 return 0;
910 }
911
912 static void dns_transaction_process_dnssec(DnsTransaction *t) {
913 int r;
914
915 assert(t);
916
917 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
918 r = dns_transaction_dnssec_ready(t);
919 if (r < 0)
920 goto fail;
921 if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
922 return;
923
924 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
925 * restart the lookup immediately. */
926 r = dns_transaction_maybe_restart(t);
927 if (r < 0)
928 goto fail;
929 if (r > 0) /* Transaction got restarted... */
930 return;
931
932 /* All our auxiliary DNSSEC transactions are complete now. Try
933 * to validate our RRset now. */
934 r = dns_transaction_validate_dnssec(t);
935 if (r == -EBADMSG) {
936 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
937 return;
938 }
939 if (r < 0)
940 goto fail;
941
942 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
943 t->scope->dnssec_mode == DNSSEC_YES) {
944
945 /* We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
946 * that works. */
947
948 if (dns_transaction_limited_retry(t))
949 return;
950
951 /* OK, let's give up, apparently all servers we tried didn't work. */
952 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
953 return;
954 }
955
956 if (!IN_SET(t->answer_dnssec_result,
957 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
958 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
959 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
960 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
961 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
962 return;
963 }
964
965 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER)
966 dns_server_warn_downgrade(t->server);
967
968 dns_transaction_cache_answer(t);
969
970 if (t->answer_rcode == DNS_RCODE_SUCCESS)
971 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
972 else
973 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
974
975 return;
976
977 fail:
978 dns_transaction_complete_errno(t, r);
979 }
980
981 static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
982 int r;
983
984 assert(t);
985
986 /* Checks whether the answer is positive, i.e. either a direct
987 * answer to the question, or a CNAME/DNAME for it */
988
989 r = dns_answer_match_key(t->answer, dns_transaction_key(t), flags);
990 if (r != 0)
991 return r;
992
993 r = dns_answer_find_cname_or_dname(t->answer, dns_transaction_key(t), NULL, flags);
994 if (r != 0)
995 return r;
996
997 return false;
998 }
999
1000 static int dns_transaction_fix_rcode(DnsTransaction *t) {
1001 int r;
1002
1003 assert(t);
1004
1005 /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
1006 * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
1007 * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
1008 * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
1009 * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
1010 * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
1011 * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
1012 * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
1013 * incomplete CNAME/DNAME chain.
1014 *
1015 * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
1016 * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
1017 * lookup. */
1018
1019 if (t->answer_rcode != DNS_RCODE_NXDOMAIN)
1020 return 0;
1021
1022 r = dns_transaction_has_positive_answer(t, NULL);
1023 if (r <= 0)
1024 return r;
1025
1026 t->answer_rcode = DNS_RCODE_SUCCESS;
1027 return 0;
1028 }
1029
1030 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted) {
1031 bool retry_with_tcp = false;
1032 int r;
1033
1034 assert(t);
1035 assert(p);
1036 assert(t->scope);
1037 assert(t->scope->manager);
1038
1039 if (t->state != DNS_TRANSACTION_PENDING)
1040 return;
1041
1042 /* Note that this call might invalidate the query. Callers
1043 * should hence not attempt to access the query or transaction
1044 * after calling this function. */
1045
1046 log_debug("Processing incoming packet of size %zu on transaction %" PRIu16" (rcode=%s).",
1047 p->size,
1048 t->id, FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)));
1049
1050 switch (t->scope->protocol) {
1051
1052 case DNS_PROTOCOL_LLMNR:
1053 /* For LLMNR we will not accept any packets from other interfaces */
1054
1055 if (p->ifindex != dns_scope_ifindex(t->scope))
1056 return;
1057
1058 if (p->family != t->scope->family)
1059 return;
1060
1061 /* Tentative packets are not full responses but still
1062 * useful for identifying uniqueness conflicts during
1063 * probing. */
1064 if (DNS_PACKET_LLMNR_T(p)) {
1065 dns_transaction_tentative(t, p);
1066 return;
1067 }
1068
1069 break;
1070
1071 case DNS_PROTOCOL_MDNS:
1072 /* For mDNS we will not accept any packets from other interfaces */
1073
1074 if (p->ifindex != dns_scope_ifindex(t->scope))
1075 return;
1076
1077 if (p->family != t->scope->family)
1078 return;
1079
1080 break;
1081
1082 case DNS_PROTOCOL_DNS:
1083 /* Note that we do not need to verify the
1084 * addresses/port numbers of incoming traffic, as we
1085 * invoked connect() on our UDP socket in which case
1086 * the kernel already does the needed verification for
1087 * us. */
1088 break;
1089
1090 default:
1091 assert_not_reached();
1092 }
1093
1094 if (t->received != p)
1095 DNS_PACKET_REPLACE(t->received, dns_packet_ref(p));
1096
1097 t->answer_source = DNS_TRANSACTION_NETWORK;
1098
1099 if (p->ipproto == IPPROTO_TCP) {
1100 if (DNS_PACKET_TC(p)) {
1101 /* Truncated via TCP? Somebody must be fucking with us */
1102 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1103 return;
1104 }
1105
1106 if (DNS_PACKET_ID(p) != t->id) {
1107 /* Not the reply to our query? Somebody must be fucking with us */
1108 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1109 return;
1110 }
1111 }
1112
1113 switch (t->scope->protocol) {
1114
1115 case DNS_PROTOCOL_DNS:
1116 assert(t->server);
1117
1118 if (!t->bypass &&
1119 IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
1120
1121 /* Request failed, immediately try again with reduced features */
1122
1123 if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
1124
1125 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
1126 * this transaction anymore, but let's see if it might make sense to send the request
1127 * to a different DNS server instead. If not let's process the response, and accept the
1128 * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1129 * packet loss, but is not going to give us better rcodes should we actually have
1130 * managed to get them already at UDP level. */
1131
1132 if (dns_transaction_limited_retry(t))
1133 return;
1134
1135 /* Give up, accept the rcode */
1136 log_debug("Server returned error: %s", FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)));
1137 break;
1138 }
1139
1140 /* SERVFAIL can happen for many reasons and may be transient.
1141 * To avoid unnecessary downgrades retry once with the initial level.
1142 * Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
1143 * first attempt to downgrade. If so, clamp to the current value so that the transaction
1144 * is retried without actually downgrading. If the next try also fails we will downgrade by
1145 * hitting the else branch below. */
1146 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SERVFAIL &&
1147 t->clamp_feature_level_servfail < 0) {
1148 t->clamp_feature_level_servfail = t->current_feature_level;
1149 log_debug("Server returned error %s, retrying transaction.",
1150 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)));
1151 } else {
1152 /* Reduce this feature level by one and try again. */
1153 switch (t->current_feature_level) {
1154 case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
1155 t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
1156 break;
1157 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
1158 /* Skip plain TLS when TLS is not supported */
1159 t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
1160 break;
1161 default:
1162 t->clamp_feature_level_servfail = t->current_feature_level - 1;
1163 }
1164
1165 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1166 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
1167 dns_server_feature_level_to_string(t->clamp_feature_level_servfail));
1168 }
1169
1170 dns_transaction_retry(t, false /* use the same server */);
1171 return;
1172 }
1173
1174 if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) {
1175 /* This server refused our request? If so, try again, use a different server */
1176 log_debug("Server returned REFUSED, switching servers, and retrying.");
1177
1178 if (dns_transaction_limited_retry(t))
1179 return;
1180
1181 break;
1182 }
1183
1184 if (DNS_PACKET_TC(p))
1185 dns_server_packet_truncated(t->server, t->current_feature_level);
1186
1187 break;
1188
1189 case DNS_PROTOCOL_LLMNR:
1190 case DNS_PROTOCOL_MDNS:
1191 dns_scope_packet_received(t->scope, p->timestamp - t->start_usec);
1192 break;
1193
1194 default:
1195 assert_not_reached();
1196 }
1197
1198 if (DNS_PACKET_TC(p)) {
1199
1200 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1201 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
1202 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1203 return;
1204 }
1205
1206 /* Response was truncated, let's try again with good old TCP */
1207 log_debug("Reply truncated, retrying via TCP.");
1208 retry_with_tcp = true;
1209
1210 } else if (t->scope->protocol == DNS_PROTOCOL_DNS &&
1211 DNS_PACKET_IS_FRAGMENTED(p)) {
1212
1213 /* Report the fragment size, so that we downgrade from LARGE to regular EDNS0 if needed */
1214 if (t->server)
1215 dns_server_packet_udp_fragmented(t->server, dns_packet_size_unfragmented(p));
1216
1217 if (t->current_feature_level > DNS_SERVER_FEATURE_LEVEL_UDP) {
1218 /* Packet was fragmented. Let's retry with TCP to avoid fragmentation attack
1219 * issues. (We don't do that on the lowest feature level however, since crappy DNS
1220 * servers often do not implement TCP, hence falling back to TCP on fragmentation is
1221 * counter-productive there.) */
1222
1223 log_debug("Reply fragmented, retrying via TCP. (Largest fragment size: %zu; Datagram size: %zu)",
1224 p->fragsize, p->size);
1225 retry_with_tcp = true;
1226 }
1227 }
1228
1229 if (retry_with_tcp) {
1230 r = dns_transaction_emit_tcp(t);
1231 if (r == -ESRCH) {
1232 /* No servers found? Damn! */
1233 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1234 return;
1235 }
1236 if (r == -EOPNOTSUPP) {
1237 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1238 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1239 return;
1240 }
1241 if (r < 0) {
1242 /* On LLMNR, if we cannot connect to the host,
1243 * we immediately give up */
1244 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1245 goto fail;
1246
1247 /* On DNS, couldn't send? Try immediately again, with a new server */
1248 if (dns_transaction_limited_retry(t))
1249 return;
1250
1251 /* No new server to try, give up */
1252 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1253 }
1254
1255 return;
1256 }
1257
1258 /* After the superficial checks, actually parse the message. */
1259 r = dns_packet_extract(p);
1260 if (r < 0) {
1261 if (t->server) {
1262 dns_server_packet_invalid(t->server, t->current_feature_level);
1263
1264 r = dns_transaction_maybe_restart(t);
1265 if (r < 0)
1266 goto fail;
1267 if (r > 0) /* Transaction got restarted... */
1268 return;
1269 }
1270
1271 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1272 return;
1273 }
1274
1275 if (t->server) {
1276 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1277 * rcode and subsequently downgraded the protocol */
1278
1279 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN) &&
1280 t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID)
1281 dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level_servfail);
1282
1283 /* Report that the OPT RR was missing */
1284 if (!p->opt)
1285 dns_server_packet_bad_opt(t->server, t->current_feature_level);
1286
1287 /* Report that the server didn't copy our query DO bit from request to response */
1288 if (DNS_PACKET_DO(t->sent) && !DNS_PACKET_DO(t->received))
1289 dns_server_packet_do_off(t->server, t->current_feature_level);
1290
1291 /* Report that we successfully received a packet. We keep track of the largest packet
1292 * size/fragment size we got. Which is useful for announcing the EDNS(0) packet size we can
1293 * receive to our server. */
1294 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, dns_packet_size_unfragmented(p));
1295 }
1296
1297 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1298 r = dns_transaction_maybe_restart(t);
1299 if (r < 0)
1300 goto fail;
1301 if (r > 0) /* Transaction got restarted... */
1302 return;
1303
1304 /* When dealing with protocols other than mDNS only consider responses with equivalent query section
1305 * to the request. For mDNS this check doesn't make sense, because the section 6 of RFC6762 states
1306 * that "Multicast DNS responses MUST NOT contain any questions in the Question Section". */
1307 if (t->scope->protocol != DNS_PROTOCOL_MDNS) {
1308 r = dns_packet_is_reply_for(p, dns_transaction_key(t));
1309 if (r < 0)
1310 goto fail;
1311 if (r == 0) {
1312 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1313 return;
1314 }
1315 }
1316
1317 /* Install the answer as answer to the transaction. We ref the answer twice here: the main `answer`
1318 * field is later replaced by the DNSSEC validated subset. The 'answer_auxiliary' field carries the
1319 * original complete record set, including RRSIG and friends. We use this when passing data to
1320 * clients that ask for DNSSEC metadata. */
1321 DNS_ANSWER_REPLACE(t->answer, dns_answer_ref(p->answer));
1322 t->answer_rcode = DNS_PACKET_RCODE(p);
1323 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
1324 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
1325 SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, encrypted);
1326
1327 r = dns_transaction_fix_rcode(t);
1328 if (r < 0)
1329 goto fail;
1330
1331 /* Block GC while starting requests for additional DNSSEC RRs */
1332 t->block_gc++;
1333 r = dns_transaction_request_dnssec_keys(t);
1334 t->block_gc--;
1335
1336 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1337 if (!dns_transaction_gc(t))
1338 return;
1339
1340 /* Requesting additional keys might have resulted in this transaction to fail, since the auxiliary
1341 * request failed for some reason. If so, we are not in pending state anymore, and we should exit
1342 * quickly. */
1343 if (t->state != DNS_TRANSACTION_PENDING)
1344 return;
1345 if (r < 0)
1346 goto fail;
1347 if (r > 0) {
1348 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1349 t->state = DNS_TRANSACTION_VALIDATING;
1350 dns_transaction_close_connection(t, true);
1351 dns_transaction_stop_timeout(t);
1352 return;
1353 }
1354
1355 dns_transaction_process_dnssec(t);
1356 return;
1357
1358 fail:
1359 dns_transaction_complete_errno(t, r);
1360 }
1361
1362 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1363 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1364 DnsTransaction *t = ASSERT_PTR(userdata);
1365 int r;
1366
1367 assert(t->scope);
1368
1369 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
1370 if (ERRNO_IS_DISCONNECT(r)) {
1371 usec_t usec;
1372
1373 /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
1374 * next recvmsg(). Treat this like a lost packet. */
1375
1376 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
1377 assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &usec) >= 0);
1378 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level);
1379
1380 dns_transaction_close_connection(t, /* use_graveyard = */ false);
1381
1382 if (dns_transaction_limited_retry(t)) /* Try a different server */
1383 return 0;
1384
1385 dns_transaction_complete_errno(t, r);
1386 return 0;
1387 }
1388 if (r < 0) {
1389 dns_transaction_complete_errno(t, r);
1390 return 0;
1391 }
1392 if (r == 0)
1393 /* Spurious wakeup without any data */
1394 return 0;
1395
1396 r = dns_packet_validate_reply(p);
1397 if (r < 0) {
1398 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
1399 return 0;
1400 }
1401 if (r == 0) {
1402 log_debug("Received inappropriate DNS packet as response, ignoring.");
1403 return 0;
1404 }
1405
1406 if (DNS_PACKET_ID(p) != t->id) {
1407 log_debug("Received packet with incorrect transaction ID, ignoring.");
1408 return 0;
1409 }
1410
1411 dns_transaction_process_reply(t, p, false);
1412 return 0;
1413 }
1414
1415 static int dns_transaction_emit_udp(DnsTransaction *t) {
1416 int r;
1417
1418 assert(t);
1419
1420 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
1421
1422 r = dns_transaction_pick_server(t);
1423 if (r < 0)
1424 return r;
1425
1426 if (manager_server_is_stub(t->scope->manager, t->server))
1427 return -ELOOP;
1428
1429 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP || DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
1430 return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
1431
1432 if (!t->bypass && !dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(dns_transaction_key(t)->type))
1433 return -EOPNOTSUPP;
1434
1435 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1436 int fd;
1437
1438 dns_transaction_close_connection(t, true);
1439
1440 /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */
1441 manager_socket_graveyard_process(t->scope->manager);
1442
1443 fd = dns_scope_socket_udp(t->scope, t->server);
1444 if (fd < 0)
1445 return fd;
1446
1447 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1448 if (r < 0) {
1449 safe_close(fd);
1450 return r;
1451 }
1452
1453 (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
1454 t->dns_udp_fd = fd;
1455 }
1456
1457 if (!t->bypass) {
1458 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
1459 if (r < 0)
1460 return r;
1461 }
1462 } else
1463 dns_transaction_close_connection(t, true);
1464
1465 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->server ? t->server->family : AF_UNSPEC, t->sent);
1466 if (r < 0)
1467 return r;
1468
1469 dns_transaction_reset_answer(t);
1470
1471 return 0;
1472 }
1473
1474 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1475 DnsTransaction *t = ASSERT_PTR(userdata);
1476
1477 assert(s);
1478
1479 if (t->initial_jitter_scheduled && !t->initial_jitter_elapsed) {
1480 log_debug("Initial jitter phase for transaction %" PRIu16 " elapsed.", t->id);
1481 t->initial_jitter_elapsed = true;
1482 } else {
1483 /* Timeout reached? Increase the timeout for the server used */
1484 switch (t->scope->protocol) {
1485
1486 case DNS_PROTOCOL_DNS:
1487 assert(t->server);
1488 dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level);
1489 break;
1490
1491 case DNS_PROTOCOL_LLMNR:
1492 case DNS_PROTOCOL_MDNS:
1493 dns_scope_packet_lost(t->scope, usec - t->start_usec);
1494 break;
1495
1496 default:
1497 assert_not_reached();
1498 }
1499
1500 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1501 }
1502
1503 dns_transaction_retry(t, /* next_server= */ true); /* try a different server, but given this means
1504 * packet loss, let's do so even if we already
1505 * tried a bunch */
1506 return 0;
1507 }
1508
1509 static int dns_transaction_setup_timeout(
1510 DnsTransaction *t,
1511 usec_t timeout_usec /* relative */,
1512 usec_t next_usec /* CLOCK_BOOTTIME */) {
1513
1514 int r;
1515
1516 assert(t);
1517
1518 dns_transaction_stop_timeout(t);
1519
1520 r = sd_event_add_time_relative(
1521 t->scope->manager->event,
1522 &t->timeout_event_source,
1523 CLOCK_BOOTTIME,
1524 timeout_usec, 0,
1525 on_transaction_timeout, t);
1526 if (r < 0)
1527 return r;
1528
1529 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1530
1531 t->next_attempt_after = next_usec;
1532 t->state = DNS_TRANSACTION_PENDING;
1533 return 0;
1534 }
1535
1536 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1537 assert(t);
1538 assert(t->scope);
1539
1540 switch (t->scope->protocol) {
1541
1542 case DNS_PROTOCOL_DNS:
1543
1544 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1545 * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1546 * needlessly. */
1547 if (t->stream)
1548 return TRANSACTION_TCP_TIMEOUT_USEC;
1549
1550 return DNS_TIMEOUT_USEC;
1551
1552 case DNS_PROTOCOL_MDNS:
1553 if (t->probing)
1554 return MDNS_PROBING_INTERVAL_USEC;
1555
1556 /* See RFC 6762 Section 5.1 suggests that timeout should be a few seconds. */
1557 assert(t->n_attempts > 0);
1558 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
1559
1560 case DNS_PROTOCOL_LLMNR:
1561 return t->scope->resend_timeout;
1562
1563 default:
1564 assert_not_reached();
1565 }
1566 }
1567
1568 static void dns_transaction_randomize_answer(DnsTransaction *t) {
1569 int r;
1570
1571 assert(t);
1572
1573 /* Randomizes the order of the answer array. This is done for all cached responses, so that we return
1574 * a different order each time. We do this only for DNS traffic, in order to do some minimal, crappy
1575 * load balancing. We don't do this for LLMNR or mDNS, since the order (preferring link-local
1576 * addresses, and such like) might have meaning there, and load balancing is pointless. */
1577
1578 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1579 return;
1580
1581 /* No point in randomizing, if there's just one RR */
1582 if (dns_answer_size(t->answer) <= 1)
1583 return;
1584
1585 r = dns_answer_reserve_or_clone(&t->answer, 0);
1586 if (r < 0) /* If this fails, just don't randomize, this is non-essential stuff after all */
1587 return (void) log_debug_errno(r, "Failed to clone answer record, not randomizing RR order of answer: %m");
1588
1589 dns_answer_randomize(t->answer);
1590 }
1591
1592 static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
1593 int r;
1594
1595 assert(t);
1596
1597 /* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
1598 * candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
1599 * has been prepared. */
1600
1601 dns_transaction_stop_timeout(t);
1602
1603 if (!dns_scope_network_good(t->scope)) {
1604 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
1605 return 0;
1606 }
1607
1608 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1609 DnsTransactionState result;
1610
1611 if (t->scope->protocol == DNS_PROTOCOL_LLMNR)
1612 /* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
1613 * the name. */
1614 result = DNS_TRANSACTION_NOT_FOUND;
1615 else
1616 result = DNS_TRANSACTION_ATTEMPTS_MAX_REACHED;
1617
1618 dns_transaction_complete(t, result);
1619 return 0;
1620 }
1621
1622 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
1623 /* If we already tried via a stream, then we don't
1624 * retry on LLMNR. See RFC 4795, Section 2.7. */
1625 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1626 return 0;
1627 }
1628
1629 t->n_attempts++;
1630 t->start_usec = ts;
1631
1632 dns_transaction_reset_answer(t);
1633 dns_transaction_flush_dnssec_transactions(t);
1634
1635 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1636 if (t->scope->protocol == DNS_PROTOCOL_DNS &&
1637 !FLAGS_SET(t->query_flags, SD_RESOLVED_NO_TRUST_ANCHOR)) {
1638 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, dns_transaction_key(t), &t->answer);
1639 if (r < 0)
1640 return r;
1641 if (r > 0) {
1642 t->answer_rcode = DNS_RCODE_SUCCESS;
1643 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1644 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
1645 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1646 return 0;
1647 }
1648
1649 if (dns_name_is_root(dns_resource_key_name(dns_transaction_key(t))) &&
1650 dns_transaction_key(t)->type == DNS_TYPE_DS) {
1651
1652 /* Hmm, this is a request for the root DS? A DS RR doesn't exist in the root zone,
1653 * and if our trust anchor didn't know it either, this means we cannot do any DNSSEC
1654 * logic anymore. */
1655
1656 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
1657 /* We are in downgrade mode. In this case, synthesize an unsigned empty
1658 * response, so that the any lookup depending on this one can continue
1659 * assuming there was no DS, and hence the root zone was unsigned. */
1660
1661 t->answer_rcode = DNS_RCODE_SUCCESS;
1662 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1663 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
1664 SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, true);
1665 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1666 } else
1667 /* If we are not in downgrade mode, then fail the lookup, because we cannot
1668 * reasonably answer it. There might be DS RRs, but we don't know them, and
1669 * the DNS server won't tell them to us (and even if it would, we couldn't
1670 * validate and trust them. */
1671 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1672
1673 return 0;
1674 }
1675 }
1676
1677 /* Check the zone. */
1678 if (!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_ZONE)) {
1679 r = dns_zone_lookup(&t->scope->zone, dns_transaction_key(t), dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
1680 if (r < 0)
1681 return r;
1682 if (r > 0) {
1683 t->answer_rcode = DNS_RCODE_SUCCESS;
1684 t->answer_source = DNS_TRANSACTION_ZONE;
1685 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
1686 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1687 return 0;
1688 }
1689 }
1690
1691 /* Check the cache. */
1692 if (!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_CACHE)) {
1693
1694 /* Before trying the cache, let's make sure we figured out a server to use. Should this cause
1695 * a change of server this might flush the cache. */
1696 (void) dns_scope_get_dns_server(t->scope);
1697
1698 /* Let's then prune all outdated entries */
1699 dns_cache_prune(&t->scope->cache);
1700
1701 /* For the initial attempt or when no stale data is requested, disable serve stale
1702 * and answer the question from the cache (honors ttl property).
1703 * On the second attempt, if StaleRetentionSec is greater than zero,
1704 * try to answer the question using stale date (honors until property) */
1705 uint64_t query_flags = t->query_flags;
1706 if (t->n_attempts == 1 || t->scope->manager->stale_retention_usec == 0)
1707 query_flags |= SD_RESOLVED_NO_STALE;
1708
1709 r = dns_cache_lookup(
1710 &t->scope->cache,
1711 dns_transaction_key(t),
1712 query_flags,
1713 &t->answer_rcode,
1714 &t->answer,
1715 &t->received,
1716 &t->answer_query_flags,
1717 &t->answer_dnssec_result);
1718 if (r < 0)
1719 return r;
1720 if (r > 0) {
1721 dns_transaction_randomize_answer(t);
1722
1723 if (t->bypass && t->scope->protocol == DNS_PROTOCOL_DNS && !t->received)
1724 /* When bypass mode is on, do not use cached data unless it came with a full
1725 * packet. */
1726 dns_transaction_reset_answer(t);
1727 else {
1728 if (t->n_attempts > 1 && !FLAGS_SET(query_flags, SD_RESOLVED_NO_STALE)) {
1729 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
1730 log_debug("Serve Stale response rcode=%s for %s",
1731 FORMAT_DNS_RCODE(t->answer_rcode),
1732 dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str));
1733 }
1734
1735 t->answer_source = DNS_TRANSACTION_CACHE;
1736 if (t->answer_rcode == DNS_RCODE_SUCCESS)
1737 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1738 else
1739 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
1740 return 0;
1741 }
1742 }
1743 }
1744
1745 if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_NETWORK)) {
1746 dns_transaction_complete(t, DNS_TRANSACTION_NO_SOURCE);
1747 return 0;
1748 }
1749
1750 return 1;
1751 }
1752
1753 static int dns_packet_append_zone(DnsPacket *p, DnsTransaction *t, DnsResourceKey *k, unsigned *nscount) {
1754 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1755 bool tentative;
1756 int r;
1757
1758 assert(p);
1759 assert(t);
1760 assert(k);
1761
1762 if (k->type != DNS_TYPE_ANY)
1763 return 0;
1764
1765 r = dns_zone_lookup(&t->scope->zone, k, t->scope->link->ifindex, &answer, NULL, &tentative);
1766 if (r < 0)
1767 return r;
1768
1769 return dns_packet_append_answer(p, answer, nscount);
1770 }
1771
1772 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1773 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1774 _cleanup_set_free_ Set *keys = NULL;
1775 unsigned qdcount, ancount = 0 /* avoid false maybe-uninitialized warning */, nscount;
1776 bool add_known_answers = false;
1777 usec_t ts;
1778 int r;
1779
1780 assert(t);
1781 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1782
1783 /* Discard any previously prepared packet, so we can start over and coalesce again */
1784 t->sent = dns_packet_unref(t->sent);
1785
1786 /* First, create a dummy packet to calculate packet size. */
1787 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1788 if (r < 0)
1789 return r;
1790
1791 r = dns_packet_append_key(p, dns_transaction_key(t), 0, NULL);
1792 if (r < 0)
1793 return r;
1794
1795 qdcount = 1;
1796
1797 if (dns_key_is_shared(dns_transaction_key(t)))
1798 add_known_answers = true;
1799
1800 r = dns_packet_append_zone(p, t, dns_transaction_key(t), NULL);
1801 if (r < 0)
1802 return r;
1803
1804 /* Save appended keys */
1805 r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(t));
1806 if (r < 0)
1807 return r;
1808
1809 /*
1810 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1811 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1812 * in our current scope, and see whether their timing constraints allow them to be sent.
1813 */
1814
1815 assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &ts) >= 0);
1816
1817 for (bool restart = true; restart;) {
1818 restart = false;
1819 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1820 size_t saved_packet_size;
1821 bool append = false;
1822
1823 /* Skip ourselves */
1824 if (other == t)
1825 continue;
1826
1827 if (other->state != DNS_TRANSACTION_PENDING)
1828 continue;
1829
1830 if (other->next_attempt_after > ts)
1831 continue;
1832
1833 if (!set_contains(keys, dns_transaction_key(other))) {
1834 r = dns_packet_append_key(p, dns_transaction_key(other), 0, &saved_packet_size);
1835 /* If we can't stuff more questions into the packet, just give up.
1836 * One of the 'other' transactions will fire later and take care of the rest. */
1837 if (r == -EMSGSIZE)
1838 break;
1839 if (r < 0)
1840 return r;
1841
1842 r = dns_packet_append_zone(p, t, dns_transaction_key(other), NULL);
1843 if (r == -EMSGSIZE)
1844 break;
1845 if (r < 0)
1846 return r;
1847
1848 append = true;
1849 }
1850
1851 r = dns_transaction_prepare(other, ts);
1852 if (r < 0)
1853 return r;
1854 if (r == 0) {
1855 if (append)
1856 dns_packet_truncate(p, saved_packet_size);
1857
1858 /* In this case, not only this transaction, but multiple transactions may be
1859 * freed. Hence, we need to restart the loop. */
1860 restart = true;
1861 break;
1862 }
1863
1864 usec_t timeout = transaction_get_resend_timeout(other);
1865 r = dns_transaction_setup_timeout(other, timeout, usec_add(ts, timeout));
1866 if (r < 0)
1867 return r;
1868
1869 if (dns_key_is_shared(dns_transaction_key(other)))
1870 add_known_answers = true;
1871
1872 if (append) {
1873 r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(other));
1874 if (r < 0)
1875 return r;
1876 }
1877
1878 qdcount++;
1879 if (qdcount >= UINT16_MAX)
1880 break;
1881 }
1882 }
1883
1884 /* Append known answer section if we're asking for any shared record */
1885 if (add_known_answers) {
1886 r = dns_cache_export_shared_to_packet(&t->scope->cache, p, ts, 0);
1887 if (r < 0)
1888 return r;
1889
1890 ancount = be16toh(DNS_PACKET_HEADER(p)->ancount);
1891 }
1892
1893 /* Then, create actual packet. */
1894 p = dns_packet_unref(p);
1895 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1896 if (r < 0)
1897 return r;
1898
1899 /* Questions */
1900 DnsResourceKey *k;
1901 SET_FOREACH(k, keys) {
1902 r = dns_packet_append_key(p, k, 0, NULL);
1903 if (r < 0)
1904 return r;
1905 }
1906 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
1907
1908 /* Known answers */
1909 if (add_known_answers) {
1910 r = dns_cache_export_shared_to_packet(&t->scope->cache, p, ts, ancount);
1911 if (r < 0)
1912 return r;
1913 }
1914
1915 /* Authorities */
1916 nscount = 0;
1917 SET_FOREACH(k, keys) {
1918 r = dns_packet_append_zone(p, t, k, &nscount);
1919 if (r < 0)
1920 return r;
1921 }
1922 DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
1923
1924 t->sent = TAKE_PTR(p);
1925 return 0;
1926 }
1927
1928 static int dns_transaction_make_packet(DnsTransaction *t) {
1929 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1930 int r;
1931
1932 assert(t);
1933
1934 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1935 return dns_transaction_make_packet_mdns(t);
1936
1937 if (t->sent)
1938 return 0;
1939
1940 if (t->bypass && t->bypass->protocol == t->scope->protocol) {
1941 /* If bypass logic is enabled and the protocol if the original packet and our scope match,
1942 * take the original packet, copy it, and patch in our new ID */
1943 r = dns_packet_dup(&p, t->bypass);
1944 if (r < 0)
1945 return r;
1946 } else {
1947 r = dns_packet_new_query(
1948 &p, t->scope->protocol,
1949 /* min_alloc_dsize = */ 0,
1950 /* dnssec_cd = */ !FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) &&
1951 t->scope->dnssec_mode != DNSSEC_NO);
1952 if (r < 0)
1953 return r;
1954
1955 r = dns_packet_append_key(p, dns_transaction_key(t), 0, NULL);
1956 if (r < 0)
1957 return r;
1958
1959 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1960 }
1961
1962 DNS_PACKET_HEADER(p)->id = t->id;
1963
1964 t->sent = TAKE_PTR(p);
1965 return 0;
1966 }
1967
1968 int dns_transaction_go(DnsTransaction *t) {
1969 usec_t ts;
1970 int r;
1971 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
1972
1973 assert(t);
1974
1975 /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
1976 * finished now. In the latter case, the transaction and query candidate objects must not be accessed.
1977 */
1978
1979 assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &ts) >= 0);
1980
1981 r = dns_transaction_prepare(t, ts);
1982 if (r <= 0)
1983 return r;
1984
1985 log_debug("Firing %s transaction %" PRIu16 " for <%s> scope %s on %s/%s (validate=%s).",
1986 t->bypass ? "bypass" : "regular",
1987 t->id,
1988 dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
1989 dns_protocol_to_string(t->scope->protocol),
1990 t->scope->link ? t->scope->link->ifname : "*",
1991 af_to_name_short(t->scope->family),
1992 yes_no(!FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE)));
1993
1994 if (!t->initial_jitter_scheduled &&
1995 IN_SET(t->scope->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
1996 usec_t jitter;
1997
1998 /* RFC 4795 Section 2.7 suggests all LLMNR queries should be delayed by a random time from 0 to
1999 * JITTER_INTERVAL.
2000 * RFC 6762 Section 8.1 suggests initial probe queries should be delayed by a random time from
2001 * 0 to 250ms. */
2002
2003 t->initial_jitter_scheduled = true;
2004 t->n_attempts = 0;
2005
2006 switch (t->scope->protocol) {
2007
2008 case DNS_PROTOCOL_LLMNR:
2009 jitter = random_u64_range(LLMNR_JITTER_INTERVAL_USEC);
2010 break;
2011
2012 case DNS_PROTOCOL_MDNS:
2013 if (t->probing)
2014 jitter = random_u64_range(MDNS_PROBING_INTERVAL_USEC);
2015 else
2016 jitter = 0;
2017 break;
2018 default:
2019 assert_not_reached();
2020 }
2021
2022 r = dns_transaction_setup_timeout(t, jitter, ts);
2023 if (r < 0)
2024 return r;
2025
2026 log_debug("Delaying %s transaction %" PRIu16 " for " USEC_FMT "us.",
2027 dns_protocol_to_string(t->scope->protocol),
2028 t->id,
2029 jitter);
2030 return 1;
2031 }
2032
2033 /* Otherwise, we need to ask the network */
2034 r = dns_transaction_make_packet(t);
2035 if (r < 0)
2036 return r;
2037
2038 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
2039 (dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), "in-addr.arpa") > 0 ||
2040 dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), "ip6.arpa") > 0)) {
2041
2042 /* RFC 4795, Section 2.4. says reverse lookups shall
2043 * always be made via TCP on LLMNR */
2044 r = dns_transaction_emit_tcp(t);
2045 } else {
2046 /* Try via UDP, and if that fails due to large size or lack of
2047 * support try via TCP */
2048 r = dns_transaction_emit_udp(t);
2049 if (r == -EMSGSIZE)
2050 log_debug("Sending query via TCP since it is too large.");
2051 else if (r == -EAGAIN)
2052 log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
2053 else if (r == -EPERM)
2054 log_debug("Sending query via TCP since UDP is blocked.");
2055 if (IN_SET(r, -EMSGSIZE, -EAGAIN, -EPERM))
2056 r = dns_transaction_emit_tcp(t);
2057 }
2058 if (r == -ELOOP) {
2059 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2060 return r;
2061
2062 /* One of our own stub listeners */
2063 log_debug_errno(r, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
2064
2065 dns_scope_next_dns_server(t->scope, t->server);
2066
2067 if (dns_scope_get_dns_server(t->scope) == t->server) {
2068 log_debug_errno(r, "Still pointing to extra listener after switching DNS servers, refusing operation.");
2069 dns_transaction_complete(t, DNS_TRANSACTION_STUB_LOOP);
2070 return 0;
2071 }
2072
2073 return dns_transaction_go(t);
2074 }
2075 if (r == -ESRCH) {
2076 /* No servers to send this to? */
2077 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
2078 return 0;
2079 }
2080 if (r == -EOPNOTSUPP) {
2081 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
2082 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
2083 return 0;
2084 }
2085 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(r)) {
2086 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
2087 * answer this request with this protocol. */
2088 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
2089 return 0;
2090 }
2091 if (r < 0) {
2092 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2093 return r;
2094
2095 /* Couldn't send? Try immediately again, with a new server */
2096 dns_scope_next_dns_server(t->scope, t->server);
2097
2098 return dns_transaction_go(t);
2099 }
2100
2101 usec_t timeout = transaction_get_resend_timeout(t);
2102 r = dns_transaction_setup_timeout(t, timeout, usec_add(ts, timeout));
2103 if (r < 0)
2104 return r;
2105
2106 return 1;
2107 }
2108
2109 static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
2110 DnsTransaction *n;
2111 int r;
2112
2113 assert(t);
2114 assert(aux);
2115
2116 /* Try to find cyclic dependencies between transaction objects */
2117
2118 if (t == aux)
2119 return 1;
2120
2121 SET_FOREACH(n, aux->dnssec_transactions) {
2122 r = dns_transaction_find_cyclic(t, n);
2123 if (r != 0)
2124 return r;
2125 }
2126
2127 return 0;
2128 }
2129
2130 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
2131 _cleanup_(dns_transaction_gcp) DnsTransaction *aux = NULL;
2132 int r;
2133
2134 assert(t);
2135 assert(ret);
2136 assert(key);
2137
2138 aux = dns_scope_find_transaction(t->scope, key, t->query_flags);
2139 if (!aux) {
2140 r = dns_transaction_new(&aux, t->scope, key, NULL, t->query_flags);
2141 if (r < 0)
2142 return r;
2143 } else {
2144 if (set_contains(t->dnssec_transactions, aux)) {
2145 *ret = aux;
2146 return 0;
2147 }
2148
2149 r = dns_transaction_find_cyclic(t, aux);
2150 if (r < 0)
2151 return r;
2152 if (r > 0) {
2153 char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
2154
2155 return log_debug_errno(SYNTHETIC_ERRNO(ELOOP),
2156 "Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
2157 aux->id,
2158 dns_resource_key_to_string(dns_transaction_key(t), s, sizeof s),
2159 t->id,
2160 dns_resource_key_to_string(dns_transaction_key(aux), saux, sizeof saux));
2161 }
2162 }
2163
2164 r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
2165 if (r < 0)
2166 return r;
2167
2168 r = set_ensure_put(&t->dnssec_transactions, NULL, aux);
2169 if (r < 0)
2170 return r;
2171
2172 r = set_ensure_put(&aux->notify_transactions, NULL, t);
2173 if (r < 0) {
2174 (void) set_remove(t->dnssec_transactions, aux);
2175 return r;
2176 }
2177
2178 *ret = TAKE_PTR(aux);
2179 return 1;
2180 }
2181
2182 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
2183 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
2184 DnsTransaction *aux;
2185 int r;
2186
2187 assert(t);
2188 assert(key);
2189
2190 /* Try to get the data from the trust anchor */
2191 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
2192 if (r < 0)
2193 return r;
2194 if (r > 0) {
2195 r = dns_answer_extend(&t->validated_keys, a);
2196 if (r < 0)
2197 return r;
2198
2199 return 0;
2200 }
2201
2202 /* This didn't work, ask for it via the network/cache then. */
2203 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
2204 if (r == -ELOOP) /* This would result in a cyclic dependency */
2205 return 0;
2206 if (r < 0)
2207 return r;
2208
2209 if (aux->state == DNS_TRANSACTION_NULL) {
2210 r = dns_transaction_go(aux);
2211 if (r < 0)
2212 return r;
2213 }
2214
2215 return 1;
2216 }
2217
2218 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
2219 int r;
2220
2221 assert(t);
2222
2223 /* Check whether the specified name is in the NTA
2224 * database, either in the global one, or the link-local
2225 * one. */
2226
2227 r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
2228 if (r != 0)
2229 return r;
2230
2231 if (!t->scope->link)
2232 return 0;
2233
2234 return link_negative_trust_anchor_lookup(t->scope->link, name);
2235 }
2236
2237 static int dns_transaction_has_negative_answer(DnsTransaction *t) {
2238 int r;
2239
2240 assert(t);
2241
2242 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
2243 * RRs to prove it */
2244
2245 r = dns_transaction_has_positive_answer(t, NULL);
2246 if (r < 0)
2247 return r;
2248 if (r > 0)
2249 return false;
2250
2251 /* Is this key explicitly listed as a negative trust anchor?
2252 * If so, it's nothing we need to care about */
2253 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(dns_transaction_key(t)));
2254 if (r < 0)
2255 return r;
2256 return !r;
2257 }
2258
2259 static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
2260 int r;
2261
2262 assert(t);
2263 assert(rr);
2264
2265 /* Check if the specified RR is the "primary" response,
2266 * i.e. either matches the question precisely or is a
2267 * CNAME/DNAME for it. */
2268
2269 r = dns_resource_key_match_rr(dns_transaction_key(t), rr, NULL);
2270 if (r != 0)
2271 return r;
2272
2273 return dns_resource_key_match_cname_or_dname(dns_transaction_key(t), rr->key, NULL);
2274 }
2275
2276 static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
2277 assert(t);
2278
2279 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2280 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2281
2282 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2283 return false;
2284
2285 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2286 * be supported, hence return true. */
2287 if (!t->server)
2288 return true;
2289
2290 /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2291 * the server is known to support currently, as the transaction feature level might be lower than what the
2292 * server actually supports, since we might have downgraded this transaction's feature level because we got a
2293 * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
2294
2295 return dns_server_dnssec_supported(t->server);
2296 }
2297
2298 static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
2299 DnsTransaction *dt;
2300
2301 assert(t);
2302
2303 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2304
2305 if (!dns_transaction_dnssec_supported(t))
2306 return false;
2307
2308 SET_FOREACH(dt, t->dnssec_transactions)
2309 if (!dns_transaction_dnssec_supported(dt))
2310 return false;
2311
2312 return true;
2313 }
2314
2315 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
2316 DnsResourceRecord *rr;
2317
2318 int r;
2319
2320 assert(t);
2321
2322 /*
2323 * Retrieve all auxiliary RRs for the answer we got, so that
2324 * we can verify signatures or prove that RRs are rightfully
2325 * unsigned. Specifically:
2326 *
2327 * - For RRSIG we get the matching DNSKEY
2328 * - For DNSKEY we get the matching DS
2329 * - For unsigned SOA/NS we get the matching DS
2330 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
2331 * - For other unsigned RRs we get the matching SOA RR
2332 * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2333 * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
2334 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2335 */
2336
2337 if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO)
2338 return 0;
2339 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2340 return 0; /* We only need to validate stuff from the network */
2341 if (!dns_transaction_dnssec_supported(t))
2342 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
2343
2344 DNS_ANSWER_FOREACH(rr, t->answer) {
2345
2346 if (dns_type_is_pseudo(rr->key->type))
2347 continue;
2348
2349 /* If this RR is in the negative trust anchor, we don't need to validate it. */
2350 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2351 if (r < 0)
2352 return r;
2353 if (r > 0)
2354 continue;
2355
2356 switch (rr->key->type) {
2357
2358 case DNS_TYPE_RRSIG: {
2359 /* For each RRSIG we request the matching DNSKEY */
2360 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
2361
2362 /* If this RRSIG is about a DNSKEY RR and the
2363 * signer is the same as the owner, then we
2364 * already have the DNSKEY, and we don't have
2365 * to look for more. */
2366 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
2367 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
2368 if (r < 0)
2369 return r;
2370 if (r > 0)
2371 continue;
2372 }
2373
2374 /* If the signer is not a parent of our
2375 * original query, then this is about an
2376 * auxiliary RRset, but not anything we asked
2377 * for. In this case we aren't interested,
2378 * because we don't want to request additional
2379 * RRs for stuff we didn't really ask for, and
2380 * also to avoid request loops, where
2381 * additional RRs from one transaction result
2382 * in another transaction whose additional RRs
2383 * point back to the original transaction, and
2384 * we deadlock. */
2385 r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), rr->rrsig.signer);
2386 if (r < 0)
2387 return r;
2388 if (r == 0)
2389 continue;
2390
2391 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
2392 if (!dnskey)
2393 return -ENOMEM;
2394
2395 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
2396 t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
2397 r = dns_transaction_request_dnssec_rr(t, dnskey);
2398 if (r < 0)
2399 return r;
2400 break;
2401 }
2402
2403 case DNS_TYPE_DNSKEY: {
2404 /* For each DNSKEY we request the matching DS */
2405 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2406
2407 /* If the DNSKEY we are looking at is not for
2408 * zone we are interested in, nor any of its
2409 * parents, we aren't interested, and don't
2410 * request it. After all, we don't want to end
2411 * up in request loops, and want to keep
2412 * additional traffic down. */
2413
2414 r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), dns_resource_key_name(rr->key));
2415 if (r < 0)
2416 return r;
2417 if (r == 0)
2418 continue;
2419
2420 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
2421 if (!ds)
2422 return -ENOMEM;
2423
2424 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
2425 t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
2426 r = dns_transaction_request_dnssec_rr(t, ds);
2427 if (r < 0)
2428 return r;
2429
2430 break;
2431 }
2432
2433 case DNS_TYPE_SOA:
2434 case DNS_TYPE_NS: {
2435 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2436
2437 /* For an unsigned SOA or NS, try to acquire
2438 * the matching DS RR, as we are at a zone cut
2439 * then, and whether a DS exists tells us
2440 * whether the zone is signed. Do so only if
2441 * this RR matches our original question,
2442 * however. */
2443
2444 r = dns_resource_key_match_rr(dns_transaction_key(t), rr, NULL);
2445 if (r < 0)
2446 return r;
2447 if (r == 0) {
2448 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2449 * a negative reply, and we need the SOA RR's TTL in order to cache a negative entry?
2450 * If so, we need to validate it, too. */
2451
2452 r = dns_answer_match_key(t->answer, dns_transaction_key(t), NULL);
2453 if (r < 0)
2454 return r;
2455 if (r > 0) /* positive reply, we won't need the SOA and hence don't need to validate
2456 * it. */
2457 continue;
2458
2459 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
2460 * what we are looking for, otherwise there's no value in it for us. */
2461 r = dns_name_endswith(dns_resource_key_name(dns_transaction_key(t)), dns_resource_key_name(rr->key));
2462 if (r < 0)
2463 return r;
2464 if (r == 0)
2465 continue;
2466 }
2467
2468 r = dnssec_has_rrsig(t->answer, rr->key);
2469 if (r < 0)
2470 return r;
2471 if (r > 0)
2472 continue;
2473
2474 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
2475 if (!ds)
2476 return -ENOMEM;
2477
2478 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
2479 t->id, dns_resource_key_name(rr->key));
2480 r = dns_transaction_request_dnssec_rr(t, ds);
2481 if (r < 0)
2482 return r;
2483
2484 break;
2485 }
2486
2487 case DNS_TYPE_DS:
2488 case DNS_TYPE_CNAME:
2489 case DNS_TYPE_DNAME: {
2490 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2491 const char *name;
2492
2493 /* CNAMEs and DNAMEs cannot be located at a
2494 * zone apex, hence ask for the parent SOA for
2495 * unsigned CNAME/DNAME RRs, maybe that's the
2496 * apex. But do all that only if this is
2497 * actually a response to our original
2498 * question.
2499 *
2500 * Similar for DS RRs, which are signed when
2501 * the parent SOA is signed. */
2502
2503 r = dns_transaction_is_primary_response(t, rr);
2504 if (r < 0)
2505 return r;
2506 if (r == 0)
2507 continue;
2508
2509 r = dnssec_has_rrsig(t->answer, rr->key);
2510 if (r < 0)
2511 return r;
2512 if (r > 0)
2513 continue;
2514
2515 r = dns_answer_has_dname_for_cname(t->answer, rr);
2516 if (r < 0)
2517 return r;
2518 if (r > 0)
2519 continue;
2520
2521 name = dns_resource_key_name(rr->key);
2522 r = dns_name_parent(&name);
2523 if (r < 0)
2524 return r;
2525 if (r == 0)
2526 continue;
2527
2528 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
2529 if (!soa)
2530 return -ENOMEM;
2531
2532 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
2533 t->id, dns_resource_key_name(rr->key));
2534 r = dns_transaction_request_dnssec_rr(t, soa);
2535 if (r < 0)
2536 return r;
2537
2538 break;
2539 }
2540
2541 default: {
2542 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2543
2544 /* For other unsigned RRsets (including
2545 * NSEC/NSEC3!), look for proof the zone is
2546 * unsigned, by requesting the SOA RR of the
2547 * zone. However, do so only if they are
2548 * directly relevant to our original
2549 * question. */
2550
2551 r = dns_transaction_is_primary_response(t, rr);
2552 if (r < 0)
2553 return r;
2554 if (r == 0)
2555 continue;
2556
2557 r = dnssec_has_rrsig(t->answer, rr->key);
2558 if (r < 0)
2559 return r;
2560 if (r > 0)
2561 continue;
2562
2563 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
2564 if (!soa)
2565 return -ENOMEM;
2566
2567 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
2568 t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
2569 r = dns_transaction_request_dnssec_rr(t, soa);
2570 if (r < 0)
2571 return r;
2572 break;
2573 }}
2574 }
2575
2576 /* Above, we requested everything necessary to validate what
2577 * we got. Now, let's request what we need to validate what we
2578 * didn't get... */
2579
2580 r = dns_transaction_has_negative_answer(t);
2581 if (r < 0)
2582 return r;
2583 if (r > 0) {
2584 const char *name, *signed_status;
2585 uint16_t type = 0;
2586
2587 name = dns_resource_key_name(dns_transaction_key(t));
2588 signed_status = dns_answer_contains_nsec_or_nsec3(t->answer) ? "signed" : "unsigned";
2589
2590 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2591 * could also be used as indication that we are not at a zone apex, but in real world setups there are
2592 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2593 * though they have further children. If this was a DS request, then it's signed when the parent zone
2594 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2595 * to see if that is signed. */
2596
2597 if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
2598 r = dns_name_parent(&name);
2599 if (r > 0) {
2600 type = DNS_TYPE_SOA;
2601 log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty DS response).",
2602 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id,
2603 dns_resource_key_name(dns_transaction_key(t)), signed_status);
2604 } else
2605 name = NULL;
2606
2607 } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
2608
2609 type = DNS_TYPE_DS;
2610 log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16 " (%s, %s empty SOA/NS response).",
2611 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status);
2612
2613 } else {
2614 type = DNS_TYPE_SOA;
2615 log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty non-SOA/NS/DS response).",
2616 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status);
2617 }
2618
2619 if (name) {
2620 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2621
2622 soa = dns_resource_key_new(dns_transaction_key(t)->class, type, name);
2623 if (!soa)
2624 return -ENOMEM;
2625
2626 r = dns_transaction_request_dnssec_rr(t, soa);
2627 if (r < 0)
2628 return r;
2629 }
2630 }
2631
2632 return dns_transaction_dnssec_is_live(t);
2633 }
2634
2635 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
2636 assert(t);
2637 assert(source);
2638
2639 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2640 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2641 the state is VALIDATING however, we should check if we are complete now. */
2642
2643 if (t->state == DNS_TRANSACTION_VALIDATING)
2644 dns_transaction_process_dnssec(t);
2645 }
2646
2647 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2648 DnsAnswerItem *item;
2649 int r;
2650
2651 assert(t);
2652
2653 /* Add all DNSKEY RRs from the answer that are validated by DS
2654 * RRs from the list of validated keys to the list of
2655 * validated keys. */
2656
2657 DNS_ANSWER_FOREACH_ITEM(item, t->answer) {
2658
2659 r = dnssec_verify_dnskey_by_ds_search(item->rr, t->validated_keys);
2660 if (r < 0)
2661 return r;
2662 if (r == 0)
2663 continue;
2664
2665 /* If so, the DNSKEY is validated too. */
2666 r = dns_answer_add_extend(&t->validated_keys, item->rr, item->ifindex, item->flags|DNS_ANSWER_AUTHENTICATED, item->rrsig);
2667 if (r < 0)
2668 return r;
2669 }
2670
2671 return 0;
2672 }
2673
2674 static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
2675 int r;
2676
2677 assert(t);
2678 assert(rr);
2679
2680 /* Checks if the RR we are looking for must be signed with an
2681 * RRSIG. This is used for positive responses. */
2682
2683 if (t->scope->dnssec_mode == DNSSEC_NO)
2684 return false;
2685
2686 if (dns_type_is_pseudo(rr->key->type))
2687 return -EINVAL;
2688
2689 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2690 if (r < 0)
2691 return r;
2692 if (r > 0)
2693 return false;
2694
2695 switch (rr->key->type) {
2696
2697 case DNS_TYPE_RRSIG:
2698 /* RRSIGs are the signatures themselves, they need no signing. */
2699 return false;
2700
2701 case DNS_TYPE_SOA:
2702 case DNS_TYPE_NS: {
2703 DnsTransaction *dt;
2704
2705 /* For SOA or NS RRs we look for a matching DS transaction */
2706
2707 SET_FOREACH(dt, t->dnssec_transactions) {
2708
2709 if (dns_transaction_key(dt)->class != rr->key->class)
2710 continue;
2711 if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
2712 continue;
2713
2714 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
2715 if (r < 0)
2716 return r;
2717 if (r == 0)
2718 continue;
2719
2720 /* We found a DS transactions for the SOA/NS
2721 * RRs we are looking at. If it discovered signed DS
2722 * RRs, then we need to be signed, too. */
2723
2724 if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
2725 return false;
2726
2727 return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
2728 }
2729
2730 /* We found nothing that proves this is safe to leave
2731 * this unauthenticated, hence ask inist on
2732 * authentication. */
2733 return true;
2734 }
2735
2736 case DNS_TYPE_DS:
2737 case DNS_TYPE_CNAME:
2738 case DNS_TYPE_DNAME: {
2739 const char *parent = NULL;
2740 DnsTransaction *dt;
2741
2742 /*
2743 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2744 *
2745 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2746 */
2747
2748 SET_FOREACH(dt, t->dnssec_transactions) {
2749
2750 if (dns_transaction_key(dt)->class != rr->key->class)
2751 continue;
2752 if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
2753 continue;
2754
2755 if (!parent) {
2756 parent = dns_resource_key_name(rr->key);
2757 r = dns_name_parent(&parent);
2758 if (r < 0)
2759 return r;
2760 if (r == 0) {
2761 if (rr->key->type == DNS_TYPE_DS)
2762 return true;
2763
2764 /* A CNAME/DNAME without a parent? That's sooo weird. */
2765 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2766 "Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2767 }
2768 }
2769
2770 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), parent);
2771 if (r < 0)
2772 return r;
2773 if (r == 0)
2774 continue;
2775
2776 return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2777 }
2778
2779 return true;
2780 }
2781
2782 default: {
2783 DnsTransaction *dt;
2784
2785 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2786
2787 SET_FOREACH(dt, t->dnssec_transactions) {
2788
2789 if (dns_transaction_key(dt)->class != rr->key->class)
2790 continue;
2791 if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
2792 continue;
2793
2794 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
2795 if (r < 0)
2796 return r;
2797 if (r == 0)
2798 continue;
2799
2800 /* We found the transaction that was supposed to find the SOA RR for us. It was
2801 * successful, but found no RR for us. This means we are not at a zone cut. In this
2802 * case, we require authentication if the SOA lookup was authenticated too. */
2803 return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2804 }
2805
2806 return true;
2807 }}
2808 }
2809
2810 static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2811 DnsTransaction *dt;
2812 const char *tld;
2813 int r;
2814
2815 /* If DNSSEC downgrade mode is on, checks whether the
2816 * specified RR is one level below a TLD we have proven not to
2817 * exist. In such a case we assume that this is a private
2818 * domain, and permit it.
2819 *
2820 * This detects cases like the Fritz!Box router networks. Each
2821 * Fritz!Box router serves a private "fritz.box" zone, in the
2822 * non-existing TLD "box". Requests for the "fritz.box" domain
2823 * are served by the router itself, while requests for the
2824 * "box" domain will result in NXDOMAIN.
2825 *
2826 * Note that this logic is unable to detect cases where a
2827 * router serves a private DNS zone directly under
2828 * non-existing TLD. In such a case we cannot detect whether
2829 * the TLD is supposed to exist or not, as all requests we
2830 * make for it will be answered by the router's zone, and not
2831 * by the root zone. */
2832
2833 assert(t);
2834
2835 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2836 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2837
2838 tld = dns_resource_key_name(key);
2839 r = dns_name_parent(&tld);
2840 if (r < 0)
2841 return r;
2842 if (r == 0)
2843 return false; /* Already the root domain */
2844
2845 if (!dns_name_is_single_label(tld))
2846 return false;
2847
2848 SET_FOREACH(dt, t->dnssec_transactions) {
2849
2850 if (dns_transaction_key(dt)->class != key->class)
2851 continue;
2852
2853 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), tld);
2854 if (r < 0)
2855 return r;
2856 if (r == 0)
2857 continue;
2858
2859 /* We found an auxiliary lookup we did for the TLD. If
2860 * that returned with NXDOMAIN, we know the TLD didn't
2861 * exist, and hence this might be a private zone. */
2862
2863 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2864 }
2865
2866 return false;
2867 }
2868
2869 static int dns_transaction_requires_nsec(DnsTransaction *t) {
2870 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
2871 DnsTransaction *dt;
2872 const char *name;
2873 uint16_t type = 0;
2874 int r;
2875
2876 assert(t);
2877
2878 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2879 * this negative reply */
2880
2881 if (t->scope->dnssec_mode == DNSSEC_NO)
2882 return false;
2883
2884 if (dns_type_is_pseudo(dns_transaction_key(t)->type))
2885 return -EINVAL;
2886
2887 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(dns_transaction_key(t)));
2888 if (r < 0)
2889 return r;
2890 if (r > 0)
2891 return false;
2892
2893 r = dns_transaction_in_private_tld(t, dns_transaction_key(t));
2894 if (r < 0)
2895 return r;
2896 if (r > 0) {
2897 /* The lookup is from a TLD that is proven not to
2898 * exist, and we are in downgrade mode, hence ignore
2899 * that fact that we didn't get any NSEC RRs. */
2900
2901 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2902 dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str));
2903 return false;
2904 }
2905
2906 name = dns_resource_key_name(dns_transaction_key(t));
2907
2908 if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
2909
2910 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
2911 * hence check the parent SOA in this case. */
2912
2913 r = dns_name_parent(&name);
2914 if (r < 0)
2915 return r;
2916 if (r == 0)
2917 return true;
2918
2919 type = DNS_TYPE_SOA;
2920
2921 } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS))
2922 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
2923 type = DNS_TYPE_DS;
2924 else
2925 /* For all other negative replies, check for the SOA lookup */
2926 type = DNS_TYPE_SOA;
2927
2928 /* For all other RRs we check the SOA on the same level to see
2929 * if it's signed. */
2930
2931 SET_FOREACH(dt, t->dnssec_transactions) {
2932
2933 if (dns_transaction_key(dt)->class != dns_transaction_key(t)->class)
2934 continue;
2935 if (dns_transaction_key(dt)->type != type)
2936 continue;
2937
2938 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), name);
2939 if (r < 0)
2940 return r;
2941 if (r == 0)
2942 continue;
2943
2944 return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
2945 }
2946
2947 /* If in doubt, require NSEC/NSEC3 */
2948 return true;
2949 }
2950
2951 static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2952 DnsResourceRecord *rrsig;
2953 bool found = false;
2954 int r;
2955
2956 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2957 * the specified RRset is authenticated (i.e. has a matching
2958 * DS RR). */
2959
2960 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
2961 if (r < 0)
2962 return r;
2963 if (r > 0)
2964 return false;
2965
2966 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2967 DnsTransaction *dt;
2968
2969 r = dnssec_key_match_rrsig(rr->key, rrsig);
2970 if (r < 0)
2971 return r;
2972 if (r == 0)
2973 continue;
2974
2975 SET_FOREACH(dt, t->dnssec_transactions) {
2976
2977 if (dns_transaction_key(dt)->class != rr->key->class)
2978 continue;
2979
2980 if (dns_transaction_key(dt)->type == DNS_TYPE_DNSKEY) {
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 DNSKEY lookup. If that lookup is authenticated,
2989 * report this. */
2990
2991 if (FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
2992 return true;
2993
2994 found = true;
2995
2996 } else if (dns_transaction_key(dt)->type == DNS_TYPE_DS) {
2997
2998 r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), rrsig->rrsig.signer);
2999 if (r < 0)
3000 return r;
3001 if (r == 0)
3002 continue;
3003
3004 /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
3005 * non-zero, we won! */
3006
3007 if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
3008 return false;
3009
3010 return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
3011 }
3012 }
3013 }
3014
3015 return found ? false : -ENXIO;
3016 }
3017
3018 static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
3019 assert(t);
3020 assert(rr);
3021
3022 /* We know that the root domain is signed, hence if it appears
3023 * not to be signed, there's a problem with the DNS server */
3024
3025 return rr->key->class == DNS_CLASS_IN &&
3026 dns_name_is_root(dns_resource_key_name(rr->key));
3027 }
3028
3029 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
3030 DnsResourceRecord *rr;
3031 int r;
3032
3033 assert(t);
3034
3035 /* Maybe warn the user that we encountered a revoked DNSKEY
3036 * for a key from our trust anchor. Note that we don't care
3037 * whether the DNSKEY can be authenticated or not. It's
3038 * sufficient if it is self-signed. */
3039
3040 DNS_ANSWER_FOREACH(rr, t->answer) {
3041 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
3042 if (r < 0)
3043 return r;
3044 }
3045
3046 return 0;
3047 }
3048
3049 static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
3050 bool changed;
3051 int r;
3052
3053 assert(t);
3054
3055 /* Removes all DNSKEY/DS objects from t->validated_keys that
3056 * our trust anchors database considers revoked. */
3057
3058 do {
3059 DnsResourceRecord *rr;
3060
3061 changed = false;
3062
3063 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
3064 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
3065 if (r < 0)
3066 return r;
3067 if (r > 0) {
3068 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
3069 if (r < 0)
3070 return r;
3071
3072 assert(r > 0);
3073 changed = true;
3074 break;
3075 }
3076 }
3077 } while (changed);
3078
3079 return 0;
3080 }
3081
3082 static int dns_transaction_copy_validated(DnsTransaction *t) {
3083 DnsTransaction *dt;
3084 int r;
3085
3086 assert(t);
3087
3088 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
3089
3090 SET_FOREACH(dt, t->dnssec_transactions) {
3091
3092 if (DNS_TRANSACTION_IS_LIVE(dt->state))
3093 continue;
3094
3095 if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
3096 continue;
3097
3098 r = dns_answer_extend(&t->validated_keys, dt->answer);
3099 if (r < 0)
3100 return r;
3101 }
3102
3103 return 0;
3104 }
3105
3106 typedef enum {
3107 DNSSEC_PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
3108 DNSSEC_PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
3109 DNSSEC_PHASE_ALL, /* Phase #3, validate everything else */
3110 } Phase;
3111
3112 static int dnssec_validate_records(
3113 DnsTransaction *t,
3114 Phase phase,
3115 bool *have_nsec,
3116 DnsAnswer **validated) {
3117
3118 DnsResourceRecord *rr;
3119 int r;
3120
3121 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
3122
3123 DNS_ANSWER_FOREACH(rr, t->answer) {
3124 _unused_ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr_ref = dns_resource_record_ref(rr);
3125 DnsResourceRecord *rrsig = NULL;
3126 DnssecResult result;
3127
3128 switch (rr->key->type) {
3129 case DNS_TYPE_RRSIG:
3130 continue;
3131
3132 case DNS_TYPE_DNSKEY:
3133 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
3134 if (phase == DNSSEC_PHASE_NSEC)
3135 continue;
3136 break;
3137
3138 case DNS_TYPE_NSEC:
3139 case DNS_TYPE_NSEC3:
3140 *have_nsec = true;
3141
3142 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
3143 if (phase == DNSSEC_PHASE_DNSKEY)
3144 continue;
3145 break;
3146
3147 default:
3148 /* We validate all other RRs only in the ALL phases */
3149 if (phase != DNSSEC_PHASE_ALL)
3150 continue;
3151 }
3152
3153 r = dnssec_verify_rrset_search(
3154 t->answer,
3155 rr->key,
3156 t->validated_keys,
3157 USEC_INFINITY,
3158 &result,
3159 &rrsig);
3160 if (r < 0)
3161 return r;
3162
3163 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
3164
3165 if (result == DNSSEC_VALIDATED) {
3166 assert(rrsig);
3167
3168 if (rr->key->type == DNS_TYPE_DNSKEY) {
3169 /* If we just validated a DNSKEY RRset, then let's add these keys to
3170 * the set of validated keys for this transaction. */
3171
3172 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED, rrsig);
3173 if (r < 0)
3174 return r;
3175
3176 /* Some of the DNSKEYs we just added might already have been revoked,
3177 * remove them again in that case. */
3178 r = dns_transaction_invalidate_revoked_keys(t);
3179 if (r < 0)
3180 return r;
3181 }
3182
3183 /* Add the validated RRset to the new list of validated RRsets, and remove it from
3184 * the unvalidated RRsets. We mark the RRset as authenticated and cacheable. */
3185 r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE, rrsig);
3186 if (r < 0)
3187 return r;
3188
3189 manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
3190
3191 /* Exit the loop, we dropped something from the answer, start from the beginning */
3192 return 1;
3193 }
3194
3195 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
3196 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
3197 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
3198 if (phase != DNSSEC_PHASE_ALL)
3199 continue;
3200
3201 if (result == DNSSEC_VALIDATED_WILDCARD) {
3202 bool authenticated = false;
3203 const char *source;
3204
3205 assert(rrsig);
3206
3207 /* This RRset validated, but as a wildcard. This means we need
3208 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
3209
3210 /* First step, determine the source of synthesis */
3211 r = dns_resource_record_source(rrsig, &source);
3212 if (r < 0)
3213 return r;
3214
3215 r = dnssec_test_positive_wildcard(*validated,
3216 dns_resource_key_name(rr->key),
3217 source,
3218 rrsig->rrsig.signer,
3219 &authenticated);
3220
3221 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
3222 if (r == 0)
3223 result = DNSSEC_INVALID;
3224 else {
3225 r = dns_answer_move_by_key(
3226 validated,
3227 &t->answer,
3228 rr->key,
3229 authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0,
3230 rrsig);
3231 if (r < 0)
3232 return r;
3233
3234 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
3235
3236 /* Exit the loop, we dropped something from the answer, start from the beginning */
3237 return 1;
3238 }
3239 }
3240
3241 if (result == DNSSEC_NO_SIGNATURE) {
3242 r = dns_transaction_requires_rrsig(t, rr);
3243 if (r < 0)
3244 return r;
3245 if (r == 0) {
3246 /* Data does not require signing. In that case, just copy it over,
3247 * but remember that this is by no means authenticated. */
3248 r = dns_answer_move_by_key(
3249 validated,
3250 &t->answer,
3251 rr->key,
3252 0,
3253 NULL);
3254 if (r < 0)
3255 return r;
3256
3257 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3258 return 1;
3259 }
3260
3261 r = dns_transaction_known_signed(t, rr);
3262 if (r < 0)
3263 return r;
3264 if (r > 0) {
3265 /* This is an RR we know has to be signed. If it isn't this means
3266 * the server is not attaching RRSIGs, hence complain. */
3267
3268 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
3269
3270 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
3271
3272 /* Downgrading is OK? If so, just consider the information unsigned */
3273
3274 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3275 if (r < 0)
3276 return r;
3277
3278 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3279 return 1;
3280 }
3281
3282 /* Otherwise, fail */
3283 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
3284 return 0;
3285 }
3286
3287 r = dns_transaction_in_private_tld(t, rr->key);
3288 if (r < 0)
3289 return r;
3290 if (r > 0) {
3291 char s[DNS_RESOURCE_KEY_STRING_MAX];
3292
3293 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3294 * mode, hence ignore the fact that this was not signed. */
3295
3296 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3297 dns_resource_key_to_string(rr->key, s, sizeof s));
3298
3299 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3300 if (r < 0)
3301 return r;
3302
3303 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3304 return 1;
3305 }
3306 }
3307
3308 /* https://datatracker.ietf.org/doc/html/rfc6840#section-5.2 */
3309 if (result == DNSSEC_UNSUPPORTED_ALGORITHM) {
3310 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3311 if (r < 0)
3312 return r;
3313
3314 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3315 return 1;
3316 }
3317
3318 if (IN_SET(result,
3319 DNSSEC_MISSING_KEY,
3320 DNSSEC_SIGNATURE_EXPIRED)) {
3321
3322 r = dns_transaction_dnskey_authenticated(t, rr);
3323 if (r < 0 && r != -ENXIO)
3324 return r;
3325 if (r == 0) {
3326 /* The DNSKEY transaction was not authenticated, this means there's
3327 * no DS for this, which means it's OK if no keys are found for this signature. */
3328
3329 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0, NULL);
3330 if (r < 0)
3331 return r;
3332
3333 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3334 return 1;
3335 }
3336 }
3337
3338 r = dns_transaction_is_primary_response(t, rr);
3339 if (r < 0)
3340 return r;
3341 if (r > 0) {
3342 /* Look for a matching DNAME for this CNAME */
3343 r = dns_answer_has_dname_for_cname(t->answer, rr);
3344 if (r < 0)
3345 return r;
3346 if (r == 0) {
3347 /* Also look among the stuff we already validated */
3348 r = dns_answer_has_dname_for_cname(*validated, rr);
3349 if (r < 0)
3350 return r;
3351 }
3352
3353 if (r == 0) {
3354 if (IN_SET(result,
3355 DNSSEC_INVALID,
3356 DNSSEC_SIGNATURE_EXPIRED,
3357 DNSSEC_NO_SIGNATURE))
3358 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
3359 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3360 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
3361
3362 /* This is a primary response to our question, and it failed validation.
3363 * That's fatal. */
3364 t->answer_dnssec_result = result;
3365 return 0;
3366 }
3367
3368 /* This is a primary response, but we do have a DNAME RR
3369 * in the RR that can replay this CNAME, hence rely on
3370 * that, and we can remove the CNAME in favour of it. */
3371 }
3372
3373 /* This is just some auxiliary data. Just remove the RRset and continue. */
3374 r = dns_answer_remove_by_key(&t->answer, rr->key);
3375 if (r < 0)
3376 return r;
3377
3378 /* We dropped something from the answer, start from the beginning. */
3379 return 1;
3380 }
3381
3382 return 2; /* Finito. */
3383 }
3384
3385 int dns_transaction_validate_dnssec(DnsTransaction *t) {
3386 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
3387 Phase phase;
3388 DnsAnswerFlags flags;
3389 int r;
3390 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
3391
3392 assert(t);
3393
3394 /* We have now collected all DS and DNSKEY RRs in t->validated_keys, let's see which RRs we can now
3395 * authenticate with that. */
3396
3397 if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO)
3398 return 0;
3399
3400 /* Already validated */
3401 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
3402 return 0;
3403
3404 /* Our own stuff needs no validation */
3405 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
3406 t->answer_dnssec_result = DNSSEC_VALIDATED;
3407 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
3408 return 0;
3409 }
3410
3411 /* Cached stuff is not affected by validation. */
3412 if (t->answer_source != DNS_TRANSACTION_NETWORK)
3413 return 0;
3414
3415 if (!dns_transaction_dnssec_supported_full(t)) {
3416 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3417 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
3418 log_debug("Not validating response for %" PRIu16 ", used server feature level does not support DNSSEC.", t->id);
3419 return 0;
3420 }
3421
3422 log_debug("Validating response from transaction %" PRIu16 " (%s).",
3423 t->id,
3424 dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str));
3425
3426 /* First, see if this response contains any revoked trust
3427 * anchors we care about */
3428 r = dns_transaction_check_revoked_trust_anchors(t);
3429 if (r < 0)
3430 return r;
3431
3432 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3433 r = dns_transaction_copy_validated(t);
3434 if (r < 0)
3435 return r;
3436
3437 /* Second, see if there are DNSKEYs we already know a
3438 * validated DS for. */
3439 r = dns_transaction_validate_dnskey_by_ds(t);
3440 if (r < 0)
3441 return r;
3442
3443 /* Fourth, remove all DNSKEY and DS RRs again that our trust
3444 * anchor says are revoked. After all we might have marked
3445 * some keys revoked above, but they might still be lingering
3446 * in our validated_keys list. */
3447 r = dns_transaction_invalidate_revoked_keys(t);
3448 if (r < 0)
3449 return r;
3450
3451 phase = DNSSEC_PHASE_DNSKEY;
3452 for (;;) {
3453 bool have_nsec = false;
3454
3455 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
3456 if (r <= 0)
3457 return r;
3458
3459 /* Try again as long as we managed to achieve something */
3460 if (r == 1)
3461 continue;
3462
3463 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
3464 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
3465 phase = DNSSEC_PHASE_NSEC;
3466 continue;
3467 }
3468
3469 if (phase != DNSSEC_PHASE_ALL) {
3470 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3471 * Note that in this third phase we start to remove RRs we couldn't validate. */
3472 phase = DNSSEC_PHASE_ALL;
3473 continue;
3474 }
3475
3476 /* We're done */
3477 break;
3478 }
3479
3480 DNS_ANSWER_REPLACE(t->answer, TAKE_PTR(validated));
3481
3482 /* At this point the answer only contains validated
3483 * RRsets. Now, let's see if it actually answers the question
3484 * we asked. If so, great! If it doesn't, then see if
3485 * NSEC/NSEC3 can prove this. */
3486 r = dns_transaction_has_positive_answer(t, &flags);
3487 if (r > 0) {
3488 /* Yes, it answers the question! */
3489
3490 if (flags & DNS_ANSWER_AUTHENTICATED) {
3491 /* The answer is fully authenticated, yay. */
3492 t->answer_dnssec_result = DNSSEC_VALIDATED;
3493 t->answer_rcode = DNS_RCODE_SUCCESS;
3494 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
3495 } else {
3496 /* The answer is not fully authenticated. */
3497 t->answer_dnssec_result = DNSSEC_UNSIGNED;
3498 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3499 }
3500
3501 } else if (r == 0) {
3502 DnssecNsecResult nr;
3503 bool authenticated = false;
3504
3505 /* Bummer! Let's check NSEC/NSEC3 */
3506 r = dnssec_nsec_test(t->answer, dns_transaction_key(t), &nr, &authenticated, &t->answer_nsec_ttl);
3507 if (r < 0)
3508 return r;
3509
3510 switch (nr) {
3511
3512 case DNSSEC_NSEC_NXDOMAIN:
3513 /* NSEC proves the domain doesn't exist. Very good. */
3514 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3515 t->answer_dnssec_result = DNSSEC_VALIDATED;
3516 t->answer_rcode = DNS_RCODE_NXDOMAIN;
3517 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
3518
3519 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
3520 break;
3521
3522 case DNSSEC_NSEC_NODATA:
3523 /* NSEC proves that there's no data here, very good. */
3524 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3525 t->answer_dnssec_result = DNSSEC_VALIDATED;
3526 t->answer_rcode = DNS_RCODE_SUCCESS;
3527 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
3528
3529 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
3530 break;
3531
3532 case DNSSEC_NSEC_OPTOUT:
3533 /* NSEC3 says the data might not be signed */
3534 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
3535 t->answer_dnssec_result = DNSSEC_UNSIGNED;
3536 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3537
3538 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
3539 break;
3540
3541 case DNSSEC_NSEC_NO_RR:
3542 /* No NSEC data? Bummer! */
3543
3544 r = dns_transaction_requires_nsec(t);
3545 if (r < 0)
3546 return r;
3547 if (r > 0) {
3548 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
3549 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
3550 } else {
3551 t->answer_dnssec_result = DNSSEC_UNSIGNED;
3552 SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
3553 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
3554 }
3555
3556 break;
3557
3558 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
3559 /* We don't know the NSEC3 algorithm used? */
3560 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
3561 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, dns_transaction_key(t));
3562 break;
3563
3564 case DNSSEC_NSEC_FOUND:
3565 case DNSSEC_NSEC_CNAME:
3566 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
3567 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
3568 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
3569 break;
3570
3571 default:
3572 assert_not_reached();
3573 }
3574 }
3575
3576 return 1;
3577 }
3578
3579 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
3580 [DNS_TRANSACTION_NULL] = "null",
3581 [DNS_TRANSACTION_PENDING] = "pending",
3582 [DNS_TRANSACTION_VALIDATING] = "validating",
3583 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
3584 [DNS_TRANSACTION_SUCCESS] = "success",
3585 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
3586 [DNS_TRANSACTION_TIMEOUT] = "timeout",
3587 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
3588 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
3589 [DNS_TRANSACTION_ERRNO] = "errno",
3590 [DNS_TRANSACTION_ABORTED] = "aborted",
3591 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
3592 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
3593 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
3594 [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
3595 [DNS_TRANSACTION_NOT_FOUND] = "not-found",
3596 [DNS_TRANSACTION_NO_SOURCE] = "no-source",
3597 [DNS_TRANSACTION_STUB_LOOP] = "stub-loop",
3598 };
3599 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
3600
3601 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3602 [DNS_TRANSACTION_NETWORK] = "network",
3603 [DNS_TRANSACTION_CACHE] = "cache",
3604 [DNS_TRANSACTION_ZONE] = "zone",
3605 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
3606 };
3607 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);