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 usecase for caching them
820 * is "bypass" mode which is only
821 * enabled for CD packets. */
822 t
->answer_query_flags
,
823 t
->answer_dnssec_result
,
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 /* Note that this call might invalidate the query. Callers
1043 * should hence not attempt to access the query or transaction
1044 * after calling this function. */
1046 log_debug("Processing incoming packet of size %zu on transaction %" PRIu16
" (rcode=%s).",
1048 t
->id
, FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1050 switch (t
->scope
->protocol
) {
1052 case DNS_PROTOCOL_LLMNR
:
1053 /* For LLMNR we will not accept any packets from other interfaces */
1055 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1058 if (p
->family
!= t
->scope
->family
)
1061 /* Tentative packets are not full responses but still
1062 * useful for identifying uniqueness conflicts during
1064 if (DNS_PACKET_LLMNR_T(p
)) {
1065 dns_transaction_tentative(t
, p
);
1071 case DNS_PROTOCOL_MDNS
:
1072 /* For mDNS we will not accept any packets from other interfaces */
1074 if (p
->ifindex
!= dns_scope_ifindex(t
->scope
))
1077 if (p
->family
!= t
->scope
->family
)
1082 case DNS_PROTOCOL_DNS
:
1083 /* Note that we do not need to verify the
1084 * addresses/port numbers of incoming traffic, as we
1085 * invoked connect() on our UDP socket in which case
1086 * the kernel already does the needed verification for
1091 assert_not_reached();
1094 if (t
->received
!= p
)
1095 DNS_PACKET_REPLACE(t
->received
, dns_packet_ref(p
));
1097 t
->answer_source
= DNS_TRANSACTION_NETWORK
;
1099 if (p
->ipproto
== IPPROTO_TCP
) {
1100 if (DNS_PACKET_TC(p
)) {
1101 /* Truncated via TCP? Somebody must be fucking with us */
1102 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1106 if (DNS_PACKET_ID(p
) != t
->id
) {
1107 /* Not the reply to our query? Somebody must be fucking with us */
1108 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1113 switch (t
->scope
->protocol
) {
1115 case DNS_PROTOCOL_DNS
:
1119 IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_FORMERR
, DNS_RCODE_SERVFAIL
, DNS_RCODE_NOTIMP
)) {
1121 /* Request failed, immediately try again with reduced features */
1123 if (t
->current_feature_level
<= DNS_SERVER_FEATURE_LEVEL_UDP
) {
1125 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
1126 * this transaction anymore, but let's see if it might make sense to send the request
1127 * to a different DNS server instead. If not let's process the response, and accept the
1128 * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1129 * packet loss, but is not going to give us better rcodes should we actually have
1130 * managed to get them already at UDP level. */
1132 if (dns_transaction_limited_retry(t
))
1135 /* Give up, accept the rcode */
1136 log_debug("Server returned error: %s", FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1140 /* SERVFAIL can happen for many reasons and may be transient.
1141 * To avoid unnecessary downgrades retry once with the initial level.
1142 * Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
1143 * first attempt to downgrade. If so, clamp to the current value so that the transaction
1144 * is retried without actually downgrading. If the next try also fails we will downgrade by
1145 * hitting the else branch below. */
1146 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_SERVFAIL
&&
1147 t
->clamp_feature_level_servfail
< 0) {
1148 t
->clamp_feature_level_servfail
= t
->current_feature_level
;
1149 log_debug("Server returned error %s, retrying transaction.",
1150 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)));
1152 /* Reduce this feature level by one and try again. */
1153 switch (t
->current_feature_level
) {
1154 case DNS_SERVER_FEATURE_LEVEL_TLS_DO
:
1155 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
;
1157 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
+ 1:
1158 /* Skip plain TLS when TLS is not supported */
1159 t
->clamp_feature_level_servfail
= DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN
- 1;
1162 t
->clamp_feature_level_servfail
= t
->current_feature_level
- 1;
1165 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1166 FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p
)),
1167 dns_server_feature_level_to_string(t
->clamp_feature_level_servfail
));
1170 dns_transaction_retry(t
, false /* use the same server */);
1174 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_REFUSED
) {
1175 /* This server refused our request? If so, try again, use a different server */
1176 log_debug("Server returned REFUSED, switching servers, and retrying.");
1178 if (dns_transaction_limited_retry(t
))
1184 if (DNS_PACKET_TC(p
))
1185 dns_server_packet_truncated(t
->server
, t
->current_feature_level
);
1189 case DNS_PROTOCOL_LLMNR
:
1190 case DNS_PROTOCOL_MDNS
:
1191 dns_scope_packet_received(t
->scope
, p
->timestamp
- t
->start_usec
);
1195 assert_not_reached();
1198 if (DNS_PACKET_TC(p
)) {
1200 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1201 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
) {
1202 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1206 /* Response was truncated, let's try again with good old TCP */
1207 log_debug("Reply truncated, retrying via TCP.");
1208 retry_with_tcp
= true;
1210 } else if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1211 DNS_PACKET_IS_FRAGMENTED(p
)) {
1213 /* Report the fragment size, so that we downgrade from LARGE to regular EDNS0 if needed */
1215 dns_server_packet_udp_fragmented(t
->server
, dns_packet_size_unfragmented(p
));
1217 if (t
->current_feature_level
> DNS_SERVER_FEATURE_LEVEL_UDP
) {
1218 /* Packet was fragmented. Let's retry with TCP to avoid fragmentation attack
1219 * issues. (We don't do that on the lowest feature level however, since crappy DNS
1220 * servers often do not implement TCP, hence falling back to TCP on fragmentation is
1221 * counter-productive there.) */
1223 log_debug("Reply fragmented, retrying via TCP. (Largest fragment size: %zu; Datagram size: %zu)",
1224 p
->fragsize
, p
->size
);
1225 retry_with_tcp
= true;
1229 if (retry_with_tcp
) {
1230 r
= dns_transaction_emit_tcp(t
);
1232 /* No servers found? Damn! */
1233 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1236 if (r
== -EOPNOTSUPP
) {
1237 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1238 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
1242 /* On LLMNR, if we cannot connect to the host,
1243 * we immediately give up */
1244 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1247 /* On DNS, couldn't send? Try immediately again, with a new server */
1248 if (dns_transaction_limited_retry(t
))
1251 /* No new server to try, give up */
1252 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1258 /* After the superficial checks, actually parse the message. */
1259 r
= dns_packet_extract(p
);
1262 dns_server_packet_invalid(t
->server
, t
->current_feature_level
);
1264 r
= dns_transaction_maybe_restart(t
);
1267 if (r
> 0) /* Transaction got restarted... */
1271 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1276 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1277 * rcode and subsequently downgraded the protocol */
1279 if (IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_SUCCESS
, DNS_RCODE_NXDOMAIN
) &&
1280 t
->clamp_feature_level_servfail
!= _DNS_SERVER_FEATURE_LEVEL_INVALID
)
1281 dns_server_packet_rcode_downgrade(t
->server
, t
->clamp_feature_level_servfail
);
1283 /* Report that the OPT RR was missing */
1285 dns_server_packet_bad_opt(t
->server
, t
->current_feature_level
);
1287 /* Report that the server didn't copy our query DO bit from request to response */
1288 if (DNS_PACKET_DO(t
->sent
) && !DNS_PACKET_DO(t
->received
))
1289 dns_server_packet_do_off(t
->server
, t
->current_feature_level
);
1291 /* Report that we successfully received a packet. We keep track of the largest packet
1292 * size/fragment size we got. Which is useful for announcing the EDNS(0) packet size we can
1293 * receive to our server. */
1294 dns_server_packet_received(t
->server
, p
->ipproto
, t
->current_feature_level
, dns_packet_size_unfragmented(p
));
1297 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1298 r
= dns_transaction_maybe_restart(t
);
1301 if (r
> 0) /* Transaction got restarted... */
1304 /* When dealing with protocols other than mDNS only consider responses with equivalent query section
1305 * to the request. For mDNS this check doesn't make sense, because the section 6 of RFC6762 states
1306 * that "Multicast DNS responses MUST NOT contain any questions in the Question Section". */
1307 if (t
->scope
->protocol
!= DNS_PROTOCOL_MDNS
) {
1308 r
= dns_packet_is_reply_for(p
, dns_transaction_key(t
));
1312 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
1317 /* Install the answer as answer to the transaction. We ref the answer twice here: the main `answer`
1318 * field is later replaced by the DNSSEC validated subset. The 'answer_auxiliary' field carries the
1319 * original complete record set, including RRSIG and friends. We use this when passing data to
1320 * clients that ask for DNSSEC metadata. */
1321 DNS_ANSWER_REPLACE(t
->answer
, dns_answer_ref(p
->answer
));
1322 t
->answer_rcode
= DNS_PACKET_RCODE(p
);
1323 t
->answer_dnssec_result
= _DNSSEC_RESULT_INVALID
;
1324 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1325 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, encrypted
);
1327 r
= dns_transaction_fix_rcode(t
);
1331 /* Block GC while starting requests for additional DNSSEC RRs */
1333 r
= dns_transaction_request_dnssec_keys(t
);
1336 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1337 if (!dns_transaction_gc(t
))
1340 /* Requesting additional keys might have resulted in this transaction to fail, since the auxiliary
1341 * request failed for some reason. If so, we are not in pending state anymore, and we should exit
1343 if (t
->state
!= DNS_TRANSACTION_PENDING
)
1348 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1349 t
->state
= DNS_TRANSACTION_VALIDATING
;
1350 dns_transaction_close_connection(t
, true);
1351 dns_transaction_stop_timeout(t
);
1355 dns_transaction_process_dnssec(t
);
1359 dns_transaction_complete_errno(t
, r
);
1362 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1363 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1364 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1369 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
1370 if (ERRNO_IS_DISCONNECT(r
)) {
1373 /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
1374 * next recvmsg(). Treat this like a lost packet. */
1376 log_debug_errno(r
, "Connection failure for DNS UDP packet: %m");
1377 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &usec
) >= 0);
1378 dns_server_packet_lost(t
->server
, IPPROTO_UDP
, t
->current_feature_level
);
1380 dns_transaction_close_connection(t
, /* use_graveyard = */ false);
1382 if (dns_transaction_limited_retry(t
)) /* Try a different server */
1385 dns_transaction_complete_errno(t
, r
);
1389 dns_transaction_complete_errno(t
, r
);
1393 /* Spurious wakeup without any data */
1396 r
= dns_packet_validate_reply(p
);
1398 log_debug_errno(r
, "Received invalid DNS packet as response, ignoring: %m");
1402 log_debug("Received inappropriate DNS packet as response, ignoring.");
1406 if (DNS_PACKET_ID(p
) != t
->id
) {
1407 log_debug("Received packet with incorrect transaction ID, ignoring.");
1411 dns_transaction_process_reply(t
, p
, false);
1415 static int dns_transaction_emit_udp(DnsTransaction
*t
) {
1420 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
) {
1422 r
= dns_transaction_pick_server(t
);
1426 if (manager_server_is_stub(t
->scope
->manager
, t
->server
))
1429 if (t
->current_feature_level
< DNS_SERVER_FEATURE_LEVEL_UDP
|| DNS_SERVER_FEATURE_LEVEL_IS_TLS(t
->current_feature_level
))
1430 return -EAGAIN
; /* Sorry, can't do UDP, try TCP! */
1432 if (!t
->bypass
&& !dns_server_dnssec_supported(t
->server
) && dns_type_is_dnssec(dns_transaction_key(t
)->type
))
1435 if (r
> 0 || t
->dns_udp_fd
< 0) { /* Server changed, or no connection yet. */
1438 dns_transaction_close_connection(t
, true);
1440 /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */
1441 manager_socket_graveyard_process(t
->scope
->manager
);
1443 fd
= dns_scope_socket_udp(t
->scope
, t
->server
);
1447 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
1453 (void) sd_event_source_set_description(t
->dns_udp_event_source
, "dns-transaction-udp");
1458 r
= dns_server_adjust_opt(t
->server
, t
->sent
, t
->current_feature_level
);
1463 dns_transaction_close_connection(t
, true);
1465 r
= dns_scope_emit_udp(t
->scope
, t
->dns_udp_fd
, t
->server
? t
->server
->family
: AF_UNSPEC
, t
->sent
);
1469 dns_transaction_reset_answer(t
);
1474 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1475 DnsTransaction
*t
= ASSERT_PTR(userdata
);
1479 if (t
->initial_jitter_scheduled
&& !t
->initial_jitter_elapsed
) {
1480 log_debug("Initial jitter phase for transaction %" PRIu16
" elapsed.", t
->id
);
1481 t
->initial_jitter_elapsed
= true;
1483 /* Timeout reached? Increase the timeout for the server used */
1484 switch (t
->scope
->protocol
) {
1486 case DNS_PROTOCOL_DNS
:
1488 dns_server_packet_lost(t
->server
, t
->stream
? IPPROTO_TCP
: IPPROTO_UDP
, t
->current_feature_level
);
1491 case DNS_PROTOCOL_LLMNR
:
1492 case DNS_PROTOCOL_MDNS
:
1493 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
1497 assert_not_reached();
1500 log_debug("Timeout reached on transaction %" PRIu16
".", t
->id
);
1503 dns_transaction_retry(t
, /* next_server= */ true); /* try a different server, but given this means
1504 * packet loss, let's do so even if we already
1509 static int dns_transaction_setup_timeout(
1511 usec_t timeout_usec
/* relative */,
1512 usec_t next_usec
/* CLOCK_BOOTTIME */) {
1518 dns_transaction_stop_timeout(t
);
1520 r
= sd_event_add_time_relative(
1521 t
->scope
->manager
->event
,
1522 &t
->timeout_event_source
,
1525 on_transaction_timeout
, t
);
1529 (void) sd_event_source_set_description(t
->timeout_event_source
, "dns-transaction-timeout");
1531 t
->next_attempt_after
= next_usec
;
1532 t
->state
= DNS_TRANSACTION_PENDING
;
1536 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
1540 switch (t
->scope
->protocol
) {
1542 case DNS_PROTOCOL_DNS
:
1544 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1545 * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1548 return TRANSACTION_TCP_TIMEOUT_USEC
;
1550 return DNS_TIMEOUT_USEC
;
1552 case DNS_PROTOCOL_MDNS
:
1554 return MDNS_PROBING_INTERVAL_USEC
;
1556 /* See RFC 6762 Section 5.1 suggests that timeout should be a few seconds. */
1557 assert(t
->n_attempts
> 0);
1558 return (1 << (t
->n_attempts
- 1)) * USEC_PER_SEC
;
1560 case DNS_PROTOCOL_LLMNR
:
1561 return t
->scope
->resend_timeout
;
1564 assert_not_reached();
1568 static void dns_transaction_randomize_answer(DnsTransaction
*t
) {
1573 /* Randomizes the order of the answer array. This is done for all cached responses, so that we return
1574 * a different order each time. We do this only for DNS traffic, in order to do some minimal, crappy
1575 * load balancing. We don't do this for LLMNR or mDNS, since the order (preferring link-local
1576 * addresses, and such like) might have meaning there, and load balancing is pointless. */
1578 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
1581 /* No point in randomizing, if there's just one RR */
1582 if (dns_answer_size(t
->answer
) <= 1)
1585 r
= dns_answer_reserve_or_clone(&t
->answer
, 0);
1586 if (r
< 0) /* If this fails, just don't randomize, this is non-essential stuff after all */
1587 return (void) log_debug_errno(r
, "Failed to clone answer record, not randomizing RR order of answer: %m");
1589 dns_answer_randomize(t
->answer
);
1592 static int dns_transaction_prepare(DnsTransaction
*t
, usec_t ts
) {
1597 /* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
1598 * candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
1599 * has been prepared. */
1601 dns_transaction_stop_timeout(t
);
1603 if (!dns_scope_network_good(t
->scope
)) {
1604 dns_transaction_complete(t
, DNS_TRANSACTION_NETWORK_DOWN
);
1608 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
1609 DnsTransactionState result
;
1611 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
)
1612 /* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
1614 result
= DNS_TRANSACTION_NOT_FOUND
;
1616 result
= DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
;
1618 dns_transaction_complete(t
, result
);
1622 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& t
->tried_stream
) {
1623 /* If we already tried via a stream, then we don't
1624 * retry on LLMNR. See RFC 4795, Section 2.7. */
1625 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
1632 dns_transaction_reset_answer(t
);
1633 dns_transaction_flush_dnssec_transactions(t
);
1635 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1636 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&&
1637 !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_TRUST_ANCHOR
)) {
1638 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, dns_transaction_key(t
), &t
->answer
);
1642 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1643 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1644 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1645 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1649 if (dns_name_is_root(dns_resource_key_name(dns_transaction_key(t
))) &&
1650 dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
1652 /* Hmm, this is a request for the root DS? A DS RR doesn't exist in the root zone,
1653 * and if our trust anchor didn't know it either, this means we cannot do any DNSSEC
1656 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
1657 /* We are in downgrade mode. In this case, synthesize an unsigned empty
1658 * response, so that the any lookup depending on this one can continue
1659 * assuming there was no DS, and hence the root zone was unsigned. */
1661 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1662 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
1663 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
1664 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_CONFIDENTIAL
, true);
1665 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1667 /* If we are not in downgrade mode, then fail the lookup, because we cannot
1668 * reasonably answer it. There might be DS RRs, but we don't know them, and
1669 * the DNS server won't tell them to us (and even if it would, we couldn't
1670 * validate and trust them. */
1671 dns_transaction_complete(t
, DNS_TRANSACTION_NO_TRUST_ANCHOR
);
1677 /* Check the zone. */
1678 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_ZONE
)) {
1679 r
= dns_zone_lookup(&t
->scope
->zone
, dns_transaction_key(t
), dns_scope_ifindex(t
->scope
), &t
->answer
, NULL
, NULL
);
1683 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
1684 t
->answer_source
= DNS_TRANSACTION_ZONE
;
1685 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
|SD_RESOLVED_CONFIDENTIAL
, true);
1686 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1691 /* Check the cache. */
1692 if (!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_CACHE
)) {
1694 /* Before trying the cache, let's make sure we figured out a server to use. Should this cause
1695 * a change of server this might flush the cache. */
1696 (void) dns_scope_get_dns_server(t
->scope
);
1698 /* Let's then prune all outdated entries */
1699 dns_cache_prune(&t
->scope
->cache
);
1701 /* For the initial attempt or when no stale data is requested, disable serve stale
1702 * and answer the question from the cache (honors ttl property).
1703 * On the second attempt, if StaleRetentionSec is greater than zero,
1704 * try to answer the question using stale date (honors until property) */
1705 uint64_t query_flags
= t
->query_flags
;
1706 if (t
->n_attempts
== 1 || t
->scope
->manager
->stale_retention_usec
== 0)
1707 query_flags
|= SD_RESOLVED_NO_STALE
;
1709 r
= dns_cache_lookup(
1711 dns_transaction_key(t
),
1716 &t
->answer_query_flags
,
1717 &t
->answer_dnssec_result
);
1721 dns_transaction_randomize_answer(t
);
1723 if (t
->bypass
&& t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->received
)
1724 /* When bypass mode is on, do not use cached data unless it came with a full
1726 dns_transaction_reset_answer(t
);
1728 if (t
->n_attempts
> 1 && !FLAGS_SET(query_flags
, SD_RESOLVED_NO_STALE
)) {
1729 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
1730 log_debug("Serve Stale response rcode=%s for %s",
1731 FORMAT_DNS_RCODE(t
->answer_rcode
),
1732 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
1735 t
->answer_source
= DNS_TRANSACTION_CACHE
;
1736 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
1737 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
1739 dns_transaction_complete(t
, DNS_TRANSACTION_RCODE_FAILURE
);
1745 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_NETWORK
)) {
1746 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SOURCE
);
1753 static int dns_packet_append_zone(DnsPacket
*p
, DnsTransaction
*t
, DnsResourceKey
*k
, unsigned *nscount
) {
1754 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1762 if (k
->type
!= DNS_TYPE_ANY
)
1765 r
= dns_zone_lookup(&t
->scope
->zone
, k
, t
->scope
->link
->ifindex
, &answer
, NULL
, &tentative
);
1769 return dns_packet_append_answer(p
, answer
, nscount
);
1772 static int dns_transaction_make_packet_mdns(DnsTransaction
*t
) {
1773 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1774 _cleanup_set_free_ Set
*keys
= NULL
;
1775 unsigned qdcount
, ancount
= 0 /* avoid false maybe-uninitialized warning */, nscount
;
1776 bool add_known_answers
= false;
1781 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
1783 /* Discard any previously prepared packet, so we can start over and coalesce again */
1784 t
->sent
= dns_packet_unref(t
->sent
);
1786 /* First, create a dummy packet to calculate packet size. */
1787 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
1791 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
1797 if (dns_key_is_shared(dns_transaction_key(t
)))
1798 add_known_answers
= true;
1800 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(t
), NULL
);
1804 /* Save appended keys */
1805 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(t
));
1810 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1811 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1812 * in our current scope, and see whether their timing constraints allow them to be sent.
1815 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
1817 for (bool restart
= true; restart
;) {
1819 LIST_FOREACH(transactions_by_scope
, other
, t
->scope
->transactions
) {
1820 size_t saved_packet_size
;
1821 bool append
= false;
1823 /* Skip ourselves */
1827 if (other
->state
!= DNS_TRANSACTION_PENDING
)
1830 if (other
->next_attempt_after
> ts
)
1833 if (!set_contains(keys
, dns_transaction_key(other
))) {
1834 r
= dns_packet_append_key(p
, dns_transaction_key(other
), 0, &saved_packet_size
);
1835 /* If we can't stuff more questions into the packet, just give up.
1836 * One of the 'other' transactions will fire later and take care of the rest. */
1842 r
= dns_packet_append_zone(p
, t
, dns_transaction_key(other
), NULL
);
1851 r
= dns_transaction_prepare(other
, ts
);
1856 dns_packet_truncate(p
, saved_packet_size
);
1858 /* In this case, not only this transaction, but multiple transactions may be
1859 * freed. Hence, we need to restart the loop. */
1864 usec_t timeout
= transaction_get_resend_timeout(other
);
1865 r
= dns_transaction_setup_timeout(other
, timeout
, usec_add(ts
, timeout
));
1869 if (dns_key_is_shared(dns_transaction_key(other
)))
1870 add_known_answers
= true;
1873 r
= set_ensure_put(&keys
, &dns_resource_key_hash_ops
, dns_transaction_key(other
));
1879 if (qdcount
>= UINT16_MAX
)
1884 /* Append known answer section if we're asking for any shared record */
1885 if (add_known_answers
) {
1886 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, 0);
1890 ancount
= be16toh(DNS_PACKET_HEADER(p
)->ancount
);
1893 /* Then, create actual packet. */
1894 p
= dns_packet_unref(p
);
1895 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
1901 SET_FOREACH(k
, keys
) {
1902 r
= dns_packet_append_key(p
, k
, 0, NULL
);
1906 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(qdcount
);
1909 if (add_known_answers
) {
1910 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
, ts
, ancount
);
1917 SET_FOREACH(k
, keys
) {
1918 r
= dns_packet_append_zone(p
, t
, k
, &nscount
);
1922 DNS_PACKET_HEADER(p
)->nscount
= htobe16(nscount
);
1924 t
->sent
= TAKE_PTR(p
);
1928 static int dns_transaction_make_packet(DnsTransaction
*t
) {
1929 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
1934 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)
1935 return dns_transaction_make_packet_mdns(t
);
1940 if (t
->bypass
&& t
->bypass
->protocol
== t
->scope
->protocol
) {
1941 /* If bypass logic is enabled and the protocol if the original packet and our scope match,
1942 * take the original packet, copy it, and patch in our new ID */
1943 r
= dns_packet_dup(&p
, t
->bypass
);
1947 r
= dns_packet_new_query(
1948 &p
, t
->scope
->protocol
,
1949 /* min_alloc_dsize = */ 0,
1950 /* dnssec_cd = */ !FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) &&
1951 t
->scope
->dnssec_mode
!= DNSSEC_NO
);
1955 r
= dns_packet_append_key(p
, dns_transaction_key(t
), 0, NULL
);
1959 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
1962 DNS_PACKET_HEADER(p
)->id
= t
->id
;
1964 t
->sent
= TAKE_PTR(p
);
1968 int dns_transaction_go(DnsTransaction
*t
) {
1971 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
1975 /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
1976 * finished now. In the latter case, the transaction and query candidate objects must not be accessed.
1979 assert_se(sd_event_now(t
->scope
->manager
->event
, CLOCK_BOOTTIME
, &ts
) >= 0);
1981 r
= dns_transaction_prepare(t
, ts
);
1985 log_debug("Firing %s transaction %" PRIu16
" for <%s> scope %s on %s/%s (validate=%s).",
1986 t
->bypass
? "bypass" : "regular",
1988 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
),
1989 dns_protocol_to_string(t
->scope
->protocol
),
1990 t
->scope
->link
? t
->scope
->link
->ifname
: "*",
1991 af_to_name_short(t
->scope
->family
),
1992 yes_no(!FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
)));
1994 if (!t
->initial_jitter_scheduled
&&
1995 IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_LLMNR
, DNS_PROTOCOL_MDNS
)) {
1998 /* RFC 4795 Section 2.7 suggests all LLMNR queries should be delayed by a random time from 0 to
2000 * RFC 6762 Section 8.1 suggests initial probe queries should be delayed by a random time from
2003 t
->initial_jitter_scheduled
= true;
2006 switch (t
->scope
->protocol
) {
2008 case DNS_PROTOCOL_LLMNR
:
2009 jitter
= random_u64_range(LLMNR_JITTER_INTERVAL_USEC
);
2012 case DNS_PROTOCOL_MDNS
:
2014 jitter
= random_u64_range(MDNS_PROBING_INTERVAL_USEC
);
2019 assert_not_reached();
2022 r
= dns_transaction_setup_timeout(t
, jitter
, ts
);
2026 log_debug("Delaying %s transaction %" PRIu16
" for " USEC_FMT
"us.",
2027 dns_protocol_to_string(t
->scope
->protocol
),
2033 /* Otherwise, we need to ask the network */
2034 r
= dns_transaction_make_packet(t
);
2038 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
2039 (dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "in-addr.arpa") > 0 ||
2040 dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), "ip6.arpa") > 0)) {
2042 /* RFC 4795, Section 2.4. says reverse lookups shall
2043 * always be made via TCP on LLMNR */
2044 r
= dns_transaction_emit_tcp(t
);
2046 /* Try via UDP, and if that fails due to large size or lack of
2047 * support try via TCP */
2048 r
= dns_transaction_emit_udp(t
);
2050 log_debug("Sending query via TCP since it is too large.");
2051 else if (r
== -EAGAIN
)
2052 log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
2053 else if (r
== -EPERM
)
2054 log_debug("Sending query via TCP since UDP is blocked.");
2055 if (IN_SET(r
, -EMSGSIZE
, -EAGAIN
, -EPERM
))
2056 r
= dns_transaction_emit_tcp(t
);
2059 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2062 /* One of our own stub listeners */
2063 log_debug_errno(r
, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
2065 dns_scope_next_dns_server(t
->scope
, t
->server
);
2067 if (dns_scope_get_dns_server(t
->scope
) == t
->server
) {
2068 log_debug_errno(r
, "Still pointing to extra listener after switching DNS servers, refusing operation.");
2069 dns_transaction_complete(t
, DNS_TRANSACTION_STUB_LOOP
);
2073 return dns_transaction_go(t
);
2076 /* No servers to send this to? */
2077 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
2080 if (r
== -EOPNOTSUPP
) {
2081 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
2082 dns_transaction_complete(t
, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
);
2085 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& ERRNO_IS_DISCONNECT(r
)) {
2086 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
2087 * answer this request with this protocol. */
2088 dns_transaction_complete(t
, DNS_TRANSACTION_NOT_FOUND
);
2092 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2095 /* Couldn't send? Try immediately again, with a new server */
2096 dns_scope_next_dns_server(t
->scope
, t
->server
);
2098 return dns_transaction_go(t
);
2101 usec_t timeout
= transaction_get_resend_timeout(t
);
2102 r
= dns_transaction_setup_timeout(t
, timeout
, usec_add(ts
, timeout
));
2109 static int dns_transaction_find_cyclic(DnsTransaction
*t
, DnsTransaction
*aux
) {
2116 /* Try to find cyclic dependencies between transaction objects */
2121 SET_FOREACH(n
, aux
->dnssec_transactions
) {
2122 r
= dns_transaction_find_cyclic(t
, n
);
2130 static int dns_transaction_add_dnssec_transaction(DnsTransaction
*t
, DnsResourceKey
*key
, DnsTransaction
**ret
) {
2131 _cleanup_(dns_transaction_gcp
) DnsTransaction
*aux
= NULL
;
2138 aux
= dns_scope_find_transaction(t
->scope
, key
, t
->query_flags
);
2140 r
= dns_transaction_new(&aux
, t
->scope
, key
, NULL
, t
->query_flags
);
2144 if (set_contains(t
->dnssec_transactions
, aux
)) {
2149 r
= dns_transaction_find_cyclic(t
, aux
);
2153 char s
[DNS_RESOURCE_KEY_STRING_MAX
], saux
[DNS_RESOURCE_KEY_STRING_MAX
];
2155 return log_debug_errno(SYNTHETIC_ERRNO(ELOOP
),
2156 "Potential cyclic dependency, refusing to add transaction %" PRIu16
" (%s) as dependency for %" PRIu16
" (%s).",
2158 dns_resource_key_to_string(dns_transaction_key(t
), s
, sizeof s
),
2160 dns_resource_key_to_string(dns_transaction_key(aux
), saux
, sizeof saux
));
2164 r
= set_ensure_allocated(&aux
->notify_transactions_done
, NULL
);
2168 r
= set_ensure_put(&t
->dnssec_transactions
, NULL
, aux
);
2172 r
= set_ensure_put(&aux
->notify_transactions
, NULL
, t
);
2174 (void) set_remove(t
->dnssec_transactions
, aux
);
2178 *ret
= TAKE_PTR(aux
);
2182 static int dns_transaction_request_dnssec_rr(DnsTransaction
*t
, DnsResourceKey
*key
) {
2183 _cleanup_(dns_answer_unrefp
) DnsAnswer
*a
= NULL
;
2184 DnsTransaction
*aux
;
2190 /* Try to get the data from the trust anchor */
2191 r
= dns_trust_anchor_lookup_positive(&t
->scope
->manager
->trust_anchor
, key
, &a
);
2195 r
= dns_answer_extend(&t
->validated_keys
, a
);
2202 /* This didn't work, ask for it via the network/cache then. */
2203 r
= dns_transaction_add_dnssec_transaction(t
, key
, &aux
);
2204 if (r
== -ELOOP
) /* This would result in a cyclic dependency */
2209 if (aux
->state
== DNS_TRANSACTION_NULL
) {
2210 r
= dns_transaction_go(aux
);
2218 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction
*t
, const char *name
) {
2223 /* Check whether the specified name is in the NTA
2224 * database, either in the global one, or the link-local
2227 r
= dns_trust_anchor_lookup_negative(&t
->scope
->manager
->trust_anchor
, name
);
2231 if (!t
->scope
->link
)
2234 return link_negative_trust_anchor_lookup(t
->scope
->link
, name
);
2237 static int dns_transaction_has_negative_answer(DnsTransaction
*t
) {
2242 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
2243 * RRs to prove it */
2245 r
= dns_transaction_has_positive_answer(t
, NULL
);
2251 /* Is this key explicitly listed as a negative trust anchor?
2252 * If so, it's nothing we need to care about */
2253 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
2259 static int dns_transaction_is_primary_response(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2265 /* Check if the specified RR is the "primary" response,
2266 * i.e. either matches the question precisely or is a
2267 * CNAME/DNAME for it. */
2269 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2273 return dns_resource_key_match_cname_or_dname(dns_transaction_key(t
), rr
->key
, NULL
);
2276 static bool dns_transaction_dnssec_supported(DnsTransaction
*t
) {
2279 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2280 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2282 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
)
2285 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2286 * be supported, hence return true. */
2290 /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2291 * the server is known to support currently, as the transaction feature level might be lower than what the
2292 * server actually supports, since we might have downgraded this transaction's feature level because we got a
2293 * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
2295 return dns_server_dnssec_supported(t
->server
);
2298 static bool dns_transaction_dnssec_supported_full(DnsTransaction
*t
) {
2303 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2305 if (!dns_transaction_dnssec_supported(t
))
2308 SET_FOREACH(dt
, t
->dnssec_transactions
)
2309 if (!dns_transaction_dnssec_supported(dt
))
2315 int dns_transaction_request_dnssec_keys(DnsTransaction
*t
) {
2316 DnsResourceRecord
*rr
;
2323 * Retrieve all auxiliary RRs for the answer we got, so that
2324 * we can verify signatures or prove that RRs are rightfully
2325 * unsigned. Specifically:
2327 * - For RRSIG we get the matching DNSKEY
2328 * - For DNSKEY we get the matching DS
2329 * - For unsigned SOA/NS we get the matching DS
2330 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
2331 * - For other unsigned RRs we get the matching SOA RR
2332 * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2333 * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
2334 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2337 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
2339 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
2340 return 0; /* We only need to validate stuff from the network */
2341 if (!dns_transaction_dnssec_supported(t
))
2342 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
2344 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
2346 if (dns_type_is_pseudo(rr
->key
->type
))
2349 /* If this RR is in the negative trust anchor, we don't need to validate it. */
2350 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2356 switch (rr
->key
->type
) {
2358 case DNS_TYPE_RRSIG
: {
2359 /* For each RRSIG we request the matching DNSKEY */
2360 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*dnskey
= NULL
;
2362 /* If this RRSIG is about a DNSKEY RR and the
2363 * signer is the same as the owner, then we
2364 * already have the DNSKEY, and we don't have
2365 * to look for more. */
2366 if (rr
->rrsig
.type_covered
== DNS_TYPE_DNSKEY
) {
2367 r
= dns_name_equal(rr
->rrsig
.signer
, dns_resource_key_name(rr
->key
));
2374 /* If the signer is not a parent of our
2375 * original query, then this is about an
2376 * auxiliary RRset, but not anything we asked
2377 * for. In this case we aren't interested,
2378 * because we don't want to request additional
2379 * RRs for stuff we didn't really ask for, and
2380 * also to avoid request loops, where
2381 * additional RRs from one transaction result
2382 * in another transaction whose additional RRs
2383 * point back to the original transaction, and
2385 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), rr
->rrsig
.signer
);
2391 dnskey
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DNSKEY
, rr
->rrsig
.signer
);
2395 log_debug("Requesting DNSKEY to validate transaction %" PRIu16
" (%s, RRSIG with key tag: %" PRIu16
").",
2396 t
->id
, dns_resource_key_name(rr
->key
), rr
->rrsig
.key_tag
);
2397 r
= dns_transaction_request_dnssec_rr(t
, dnskey
);
2403 case DNS_TYPE_DNSKEY
: {
2404 /* For each DNSKEY we request the matching DS */
2405 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2407 /* If the DNSKEY we are looking at is not for
2408 * zone we are interested in, nor any of its
2409 * parents, we aren't interested, and don't
2410 * request it. After all, we don't want to end
2411 * up in request loops, and want to keep
2412 * additional traffic down. */
2414 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2420 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2424 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, DNSKEY with key tag: %" PRIu16
").",
2425 t
->id
, dns_resource_key_name(rr
->key
), dnssec_keytag(rr
, false));
2426 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2435 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
2437 /* For an unsigned SOA or NS, try to acquire
2438 * the matching DS RR, as we are at a zone cut
2439 * then, and whether a DS exists tells us
2440 * whether the zone is signed. Do so only if
2441 * this RR matches our original question,
2444 r
= dns_resource_key_match_rr(dns_transaction_key(t
), rr
, NULL
);
2448 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2449 * a negative reply, and we need the SOA RR's TTL in order to cache a negative entry?
2450 * If so, we need to validate it, too. */
2452 r
= dns_answer_match_key(t
->answer
, dns_transaction_key(t
), NULL
);
2455 if (r
> 0) /* positive reply, we won't need the SOA and hence don't need to validate
2459 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
2460 * what we are looking for, otherwise there's no value in it for us. */
2461 r
= dns_name_endswith(dns_resource_key_name(dns_transaction_key(t
)), dns_resource_key_name(rr
->key
));
2468 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2474 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, dns_resource_key_name(rr
->key
));
2478 log_debug("Requesting DS to validate transaction %" PRIu16
" (%s, unsigned SOA/NS RRset).",
2479 t
->id
, dns_resource_key_name(rr
->key
));
2480 r
= dns_transaction_request_dnssec_rr(t
, ds
);
2488 case DNS_TYPE_CNAME
:
2489 case DNS_TYPE_DNAME
: {
2490 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2493 /* CNAMEs and DNAMEs cannot be located at a
2494 * zone apex, hence ask for the parent SOA for
2495 * unsigned CNAME/DNAME RRs, maybe that's the
2496 * apex. But do all that only if this is
2497 * actually a response to our original
2500 * Similar for DS RRs, which are signed when
2501 * the parent SOA is signed. */
2503 r
= dns_transaction_is_primary_response(t
, rr
);
2509 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2515 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
2521 name
= dns_resource_key_name(rr
->key
);
2522 r
= dns_name_parent(&name
);
2528 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, name
);
2532 log_debug("Requesting parent SOA to validate transaction %" PRIu16
" (%s, unsigned CNAME/DNAME/DS RRset).",
2533 t
->id
, dns_resource_key_name(rr
->key
));
2534 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2542 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2544 /* For other unsigned RRsets (including
2545 * NSEC/NSEC3!), look for proof the zone is
2546 * unsigned, by requesting the SOA RR of the
2547 * zone. However, do so only if they are
2548 * directly relevant to our original
2551 r
= dns_transaction_is_primary_response(t
, rr
);
2557 r
= dnssec_has_rrsig(t
->answer
, rr
->key
);
2563 soa
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_SOA
, dns_resource_key_name(rr
->key
));
2567 log_debug("Requesting SOA to validate transaction %" PRIu16
" (%s, unsigned non-SOA/NS RRset <%s>).",
2568 t
->id
, dns_resource_key_name(rr
->key
), dns_resource_record_to_string(rr
));
2569 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2576 /* Above, we requested everything necessary to validate what
2577 * we got. Now, let's request what we need to validate what we
2580 r
= dns_transaction_has_negative_answer(t
);
2584 const char *name
, *signed_status
;
2587 name
= dns_resource_key_name(dns_transaction_key(t
));
2588 signed_status
= dns_answer_contains_nsec_or_nsec3(t
->answer
) ? "signed" : "unsigned";
2590 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2591 * could also be used as indication that we are not at a zone apex, but in real world setups there are
2592 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2593 * though they have further children. If this was a DS request, then it's signed when the parent zone
2594 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2595 * to see if that is signed. */
2597 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
2598 r
= dns_name_parent(&name
);
2600 type
= DNS_TYPE_SOA
;
2601 log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty DS response).",
2602 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
,
2603 dns_resource_key_name(dns_transaction_key(t
)), signed_status
);
2607 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
)) {
2610 log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16
" (%s, %s empty SOA/NS response).",
2611 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2614 type
= DNS_TYPE_SOA
;
2615 log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16
" (%s, %s empty non-SOA/NS/DS response).",
2616 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), name
, t
->id
, name
, signed_status
);
2620 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*soa
= NULL
;
2622 soa
= dns_resource_key_new(dns_transaction_key(t
)->class, type
, name
);
2626 r
= dns_transaction_request_dnssec_rr(t
, soa
);
2632 return dns_transaction_dnssec_is_live(t
);
2635 void dns_transaction_notify(DnsTransaction
*t
, DnsTransaction
*source
) {
2639 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2640 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2641 the state is VALIDATING however, we should check if we are complete now. */
2643 if (t
->state
== DNS_TRANSACTION_VALIDATING
)
2644 dns_transaction_process_dnssec(t
);
2647 static int dns_transaction_validate_dnskey_by_ds(DnsTransaction
*t
) {
2648 DnsAnswerItem
*item
;
2653 /* Add all DNSKEY RRs from the answer that are validated by DS
2654 * RRs from the list of validated keys to the list of
2655 * validated keys. */
2657 DNS_ANSWER_FOREACH_ITEM(item
, t
->answer
) {
2659 r
= dnssec_verify_dnskey_by_ds_search(item
->rr
, t
->validated_keys
);
2665 /* If so, the DNSKEY is validated too. */
2666 r
= dns_answer_add_extend(&t
->validated_keys
, item
->rr
, item
->ifindex
, item
->flags
|DNS_ANSWER_AUTHENTICATED
, item
->rrsig
);
2674 static int dns_transaction_requires_rrsig(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2680 /* Checks if the RR we are looking for must be signed with an
2681 * RRSIG. This is used for positive responses. */
2683 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2686 if (dns_type_is_pseudo(rr
->key
->type
))
2689 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2695 switch (rr
->key
->type
) {
2697 case DNS_TYPE_RRSIG
:
2698 /* RRSIGs are the signatures themselves, they need no signing. */
2705 /* For SOA or NS RRs we look for a matching DS transaction */
2707 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2709 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2711 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_DS
)
2714 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2720 /* We found a DS transactions for the SOA/NS
2721 * RRs we are looking at. If it discovered signed DS
2722 * RRs, then we need to be signed, too. */
2724 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
2727 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
2730 /* We found nothing that proves this is safe to leave
2731 * this unauthenticated, hence ask inist on
2732 * authentication. */
2737 case DNS_TYPE_CNAME
:
2738 case DNS_TYPE_DNAME
: {
2739 const char *parent
= NULL
;
2743 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2745 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2748 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2750 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2752 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2756 parent
= dns_resource_key_name(rr
->key
);
2757 r
= dns_name_parent(&parent
);
2761 if (rr
->key
->type
== DNS_TYPE_DS
)
2764 /* A CNAME/DNAME without a parent? That's sooo weird. */
2765 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG
),
2766 "Transaction %" PRIu16
" claims CNAME/DNAME at root. Refusing.", t
->id
);
2770 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), parent
);
2776 return FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2785 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
2787 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2789 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2791 if (dns_transaction_key(dt
)->type
!= DNS_TYPE_SOA
)
2794 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), dns_resource_key_name(rr
->key
));
2800 /* We found the transaction that was supposed to find the SOA RR for us. It was
2801 * successful, but found no RR for us. This means we are not at a zone cut. In this
2802 * case, we require authentication if the SOA lookup was authenticated too. */
2803 return FLAGS_SET(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2810 static int dns_transaction_in_private_tld(DnsTransaction
*t
, const DnsResourceKey
*key
) {
2815 /* If DNSSEC downgrade mode is on, checks whether the
2816 * specified RR is one level below a TLD we have proven not to
2817 * exist. In such a case we assume that this is a private
2818 * domain, and permit it.
2820 * This detects cases like the Fritz!Box router networks. Each
2821 * Fritz!Box router serves a private "fritz.box" zone, in the
2822 * non-existing TLD "box". Requests for the "fritz.box" domain
2823 * are served by the router itself, while requests for the
2824 * "box" domain will result in NXDOMAIN.
2826 * Note that this logic is unable to detect cases where a
2827 * router serves a private DNS zone directly under
2828 * non-existing TLD. In such a case we cannot detect whether
2829 * the TLD is supposed to exist or not, as all requests we
2830 * make for it will be answered by the router's zone, and not
2831 * by the root zone. */
2835 if (t
->scope
->dnssec_mode
!= DNSSEC_ALLOW_DOWNGRADE
)
2836 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2838 tld
= dns_resource_key_name(key
);
2839 r
= dns_name_parent(&tld
);
2843 return false; /* Already the root domain */
2845 if (!dns_name_is_single_label(tld
))
2848 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2850 if (dns_transaction_key(dt
)->class != key
->class)
2853 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), tld
);
2859 /* We found an auxiliary lookup we did for the TLD. If
2860 * that returned with NXDOMAIN, we know the TLD didn't
2861 * exist, and hence this might be a private zone. */
2863 return dt
->answer_rcode
== DNS_RCODE_NXDOMAIN
;
2869 static int dns_transaction_requires_nsec(DnsTransaction
*t
) {
2870 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
2878 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2879 * this negative reply */
2881 if (t
->scope
->dnssec_mode
== DNSSEC_NO
)
2884 if (dns_type_is_pseudo(dns_transaction_key(t
)->type
))
2887 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(dns_transaction_key(t
)));
2893 r
= dns_transaction_in_private_tld(t
, dns_transaction_key(t
));
2897 /* The lookup is from a TLD that is proven not to
2898 * exist, and we are in downgrade mode, hence ignore
2899 * that fact that we didn't get any NSEC RRs. */
2901 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2902 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
2906 name
= dns_resource_key_name(dns_transaction_key(t
));
2908 if (dns_transaction_key(t
)->type
== DNS_TYPE_DS
) {
2910 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
2911 * hence check the parent SOA in this case. */
2913 r
= dns_name_parent(&name
);
2919 type
= DNS_TYPE_SOA
;
2921 } else if (IN_SET(dns_transaction_key(t
)->type
, DNS_TYPE_SOA
, DNS_TYPE_NS
))
2922 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
2925 /* For all other negative replies, check for the SOA lookup */
2926 type
= DNS_TYPE_SOA
;
2928 /* For all other RRs we check the SOA on the same level to see
2929 * if it's signed. */
2931 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2933 if (dns_transaction_key(dt
)->class != dns_transaction_key(t
)->class)
2935 if (dns_transaction_key(dt
)->type
!= type
)
2938 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), name
);
2944 return FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
);
2947 /* If in doubt, require NSEC/NSEC3 */
2951 static int dns_transaction_dnskey_authenticated(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
2952 DnsResourceRecord
*rrsig
;
2956 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2957 * the specified RRset is authenticated (i.e. has a matching
2960 r
= dns_transaction_negative_trust_anchor_lookup(t
, dns_resource_key_name(rr
->key
));
2966 DNS_ANSWER_FOREACH(rrsig
, t
->answer
) {
2969 r
= dnssec_key_match_rrsig(rr
->key
, rrsig
);
2975 SET_FOREACH(dt
, t
->dnssec_transactions
) {
2977 if (dns_transaction_key(dt
)->class != rr
->key
->class)
2980 if (dns_transaction_key(dt
)->type
== DNS_TYPE_DNSKEY
) {
2982 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
2988 /* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated,
2991 if (FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
2996 } else if (dns_transaction_key(dt
)->type
== DNS_TYPE_DS
) {
2998 r
= dns_name_equal(dns_resource_key_name(dns_transaction_key(dt
)), rrsig
->rrsig
.signer
);
3004 /* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
3005 * non-zero, we won! */
3007 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3010 return dns_answer_match_key(dt
->answer
, dns_transaction_key(dt
), NULL
);
3015 return found
? false : -ENXIO
;
3018 static int dns_transaction_known_signed(DnsTransaction
*t
, DnsResourceRecord
*rr
) {
3022 /* We know that the root domain is signed, hence if it appears
3023 * not to be signed, there's a problem with the DNS server */
3025 return rr
->key
->class == DNS_CLASS_IN
&&
3026 dns_name_is_root(dns_resource_key_name(rr
->key
));
3029 static int dns_transaction_check_revoked_trust_anchors(DnsTransaction
*t
) {
3030 DnsResourceRecord
*rr
;
3035 /* Maybe warn the user that we encountered a revoked DNSKEY
3036 * for a key from our trust anchor. Note that we don't care
3037 * whether the DNSKEY can be authenticated or not. It's
3038 * sufficient if it is self-signed. */
3040 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3041 r
= dns_trust_anchor_check_revoked(&t
->scope
->manager
->trust_anchor
, rr
, t
->answer
);
3049 static int dns_transaction_invalidate_revoked_keys(DnsTransaction
*t
) {
3055 /* Removes all DNSKEY/DS objects from t->validated_keys that
3056 * our trust anchors database considers revoked. */
3059 DnsResourceRecord
*rr
;
3063 DNS_ANSWER_FOREACH(rr
, t
->validated_keys
) {
3064 r
= dns_trust_anchor_is_revoked(&t
->scope
->manager
->trust_anchor
, rr
);
3068 r
= dns_answer_remove_by_rr(&t
->validated_keys
, rr
);
3082 static int dns_transaction_copy_validated(DnsTransaction
*t
) {
3088 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
3090 SET_FOREACH(dt
, t
->dnssec_transactions
) {
3092 if (DNS_TRANSACTION_IS_LIVE(dt
->state
))
3095 if (!FLAGS_SET(dt
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
))
3098 r
= dns_answer_extend(&t
->validated_keys
, dt
->answer
);
3107 DNSSEC_PHASE_DNSKEY
, /* Phase #1, only validate DNSKEYs */
3108 DNSSEC_PHASE_NSEC
, /* Phase #2, only validate NSEC+NSEC3 */
3109 DNSSEC_PHASE_ALL
, /* Phase #3, validate everything else */
3112 static int dnssec_validate_records(
3116 DnsAnswer
**validated
) {
3118 DnsResourceRecord
*rr
;
3121 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
3123 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
3124 _unused_
_cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr_ref
= dns_resource_record_ref(rr
);
3125 DnsResourceRecord
*rrsig
= NULL
;
3126 DnssecResult result
;
3128 switch (rr
->key
->type
) {
3129 case DNS_TYPE_RRSIG
:
3132 case DNS_TYPE_DNSKEY
:
3133 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
3134 if (phase
== DNSSEC_PHASE_NSEC
)
3139 case DNS_TYPE_NSEC3
:
3142 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
3143 if (phase
== DNSSEC_PHASE_DNSKEY
)
3148 /* We validate all other RRs only in the ALL phases */
3149 if (phase
!= DNSSEC_PHASE_ALL
)
3153 r
= dnssec_verify_rrset_search(
3163 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr
)), dnssec_result_to_string(result
));
3165 if (result
== DNSSEC_VALIDATED
) {
3168 if (rr
->key
->type
== DNS_TYPE_DNSKEY
) {
3169 /* If we just validated a DNSKEY RRset, then let's add these keys to
3170 * the set of validated keys for this transaction. */
3172 r
= dns_answer_copy_by_key(&t
->validated_keys
, t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
, rrsig
);
3176 /* Some of the DNSKEYs we just added might already have been revoked,
3177 * remove them again in that case. */
3178 r
= dns_transaction_invalidate_revoked_keys(t
);
3183 /* Add the validated RRset to the new list of validated RRsets, and remove it from
3184 * the unvalidated RRsets. We mark the RRset as authenticated and cacheable. */
3185 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
, rrsig
);
3189 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_SECURE
, rr
->key
);
3191 /* Exit the loop, we dropped something from the answer, start from the beginning */
3195 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
3196 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
3197 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
3198 if (phase
!= DNSSEC_PHASE_ALL
)
3201 if (result
== DNSSEC_VALIDATED_WILDCARD
) {
3202 bool authenticated
= false;
3207 /* This RRset validated, but as a wildcard. This means we need
3208 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
3210 /* First step, determine the source of synthesis */
3211 r
= dns_resource_record_source(rrsig
, &source
);
3215 r
= dnssec_test_positive_wildcard(*validated
,
3216 dns_resource_key_name(rr
->key
),
3218 rrsig
->rrsig
.signer
,
3221 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
3223 result
= DNSSEC_INVALID
;
3225 r
= dns_answer_move_by_key(
3229 authenticated
? (DNS_ANSWER_AUTHENTICATED
|DNS_ANSWER_CACHEABLE
) : 0,
3234 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, rr
->key
);
3236 /* Exit the loop, we dropped something from the answer, start from the beginning */
3241 if (result
== DNSSEC_NO_SIGNATURE
) {
3242 r
= dns_transaction_requires_rrsig(t
, rr
);
3246 /* Data does not require signing. In that case, just copy it over,
3247 * but remember that this is by no means authenticated. */
3248 r
= dns_answer_move_by_key(
3257 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3261 r
= dns_transaction_known_signed(t
, rr
);
3265 /* This is an RR we know has to be signed. If it isn't this means
3266 * the server is not attaching RRSIGs, hence complain. */
3268 dns_server_packet_rrsig_missing(t
->server
, t
->current_feature_level
);
3270 if (t
->scope
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
) {
3272 /* Downgrading is OK? If so, just consider the information unsigned */
3274 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3278 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3282 /* Otherwise, fail */
3283 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3287 r
= dns_transaction_in_private_tld(t
, rr
->key
);
3291 char s
[DNS_RESOURCE_KEY_STRING_MAX
];
3293 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3294 * mode, hence ignore the fact that this was not signed. */
3296 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3297 dns_resource_key_to_string(rr
->key
, s
, sizeof s
));
3299 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3303 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3308 /* https://datatracker.ietf.org/doc/html/rfc6840#section-5.2 */
3309 if (result
== DNSSEC_UNSUPPORTED_ALGORITHM
) {
3310 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3314 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3320 DNSSEC_SIGNATURE_EXPIRED
)) {
3322 r
= dns_transaction_dnskey_authenticated(t
, rr
);
3323 if (r
< 0 && r
!= -ENXIO
)
3326 /* The DNSKEY transaction was not authenticated, this means there's
3327 * no DS for this, which means it's OK if no keys are found for this signature. */
3329 r
= dns_answer_move_by_key(validated
, &t
->answer
, rr
->key
, 0, NULL
);
3333 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, rr
->key
);
3338 r
= dns_transaction_is_primary_response(t
, rr
);
3342 /* Look for a matching DNAME for this CNAME */
3343 r
= dns_answer_has_dname_for_cname(t
->answer
, rr
);
3347 /* Also look among the stuff we already validated */
3348 r
= dns_answer_has_dname_for_cname(*validated
, rr
);
3356 DNSSEC_SIGNATURE_EXPIRED
,
3357 DNSSEC_NO_SIGNATURE
))
3358 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, rr
->key
);
3359 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3360 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, rr
->key
);
3362 /* This is a primary response to our question, and it failed validation.
3364 t
->answer_dnssec_result
= result
;
3368 /* This is a primary response, but we do have a DNAME RR
3369 * in the RR that can replay this CNAME, hence rely on
3370 * that, and we can remove the CNAME in favour of it. */
3373 /* This is just some auxiliary data. Just remove the RRset and continue. */
3374 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
3378 /* We dropped something from the answer, start from the beginning. */
3382 return 2; /* Finito. */
3385 int dns_transaction_validate_dnssec(DnsTransaction
*t
) {
3386 _cleanup_(dns_answer_unrefp
) DnsAnswer
*validated
= NULL
;
3388 DnsAnswerFlags flags
;
3390 char key_str
[DNS_RESOURCE_KEY_STRING_MAX
];
3394 /* We have now collected all DS and DNSKEY RRs in t->validated_keys, let's see which RRs we can now
3395 * authenticate with that. */
3397 if (FLAGS_SET(t
->query_flags
, SD_RESOLVED_NO_VALIDATE
) || t
->scope
->dnssec_mode
== DNSSEC_NO
)
3400 /* Already validated */
3401 if (t
->answer_dnssec_result
!= _DNSSEC_RESULT_INVALID
)
3404 /* Our own stuff needs no validation */
3405 if (IN_SET(t
->answer_source
, DNS_TRANSACTION_ZONE
, DNS_TRANSACTION_TRUST_ANCHOR
)) {
3406 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3407 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3411 /* Cached stuff is not affected by validation. */
3412 if (t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
3415 if (!dns_transaction_dnssec_supported_full(t
)) {
3416 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3417 t
->answer_dnssec_result
= DNSSEC_INCOMPATIBLE_SERVER
;
3418 log_debug("Not validating response for %" PRIu16
", used server feature level does not support DNSSEC.", t
->id
);
3422 log_debug("Validating response from transaction %" PRIu16
" (%s).",
3424 dns_resource_key_to_string(dns_transaction_key(t
), key_str
, sizeof key_str
));
3426 /* First, see if this response contains any revoked trust
3427 * anchors we care about */
3428 r
= dns_transaction_check_revoked_trust_anchors(t
);
3432 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3433 r
= dns_transaction_copy_validated(t
);
3437 /* Second, see if there are DNSKEYs we already know a
3438 * validated DS for. */
3439 r
= dns_transaction_validate_dnskey_by_ds(t
);
3443 /* Fourth, remove all DNSKEY and DS RRs again that our trust
3444 * anchor says are revoked. After all we might have marked
3445 * some keys revoked above, but they might still be lingering
3446 * in our validated_keys list. */
3447 r
= dns_transaction_invalidate_revoked_keys(t
);
3451 phase
= DNSSEC_PHASE_DNSKEY
;
3453 bool have_nsec
= false;
3455 r
= dnssec_validate_records(t
, phase
, &have_nsec
, &validated
);
3459 /* Try again as long as we managed to achieve something */
3463 if (phase
== DNSSEC_PHASE_DNSKEY
&& have_nsec
) {
3464 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
3465 phase
= DNSSEC_PHASE_NSEC
;
3469 if (phase
!= DNSSEC_PHASE_ALL
) {
3470 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3471 * Note that in this third phase we start to remove RRs we couldn't validate. */
3472 phase
= DNSSEC_PHASE_ALL
;
3480 DNS_ANSWER_REPLACE(t
->answer
, TAKE_PTR(validated
));
3482 /* At this point the answer only contains validated
3483 * RRsets. Now, let's see if it actually answers the question
3484 * we asked. If so, great! If it doesn't, then see if
3485 * NSEC/NSEC3 can prove this. */
3486 r
= dns_transaction_has_positive_answer(t
, &flags
);
3488 /* Yes, it answers the question! */
3490 if (flags
& DNS_ANSWER_AUTHENTICATED
) {
3491 /* The answer is fully authenticated, yay. */
3492 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3493 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3494 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, true);
3496 /* The answer is not fully authenticated. */
3497 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3498 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3501 } else if (r
== 0) {
3502 DnssecNsecResult nr
;
3503 bool authenticated
= false;
3505 /* Bummer! Let's check NSEC/NSEC3 */
3506 r
= dnssec_nsec_test(t
->answer
, dns_transaction_key(t
), &nr
, &authenticated
, &t
->answer_nsec_ttl
);
3512 case DNSSEC_NSEC_NXDOMAIN
:
3513 /* NSEC proves the domain doesn't exist. Very good. */
3514 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3515 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3516 t
->answer_rcode
= DNS_RCODE_NXDOMAIN
;
3517 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3519 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3522 case DNSSEC_NSEC_NODATA
:
3523 /* NSEC proves that there's no data here, very good. */
3524 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3525 t
->answer_dnssec_result
= DNSSEC_VALIDATED
;
3526 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
3527 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, authenticated
);
3529 manager_dnssec_verdict(t
->scope
->manager
, authenticated
? DNSSEC_SECURE
: DNSSEC_INSECURE
, dns_transaction_key(t
));
3532 case DNSSEC_NSEC_OPTOUT
:
3533 /* NSEC3 says the data might not be signed */
3534 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t
->id
, key_str
);
3535 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3536 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3538 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3541 case DNSSEC_NSEC_NO_RR
:
3542 /* No NSEC data? Bummer! */
3544 r
= dns_transaction_requires_nsec(t
);
3548 t
->answer_dnssec_result
= DNSSEC_NO_SIGNATURE
;
3549 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3551 t
->answer_dnssec_result
= DNSSEC_UNSIGNED
;
3552 SET_FLAG(t
->answer_query_flags
, SD_RESOLVED_AUTHENTICATED
, false);
3553 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INSECURE
, dns_transaction_key(t
));
3558 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM
:
3559 /* We don't know the NSEC3 algorithm used? */
3560 t
->answer_dnssec_result
= DNSSEC_UNSUPPORTED_ALGORITHM
;
3561 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_INDETERMINATE
, dns_transaction_key(t
));
3564 case DNSSEC_NSEC_FOUND
:
3565 case DNSSEC_NSEC_CNAME
:
3566 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
3567 t
->answer_dnssec_result
= DNSSEC_NSEC_MISMATCH
;
3568 manager_dnssec_verdict(t
->scope
->manager
, DNSSEC_BOGUS
, dns_transaction_key(t
));
3572 assert_not_reached();
3579 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
3580 [DNS_TRANSACTION_NULL
] = "null",
3581 [DNS_TRANSACTION_PENDING
] = "pending",
3582 [DNS_TRANSACTION_VALIDATING
] = "validating",
3583 [DNS_TRANSACTION_RCODE_FAILURE
] = "rcode-failure",
3584 [DNS_TRANSACTION_SUCCESS
] = "success",
3585 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
3586 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
3587 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
3588 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
3589 [DNS_TRANSACTION_ERRNO
] = "errno",
3590 [DNS_TRANSACTION_ABORTED
] = "aborted",
3591 [DNS_TRANSACTION_DNSSEC_FAILED
] = "dnssec-failed",
3592 [DNS_TRANSACTION_NO_TRUST_ANCHOR
] = "no-trust-anchor",
3593 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
] = "rr-type-unsupported",
3594 [DNS_TRANSACTION_NETWORK_DOWN
] = "network-down",
3595 [DNS_TRANSACTION_NOT_FOUND
] = "not-found",
3596 [DNS_TRANSACTION_NO_SOURCE
] = "no-source",
3597 [DNS_TRANSACTION_STUB_LOOP
] = "stub-loop",
3599 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);
3601 static const char* const dns_transaction_source_table
[_DNS_TRANSACTION_SOURCE_MAX
] = {
3602 [DNS_TRANSACTION_NETWORK
] = "network",
3603 [DNS_TRANSACTION_CACHE
] = "cache",
3604 [DNS_TRANSACTION_ZONE
] = "zone",
3605 [DNS_TRANSACTION_TRUST_ANCHOR
] = "trust-anchor",
3607 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source
, DnsTransactionSource
);