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