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/>.
24 #include "resolved-llmnr.h"
25 #include "resolved-dns-transaction.h"
26 #include "random-util.h"
27 #include "dns-domain.h"
29 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
36 sd_event_source_unref(t
->timeout_event_source
);
38 dns_packet_unref(t
->sent
);
39 dns_packet_unref(t
->received
);
40 dns_answer_unref(t
->cached
);
42 sd_event_source_unref(t
->dns_udp_event_source
);
43 safe_close(t
->dns_udp_fd
);
45 dns_server_unref(t
->server
);
46 dns_stream_free(t
->stream
);
49 hashmap_remove(t
->scope
->transactions
, t
->key
);
52 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
55 dns_resource_key_unref(t
->key
);
57 while ((q
= set_steal_first(t
->queries
)))
58 set_remove(q
->transactions
, t
);
61 while ((i
= set_steal_first(t
->zone_items
)))
62 i
->probe_transaction
= NULL
;
63 set_free(t
->zone_items
);
69 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
71 void dns_transaction_gc(DnsTransaction
*t
) {
77 if (set_isempty(t
->queries
) && set_isempty(t
->zone_items
))
78 dns_transaction_free(t
);
81 int dns_transaction_new(DnsTransaction
**ret
, DnsScope
*s
, DnsResourceKey
*key
) {
82 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
89 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
93 r
= hashmap_ensure_allocated(&s
->transactions
, &dns_resource_key_hash_ops
);
97 t
= new0(DnsTransaction
, 1);
102 t
->key
= dns_resource_key_ref(key
);
104 /* Find a fresh, unused transaction id */
106 random_bytes(&t
->id
, sizeof(t
->id
));
108 hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
)));
110 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
116 r
= hashmap_put(s
->transactions
, t
->key
, t
);
118 hashmap_remove(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
132 static void dns_transaction_stop(DnsTransaction
*t
) {
135 t
->timeout_event_source
= sd_event_source_unref(t
->timeout_event_source
);
136 t
->stream
= dns_stream_free(t
->stream
);
139 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
140 _cleanup_free_
char *pretty
= NULL
;
146 if (manager_our_packet(t
->scope
->manager
, p
) != 0)
149 in_addr_to_string(p
->family
, &p
->sender
, &pretty
);
151 log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
152 dns_protocol_to_string(t
->scope
->protocol
),
153 t
->scope
->link
? t
->scope
->link
->name
: "*",
154 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
157 /* RFC 4795, Section 4.1 says that the peer with the
158 * lexicographically smaller IP address loses */
159 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
160 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
164 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
167 while ((z
= set_first(t
->zone_items
))) {
168 /* First, make sure the zone item drops the reference
170 dns_zone_item_probe_stop(z
);
172 /* Secondly, report this as conflict, so that we might
173 * look for a different hostname */
174 dns_zone_item_conflict(z
);
178 dns_transaction_gc(t
);
181 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
187 assert(!IN_SET(state
, DNS_TRANSACTION_NULL
, DNS_TRANSACTION_PENDING
));
189 /* Note that this call might invalidate the query. Callers
190 * should hence not attempt to access the query or transaction
191 * after calling this function. */
193 log_debug("Transaction on scope %s on %s/%s now complete with <%s>",
194 dns_protocol_to_string(t
->scope
->protocol
),
195 t
->scope
->link
? t
->scope
->link
->name
: "*",
196 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
197 dns_transaction_state_to_string(state
));
201 dns_transaction_stop(t
);
203 /* Notify all queries that are interested, but make sure the
204 * transaction isn't freed while we are still looking at it */
206 SET_FOREACH(q
, t
->queries
, i
)
208 SET_FOREACH(z
, t
->zone_items
, i
)
209 dns_zone_item_ready(z
);
212 dns_transaction_gc(t
);
215 static int on_stream_complete(DnsStream
*s
, int error
) {
216 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
220 assert(s
->transaction
);
222 /* Copy the data we care about out of the stream before we
225 p
= dns_packet_ref(s
->read_packet
);
227 t
->stream
= dns_stream_free(t
->stream
);
230 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
234 if (dns_packet_validate_reply(p
) <= 0) {
235 log_debug("Invalid LLMNR TCP packet.");
236 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
240 dns_scope_check_conflicts(t
->scope
, p
);
243 dns_transaction_process_reply(t
, p
);
246 /* If the response wasn't useful, then complete the transition now */
247 if (t
->state
== DNS_TRANSACTION_PENDING
)
248 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
253 static int dns_transaction_open_tcp(DnsTransaction
*t
) {
254 DnsServer
*server
= NULL
;
255 _cleanup_close_
int fd
= -1;
263 switch (t
->scope
->protocol
) {
264 case DNS_PROTOCOL_DNS
:
265 fd
= dns_scope_tcp_socket(t
->scope
, AF_UNSPEC
, NULL
, 53, &server
);
268 case DNS_PROTOCOL_LLMNR
:
269 /* When we already received a reply to this (but it was truncated), send to its sender address */
271 fd
= dns_scope_tcp_socket(t
->scope
, t
->received
->family
, &t
->received
->sender
, t
->received
->sender_port
, NULL
);
273 union in_addr_union address
;
274 int family
= AF_UNSPEC
;
276 /* Otherwise, try to talk to the owner of a
277 * the IP address, in case this is a reverse
280 r
= dns_name_address(DNS_RESOURCE_KEY_NAME(t
->key
), &family
, &address
);
285 if (family
!= t
->scope
->family
)
288 fd
= dns_scope_tcp_socket(t
->scope
, family
, &address
, LLMNR_PORT
, NULL
);
294 return -EAFNOSUPPORT
;
300 r
= dns_stream_new(t
->scope
->manager
, &t
->stream
, t
->scope
->protocol
, fd
);
306 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
308 t
->stream
= dns_stream_free(t
->stream
);
312 dns_server_unref(t
->server
);
313 t
->server
= dns_server_ref(server
);
314 t
->received
= dns_packet_unref(t
->received
);
315 t
->stream
->complete
= on_stream_complete
;
316 t
->stream
->transaction
= t
;
318 /* The interface index is difficult to determine if we are
319 * connecting to the local host, hence fill this in right away
320 * instead of determining it from the socket */
322 t
->stream
->ifindex
= t
->scope
->link
->ifindex
;
327 static void dns_transaction_next_dns_server(DnsTransaction
*t
) {
330 t
->server
= dns_server_unref(t
->server
);
331 t
->dns_udp_event_source
= sd_event_source_unref(t
->dns_udp_event_source
);
332 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
334 dns_scope_next_dns_server(t
->scope
);
337 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
) {
343 assert(t
->state
== DNS_TRANSACTION_PENDING
);
345 assert(t
->scope
->manager
);
347 /* Note that this call might invalidate the query. Callers
348 * should hence not attempt to access the query or transaction
349 * after calling this function. */
351 switch (t
->scope
->protocol
) {
352 case DNS_PROTOCOL_LLMNR
:
353 assert(t
->scope
->link
);
355 /* For LLMNR we will not accept any packets from other
358 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
361 if (p
->family
!= t
->scope
->family
)
364 /* Tentative packets are not full responses but still
365 * useful for identifying uniqueness conflicts during
367 if (DNS_PACKET_LLMNR_T(p
)) {
368 dns_transaction_tentative(t
, p
);
374 case DNS_PROTOCOL_DNS
:
378 assert_not_reached("Invalid DNS protocol.");
381 if (t
->received
!= p
) {
382 dns_packet_unref(t
->received
);
383 t
->received
= dns_packet_ref(p
);
386 if (p
->ipproto
== IPPROTO_TCP
) {
387 if (DNS_PACKET_TC(p
)) {
388 /* Truncated via TCP? Somebody must be fucking with us */
389 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
393 if (DNS_PACKET_ID(p
) != t
->id
) {
394 /* Not the reply to our query? Somebody must be fucking with us */
395 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
400 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
402 switch (t
->scope
->protocol
) {
403 case DNS_PROTOCOL_DNS
:
406 dns_server_packet_received(t
->server
, ts
- t
->start_usec
);
409 case DNS_PROTOCOL_LLMNR
:
410 case DNS_PROTOCOL_MDNS
:
411 dns_scope_packet_received(t
->scope
, ts
- t
->start_usec
);
418 if (DNS_PACKET_TC(p
)) {
419 /* Response was truncated, let's try again with good old TCP */
420 r
= dns_transaction_open_tcp(t
);
422 /* No servers found? Damn! */
423 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
427 /* On LLMNR, if we cannot connect to the host,
428 * we immediately give up */
429 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
430 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
434 /* On DNS, couldn't send? Try immediately again, with a new server */
435 dns_transaction_next_dns_server(t
);
437 r
= dns_transaction_go(t
);
439 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
447 /* Parse and update the cache */
448 r
= dns_packet_extract(p
);
450 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
454 /* Only consider responses with equivalent query section to the request */
455 if (p
->question
->n_keys
!= 1 || dns_resource_key_equal(p
->question
->keys
[0], t
->key
) <= 0) {
456 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
460 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
461 dns_cache_put(&t
->scope
->cache
, p
->question
, DNS_PACKET_RCODE(p
), p
->answer
, DNS_PACKET_ANCOUNT(p
), 0, p
->family
, &p
->sender
);
463 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_SUCCESS
)
464 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
466 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
469 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
470 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
471 DnsTransaction
*t
= userdata
;
477 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
481 if (dns_packet_validate_reply(p
) > 0 &&
482 DNS_PACKET_ID(p
) == t
->id
)
483 dns_transaction_process_reply(t
, p
);
485 log_debug("Invalid DNS packet.");
490 static int dns_transaction_emit(DnsTransaction
*t
) {
495 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->server
) {
496 DnsServer
*server
= NULL
;
497 _cleanup_close_
int fd
= -1;
499 fd
= dns_scope_udp_dns_socket(t
->scope
, &server
);
503 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
509 t
->server
= dns_server_ref(server
);
512 r
= dns_scope_emit(t
->scope
, t
->dns_udp_fd
, t
->sent
);
519 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
520 DnsTransaction
*t
= userdata
;
526 /* Timeout reached? Try again, with a new server */
527 dns_transaction_next_dns_server(t
);
529 /* ... and possibly increased timeout */
531 dns_server_packet_lost(t
->server
, usec
- t
->start_usec
);
533 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
535 r
= dns_transaction_go(t
);
537 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
542 static int dns_transaction_make_packet(DnsTransaction
*t
) {
543 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
551 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0);
555 r
= dns_scope_good_key(t
->scope
, t
->key
);
561 r
= dns_packet_append_key(p
, t
->key
, NULL
);
565 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
566 DNS_PACKET_HEADER(p
)->id
= t
->id
;
574 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
578 switch (t
->scope
->protocol
) {
579 case DNS_PROTOCOL_DNS
:
582 return t
->server
->resend_timeout
;
583 case DNS_PROTOCOL_LLMNR
:
584 case DNS_PROTOCOL_MDNS
:
585 return t
->scope
->resend_timeout
;
587 assert_not_reached("Invalid DNS protocol.");
591 int dns_transaction_go(DnsTransaction
*t
) {
598 had_stream
= !!t
->stream
;
600 dns_transaction_stop(t
);
602 log_debug("Excercising transaction on scope %s on %s/%s",
603 dns_protocol_to_string(t
->scope
->protocol
),
604 t
->scope
->link
? t
->scope
->link
->name
: "*",
605 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
));
607 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
608 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
612 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& had_stream
) {
613 /* If we already tried via a stream, then we don't
614 * retry on LLMNR. See RFC 4795, Section 2.7. */
615 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
619 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
623 t
->received
= dns_packet_unref(t
->received
);
624 t
->cached
= dns_answer_unref(t
->cached
);
627 /* Check the cache, but only if this transaction is not used
628 * for probing or verifying a zone item. */
629 if (set_isempty(t
->zone_items
)) {
631 /* Before trying the cache, let's make sure we figured out a
632 * server to use. Should this cause a change of server this
633 * might flush the cache. */
634 dns_scope_get_dns_server(t
->scope
);
636 /* Let's then prune all outdated entries */
637 dns_cache_prune(&t
->scope
->cache
);
639 r
= dns_cache_lookup(&t
->scope
->cache
, t
->key
, &t
->cached_rcode
, &t
->cached
);
643 if (t
->cached_rcode
== DNS_RCODE_SUCCESS
)
644 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
646 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
651 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& !t
->initial_jitter
) {
654 /* RFC 4795 Section 2.7 suggests all queries should be
655 * delayed by a random time from 0 to JITTER_INTERVAL. */
657 t
->initial_jitter
= true;
659 random_bytes(&jitter
, sizeof(jitter
));
660 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
662 r
= sd_event_add_time(
663 t
->scope
->manager
->event
,
664 &t
->timeout_event_source
,
665 clock_boottime_or_monotonic(),
667 LLMNR_JITTER_INTERVAL_USEC
,
668 on_transaction_timeout
, t
);
673 t
->state
= DNS_TRANSACTION_PENDING
;
675 log_debug("Delaying LLMNR transaction for " USEC_FMT
"us.", jitter
);
679 /* Otherwise, we need to ask the network */
680 r
= dns_transaction_make_packet(t
);
682 /* Not the right request to make on this network?
683 * (i.e. an A request made on IPv6 or an AAAA request
684 * made on IPv4, on LLMNR or mDNS.) */
685 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
691 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
692 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "in-addr.arpa") > 0 ||
693 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "ip6.arpa") > 0)) {
695 /* RFC 4795, Section 2.4. says reverse lookups shall
696 * always be made via TCP on LLMNR */
697 r
= dns_transaction_open_tcp(t
);
699 /* Try via UDP, and if that fails due to large size try via TCP */
700 r
= dns_transaction_emit(t
);
702 r
= dns_transaction_open_tcp(t
);
705 /* No servers to send this to? */
706 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
709 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
) {
710 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
714 /* Couldn't send? Try immediately again, with a new server */
715 dns_transaction_next_dns_server(t
);
717 return dns_transaction_go(t
);
720 r
= sd_event_add_time(
721 t
->scope
->manager
->event
,
722 &t
->timeout_event_source
,
723 clock_boottime_or_monotonic(),
724 ts
+ transaction_get_resend_timeout(t
), 0,
725 on_transaction_timeout
, t
);
729 t
->state
= DNS_TRANSACTION_PENDING
;
733 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
734 [DNS_TRANSACTION_NULL
] = "null",
735 [DNS_TRANSACTION_PENDING
] = "pending",
736 [DNS_TRANSACTION_FAILURE
] = "failure",
737 [DNS_TRANSACTION_SUCCESS
] = "success",
738 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
739 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
740 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
741 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
742 [DNS_TRANSACTION_RESOURCES
] = "resources",
743 [DNS_TRANSACTION_ABORTED
] = "aborted",
745 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);