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-transaction.h"
28 #include "resolved-llmnr.h"
29 #include "string-table.h"
31 DnsTransaction
* dns_transaction_free(DnsTransaction
*t
) {
38 sd_event_source_unref(t
->timeout_event_source
);
40 dns_packet_unref(t
->sent
);
41 dns_packet_unref(t
->received
);
42 dns_answer_unref(t
->cached
);
44 sd_event_source_unref(t
->dns_udp_event_source
);
45 safe_close(t
->dns_udp_fd
);
47 dns_server_unref(t
->server
);
48 dns_stream_free(t
->stream
);
51 hashmap_remove(t
->scope
->transactions
, t
->key
);
54 hashmap_remove(t
->scope
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
57 dns_resource_key_unref(t
->key
);
59 while ((q
= set_steal_first(t
->queries
)))
60 set_remove(q
->transactions
, t
);
63 while ((i
= set_steal_first(t
->zone_items
)))
64 i
->probe_transaction
= NULL
;
65 set_free(t
->zone_items
);
71 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction
*, dns_transaction_free
);
73 void dns_transaction_gc(DnsTransaction
*t
) {
79 if (set_isempty(t
->queries
) && set_isempty(t
->zone_items
))
80 dns_transaction_free(t
);
83 int dns_transaction_new(DnsTransaction
**ret
, DnsScope
*s
, DnsResourceKey
*key
) {
84 _cleanup_(dns_transaction_freep
) DnsTransaction
*t
= NULL
;
91 r
= hashmap_ensure_allocated(&s
->manager
->dns_transactions
, NULL
);
95 r
= hashmap_ensure_allocated(&s
->transactions
, &dns_resource_key_hash_ops
);
99 t
= new0(DnsTransaction
, 1);
104 t
->key
= dns_resource_key_ref(key
);
106 /* Find a fresh, unused transaction id */
108 random_bytes(&t
->id
, sizeof(t
->id
));
110 hashmap_get(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
)));
112 r
= hashmap_put(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
), t
);
118 r
= hashmap_put(s
->transactions
, t
->key
, t
);
120 hashmap_remove(s
->manager
->dns_transactions
, UINT_TO_PTR(t
->id
));
134 static void dns_transaction_stop(DnsTransaction
*t
) {
137 t
->timeout_event_source
= sd_event_source_unref(t
->timeout_event_source
);
138 t
->stream
= dns_stream_free(t
->stream
);
141 static void dns_transaction_tentative(DnsTransaction
*t
, DnsPacket
*p
) {
142 _cleanup_free_
char *pretty
= NULL
;
148 if (manager_our_packet(t
->scope
->manager
, p
) != 0)
151 in_addr_to_string(p
->family
, &p
->sender
, &pretty
);
153 log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
154 dns_protocol_to_string(t
->scope
->protocol
),
155 t
->scope
->link
? t
->scope
->link
->name
: "*",
156 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
159 /* RFC 4795, Section 4.1 says that the peer with the
160 * lexicographically smaller IP address loses */
161 if (memcmp(&p
->sender
, &p
->destination
, FAMILY_ADDRESS_SIZE(p
->family
)) >= 0) {
162 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
166 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
169 while ((z
= set_first(t
->zone_items
))) {
170 /* First, make sure the zone item drops the reference
172 dns_zone_item_probe_stop(z
);
174 /* Secondly, report this as conflict, so that we might
175 * look for a different hostname */
176 dns_zone_item_conflict(z
);
180 dns_transaction_gc(t
);
183 void dns_transaction_complete(DnsTransaction
*t
, DnsTransactionState state
) {
189 assert(!IN_SET(state
, DNS_TRANSACTION_NULL
, DNS_TRANSACTION_PENDING
));
191 /* Note that this call might invalidate the query. Callers
192 * should hence not attempt to access the query or transaction
193 * after calling this function. */
195 log_debug("Transaction on scope %s on %s/%s now complete with <%s>",
196 dns_protocol_to_string(t
->scope
->protocol
),
197 t
->scope
->link
? t
->scope
->link
->name
: "*",
198 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
),
199 dns_transaction_state_to_string(state
));
203 dns_transaction_stop(t
);
205 /* Notify all queries that are interested, but make sure the
206 * transaction isn't freed while we are still looking at it */
208 SET_FOREACH(q
, t
->queries
, i
)
210 SET_FOREACH(z
, t
->zone_items
, i
)
211 dns_zone_item_ready(z
);
214 dns_transaction_gc(t
);
217 static int on_stream_complete(DnsStream
*s
, int error
) {
218 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
222 assert(s
->transaction
);
224 /* Copy the data we care about out of the stream before we
227 p
= dns_packet_ref(s
->read_packet
);
229 t
->stream
= dns_stream_free(t
->stream
);
232 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
236 if (dns_packet_validate_reply(p
) <= 0) {
237 log_debug("Invalid LLMNR TCP packet.");
238 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
242 dns_scope_check_conflicts(t
->scope
, p
);
245 dns_transaction_process_reply(t
, p
);
248 /* If the response wasn't useful, then complete the transition now */
249 if (t
->state
== DNS_TRANSACTION_PENDING
)
250 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
255 static int dns_transaction_open_tcp(DnsTransaction
*t
) {
256 DnsServer
*server
= NULL
;
257 _cleanup_close_
int fd
= -1;
265 switch (t
->scope
->protocol
) {
266 case DNS_PROTOCOL_DNS
:
267 fd
= dns_scope_tcp_socket(t
->scope
, AF_UNSPEC
, NULL
, 53, &server
);
270 case DNS_PROTOCOL_LLMNR
:
271 /* When we already received a reply to this (but it was truncated), send to its sender address */
273 fd
= dns_scope_tcp_socket(t
->scope
, t
->received
->family
, &t
->received
->sender
, t
->received
->sender_port
, NULL
);
275 union in_addr_union address
;
276 int family
= AF_UNSPEC
;
278 /* Otherwise, try to talk to the owner of a
279 * the IP address, in case this is a reverse
282 r
= dns_name_address(DNS_RESOURCE_KEY_NAME(t
->key
), &family
, &address
);
287 if (family
!= t
->scope
->family
)
290 fd
= dns_scope_tcp_socket(t
->scope
, family
, &address
, LLMNR_PORT
, NULL
);
296 return -EAFNOSUPPORT
;
302 r
= dns_stream_new(t
->scope
->manager
, &t
->stream
, t
->scope
->protocol
, fd
);
308 r
= dns_stream_write_packet(t
->stream
, t
->sent
);
310 t
->stream
= dns_stream_free(t
->stream
);
314 dns_server_unref(t
->server
);
315 t
->server
= dns_server_ref(server
);
316 t
->received
= dns_packet_unref(t
->received
);
317 t
->stream
->complete
= on_stream_complete
;
318 t
->stream
->transaction
= t
;
320 /* The interface index is difficult to determine if we are
321 * connecting to the local host, hence fill this in right away
322 * instead of determining it from the socket */
324 t
->stream
->ifindex
= t
->scope
->link
->ifindex
;
329 static void dns_transaction_next_dns_server(DnsTransaction
*t
) {
332 t
->server
= dns_server_unref(t
->server
);
333 t
->dns_udp_event_source
= sd_event_source_unref(t
->dns_udp_event_source
);
334 t
->dns_udp_fd
= safe_close(t
->dns_udp_fd
);
336 dns_scope_next_dns_server(t
->scope
);
339 void dns_transaction_process_reply(DnsTransaction
*t
, DnsPacket
*p
) {
345 assert(t
->state
== DNS_TRANSACTION_PENDING
);
347 assert(t
->scope
->manager
);
349 /* Note that this call might invalidate the query. Callers
350 * should hence not attempt to access the query or transaction
351 * after calling this function. */
353 switch (t
->scope
->protocol
) {
354 case DNS_PROTOCOL_LLMNR
:
355 assert(t
->scope
->link
);
357 /* For LLMNR we will not accept any packets from other
360 if (p
->ifindex
!= t
->scope
->link
->ifindex
)
363 if (p
->family
!= t
->scope
->family
)
366 /* Tentative packets are not full responses but still
367 * useful for identifying uniqueness conflicts during
369 if (DNS_PACKET_LLMNR_T(p
)) {
370 dns_transaction_tentative(t
, p
);
376 case DNS_PROTOCOL_DNS
:
380 assert_not_reached("Invalid DNS protocol.");
383 if (t
->received
!= p
) {
384 dns_packet_unref(t
->received
);
385 t
->received
= dns_packet_ref(p
);
388 if (p
->ipproto
== IPPROTO_TCP
) {
389 if (DNS_PACKET_TC(p
)) {
390 /* Truncated via TCP? Somebody must be fucking with us */
391 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
395 if (DNS_PACKET_ID(p
) != t
->id
) {
396 /* Not the reply to our query? Somebody must be fucking with us */
397 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
402 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
404 switch (t
->scope
->protocol
) {
405 case DNS_PROTOCOL_DNS
:
408 dns_server_packet_received(t
->server
, ts
- t
->start_usec
);
411 case DNS_PROTOCOL_LLMNR
:
412 case DNS_PROTOCOL_MDNS
:
413 dns_scope_packet_received(t
->scope
, ts
- t
->start_usec
);
420 if (DNS_PACKET_TC(p
)) {
421 /* Response was truncated, let's try again with good old TCP */
422 r
= dns_transaction_open_tcp(t
);
424 /* No servers found? Damn! */
425 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
429 /* On LLMNR, if we cannot connect to the host,
430 * we immediately give up */
431 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
) {
432 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
436 /* On DNS, couldn't send? Try immediately again, with a new server */
437 dns_transaction_next_dns_server(t
);
439 r
= dns_transaction_go(t
);
441 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
449 /* Parse and update the cache */
450 r
= dns_packet_extract(p
);
452 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
456 /* Only consider responses with equivalent query section to the request */
457 if (p
->question
->n_keys
!= 1 || dns_resource_key_equal(p
->question
->keys
[0], t
->key
) <= 0) {
458 dns_transaction_complete(t
, DNS_TRANSACTION_INVALID_REPLY
);
462 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
463 dns_cache_put(&t
->scope
->cache
, t
->key
, DNS_PACKET_RCODE(p
), p
->answer
, DNS_PACKET_ANCOUNT(p
), 0, p
->family
, &p
->sender
);
465 if (DNS_PACKET_RCODE(p
) == DNS_RCODE_SUCCESS
)
466 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
468 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
471 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
472 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
473 DnsTransaction
*t
= userdata
;
479 r
= manager_recv(t
->scope
->manager
, fd
, DNS_PROTOCOL_DNS
, &p
);
483 if (dns_packet_validate_reply(p
) > 0 &&
484 DNS_PACKET_ID(p
) == t
->id
)
485 dns_transaction_process_reply(t
, p
);
487 log_debug("Invalid DNS packet.");
492 static int dns_transaction_emit(DnsTransaction
*t
) {
497 if (t
->scope
->protocol
== DNS_PROTOCOL_DNS
&& !t
->server
) {
498 DnsServer
*server
= NULL
;
499 _cleanup_close_
int fd
= -1;
501 fd
= dns_scope_udp_dns_socket(t
->scope
, &server
);
505 r
= sd_event_add_io(t
->scope
->manager
->event
, &t
->dns_udp_event_source
, fd
, EPOLLIN
, on_dns_packet
, t
);
511 t
->server
= dns_server_ref(server
);
514 r
= dns_scope_emit(t
->scope
, t
->dns_udp_fd
, t
->sent
);
521 static int on_transaction_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
522 DnsTransaction
*t
= userdata
;
528 /* Timeout reached? Try again, with a new server */
529 dns_transaction_next_dns_server(t
);
531 /* ... and possibly increased timeout */
533 dns_server_packet_lost(t
->server
, usec
- t
->start_usec
);
535 dns_scope_packet_lost(t
->scope
, usec
- t
->start_usec
);
537 r
= dns_transaction_go(t
);
539 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
544 static int dns_transaction_make_packet(DnsTransaction
*t
) {
545 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
553 r
= dns_packet_new_query(&p
, t
->scope
->protocol
, 0);
557 r
= dns_scope_good_key(t
->scope
, t
->key
);
563 r
= dns_packet_append_key(p
, t
->key
, NULL
);
567 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
568 DNS_PACKET_HEADER(p
)->id
= t
->id
;
576 static usec_t
transaction_get_resend_timeout(DnsTransaction
*t
) {
580 switch (t
->scope
->protocol
) {
581 case DNS_PROTOCOL_DNS
:
584 return t
->server
->resend_timeout
;
585 case DNS_PROTOCOL_LLMNR
:
586 case DNS_PROTOCOL_MDNS
:
587 return t
->scope
->resend_timeout
;
589 assert_not_reached("Invalid DNS protocol.");
593 int dns_transaction_go(DnsTransaction
*t
) {
600 had_stream
= !!t
->stream
;
602 dns_transaction_stop(t
);
604 log_debug("Excercising transaction on scope %s on %s/%s",
605 dns_protocol_to_string(t
->scope
->protocol
),
606 t
->scope
->link
? t
->scope
->link
->name
: "*",
607 t
->scope
->family
== AF_UNSPEC
? "*" : af_to_name(t
->scope
->family
));
609 if (t
->n_attempts
>= TRANSACTION_ATTEMPTS_MAX(t
->scope
->protocol
)) {
610 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
614 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& had_stream
) {
615 /* If we already tried via a stream, then we don't
616 * retry on LLMNR. See RFC 4795, Section 2.7. */
617 dns_transaction_complete(t
, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
);
621 assert_se(sd_event_now(t
->scope
->manager
->event
, clock_boottime_or_monotonic(), &ts
) >= 0);
625 t
->received
= dns_packet_unref(t
->received
);
626 t
->cached
= dns_answer_unref(t
->cached
);
629 /* Check the zone, but obly if this transaction is not used
630 * for probing or verifying a zone item. */
631 if (set_isempty(t
->zone_items
)) {
633 r
= dns_zone_lookup(&t
->scope
->zone
, t
->key
, &t
->cached
, NULL
, NULL
);
637 t
->cached_rcode
= DNS_RCODE_SUCCESS
;
638 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
643 /* Check the cache, but only if this transaction is not used
644 * for probing or verifying a zone item. */
645 if (set_isempty(t
->zone_items
)) {
647 /* Before trying the cache, let's make sure we figured out a
648 * server to use. Should this cause a change of server this
649 * might flush the cache. */
650 dns_scope_get_dns_server(t
->scope
);
652 /* Let's then prune all outdated entries */
653 dns_cache_prune(&t
->scope
->cache
);
655 r
= dns_cache_lookup(&t
->scope
->cache
, t
->key
, &t
->cached_rcode
, &t
->cached
);
659 if (t
->cached_rcode
== DNS_RCODE_SUCCESS
)
660 dns_transaction_complete(t
, DNS_TRANSACTION_SUCCESS
);
662 dns_transaction_complete(t
, DNS_TRANSACTION_FAILURE
);
667 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&& !t
->initial_jitter
) {
670 /* RFC 4795 Section 2.7 suggests all queries should be
671 * delayed by a random time from 0 to JITTER_INTERVAL. */
673 t
->initial_jitter
= true;
675 random_bytes(&jitter
, sizeof(jitter
));
676 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
678 r
= sd_event_add_time(
679 t
->scope
->manager
->event
,
680 &t
->timeout_event_source
,
681 clock_boottime_or_monotonic(),
683 LLMNR_JITTER_INTERVAL_USEC
,
684 on_transaction_timeout
, t
);
689 t
->state
= DNS_TRANSACTION_PENDING
;
691 log_debug("Delaying LLMNR transaction for " USEC_FMT
"us.", jitter
);
695 /* Otherwise, we need to ask the network */
696 r
= dns_transaction_make_packet(t
);
698 /* Not the right request to make on this network?
699 * (i.e. an A request made on IPv6 or an AAAA request
700 * made on IPv4, on LLMNR or mDNS.) */
701 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
707 if (t
->scope
->protocol
== DNS_PROTOCOL_LLMNR
&&
708 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "in-addr.arpa") > 0 ||
709 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t
->key
), "ip6.arpa") > 0)) {
711 /* RFC 4795, Section 2.4. says reverse lookups shall
712 * always be made via TCP on LLMNR */
713 r
= dns_transaction_open_tcp(t
);
715 /* Try via UDP, and if that fails due to large size try via TCP */
716 r
= dns_transaction_emit(t
);
718 r
= dns_transaction_open_tcp(t
);
721 /* No servers to send this to? */
722 dns_transaction_complete(t
, DNS_TRANSACTION_NO_SERVERS
);
725 if (t
->scope
->protocol
!= DNS_PROTOCOL_DNS
) {
726 dns_transaction_complete(t
, DNS_TRANSACTION_RESOURCES
);
730 /* Couldn't send? Try immediately again, with a new server */
731 dns_transaction_next_dns_server(t
);
733 return dns_transaction_go(t
);
736 r
= sd_event_add_time(
737 t
->scope
->manager
->event
,
738 &t
->timeout_event_source
,
739 clock_boottime_or_monotonic(),
740 ts
+ transaction_get_resend_timeout(t
), 0,
741 on_transaction_timeout
, t
);
745 t
->state
= DNS_TRANSACTION_PENDING
;
749 static const char* const dns_transaction_state_table
[_DNS_TRANSACTION_STATE_MAX
] = {
750 [DNS_TRANSACTION_NULL
] = "null",
751 [DNS_TRANSACTION_PENDING
] = "pending",
752 [DNS_TRANSACTION_FAILURE
] = "failure",
753 [DNS_TRANSACTION_SUCCESS
] = "success",
754 [DNS_TRANSACTION_NO_SERVERS
] = "no-servers",
755 [DNS_TRANSACTION_TIMEOUT
] = "timeout",
756 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
] = "attempts-max-reached",
757 [DNS_TRANSACTION_INVALID_REPLY
] = "invalid-reply",
758 [DNS_TRANSACTION_RESOURCES
] = "resources",
759 [DNS_TRANSACTION_ABORTED
] = "aborted",
761 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state
, DnsTransactionState
);