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/>.
22 #include <netinet/tcp.h>
25 #include "alloc-util.h"
26 #include "dns-domain.h"
28 #include "hostname-util.h"
30 #include "random-util.h"
31 #include "resolved-dns-scope.h"
32 #include "resolved-llmnr.h"
33 #include "resolved-mdns.h"
34 #include "socket-util.h"
37 #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
38 #define MULTICAST_RATELIMIT_BURST 1000
40 /* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
41 #define MULTICAST_RESEND_TIMEOUT_MIN_USEC (100 * USEC_PER_MSEC)
42 #define MULTICAST_RESEND_TIMEOUT_MAX_USEC (1 * USEC_PER_SEC)
44 int dns_scope_new(Manager
*m
, DnsScope
**ret
, Link
*l
, DnsProtocol protocol
, int family
) {
50 s
= new0(DnsScope
, 1);
56 s
->protocol
= protocol
;
58 s
->resend_timeout
= MULTICAST_RESEND_TIMEOUT_MIN_USEC
;
60 LIST_PREPEND(scopes
, m
->dns_scopes
, s
);
62 dns_scope_llmnr_membership(s
, true);
63 dns_scope_mdns_membership(s
, true);
65 log_debug("New scope on link %s, protocol %s, family %s", l
? l
->name
: "*", dns_protocol_to_string(protocol
), family
== AF_UNSPEC
? "*" : af_to_name(family
));
67 /* Enforce ratelimiting for the multicast protocols */
68 RATELIMIT_INIT(s
->ratelimit
, MULTICAST_RATELIMIT_INTERVAL_USEC
, MULTICAST_RATELIMIT_BURST
);
74 static void dns_scope_abort_transactions(DnsScope
*s
) {
77 while (s
->transactions
) {
78 DnsTransaction
*t
= s
->transactions
;
80 /* Abort the transaction, but make sure it is not
81 * freed while we still look at it */
84 dns_transaction_complete(t
, DNS_TRANSACTION_ABORTED
);
87 dns_transaction_free(t
);
91 DnsScope
* dns_scope_free(DnsScope
*s
) {
92 DnsResourceRecord
*rr
;
97 log_debug("Removing scope on link %s, protocol %s, family %s", s
->link
? s
->link
->name
: "*", dns_protocol_to_string(s
->protocol
), s
->family
== AF_UNSPEC
? "*" : af_to_name(s
->family
));
99 dns_scope_llmnr_membership(s
, false);
100 dns_scope_mdns_membership(s
, false);
101 dns_scope_abort_transactions(s
);
103 while (s
->query_candidates
)
104 dns_query_candidate_free(s
->query_candidates
);
106 hashmap_free(s
->transactions_by_key
);
108 while ((rr
= ordered_hashmap_steal_first(s
->conflict_queue
)))
109 dns_resource_record_unref(rr
);
111 ordered_hashmap_free(s
->conflict_queue
);
112 sd_event_source_unref(s
->conflict_event_source
);
114 dns_cache_flush(&s
->cache
);
115 dns_zone_flush(&s
->zone
);
117 LIST_REMOVE(scopes
, s
->manager
->dns_scopes
, s
);
123 DnsServer
*dns_scope_get_dns_server(DnsScope
*s
) {
126 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
130 return link_get_dns_server(s
->link
);
132 return manager_get_dns_server(s
->manager
);
135 void dns_scope_next_dns_server(DnsScope
*s
) {
138 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
142 link_next_dns_server(s
->link
);
144 manager_next_dns_server(s
->manager
);
147 void dns_scope_packet_received(DnsScope
*s
, usec_t rtt
) {
150 if (rtt
<= s
->max_rtt
)
154 s
->resend_timeout
= MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC
, s
->max_rtt
* 2), MULTICAST_RESEND_TIMEOUT_MAX_USEC
);
157 void dns_scope_packet_lost(DnsScope
*s
, usec_t usec
) {
160 if (s
->resend_timeout
<= usec
)
161 s
->resend_timeout
= MIN(s
->resend_timeout
* 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC
);
164 int dns_scope_emit(DnsScope
*s
, int fd
, DnsServer
*server
, DnsPacket
*p
) {
165 union in_addr_union addr
;
169 size_t saved_size
= 0;
173 assert(p
->protocol
== s
->protocol
);
174 assert((s
->protocol
== DNS_PROTOCOL_DNS
) != (fd
< 0));
178 ifindex
= s
->link
->ifindex
;
180 mtu
= manager_find_mtu(s
->manager
);
182 switch (s
->protocol
) {
183 case DNS_PROTOCOL_DNS
:
186 if (DNS_PACKET_QDCOUNT(p
) > 1)
189 if (server
->possible_features
>= DNS_SERVER_FEATURE_LEVEL_EDNS0
) {
193 edns_do
= server
->possible_features
>= DNS_SERVER_FEATURE_LEVEL_DO
;
195 if (server
->possible_features
>= DNS_SERVER_FEATURE_LEVEL_LARGE
)
196 packet_size
= DNS_PACKET_UNICAST_SIZE_LARGE_MAX
;
198 packet_size
= server
->received_udp_packet_max
;
200 r
= dns_packet_append_opt_rr(p
, packet_size
, edns_do
, &saved_size
);
204 DNS_PACKET_HEADER(p
)->arcount
= htobe16(be16toh(DNS_PACKET_HEADER(p
)->arcount
) + 1);
207 if (p
->size
> DNS_PACKET_UNICAST_SIZE_MAX
)
210 if (p
->size
+ UDP_PACKET_HEADER_SIZE
> mtu
)
213 r
= manager_write(s
->manager
, fd
, p
);
217 if (saved_size
> 0) {
218 dns_packet_truncate(p
, saved_size
);
220 DNS_PACKET_HEADER(p
)->arcount
= htobe16(be16toh(DNS_PACKET_HEADER(p
)->arcount
) - 1);
225 case DNS_PROTOCOL_LLMNR
:
226 if (DNS_PACKET_QDCOUNT(p
) > 1)
229 if (!ratelimit_test(&s
->ratelimit
))
234 if (family
== AF_INET
) {
235 addr
.in
= LLMNR_MULTICAST_IPV4_ADDRESS
;
236 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
237 } else if (family
== AF_INET6
) {
238 addr
.in6
= LLMNR_MULTICAST_IPV6_ADDRESS
;
239 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
241 return -EAFNOSUPPORT
;
245 r
= manager_send(s
->manager
, fd
, ifindex
, family
, &addr
, LLMNR_PORT
, p
);
251 case DNS_PROTOCOL_MDNS
:
252 if (!ratelimit_test(&s
->ratelimit
))
257 if (family
== AF_INET
) {
258 addr
.in
= MDNS_MULTICAST_IPV4_ADDRESS
;
259 fd
= manager_mdns_ipv4_fd(s
->manager
);
260 } else if (family
== AF_INET6
) {
261 addr
.in6
= MDNS_MULTICAST_IPV6_ADDRESS
;
262 fd
= manager_mdns_ipv6_fd(s
->manager
);
264 return -EAFNOSUPPORT
;
268 r
= manager_send(s
->manager
, fd
, ifindex
, family
, &addr
, MDNS_PORT
, p
);
275 return -EAFNOSUPPORT
;
281 static int dns_scope_socket(DnsScope
*s
, int type
, int family
, const union in_addr_union
*address
, uint16_t port
, DnsServer
**server
) {
282 DnsServer
*srv
= NULL
;
283 _cleanup_close_
int fd
= -1;
284 union sockaddr_union sa
= {};
286 static const int one
= 1;
290 assert((family
== AF_UNSPEC
) == !address
);
292 if (family
== AF_UNSPEC
) {
293 srv
= dns_scope_get_dns_server(s
);
297 srv
->possible_features
= dns_server_possible_features(srv
);
299 if (type
== SOCK_DGRAM
&& srv
->possible_features
< DNS_SERVER_FEATURE_LEVEL_UDP
)
302 sa
.sa
.sa_family
= srv
->family
;
303 if (srv
->family
== AF_INET
) {
304 sa
.in
.sin_port
= htobe16(port
);
305 sa
.in
.sin_addr
= srv
->address
.in
;
306 salen
= sizeof(sa
.in
);
307 } else if (srv
->family
== AF_INET6
) {
308 sa
.in6
.sin6_port
= htobe16(port
);
309 sa
.in6
.sin6_addr
= srv
->address
.in6
;
310 sa
.in6
.sin6_scope_id
= s
->link
? s
->link
->ifindex
: 0;
311 salen
= sizeof(sa
.in6
);
313 return -EAFNOSUPPORT
;
315 sa
.sa
.sa_family
= family
;
317 if (family
== AF_INET
) {
318 sa
.in
.sin_port
= htobe16(port
);
319 sa
.in
.sin_addr
= address
->in
;
320 salen
= sizeof(sa
.in
);
321 } else if (family
== AF_INET6
) {
322 sa
.in6
.sin6_port
= htobe16(port
);
323 sa
.in6
.sin6_addr
= address
->in6
;
324 sa
.in6
.sin6_scope_id
= s
->link
? s
->link
->ifindex
: 0;
325 salen
= sizeof(sa
.in6
);
327 return -EAFNOSUPPORT
;
330 fd
= socket(sa
.sa
.sa_family
, type
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
334 if (type
== SOCK_STREAM
) {
335 r
= setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &one
, sizeof(one
));
341 uint32_t ifindex
= htobe32(s
->link
->ifindex
);
343 if (sa
.sa
.sa_family
== AF_INET
) {
344 r
= setsockopt(fd
, IPPROTO_IP
, IP_UNICAST_IF
, &ifindex
, sizeof(ifindex
));
347 } else if (sa
.sa
.sa_family
== AF_INET6
) {
348 r
= setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_IF
, &ifindex
, sizeof(ifindex
));
354 if (s
->protocol
== DNS_PROTOCOL_LLMNR
) {
355 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
357 if (sa
.sa
.sa_family
== AF_INET
) {
358 r
= setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &one
, sizeof(one
));
361 } else if (sa
.sa
.sa_family
== AF_INET6
) {
362 r
= setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &one
, sizeof(one
));
368 r
= connect(fd
, &sa
.sa
, salen
);
369 if (r
< 0 && errno
!= EINPROGRESS
)
381 int dns_scope_udp_dns_socket(DnsScope
*s
, DnsServer
**server
) {
382 return dns_scope_socket(s
, SOCK_DGRAM
, AF_UNSPEC
, NULL
, 53, server
);
385 int dns_scope_tcp_socket(DnsScope
*s
, int family
, const union in_addr_union
*address
, uint16_t port
, DnsServer
**server
) {
386 return dns_scope_socket(s
, SOCK_STREAM
, family
, address
, port
, server
);
389 DnsScopeMatch
dns_scope_good_domain(DnsScope
*s
, int ifindex
, uint64_t flags
, const char *domain
) {
395 /* Checks if the specified domain is something to look up on
396 * this scope. Note that this accepts non-qualified hostnames,
397 * i.e. those without any search path prefixed yet. */
399 if (ifindex
!= 0 && (!s
->link
|| s
->link
->ifindex
!= ifindex
))
402 if ((SD_RESOLVED_FLAGS_MAKE(s
->protocol
, s
->family
, 0) & flags
) == 0)
405 /* Never resolve any loopback hostname or IP address via DNS,
406 * LLMNR or mDNS. Instead, always rely on synthesized RRs for
408 if (is_localhost(domain
) ||
409 dns_name_endswith(domain
, "127.in-addr.arpa") > 0 ||
410 dns_name_equal(domain
, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0)
413 /* Never respond to some of the domains listed in RFC6303 */
414 if (dns_name_endswith(domain
, "0.in-addr.arpa") > 0 ||
415 dns_name_equal(domain
, "255.255.255.255.in-addr.arpa") > 0 ||
416 dns_name_equal(domain
, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0)
419 /* Always honour search domains for routing queries. Note that
420 * we return DNS_SCOPE_YES here, rather than just
421 * DNS_SCOPE_MAYBE, which means wildcard scopes won't be
422 * considered anymore. */
423 LIST_FOREACH(domains
, d
, dns_scope_get_search_domains(s
))
424 if (dns_name_endswith(domain
, d
->name
) > 0)
425 return DNS_SCOPE_YES
;
427 switch (s
->protocol
) {
429 case DNS_PROTOCOL_DNS
:
431 /* Exclude link-local IP ranges */
432 if (dns_name_endswith(domain
, "254.169.in-addr.arpa") == 0 &&
433 dns_name_endswith(domain
, "8.e.f.ip6.arpa") == 0 &&
434 dns_name_endswith(domain
, "9.e.f.ip6.arpa") == 0 &&
435 dns_name_endswith(domain
, "a.e.f.ip6.arpa") == 0 &&
436 dns_name_endswith(domain
, "b.e.f.ip6.arpa") == 0 &&
437 /* If networks use .local in their private setups, they are supposed to also add .local to their search
438 * domains, which we already checked above. Otherwise, we consider .local specific to mDNS and won't
439 * send such queries ordinary DNS servers. */
440 dns_name_endswith(domain
, "local") == 0)
441 return DNS_SCOPE_MAYBE
;
445 case DNS_PROTOCOL_MDNS
:
446 if ((s
->family
== AF_INET
&& dns_name_endswith(domain
, "in-addr.arpa") > 0) ||
447 (s
->family
== AF_INET6
&& dns_name_endswith(domain
, "ip6.arpa") > 0) ||
448 (dns_name_endswith(domain
, "local") > 0 && /* only resolve names ending in .local via mDNS */
449 dns_name_equal(domain
, "local") == 0 && /* but not the single-label "local" name itself */
450 manager_is_own_hostname(s
->manager
, domain
) <= 0)) /* never resolve the local hostname via mDNS */
451 return DNS_SCOPE_MAYBE
;
455 case DNS_PROTOCOL_LLMNR
:
456 if ((s
->family
== AF_INET
&& dns_name_endswith(domain
, "in-addr.arpa") > 0) ||
457 (s
->family
== AF_INET6
&& dns_name_endswith(domain
, "ip6.arpa") > 0) ||
458 (dns_name_is_single_label(domain
) && /* only resolve single label names via LLMNR */
459 !is_gateway_hostname(domain
) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
460 manager_is_own_hostname(s
->manager
, domain
) <= 0)) /* never resolve the local hostname via LLMNR */
461 return DNS_SCOPE_MAYBE
;
466 assert_not_reached("Unknown scope protocol");
470 int dns_scope_good_key(DnsScope
*s
, DnsResourceKey
*key
) {
474 /* Check if it makes sense to resolve the specified key on
475 * this scope. Note that this call assumes as fully qualified
476 * name, i.e. the search suffixes already appended. */
478 if (s
->protocol
== DNS_PROTOCOL_DNS
) {
480 /* On classic DNS, lookin up non-address RRs is always
481 * fine. (Specifically, we want to permit looking up
482 * DNSKEY and DS records on the root and top-level
484 if (!dns_resource_key_is_address(key
))
487 /* However, we refuse to look up A and AAAA RRs on the
488 * root and single-label domains, under the assumption
489 * that those should be resolved via LLMNR or search
490 * path only, and should not be leaked onto the
492 return !(dns_name_is_single_label(DNS_RESOURCE_KEY_NAME(key
)) ||
493 dns_name_is_root(DNS_RESOURCE_KEY_NAME(key
)));
496 /* On mDNS and LLMNR, send A and AAAA queries only on the
497 * respective scopes */
499 if (s
->family
== AF_INET
&& key
->class == DNS_CLASS_IN
&& key
->type
== DNS_TYPE_AAAA
)
502 if (s
->family
== AF_INET6
&& key
->class == DNS_CLASS_IN
&& key
->type
== DNS_TYPE_A
)
508 static int dns_scope_multicast_membership(DnsScope
*s
, bool b
, struct in_addr in
, struct in6_addr in6
) {
514 if (s
->family
== AF_INET
) {
515 struct ip_mreqn mreqn
= {
517 .imr_ifindex
= s
->link
->ifindex
,
520 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
524 /* Always first try to drop membership before we add
525 * one. This is necessary on some devices, such as
528 (void) setsockopt(fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreqn
, sizeof(mreqn
));
530 if (setsockopt(fd
, IPPROTO_IP
, b
? IP_ADD_MEMBERSHIP
: IP_DROP_MEMBERSHIP
, &mreqn
, sizeof(mreqn
)) < 0)
533 } else if (s
->family
== AF_INET6
) {
534 struct ipv6_mreq mreq
= {
535 .ipv6mr_multiaddr
= in6
,
536 .ipv6mr_interface
= s
->link
->ifindex
,
539 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
544 (void) setsockopt(fd
, IPPROTO_IPV6
, IPV6_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));
546 if (setsockopt(fd
, IPPROTO_IPV6
, b
? IPV6_ADD_MEMBERSHIP
: IPV6_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
)) < 0)
549 return -EAFNOSUPPORT
;
554 int dns_scope_llmnr_membership(DnsScope
*s
, bool b
) {
556 if (s
->protocol
!= DNS_PROTOCOL_LLMNR
)
559 return dns_scope_multicast_membership(s
, b
, LLMNR_MULTICAST_IPV4_ADDRESS
, LLMNR_MULTICAST_IPV6_ADDRESS
);
562 int dns_scope_mdns_membership(DnsScope
*s
, bool b
) {
564 if (s
->protocol
!= DNS_PROTOCOL_MDNS
)
567 return dns_scope_multicast_membership(s
, b
, MDNS_MULTICAST_IPV4_ADDRESS
, MDNS_MULTICAST_IPV6_ADDRESS
);
570 static int dns_scope_make_reply_packet(
580 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
587 if ((!q
|| q
->n_keys
<= 0)
588 && (!answer
|| answer
->n_rrs
<= 0)
589 && (!soa
|| soa
->n_rrs
<= 0))
592 r
= dns_packet_new(&p
, s
->protocol
, 0);
596 DNS_PACKET_HEADER(p
)->id
= id
;
597 DNS_PACKET_HEADER(p
)->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(
609 for (i
= 0; i
< q
->n_keys
; i
++) {
610 r
= dns_packet_append_key(p
, q
->keys
[i
], NULL
);
615 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(q
->n_keys
);
619 for (i
= 0; i
< answer
->n_rrs
; i
++) {
620 r
= dns_packet_append_rr(p
, answer
->items
[i
].rr
, NULL
, NULL
);
625 DNS_PACKET_HEADER(p
)->ancount
= htobe16(answer
->n_rrs
);
629 for (i
= 0; i
< soa
->n_rrs
; i
++) {
630 r
= dns_packet_append_rr(p
, soa
->items
[i
].rr
, NULL
, NULL
);
635 DNS_PACKET_HEADER(p
)->arcount
= htobe16(soa
->n_rrs
);
644 static void dns_scope_verify_conflicts(DnsScope
*s
, DnsPacket
*p
) {
651 for (n
= 0; n
< p
->question
->n_keys
; n
++)
652 dns_zone_verify_conflicts(&s
->zone
, p
->question
->keys
[n
]);
654 for (n
= 0; n
< p
->answer
->n_rrs
; n
++)
655 dns_zone_verify_conflicts(&s
->zone
, p
->answer
->items
[n
].rr
->key
);
658 void dns_scope_process_query(DnsScope
*s
, DnsStream
*stream
, DnsPacket
*p
) {
659 _cleanup_(dns_packet_unrefp
) DnsPacket
*reply
= NULL
;
660 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
, *soa
= NULL
;
661 DnsResourceKey
*key
= NULL
;
662 bool tentative
= false;
668 if (p
->protocol
!= DNS_PROTOCOL_LLMNR
)
671 if (p
->ipproto
== IPPROTO_UDP
) {
672 /* Don't accept UDP queries directed to anything but
673 * the LLMNR multicast addresses. See RFC 4795,
676 if (p
->family
== AF_INET
&& !in_addr_equal(AF_INET
, &p
->destination
, (union in_addr_union
*) &LLMNR_MULTICAST_IPV4_ADDRESS
))
679 if (p
->family
== AF_INET6
&& !in_addr_equal(AF_INET6
, &p
->destination
, (union in_addr_union
*) &LLMNR_MULTICAST_IPV6_ADDRESS
))
683 r
= dns_packet_extract(p
);
685 log_debug_errno(r
, "Failed to extract resources from incoming packet: %m");
689 if (DNS_PACKET_LLMNR_C(p
)) {
690 /* Somebody notified us about a possible conflict */
691 dns_scope_verify_conflicts(s
, p
);
695 assert(p
->question
->n_keys
== 1);
696 key
= p
->question
->keys
[0];
698 r
= dns_zone_lookup(&s
->zone
, key
, &answer
, &soa
, &tentative
);
700 log_debug_errno(r
, "Failed to lookup key: %m");
707 dns_answer_order_by_scope(answer
, in_addr_is_link_local(p
->family
, &p
->sender
) > 0);
709 r
= dns_scope_make_reply_packet(s
, DNS_PACKET_ID(p
), DNS_RCODE_SUCCESS
, p
->question
, answer
, soa
, tentative
, &reply
);
711 log_debug_errno(r
, "Failed to build reply packet: %m");
716 r
= dns_stream_write_packet(stream
, reply
);
718 if (!ratelimit_test(&s
->ratelimit
))
721 if (p
->family
== AF_INET
)
722 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
723 else if (p
->family
== AF_INET6
)
724 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
726 log_debug("Unknown protocol");
730 log_debug_errno(fd
, "Failed to get reply socket: %m");
734 /* Note that we always immediately reply to all LLMNR
735 * requests, and do not wait any time, since we
736 * verified uniqueness for all records. Also see RFC
737 * 4795, Section 2.7 */
739 r
= manager_send(s
->manager
, fd
, p
->ifindex
, p
->family
, &p
->sender
, p
->sender_port
, reply
);
743 log_debug_errno(r
, "Failed to send reply packet: %m");
748 DnsTransaction
*dns_scope_find_transaction(DnsScope
*scope
, DnsResourceKey
*key
, bool cache_ok
) {
754 /* Try to find an ongoing transaction that is a equal to the
755 * specified question */
756 t
= hashmap_get(scope
->transactions_by_key
, key
);
760 /* Refuse reusing transactions that completed based on cached
761 * data instead of a real packet, if that's requested. */
763 IN_SET(t
->state
, DNS_TRANSACTION_SUCCESS
, DNS_TRANSACTION_FAILURE
) &&
764 t
->answer_source
!= DNS_TRANSACTION_NETWORK
)
770 static int dns_scope_make_conflict_packet(
772 DnsResourceRecord
*rr
,
775 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
782 r
= dns_packet_new(&p
, s
->protocol
, 0);
786 DNS_PACKET_HEADER(p
)->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(
796 random_bytes(&DNS_PACKET_HEADER(p
)->id
, sizeof(uint16_t));
797 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
798 DNS_PACKET_HEADER(p
)->arcount
= htobe16(1);
800 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
804 r
= dns_packet_append_rr(p
, rr
, NULL
, NULL
);
814 static int on_conflict_dispatch(sd_event_source
*es
, usec_t usec
, void *userdata
) {
815 DnsScope
*scope
= userdata
;
821 scope
->conflict_event_source
= sd_event_source_unref(scope
->conflict_event_source
);
824 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
825 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
827 rr
= ordered_hashmap_steal_first(scope
->conflict_queue
);
831 r
= dns_scope_make_conflict_packet(scope
, rr
, &p
);
833 log_error_errno(r
, "Failed to make conflict packet: %m");
837 r
= dns_scope_emit(scope
, -1, NULL
, p
);
839 log_debug_errno(r
, "Failed to send conflict packet: %m");
845 int dns_scope_notify_conflict(DnsScope
*scope
, DnsResourceRecord
*rr
) {
852 /* We don't send these queries immediately. Instead, we queue
853 * them, and send them after some jitter delay. */
854 r
= ordered_hashmap_ensure_allocated(&scope
->conflict_queue
, &dns_resource_key_hash_ops
);
860 /* We only place one RR per key in the conflict
861 * messages, not all of them. That should be enough to
862 * indicate where there might be a conflict */
863 r
= ordered_hashmap_put(scope
->conflict_queue
, rr
->key
, rr
);
864 if (r
== -EEXIST
|| r
== 0)
867 return log_debug_errno(r
, "Failed to queue conflicting RR: %m");
869 dns_resource_record_ref(rr
);
871 if (scope
->conflict_event_source
)
874 random_bytes(&jitter
, sizeof(jitter
));
875 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
877 r
= sd_event_add_time(scope
->manager
->event
,
878 &scope
->conflict_event_source
,
879 clock_boottime_or_monotonic(),
880 now(clock_boottime_or_monotonic()) + jitter
,
881 LLMNR_JITTER_INTERVAL_USEC
,
882 on_conflict_dispatch
, scope
);
884 return log_debug_errno(r
, "Failed to add conflict dispatch event: %m");
889 void dns_scope_check_conflicts(DnsScope
*scope
, DnsPacket
*p
) {
896 if (p
->protocol
!= DNS_PROTOCOL_LLMNR
)
899 if (DNS_PACKET_RRCOUNT(p
) <= 0)
902 if (DNS_PACKET_LLMNR_C(p
) != 0)
905 if (DNS_PACKET_LLMNR_T(p
) != 0)
908 if (manager_our_packet(scope
->manager
, p
))
911 r
= dns_packet_extract(p
);
913 log_debug_errno(r
, "Failed to extract packet: %m");
917 log_debug("Checking for conflicts...");
919 for (i
= 0; i
< p
->answer
->n_rrs
; i
++) {
921 /* Check for conflicts against the local zone. If we
922 * found one, we won't check any further */
923 r
= dns_zone_check_conflicts(&scope
->zone
, p
->answer
->items
[i
].rr
);
927 /* Check for conflicts against the local cache. If so,
928 * send out an advisory query, to inform everybody */
929 r
= dns_cache_check_conflicts(&scope
->cache
, p
->answer
->items
[i
].rr
, p
->family
, &p
->sender
);
933 dns_scope_notify_conflict(scope
, p
->answer
->items
[i
].rr
);
937 void dns_scope_dump(DnsScope
*s
, FILE *f
) {
943 fputs("[Scope protocol=", f
);
944 fputs(dns_protocol_to_string(s
->protocol
), f
);
947 fputs(" interface=", f
);
948 fputs(s
->link
->name
, f
);
951 if (s
->family
!= AF_UNSPEC
) {
952 fputs(" family=", f
);
953 fputs(af_to_name(s
->family
), f
);
958 if (!dns_zone_is_empty(&s
->zone
)) {
960 dns_zone_dump(&s
->zone
, f
);
963 if (!dns_cache_is_empty(&s
->cache
)) {
964 fputs("CACHE:\n", f
);
965 dns_cache_dump(&s
->cache
, f
);
969 DnsSearchDomain
*dns_scope_get_search_domains(DnsScope
*s
) {
972 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
976 return s
->link
->search_domains
;
978 return s
->manager
->search_domains
;
981 bool dns_scope_name_needs_search_domain(DnsScope
*s
, const char *name
) {
984 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
987 return dns_name_is_single_label(name
);