1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "alloc-util.h"
24 #include "dns-domain.h"
26 #include "random-util.h"
27 #include "resolved-dns-cache.h"
28 #include "resolved-dns-transaction.h"
29 #include "resolved-llmnr.h"
30 #include "string-table.h"
32 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
40 sd_event_source_unref(t
->timeout_event_source
);
42 dns_packet_unref(t
->sent
);
43 dns_packet_unref(t
->received
);
45 dns_answer_unref(t
->answer
);
47 sd_event_source_unref(t
->dns_udp_event_source
);
48 safe_close(t
->dns_udp_fd
);
50 dns_server_unref(t
->server
);
51 dns_stream_free(t
->stream
);
54 hashmap_remove_value(t
->scope
->transactions_by_key
, t
->key
, t
);
55 LIST_REMOVE(transactions_by_scope
, t
->scope
->transactions
, t
);
58 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
61 dns_resource_key_unref(t
->key
);
63 while ((c
= set_steal_first(t
->notify_query_candidates
)))
64 set_remove(c
->transactions
, t
);
65 set_free(t
->notify_query_candidates
);
67 while ((i
= set_steal_first(t
->notify_zone_items
)))
68 i
->probe_transaction
= NULL
;
69 set_free(t
->notify_zone_items
);
71 while ((z
= set_steal_first(t
->notify_transactions
)))
72 set_remove(z
->dnssec_transactions
, t
);
73 set_free(t
->notify_transactions
);
75 while ((z
= set_steal_first(t
->dnssec_transactions
))) {
76 set_remove(z
->notify_transactions
, t
);
77 dns_transaction_gc(z
);
79 set_free(t
->dnssec_transactions
);
81 dns_answer_unref(t
->validated_keys
);
87 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
89 void dns_transaction_gc(DnsTransaction
*t
) {
95 if (set_isempty(t
->notify_query_candidates
) &&
96 set_isempty(t
->notify_zone_items
) &&
97 set_isempty(t
->notify_transactions
))
98 dns_transaction_free(t
);
101 int dns_transaction_new(DnsTransaction
**ret
, DnsScope
*s
, DnsResourceKey
*key
) {
102 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
109 /* Don't allow looking up invalid or pseudo RRs */
110 if (!dns_type_is_valid_query(key
->type
))
113 /* We only support the IN class */
114 if (key
->class != DNS_CLASS_IN
&& key
->class != DNS_CLASS_ANY
)
117 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
121 r
= hashmap_ensure_allocated(&s
->transactions_by_key
, &dns_resource_key_hash_ops
);
125 t
= new0(DnsTransaction
, 1);
130 t
->answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
;
131 t
->dnssec_result
= _DNSSEC_RESULT_INVALID
;
132 t
->key
= dns_resource_key_ref(key
);
134 /* Find a fresh, unused transaction id */
136 random_bytes(&t
->id
, sizeof(t
->id
));
138 hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
)));
140 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
146 r
= hashmap_replace(s
->transactions_by_key
, t
->key
, t
);
148 hashmap_remove(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
152 LIST_PREPEND(transactions_by_scope
, s
->transactions
, t
);
163 static void dns_transaction_stop(DnsTransaction
*t
) {
166 t
->timeout_event_source
= sd_event_source_unref(t
->timeout_event_source
);
167 t
->stream
= dns_stream_free(t
->stream
);
169 /* Note that we do not drop the UDP socket here, as we want to
170 * reuse it to repeat the interaction. */
173 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
174 _cleanup_free_
char *pretty
= NULL
;
180 if (manager_our_packet(t
->scope
->manager
, p
) != 0)
183 in_addr_to_string(p
->family
, &p
->sender
, &pretty
);
185 log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
186 dns_protocol_to_string(t
->scope
->protocol
),
187 t
->scope
->link
? t
->scope
->link
->name
: "*",
188 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
191 /* RFC 4795, Section 4.1 says that the peer with the
192 * lexicographically smaller IP address loses */
193 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
194 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
198 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
201 while ((z
= set_first(t
->notify_zone_items
))) {
202 /* First, make sure the zone item drops the reference
204 dns_zone_item_probe_stop(z
);
206 /* Secondly, report this as conflict, so that we might
207 * look for a different hostname */
208 dns_zone_item_conflict(z
);
212 dns_transaction_gc(t
);
215 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
216 DnsQueryCandidate
*c
;
222 assert(!DNS_TRANSACTION_IS_LIVE(state
));
224 /* Note that this call might invalidate the query. Callers
225 * should hence not attempt to access the query or transaction
226 * after calling this function. */
228 log_debug("Transaction on scope %s on %s/%s now complete with <%s> from %s",
229 dns_protocol_to_string(t
->scope
->protocol
),
230 t
->scope
->link
? t
->scope
->link
->name
: "*",
231 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
232 dns_transaction_state_to_string(state
),
233 t
->answer_source
< 0 ? "none" : dns_transaction_source_to_string(t
->answer_source
));
237 dns_transaction_stop(t
);
239 /* Notify all queries that are interested, but make sure the
240 * transaction isn't freed while we are still looking at it */
242 SET_FOREACH(c
, t
->notify_query_candidates
, i
)
243 dns_query_candidate_notify(c
);
244 SET_FOREACH(z
, t
->notify_zone_items
, i
)
245 dns_zone_item_notify(z
);
246 SET_FOREACH(d
, t
->notify_transactions
, i
)
247 dns_transaction_notify(d
, t
);
250 dns_transaction_gc(t
);
253 static int on_stream_complete(DnsStream
*s
, int error
) {
254 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
258 assert(s
->transaction
);
260 /* Copy the data we care about out of the stream before we
263 p
= dns_packet_ref(s
->read_packet
);
265 t
->stream
= dns_stream_free(t
->stream
);
268 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
272 if (dns_packet_validate_reply(p
) <= 0) {
273 log_debug("Invalid TCP reply packet.");
274 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
278 dns_scope_check_conflicts(t
->scope
, p
);
281 dns_transaction_process_reply(t
, p
);
284 /* If the response wasn't useful, then complete the transition now */
285 if (t
->state
== DNS_TRANSACTION_PENDING
)
286 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
291 static int dns_transaction_open_tcp(DnsTransaction
*t
) {
292 DnsServer
*server
= NULL
;
293 _cleanup_close_
int fd
= -1;
301 switch (t
->scope
->protocol
) {
302 case DNS_PROTOCOL_DNS
:
303 fd
= dns_scope_tcp_socket(t
->scope
, AF_UNSPEC
, NULL
, 53, &server
);
306 case DNS_PROTOCOL_LLMNR
:
307 /* When we already received a reply to this (but it was truncated), send to its sender address */
309 fd
= dns_scope_tcp_socket(t
->scope
, t
->received
->family
, &t
->received
->sender
, t
->received
->sender_port
, NULL
);
311 union in_addr_union address
;
312 int family
= AF_UNSPEC
;
314 /* Otherwise, try to talk to the owner of a
315 * the IP address, in case this is a reverse
318 r
= dns_name_address(DNS_RESOURCE_KEY_NAME(t
->key
), &family
, &address
);
323 if (family
!= t
->scope
->family
)
326 fd
= dns_scope_tcp_socket(t
->scope
, family
, &address
, LLMNR_PORT
, NULL
);
332 return -EAFNOSUPPORT
;
338 r
= dns_stream_new(t
->scope
->manager
, &t
->stream
, t
->scope
->protocol
, fd
);
344 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
346 t
->stream
= dns_stream_free(t
->stream
);
350 dns_server_unref(t
->server
);
351 t
->server
= dns_server_ref(server
);
352 t
->received
= dns_packet_unref(t
->received
);
353 t
->answer
= dns_answer_unref(t
->answer
);
355 t
->stream
->complete
= on_stream_complete
;
356 t
->stream
->transaction
= t
;
358 /* The interface index is difficult to determine if we are
359 * connecting to the local host, hence fill this in right away
360 * instead of determining it from the socket */
362 t
->stream
->ifindex
= t
->scope
->link
->ifindex
;
367 static void dns_transaction_next_dns_server(DnsTransaction
*t
) {
370 t
->server
= dns_server_unref(t
->server
);
371 t
->dns_udp_event_source
= sd_event_source_unref(t
->dns_udp_event_source
);
372 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
374 dns_scope_next_dns_server(t
->scope
);
377 static void dns_transaction_cache_answer(DnsTransaction
*t
) {
382 /* For mDNS we cache whenever we get the packet, rather than
383 * in each transaction. */
384 if (!IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
))
387 /* We never cache if this packet is from the local host, under
388 * the assumption that a locally running DNS server would
389 * cache this anyway, and probably knows better when to flush
390 * the cache then we could. */
391 if (!DNS_PACKET_SHALL_CACHE(t
->received
))
394 /* According to RFC 4795, section 2.9. only the RRs from the
395 * answer section shall be cached. However, if we know the
396 * message is authenticated, we might as well cache
398 if (t
->answer_authenticated
)
399 n_cache
= dns_answer_size(t
->answer
);
401 n_cache
= DNS_PACKET_ANCOUNT(t
->received
);
403 dns_cache_put(&t
->scope
->cache
,
408 t
->answer_authenticated
,
411 &t
->received
->sender
);
414 static void dns_transaction_process_dnssec(DnsTransaction
*t
) {
419 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
420 if (!set_isempty(t
->dnssec_transactions
))
423 /* All our auxiliary DNSSEC transactions are complete now. Try
424 * to validate our RRset now. */
425 r
= dns_transaction_validate_dnssec(t
);
427 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
431 if (!IN_SET(t
->dnssec_result
, _DNSSEC_RESULT_INVALID
, DNSSEC_VALIDATED
, DNSSEC_NO_SIGNATURE
/* FOR NOW! */)) {
432 dns_transaction_complete(t
, DNS_TRANSACTION_DNSSEC_FAILED
);
436 dns_transaction_cache_answer(t
);
438 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
439 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
441 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
444 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
) {
450 assert(t
->state
== DNS_TRANSACTION_PENDING
);
452 assert(t
->scope
->manager
);
454 /* Note that this call might invalidate the query. Callers
455 * should hence not attempt to access the query or transaction
456 * after calling this function. */
458 log_debug("Processing incoming packet on transaction %" PRIu16
".", t
->id
);
460 switch (t
->scope
->protocol
) {
462 case DNS_PROTOCOL_LLMNR
:
463 assert(t
->scope
->link
);
465 /* For LLMNR we will not accept any packets from other
468 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
471 if (p
->family
!= t
->scope
->family
)
474 /* Tentative packets are not full responses but still
475 * useful for identifying uniqueness conflicts during
477 if (DNS_PACKET_LLMNR_T(p
)) {
478 dns_transaction_tentative(t
, p
);
484 case DNS_PROTOCOL_MDNS
:
485 assert(t
->scope
->link
);
487 /* For mDNS we will not accept any packets from other interfaces */
488 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
491 if (p
->family
!= t
->scope
->family
)
496 case DNS_PROTOCOL_DNS
:
500 assert_not_reached("Invalid DNS protocol.");
503 if (t
->received
!= p
) {
504 dns_packet_unref(t
->received
);
505 t
->received
= dns_packet_ref(p
);
508 t
->answer_source
= DNS_TRANSACTION_NETWORK
;
510 if (p
->ipproto
== IPPROTO_TCP
) {
511 if (DNS_PACKET_TC(p
)) {
512 /* Truncated via TCP? Somebody must be fucking with us */
513 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
517 if (DNS_PACKET_ID(p
) != t
->id
) {
518 /* Not the reply to our query? Somebody must be fucking with us */
519 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
524 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
526 switch (t
->scope
->protocol
) {
528 case DNS_PROTOCOL_DNS
:
531 if (IN_SET(DNS_PACKET_RCODE(p
), DNS_RCODE_FORMERR
, DNS_RCODE_SERVFAIL
, DNS_RCODE_NOTIMP
)) {
533 /* Request failed, immediately try again with reduced features */
534 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p
)));
536 dns_server_packet_failed(t
->server
, t
->current_features
);
538 r
= dns_transaction_go(t
);
540 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
546 dns_server_packet_received(t
->server
, t
->current_features
, ts
- t
->start_usec
, p
->size
);
550 case DNS_PROTOCOL_LLMNR
:
551 case DNS_PROTOCOL_MDNS
:
552 dns_scope_packet_received(t
->scope
, ts
- t
->start_usec
);
556 assert_not_reached("Invalid DNS protocol.");
559 if (DNS_PACKET_TC(p
)) {
561 /* Truncated packets for mDNS are not allowed. Give up immediately. */
562 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
) {
563 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
567 /* Response was truncated, let's try again with good old TCP */
568 r
= dns_transaction_open_tcp(t
);
570 /* No servers found? Damn! */
571 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
575 /* On LLMNR, if we cannot connect to the host,
576 * we immediately give up */
577 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
578 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
582 /* On DNS, couldn't send? Try immediately again, with a new server */
583 dns_transaction_next_dns_server(t
);
585 r
= dns_transaction_go(t
);
587 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
595 /* Parse message, if it isn't parsed yet. */
596 r
= dns_packet_extract(p
);
598 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
602 if (IN_SET(t
->scope
->protocol
, DNS_PROTOCOL_DNS
, DNS_PROTOCOL_LLMNR
)) {
604 /* Only consider responses with equivalent query section to the request */
605 r
= dns_packet_is_reply_for(p
, t
->key
);
607 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
611 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
615 /* Install the answer as answer to the transaction */
616 dns_answer_unref(t
->answer
);
617 t
->answer
= dns_answer_ref(p
->answer
);
618 t
->answer_rcode
= DNS_PACKET_RCODE(p
);
619 t
->answer_authenticated
= t
->scope
->dnssec_mode
== DNSSEC_TRUST
&& DNS_PACKET_AD(p
);
621 r
= dns_transaction_request_dnssec_keys(t
);
623 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
627 /* There are DNSSEC transactions pending now. Update the state accordingly. */
628 t
->state
= DNS_TRANSACTION_VALIDATING
;
633 dns_transaction_process_dnssec(t
);
636 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
637 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
638 DnsTransaction
*t
= userdata
;
644 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
648 if (dns_packet_validate_reply(p
) > 0 &&
649 DNS_PACKET_ID(p
) == t
->id
)
650 dns_transaction_process_reply(t
, p
);
652 log_debug("Invalid DNS packet, ignoring.");
657 static int dns_transaction_emit(DnsTransaction
*t
) {
662 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->server
) {
663 DnsServer
*server
= NULL
;
664 _cleanup_close_
int fd
= -1;
666 fd
= dns_scope_udp_dns_socket(t
->scope
, &server
);
670 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
676 t
->server
= dns_server_ref(server
);
679 r
= dns_scope_emit(t
->scope
, t
->dns_udp_fd
, t
->server
, t
->sent
);
684 t
->current_features
= t
->server
->possible_features
;
689 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
690 DnsTransaction
*t
= userdata
;
696 if (!t
->initial_jitter_scheduled
|| t
->initial_jitter_elapsed
) {
697 /* Timeout reached? Increase the timeout for the server used */
698 switch (t
->scope
->protocol
) {
699 case DNS_PROTOCOL_DNS
:
702 dns_server_packet_lost(t
->server
, t
->current_features
, usec
- t
->start_usec
);
705 case DNS_PROTOCOL_LLMNR
:
706 case DNS_PROTOCOL_MDNS
:
707 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
711 assert_not_reached("Invalid DNS protocol.");
714 if (t
->initial_jitter_scheduled
)
715 t
->initial_jitter_elapsed
= true;
718 /* ...and try again with a new server */
719 dns_transaction_next_dns_server(t
);
721 r
= dns_transaction_go(t
);
723 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
728 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
732 switch (t
->scope
->protocol
) {
733 case DNS_PROTOCOL_DNS
:
736 return t
->server
->resend_timeout
;
737 case DNS_PROTOCOL_MDNS
:
738 assert(t
->n_attempts
> 0);
739 return (1 << (t
->n_attempts
- 1)) * USEC_PER_SEC
;
740 case DNS_PROTOCOL_LLMNR
:
741 return t
->scope
->resend_timeout
;
743 assert_not_reached("Invalid DNS protocol.");
747 static int dns_transaction_prepare(DnsTransaction
*t
, usec_t ts
) {
753 had_stream
= !!t
->stream
;
755 dns_transaction_stop(t
);
757 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
758 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
762 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& had_stream
) {
763 /* If we already tried via a stream, then we don't
764 * retry on LLMNR. See RFC 4795, Section 2.7. */
765 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
771 t
->received
= dns_packet_unref(t
->received
);
772 t
->answer
= dns_answer_unref(t
->answer
);
774 t
->answer_source
= _DNS_TRANSACTION_SOURCE_INVALID
;
776 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
777 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
) {
778 r
= dns_trust_anchor_lookup(&t
->scope
->manager
->trust_anchor
, t
->key
, &t
->answer
);
782 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
783 t
->answer_source
= DNS_TRANSACTION_TRUST_ANCHOR
;
784 t
->answer_authenticated
= true;
785 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
790 /* Check the zone, but only if this transaction is not used
791 * for probing or verifying a zone item. */
792 if (set_isempty(t
->notify_zone_items
)) {
794 r
= dns_zone_lookup(&t
->scope
->zone
, t
->key
, &t
->answer
, NULL
, NULL
);
798 t
->answer_rcode
= DNS_RCODE_SUCCESS
;
799 t
->answer_source
= DNS_TRANSACTION_ZONE
;
800 t
->answer_authenticated
= true;
801 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
806 /* Check the cache, but only if this transaction is not used
807 * for probing or verifying a zone item. */
808 if (set_isempty(t
->notify_zone_items
)) {
810 /* Before trying the cache, let's make sure we figured out a
811 * server to use. Should this cause a change of server this
812 * might flush the cache. */
813 dns_scope_get_dns_server(t
->scope
);
815 /* Let's then prune all outdated entries */
816 dns_cache_prune(&t
->scope
->cache
);
818 r
= dns_cache_lookup(&t
->scope
->cache
, t
->key
, &t
->answer_rcode
, &t
->answer
, &t
->answer_authenticated
);
822 t
->answer_source
= DNS_TRANSACTION_CACHE
;
823 if (t
->answer_rcode
== DNS_RCODE_SUCCESS
)
824 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
826 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
834 static int dns_transaction_make_packet_mdns(DnsTransaction
*t
) {
836 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
837 bool add_known_answers
= false;
838 DnsTransaction
*other
;
844 assert(t
->scope
->protocol
== DNS_PROTOCOL_MDNS
);
846 /* Discard any previously prepared packet, so we can start over and coaleasce again */
847 t
->sent
= dns_packet_unref(t
->sent
);
849 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, false);
853 r
= dns_packet_append_key(p
, t
->key
, NULL
);
859 if (dns_key_is_shared(t
->key
))
860 add_known_answers
= true;
863 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
864 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
865 * in our current scope, and see whether their timing contraints allow them to be sent.
868 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
870 LIST_FOREACH(transactions_by_scope
, other
, t
->scope
->transactions
) {
876 if (other
->state
!= DNS_TRANSACTION_PENDING
)
879 if (other
->next_attempt_after
> ts
)
882 if (qdcount
>= UINT16_MAX
)
885 r
= dns_packet_append_key(p
, other
->key
, NULL
);
888 * If we can't stuff more questions into the packet, just give up.
889 * One of the 'other' transactions will fire later and take care of the rest.
897 r
= dns_transaction_prepare(other
, ts
);
901 ts
+= transaction_get_resend_timeout(other
);
903 r
= sd_event_add_time(
904 other
->scope
->manager
->event
,
905 &other
->timeout_event_source
,
906 clock_boottime_or_monotonic(),
908 on_transaction_timeout
, other
);
912 other
->state
= DNS_TRANSACTION_PENDING
;
913 other
->next_attempt_after
= ts
;
917 if (dns_key_is_shared(other
->key
))
918 add_known_answers
= true;
921 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(qdcount
);
923 /* Append known answer section if we're asking for any shared record */
924 if (add_known_answers
) {
925 r
= dns_cache_export_shared_to_packet(&t
->scope
->cache
, p
);
936 static int dns_transaction_make_packet(DnsTransaction
*t
) {
937 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
942 if (t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)
943 return dns_transaction_make_packet_mdns(t
);
948 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0, t
->scope
->dnssec_mode
== DNSSEC_YES
);
952 r
= dns_scope_good_key(t
->scope
, t
->key
);
958 r
= dns_packet_append_key(p
, t
->key
, NULL
);
962 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
963 DNS_PACKET_HEADER(p
)->id
= t
->id
;
971 int dns_transaction_go(DnsTransaction
*t
) {
977 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
979 r
= dns_transaction_prepare(t
, ts
);
983 if (log_get_max_level() >= LOG_DEBUG
) {
984 _cleanup_free_
char *ks
= NULL
;
986 (void) dns_resource_key_to_string(t
->key
, &ks
);
988 log_debug("Excercising transaction for <%s> on scope %s on %s/%s",
989 ks
? strstrip(ks
) : "???",
990 dns_protocol_to_string(t
->scope
->protocol
),
991 t
->scope
->link
? t
->scope
->link
->name
: "*",
992 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
));
995 if (!t
->initial_jitter_scheduled
&&
996 (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
||
997 t
->scope
->protocol
== DNS_PROTOCOL_MDNS
)) {
998 usec_t jitter
, accuracy
;
1000 /* RFC 4795 Section 2.7 suggests all queries should be
1001 * delayed by a random time from 0 to JITTER_INTERVAL. */
1003 t
->initial_jitter_scheduled
= true;
1005 random_bytes(&jitter
, sizeof(jitter
));
1007 switch (t
->scope
->protocol
) {
1008 case DNS_PROTOCOL_LLMNR
:
1009 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
1010 accuracy
= LLMNR_JITTER_INTERVAL_USEC
;
1012 case DNS_PROTOCOL_MDNS
:
1013 jitter
%= MDNS_JITTER_RANGE_USEC
;
1014 jitter
+= MDNS_JITTER_MIN_USEC
;
1015 accuracy
= MDNS_JITTER_RANGE_USEC
;
1018 assert_not_reached("bad protocol");
1021 r
= sd_event_add_time(
1022 t
->scope
->manager
->event
,
1023 &t
->timeout_event_source
,
1024 clock_boottime_or_monotonic(),
1025 ts
+ jitter
, accuracy
,
1026 on_transaction_timeout
, t
);
1031 t
->next_attempt_after
= ts
;
1032 t
->state
= DNS_TRANSACTION_PENDING
;
1034 log_debug("Delaying %s transaction for " USEC_FMT
"us.", dns_protocol_to_string(t
->scope
->protocol
), jitter
);
1038 /* Otherwise, we need to ask the network */
1039 r
= dns_transaction_make_packet(t
);
1041 /* Not the right request to make on this network?
1042 * (i.e. an A request made on IPv6 or an AAAA request
1043 * made on IPv4, on LLMNR or mDNS.) */
1044 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1050 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
1051 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "in-addr.arpa") > 0 ||
1052 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "ip6.arpa") > 0)) {
1054 /* RFC 4795, Section 2.4. says reverse lookups shall
1055 * always be made via TCP on LLMNR */
1056 r
= dns_transaction_open_tcp(t
);
1058 /* Try via UDP, and if that fails due to large size or lack of
1059 * support try via TCP */
1060 r
= dns_transaction_emit(t
);
1061 if (r
== -EMSGSIZE
|| r
== -EAGAIN
)
1062 r
= dns_transaction_open_tcp(t
);
1066 /* No servers to send this to? */
1067 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
1070 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
) {
1071 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
1075 /* Couldn't send? Try immediately again, with a new server */
1076 dns_transaction_next_dns_server(t
);
1078 return dns_transaction_go(t
);
1081 ts
+= transaction_get_resend_timeout(t
);
1083 r
= sd_event_add_time(
1084 t
->scope
->manager
->event
,
1085 &t
->timeout_event_source
,
1086 clock_boottime_or_monotonic(),
1088 on_transaction_timeout
, t
);
1092 t
->state
= DNS_TRANSACTION_PENDING
;
1093 t
->next_attempt_after
= ts
;
1098 static int dns_transaction_add_dnssec_transaction(DnsTransaction
*t
, DnsResourceKey
*key
, DnsTransaction
**ret
) {
1099 DnsTransaction
*aux
;
1106 aux
= dns_scope_find_transaction(t
->scope
, key
, true);
1108 r
= dns_transaction_new(&aux
, t
->scope
, key
);
1112 if (set_contains(t
->dnssec_transactions
, aux
)) {
1118 r
= set_ensure_allocated(&t
->dnssec_transactions
, NULL
);
1122 r
= set_ensure_allocated(&aux
->notify_transactions
, NULL
);
1126 r
= set_put(t
->dnssec_transactions
, aux
);
1130 r
= set_put(aux
->notify_transactions
, t
);
1132 (void) set_remove(t
->dnssec_transactions
, aux
);
1140 dns_transaction_gc(aux
);
1144 static int dns_transaction_request_dnssec_rr(DnsTransaction
*t
, DnsResourceKey
*key
) {
1145 _cleanup_(dns_answer_unrefp
) DnsAnswer
*a
= NULL
;
1146 DnsTransaction
*aux
;
1152 /* Try to get the data from the trust anchor */
1153 r
= dns_trust_anchor_lookup(&t
->scope
->manager
->trust_anchor
, key
, &a
);
1157 r
= dns_answer_extend(&t
->validated_keys
, a
);
1164 /* This didn't work, ask for it via the network/cache then. */
1165 r
= dns_transaction_add_dnssec_transaction(t
, key
, &aux
);
1169 if (aux
->state
== DNS_TRANSACTION_NULL
) {
1170 r
= dns_transaction_go(aux
);
1178 int dns_transaction_request_dnssec_keys(DnsTransaction
*t
) {
1179 DnsResourceRecord
*rr
;
1184 if (t
->scope
->dnssec_mode
!= DNSSEC_YES
)
1187 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
1189 switch (rr
->key
->type
) {
1191 case DNS_TYPE_RRSIG
: {
1192 /* For each RRSIG we request the matching DNSKEY */
1193 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*dnskey
= NULL
;
1195 /* If this RRSIG is about a DNSKEY RR and the
1196 * signer is the same as the owner, then we
1197 * already have the DNSKEY, and we don't have
1198 * to look for more. */
1199 if (rr
->rrsig
.type_covered
== DNS_TYPE_DNSKEY
) {
1200 r
= dns_name_equal(rr
->rrsig
.signer
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1207 /* If the signer is not a parent of the owner,
1208 * then the signature is bogus, let's ignore
1210 r
= dns_name_endswith(DNS_RESOURCE_KEY_NAME(rr
->key
), rr
->rrsig
.signer
);
1216 dnskey
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DNSKEY
, rr
->rrsig
.signer
);
1220 log_debug("Requesting DNSKEY to validate transaction %" PRIu16
" (key tag: %" PRIu16
").", t
->id
, rr
->rrsig
.key_tag
);
1222 r
= dns_transaction_request_dnssec_rr(t
, dnskey
);
1228 case DNS_TYPE_DNSKEY
: {
1229 /* For each DNSKEY we request the matching DS */
1230 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*ds
= NULL
;
1232 ds
= dns_resource_key_new(rr
->key
->class, DNS_TYPE_DS
, DNS_RESOURCE_KEY_NAME(rr
->key
));
1236 log_debug("Requesting DS to validate transaction %" PRIu16
" (key tag: %" PRIu16
").", t
->id
, dnssec_keytag(rr
));
1238 r
= dns_transaction_request_dnssec_rr(t
, ds
);
1246 return !set_isempty(t
->dnssec_transactions
);
1249 void dns_transaction_notify(DnsTransaction
*t
, DnsTransaction
*source
) {
1253 assert(IN_SET(t
->state
, DNS_TRANSACTION_PENDING
, DNS_TRANSACTION_VALIDATING
));
1256 /* Invoked whenever any of our auxiliary DNSSEC transactions
1257 completed its work. We simply copy the answer from that
1258 transaction over. */
1260 if (source
->state
!= DNS_TRANSACTION_SUCCESS
) {
1261 log_debug("Auxiliary DNSSEC RR query failed.");
1262 t
->dnssec_result
= DNSSEC_FAILED_AUXILIARY
;
1264 r
= dns_answer_extend(&t
->validated_keys
, source
->answer
);
1266 log_error_errno(r
, "Failed to merge validated DNSSEC key data: %m");
1267 t
->dnssec_result
= DNSSEC_FAILED_AUXILIARY
;
1271 /* Detach us from the DNSSEC transaction. */
1272 (void) set_remove(t
->dnssec_transactions
, source
);
1273 (void) set_remove(source
->notify_transactions
, t
);
1275 /* If the state is still PENDING, we are still in the loop
1276 * that adds further DNSSEC transactions, hence don't check if
1277 * we are ready yet. If the state is VALIDATING however, we
1278 * should check if we are complete now. */
1279 if (t
->state
== DNS_TRANSACTION_VALIDATING
)
1280 dns_transaction_process_dnssec(t
);
1283 int dns_transaction_validate_dnssec(DnsTransaction
*t
) {
1284 _cleanup_(dns_answer_unrefp
) DnsAnswer
*validated
= NULL
;
1285 DnsResourceRecord
*rr
;
1290 /* We have now collected all DS and DNSKEY RRs in
1291 * t->validated_keys, let's see which RRs we can now
1292 * authenticate with that. */
1294 if (t
->scope
->dnssec_mode
!= DNSSEC_YES
)
1297 /* Already validated */
1298 if (t
->dnssec_result
!= _DNSSEC_RESULT_INVALID
)
1301 if (IN_SET(t
->answer_source
, DNS_TRANSACTION_ZONE
, DNS_TRANSACTION_TRUST_ANCHOR
)) {
1302 t
->dnssec_result
= DNSSEC_VALIDATED
;
1303 t
->answer_authenticated
= true;
1307 if (log_get_max_level() >= LOG_DEBUG
) {
1308 _cleanup_free_
char *ks
= NULL
;
1310 (void) dns_resource_key_to_string(t
->key
, &ks
);
1311 log_debug("Validating response from transaction %" PRIu16
" (%s).", t
->id
, ks
? strstrip(ks
) : "???");
1314 /* First see if there are DNSKEYs we already known a validated DS for. */
1315 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, t
->answer
) {
1317 r
= dnssec_verify_dnskey_search(rr
, t
->validated_keys
);
1323 /* If so, the DNSKEY is validated too. */
1324 r
= dns_answer_add_extend(&t
->validated_keys
, rr
, ifindex
);
1330 bool changed
= false, missing_key_for_transaction
= false;
1332 DNS_ANSWER_FOREACH(rr
, t
->answer
) {
1333 DnssecResult result
;
1335 if (rr
->key
->type
== DNS_TYPE_RRSIG
)
1338 r
= dnssec_verify_rrset_search(t
->answer
, rr
->key
, t
->validated_keys
, USEC_INFINITY
, &result
);
1342 if (log_get_max_level() >= LOG_DEBUG
) {
1343 _cleanup_free_
char *rrs
= NULL
;
1345 (void) dns_resource_record_to_string(rr
, &rrs
);
1346 log_debug("Looking at %s: %s", rrs
? strstrip(rrs
) : "???", dnssec_result_to_string(result
));
1351 case DNSSEC_VALIDATED
:
1353 /* Add the validated RRset to the new list of validated RRsets */
1354 r
= dns_answer_copy_by_key(&validated
, t
->answer
, rr
->key
);
1358 if (rr
->key
->type
== DNS_TYPE_DNSKEY
) {
1359 /* If we just validated a
1360 * DNSKEY RRset, then let's
1361 * add these keys to the set
1362 * of validated keys for this
1365 r
= dns_answer_copy_by_key(&t
->validated_keys
, t
->answer
, rr
->key
);
1370 /* Now, remove this RRset from the RRs still to process */
1371 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
1378 case DNSSEC_INVALID
:
1379 case DNSSEC_NO_SIGNATURE
:
1380 case DNSSEC_SIGNATURE_EXPIRED
:
1382 /* Is this the RRset that we were looking for? If so, this is fatal for the whole transaction */
1383 r
= dns_resource_key_match_rr(t
->key
, rr
, NULL
);
1387 t
->dnssec_result
= result
;
1391 /* Is this a CNAME for a record we were looking for? If so, it's also fatal for the whole transaction */
1392 r
= dns_resource_key_match_cname_or_dname(t
->key
, rr
->key
, NULL
);
1396 t
->dnssec_result
= result
;
1400 /* This is just something auxiliary. Just remove the RRset and continue. */
1401 r
= dns_answer_remove_by_key(&t
->answer
, rr
->key
);
1408 case DNSSEC_MISSING_KEY
:
1409 /* They key is missing? Let's continue
1410 * with the next iteration, maybe
1411 * we'll find it in an DNSKEY RRset
1414 r
= dns_resource_key_equal(rr
->key
, t
->key
);
1418 missing_key_for_transaction
= true;
1423 assert_not_reached("Unexpected DNSSEC result");
1433 /* This didn't work either, there's no point in
1435 if (missing_key_for_transaction
) {
1436 t
->dnssec_result
= DNSSEC_MISSING_KEY
;
1443 dns_answer_unref(t
->answer
);
1444 t
->answer
= validated
;
1447 t
->answer_authenticated
= true;
1448 t
->dnssec_result
= DNSSEC_VALIDATED
;
1452 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
1453 [DNS_TRANSACTION_NULL
] = "null",
1454 [DNS_TRANSACTION_PENDING
] = "pending",
1455 [DNS_TRANSACTION_VALIDATING
] = "validating",
1456 [DNS_TRANSACTION_FAILURE
] = "failure",
1457 [DNS_TRANSACTION_SUCCESS
] = "success",
1458 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
1459 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
1460 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
1461 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
1462 [DNS_TRANSACTION_RESOURCES
] = "resources",
1463 [DNS_TRANSACTION_ABORTED
] = "aborted",
1464 [DNS_TRANSACTION_DNSSEC_FAILED
] = "dnssec-failed",
1466 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);
1468 static const char* const dns_transaction_source_table
[_DNS_TRANSACTION_SOURCE_MAX
] = {
1469 [DNS_TRANSACTION_NETWORK
] = "network",
1470 [DNS_TRANSACTION_CACHE
] = "cache",
1471 [DNS_TRANSACTION_ZONE
] = "zone",
1472 [DNS_TRANSACTION_TRUST_ANCHOR
] = "trust-anchor",
1474 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source
, DnsTransactionSource
);