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 if (use_graveyard
&& t
->dns_udp_fd
>= 0 && t
->sent
&& !t
->received
) {
78 r
= manager_add_socket_to_graveyard(t
->scope
->manager
, t
->dns_udp_fd
);
80 log_debug_errno(r
, "Failed to add UDP socket to graveyard, closing immediately: %m");
82 TAKE_FD(t
->dns_udp_fd
);
85 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
88 static void dns_transaction_stop_timeout(DnsTransaction
*t
) {
91 t
->timeout_event_source
= sd_event_source_disable_unref(t
->timeout_event_source
);
94 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
102 log_debug("Freeing transaction %" PRIu16
".", t
->id
);
104 dns_transaction_close_connection(t
, true);
105 dns_transaction_stop_timeout(t
);
107 dns_packet_unref(t
->sent
);
108 dns_transaction_reset_answer(t
);
110 dns_server_unref(t
->server
);
114 DnsTransaction
*first
;
116 first
= hashmap_get(t
->scope
->transactions_by_key
, t
->key
);
117 LIST_REMOVE(transactions_by_key
, first
, t
);
119 hashmap_replace(t
->scope
->transactions_by_key
, first
->key
, first
);
121 hashmap_remove(t
->scope
->transactions_by_key
, t
->key
);
124 LIST_REMOVE(transactions_by_scope
, t
->scope
->transactions
, t
);
127 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
130 while ((c
= set_steal_first(t
->notify_query_candidates
)))
131 set_remove(c
->transactions
, t
);
132 set_free(t
->notify_query_candidates
);
134 while ((c
= set_steal_first(t
->notify_query_candidates_done
)))
135 set_remove(c
->transactions
, t
);
136 set_free(t
->notify_query_candidates_done
);
138 while ((i
= set_steal_first(t
->notify_zone_items
)))
139 i
->probe_transaction
= NULL
;
140 set_free(t
->notify_zone_items
);
142 while ((i
= set_steal_first(t
->notify_zone_items_done
)))
143 i
->probe_transaction
= NULL
;
144 set_free(t
->notify_zone_items_done
);
146 while ((z
= set_steal_first(t
->notify_transactions
)))
147 set_remove(z
->dnssec_transactions
, t
);
148 set_free(t
->notify_transactions
);
150 while ((z
= set_steal_first(t
->notify_transactions_done
)))
151 set_remove(z
->dnssec_transactions
, t
);
152 set_free(t
->notify_transactions_done
);
154 dns_transaction_flush_dnssec_transactions(t
);
155 set_free(t
->dnssec_transactions
);
157 dns_answer_unref(t
->validated_keys
);
158 dns_resource_key_unref(t
->key
);
159 dns_packet_unref(t
->bypass
);
164 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
166 DnsTransaction
* dns_transaction_gc(DnsTransaction
*t
) {
169 /* Returns !NULL if we can't gc yet. */
174 if (set_isempty(t
->notify_query_candidates
) &&
175 set_isempty(t
->notify_query_candidates_done
) &&
176 set_isempty(t
->notify_zone_items
) &&
177 set_isempty(t
->notify_zone_items_done
) &&
178 set_isempty(t
->notify_transactions
) &&
179 set_isempty(t
->notify_transactions_done
))
180 return dns_transaction_free(t
);
185 static uint16_t pick_new_id(Manager
*m
) {
188 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the
189 * number of transactions, and it's much lower than the space of IDs. */
191 assert_cc(TRANSACTIONS_MAX
< 0xFFFF);
194 random_bytes(&new_id
, sizeof(new_id
));
195 while (new_id
== 0 ||
196 hashmap_get(m
->dns_transactions
, UINT_TO_PTR(new_id
)));
203 DnsResourceKey
*key
) {
205 /* Don't allow looking up invalid or pseudo RRs */
206 if (!dns_type_is_valid_query(key
->type
))
208 if (dns_type_is_obsolete(key
->type
))
211 /* We only support the IN class */
212 if (!IN_SET(key
->class, DNS_CLASS_IN
, DNS_CLASS_ANY
))
215 /* Don't allows DNSSEC RRs to be looked up via LLMNR/mDNS. They don't really make sense
216 * there, and it speeds up our queries if we refuse this early */
217 if (scope
->protocol
!= DNS_PROTOCOL_DNS
&&
218 dns_type_is_dnssec(key
->type
))
224 int dns_transaction_new(
225 DnsTransaction
**ret
,
229 uint64_t query_flags
) {
231 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
247 r
= dns_packet_validate_query(bypass
);
251 DNS_QUESTION_FOREACH(qk
, bypass
->question
) {
258 if (hashmap_size(s
->manager
->dns_transactions
) >= TRANSACTIONS_MAX
)
261 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
266 r
= hashmap_ensure_allocated(&s
->transactions_by_key
, &dns_resource_key_hash_ops
);
271 t
= new(DnsTransaction
, 1);
275 *t
= (DnsTransaction
) {
276 .dns_udp_fd
= -EBADF
,
277 .answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
,
278 .answer_dnssec_result
= _DNSSEC_RESULT_INVALID
,
279 .answer_nsec_ttl
= UINT32_MAX
,
280 .key
= dns_resource_key_ref(key
),
281 .query_flags
= query_flags
,
282 .bypass
= dns_packet_ref(bypass
),
283 .current_feature_level
= _DNS_SERVER_FEATURE_LEVEL_INVALID
,
284 .clamp_feature_level_servfail
= _DNS_SERVER_FEATURE_LEVEL_INVALID
,
285 .id
= pick_new_id(s
->manager
),
288 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
295 DnsTransaction
*first
;
297 first
= hashmap_get(s
->transactions_by_key
, t
->key
);
298 LIST_PREPEND(transactions_by_key
, first
, t
);
300 r
= hashmap_replace(s
->transactions_by_key
, first
->key
, first
);
302 LIST_REMOVE(transactions_by_key
, first
, t
);
307 LIST_PREPEND(transactions_by_scope
, s
->transactions
, t
);
310 s
->manager
->n_transactions_total
++;
319 static void dns_transaction_shuffle_id(DnsTransaction
*t
) {
323 /* Pick a new ID for this transaction. */
325 new_id
= pick_new_id(t
->scope
->manager
);
326 assert_se(hashmap_remove_and_put(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), UINT_TO_PTR(new_id
), t
) >= 0);
328 log_debug("Transaction %" PRIu16
" is now %" PRIu16
".", t
->id
, new_id
);
331 /* Make sure we generate a new packet with the new ID */
332 t
->sent
= dns_packet_unref(t
->sent
);
335 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
336 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
341 assert(t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
);
343 if (manager_packet_from_local_address(t
->scope
->manager
, p
) != 0)
346 log_debug("Transaction %" PRIu16
" for <%s> on scope %s on %s/%s got tentative packet from %s.",
348 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
349 dns_protocol_to_string(t
->scope
->protocol
),
350 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
351 af_to_name_short(t
->scope
->family
),
352 IN_ADDR_TO_STRING(p
->family
, &p
->sender
));
354 /* RFC 4795, Section 4.1 says that the peer with the
355 * lexicographically smaller IP address loses */
356 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
357 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
361 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
365 while ((z
= set_first(t
->notify_zone_items
))) {
366 /* First, make sure the zone item drops the reference
368 dns_zone_item_probe_stop(z
);
370 /* Secondly, report this as conflict, so that we might
371 * look for a different hostname */
372 dns_zone_item_conflict(z
);
376 dns_transaction_gc(t
);
379 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
380 DnsQueryCandidate
*c
;
384 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
387 assert(!DNS_TRANSACTION_IS_LIVE(state
));
389 if (state
== DNS_TRANSACTION_DNSSEC_FAILED
) {
390 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
);
392 log_struct(LOG_NOTICE
,
393 "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR
,
394 LOG_MESSAGE("DNSSEC validation failed for question %s: %s",
395 key_str
, dnssec_result_to_string(t
->answer_dnssec_result
)),
396 "DNS_TRANSACTION=%" PRIu16
, t
->id
,
397 "DNS_QUESTION=%s", key_str
,
398 "DNSSEC_RESULT=%s", dnssec_result_to_string(t
->answer_dnssec_result
),
399 "DNS_SERVER=%s", strna(dns_server_string_full(t
->server
)),
400 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t
->server
->possible_feature_level
));
403 /* Note that this call might invalidate the query. Callers
404 * should hence not attempt to access the query or transaction
405 * after calling this function. */
407 if (state
== DNS_TRANSACTION_ERRNO
)
408 st
= errno_to_name(t
->answer_errno
);
410 st
= dns_transaction_state_to_string(state
);
412 log_debug("%s transaction %" PRIu16
" for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s; %s).",
413 t
->bypass
? "Bypass" : "Regular",
415 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
416 dns_protocol_to_string(t
->scope
->protocol
),
417 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
418 af_to_name_short(t
->scope
->family
),
420 t
->answer_source
< 0 ? "none" : dns_transaction_source_to_string(t
->answer_source
),
421 FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) ? "not validated" :
422 (FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
) ? "authenticated" : "unsigned"),
423 FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
) ? "confidential" : "non-confidential");
427 dns_transaction_close_connection(t
, true);
428 dns_transaction_stop_timeout(t
);
430 /* Notify all queries that are interested, but make sure the
431 * transaction isn't freed while we are still looking at it */
434 SET_FOREACH_MOVE(c
, t
->notify_query_candidates_done
, t
->notify_query_candidates
)
435 dns_query_candidate_notify(c
);
436 SWAP_TWO(t
->notify_query_candidates
, t
->notify_query_candidates_done
);
438 SET_FOREACH_MOVE(z
, t
->notify_zone_items_done
, t
->notify_zone_items
)
439 dns_zone_item_notify(z
);
440 SWAP_TWO(t
->notify_zone_items
, t
->notify_zone_items_done
);
441 if (t
->probing
&& t
->state
== DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
)
442 (void) dns_scope_announce(t
->scope
, false);
444 SET_FOREACH_MOVE(d
, t
->notify_transactions_done
, t
->notify_transactions
)
445 dns_transaction_notify(d
, t
);
446 SWAP_TWO(t
->notify_transactions
, t
->notify_transactions_done
);
449 dns_transaction_gc(t
);
452 static void dns_transaction_complete_errno(DnsTransaction
*t
, int error
) {
456 t
->answer_errno
= abs(error
);
457 dns_transaction_complete(t
, DNS_TRANSACTION_ERRNO
);
460 static int dns_transaction_pick_server(DnsTransaction
*t
) {
464 assert(t
->scope
->protocol
== DNS_PROTOCOL_DNS
);
466 /* Pick a DNS server and a feature level for it. */
468 server
= dns_scope_get_dns_server(t
->scope
);
472 /* If we changed the server invalidate the feature level clamping, as the new server might have completely
473 * different properties. */
474 if (server
!= t
->server
)
475 t
->clamp_feature_level_servfail
= _DNS_SERVER_FEATURE_LEVEL_INVALID
;
477 t
->current_feature_level
= dns_server_possible_feature_level(server
);
479 /* Clamp the feature level if that is requested. */
480 if (t
->clamp_feature_level_servfail
!= _DNS_SERVER_FEATURE_LEVEL_INVALID
&&
481 t
->current_feature_level
> t
->clamp_feature_level_servfail
)
482 t
->current_feature_level
= t
->clamp_feature_level_servfail
;
484 log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t
->current_feature_level
), t
->id
);
486 if (server
== t
->server
)
489 dns_server_unref(t
->server
);
490 t
->server
= dns_server_ref(server
);
492 t
->n_picked_servers
++;
494 log_debug("Using DNS server %s for transaction %u.", strna(dns_server_string_full(t
->server
)), t
->id
);
499 static void dns_transaction_retry(DnsTransaction
*t
, bool next_server
) {
504 /* Retries the transaction as it is, possibly on a different server */
506 if (next_server
&& t
->scope
->protocol
== DNS_PROTOCOL_DNS
)
507 log_debug("Retrying transaction %" PRIu16
", after switching servers.", t
->id
);
509 log_debug("Retrying transaction %" PRIu16
".", t
->id
);
511 /* Before we try again, switch to a new server. */
513 dns_scope_next_dns_server(t
->scope
, t
->server
);
515 r
= dns_transaction_go(t
);
517 dns_transaction_complete_errno(t
, r
);
520 static bool dns_transaction_limited_retry(DnsTransaction
*t
) {
523 /* If we haven't tried all different servers yet, let's try again with a different server */
525 if (t
->n_picked_servers
>= dns_scope_get_n_dns_servers(t
->scope
))
528 dns_transaction_retry(t
, /* next_server= */ true);
532 static int dns_transaction_maybe_restart(DnsTransaction
*t
) {
537 /* Restarts the transaction, under a new ID if the feature level of the server changed since we first
538 * tried, without changing DNS server. Returns > 0 if the transaction was restarted, 0 if not. */
543 if (t
->current_feature_level
<= dns_server_possible_feature_level(t
->server
))
546 /* The server's current feature level is lower than when we sent the original query. We learnt something from
547 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
548 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
549 OPT RR or DO bit. One of these cases is documented here, for example:
550 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
552 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
553 dns_transaction_shuffle_id(t
);
555 r
= dns_transaction_go(t
);
562 static void on_transaction_stream_error(DnsTransaction
*t
, int error
) {
565 dns_transaction_close_connection(t
, true);
567 if (ERRNO_IS_DISCONNECT(error
)) {
568 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
569 /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
570 * question on this scope. */
571 dns_transaction_complete(t
, DNS_TRANSACTION_NOT_FOUND
);
575 dns_transaction_retry(t
, true);
579 dns_transaction_complete_errno(t
, error
);
582 static int dns_transaction_on_stream_packet(DnsTransaction
*t
, DnsStream
*s
, DnsPacket
*p
) {
589 encrypted
= s
->encrypted
;
591 dns_transaction_close_connection(t
, true);
593 if (dns_packet_validate_reply(p
) <= 0) {
594 log_debug("Invalid TCP reply packet.");
595 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
599 dns_scope_check_conflicts(t
->scope
, p
);
602 dns_transaction_process_reply(t
, p
, encrypted
);
605 /* If the response wasn't useful, then complete the transition
606 * now. After all, we are the worst feature set now with TCP
607 * sockets, and there's really no point in retrying. */
608 if (t
->state
== DNS_TRANSACTION_PENDING
)
609 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
611 dns_transaction_gc(t
);
616 static int on_stream_complete(DnsStream
*s
, int error
) {
619 if (ERRNO_IS_DISCONNECT(error
) && s
->protocol
!= DNS_PROTOCOL_LLMNR
) {
620 log_debug_errno(error
, "Connection failure for DNS TCP stream: %m");
622 if (s
->transactions
) {
626 dns_server_packet_lost(t
->server
, IPPROTO_TCP
, t
->current_feature_level
);
631 LIST_FOREACH(transactions_by_stream
, t
, s
->transactions
)
632 on_transaction_stream_error(t
, error
);
637 static int on_stream_packet(DnsStream
*s
, DnsPacket
*p
) {
644 t
= hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
645 if (t
&& t
->stream
== s
) /* Validate that the stream we got this on actually is the stream the
646 * transaction was using. */
647 return dns_transaction_on_stream_packet(t
, s
, p
);
649 /* Ignore incorrect transaction id as an old transaction can have been canceled. */
650 log_debug("Received unexpected TCP reply packet with id %" PRIu16
", ignoring.", DNS_PACKET_ID(p
));
654 static uint16_t dns_transaction_port(DnsTransaction
*t
) {
657 if (t
->server
->port
> 0)
658 return t
->server
->port
;
660 return DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) ? 853 : 53;
663 static int dns_transaction_emit_tcp(DnsTransaction
*t
) {
664 usec_t stream_timeout_usec
= DNS_STREAM_DEFAULT_TIMEOUT_USEC
;
665 _cleanup_(dns_stream_unrefp
) DnsStream
*s
= NULL
;
666 _cleanup_close_
int fd
= -EBADF
;
667 union sockaddr_union sa
;
674 dns_transaction_close_connection(t
, true);
676 switch (t
->scope
->protocol
) {
678 case DNS_PROTOCOL_DNS
:
679 r
= dns_transaction_pick_server(t
);
683 if (manager_server_is_stub(t
->scope
->manager
, t
->server
))
687 if (!dns_server_dnssec_supported(t
->server
) && dns_type_is_dnssec(dns_transaction_key(t
)->type
))
690 r
= dns_server_adjust_opt(t
->server
, t
->sent
, t
->current_feature_level
);
695 if (t
->server
->stream
&& (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) == t
->server
->stream
->encrypted
))
696 s
= dns_stream_ref(t
->server
->stream
);
698 fd
= dns_scope_socket_tcp(t
->scope
, AF_UNSPEC
, NULL
, t
->server
, dns_transaction_port(t
), &sa
);
700 /* Lower timeout in DNS-over-TLS opportunistic mode. In environments where DoT is blocked
701 * without ICMP response overly long delays when contacting DoT servers are nasty, in
702 * particular if multiple DNS servers are defined which we try in turn and all are
703 * blocked. Hence, substantially lower the timeout in that case. */
704 if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
) &&
705 dns_server_get_dns_over_tls_mode(t
->server
) == DNS_OVER_TLS_OPPORTUNISTIC
)
706 stream_timeout_usec
= DNS_STREAM_OPPORTUNISTIC_TLS_TIMEOUT_USEC
;
708 type
= DNS_STREAM_LOOKUP
;
711 case DNS_PROTOCOL_LLMNR
:
712 /* When we already received a reply to this (but it was truncated), send to its sender address */
714 fd
= dns_scope_socket_tcp(t
->scope
, t
->received
->family
, &t
->received
->sender
, NULL
, t
->received
->sender_port
, &sa
);
716 union in_addr_union address
;
717 int family
= AF_UNSPEC
;
719 /* Otherwise, try to talk to the owner of a
720 * the IP address, in case this is a reverse
723 r
= dns_name_address(dns_resource_key_name(dns_transaction_key(t
)), &family
, &address
);
728 if (family
!= t
->scope
->family
)
731 fd
= dns_scope_socket_tcp(t
->scope
, family
, &address
, NULL
, LLMNR_PORT
, &sa
);
734 type
= DNS_STREAM_LLMNR_SEND
;
738 return -EAFNOSUPPORT
;
745 r
= dns_stream_new(t
->scope
->manager
, &s
, type
, t
->scope
->protocol
, fd
, &sa
,
746 on_stream_packet
, on_stream_complete
, stream_timeout_usec
);
752 #if ENABLE_DNS_OVER_TLS
753 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
754 DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
)) {
757 r
= dnstls_stream_connect_tls(s
, t
->server
);
764 dns_server_unref_stream(t
->server
);
765 s
->server
= dns_server_ref(t
->server
);
766 t
->server
->stream
= dns_stream_ref(s
);
769 /* The interface index is difficult to determine if we are
770 * connecting to the local host, hence fill this in right away
771 * instead of determining it from the socket */
772 s
->ifindex
= dns_scope_ifindex(t
->scope
);
775 t
->stream
= TAKE_PTR(s
);
776 LIST_PREPEND(transactions_by_stream
, t
->stream
->transactions
, t
);
778 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
780 dns_transaction_close_connection(t
, /* use_graveyard= */ false);
784 dns_transaction_reset_answer(t
);
786 t
->tried_stream
= true;
791 static void dns_transaction_cache_answer(DnsTransaction
*t
) {
794 /* For mDNS we cache whenever we get the packet, rather than
795 * in each transaction. */
796 if (!IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
))
799 /* Caching disabled? */
800 if (t
->scope
->manager
->enable_cache
== DNS_CACHE_MODE_NO
)
803 /* If validation is turned off for this transaction, but DNSSEC is on, then let's not cache this */
804 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) && t
->scope
->dnssec_mode
!= DNSSEC_NO
)
807 /* Packet from localhost? */
808 if (!t
->scope
->manager
->cache_from_localhost
&&
809 in_addr_is_localhost(t
->received
->family
, &t
->received
->sender
) != 0)
812 dns_cache_put(&t
->scope
->cache
,
813 t
->scope
->manager
->enable_cache
,
815 dns_transaction_key(t
),
818 DNS_PACKET_CD(t
->received
) ? t
->received
: NULL
, /* only cache full packets with CD on,
819 * since our use case for caching them
820 * is "bypass" mode which is only
821 * enabled for CD packets. */
822 t
->answer_query_flags
,
823 t
->answer_dnssec_result
,
826 &t
->received
->sender
,
827 t
->scope
->manager
->stale_retention_usec
);
830 static bool dns_transaction_dnssec_is_live(DnsTransaction
*t
) {
835 SET_FOREACH(dt
, t
->dnssec_transactions
)
836 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
842 static int dns_transaction_dnssec_ready(DnsTransaction
*t
) {
848 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
849 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
851 SET_FOREACH(dt
, t
->dnssec_transactions
) {
855 case DNS_TRANSACTION_NULL
:
856 case DNS_TRANSACTION_PENDING
:
857 case DNS_TRANSACTION_VALIDATING
:
861 case DNS_TRANSACTION_RCODE_FAILURE
:
862 if (!IN_SET(dt
->answer_rcode
, DNS_RCODE_NXDOMAIN
, DNS_RCODE_SERVFAIL
)) {
863 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", FORMAT_DNS_RCODE(dt
->answer_rcode
));
867 /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
868 * erroneously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
869 * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
870 * RRs to make unsigned proofs. */
872 case DNS_TRANSACTION_SUCCESS
:
876 case DNS_TRANSACTION_DNSSEC_FAILED
:
877 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
878 * validation result */
880 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt
->answer_dnssec_result
));
881 t
->answer_dnssec_result
= dt
->answer_dnssec_result
; /* Copy error code over */
882 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
886 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt
->state
));
891 /* All is ready, we can go and validate */
895 /* Some auxiliary DNSSEC transaction failed for some reason. Maybe we learned something about the
896 * server due to this failure, and the feature level is now different? Let's see and restart the
897 * transaction if so. If not, let's propagate the auxiliary failure.
899 * This is particularly relevant if an auxiliary request figured out that DNSSEC doesn't work, and we
900 * are in permissive DNSSEC mode, and thus should restart things without DNSSEC magic. */
901 r
= dns_transaction_maybe_restart(t
);
905 return 0; /* don't validate just yet, we restarted things */
907 t
->answer_dnssec_result
= DNSSEC_FAILED_AUXILIARY
;
908 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
912 static void dns_transaction_process_dnssec(DnsTransaction
*t
) {
917 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
918 r
= dns_transaction_dnssec_ready(t
);
921 if (r
== 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
924 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
925 * restart the lookup immediately. */
926 r
= dns_transaction_maybe_restart(t
);
929 if (r
> 0) /* Transaction got restarted... */
932 /* All our auxiliary DNSSEC transactions are complete now. Try
933 * to validate our RRset now. */
934 r
= dns_transaction_validate_dnssec(t
);
936 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
942 if (t
->answer_dnssec_result
== DNSSEC_INCOMPATIBLE_SERVER
&&
943 t
->scope
->dnssec_mode
== DNSSEC_YES
) {
945 /* We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
948 if (dns_transaction_limited_retry(t
))
951 /* OK, let's give up, apparently all servers we tried didn't work. */
952 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
956 if (!IN_SET(t
->answer_dnssec_result
,
957 _DNSSEC_RESULT_INVALID
, /* No DNSSEC validation enabled */
958 DNSSEC_VALIDATED
, /* Answer is signed and validated successfully */
959 DNSSEC_UNSIGNED
, /* Answer is right-fully unsigned */
960 DNSSEC_INCOMPATIBLE_SERVER
)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
961 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
965 if (t
->answer_dnssec_result
== DNSSEC_INCOMPATIBLE_SERVER
)
966 dns_server_warn_downgrade(t
->server
);
968 dns_transaction_cache_answer(t
);
970 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
971 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
973 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
978 dns_transaction_complete_errno(t
, r
);
981 static int dns_transaction_has_positive_answer(DnsTransaction
*t
, DnsAnswerFlags
*flags
) {
986 /* Checks whether the answer is positive, i.e. either a direct
987 * answer to the question, or a CNAME/DNAME for it */
989 r
= dns_answer_match_key(t
->answer
, dns_transaction_key(t
), flags
);
993 r
= dns_answer_find_cname_or_dname(t
->answer
, dns_transaction_key(t
), NULL
, flags
);
1000 static int dns_transaction_fix_rcode(DnsTransaction
*t
) {
1005 /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
1006 * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
1007 * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
1008 * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
1009 * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
1010 * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
1011 * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
1012 * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
1013 * incomplete CNAME/DNAME chain.
1015 * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
1016 * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
1019 if (t
->answer_rcode
!= DNS_RCODE_NXDOMAIN
)
1022 r
= dns_transaction_has_positive_answer(t
, NULL
);
1026 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1030 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
, bool encrypted
) {
1031 bool retry_with_tcp
= false;
1037 assert(t
->scope
->manager
);
1039 if (t
->state
!= DNS_TRANSACTION_PENDING
)
1042 /* Increment the total failure counter only when it is the first attempt at querying and the upstream
1043 * server returns a failure response code. This ensures a more accurate count of the number of queries
1044 * that received a failure response code, as it doesn't consider retries. */
1046 if (t
->n_attempts
== 1 && !IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_SUCCESS
, DNS_RCODE_NXDOMAIN
))
1047 t
->scope
->manager
->n_failure_responses_total
++;
1049 /* Note that this call might invalidate the query. Callers
1050 * should hence not attempt to access the query or transaction
1051 * after calling this function. */
1053 log_debug("Processing incoming packet of size %zu on transaction %" PRIu16
" (rcode=%s).",
1055 t
->id
, FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1057 switch (t
->scope
->protocol
) {
1059 case DNS_PROTOCOL_LLMNR
:
1060 /* For LLMNR we will not accept any packets from other interfaces */
1062 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1065 if (p
->family
!= t
->scope
->family
)
1068 /* Tentative packets are not full responses but still
1069 * useful for identifying uniqueness conflicts during
1071 if (DNS_PACKET_LLMNR_T(p
)) {
1072 dns_transaction_tentative(t
, p
);
1078 case DNS_PROTOCOL_MDNS
:
1079 /* For mDNS we will not accept any packets from other interfaces */
1081 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1084 if (p
->family
!= t
->scope
->family
)
1089 case DNS_PROTOCOL_DNS
:
1090 /* Note that we do not need to verify the
1091 * addresses/port numbers of incoming traffic, as we
1092 * invoked connect() on our UDP socket in which case
1093 * the kernel already does the needed verification for
1098 assert_not_reached();
1101 if (t
->received
!= p
)
1102 DNS_PACKET_REPLACE(t
->received
, dns_packet_ref(p
));
1104 t
->answer_source
= DNS_TRANSACTION_NETWORK
;
1106 if (p
->ipproto
== IPPROTO_TCP
) {
1107 if (DNS_PACKET_TC(p
)) {
1108 /* Truncated via TCP? Somebody must be fucking with us */
1109 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1113 if (DNS_PACKET_ID(p
) != t
->id
) {
1114 /* Not the reply to our query? Somebody must be fucking with us */
1115 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1120 switch (t
->scope
->protocol
) {
1122 case DNS_PROTOCOL_DNS
:
1126 IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_FORMERR
, DNS_RCODE_SERVFAIL
, DNS_RCODE_NOTIMP
)) {
1128 /* Request failed, immediately try again with reduced features */
1130 if (t
->current_feature_level
<= DNS_SERVER_FEATURE_LEVEL_UDP
) {
1132 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
1133 * this transaction anymore, but let's see if it might make sense to send the request
1134 * to a different DNS server instead. If not let's process the response, and accept the
1135 * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1136 * packet loss, but is not going to give us better rcodes should we actually have
1137 * managed to get them already at UDP level. */
1139 if (dns_transaction_limited_retry(t
))
1142 /* Give up, accept the rcode */
1143 log_debug("Server returned error: %s", FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1147 /* SERVFAIL can happen for many reasons and may be transient.
1148 * To avoid unnecessary downgrades retry once with the initial level.
1149 * Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
1150 * first attempt to downgrade. If so, clamp to the current value so that the transaction
1151 * is retried without actually downgrading. If the next try also fails we will downgrade by
1152 * hitting the else branch below. */
1153 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_SERVFAIL
&&
1154 t
->clamp_feature_level_servfail
< 0) {
1155 t
->clamp_feature_level_servfail
= t
->current_feature_level
;
1156 log_debug("Server returned error %s, retrying transaction.",
1157 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1159 /* Reduce this feature level by one and try again. */
1160 switch (t
->current_feature_level
) {
1161 case DNS_SERVER_FEATURE_LEVEL_TLS_DO
:
1162 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
;
1164 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
+ 1:
1165 /* Skip plain TLS when TLS is not supported */
1166 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
- 1;
1169 t
->clamp_feature_level_servfail
= t
->current_feature_level
- 1;
1172 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1173 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1174 dns_server_feature_level_to_string(t
->clamp_feature_level_servfail
));
1177 dns_transaction_retry(t
, false /* use the same server */);
1181 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_REFUSED
) {
1182 /* This server refused our request? If so, try again, use a different server */
1183 log_debug("Server returned REFUSED, switching servers, and retrying.");
1185 if (dns_transaction_limited_retry(t
))
1191 if (DNS_PACKET_TC(p
))
1192 dns_server_packet_truncated(t
->server
, t
->current_feature_level
);
1196 case DNS_PROTOCOL_LLMNR
:
1197 case DNS_PROTOCOL_MDNS
:
1198 dns_scope_packet_received(t
->scope
, p
->timestamp
- t
->start_usec
);
1202 assert_not_reached();
1205 if (DNS_PACKET_TC(p
)) {
1207 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1208 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
) {
1209 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1213 /* Response was truncated, let's try again with good old TCP */
1214 log_debug("Reply truncated, retrying via TCP.");
1215 retry_with_tcp
= true;
1217 } else if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1218 DNS_PACKET_IS_FRAGMENTED(p
)) {
1220 /* Report the fragment size, so that we downgrade from LARGE to regular EDNS0 if needed */
1222 dns_server_packet_udp_fragmented(t
->server
, dns_packet_size_unfragmented(p
));
1224 if (t
->current_feature_level
> DNS_SERVER_FEATURE_LEVEL_UDP
) {
1225 /* Packet was fragmented. Let's retry with TCP to avoid fragmentation attack
1226 * issues. (We don't do that on the lowest feature level however, since crappy DNS
1227 * servers often do not implement TCP, hence falling back to TCP on fragmentation is
1228 * counter-productive there.) */
1230 log_debug("Reply fragmented, retrying via TCP. (Largest fragment size: %zu; Datagram size: %zu)",
1231 p
->fragsize
, p
->size
);
1232 retry_with_tcp
= true;
1236 if (retry_with_tcp
) {
1237 r
= dns_transaction_emit_tcp(t
);
1239 /* No servers found? Damn! */
1240 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1243 if (r
== -EOPNOTSUPP
) {
1244 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1245 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
1249 /* On LLMNR, if we cannot connect to the host,
1250 * we immediately give up */
1251 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1254 /* On DNS, couldn't send? Try immediately again, with a new server */
1255 if (dns_transaction_limited_retry(t
))
1258 /* No new server to try, give up */
1259 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1265 /* After the superficial checks, actually parse the message. */
1266 r
= dns_packet_extract(p
);
1269 dns_server_packet_invalid(t
->server
, t
->current_feature_level
);
1271 r
= dns_transaction_maybe_restart(t
);
1274 if (r
> 0) /* Transaction got restarted... */
1278 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1283 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1284 * rcode and subsequently downgraded the protocol */
1286 if (IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_SUCCESS
, DNS_RCODE_NXDOMAIN
) &&
1287 t
->clamp_feature_level_servfail
!= _DNS_SERVER_FEATURE_LEVEL_INVALID
)
1288 dns_server_packet_rcode_downgrade(t
->server
, t
->clamp_feature_level_servfail
);
1290 /* Report that the OPT RR was missing */
1292 dns_server_packet_bad_opt(t
->server
, t
->current_feature_level
);
1294 /* Report that the server didn't copy our query DO bit from request to response */
1295 if (DNS_PACKET_DO(t
->sent
) && !DNS_PACKET_DO(t
->received
))
1296 dns_server_packet_do_off(t
->server
, t
->current_feature_level
);
1298 /* Report that we successfully received a packet. We keep track of the largest packet
1299 * size/fragment size we got. Which is useful for announcing the EDNS(0) packet size we can
1300 * receive to our server. */
1301 dns_server_packet_received(t
->server
, p
->ipproto
, t
->current_feature_level
, dns_packet_size_unfragmented(p
));
1304 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1305 r
= dns_transaction_maybe_restart(t
);
1308 if (r
> 0) /* Transaction got restarted... */
1311 /* When dealing with protocols other than mDNS only consider responses with equivalent query section
1312 * to the request. For mDNS this check doesn't make sense, because the section 6 of RFC6762 states
1313 * that "Multicast DNS responses MUST NOT contain any questions in the Question Section". */
1314 if (t
->scope
->protocol
!= DNS_PROTOCOL_MDNS
) {
1315 r
= dns_packet_is_reply_for(p
, dns_transaction_key(t
));
1319 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1324 /* Install the answer as answer to the transaction. We ref the answer twice here: the main `answer`
1325 * field is later replaced by the DNSSEC validated subset. The 'answer_auxiliary' field carries the
1326 * original complete record set, including RRSIG and friends. We use this when passing data to
1327 * clients that ask for DNSSEC metadata. */
1328 DNS_ANSWER_REPLACE(t
->answer
, dns_answer_ref(p
->answer
));
1329 t
->answer_rcode
= DNS_PACKET_RCODE(p
);
1330 t
->answer_dnssec_result
= _DNSSEC_RESULT_INVALID
;
1331 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1332 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, encrypted
);
1334 r
= dns_transaction_fix_rcode(t
);
1338 /* Block GC while starting requests for additional DNSSEC RRs */
1340 r
= dns_transaction_request_dnssec_keys(t
);
1343 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1344 if (!dns_transaction_gc(t
))
1347 /* Requesting additional keys might have resulted in this transaction to fail, since the auxiliary
1348 * request failed for some reason. If so, we are not in pending state anymore, and we should exit
1350 if (t
->state
!= DNS_TRANSACTION_PENDING
)
1355 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1356 t
->state
= DNS_TRANSACTION_VALIDATING
;
1357 dns_transaction_close_connection(t
, true);
1358 dns_transaction_stop_timeout(t
);
1362 dns_transaction_process_dnssec(t
);
1366 dns_transaction_complete_errno(t
, r
);
1369 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1370 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1371 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1376 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
1378 if (ERRNO_IS_DISCONNECT(r
)) {
1381 /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
1382 * next recvmsg(). Treat this like a lost packet. */
1384 log_debug_errno(r
, "Connection failure for DNS UDP packet: %m");
1385 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &usec
) >= 0);
1386 dns_server_packet_lost(t
->server
, IPPROTO_UDP
, t
->current_feature_level
);
1388 dns_transaction_close_connection(t
, /* use_graveyard = */ false);
1390 if (dns_transaction_limited_retry(t
)) /* Try a different server */
1393 dns_transaction_complete_errno(t
, r
);
1397 /* Spurious wakeup without any data */
1400 r
= dns_packet_validate_reply(p
);
1402 log_debug_errno(r
, "Received invalid DNS packet as response, ignoring: %m");
1406 log_debug("Received inappropriate DNS packet as response, ignoring.");
1410 if (DNS_PACKET_ID(p
) != t
->id
) {
1411 log_debug("Received packet with incorrect transaction ID, ignoring.");
1415 dns_transaction_process_reply(t
, p
, false);
1419 static int dns_transaction_emit_udp(DnsTransaction
*t
) {
1424 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
) {
1426 r
= dns_transaction_pick_server(t
);
1430 if (manager_server_is_stub(t
->scope
->manager
, t
->server
))
1433 if (t
->current_feature_level
< DNS_SERVER_FEATURE_LEVEL_UDP
|| DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
))
1434 return -EAGAIN
; /* Sorry, can't do UDP, try TCP! */
1436 if (!t
->bypass
&& !dns_server_dnssec_supported(t
->server
) && dns_type_is_dnssec(dns_transaction_key(t
)->type
))
1439 if (r
> 0 || t
->dns_udp_fd
< 0) { /* Server changed, or no connection yet. */
1442 dns_transaction_close_connection(t
, true);
1444 /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */
1445 manager_socket_graveyard_process(t
->scope
->manager
);
1447 fd
= dns_scope_socket_udp(t
->scope
, t
->server
);
1451 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
1457 (void) sd_event_source_set_description(t
->dns_udp_event_source
, "dns-transaction-udp");
1462 r
= dns_server_adjust_opt(t
->server
, t
->sent
, t
->current_feature_level
);
1467 dns_transaction_close_connection(t
, true);
1469 r
= dns_scope_emit_udp(t
->scope
, t
->dns_udp_fd
, t
->server
? t
->server
->family
: AF_UNSPEC
, t
->sent
);
1473 dns_transaction_reset_answer(t
);
1478 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1479 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1483 t
->seen_timeout
= true;
1485 if (t
->initial_jitter_scheduled
&& !t
->initial_jitter_elapsed
) {
1486 log_debug("Initial jitter phase for transaction %" PRIu16
" elapsed.", t
->id
);
1487 t
->initial_jitter_elapsed
= true;
1489 /* Timeout reached? Increase the timeout for the server used */
1490 switch (t
->scope
->protocol
) {
1492 case DNS_PROTOCOL_DNS
:
1494 dns_server_packet_lost(t
->server
, t
->stream
? IPPROTO_TCP
: IPPROTO_UDP
, t
->current_feature_level
);
1497 case DNS_PROTOCOL_LLMNR
:
1498 case DNS_PROTOCOL_MDNS
:
1499 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
1503 assert_not_reached();
1506 log_debug("Timeout reached on transaction %" PRIu16
".", t
->id
);
1509 dns_transaction_retry(t
, /* next_server= */ true); /* try a different server, but given this means
1510 * packet loss, let's do so even if we already
1515 static int dns_transaction_setup_timeout(
1517 usec_t timeout_usec
/* relative */,
1518 usec_t next_usec
/* CLOCK_BOOTTIME */) {
1524 dns_transaction_stop_timeout(t
);
1526 r
= sd_event_add_time_relative(
1527 t
->scope
->manager
->event
,
1528 &t
->timeout_event_source
,
1531 on_transaction_timeout
, t
);
1535 (void) sd_event_source_set_description(t
->timeout_event_source
, "dns-transaction-timeout");
1537 t
->next_attempt_after
= next_usec
;
1538 t
->state
= DNS_TRANSACTION_PENDING
;
1542 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
1546 switch (t
->scope
->protocol
) {
1548 case DNS_PROTOCOL_DNS
:
1550 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1551 * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1554 return TRANSACTION_TCP_TIMEOUT_USEC
;
1556 return DNS_TIMEOUT_USEC
;
1558 case DNS_PROTOCOL_MDNS
:
1560 return MDNS_PROBING_INTERVAL_USEC
;
1562 /* See RFC 6762 Section 5.1 suggests that timeout should be a few seconds. */
1563 assert(t
->n_attempts
> 0);
1564 return (1 << (t
->n_attempts
- 1)) * USEC_PER_SEC
;
1566 case DNS_PROTOCOL_LLMNR
:
1567 return t
->scope
->resend_timeout
;
1570 assert_not_reached();
1574 static void dns_transaction_randomize_answer(DnsTransaction
*t
) {
1579 /* Randomizes the order of the answer array. This is done for all cached responses, so that we return
1580 * a different order each time. We do this only for DNS traffic, in order to do some minimal, crappy
1581 * load balancing. We don't do this for LLMNR or mDNS, since the order (preferring link-local
1582 * addresses, and such like) might have meaning there, and load balancing is pointless. */
1584 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1587 /* No point in randomizing, if there's just one RR */
1588 if (dns_answer_size(t
->answer
) <= 1)
1591 r
= dns_answer_reserve_or_clone(&t
->answer
, 0);
1592 if (r
< 0) /* If this fails, just don't randomize, this is non-essential stuff after all */
1593 return (void) log_debug_errno(r
, "Failed to clone answer record, not randomizing RR order of answer: %m");
1595 dns_answer_randomize(t
->answer
);
1598 static int dns_transaction_prepare(DnsTransaction
*t
, usec_t ts
) {
1603 /* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
1604 * candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
1605 * has been prepared. */
1607 dns_transaction_stop_timeout(t
);
1609 if (t
->n_attempts
== 1 && t
->seen_timeout
)
1610 t
->scope
->manager
->n_timeouts_total
++;
1612 if (!dns_scope_network_good(t
->scope
)) {
1613 dns_transaction_complete(t
, DNS_TRANSACTION_NETWORK_DOWN
);
1617 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
1618 DnsTransactionState result
;
1620 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
)
1621 /* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
1623 result
= DNS_TRANSACTION_NOT_FOUND
;
1625 result
= DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
;
1627 dns_transaction_complete(t
, result
);
1631 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& t
->tried_stream
) {
1632 /* If we already tried via a stream, then we don't
1633 * retry on LLMNR. See RFC 4795, Section 2.7. */
1634 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1641 dns_transaction_reset_answer(t
);
1642 dns_transaction_flush_dnssec_transactions(t
);
1644 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1645 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1646 !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_TRUST_ANCHOR
)) {
1647 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, dns_transaction_key(t
), &t
->answer
);
1651 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1652 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1653 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1654 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1658 if (dns_name_is_root(dns_resource_key_name(dns_transaction_key(t
))) &&
1659 dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
1661 /* Hmm, this is a request for the root DS? A DS RR doesn't exist in the root zone,
1662 * and if our trust anchor didn't know it either, this means we cannot do any DNSSEC
1665 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
1666 /* We are in downgrade mode. In this case, synthesize an unsigned empty
1667 * response, so that the any lookup depending on this one can continue
1668 * assuming there was no DS, and hence the root zone was unsigned. */
1670 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1671 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1672 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1673 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, true);
1674 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1676 /* If we are not in downgrade mode, then fail the lookup, because we cannot
1677 * reasonably answer it. There might be DS RRs, but we don't know them, and
1678 * the DNS server won't tell them to us (and even if it would, we couldn't
1679 * validate and trust them. */
1680 dns_transaction_complete(t
, DNS_TRANSACTION_NO_TRUST_ANCHOR
);
1686 /* Check the zone. */
1687 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_ZONE
)) {
1688 r
= dns_zone_lookup(&t
->scope
->zone
, dns_transaction_key(t
), dns_scope_ifindex(t
->scope
), &t
->answer
, NULL
, NULL
);
1692 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1693 t
->answer_source
= DNS_TRANSACTION_ZONE
;
1694 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1695 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1700 /* Check the cache. */
1701 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_CACHE
)) {
1703 /* Before trying the cache, let's make sure we figured out a server to use. Should this cause
1704 * a change of server this might flush the cache. */
1705 (void) dns_scope_get_dns_server(t
->scope
);
1707 /* Let's then prune all outdated entries */
1708 dns_cache_prune(&t
->scope
->cache
);
1710 /* For the initial attempt or when no stale data is requested, disable serve stale
1711 * and answer the question from the cache (honors ttl property).
1712 * On the second attempt, if StaleRetentionSec is greater than zero,
1713 * try to answer the question using stale date (honors until property) */
1714 uint64_t query_flags
= t
->query_flags
;
1715 if (t
->n_attempts
== 1 || t
->scope
->manager
->stale_retention_usec
== 0)
1716 query_flags
|= SD_RESOLVED_NO_STALE
;
1718 r
= dns_cache_lookup(
1720 dns_transaction_key(t
),
1725 &t
->answer_query_flags
,
1726 &t
->answer_dnssec_result
);
1730 dns_transaction_randomize_answer(t
);
1732 if (t
->bypass
&& t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->received
)
1733 /* When bypass mode is on, do not use cached data unless it came with a full
1735 dns_transaction_reset_answer(t
);
1737 if (t
->n_attempts
> 1 && !FLAGS_SET(query_flags
, SD_RESOLVED_NO_STALE
)) {
1739 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
) {
1740 if (t
->seen_timeout
)
1741 t
->scope
->manager
->n_timeouts_served_stale_total
++;
1743 t
->scope
->manager
->n_failure_responses_served_stale_total
++;
1746 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
1747 log_debug("Serve Stale response rcode=%s for %s",
1748 FORMAT_DNS_RCODE(t
->answer_rcode
),
1749 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
1752 t
->answer_source
= DNS_TRANSACTION_CACHE
;
1753 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
1754 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1756 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
1762 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_NETWORK
)) {
1763 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SOURCE
);
1770 static int dns_packet_append_zone(DnsPacket
*p
, DnsTransaction
*t
, DnsResourceKey
*k
, unsigned *nscount
) {
1771 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1779 if (k
->type
!= DNS_TYPE_ANY
)
1782 r
= dns_zone_lookup(&t
->scope
->zone
, k
, t
->scope
->link
->ifindex
, &answer
, NULL
, &tentative
);
1786 return dns_packet_append_answer(p
, answer
, nscount
);
1789 static int mdns_make_dummy_packet(DnsTransaction
*t
, DnsPacket
**ret_packet
, Set
**ret_keys
) {
1790 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1791 _cleanup_set_free_ Set
*keys
= NULL
;
1792 bool add_known_answers
= false;
1799 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
1803 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
1807 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
1813 if (dns_key_is_shared(dns_transaction_key(t
)))
1814 add_known_answers
= true;
1816 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(t
), NULL
);
1820 /* Save appended keys */
1821 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(t
));
1825 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
1827 LIST_FOREACH(transactions_by_scope
, other
, t
->scope
->transactions
) {
1829 /* Skip ourselves */
1833 if (other
->state
!= DNS_TRANSACTION_PENDING
)
1836 if (other
->next_attempt_after
> ts
)
1839 if (!set_contains(keys
, dns_transaction_key(other
))) {
1840 size_t saved_packet_size
;
1842 r
= dns_packet_append_key(p
, dns_transaction_key(other
), 0, &saved_packet_size
);
1843 /* If we can't stuff more questions into the packet, just give up.
1844 * One of the 'other' transactions will fire later and take care of the rest. */
1850 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(other
), NULL
);
1851 if (r
== -EMSGSIZE
) {
1852 dns_packet_truncate(p
, saved_packet_size
);
1858 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(other
));
1863 r
= dns_transaction_prepare(other
, ts
);
1867 /* In this case, not only this transaction, but multiple transactions may be
1868 * freed. Hence, we need to restart the loop. */
1871 usec_t timeout
= transaction_get_resend_timeout(other
);
1872 r
= dns_transaction_setup_timeout(other
, timeout
, usec_add(ts
, timeout
));
1876 if (dns_key_is_shared(dns_transaction_key(other
)))
1877 add_known_answers
= true;
1880 if (qdcount
>= UINT16_MAX
)
1884 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(qdcount
);
1886 /* Append known answers section if we're asking for any shared record */
1887 if (add_known_answers
) {
1888 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, 0);
1893 *ret_packet
= TAKE_PTR(p
);
1894 *ret_keys
= TAKE_PTR(keys
);
1895 return add_known_answers
;
1898 static int dns_transaction_make_packet_mdns(DnsTransaction
*t
) {
1899 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
, *dummy
= NULL
;
1900 _cleanup_set_free_ Set
*keys
= NULL
;
1901 bool add_known_answers
;
1907 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
1909 /* Discard any previously prepared packet, so we can start over and coalesce again */
1910 t
->sent
= dns_packet_unref(t
->sent
);
1912 /* First, create a dummy packet to calculate the number of known answers to be appended in the first packet. */
1914 r
= mdns_make_dummy_packet(t
, &dummy
, &keys
);
1920 add_known_answers
= r
;
1924 /* Then, create actual packet. */
1925 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
1931 SET_FOREACH(k
, keys
) {
1932 r
= dns_packet_append_key(p
, k
, 0, NULL
);
1937 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(c
);
1940 if (add_known_answers
) {
1943 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
1945 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, be16toh(DNS_PACKET_HEADER(dummy
)->ancount
));
1952 SET_FOREACH(k
, keys
) {
1953 r
= dns_packet_append_zone(p
, t
, k
, &c
);
1957 DNS_PACKET_HEADER(p
)->nscount
= htobe16(c
);
1959 t
->sent
= TAKE_PTR(p
);
1963 static int dns_transaction_make_packet(DnsTransaction
*t
) {
1964 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1969 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)
1970 return dns_transaction_make_packet_mdns(t
);
1975 if (t
->bypass
&& t
->bypass
->protocol
== t
->scope
->protocol
) {
1976 /* If bypass logic is enabled and the protocol if the original packet and our scope match,
1977 * take the original packet, copy it, and patch in our new ID */
1978 r
= dns_packet_dup(&p
, t
->bypass
);
1982 r
= dns_packet_new_query(
1983 &p
, t
->scope
->protocol
,
1984 /* min_alloc_dsize = */ 0,
1985 /* dnssec_cd = */ !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) &&
1986 t
->scope
->dnssec_mode
!= DNSSEC_NO
);
1990 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
1994 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
1997 DNS_PACKET_HEADER(p
)->id
= t
->id
;
1999 t
->sent
= TAKE_PTR(p
);
2003 int dns_transaction_go(DnsTransaction
*t
) {
2006 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
2010 /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
2011 * finished now. In the latter case, the transaction and query candidate objects must not be accessed.
2014 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
2016 r
= dns_transaction_prepare(t
, ts
);
2020 log_debug("Firing %s transaction %" PRIu16
" for <%s> scope %s on %s/%s (validate=%s).",
2021 t
->bypass
? "bypass" : "regular",
2023 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
2024 dns_protocol_to_string(t
->scope
->protocol
),
2025 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
2026 af_to_name_short(t
->scope
->family
),
2027 yes_no(!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
)));
2029 if (!t
->initial_jitter_scheduled
&&
2030 IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_LLMNR
, DNS_PROTOCOL_MDNS
)) {
2033 /* RFC 4795 Section 2.7 suggests all LLMNR queries should be delayed by a random time from 0 to
2035 * RFC 6762 Section 8.1 suggests initial probe queries should be delayed by a random time from
2038 t
->initial_jitter_scheduled
= true;
2041 switch (t
->scope
->protocol
) {
2043 case DNS_PROTOCOL_LLMNR
:
2044 jitter
= random_u64_range(LLMNR_JITTER_INTERVAL_USEC
);
2047 case DNS_PROTOCOL_MDNS
:
2049 jitter
= random_u64_range(MDNS_PROBING_INTERVAL_USEC
);
2054 assert_not_reached();
2057 r
= dns_transaction_setup_timeout(t
, jitter
, ts
);
2061 log_debug("Delaying %s transaction %" PRIu16
" for " USEC_FMT
"us.",
2062 dns_protocol_to_string(t
->scope
->protocol
),
2068 /* Otherwise, we need to ask the network */
2069 r
= dns_transaction_make_packet(t
);
2073 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
2074 (dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "in-addr.arpa") > 0 ||
2075 dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "ip6.arpa") > 0)) {
2077 /* RFC 4795, Section 2.4. says reverse lookups shall
2078 * always be made via TCP on LLMNR */
2079 r
= dns_transaction_emit_tcp(t
);
2081 /* Try via UDP, and if that fails due to large size or lack of
2082 * support try via TCP */
2083 r
= dns_transaction_emit_udp(t
);
2085 log_debug("Sending query via TCP since it is too large.");
2086 else if (r
== -EAGAIN
)
2087 log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
2088 else if (r
== -EPERM
)
2089 log_debug("Sending query via TCP since UDP is blocked.");
2090 if (IN_SET(r
, -EMSGSIZE
, -EAGAIN
, -EPERM
))
2091 r
= dns_transaction_emit_tcp(t
);
2094 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2097 /* One of our own stub listeners */
2098 log_debug_errno(r
, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
2100 dns_scope_next_dns_server(t
->scope
, t
->server
);
2102 if (dns_scope_get_dns_server(t
->scope
) == t
->server
) {
2103 log_debug_errno(r
, "Still pointing to extra listener after switching DNS servers, refusing operation.");
2104 dns_transaction_complete(t
, DNS_TRANSACTION_STUB_LOOP
);
2108 return dns_transaction_go(t
);
2111 /* No servers to send this to? */
2112 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
2115 if (r
== -EOPNOTSUPP
) {
2116 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
2117 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
2120 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& ERRNO_IS_NEG_DISCONNECT(r
)) {
2121 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
2122 * answer this request with this protocol. */
2123 dns_transaction_complete(t
, DNS_TRANSACTION_NOT_FOUND
);
2127 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2130 /* Couldn't send? Try immediately again, with a new server */
2131 dns_scope_next_dns_server(t
->scope
, t
->server
);
2133 return dns_transaction_go(t
);
2136 usec_t timeout
= transaction_get_resend_timeout(t
);
2137 r
= dns_transaction_setup_timeout(t
, timeout
, usec_add(ts
, timeout
));
2144 static int dns_transaction_find_cyclic(DnsTransaction
*t
, DnsTransaction
*aux
) {
2151 /* Try to find cyclic dependencies between transaction objects */
2156 SET_FOREACH(n
, aux
->dnssec_transactions
) {
2157 r
= dns_transaction_find_cyclic(t
, n
);
2165 static int dns_transaction_add_dnssec_transaction(DnsTransaction
*t
, DnsResourceKey
*key
, DnsTransaction
**ret
) {
2166 _cleanup_(dns_transaction_gcp
) DnsTransaction
*aux
= NULL
;
2173 aux
= dns_scope_find_transaction(t
->scope
, key
, t
->query_flags
);
2175 r
= dns_transaction_new(&aux
, t
->scope
, key
, NULL
, t
->query_flags
);
2179 if (set_contains(t
->dnssec_transactions
, aux
)) {
2184 r
= dns_transaction_find_cyclic(t
, aux
);
2188 char s
[DNS_RESOURCE_KEY_STRING_MAX
], saux
[DNS_RESOURCE_KEY_STRING_MAX
];
2190 return log_debug_errno(SYNTHETIC_ERRNO(ELOOP
),
2191 "Potential cyclic dependency, refusing to add transaction %" PRIu16
" (%s) as dependency for %" PRIu16
" (%s).",
2193 dns_resource_key_to_string(dns_transaction_key(t
), s
, sizeof s
),
2195 dns_resource_key_to_string(dns_transaction_key(aux
), saux
, sizeof saux
));
2199 r
= set_ensure_allocated(&aux
->notify_transactions_done
, NULL
);
2203 r
= set_ensure_put(&t
->dnssec_transactions
, NULL
, aux
);
2207 r
= set_ensure_put(&aux
->notify_transactions
, NULL
, t
);
2209 (void) set_remove(t
->dnssec_transactions
, aux
);
2213 *ret
= TAKE_PTR(aux
);
2217 static int dns_transaction_request_dnssec_rr(DnsTransaction
*t
, DnsResourceKey
*key
) {
2218 _cleanup_(dns_answer_unrefp
) DnsAnswer
*a
= NULL
;
2219 DnsTransaction
*aux
;
2225 /* Try to get the data from the trust anchor */
2226 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, key
, &a
);
2230 r
= dns_answer_extend(&t
->validated_keys
, a
);
2237 /* This didn't work, ask for it via the network/cache then. */
2238 r
= dns_transaction_add_dnssec_transaction(t
, key
, &aux
);
2239 if (r
== -ELOOP
) /* This would result in a cyclic dependency */
2244 if (aux
->state
== DNS_TRANSACTION_NULL
) {
2245 r
= dns_transaction_go(aux
);
2253 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction
*t
, const char *name
) {
2258 /* Check whether the specified name is in the NTA
2259 * database, either in the global one, or the link-local
2262 r
= dns_trust_anchor_lookup_negative(&t
->scope
->manager
->trust_anchor
, name
);
2266 if (!t
->scope
->link
)
2269 return link_negative_trust_anchor_lookup(t
->scope
->link
, name
);
2272 static int dns_transaction_has_negative_answer(DnsTransaction
*t
) {
2277 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
2278 * RRs to prove it */
2280 r
= dns_transaction_has_positive_answer(t
, NULL
);
2286 /* Is this key explicitly listed as a negative trust anchor?
2287 * If so, it's nothing we need to care about */
2288 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
2294 static int dns_transaction_is_primary_response(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2300 /* Check if the specified RR is the "primary" response,
2301 * i.e. either matches the question precisely or is a
2302 * CNAME/DNAME for it. */
2304 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2308 return dns_resource_key_match_cname_or_dname(dns_transaction_key(t
), rr
->key
, NULL
);
2311 static bool dns_transaction_dnssec_supported(DnsTransaction
*t
) {
2314 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2315 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2317 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2320 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2321 * be supported, hence return true. */
2325 /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2326 * the server is known to support currently, as the transaction feature level might be lower than what the
2327 * server actually supports, since we might have downgraded this transaction's feature level because we got a
2328 * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
2330 return dns_server_dnssec_supported(t
->server
);
2333 static bool dns_transaction_dnssec_supported_full(DnsTransaction
*t
) {
2338 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2340 if (!dns_transaction_dnssec_supported(t
))
2343 SET_FOREACH(dt
, t
->dnssec_transactions
)
2344 if (!dns_transaction_dnssec_supported(dt
))
2350 int dns_transaction_request_dnssec_keys(DnsTransaction
*t
) {
2351 DnsResourceRecord
*rr
;
2358 * Retrieve all auxiliary RRs for the answer we got, so that
2359 * we can verify signatures or prove that RRs are rightfully
2360 * unsigned. Specifically:
2362 * - For RRSIG we get the matching DNSKEY
2363 * - For DNSKEY we get the matching DS
2364 * - For unsigned SOA/NS we get the matching DS
2365 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
2366 * - For other unsigned RRs we get the matching SOA RR
2367 * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2368 * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
2369 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2372 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
2374 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
2375 return 0; /* We only need to validate stuff from the network */
2376 if (!dns_transaction_dnssec_supported(t
))
2377 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
2379 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
2381 if (dns_type_is_pseudo(rr
->key
->type
))
2384 /* If this RR is in the negative trust anchor, we don't need to validate it. */
2385 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2391 switch (rr
->key
->type
) {
2393 case DNS_TYPE_RRSIG
: {
2394 /* For each RRSIG we request the matching DNSKEY */
2395 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*dnskey
= NULL
;
2397 /* If this RRSIG is about a DNSKEY RR and the
2398 * signer is the same as the owner, then we
2399 * already have the DNSKEY, and we don't have
2400 * to look for more. */
2401 if (rr
->rrsig
.type_covered
== DNS_TYPE_DNSKEY
) {
2402 r
= dns_name_equal(rr
->rrsig
.signer
, dns_resource_key_name(rr
->key
));
2409 /* If the signer is not a parent of our
2410 * original query, then this is about an
2411 * auxiliary RRset, but not anything we asked
2412 * for. In this case we aren't interested,
2413 * because we don't want to request additional
2414 * RRs for stuff we didn't really ask for, and
2415 * also to avoid request loops, where
2416 * additional RRs from one transaction result
2417 * in another transaction whose additional RRs
2418 * point back to the original transaction, and
2420 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), rr
->rrsig
.signer
);
2426 dnskey
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DNSKEY
, rr
->rrsig
.signer
);
2430 log_debug("Requesting DNSKEY to validate transaction %" PRIu16
" (%s, RRSIG with key tag: %" PRIu16
").",
2431 t
->id
, dns_resource_key_name(rr
->key
), rr
->rrsig
.key_tag
);
2432 r
= dns_transaction_request_dnssec_rr(t
, dnskey
);
2438 case DNS_TYPE_DNSKEY
: {
2439 /* For each DNSKEY we request the matching DS */
2440 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2442 /* If the DNSKEY we are looking at is not for
2443 * zone we are interested in, nor any of its
2444 * parents, we aren't interested, and don't
2445 * request it. After all, we don't want to end
2446 * up in request loops, and want to keep
2447 * additional traffic down. */
2449 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2455 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2459 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, DNSKEY with key tag: %" PRIu16
").",
2460 t
->id
, dns_resource_key_name(rr
->key
), dnssec_keytag(rr
, false));
2461 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2470 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2472 /* For an unsigned SOA or NS, try to acquire
2473 * the matching DS RR, as we are at a zone cut
2474 * then, and whether a DS exists tells us
2475 * whether the zone is signed. Do so only if
2476 * this RR matches our original question,
2479 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2483 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2484 * a negative reply, and we need the SOA RR's TTL in order to cache a negative entry?
2485 * If so, we need to validate it, too. */
2487 r
= dns_answer_match_key(t
->answer
, dns_transaction_key(t
), NULL
);
2490 if (r
> 0) /* positive reply, we won't need the SOA and hence don't need to validate
2494 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
2495 * what we are looking for, otherwise there's no value in it for us. */
2496 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2503 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2509 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2513 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, unsigned SOA/NS RRset).",
2514 t
->id
, dns_resource_key_name(rr
->key
));
2515 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2523 case DNS_TYPE_CNAME
:
2524 case DNS_TYPE_DNAME
: {
2525 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2528 /* CNAMEs and DNAMEs cannot be located at a
2529 * zone apex, hence ask for the parent SOA for
2530 * unsigned CNAME/DNAME RRs, maybe that's the
2531 * apex. But do all that only if this is
2532 * actually a response to our original
2535 * Similar for DS RRs, which are signed when
2536 * the parent SOA is signed. */
2538 r
= dns_transaction_is_primary_response(t
, rr
);
2544 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2550 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
2556 name
= dns_resource_key_name(rr
->key
);
2557 r
= dns_name_parent(&name
);
2563 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, name
);
2567 log_debug("Requesting parent SOA to validate transaction %" PRIu16
" (%s, unsigned CNAME/DNAME/DS RRset).",
2568 t
->id
, dns_resource_key_name(rr
->key
));
2569 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2577 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2579 /* For other unsigned RRsets (including
2580 * NSEC/NSEC3!), look for proof the zone is
2581 * unsigned, by requesting the SOA RR of the
2582 * zone. However, do so only if they are
2583 * directly relevant to our original
2586 r
= dns_transaction_is_primary_response(t
, rr
);
2592 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2598 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, dns_resource_key_name(rr
->key
));
2602 log_debug("Requesting SOA to validate transaction %" PRIu16
" (%s, unsigned non-SOA/NS RRset <%s>).",
2603 t
->id
, dns_resource_key_name(rr
->key
), dns_resource_record_to_string(rr
));
2604 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2611 /* Above, we requested everything necessary to validate what
2612 * we got. Now, let's request what we need to validate what we
2615 r
= dns_transaction_has_negative_answer(t
);
2619 const char *name
, *signed_status
;
2622 name
= dns_resource_key_name(dns_transaction_key(t
));
2623 signed_status
= dns_answer_contains_nsec_or_nsec3(t
->answer
) ? "signed" : "unsigned";
2625 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2626 * could also be used as indication that we are not at a zone apex, but in real world setups there are
2627 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2628 * though they have further children. If this was a DS request, then it's signed when the parent zone
2629 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2630 * to see if that is signed. */
2632 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
2633 r
= dns_name_parent(&name
);
2635 type
= DNS_TYPE_SOA
;
2636 log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty DS response).",
2637 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
,
2638 dns_resource_key_name(dns_transaction_key(t
)), signed_status
);
2642 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
)) {
2645 log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16
" (%s, %s empty SOA/NS response).",
2646 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2649 type
= DNS_TYPE_SOA
;
2650 log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty non-SOA/NS/DS response).",
2651 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2655 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2657 soa
= dns_resource_key_new(dns_transaction_key(t
)->class, type
, name
);
2661 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2667 return dns_transaction_dnssec_is_live(t
);
2670 void dns_transaction_notify(DnsTransaction
*t
, DnsTransaction
*source
) {
2674 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2675 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2676 the state is VALIDATING however, we should check if we are complete now. */
2678 if (t
->state
== DNS_TRANSACTION_VALIDATING
)
2679 dns_transaction_process_dnssec(t
);
2682 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction
*t
) {
2683 DnsAnswerItem
*item
;
2688 /* Add all DNSKEY RRs from the answer that are validated by DS
2689 * RRs from the list of validated keys to the list of
2690 * validated keys. */
2692 DNS_ANSWER_FOREACH_ITEM(item
, t
->answer
) {
2694 r
= dnssec_verify_dnskey_by_ds_search(item
->rr
, t
->validated_keys
);
2700 /* If so, the DNSKEY is validated too. */
2701 r
= dns_answer_add_extend(&t
->validated_keys
, item
->rr
, item
->ifindex
, item
->flags
|DNS_ANSWER_AUTHENTICATED
, item
->rrsig
);
2709 static int dns_transaction_requires_rrsig(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2715 /* Checks if the RR we are looking for must be signed with an
2716 * RRSIG. This is used for positive responses. */
2718 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2721 if (dns_type_is_pseudo(rr
->key
->type
))
2724 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2730 switch (rr
->key
->type
) {
2732 case DNS_TYPE_RRSIG
:
2733 /* RRSIGs are the signatures themselves, they need no signing. */
2740 /* For SOA or NS RRs we look for a matching DS transaction */
2742 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2744 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2746 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_DS
)
2749 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2755 /* We found a DS transactions for the SOA/NS
2756 * RRs we are looking at. If it discovered signed DS
2757 * RRs, then we need to be signed, too. */
2759 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
2762 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
2765 /* We found nothing that proves this is safe to leave
2766 * this unauthenticated, hence ask inist on
2767 * authentication. */
2772 case DNS_TYPE_CNAME
:
2773 case DNS_TYPE_DNAME
: {
2774 const char *parent
= NULL
;
2778 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2780 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2783 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2785 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2787 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2791 parent
= dns_resource_key_name(rr
->key
);
2792 r
= dns_name_parent(&parent
);
2796 if (rr
->key
->type
== DNS_TYPE_DS
)
2799 /* A CNAME/DNAME without a parent? That's sooo weird. */
2800 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG
),
2801 "Transaction %" PRIu16
" claims CNAME/DNAME at root. Refusing.", t
->id
);
2805 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), parent
);
2811 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2820 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2822 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2824 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2826 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2829 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2835 /* We found the transaction that was supposed to find the SOA RR for us. It was
2836 * successful, but found no RR for us. This means we are not at a zone cut. In this
2837 * case, we require authentication if the SOA lookup was authenticated too. */
2838 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2845 static int dns_transaction_in_private_tld(DnsTransaction
*t
, const DnsResourceKey
*key
) {
2850 /* If DNSSEC downgrade mode is on, checks whether the
2851 * specified RR is one level below a TLD we have proven not to
2852 * exist. In such a case we assume that this is a private
2853 * domain, and permit it.
2855 * This detects cases like the Fritz!Box router networks. Each
2856 * Fritz!Box router serves a private "fritz.box" zone, in the
2857 * non-existing TLD "box". Requests for the "fritz.box" domain
2858 * are served by the router itself, while requests for the
2859 * "box" domain will result in NXDOMAIN.
2861 * Note that this logic is unable to detect cases where a
2862 * router serves a private DNS zone directly under
2863 * non-existing TLD. In such a case we cannot detect whether
2864 * the TLD is supposed to exist or not, as all requests we
2865 * make for it will be answered by the router's zone, and not
2866 * by the root zone. */
2870 if (t
->scope
->dnssec_mode
!= DNSSEC_ALLOW_DOWNGRADE
)
2871 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2873 tld
= dns_resource_key_name(key
);
2874 r
= dns_name_parent(&tld
);
2878 return false; /* Already the root domain */
2880 if (!dns_name_is_single_label(tld
))
2883 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2885 if (dns_transaction_key(dt
)->class != key
->class)
2888 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), tld
);
2894 /* We found an auxiliary lookup we did for the TLD. If
2895 * that returned with NXDOMAIN, we know the TLD didn't
2896 * exist, and hence this might be a private zone. */
2898 return dt
->answer_rcode
== DNS_RCODE_NXDOMAIN
;
2904 static int dns_transaction_requires_nsec(DnsTransaction
*t
) {
2905 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
2913 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2914 * this negative reply */
2916 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2919 if (dns_type_is_pseudo(dns_transaction_key(t
)->type
))
2922 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
2928 r
= dns_transaction_in_private_tld(t
, dns_transaction_key(t
));
2932 /* The lookup is from a TLD that is proven not to
2933 * exist, and we are in downgrade mode, hence ignore
2934 * that fact that we didn't get any NSEC RRs. */
2936 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2937 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
2941 name
= dns_resource_key_name(dns_transaction_key(t
));
2943 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
2945 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
2946 * hence check the parent SOA in this case. */
2948 r
= dns_name_parent(&name
);
2954 type
= DNS_TYPE_SOA
;
2956 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
))
2957 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
2960 /* For all other negative replies, check for the SOA lookup */
2961 type
= DNS_TYPE_SOA
;
2963 /* For all other RRs we check the SOA on the same level to see
2964 * if it's signed. */
2966 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2968 if (dns_transaction_key(dt
)->class != dns_transaction_key(t
)->class)
2970 if (dns_transaction_key(dt
)->type
!= type
)
2973 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), name
);
2979 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2982 /* If in doubt, require NSEC/NSEC3 */
2986 static int dns_transaction_dnskey_authenticated(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2987 DnsResourceRecord
*rrsig
;
2991 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2992 * the specified RRset is authenticated (i.e. has a matching
2995 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
3001 DNS_ANSWER_FOREACH(rrsig
, t
->answer
) {
3004 r
= dnssec_key_match_rrsig(rr
->key
, rrsig
);
3010 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3012 if (dns_transaction_key(dt
)->class != rr
->key
->class)
3015 if (dns_transaction_key(dt
)->type
== DNS_TYPE_DNSKEY
) {
3017 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
3023 /* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated,
3026 if (FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3031 } else if (dns_transaction_key(dt
)->type
== DNS_TYPE_DS
) {
3033 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
3039 /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
3040 * non-zero, we won! */
3042 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3045 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
3050 return found
? false : -ENXIO
;
3053 static int dns_transaction_known_signed(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
3057 /* We know that the root domain is signed, hence if it appears
3058 * not to be signed, there's a problem with the DNS server */
3060 return rr
->key
->class == DNS_CLASS_IN
&&
3061 dns_name_is_root(dns_resource_key_name(rr
->key
));
3064 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction
*t
) {
3065 DnsResourceRecord
*rr
;
3070 /* Maybe warn the user that we encountered a revoked DNSKEY
3071 * for a key from our trust anchor. Note that we don't care
3072 * whether the DNSKEY can be authenticated or not. It's
3073 * sufficient if it is self-signed. */
3075 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3076 r
= dns_trust_anchor_check_revoked(&t
->scope
->manager
->trust_anchor
, rr
, t
->answer
);
3084 static int dns_transaction_invalidate_revoked_keys(DnsTransaction
*t
) {
3090 /* Removes all DNSKEY/DS objects from t->validated_keys that
3091 * our trust anchors database considers revoked. */
3094 DnsResourceRecord
*rr
;
3098 DNS_ANSWER_FOREACH(rr
, t
->validated_keys
) {
3099 r
= dns_trust_anchor_is_revoked(&t
->scope
->manager
->trust_anchor
, rr
);
3103 r
= dns_answer_remove_by_rr(&t
->validated_keys
, rr
);
3117 static int dns_transaction_copy_validated(DnsTransaction
*t
) {
3123 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
3125 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3127 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
3130 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3133 r
= dns_answer_extend(&t
->validated_keys
, dt
->answer
);
3142 DNSSEC_PHASE_DNSKEY
, /* Phase #1, only validate DNSKEYs */
3143 DNSSEC_PHASE_NSEC
, /* Phase #2, only validate NSEC+NSEC3 */
3144 DNSSEC_PHASE_ALL
, /* Phase #3, validate everything else */
3147 static int dnssec_validate_records(
3151 DnsAnswer
**validated
) {
3153 DnsResourceRecord
*rr
;
3156 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
3158 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3159 _unused_
_cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr_ref
= dns_resource_record_ref(rr
);
3160 DnsResourceRecord
*rrsig
= NULL
;
3161 DnssecResult result
;
3163 switch (rr
->key
->type
) {
3164 case DNS_TYPE_RRSIG
:
3167 case DNS_TYPE_DNSKEY
:
3168 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
3169 if (phase
== DNSSEC_PHASE_NSEC
)
3174 case DNS_TYPE_NSEC3
:
3177 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
3178 if (phase
== DNSSEC_PHASE_DNSKEY
)
3183 /* We validate all other RRs only in the ALL phases */
3184 if (phase
!= DNSSEC_PHASE_ALL
)
3188 r
= dnssec_verify_rrset_search(
3198 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr
)), dnssec_result_to_string(result
));
3200 if (result
== DNSSEC_VALIDATED
) {
3203 if (rr
->key
->type
== DNS_TYPE_DNSKEY
) {
3204 /* If we just validated a DNSKEY RRset, then let's add these keys to
3205 * the set of validated keys for this transaction. */
3207 r
= dns_answer_copy_by_key(&t
->validated_keys
, t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
, rrsig
);
3211 /* Some of the DNSKEYs we just added might already have been revoked,
3212 * remove them again in that case. */
3213 r
= dns_transaction_invalidate_revoked_keys(t
);
3218 /* Add the validated RRset to the new list of validated RRsets, and remove it from
3219 * the unvalidated RRsets. We mark the RRset as authenticated and cacheable. */
3220 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
, rrsig
);
3224 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_SECURE
, rr
->key
);
3226 /* Exit the loop, we dropped something from the answer, start from the beginning */
3230 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
3231 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
3232 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
3233 if (phase
!= DNSSEC_PHASE_ALL
)
3236 if (result
== DNSSEC_VALIDATED_WILDCARD
) {
3237 bool authenticated
= false;
3242 /* This RRset validated, but as a wildcard. This means we need
3243 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
3245 /* First step, determine the source of synthesis */
3246 r
= dns_resource_record_source(rrsig
, &source
);
3250 r
= dnssec_test_positive_wildcard(*validated
,
3251 dns_resource_key_name(rr
->key
),
3253 rrsig
->rrsig
.signer
,
3256 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
3258 result
= DNSSEC_INVALID
;
3260 r
= dns_answer_move_by_key(
3264 authenticated
? (DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
) : 0,
3269 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, rr
->key
);
3271 /* Exit the loop, we dropped something from the answer, start from the beginning */
3276 if (result
== DNSSEC_NO_SIGNATURE
) {
3277 r
= dns_transaction_requires_rrsig(t
, rr
);
3281 /* Data does not require signing. In that case, just copy it over,
3282 * but remember that this is by no means authenticated. */
3283 r
= dns_answer_move_by_key(
3292 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3296 r
= dns_transaction_known_signed(t
, rr
);
3300 /* This is an RR we know has to be signed. If it isn't this means
3301 * the server is not attaching RRSIGs, hence complain. */
3303 dns_server_packet_rrsig_missing(t
->server
, t
->current_feature_level
);
3305 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
3307 /* Downgrading is OK? If so, just consider the information unsigned */
3309 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3313 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3317 /* Otherwise, fail */
3318 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3322 r
= dns_transaction_in_private_tld(t
, rr
->key
);
3326 char s
[DNS_RESOURCE_KEY_STRING_MAX
];
3328 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3329 * mode, hence ignore the fact that this was not signed. */
3331 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3332 dns_resource_key_to_string(rr
->key
, s
, sizeof s
));
3334 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3338 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3343 /* https://datatracker.ietf.org/doc/html/rfc6840#section-5.2 */
3344 if (result
== DNSSEC_UNSUPPORTED_ALGORITHM
) {
3345 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3349 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3355 DNSSEC_SIGNATURE_EXPIRED
)) {
3357 r
= dns_transaction_dnskey_authenticated(t
, rr
);
3358 if (r
< 0 && r
!= -ENXIO
)
3361 /* The DNSKEY transaction was not authenticated, this means there's
3362 * no DS for this, which means it's OK if no keys are found for this signature. */
3364 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3368 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3373 r
= dns_transaction_is_primary_response(t
, rr
);
3377 /* Look for a matching DNAME for this CNAME */
3378 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
3382 /* Also look among the stuff we already validated */
3383 r
= dns_answer_has_dname_for_cname(*validated
, rr
);
3391 DNSSEC_SIGNATURE_EXPIRED
,
3392 DNSSEC_NO_SIGNATURE
))
3393 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, rr
->key
);
3394 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3395 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, rr
->key
);
3397 /* This is a primary response to our question, and it failed validation.
3399 t
->answer_dnssec_result
= result
;
3403 /* This is a primary response, but we do have a DNAME RR
3404 * in the RR that can replay this CNAME, hence rely on
3405 * that, and we can remove the CNAME in favour of it. */
3408 /* This is just some auxiliary data. Just remove the RRset and continue. */
3409 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
3413 /* We dropped something from the answer, start from the beginning. */
3417 return 2; /* Finito. */
3420 int dns_transaction_validate_dnssec(DnsTransaction
*t
) {
3421 _cleanup_(dns_answer_unrefp
) DnsAnswer
*validated
= NULL
;
3423 DnsAnswerFlags flags
;
3425 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
3429 /* We have now collected all DS and DNSKEY RRs in t->validated_keys, let's see which RRs we can now
3430 * authenticate with that. */
3432 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
3435 /* Already validated */
3436 if (t
->answer_dnssec_result
!= _DNSSEC_RESULT_INVALID
)
3439 /* Our own stuff needs no validation */
3440 if (IN_SET(t
->answer_source
, DNS_TRANSACTION_ZONE
, DNS_TRANSACTION_TRUST_ANCHOR
)) {
3441 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3442 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3446 /* Cached stuff is not affected by validation. */
3447 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
3450 if (!dns_transaction_dnssec_supported_full(t
)) {
3451 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3452 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3453 log_debug("Not validating response for %" PRIu16
", used server feature level does not support DNSSEC.", t
->id
);
3457 log_debug("Validating response from transaction %" PRIu16
" (%s).",
3459 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
3461 /* First, see if this response contains any revoked trust
3462 * anchors we care about */
3463 r
= dns_transaction_check_revoked_trust_anchors(t
);
3467 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3468 r
= dns_transaction_copy_validated(t
);
3472 /* Second, see if there are DNSKEYs we already know a
3473 * validated DS for. */
3474 r
= dns_transaction_validate_dnskey_by_ds(t
);
3478 /* Fourth, remove all DNSKEY and DS RRs again that our trust
3479 * anchor says are revoked. After all we might have marked
3480 * some keys revoked above, but they might still be lingering
3481 * in our validated_keys list. */
3482 r
= dns_transaction_invalidate_revoked_keys(t
);
3486 phase
= DNSSEC_PHASE_DNSKEY
;
3488 bool have_nsec
= false;
3490 r
= dnssec_validate_records(t
, phase
, &have_nsec
, &validated
);
3494 /* Try again as long as we managed to achieve something */
3498 if (phase
== DNSSEC_PHASE_DNSKEY
&& have_nsec
) {
3499 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
3500 phase
= DNSSEC_PHASE_NSEC
;
3504 if (phase
!= DNSSEC_PHASE_ALL
) {
3505 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3506 * Note that in this third phase we start to remove RRs we couldn't validate. */
3507 phase
= DNSSEC_PHASE_ALL
;
3515 DNS_ANSWER_REPLACE(t
->answer
, TAKE_PTR(validated
));
3517 /* At this point the answer only contains validated
3518 * RRsets. Now, let's see if it actually answers the question
3519 * we asked. If so, great! If it doesn't, then see if
3520 * NSEC/NSEC3 can prove this. */
3521 r
= dns_transaction_has_positive_answer(t
, &flags
);
3523 /* Yes, it answers the question! */
3525 if (flags
& DNS_ANSWER_AUTHENTICATED
) {
3526 /* The answer is fully authenticated, yay. */
3527 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3528 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3529 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3531 /* The answer is not fully authenticated. */
3532 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3533 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3536 } else if (r
== 0) {
3537 DnssecNsecResult nr
;
3538 bool authenticated
= false;
3540 /* Bummer! Let's check NSEC/NSEC3 */
3541 r
= dnssec_nsec_test(t
->answer
, dns_transaction_key(t
), &nr
, &authenticated
, &t
->answer_nsec_ttl
);
3547 case DNSSEC_NSEC_NXDOMAIN
:
3548 /* NSEC proves the domain doesn't exist. Very good. */
3549 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3550 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3551 t
->answer_rcode
= DNS_RCODE_NXDOMAIN
;
3552 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3554 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3557 case DNSSEC_NSEC_NODATA
:
3558 /* NSEC proves that there's no data here, very good. */
3559 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3560 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3561 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3562 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3564 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3567 case DNSSEC_NSEC_OPTOUT
:
3568 /* NSEC3 says the data might not be signed */
3569 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3570 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3571 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3573 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3576 case DNSSEC_NSEC_NO_RR
:
3577 /* No NSEC data? Bummer! */
3579 r
= dns_transaction_requires_nsec(t
);
3583 t
->answer_dnssec_result
= DNSSEC_NO_SIGNATURE
;
3584 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3586 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3587 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3588 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3593 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM
:
3594 /* We don't know the NSEC3 algorithm used? */
3595 t
->answer_dnssec_result
= DNSSEC_UNSUPPORTED_ALGORITHM
;
3596 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, dns_transaction_key(t
));
3599 case DNSSEC_NSEC_FOUND
:
3600 case DNSSEC_NSEC_CNAME
:
3601 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
3602 t
->answer_dnssec_result
= DNSSEC_NSEC_MISMATCH
;
3603 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3607 assert_not_reached();
3614 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
3615 [DNS_TRANSACTION_NULL
] = "null",
3616 [DNS_TRANSACTION_PENDING
] = "pending",
3617 [DNS_TRANSACTION_VALIDATING
] = "validating",
3618 [DNS_TRANSACTION_RCODE_FAILURE
] = "rcode-failure",
3619 [DNS_TRANSACTION_SUCCESS
] = "success",
3620 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
3621 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
3622 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
3623 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
3624 [DNS_TRANSACTION_ERRNO
] = "errno",
3625 [DNS_TRANSACTION_ABORTED
] = "aborted",
3626 [DNS_TRANSACTION_DNSSEC_FAILED
] = "dnssec-failed",
3627 [DNS_TRANSACTION_NO_TRUST_ANCHOR
] = "no-trust-anchor",
3628 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
] = "rr-type-unsupported",
3629 [DNS_TRANSACTION_NETWORK_DOWN
] = "network-down",
3630 [DNS_TRANSACTION_NOT_FOUND
] = "not-found",
3631 [DNS_TRANSACTION_NO_SOURCE
] = "no-source",
3632 [DNS_TRANSACTION_STUB_LOOP
] = "stub-loop",
3634 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);
3636 static const char* const dns_transaction_source_table
[_DNS_TRANSACTION_SOURCE_MAX
] = {
3637 [DNS_TRANSACTION_NETWORK
] = "network",
3638 [DNS_TRANSACTION_CACHE
] = "cache",
3639 [DNS_TRANSACTION_ZONE
] = "zone",
3640 [DNS_TRANSACTION_TRUST_ANCHOR
] = "trust-anchor",
3642 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source
, DnsTransactionSource
);