1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "sd-messages.h"
6 #include "alloc-util.h"
7 #include "dns-domain.h"
8 #include "errno-list.h"
9 #include "errno-util.h"
11 #include "glyph-util.h"
12 #include "random-util.h"
13 #include "resolved-dns-cache.h"
14 #include "resolved-dns-transaction.h"
15 #include "resolved-dnstls.h"
16 #include "resolved-llmnr.h"
17 #include "string-table.h"
19 #define TRANSACTIONS_MAX 4096
20 #define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
22 /* After how much time to repeat classic DNS requests */
23 #define DNS_TIMEOUT_USEC (SD_RESOLVED_QUERY_TIMEOUT_USEC / DNS_TRANSACTION_ATTEMPTS_MAX)
25 static void dns_transaction_reset_answer(DnsTransaction
*t
) {
28 t
->received
= dns_packet_unref(t
->received
);
29 t
->answer
= dns_answer_unref(t
->answer
);
31 t
->answer_dnssec_result
= _DNSSEC_RESULT_INVALID
;
32 t
->answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
;
33 t
->answer_query_flags
= 0;
34 t
->answer_nsec_ttl
= UINT32_MAX
;
38 static void dns_transaction_flush_dnssec_transactions(DnsTransaction
*t
) {
43 while ((z
= set_steal_first(t
->dnssec_transactions
))) {
44 set_remove(z
->notify_transactions
, t
);
45 set_remove(z
->notify_transactions_done
, t
);
46 dns_transaction_gc(z
);
50 static void dns_transaction_close_connection(
52 bool use_graveyard
) { /* Set use_graveyard = false when you know the connection is already
53 * dead, for example because you got a connection error back from the
54 * kernel. In that case there's no point in keeping the fd around,
61 /* Let's detach the stream from our transaction, in case something else keeps a reference to it. */
62 LIST_REMOVE(transactions_by_stream
, t
->stream
->transactions
, t
);
64 /* Remove packet in case it's still in the queue */
65 dns_packet_unref(ordered_set_remove(t
->stream
->write_queue
, t
->sent
));
67 t
->stream
= dns_stream_unref(t
->stream
);
70 t
->dns_udp_event_source
= sd_event_source_disable_unref(t
->dns_udp_event_source
);
72 /* If we have a UDP socket where we sent a packet, but never received one, then add it to the socket
73 * graveyard, instead of closing it right away. That way it will stick around for a moment longer,
74 * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP
75 * port unreachable error message. */
77 /* Skip the graveyard stuff when we're shutting down, since that requires running event loop.
78 * Note that this is also called from dns_transaction_free(). In that case, scope may be NULL. */
81 !t
->scope
->manager
->event
||
82 sd_event_get_state(t
->scope
->manager
->event
) == SD_EVENT_FINISHED
)
83 use_graveyard
= false;
85 if (use_graveyard
&& t
->dns_udp_fd
>= 0 && t
->sent
&& !t
->received
) {
86 r
= manager_add_socket_to_graveyard(t
->scope
->manager
, t
->dns_udp_fd
);
88 log_debug_errno(r
, "Failed to add UDP socket to graveyard, closing immediately: %m");
90 TAKE_FD(t
->dns_udp_fd
);
93 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
96 static void dns_transaction_stop_timeout(DnsTransaction
*t
) {
99 t
->timeout_event_source
= sd_event_source_disable_unref(t
->timeout_event_source
);
102 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
103 DnsQueryCandidate
*c
;
110 log_debug("Freeing transaction %" PRIu16
".", t
->id
);
112 dns_transaction_close_connection(t
, true);
113 dns_transaction_stop_timeout(t
);
115 dns_packet_unref(t
->sent
);
116 dns_transaction_reset_answer(t
);
118 dns_server_unref(t
->server
);
122 DnsTransaction
*first
;
124 first
= hashmap_get(t
->scope
->transactions_by_key
, t
->key
);
125 LIST_REMOVE(transactions_by_key
, first
, t
);
127 hashmap_replace(t
->scope
->transactions_by_key
, first
->key
, first
);
129 hashmap_remove(t
->scope
->transactions_by_key
, t
->key
);
132 LIST_REMOVE(transactions_by_scope
, t
->scope
->transactions
, t
);
135 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
138 while ((c
= set_steal_first(t
->notify_query_candidates
)))
139 set_remove(c
->transactions
, t
);
140 set_free(t
->notify_query_candidates
);
142 while ((c
= set_steal_first(t
->notify_query_candidates_done
)))
143 set_remove(c
->transactions
, t
);
144 set_free(t
->notify_query_candidates_done
);
146 while ((i
= set_steal_first(t
->notify_zone_items
)))
147 i
->probe_transaction
= NULL
;
148 set_free(t
->notify_zone_items
);
150 while ((i
= set_steal_first(t
->notify_zone_items_done
)))
151 i
->probe_transaction
= NULL
;
152 set_free(t
->notify_zone_items_done
);
154 while ((z
= set_steal_first(t
->notify_transactions
)))
155 set_remove(z
->dnssec_transactions
, t
);
156 set_free(t
->notify_transactions
);
158 while ((z
= set_steal_first(t
->notify_transactions_done
)))
159 set_remove(z
->dnssec_transactions
, t
);
160 set_free(t
->notify_transactions_done
);
162 dns_transaction_flush_dnssec_transactions(t
);
163 set_free(t
->dnssec_transactions
);
165 dns_answer_unref(t
->validated_keys
);
166 dns_resource_key_unref(t
->key
);
167 dns_packet_unref(t
->bypass
);
169 free(t
->answer_ede_msg
);
174 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
176 DnsTransaction
* dns_transaction_gc(DnsTransaction
*t
) {
179 /* Returns !NULL if we can't gc yet. */
184 if (set_isempty(t
->notify_query_candidates
) &&
185 set_isempty(t
->notify_query_candidates_done
) &&
186 set_isempty(t
->notify_zone_items
) &&
187 set_isempty(t
->notify_zone_items_done
) &&
188 set_isempty(t
->notify_transactions
) &&
189 set_isempty(t
->notify_transactions_done
))
190 return dns_transaction_free(t
);
195 static uint16_t pick_new_id(Manager
*m
) {
198 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the
199 * number of transactions, and it's much lower than the space of IDs. */
201 assert_cc(TRANSACTIONS_MAX
< 0xFFFF);
204 random_bytes(&new_id
, sizeof(new_id
));
205 while (new_id
== 0 ||
206 hashmap_get(m
->dns_transactions
, UINT_TO_PTR(new_id
)));
213 DnsResourceKey
*key
) {
215 /* Don't allow looking up invalid or pseudo RRs */
216 if (!dns_type_is_valid_query(key
->type
))
218 if (dns_type_is_obsolete(key
->type
))
221 /* We only support the IN class */
222 if (!IN_SET(key
->class, DNS_CLASS_IN
, DNS_CLASS_ANY
))
225 /* Don't allows DNSSEC RRs to be looked up via LLMNR/mDNS. They don't really make sense
226 * there, and it speeds up our queries if we refuse this early */
227 if (scope
->protocol
!= DNS_PROTOCOL_DNS
&&
228 dns_type_is_dnssec(key
->type
))
234 int dns_transaction_new(
235 DnsTransaction
**ret
,
239 uint64_t query_flags
) {
241 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
257 r
= dns_packet_validate_query(bypass
);
261 DNS_QUESTION_FOREACH(qk
, bypass
->question
) {
268 if (hashmap_size(s
->manager
->dns_transactions
) >= TRANSACTIONS_MAX
)
271 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
276 r
= hashmap_ensure_allocated(&s
->transactions_by_key
, &dns_resource_key_hash_ops
);
281 t
= new(DnsTransaction
, 1);
285 *t
= (DnsTransaction
) {
286 .dns_udp_fd
= -EBADF
,
287 .answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
,
288 .answer_dnssec_result
= _DNSSEC_RESULT_INVALID
,
289 .answer_ede_rcode
= _DNS_EDE_RCODE_INVALID
,
290 .answer_nsec_ttl
= UINT32_MAX
,
291 .key
= dns_resource_key_ref(key
),
292 .query_flags
= query_flags
,
293 .bypass
= dns_packet_ref(bypass
),
294 .current_feature_level
= _DNS_SERVER_FEATURE_LEVEL_INVALID
,
295 .clamp_feature_level_servfail
= _DNS_SERVER_FEATURE_LEVEL_INVALID
,
296 .id
= pick_new_id(s
->manager
),
299 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
306 DnsTransaction
*first
;
308 first
= hashmap_get(s
->transactions_by_key
, t
->key
);
309 LIST_PREPEND(transactions_by_key
, first
, t
);
311 r
= hashmap_replace(s
->transactions_by_key
, first
->key
, first
);
313 LIST_REMOVE(transactions_by_key
, first
, t
);
318 LIST_PREPEND(transactions_by_scope
, s
->transactions
, t
);
321 s
->manager
->n_transactions_total
++;
330 static void dns_transaction_shuffle_id(DnsTransaction
*t
) {
334 /* Pick a new ID for this transaction. */
336 new_id
= pick_new_id(t
->scope
->manager
);
337 assert_se(hashmap_remove_and_put(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), UINT_TO_PTR(new_id
), t
) >= 0);
339 log_debug("Transaction %" PRIu16
" is now %" PRIu16
".", t
->id
, new_id
);
342 /* Make sure we generate a new packet with the new ID */
343 t
->sent
= dns_packet_unref(t
->sent
);
346 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
347 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
352 assert(t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
);
354 if (manager_packet_from_local_address(t
->scope
->manager
, p
) != 0)
357 log_debug("Transaction %" PRIu16
" for <%s> on scope %s on %s/%s got tentative packet from %s.",
359 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
360 dns_protocol_to_string(t
->scope
->protocol
),
361 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
362 af_to_name_short(t
->scope
->family
),
363 IN_ADDR_TO_STRING(p
->family
, &p
->sender
));
365 /* RFC 4795, Section 4.1 says that the peer with the
366 * lexicographically smaller IP address loses */
367 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
368 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
372 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
376 while ((z
= set_first(t
->notify_zone_items
))) {
377 /* First, make sure the zone item drops the reference
379 dns_zone_item_probe_stop(z
);
381 /* Secondly, report this as conflict, so that we might
382 * look for a different hostname */
383 dns_zone_item_conflict(z
);
387 dns_transaction_gc(t
);
390 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
391 DnsQueryCandidate
*c
;
395 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
398 assert(!DNS_TRANSACTION_IS_LIVE(state
));
400 if (state
== DNS_TRANSACTION_DNSSEC_FAILED
) {
401 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
);
403 log_struct(LOG_NOTICE
,
404 "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR
,
405 LOG_MESSAGE("DNSSEC validation failed for question %s: %s",
406 key_str
, dnssec_result_to_string(t
->answer_dnssec_result
)),
407 "DNS_TRANSACTION=%" PRIu16
, t
->id
,
408 "DNS_QUESTION=%s", key_str
,
409 "DNSSEC_RESULT=%s", dnssec_result_to_string(t
->answer_dnssec_result
),
410 "DNS_SERVER=%s", strna(dns_server_string_full(t
->server
)),
411 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t
->server
->possible_feature_level
));
414 if (state
== DNS_TRANSACTION_UPSTREAM_DNSSEC_FAILURE
) {
415 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
);
417 log_struct(LOG_NOTICE
,
418 "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR
,
419 LOG_MESSAGE("Upstream resolver reported failure for question %s: %s%s%s",
420 key_str
, dns_ede_rcode_to_string(t
->answer_ede_rcode
),
421 isempty(t
->answer_ede_msg
) ? "" : ": ", t
->answer_ede_msg
),
422 "DNS_TRANSACTION=%" PRIu16
, t
->id
,
423 "DNS_QUESTION=%s", key_str
,
424 "DNS_EDE_RCODE=%s", dns_ede_rcode_to_string(t
->answer_ede_rcode
),
425 "DNS_SERVER=%s", strna(dns_server_string_full(t
->server
)),
426 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t
->server
->possible_feature_level
));
429 /* Note that this call might invalidate the query. Callers
430 * should hence not attempt to access the query or transaction
431 * after calling this function. */
433 if (state
== DNS_TRANSACTION_ERRNO
)
434 st
= errno_to_name(t
->answer_errno
);
436 st
= dns_transaction_state_to_string(state
);
438 log_debug("%s transaction %" PRIu16
" for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s; %s).",
439 t
->bypass
? "Bypass" : "Regular",
441 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
442 dns_protocol_to_string(t
->scope
->protocol
),
443 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
444 af_to_name_short(t
->scope
->family
),
446 t
->answer_source
< 0 ? "none" : dns_transaction_source_to_string(t
->answer_source
),
447 FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) ? "not validated" :
448 (FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
) ? "authenticated" : "unsigned"),
449 FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
) ? "confidential" : "non-confidential");
453 dns_transaction_close_connection(t
, true);
454 dns_transaction_stop_timeout(t
);
456 /* Notify all queries that are interested, but make sure the
457 * transaction isn't freed while we are still looking at it */
460 SET_FOREACH_MOVE(c
, t
->notify_query_candidates_done
, t
->notify_query_candidates
)
461 dns_query_candidate_notify(c
);
462 SWAP_TWO(t
->notify_query_candidates
, t
->notify_query_candidates_done
);
464 SET_FOREACH_MOVE(z
, t
->notify_zone_items_done
, t
->notify_zone_items
)
465 dns_zone_item_notify(z
);
466 SWAP_TWO(t
->notify_zone_items
, t
->notify_zone_items_done
);
467 if (t
->probing
&& t
->state
== DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
)
468 (void) dns_scope_announce(t
->scope
, false);
470 SET_FOREACH_MOVE(d
, t
->notify_transactions_done
, t
->notify_transactions
)
471 dns_transaction_notify(d
, t
);
472 SWAP_TWO(t
->notify_transactions
, t
->notify_transactions_done
);
475 dns_transaction_gc(t
);
478 static void dns_transaction_complete_errno(DnsTransaction
*t
, int error
) {
482 t
->answer_errno
= abs(error
);
483 dns_transaction_complete(t
, DNS_TRANSACTION_ERRNO
);
486 static int dns_transaction_pick_server(DnsTransaction
*t
) {
490 assert(t
->scope
->protocol
== DNS_PROTOCOL_DNS
);
492 /* Pick a DNS server and a feature level for it. */
494 server
= dns_scope_get_dns_server(t
->scope
);
498 /* If we changed the server invalidate the feature level clamping, as the new server might have completely
499 * different properties. */
500 if (server
!= t
->server
)
501 t
->clamp_feature_level_servfail
= _DNS_SERVER_FEATURE_LEVEL_INVALID
;
503 t
->current_feature_level
= dns_server_possible_feature_level(server
);
505 /* Clamp the feature level if that is requested. */
506 if (t
->clamp_feature_level_servfail
!= _DNS_SERVER_FEATURE_LEVEL_INVALID
&&
507 t
->current_feature_level
> t
->clamp_feature_level_servfail
)
508 t
->current_feature_level
= t
->clamp_feature_level_servfail
;
510 log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t
->current_feature_level
), t
->id
);
512 if (server
== t
->server
)
515 dns_server_unref(t
->server
);
516 t
->server
= dns_server_ref(server
);
518 t
->n_picked_servers
++;
520 log_debug("Using DNS server %s for transaction %u.", strna(dns_server_string_full(t
->server
)), t
->id
);
525 static void dns_transaction_retry(DnsTransaction
*t
, bool next_server
) {
530 /* Retries the transaction as it is, possibly on a different server */
532 if (next_server
&& t
->scope
->protocol
== DNS_PROTOCOL_DNS
)
533 log_debug("Retrying transaction %" PRIu16
", after switching servers.", t
->id
);
535 log_debug("Retrying transaction %" PRIu16
".", t
->id
);
537 /* Before we try again, switch to a new server. */
539 dns_scope_next_dns_server(t
->scope
, t
->server
);
541 r
= dns_transaction_go(t
);
543 dns_transaction_complete_errno(t
, r
);
546 static bool dns_transaction_limited_retry(DnsTransaction
*t
) {
549 /* If we haven't tried all different servers yet, let's try again with a different server */
551 if (t
->n_picked_servers
>= dns_scope_get_n_dns_servers(t
->scope
))
554 dns_transaction_retry(t
, /* next_server= */ true);
558 static int dns_transaction_maybe_restart(DnsTransaction
*t
) {
563 /* Restarts the transaction, under a new ID if the feature level of the server changed since we first
564 * tried, without changing DNS server. Returns > 0 if the transaction was restarted, 0 if not. */
569 if (t
->current_feature_level
<= dns_server_possible_feature_level(t
->server
))
572 /* The server's current feature level is lower than when we sent the original query. We learnt something from
573 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
574 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
575 OPT RR or DO bit. One of these cases is documented here, for example:
576 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
578 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
579 dns_transaction_shuffle_id(t
);
581 r
= dns_transaction_go(t
);
588 static void on_transaction_stream_error(DnsTransaction
*t
, int error
) {
591 dns_transaction_close_connection(t
, true);
593 if (ERRNO_IS_DISCONNECT(error
)) {
594 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
595 /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
596 * question on this scope. */
597 dns_transaction_complete(t
, DNS_TRANSACTION_NOT_FOUND
);
601 dns_transaction_retry(t
, true);
605 dns_transaction_complete_errno(t
, error
);
608 static int dns_transaction_on_stream_packet(DnsTransaction
*t
, DnsStream
*s
, DnsPacket
*p
) {
615 encrypted
= s
->encrypted
;
617 dns_transaction_close_connection(t
, true);
619 if (dns_packet_validate_reply(p
) <= 0) {
620 log_debug("Invalid TCP reply packet.");
621 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
625 dns_scope_check_conflicts(t
->scope
, p
);
628 dns_transaction_process_reply(t
, p
, encrypted
);
631 /* If the response wasn't useful, then complete the transition
632 * now. After all, we are the worst feature set now with TCP
633 * sockets, and there's really no point in retrying. */
634 if (t
->state
== DNS_TRANSACTION_PENDING
)
635 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
637 dns_transaction_gc(t
);
642 static int on_stream_complete(DnsStream
*s
, int error
) {
645 if (ERRNO_IS_DISCONNECT(error
) && s
->protocol
!= DNS_PROTOCOL_LLMNR
) {
646 log_debug_errno(error
, "Connection failure for DNS TCP stream: %m");
648 if (s
->transactions
) {
652 dns_server_packet_lost(t
->server
, IPPROTO_TCP
, t
->current_feature_level
);
657 LIST_FOREACH(transactions_by_stream
, t
, s
->transactions
)
658 on_transaction_stream_error(t
, error
);
663 static int on_stream_packet(DnsStream
*s
, DnsPacket
*p
) {
670 t
= hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
671 if (t
&& t
->stream
== s
) /* Validate that the stream we got this on actually is the stream the
672 * transaction was using. */
673 return dns_transaction_on_stream_packet(t
, s
, p
);
675 /* Ignore incorrect transaction id as an old transaction can have been canceled. */
676 log_debug("Received unexpected TCP reply packet with id %" PRIu16
", ignoring.", DNS_PACKET_ID(p
));
680 static uint16_t dns_transaction_port(DnsTransaction
*t
) {
683 if (t
->server
->port
> 0)
684 return t
->server
->port
;
686 return DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) ? 853 : 53;
689 static int dns_transaction_emit_tcp(DnsTransaction
*t
) {
690 usec_t stream_timeout_usec
= DNS_STREAM_DEFAULT_TIMEOUT_USEC
;
691 _cleanup_(dns_stream_unrefp
) DnsStream
*s
= NULL
;
692 _cleanup_close_
int fd
= -EBADF
;
693 union sockaddr_union sa
;
700 dns_transaction_close_connection(t
, true);
702 switch (t
->scope
->protocol
) {
704 case DNS_PROTOCOL_DNS
:
705 r
= dns_transaction_pick_server(t
);
709 if (manager_server_is_stub(t
->scope
->manager
, t
->server
))
713 if (!dns_server_dnssec_supported(t
->server
) && dns_type_is_dnssec(dns_transaction_key(t
)->type
))
716 r
= dns_server_adjust_opt(t
->server
, t
->sent
, t
->current_feature_level
);
721 if (t
->server
->stream
&& (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) == t
->server
->stream
->encrypted
))
722 s
= dns_stream_ref(t
->server
->stream
);
724 fd
= dns_scope_socket_tcp(t
->scope
, AF_UNSPEC
, NULL
, t
->server
, dns_transaction_port(t
), &sa
);
726 /* Lower timeout in DNS-over-TLS opportunistic mode. In environments where DoT is blocked
727 * without ICMP response overly long delays when contacting DoT servers are nasty, in
728 * particular if multiple DNS servers are defined which we try in turn and all are
729 * blocked. Hence, substantially lower the timeout in that case. */
730 if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) &&
731 dns_server_get_dns_over_tls_mode(t
->server
) == DNS_OVER_TLS_OPPORTUNISTIC
)
732 stream_timeout_usec
= DNS_STREAM_OPPORTUNISTIC_TLS_TIMEOUT_USEC
;
734 type
= DNS_STREAM_LOOKUP
;
737 case DNS_PROTOCOL_LLMNR
:
738 /* When we already received a reply to this (but it was truncated), send to its sender address */
740 fd
= dns_scope_socket_tcp(t
->scope
, t
->received
->family
, &t
->received
->sender
, NULL
, t
->received
->sender_port
, &sa
);
742 union in_addr_union address
;
743 int family
= AF_UNSPEC
;
745 /* Otherwise, try to talk to the owner of a
746 * the IP address, in case this is a reverse
749 r
= dns_name_address(dns_resource_key_name(dns_transaction_key(t
)), &family
, &address
);
754 if (family
!= t
->scope
->family
)
757 fd
= dns_scope_socket_tcp(t
->scope
, family
, &address
, NULL
, LLMNR_PORT
, &sa
);
760 type
= DNS_STREAM_LLMNR_SEND
;
764 return -EAFNOSUPPORT
;
771 r
= dns_stream_new(t
->scope
->manager
, &s
, type
, t
->scope
->protocol
, fd
, &sa
,
772 on_stream_packet
, on_stream_complete
, stream_timeout_usec
);
778 #if ENABLE_DNS_OVER_TLS
779 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
780 DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
)) {
783 r
= dnstls_stream_connect_tls(s
, t
->server
);
790 dns_server_unref_stream(t
->server
);
791 s
->server
= dns_server_ref(t
->server
);
792 t
->server
->stream
= dns_stream_ref(s
);
795 /* The interface index is difficult to determine if we are
796 * connecting to the local host, hence fill this in right away
797 * instead of determining it from the socket */
798 s
->ifindex
= dns_scope_ifindex(t
->scope
);
801 t
->stream
= TAKE_PTR(s
);
802 LIST_PREPEND(transactions_by_stream
, t
->stream
->transactions
, t
);
804 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
806 dns_transaction_close_connection(t
, /* use_graveyard= */ false);
810 dns_transaction_reset_answer(t
);
812 t
->tried_stream
= true;
817 static void dns_transaction_cache_answer(DnsTransaction
*t
) {
820 /* For mDNS we cache whenever we get the packet, rather than
821 * in each transaction. */
822 if (!IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
))
825 /* Caching disabled? */
826 if (t
->scope
->manager
->enable_cache
== DNS_CACHE_MODE_NO
)
829 /* If validation is turned off for this transaction, but DNSSEC is on, then let's not cache this */
830 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) && t
->scope
->dnssec_mode
!= DNSSEC_NO
)
833 /* Packet from localhost? */
834 if (!t
->scope
->manager
->cache_from_localhost
&&
835 in_addr_is_localhost(t
->received
->family
, &t
->received
->sender
) != 0)
838 dns_cache_put(&t
->scope
->cache
,
839 t
->scope
->manager
->enable_cache
,
841 dns_transaction_key(t
),
844 DNS_PACKET_CD(t
->received
) ? t
->received
: NULL
, /* only cache full packets with CD on,
845 * since our use case for caching them
846 * is "bypass" mode which is only
847 * enabled for CD packets. */
848 t
->answer_query_flags
,
849 t
->answer_dnssec_result
,
852 &t
->received
->sender
,
853 t
->scope
->manager
->stale_retention_usec
);
856 static bool dns_transaction_dnssec_is_live(DnsTransaction
*t
) {
861 SET_FOREACH(dt
, t
->dnssec_transactions
)
862 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
868 static int dns_transaction_dnssec_ready(DnsTransaction
*t
) {
874 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
875 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
877 SET_FOREACH(dt
, t
->dnssec_transactions
) {
881 case DNS_TRANSACTION_NULL
:
882 case DNS_TRANSACTION_PENDING
:
883 case DNS_TRANSACTION_VALIDATING
:
887 case DNS_TRANSACTION_RCODE_FAILURE
:
888 if (!IN_SET(dt
->answer_rcode
, DNS_RCODE_NXDOMAIN
, DNS_RCODE_SERVFAIL
)) {
889 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", FORMAT_DNS_RCODE(dt
->answer_rcode
));
893 /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
894 * erroneously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
895 * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
896 * RRs to make unsigned proofs. */
898 case DNS_TRANSACTION_SUCCESS
:
902 case DNS_TRANSACTION_DNSSEC_FAILED
:
903 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
904 * validation result */
906 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt
->answer_dnssec_result
));
907 t
->answer_dnssec_result
= dt
->answer_dnssec_result
; /* Copy error code over */
908 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
912 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt
->state
));
917 /* All is ready, we can go and validate */
921 /* Some auxiliary DNSSEC transaction failed for some reason. Maybe we learned something about the
922 * server due to this failure, and the feature level is now different? Let's see and restart the
923 * transaction if so. If not, let's propagate the auxiliary failure.
925 * This is particularly relevant if an auxiliary request figured out that DNSSEC doesn't work, and we
926 * are in permissive DNSSEC mode, and thus should restart things without DNSSEC magic. */
927 r
= dns_transaction_maybe_restart(t
);
931 return 0; /* don't validate just yet, we restarted things */
933 t
->answer_dnssec_result
= DNSSEC_FAILED_AUXILIARY
;
934 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
938 static void dns_transaction_process_dnssec(DnsTransaction
*t
) {
943 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
944 r
= dns_transaction_dnssec_ready(t
);
947 if (r
== 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
950 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
951 * restart the lookup immediately. */
952 r
= dns_transaction_maybe_restart(t
);
955 if (r
> 0) /* Transaction got restarted... */
958 /* All our auxiliary DNSSEC transactions are complete now. Try
959 * to validate our RRset now. */
960 r
= dns_transaction_validate_dnssec(t
);
962 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
968 if (t
->answer_dnssec_result
== DNSSEC_INCOMPATIBLE_SERVER
&&
969 t
->scope
->dnssec_mode
== DNSSEC_YES
) {
971 /* We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
974 if (dns_transaction_limited_retry(t
))
977 /* OK, let's give up, apparently all servers we tried didn't work. */
978 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
982 if (!IN_SET(t
->answer_dnssec_result
,
983 _DNSSEC_RESULT_INVALID
, /* No DNSSEC validation enabled */
984 DNSSEC_VALIDATED
, /* Answer is signed and validated successfully */
985 DNSSEC_UNSIGNED
, /* Answer is right-fully unsigned */
986 DNSSEC_INCOMPATIBLE_SERVER
)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
987 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
991 if (t
->answer_dnssec_result
== DNSSEC_INCOMPATIBLE_SERVER
)
992 dns_server_warn_downgrade(t
->server
);
994 dns_transaction_cache_answer(t
);
996 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
997 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
999 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
1004 dns_transaction_complete_errno(t
, r
);
1007 static int dns_transaction_has_positive_answer(DnsTransaction
*t
, DnsAnswerFlags
*flags
) {
1012 /* Checks whether the answer is positive, i.e. either a direct
1013 * answer to the question, or a CNAME/DNAME for it */
1015 r
= dns_answer_match_key(t
->answer
, dns_transaction_key(t
), flags
);
1019 r
= dns_answer_find_cname_or_dname(t
->answer
, dns_transaction_key(t
), NULL
, flags
);
1026 static int dns_transaction_fix_rcode(DnsTransaction
*t
) {
1031 /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
1032 * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
1033 * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
1034 * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
1035 * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
1036 * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
1037 * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
1038 * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
1039 * incomplete CNAME/DNAME chain.
1041 * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
1042 * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
1045 if (t
->answer_rcode
!= DNS_RCODE_NXDOMAIN
)
1048 r
= dns_transaction_has_positive_answer(t
, NULL
);
1052 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1056 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
, bool encrypted
) {
1057 bool retry_with_tcp
= false;
1063 assert(t
->scope
->manager
);
1065 if (t
->state
!= DNS_TRANSACTION_PENDING
)
1068 /* Increment the total failure counter only when it is the first attempt at querying and the upstream
1069 * server returns a failure response code. This ensures a more accurate count of the number of queries
1070 * that received a failure response code, as it doesn't consider retries. */
1072 if (t
->n_attempts
== 1 && !IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_SUCCESS
, DNS_RCODE_NXDOMAIN
))
1073 t
->scope
->manager
->n_failure_responses_total
++;
1075 /* Note that this call might invalidate the query. Callers
1076 * should hence not attempt to access the query or transaction
1077 * after calling this function. */
1079 log_debug("Processing incoming packet of size %zu on transaction %" PRIu16
" (rcode=%s).",
1081 t
->id
, FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1083 switch (t
->scope
->protocol
) {
1085 case DNS_PROTOCOL_LLMNR
:
1086 /* For LLMNR we will not accept any packets from other interfaces */
1088 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1091 if (p
->family
!= t
->scope
->family
)
1094 /* Tentative packets are not full responses but still
1095 * useful for identifying uniqueness conflicts during
1097 if (DNS_PACKET_LLMNR_T(p
)) {
1098 dns_transaction_tentative(t
, p
);
1104 case DNS_PROTOCOL_MDNS
:
1105 /* For mDNS we will not accept any packets from other interfaces */
1107 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1110 if (p
->family
!= t
->scope
->family
)
1115 case DNS_PROTOCOL_DNS
:
1116 /* Note that we do not need to verify the
1117 * addresses/port numbers of incoming traffic, as we
1118 * invoked connect() on our UDP socket in which case
1119 * the kernel already does the needed verification for
1124 assert_not_reached();
1127 if (t
->received
!= p
)
1128 DNS_PACKET_REPLACE(t
->received
, dns_packet_ref(p
));
1130 t
->answer_source
= DNS_TRANSACTION_NETWORK
;
1132 if (p
->ipproto
== IPPROTO_TCP
) {
1133 if (DNS_PACKET_TC(p
)) {
1134 /* Truncated via TCP? Somebody must be fucking with us */
1135 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1139 if (DNS_PACKET_ID(p
) != t
->id
) {
1140 /* Not the reply to our query? Somebody must be fucking with us */
1141 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1146 if (DNS_PACKET_TC(p
)) {
1148 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1149 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
) {
1150 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1154 /* Response was truncated, let's try again with good old TCP */
1155 log_debug("Reply truncated, retrying via TCP.");
1156 retry_with_tcp
= true;
1158 } else if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1159 DNS_PACKET_IS_FRAGMENTED(p
)) {
1161 /* Report the fragment size, so that we downgrade from LARGE to regular EDNS0 if needed */
1163 dns_server_packet_udp_fragmented(t
->server
, dns_packet_size_unfragmented(p
));
1165 if (t
->current_feature_level
> DNS_SERVER_FEATURE_LEVEL_UDP
) {
1166 /* Packet was fragmented. Let's retry with TCP to avoid fragmentation attack
1167 * issues. (We don't do that on the lowest feature level however, since crappy DNS
1168 * servers often do not implement TCP, hence falling back to TCP on fragmentation is
1169 * counter-productive there.) */
1171 log_debug("Reply fragmented, retrying via TCP. (Largest fragment size: %zu; Datagram size: %zu)",
1172 p
->fragsize
, p
->size
);
1173 retry_with_tcp
= true;
1177 if (retry_with_tcp
) {
1178 r
= dns_transaction_emit_tcp(t
);
1180 /* No servers found? Damn! */
1181 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1184 if (r
== -EOPNOTSUPP
) {
1185 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1186 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
1190 /* On LLMNR, if we cannot connect to the host,
1191 * we immediately give up */
1192 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1195 /* On DNS, couldn't send? Try immediately again, with a new server */
1196 if (dns_transaction_limited_retry(t
))
1199 /* No new server to try, give up */
1200 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1206 /* After the superficial checks, actually parse the message. */
1207 r
= dns_packet_extract(p
);
1210 dns_server_packet_invalid(t
->server
, t
->current_feature_level
);
1212 r
= dns_transaction_maybe_restart(t
);
1215 if (r
> 0) /* Transaction got restarted... */
1219 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1223 switch (t
->scope
->protocol
) {
1225 case DNS_PROTOCOL_DNS
: {
1227 _cleanup_free_
char *ede_msg
= NULL
;
1231 ede_rcode
= dns_packet_ede_rcode(p
, &ede_msg
);
1232 if (ede_rcode
< 0 && ede_rcode
!= -EINVAL
)
1233 log_debug_errno(ede_rcode
, "Unable to extract EDE error code from packet, ignoring: %m");
1235 t
->answer_ede_rcode
= ede_rcode
;
1236 t
->answer_ede_msg
= TAKE_PTR(ede_msg
);
1240 IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_FORMERR
, DNS_RCODE_SERVFAIL
, DNS_RCODE_NOTIMP
)) {
1241 /* If the server has replied with detailed error data, using a degraded feature set
1242 * will likely not help anyone. Examine the detailed error to determine the best
1243 * course of action. */
1244 if (ede_rcode
>= 0 && DNS_PACKET_RCODE(p
) == DNS_RCODE_SERVFAIL
) {
1245 /* These codes are related to DNSSEC configuration errors. If accurate,
1246 * this is the domain operator's problem, and retrying won't help. */
1247 if (dns_ede_rcode_is_dnssec(ede_rcode
)) {
1248 log_debug("Server returned error: %s (%s%s%s). Lookup failed.",
1249 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1250 FORMAT_DNS_EDE_RCODE(ede_rcode
),
1251 isempty(t
->answer_ede_msg
) ? "" : ": ",
1253 dns_transaction_complete(t
, DNS_TRANSACTION_UPSTREAM_DNSSEC_FAILURE
);
1257 /* These codes probably indicate a transient error. Let's try again. */
1258 if (IN_SET(ede_rcode
, DNS_EDE_RCODE_NOT_READY
, DNS_EDE_RCODE_NET_ERROR
)) {
1259 log_debug("Server returned error: %s (%s%s%s), retrying transaction.",
1260 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1261 FORMAT_DNS_EDE_RCODE(ede_rcode
),
1262 isempty(t
->answer_ede_msg
) ? "" : ": ",
1264 dns_transaction_retry(t
, false);
1268 /* OK, the query failed, but we still shouldn't degrade the feature set for
1270 log_debug("Server returned error: %s (%s%s%s)",
1271 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1272 FORMAT_DNS_EDE_RCODE(ede_rcode
),
1273 isempty(t
->answer_ede_msg
) ? "" : ": ", t
->answer_ede_msg
);
1275 } /* No EDE rcode, or EDE rcode we don't understand */
1277 /* Request failed, immediately try again with reduced features */
1279 if (t
->current_feature_level
<= DNS_SERVER_FEATURE_LEVEL_UDP
) {
1281 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
1282 * this transaction anymore, but let's see if it might make sense to send the request
1283 * to a different DNS server instead. If not let's process the response, and accept the
1284 * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1285 * packet loss, but is not going to give us better rcodes should we actually have
1286 * managed to get them already at UDP level. */
1288 if (dns_transaction_limited_retry(t
))
1291 /* Give up, accept the rcode */
1292 log_debug("Server returned error: %s", FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1296 /* SERVFAIL can happen for many reasons and may be transient.
1297 * To avoid unnecessary downgrades retry once with the initial level.
1298 * Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
1299 * first attempt to downgrade. If so, clamp to the current value so that the transaction
1300 * is retried without actually downgrading. If the next try also fails we will downgrade by
1301 * hitting the else branch below. */
1302 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_SERVFAIL
&&
1303 t
->clamp_feature_level_servfail
< 0) {
1304 t
->clamp_feature_level_servfail
= t
->current_feature_level
;
1305 log_debug("Server returned error %s, retrying transaction.",
1306 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1308 /* Reduce this feature level by one and try again. */
1309 switch (t
->current_feature_level
) {
1310 case DNS_SERVER_FEATURE_LEVEL_TLS_DO
:
1311 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
;
1313 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
+ 1:
1314 /* Skip plain TLS when TLS is not supported */
1315 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
- 1;
1318 t
->clamp_feature_level_servfail
= t
->current_feature_level
- 1;
1321 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1322 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1323 dns_server_feature_level_to_string(t
->clamp_feature_level_servfail
));
1326 dns_transaction_retry(t
, false /* use the same server */);
1330 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_REFUSED
) {
1331 /* This server refused our request? If so, try again, use a different server */
1333 log_debug("Server returned REFUSED (%s), switching servers, and retrying.",
1334 FORMAT_DNS_EDE_RCODE(ede_rcode
));
1336 log_debug("Server returned REFUSED, switching servers, and retrying.");
1338 if (dns_transaction_limited_retry(t
))
1344 if (DNS_PACKET_TC(p
))
1345 dns_server_packet_truncated(t
->server
, t
->current_feature_level
);
1350 case DNS_PROTOCOL_LLMNR
:
1351 case DNS_PROTOCOL_MDNS
:
1352 dns_scope_packet_received(t
->scope
, p
->timestamp
- t
->start_usec
);
1356 assert_not_reached();
1360 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1361 * rcode and subsequently downgraded the protocol */
1363 if (IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_SUCCESS
, DNS_RCODE_NXDOMAIN
) &&
1364 t
->clamp_feature_level_servfail
!= _DNS_SERVER_FEATURE_LEVEL_INVALID
)
1365 dns_server_packet_rcode_downgrade(t
->server
, t
->clamp_feature_level_servfail
);
1367 /* Report that the OPT RR was missing */
1369 dns_server_packet_bad_opt(t
->server
, t
->current_feature_level
);
1371 /* Report that the server didn't copy our query DO bit from request to response */
1372 if (DNS_PACKET_DO(t
->sent
) && !DNS_PACKET_DO(t
->received
))
1373 dns_server_packet_do_off(t
->server
, t
->current_feature_level
);
1375 /* Report that we successfully received a packet. We keep track of the largest packet
1376 * size/fragment size we got. Which is useful for announcing the EDNS(0) packet size we can
1377 * receive to our server. */
1378 dns_server_packet_received(t
->server
, p
->ipproto
, t
->current_feature_level
, dns_packet_size_unfragmented(p
));
1381 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1382 r
= dns_transaction_maybe_restart(t
);
1385 if (r
> 0) /* Transaction got restarted... */
1388 /* When dealing with protocols other than mDNS only consider responses with equivalent query section
1389 * to the request. For mDNS this check doesn't make sense, because the section 6 of RFC6762 states
1390 * that "Multicast DNS responses MUST NOT contain any questions in the Question Section". */
1391 if (t
->scope
->protocol
!= DNS_PROTOCOL_MDNS
) {
1392 r
= dns_packet_is_reply_for(p
, dns_transaction_key(t
));
1396 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1401 /* Install the answer as answer to the transaction. We ref the answer twice here: the main `answer`
1402 * field is later replaced by the DNSSEC validated subset. The 'answer_auxiliary' field carries the
1403 * original complete record set, including RRSIG and friends. We use this when passing data to
1404 * clients that ask for DNSSEC metadata. */
1405 DNS_ANSWER_REPLACE(t
->answer
, dns_answer_ref(p
->answer
));
1406 t
->answer_rcode
= DNS_PACKET_RCODE(p
);
1407 t
->answer_dnssec_result
= _DNSSEC_RESULT_INVALID
;
1408 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1409 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, encrypted
);
1411 r
= dns_transaction_fix_rcode(t
);
1415 /* Block GC while starting requests for additional DNSSEC RRs */
1417 r
= dns_transaction_request_dnssec_keys(t
);
1420 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1421 if (!dns_transaction_gc(t
))
1424 /* Requesting additional keys might have resulted in this transaction to fail, since the auxiliary
1425 * request failed for some reason. If so, we are not in pending state anymore, and we should exit
1427 if (t
->state
!= DNS_TRANSACTION_PENDING
)
1432 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1433 t
->state
= DNS_TRANSACTION_VALIDATING
;
1434 dns_transaction_close_connection(t
, true);
1435 dns_transaction_stop_timeout(t
);
1439 dns_transaction_process_dnssec(t
);
1443 dns_transaction_complete_errno(t
, r
);
1446 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1447 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1448 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1453 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
1455 if (ERRNO_IS_DISCONNECT(r
)) {
1458 /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
1459 * next recvmsg(). Treat this like a lost packet. */
1461 log_debug_errno(r
, "Connection failure for DNS UDP packet: %m");
1462 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &usec
) >= 0);
1463 dns_server_packet_lost(t
->server
, IPPROTO_UDP
, t
->current_feature_level
);
1465 dns_transaction_close_connection(t
, /* use_graveyard = */ false);
1467 if (dns_transaction_limited_retry(t
)) /* Try a different server */
1470 dns_transaction_complete_errno(t
, r
);
1474 /* Spurious wakeup without any data */
1477 r
= dns_packet_validate_reply(p
);
1479 log_debug_errno(r
, "Received invalid DNS packet as response, ignoring: %m");
1483 log_debug("Received inappropriate DNS packet as response, ignoring.");
1487 if (DNS_PACKET_ID(p
) != t
->id
) {
1488 log_debug("Received packet with incorrect transaction ID, ignoring.");
1492 dns_transaction_process_reply(t
, p
, false);
1496 static int dns_transaction_emit_udp(DnsTransaction
*t
) {
1501 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
) {
1503 r
= dns_transaction_pick_server(t
);
1507 if (manager_server_is_stub(t
->scope
->manager
, t
->server
))
1510 if (t
->current_feature_level
< DNS_SERVER_FEATURE_LEVEL_UDP
|| DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
))
1511 return -EAGAIN
; /* Sorry, can't do UDP, try TCP! */
1513 if (!t
->bypass
&& !dns_server_dnssec_supported(t
->server
) && dns_type_is_dnssec(dns_transaction_key(t
)->type
))
1516 if (r
> 0 || t
->dns_udp_fd
< 0) { /* Server changed, or no connection yet. */
1519 dns_transaction_close_connection(t
, true);
1521 /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */
1522 manager_socket_graveyard_process(t
->scope
->manager
);
1524 fd
= dns_scope_socket_udp(t
->scope
, t
->server
);
1528 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
1534 (void) sd_event_source_set_description(t
->dns_udp_event_source
, "dns-transaction-udp");
1539 r
= dns_server_adjust_opt(t
->server
, t
->sent
, t
->current_feature_level
);
1544 dns_transaction_close_connection(t
, true);
1546 r
= dns_scope_emit_udp(t
->scope
, t
->dns_udp_fd
, t
->server
? t
->server
->family
: AF_UNSPEC
, t
->sent
);
1550 dns_transaction_reset_answer(t
);
1555 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1556 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1560 t
->seen_timeout
= true;
1562 if (t
->initial_jitter_scheduled
&& !t
->initial_jitter_elapsed
) {
1563 log_debug("Initial jitter phase for transaction %" PRIu16
" elapsed.", t
->id
);
1564 t
->initial_jitter_elapsed
= true;
1566 /* Timeout reached? Increase the timeout for the server used */
1567 switch (t
->scope
->protocol
) {
1569 case DNS_PROTOCOL_DNS
:
1571 dns_server_packet_lost(t
->server
, t
->stream
? IPPROTO_TCP
: IPPROTO_UDP
, t
->current_feature_level
);
1574 case DNS_PROTOCOL_LLMNR
:
1575 case DNS_PROTOCOL_MDNS
:
1576 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
1580 assert_not_reached();
1583 log_debug("Timeout reached on transaction %" PRIu16
".", t
->id
);
1586 dns_transaction_retry(t
, /* next_server= */ true); /* try a different server, but given this means
1587 * packet loss, let's do so even if we already
1592 static int dns_transaction_setup_timeout(
1594 usec_t timeout_usec
/* relative */,
1595 usec_t next_usec
/* CLOCK_BOOTTIME */) {
1601 dns_transaction_stop_timeout(t
);
1603 r
= sd_event_add_time_relative(
1604 t
->scope
->manager
->event
,
1605 &t
->timeout_event_source
,
1608 on_transaction_timeout
, t
);
1612 (void) sd_event_source_set_description(t
->timeout_event_source
, "dns-transaction-timeout");
1614 t
->next_attempt_after
= next_usec
;
1615 t
->state
= DNS_TRANSACTION_PENDING
;
1619 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
1623 switch (t
->scope
->protocol
) {
1625 case DNS_PROTOCOL_DNS
:
1627 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1628 * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1631 return TRANSACTION_TCP_TIMEOUT_USEC
;
1633 return DNS_TIMEOUT_USEC
;
1635 case DNS_PROTOCOL_MDNS
:
1637 return MDNS_PROBING_INTERVAL_USEC
;
1639 /* See RFC 6762 Section 5.1 suggests that timeout should be a few seconds. */
1640 assert(t
->n_attempts
> 0);
1641 return (1 << (t
->n_attempts
- 1)) * USEC_PER_SEC
;
1643 case DNS_PROTOCOL_LLMNR
:
1644 return t
->scope
->resend_timeout
;
1647 assert_not_reached();
1651 static void dns_transaction_randomize_answer(DnsTransaction
*t
) {
1656 /* Randomizes the order of the answer array. This is done for all cached responses, so that we return
1657 * a different order each time. We do this only for DNS traffic, in order to do some minimal, crappy
1658 * load balancing. We don't do this for LLMNR or mDNS, since the order (preferring link-local
1659 * addresses, and such like) might have meaning there, and load balancing is pointless. */
1661 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1664 /* No point in randomizing, if there's just one RR */
1665 if (dns_answer_size(t
->answer
) <= 1)
1668 r
= dns_answer_reserve_or_clone(&t
->answer
, 0);
1669 if (r
< 0) /* If this fails, just don't randomize, this is non-essential stuff after all */
1670 return (void) log_debug_errno(r
, "Failed to clone answer record, not randomizing RR order of answer: %m");
1672 dns_answer_randomize(t
->answer
);
1675 static int dns_transaction_prepare(DnsTransaction
*t
, usec_t ts
) {
1680 /* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
1681 * candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
1682 * has been prepared. */
1684 dns_transaction_stop_timeout(t
);
1686 if (t
->n_attempts
== 1 && t
->seen_timeout
)
1687 t
->scope
->manager
->n_timeouts_total
++;
1689 if (!dns_scope_network_good(t
->scope
)) {
1690 dns_transaction_complete(t
, DNS_TRANSACTION_NETWORK_DOWN
);
1694 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
1695 DnsTransactionState result
;
1697 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
)
1698 /* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
1700 result
= DNS_TRANSACTION_NOT_FOUND
;
1702 result
= DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
;
1704 dns_transaction_complete(t
, result
);
1708 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& t
->tried_stream
) {
1709 /* If we already tried via a stream, then we don't
1710 * retry on LLMNR. See RFC 4795, Section 2.7. */
1711 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1718 dns_transaction_reset_answer(t
);
1719 dns_transaction_flush_dnssec_transactions(t
);
1721 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1722 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1723 !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_TRUST_ANCHOR
)) {
1724 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, dns_transaction_key(t
), &t
->answer
);
1728 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1729 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1730 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1731 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1735 if (dns_name_is_root(dns_resource_key_name(dns_transaction_key(t
))) &&
1736 dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
1738 /* Hmm, this is a request for the root DS? A DS RR doesn't exist in the root zone,
1739 * and if our trust anchor didn't know it either, this means we cannot do any DNSSEC
1742 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
1743 /* We are in downgrade mode. In this case, synthesize an unsigned empty
1744 * response, so that the any lookup depending on this one can continue
1745 * assuming there was no DS, and hence the root zone was unsigned. */
1747 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1748 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1749 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1750 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, true);
1751 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1753 /* If we are not in downgrade mode, then fail the lookup, because we cannot
1754 * reasonably answer it. There might be DS RRs, but we don't know them, and
1755 * the DNS server won't tell them to us (and even if it would, we couldn't
1756 * validate and trust them. */
1757 dns_transaction_complete(t
, DNS_TRANSACTION_NO_TRUST_ANCHOR
);
1763 /* Check the zone. */
1764 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_ZONE
)) {
1765 r
= dns_zone_lookup(&t
->scope
->zone
, dns_transaction_key(t
), dns_scope_ifindex(t
->scope
), &t
->answer
, NULL
, NULL
);
1769 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1770 t
->answer_source
= DNS_TRANSACTION_ZONE
;
1771 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1772 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1777 /* Check the cache. */
1778 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_CACHE
)) {
1780 /* Before trying the cache, let's make sure we figured out a server to use. Should this cause
1781 * a change of server this might flush the cache. */
1782 (void) dns_scope_get_dns_server(t
->scope
);
1784 /* Let's then prune all outdated entries */
1785 dns_cache_prune(&t
->scope
->cache
);
1787 /* For the initial attempt or when no stale data is requested, disable serve stale
1788 * and answer the question from the cache (honors ttl property).
1789 * On the second attempt, if StaleRetentionSec is greater than zero,
1790 * try to answer the question using stale date (honors until property) */
1791 uint64_t query_flags
= t
->query_flags
;
1792 if (t
->n_attempts
== 1 || t
->scope
->manager
->stale_retention_usec
== 0)
1793 query_flags
|= SD_RESOLVED_NO_STALE
;
1795 r
= dns_cache_lookup(
1797 dns_transaction_key(t
),
1802 &t
->answer_query_flags
,
1803 &t
->answer_dnssec_result
);
1807 dns_transaction_randomize_answer(t
);
1809 if (t
->bypass
&& t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->received
)
1810 /* When bypass mode is on, do not use cached data unless it came with a full
1812 dns_transaction_reset_answer(t
);
1814 if (t
->n_attempts
> 1 && !FLAGS_SET(query_flags
, SD_RESOLVED_NO_STALE
)) {
1816 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
) {
1817 if (t
->seen_timeout
)
1818 t
->scope
->manager
->n_timeouts_served_stale_total
++;
1820 t
->scope
->manager
->n_failure_responses_served_stale_total
++;
1823 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
1824 log_debug("Serve Stale response rcode=%s for %s",
1825 FORMAT_DNS_RCODE(t
->answer_rcode
),
1826 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
1829 t
->answer_source
= DNS_TRANSACTION_CACHE
;
1830 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
1831 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1833 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
1839 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_NETWORK
)) {
1840 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SOURCE
);
1847 static int dns_packet_append_zone(DnsPacket
*p
, DnsTransaction
*t
, DnsResourceKey
*k
, unsigned *nscount
) {
1848 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1856 if (k
->type
!= DNS_TYPE_ANY
)
1859 r
= dns_zone_lookup(&t
->scope
->zone
, k
, t
->scope
->link
->ifindex
, &answer
, NULL
, &tentative
);
1863 return dns_packet_append_answer(p
, answer
, nscount
);
1866 static int mdns_make_dummy_packet(DnsTransaction
*t
, DnsPacket
**ret_packet
, Set
**ret_keys
) {
1867 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1868 _cleanup_set_free_ Set
*keys
= NULL
;
1869 bool add_known_answers
= false;
1876 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
1880 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
1884 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
1890 if (dns_key_is_shared(dns_transaction_key(t
)))
1891 add_known_answers
= true;
1893 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(t
), NULL
);
1897 /* Save appended keys */
1898 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(t
));
1902 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
1904 LIST_FOREACH(transactions_by_scope
, other
, t
->scope
->transactions
) {
1906 /* Skip ourselves */
1910 if (other
->state
!= DNS_TRANSACTION_PENDING
)
1913 if (other
->next_attempt_after
> ts
)
1916 if (!set_contains(keys
, dns_transaction_key(other
))) {
1917 size_t saved_packet_size
;
1919 r
= dns_packet_append_key(p
, dns_transaction_key(other
), 0, &saved_packet_size
);
1920 /* If we can't stuff more questions into the packet, just give up.
1921 * One of the 'other' transactions will fire later and take care of the rest. */
1927 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(other
), NULL
);
1928 if (r
== -EMSGSIZE
) {
1929 dns_packet_truncate(p
, saved_packet_size
);
1935 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(other
));
1940 r
= dns_transaction_prepare(other
, ts
);
1944 /* In this case, not only this transaction, but multiple transactions may be
1945 * freed. Hence, we need to restart the loop. */
1948 usec_t timeout
= transaction_get_resend_timeout(other
);
1949 r
= dns_transaction_setup_timeout(other
, timeout
, usec_add(ts
, timeout
));
1953 if (dns_key_is_shared(dns_transaction_key(other
)))
1954 add_known_answers
= true;
1957 if (qdcount
>= UINT16_MAX
)
1961 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(qdcount
);
1963 /* Append known answers section if we're asking for any shared record */
1964 if (add_known_answers
) {
1965 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, 0);
1970 *ret_packet
= TAKE_PTR(p
);
1971 *ret_keys
= TAKE_PTR(keys
);
1972 return add_known_answers
;
1975 static int dns_transaction_make_packet_mdns(DnsTransaction
*t
) {
1976 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
, *dummy
= NULL
;
1977 _cleanup_set_free_ Set
*keys
= NULL
;
1978 bool add_known_answers
;
1984 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
1986 /* Discard any previously prepared packet, so we can start over and coalesce again */
1987 t
->sent
= dns_packet_unref(t
->sent
);
1989 /* First, create a dummy packet to calculate the number of known answers to be appended in the first packet. */
1991 r
= mdns_make_dummy_packet(t
, &dummy
, &keys
);
1997 add_known_answers
= r
;
2001 /* Then, create actual packet. */
2002 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
2008 SET_FOREACH(k
, keys
) {
2009 r
= dns_packet_append_key(p
, k
, 0, NULL
);
2014 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(c
);
2017 if (add_known_answers
) {
2020 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
2022 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, be16toh(DNS_PACKET_HEADER(dummy
)->ancount
));
2029 SET_FOREACH(k
, keys
) {
2030 r
= dns_packet_append_zone(p
, t
, k
, &c
);
2034 DNS_PACKET_HEADER(p
)->nscount
= htobe16(c
);
2036 t
->sent
= TAKE_PTR(p
);
2040 static int dns_transaction_make_packet(DnsTransaction
*t
) {
2041 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
2046 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)
2047 return dns_transaction_make_packet_mdns(t
);
2052 if (t
->bypass
&& t
->bypass
->protocol
== t
->scope
->protocol
) {
2053 /* If bypass logic is enabled and the protocol if the original packet and our scope match,
2054 * take the original packet, copy it, and patch in our new ID */
2055 r
= dns_packet_dup(&p
, t
->bypass
);
2059 r
= dns_packet_new_query(
2060 &p
, t
->scope
->protocol
,
2061 /* min_alloc_dsize = */ 0,
2062 /* dnssec_cd = */ !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) &&
2063 t
->scope
->dnssec_mode
!= DNSSEC_NO
);
2067 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
2071 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
2074 DNS_PACKET_HEADER(p
)->id
= t
->id
;
2076 t
->sent
= TAKE_PTR(p
);
2080 int dns_transaction_go(DnsTransaction
*t
) {
2083 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
2087 /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
2088 * finished now. In the latter case, the transaction and query candidate objects must not be accessed.
2091 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
2093 r
= dns_transaction_prepare(t
, ts
);
2097 log_debug("Firing %s transaction %" PRIu16
" for <%s> scope %s on %s/%s (validate=%s).",
2098 t
->bypass
? "bypass" : "regular",
2100 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
2101 dns_protocol_to_string(t
->scope
->protocol
),
2102 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
2103 af_to_name_short(t
->scope
->family
),
2104 yes_no(!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
)));
2106 if (!t
->initial_jitter_scheduled
&&
2107 IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_LLMNR
, DNS_PROTOCOL_MDNS
)) {
2110 /* RFC 4795 Section 2.7 suggests all LLMNR queries should be delayed by a random time from 0 to
2112 * RFC 6762 Section 8.1 suggests initial probe queries should be delayed by a random time from
2115 t
->initial_jitter_scheduled
= true;
2118 switch (t
->scope
->protocol
) {
2120 case DNS_PROTOCOL_LLMNR
:
2121 jitter
= random_u64_range(LLMNR_JITTER_INTERVAL_USEC
);
2124 case DNS_PROTOCOL_MDNS
:
2126 jitter
= random_u64_range(MDNS_PROBING_INTERVAL_USEC
);
2131 assert_not_reached();
2134 r
= dns_transaction_setup_timeout(t
, jitter
, ts
);
2138 log_debug("Delaying %s transaction %" PRIu16
" for " USEC_FMT
"us.",
2139 dns_protocol_to_string(t
->scope
->protocol
),
2145 /* Otherwise, we need to ask the network */
2146 r
= dns_transaction_make_packet(t
);
2150 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
2151 (dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "in-addr.arpa") > 0 ||
2152 dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "ip6.arpa") > 0)) {
2154 /* RFC 4795, Section 2.4. says reverse lookups shall
2155 * always be made via TCP on LLMNR */
2156 r
= dns_transaction_emit_tcp(t
);
2158 /* Try via UDP, and if that fails due to large size or lack of
2159 * support try via TCP */
2160 r
= dns_transaction_emit_udp(t
);
2162 log_debug("Sending query via TCP since it is too large.");
2163 else if (r
== -EAGAIN
)
2164 log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
2165 else if (r
== -EPERM
)
2166 log_debug("Sending query via TCP since UDP is blocked.");
2167 if (IN_SET(r
, -EMSGSIZE
, -EAGAIN
, -EPERM
))
2168 r
= dns_transaction_emit_tcp(t
);
2171 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2174 /* One of our own stub listeners */
2175 log_debug_errno(r
, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
2177 dns_scope_next_dns_server(t
->scope
, t
->server
);
2179 if (dns_scope_get_dns_server(t
->scope
) == t
->server
) {
2180 log_debug_errno(r
, "Still pointing to extra listener after switching DNS servers, refusing operation.");
2181 dns_transaction_complete(t
, DNS_TRANSACTION_STUB_LOOP
);
2185 return dns_transaction_go(t
);
2188 /* No servers to send this to? */
2189 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
2192 if (r
== -EOPNOTSUPP
) {
2193 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
2194 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
2197 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& ERRNO_IS_NEG_DISCONNECT(r
)) {
2198 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
2199 * answer this request with this protocol. */
2200 dns_transaction_complete(t
, DNS_TRANSACTION_NOT_FOUND
);
2204 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2207 /* Couldn't send? Try immediately again, with a new server */
2208 dns_scope_next_dns_server(t
->scope
, t
->server
);
2210 return dns_transaction_go(t
);
2213 usec_t timeout
= transaction_get_resend_timeout(t
);
2214 r
= dns_transaction_setup_timeout(t
, timeout
, usec_add(ts
, timeout
));
2221 static int dns_transaction_find_cyclic(DnsTransaction
*t
, DnsTransaction
*aux
) {
2228 /* Try to find cyclic dependencies between transaction objects */
2233 SET_FOREACH(n
, aux
->dnssec_transactions
) {
2234 r
= dns_transaction_find_cyclic(t
, n
);
2242 static int dns_transaction_add_dnssec_transaction(DnsTransaction
*t
, DnsResourceKey
*key
, DnsTransaction
**ret
) {
2243 _cleanup_(dns_transaction_gcp
) DnsTransaction
*aux
= NULL
;
2250 aux
= dns_scope_find_transaction(t
->scope
, key
, t
->query_flags
);
2252 r
= dns_transaction_new(&aux
, t
->scope
, key
, NULL
, t
->query_flags
);
2256 if (set_contains(t
->dnssec_transactions
, aux
)) {
2261 r
= dns_transaction_find_cyclic(t
, aux
);
2265 char s
[DNS_RESOURCE_KEY_STRING_MAX
], saux
[DNS_RESOURCE_KEY_STRING_MAX
];
2267 return log_debug_errno(SYNTHETIC_ERRNO(ELOOP
),
2268 "Potential cyclic dependency, refusing to add transaction %" PRIu16
" (%s) as dependency for %" PRIu16
" (%s).",
2270 dns_resource_key_to_string(dns_transaction_key(t
), s
, sizeof s
),
2272 dns_resource_key_to_string(dns_transaction_key(aux
), saux
, sizeof saux
));
2276 r
= set_ensure_allocated(&aux
->notify_transactions_done
, NULL
);
2280 r
= set_ensure_put(&t
->dnssec_transactions
, NULL
, aux
);
2284 r
= set_ensure_put(&aux
->notify_transactions
, NULL
, t
);
2286 (void) set_remove(t
->dnssec_transactions
, aux
);
2290 *ret
= TAKE_PTR(aux
);
2294 static int dns_transaction_request_dnssec_rr(DnsTransaction
*t
, DnsResourceKey
*key
) {
2295 _cleanup_(dns_answer_unrefp
) DnsAnswer
*a
= NULL
;
2296 DnsTransaction
*aux
;
2302 /* Try to get the data from the trust anchor */
2303 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, key
, &a
);
2307 r
= dns_answer_extend(&t
->validated_keys
, a
);
2314 /* This didn't work, ask for it via the network/cache then. */
2315 r
= dns_transaction_add_dnssec_transaction(t
, key
, &aux
);
2316 if (r
== -ELOOP
) /* This would result in a cyclic dependency */
2321 if (aux
->state
== DNS_TRANSACTION_NULL
) {
2322 r
= dns_transaction_go(aux
);
2330 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction
*t
, const char *name
) {
2335 /* Check whether the specified name is in the NTA
2336 * database, either in the global one, or the link-local
2339 r
= dns_trust_anchor_lookup_negative(&t
->scope
->manager
->trust_anchor
, name
);
2343 if (!t
->scope
->link
)
2346 return link_negative_trust_anchor_lookup(t
->scope
->link
, name
);
2349 static int dns_transaction_has_negative_answer(DnsTransaction
*t
) {
2354 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
2355 * RRs to prove it */
2357 r
= dns_transaction_has_positive_answer(t
, NULL
);
2363 /* Is this key explicitly listed as a negative trust anchor?
2364 * If so, it's nothing we need to care about */
2365 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
2371 static int dns_transaction_is_primary_response(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2377 /* Check if the specified RR is the "primary" response,
2378 * i.e. either matches the question precisely or is a
2379 * CNAME/DNAME for it. */
2381 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2385 return dns_resource_key_match_cname_or_dname(dns_transaction_key(t
), rr
->key
, NULL
);
2388 static bool dns_transaction_dnssec_supported(DnsTransaction
*t
) {
2391 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2392 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2394 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2397 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2398 * be supported, hence return true. */
2402 /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2403 * the server is known to support currently, as the transaction feature level might be lower than what the
2404 * server actually supports, since we might have downgraded this transaction's feature level because we got a
2405 * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
2407 return dns_server_dnssec_supported(t
->server
);
2410 static bool dns_transaction_dnssec_supported_full(DnsTransaction
*t
) {
2415 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2417 if (!dns_transaction_dnssec_supported(t
))
2420 SET_FOREACH(dt
, t
->dnssec_transactions
)
2421 if (!dns_transaction_dnssec_supported(dt
))
2427 int dns_transaction_request_dnssec_keys(DnsTransaction
*t
) {
2428 DnsResourceRecord
*rr
;
2435 * Retrieve all auxiliary RRs for the answer we got, so that
2436 * we can verify signatures or prove that RRs are rightfully
2437 * unsigned. Specifically:
2439 * - For RRSIG we get the matching DNSKEY
2440 * - For DNSKEY we get the matching DS
2441 * - For unsigned SOA/NS we get the matching DS
2442 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
2443 * - For other unsigned RRs we get the matching SOA RR
2444 * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2445 * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
2446 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2449 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
2451 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
2452 return 0; /* We only need to validate stuff from the network */
2453 if (!dns_transaction_dnssec_supported(t
))
2454 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
2456 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
2458 if (dns_type_is_pseudo(rr
->key
->type
))
2461 /* If this RR is in the negative trust anchor, we don't need to validate it. */
2462 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2468 switch (rr
->key
->type
) {
2470 case DNS_TYPE_RRSIG
: {
2471 /* For each RRSIG we request the matching DNSKEY */
2472 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*dnskey
= NULL
;
2474 /* If this RRSIG is about a DNSKEY RR and the
2475 * signer is the same as the owner, then we
2476 * already have the DNSKEY, and we don't have
2477 * to look for more. */
2478 if (rr
->rrsig
.type_covered
== DNS_TYPE_DNSKEY
) {
2479 r
= dns_name_equal(rr
->rrsig
.signer
, dns_resource_key_name(rr
->key
));
2486 /* If the signer is not a parent of our
2487 * original query, then this is about an
2488 * auxiliary RRset, but not anything we asked
2489 * for. In this case we aren't interested,
2490 * because we don't want to request additional
2491 * RRs for stuff we didn't really ask for, and
2492 * also to avoid request loops, where
2493 * additional RRs from one transaction result
2494 * in another transaction whose additional RRs
2495 * point back to the original transaction, and
2497 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), rr
->rrsig
.signer
);
2503 dnskey
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DNSKEY
, rr
->rrsig
.signer
);
2507 log_debug("Requesting DNSKEY to validate transaction %" PRIu16
" (%s, RRSIG with key tag: %" PRIu16
").",
2508 t
->id
, dns_resource_key_name(rr
->key
), rr
->rrsig
.key_tag
);
2509 r
= dns_transaction_request_dnssec_rr(t
, dnskey
);
2515 case DNS_TYPE_DNSKEY
: {
2516 /* For each DNSKEY we request the matching DS */
2517 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2519 /* If the DNSKEY we are looking at is not for
2520 * zone we are interested in, nor any of its
2521 * parents, we aren't interested, and don't
2522 * request it. After all, we don't want to end
2523 * up in request loops, and want to keep
2524 * additional traffic down. */
2526 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2532 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2536 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, DNSKEY with key tag: %" PRIu16
").",
2537 t
->id
, dns_resource_key_name(rr
->key
), dnssec_keytag(rr
, false));
2538 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2547 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2549 /* For an unsigned SOA or NS, try to acquire
2550 * the matching DS RR, as we are at a zone cut
2551 * then, and whether a DS exists tells us
2552 * whether the zone is signed. Do so only if
2553 * this RR matches our original question,
2556 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2560 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2561 * a negative reply, and we need the SOA RR's TTL in order to cache a negative entry?
2562 * If so, we need to validate it, too. */
2564 r
= dns_answer_match_key(t
->answer
, dns_transaction_key(t
), NULL
);
2567 if (r
> 0) /* positive reply, we won't need the SOA and hence don't need to validate
2571 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
2572 * what we are looking for, otherwise there's no value in it for us. */
2573 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2580 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2586 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2590 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, unsigned SOA/NS RRset).",
2591 t
->id
, dns_resource_key_name(rr
->key
));
2592 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2600 case DNS_TYPE_CNAME
:
2601 case DNS_TYPE_DNAME
: {
2602 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2605 /* CNAMEs and DNAMEs cannot be located at a
2606 * zone apex, hence ask for the parent SOA for
2607 * unsigned CNAME/DNAME RRs, maybe that's the
2608 * apex. But do all that only if this is
2609 * actually a response to our original
2612 * Similar for DS RRs, which are signed when
2613 * the parent SOA is signed. */
2615 r
= dns_transaction_is_primary_response(t
, rr
);
2621 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2627 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
2633 name
= dns_resource_key_name(rr
->key
);
2634 r
= dns_name_parent(&name
);
2640 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, name
);
2644 log_debug("Requesting parent SOA to validate transaction %" PRIu16
" (%s, unsigned CNAME/DNAME/DS RRset).",
2645 t
->id
, dns_resource_key_name(rr
->key
));
2646 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2654 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2656 /* For other unsigned RRsets (including
2657 * NSEC/NSEC3!), look for proof the zone is
2658 * unsigned, by requesting the SOA RR of the
2659 * zone. However, do so only if they are
2660 * directly relevant to our original
2663 r
= dns_transaction_is_primary_response(t
, rr
);
2669 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2675 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, dns_resource_key_name(rr
->key
));
2679 log_debug("Requesting SOA to validate transaction %" PRIu16
" (%s, unsigned non-SOA/NS RRset <%s>).",
2680 t
->id
, dns_resource_key_name(rr
->key
), dns_resource_record_to_string(rr
));
2681 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2688 /* Above, we requested everything necessary to validate what
2689 * we got. Now, let's request what we need to validate what we
2692 r
= dns_transaction_has_negative_answer(t
);
2696 const char *name
, *signed_status
;
2699 name
= dns_resource_key_name(dns_transaction_key(t
));
2700 signed_status
= dns_answer_contains_nsec_or_nsec3(t
->answer
) ? "signed" : "unsigned";
2702 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2703 * could also be used as indication that we are not at a zone apex, but in real world setups there are
2704 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2705 * though they have further children. If this was a DS request, then it's signed when the parent zone
2706 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2707 * to see if that is signed. */
2709 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
2710 r
= dns_name_parent(&name
);
2712 type
= DNS_TYPE_SOA
;
2713 log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty DS response).",
2714 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
,
2715 dns_resource_key_name(dns_transaction_key(t
)), signed_status
);
2719 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
)) {
2722 log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16
" (%s, %s empty SOA/NS response).",
2723 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2726 type
= DNS_TYPE_SOA
;
2727 log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty non-SOA/NS/DS response).",
2728 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2732 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2734 soa
= dns_resource_key_new(dns_transaction_key(t
)->class, type
, name
);
2738 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2744 return dns_transaction_dnssec_is_live(t
);
2747 void dns_transaction_notify(DnsTransaction
*t
, DnsTransaction
*source
) {
2751 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2752 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2753 the state is VALIDATING however, we should check if we are complete now. */
2755 if (t
->state
== DNS_TRANSACTION_VALIDATING
)
2756 dns_transaction_process_dnssec(t
);
2759 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction
*t
) {
2760 DnsAnswerItem
*item
;
2765 /* Add all DNSKEY RRs from the answer that are validated by DS
2766 * RRs from the list of validated keys to the list of
2767 * validated keys. */
2769 DNS_ANSWER_FOREACH_ITEM(item
, t
->answer
) {
2771 r
= dnssec_verify_dnskey_by_ds_search(item
->rr
, t
->validated_keys
);
2777 /* If so, the DNSKEY is validated too. */
2778 r
= dns_answer_add_extend(&t
->validated_keys
, item
->rr
, item
->ifindex
, item
->flags
|DNS_ANSWER_AUTHENTICATED
, item
->rrsig
);
2786 static int dns_transaction_requires_rrsig(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2792 /* Checks if the RR we are looking for must be signed with an
2793 * RRSIG. This is used for positive responses. */
2795 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2798 if (dns_type_is_pseudo(rr
->key
->type
))
2801 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2807 switch (rr
->key
->type
) {
2809 case DNS_TYPE_RRSIG
:
2810 /* RRSIGs are the signatures themselves, they need no signing. */
2817 /* For SOA or NS RRs we look for a matching DS transaction */
2819 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2821 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2823 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_DS
)
2826 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2832 /* We found a DS transactions for the SOA/NS
2833 * RRs we are looking at. If it discovered signed DS
2834 * RRs, then we need to be signed, too. */
2836 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
2839 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
2842 /* We found nothing that proves this is safe to leave
2843 * this unauthenticated, hence ask inist on
2844 * authentication. */
2849 case DNS_TYPE_CNAME
:
2850 case DNS_TYPE_DNAME
: {
2851 const char *parent
= NULL
;
2855 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2857 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2860 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2862 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2864 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2868 parent
= dns_resource_key_name(rr
->key
);
2869 r
= dns_name_parent(&parent
);
2873 if (rr
->key
->type
== DNS_TYPE_DS
)
2876 /* A CNAME/DNAME without a parent? That's sooo weird. */
2877 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG
),
2878 "Transaction %" PRIu16
" claims CNAME/DNAME at root. Refusing.", t
->id
);
2882 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), parent
);
2888 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2897 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2899 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2901 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2903 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2906 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2912 /* We found the transaction that was supposed to find the SOA RR for us. It was
2913 * successful, but found no RR for us. This means we are not at a zone cut. In this
2914 * case, we require authentication if the SOA lookup was authenticated too. */
2915 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2922 static int dns_transaction_in_private_tld(DnsTransaction
*t
, const DnsResourceKey
*key
) {
2927 /* If DNSSEC downgrade mode is on, checks whether the
2928 * specified RR is one level below a TLD we have proven not to
2929 * exist. In such a case we assume that this is a private
2930 * domain, and permit it.
2932 * This detects cases like the Fritz!Box router networks. Each
2933 * Fritz!Box router serves a private "fritz.box" zone, in the
2934 * non-existing TLD "box". Requests for the "fritz.box" domain
2935 * are served by the router itself, while requests for the
2936 * "box" domain will result in NXDOMAIN.
2938 * Note that this logic is unable to detect cases where a
2939 * router serves a private DNS zone directly under
2940 * non-existing TLD. In such a case we cannot detect whether
2941 * the TLD is supposed to exist or not, as all requests we
2942 * make for it will be answered by the router's zone, and not
2943 * by the root zone. */
2947 if (t
->scope
->dnssec_mode
!= DNSSEC_ALLOW_DOWNGRADE
)
2948 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2950 tld
= dns_resource_key_name(key
);
2951 r
= dns_name_parent(&tld
);
2955 return false; /* Already the root domain */
2957 if (!dns_name_is_single_label(tld
))
2960 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2962 if (dns_transaction_key(dt
)->class != key
->class)
2965 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), tld
);
2971 /* We found an auxiliary lookup we did for the TLD. If
2972 * that returned with NXDOMAIN, we know the TLD didn't
2973 * exist, and hence this might be a private zone. */
2975 return dt
->answer_rcode
== DNS_RCODE_NXDOMAIN
;
2981 static int dns_transaction_requires_nsec(DnsTransaction
*t
) {
2982 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
2990 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2991 * this negative reply */
2993 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2996 if (dns_type_is_pseudo(dns_transaction_key(t
)->type
))
2999 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
3005 r
= dns_transaction_in_private_tld(t
, dns_transaction_key(t
));
3009 /* The lookup is from a TLD that is proven not to
3010 * exist, and we are in downgrade mode, hence ignore
3011 * that fact that we didn't get any NSEC RRs. */
3013 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
3014 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
3018 name
= dns_resource_key_name(dns_transaction_key(t
));
3020 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
3022 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
3023 * hence check the parent SOA in this case. */
3025 r
= dns_name_parent(&name
);
3031 type
= DNS_TYPE_SOA
;
3033 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
))
3034 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
3037 /* For all other negative replies, check for the SOA lookup */
3038 type
= DNS_TYPE_SOA
;
3040 /* For all other RRs we check the SOA on the same level to see
3041 * if it's signed. */
3043 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3045 if (dns_transaction_key(dt
)->class != dns_transaction_key(t
)->class)
3047 if (dns_transaction_key(dt
)->type
!= type
)
3050 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), name
);
3056 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
3059 /* If in doubt, require NSEC/NSEC3 */
3063 static int dns_transaction_dnskey_authenticated(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
3064 DnsResourceRecord
*rrsig
;
3068 /* Checks whether any of the DNSKEYs used for the RRSIGs for
3069 * the specified RRset is authenticated (i.e. has a matching
3072 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
3078 DNS_ANSWER_FOREACH(rrsig
, t
->answer
) {
3081 r
= dnssec_key_match_rrsig(rr
->key
, rrsig
);
3087 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3089 if (dns_transaction_key(dt
)->class != rr
->key
->class)
3092 if (dns_transaction_key(dt
)->type
== DNS_TYPE_DNSKEY
) {
3094 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
3100 /* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated,
3103 if (FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3108 } else if (dns_transaction_key(dt
)->type
== DNS_TYPE_DS
) {
3110 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
3116 /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
3117 * non-zero, we won! */
3119 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3122 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
3127 return found
? false : -ENXIO
;
3130 static int dns_transaction_known_signed(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
3134 /* We know that the root domain is signed, hence if it appears
3135 * not to be signed, there's a problem with the DNS server */
3137 return rr
->key
->class == DNS_CLASS_IN
&&
3138 dns_name_is_root(dns_resource_key_name(rr
->key
));
3141 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction
*t
) {
3142 DnsResourceRecord
*rr
;
3147 /* Maybe warn the user that we encountered a revoked DNSKEY
3148 * for a key from our trust anchor. Note that we don't care
3149 * whether the DNSKEY can be authenticated or not. It's
3150 * sufficient if it is self-signed. */
3152 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3153 r
= dns_trust_anchor_check_revoked(&t
->scope
->manager
->trust_anchor
, rr
, t
->answer
);
3161 static int dns_transaction_invalidate_revoked_keys(DnsTransaction
*t
) {
3167 /* Removes all DNSKEY/DS objects from t->validated_keys that
3168 * our trust anchors database considers revoked. */
3171 DnsResourceRecord
*rr
;
3175 DNS_ANSWER_FOREACH(rr
, t
->validated_keys
) {
3176 r
= dns_trust_anchor_is_revoked(&t
->scope
->manager
->trust_anchor
, rr
);
3180 r
= dns_answer_remove_by_rr(&t
->validated_keys
, rr
);
3194 static int dns_transaction_copy_validated(DnsTransaction
*t
) {
3200 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
3202 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3204 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
3207 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3210 r
= dns_answer_extend(&t
->validated_keys
, dt
->answer
);
3219 DNSSEC_PHASE_DNSKEY
, /* Phase #1, only validate DNSKEYs */
3220 DNSSEC_PHASE_NSEC
, /* Phase #2, only validate NSEC+NSEC3 */
3221 DNSSEC_PHASE_ALL
, /* Phase #3, validate everything else */
3224 static int dnssec_validate_records(
3228 DnsAnswer
**validated
) {
3230 DnsResourceRecord
*rr
;
3233 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
3235 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3236 _unused_
_cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr_ref
= dns_resource_record_ref(rr
);
3237 DnsResourceRecord
*rrsig
= NULL
;
3238 DnssecResult result
;
3240 switch (rr
->key
->type
) {
3241 case DNS_TYPE_RRSIG
:
3244 case DNS_TYPE_DNSKEY
:
3245 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
3246 if (phase
== DNSSEC_PHASE_NSEC
)
3251 case DNS_TYPE_NSEC3
:
3254 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
3255 if (phase
== DNSSEC_PHASE_DNSKEY
)
3260 /* We validate all other RRs only in the ALL phases */
3261 if (phase
!= DNSSEC_PHASE_ALL
)
3265 r
= dnssec_verify_rrset_search(
3275 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr
)), dnssec_result_to_string(result
));
3277 if (result
== DNSSEC_VALIDATED
) {
3280 if (rr
->key
->type
== DNS_TYPE_DNSKEY
) {
3281 /* If we just validated a DNSKEY RRset, then let's add these keys to
3282 * the set of validated keys for this transaction. */
3284 r
= dns_answer_copy_by_key(&t
->validated_keys
, t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
, rrsig
);
3288 /* Some of the DNSKEYs we just added might already have been revoked,
3289 * remove them again in that case. */
3290 r
= dns_transaction_invalidate_revoked_keys(t
);
3295 /* Add the validated RRset to the new list of validated RRsets, and remove it from
3296 * the unvalidated RRsets. We mark the RRset as authenticated and cacheable. */
3297 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
, rrsig
);
3301 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_SECURE
, rr
->key
);
3303 /* Exit the loop, we dropped something from the answer, start from the beginning */
3307 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
3308 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
3309 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
3310 if (phase
!= DNSSEC_PHASE_ALL
)
3313 if (result
== DNSSEC_VALIDATED_WILDCARD
) {
3314 bool authenticated
= false;
3319 /* This RRset validated, but as a wildcard. This means we need
3320 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
3322 /* First step, determine the source of synthesis */
3323 r
= dns_resource_record_source(rrsig
, &source
);
3327 r
= dnssec_test_positive_wildcard(*validated
,
3328 dns_resource_key_name(rr
->key
),
3330 rrsig
->rrsig
.signer
,
3333 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
3335 result
= DNSSEC_INVALID
;
3337 r
= dns_answer_move_by_key(
3341 authenticated
? (DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
) : 0,
3346 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, rr
->key
);
3348 /* Exit the loop, we dropped something from the answer, start from the beginning */
3353 if (result
== DNSSEC_NO_SIGNATURE
) {
3354 r
= dns_transaction_requires_rrsig(t
, rr
);
3358 /* Data does not require signing. In that case, just copy it over,
3359 * but remember that this is by no means authenticated. */
3360 r
= dns_answer_move_by_key(
3369 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3373 r
= dns_transaction_known_signed(t
, rr
);
3377 /* This is an RR we know has to be signed. If it isn't this means
3378 * the server is not attaching RRSIGs, hence complain. */
3380 dns_server_packet_rrsig_missing(t
->server
, t
->current_feature_level
);
3382 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
3384 /* Downgrading is OK? If so, just consider the information unsigned */
3386 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3390 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3394 /* Otherwise, fail */
3395 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3399 r
= dns_transaction_in_private_tld(t
, rr
->key
);
3403 char s
[DNS_RESOURCE_KEY_STRING_MAX
];
3405 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3406 * mode, hence ignore the fact that this was not signed. */
3408 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3409 dns_resource_key_to_string(rr
->key
, s
, sizeof s
));
3411 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3415 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3420 /* https://datatracker.ietf.org/doc/html/rfc6840#section-5.2 */
3421 if (result
== DNSSEC_UNSUPPORTED_ALGORITHM
) {
3422 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3426 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3432 DNSSEC_SIGNATURE_EXPIRED
)) {
3434 r
= dns_transaction_dnskey_authenticated(t
, rr
);
3435 if (r
< 0 && r
!= -ENXIO
)
3438 /* The DNSKEY transaction was not authenticated, this means there's
3439 * no DS for this, which means it's OK if no keys are found for this signature. */
3441 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3445 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3450 r
= dns_transaction_is_primary_response(t
, rr
);
3454 /* Look for a matching DNAME for this CNAME */
3455 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
3459 /* Also look among the stuff we already validated */
3460 r
= dns_answer_has_dname_for_cname(*validated
, rr
);
3468 DNSSEC_SIGNATURE_EXPIRED
,
3469 DNSSEC_NO_SIGNATURE
))
3470 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, rr
->key
);
3471 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3472 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, rr
->key
);
3474 /* This is a primary response to our question, and it failed validation.
3476 t
->answer_dnssec_result
= result
;
3480 /* This is a primary response, but we do have a DNAME RR
3481 * in the RR that can replay this CNAME, hence rely on
3482 * that, and we can remove the CNAME in favour of it. */
3485 /* This is just some auxiliary data. Just remove the RRset and continue. */
3486 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
3490 /* We dropped something from the answer, start from the beginning. */
3494 return 2; /* Finito. */
3497 int dns_transaction_validate_dnssec(DnsTransaction
*t
) {
3498 _cleanup_(dns_answer_unrefp
) DnsAnswer
*validated
= NULL
;
3500 DnsAnswerFlags flags
;
3502 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
3506 /* We have now collected all DS and DNSKEY RRs in t->validated_keys, let's see which RRs we can now
3507 * authenticate with that. */
3509 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
3512 /* Already validated */
3513 if (t
->answer_dnssec_result
!= _DNSSEC_RESULT_INVALID
)
3516 /* Our own stuff needs no validation */
3517 if (IN_SET(t
->answer_source
, DNS_TRANSACTION_ZONE
, DNS_TRANSACTION_TRUST_ANCHOR
)) {
3518 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3519 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3523 /* Cached stuff is not affected by validation. */
3524 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
3527 if (!dns_transaction_dnssec_supported_full(t
)) {
3528 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3529 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3530 log_debug("Not validating response for %" PRIu16
", used server feature level does not support DNSSEC.", t
->id
);
3534 log_debug("Validating response from transaction %" PRIu16
" (%s).",
3536 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
3538 /* First, see if this response contains any revoked trust
3539 * anchors we care about */
3540 r
= dns_transaction_check_revoked_trust_anchors(t
);
3544 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3545 r
= dns_transaction_copy_validated(t
);
3549 /* Second, see if there are DNSKEYs we already know a
3550 * validated DS for. */
3551 r
= dns_transaction_validate_dnskey_by_ds(t
);
3555 /* Fourth, remove all DNSKEY and DS RRs again that our trust
3556 * anchor says are revoked. After all we might have marked
3557 * some keys revoked above, but they might still be lingering
3558 * in our validated_keys list. */
3559 r
= dns_transaction_invalidate_revoked_keys(t
);
3563 phase
= DNSSEC_PHASE_DNSKEY
;
3565 bool have_nsec
= false;
3567 r
= dnssec_validate_records(t
, phase
, &have_nsec
, &validated
);
3571 /* Try again as long as we managed to achieve something */
3575 if (phase
== DNSSEC_PHASE_DNSKEY
&& have_nsec
) {
3576 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
3577 phase
= DNSSEC_PHASE_NSEC
;
3581 if (phase
!= DNSSEC_PHASE_ALL
) {
3582 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3583 * Note that in this third phase we start to remove RRs we couldn't validate. */
3584 phase
= DNSSEC_PHASE_ALL
;
3592 DNS_ANSWER_REPLACE(t
->answer
, TAKE_PTR(validated
));
3594 /* At this point the answer only contains validated
3595 * RRsets. Now, let's see if it actually answers the question
3596 * we asked. If so, great! If it doesn't, then see if
3597 * NSEC/NSEC3 can prove this. */
3598 r
= dns_transaction_has_positive_answer(t
, &flags
);
3600 /* Yes, it answers the question! */
3602 if (flags
& DNS_ANSWER_AUTHENTICATED
) {
3603 /* The answer is fully authenticated, yay. */
3604 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3605 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3606 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3608 /* The answer is not fully authenticated. */
3609 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3610 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3613 } else if (r
== 0) {
3614 DnssecNsecResult nr
;
3615 bool authenticated
= false;
3617 /* Bummer! Let's check NSEC/NSEC3 */
3618 r
= dnssec_nsec_test(t
->answer
, dns_transaction_key(t
), &nr
, &authenticated
, &t
->answer_nsec_ttl
);
3624 case DNSSEC_NSEC_NXDOMAIN
:
3625 /* NSEC proves the domain doesn't exist. Very good. */
3626 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3627 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3628 t
->answer_rcode
= DNS_RCODE_NXDOMAIN
;
3629 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3631 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3634 case DNSSEC_NSEC_NODATA
:
3635 /* NSEC proves that there's no data here, very good. */
3636 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3637 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3638 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3639 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3641 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3644 case DNSSEC_NSEC_OPTOUT
:
3645 /* NSEC3 says the data might not be signed */
3646 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3647 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3648 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3650 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3653 case DNSSEC_NSEC_NO_RR
:
3654 /* No NSEC data? Bummer! */
3656 r
= dns_transaction_requires_nsec(t
);
3660 t
->answer_dnssec_result
= DNSSEC_NO_SIGNATURE
;
3661 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3663 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3664 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3665 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3670 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM
:
3671 /* We don't know the NSEC3 algorithm used? */
3672 t
->answer_dnssec_result
= DNSSEC_UNSUPPORTED_ALGORITHM
;
3673 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, dns_transaction_key(t
));
3676 case DNSSEC_NSEC_FOUND
:
3677 case DNSSEC_NSEC_CNAME
:
3678 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
3679 t
->answer_dnssec_result
= DNSSEC_NSEC_MISMATCH
;
3680 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3684 assert_not_reached();
3691 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
3692 [DNS_TRANSACTION_NULL
] = "null",
3693 [DNS_TRANSACTION_PENDING
] = "pending",
3694 [DNS_TRANSACTION_VALIDATING
] = "validating",
3695 [DNS_TRANSACTION_RCODE_FAILURE
] = "rcode-failure",
3696 [DNS_TRANSACTION_SUCCESS
] = "success",
3697 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
3698 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
3699 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
3700 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
3701 [DNS_TRANSACTION_ERRNO
] = "errno",
3702 [DNS_TRANSACTION_ABORTED
] = "aborted",
3703 [DNS_TRANSACTION_DNSSEC_FAILED
] = "dnssec-failed",
3704 [DNS_TRANSACTION_NO_TRUST_ANCHOR
] = "no-trust-anchor",
3705 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
] = "rr-type-unsupported",
3706 [DNS_TRANSACTION_NETWORK_DOWN
] = "network-down",
3707 [DNS_TRANSACTION_NOT_FOUND
] = "not-found",
3708 [DNS_TRANSACTION_NO_SOURCE
] = "no-source",
3709 [DNS_TRANSACTION_STUB_LOOP
] = "stub-loop",
3711 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);
3713 static const char* const dns_transaction_source_table
[_DNS_TRANSACTION_SOURCE_MAX
] = {
3714 [DNS_TRANSACTION_NETWORK
] = "network",
3715 [DNS_TRANSACTION_CACHE
] = "cache",
3716 [DNS_TRANSACTION_ZONE
] = "zone",
3717 [DNS_TRANSACTION_TRUST_ANCHOR
] = "trust-anchor",
3719 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source
, DnsTransactionSource
);