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 "socket-util.h"
36 #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
37 #define MULTICAST_RATELIMIT_BURST 1000
39 /* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
40 #define MULTICAST_RESEND_TIMEOUT_MIN_USEC (100 * USEC_PER_MSEC)
41 #define MULTICAST_RESEND_TIMEOUT_MAX_USEC (1 * USEC_PER_SEC)
43 int dns_scope_new(Manager
*m
, DnsScope
**ret
, Link
*l
, DnsProtocol protocol
, int family
) {
49 s
= new0(DnsScope
, 1);
55 s
->protocol
= protocol
;
57 s
->resend_timeout
= MULTICAST_RESEND_TIMEOUT_MIN_USEC
;
59 LIST_PREPEND(scopes
, m
->dns_scopes
, s
);
61 dns_scope_llmnr_membership(s
, true);
63 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
));
65 /* Enforce ratelimiting for the multicast protocols */
66 RATELIMIT_INIT(s
->ratelimit
, MULTICAST_RATELIMIT_INTERVAL_USEC
, MULTICAST_RATELIMIT_BURST
);
72 static void dns_scope_abort_transactions(DnsScope
*s
) {
77 while ((t
= hashmap_first(s
->transactions
))) {
78 /* Abort the transaction, but make sure it is not
79 * freed while we still look at it */
82 dns_transaction_complete(t
, DNS_TRANSACTION_ABORTED
);
85 dns_transaction_free(t
);
89 DnsScope
* dns_scope_free(DnsScope
*s
) {
90 DnsResourceRecord
*rr
;
95 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
));
97 dns_scope_llmnr_membership(s
, false);
98 dns_scope_abort_transactions(s
);
100 while (s
->query_candidates
)
101 dns_query_candidate_free(s
->query_candidates
);
103 hashmap_free(s
->transactions
);
105 while ((rr
= ordered_hashmap_steal_first(s
->conflict_queue
)))
106 dns_resource_record_unref(rr
);
108 ordered_hashmap_free(s
->conflict_queue
);
109 sd_event_source_unref(s
->conflict_event_source
);
111 dns_cache_flush(&s
->cache
);
112 dns_zone_flush(&s
->zone
);
114 LIST_REMOVE(scopes
, s
->manager
->dns_scopes
, s
);
120 DnsServer
*dns_scope_get_dns_server(DnsScope
*s
) {
123 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
127 return link_get_dns_server(s
->link
);
129 return manager_get_dns_server(s
->manager
);
132 void dns_scope_next_dns_server(DnsScope
*s
) {
135 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
139 link_next_dns_server(s
->link
);
141 manager_next_dns_server(s
->manager
);
144 void dns_scope_packet_received(DnsScope
*s
, usec_t rtt
) {
147 if (rtt
<= s
->max_rtt
)
151 s
->resend_timeout
= MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC
, s
->max_rtt
* 2), MULTICAST_RESEND_TIMEOUT_MAX_USEC
);
154 void dns_scope_packet_lost(DnsScope
*s
, usec_t usec
) {
157 if (s
->resend_timeout
<= usec
)
158 s
->resend_timeout
= MIN(s
->resend_timeout
* 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC
);
161 int dns_scope_emit(DnsScope
*s
, int fd
, DnsPacket
*p
) {
162 union in_addr_union addr
;
170 assert(p
->protocol
== s
->protocol
);
171 assert((s
->protocol
== DNS_PROTOCOL_DNS
) != (fd
< 0));
175 ifindex
= s
->link
->ifindex
;
177 mtu
= manager_find_mtu(s
->manager
);
179 switch (s
->protocol
) {
180 case DNS_PROTOCOL_DNS
:
181 if (DNS_PACKET_QDCOUNT(p
) > 1)
184 if (p
->size
> DNS_PACKET_UNICAST_SIZE_MAX
)
187 if (p
->size
+ UDP_PACKET_HEADER_SIZE
> mtu
)
190 r
= manager_write(s
->manager
, fd
, p
);
196 case DNS_PROTOCOL_LLMNR
:
197 if (DNS_PACKET_QDCOUNT(p
) > 1)
200 if (!ratelimit_test(&s
->ratelimit
))
206 if (family
== AF_INET
) {
207 addr
.in
= LLMNR_MULTICAST_IPV4_ADDRESS
;
208 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
209 } else if (family
== AF_INET6
) {
210 addr
.in6
= LLMNR_MULTICAST_IPV6_ADDRESS
;
211 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
213 return -EAFNOSUPPORT
;
217 r
= manager_send(s
->manager
, fd
, ifindex
, family
, &addr
, port
, p
);
224 return -EAFNOSUPPORT
;
230 static int dns_scope_socket(DnsScope
*s
, int type
, int family
, const union in_addr_union
*address
, uint16_t port
, DnsServer
**server
) {
231 DnsServer
*srv
= NULL
;
232 _cleanup_close_
int fd
= -1;
233 union sockaddr_union sa
= {};
235 static const int one
= 1;
239 assert((family
== AF_UNSPEC
) == !address
);
241 if (family
== AF_UNSPEC
) {
242 srv
= dns_scope_get_dns_server(s
);
246 sa
.sa
.sa_family
= srv
->family
;
247 if (srv
->family
== AF_INET
) {
248 sa
.in
.sin_port
= htobe16(port
);
249 sa
.in
.sin_addr
= srv
->address
.in
;
250 salen
= sizeof(sa
.in
);
251 } else if (srv
->family
== AF_INET6
) {
252 sa
.in6
.sin6_port
= htobe16(port
);
253 sa
.in6
.sin6_addr
= srv
->address
.in6
;
254 sa
.in6
.sin6_scope_id
= s
->link
? s
->link
->ifindex
: 0;
255 salen
= sizeof(sa
.in6
);
257 return -EAFNOSUPPORT
;
259 sa
.sa
.sa_family
= family
;
261 if (family
== AF_INET
) {
262 sa
.in
.sin_port
= htobe16(port
);
263 sa
.in
.sin_addr
= address
->in
;
264 salen
= sizeof(sa
.in
);
265 } else if (family
== AF_INET6
) {
266 sa
.in6
.sin6_port
= htobe16(port
);
267 sa
.in6
.sin6_addr
= address
->in6
;
268 sa
.in6
.sin6_scope_id
= s
->link
? s
->link
->ifindex
: 0;
269 salen
= sizeof(sa
.in6
);
271 return -EAFNOSUPPORT
;
274 fd
= socket(sa
.sa
.sa_family
, type
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
278 if (type
== SOCK_STREAM
) {
279 r
= setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &one
, sizeof(one
));
285 uint32_t ifindex
= htobe32(s
->link
->ifindex
);
287 if (sa
.sa
.sa_family
== AF_INET
) {
288 r
= setsockopt(fd
, IPPROTO_IP
, IP_UNICAST_IF
, &ifindex
, sizeof(ifindex
));
291 } else if (sa
.sa
.sa_family
== AF_INET6
) {
292 r
= setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_IF
, &ifindex
, sizeof(ifindex
));
298 if (s
->protocol
== DNS_PROTOCOL_LLMNR
) {
299 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
301 if (sa
.sa
.sa_family
== AF_INET
) {
302 r
= setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &one
, sizeof(one
));
305 } else if (sa
.sa
.sa_family
== AF_INET6
) {
306 r
= setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &one
, sizeof(one
));
312 r
= connect(fd
, &sa
.sa
, salen
);
313 if (r
< 0 && errno
!= EINPROGRESS
)
325 int dns_scope_udp_dns_socket(DnsScope
*s
, DnsServer
**server
) {
326 return dns_scope_socket(s
, SOCK_DGRAM
, AF_UNSPEC
, NULL
, 53, server
);
329 int dns_scope_tcp_socket(DnsScope
*s
, int family
, const union in_addr_union
*address
, uint16_t port
, DnsServer
**server
) {
330 return dns_scope_socket(s
, SOCK_STREAM
, family
, address
, port
, server
);
333 DnsScopeMatch
dns_scope_good_domain(DnsScope
*s
, int ifindex
, uint64_t flags
, const char *domain
) {
339 if (ifindex
!= 0 && (!s
->link
|| s
->link
->ifindex
!= ifindex
))
342 if ((SD_RESOLVED_FLAGS_MAKE(s
->protocol
, s
->family
) & flags
) == 0)
345 if (dns_name_is_root(domain
))
348 /* Never resolve any loopback hostname or IP address via DNS,
349 * LLMNR or mDNS. Instead, always rely on synthesized RRs for
351 if (is_localhost(domain
) ||
352 dns_name_endswith(domain
, "127.in-addr.arpa") > 0 ||
353 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)
356 /* Always honour search domains for routing queries. Note that
357 * we return DNS_SCOPE_YES here, rather than just
358 * DNS_SCOPE_MAYBE, which means wildcard scopes won't be
359 * considered anymore. */
360 LIST_FOREACH(domains
, d
, dns_scope_get_search_domains(s
))
361 if (dns_name_endswith(domain
, d
->name
) > 0)
362 return DNS_SCOPE_YES
;
364 switch (s
->protocol
) {
366 case DNS_PROTOCOL_DNS
:
368 if ((!dns_name_is_single_label(domain
) ||
369 (!(flags
& SD_RESOLVED_NO_SEARCH
) && dns_scope_has_search_domains(s
))) &&
370 dns_name_endswith(domain
, "254.169.in-addr.arpa") == 0 &&
371 dns_name_endswith(domain
, "0.8.e.f.ip6.arpa") == 0)
372 return DNS_SCOPE_MAYBE
;
376 case DNS_PROTOCOL_MDNS
:
377 if ((s
->family
== AF_INET
&& dns_name_endswith(domain
, "in-addr.arpa") > 0) ||
378 (s
->family
== AF_INET6
&& dns_name_endswith(domain
, "ip6.arpa") > 0) ||
379 (dns_name_endswith(domain
, "local") > 0 && /* only resolve names ending in .local via mDNS */
380 dns_name_equal(domain
, "local") == 0 && /* but not the single-label "local" name itself */
381 manager_is_own_hostname(s
->manager
, domain
) <= 0)) /* never resolve the local hostname via mDNS */
382 return DNS_SCOPE_MAYBE
;
386 case DNS_PROTOCOL_LLMNR
:
387 if ((s
->family
== AF_INET
&& dns_name_endswith(domain
, "in-addr.arpa") > 0) ||
388 (s
->family
== AF_INET6
&& dns_name_endswith(domain
, "ip6.arpa") > 0) ||
389 (dns_name_is_single_label(domain
) && /* only resolve single label names via LLMNR */
390 !is_gateway_hostname(domain
) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
391 manager_is_own_hostname(s
->manager
, domain
) <= 0)) /* never resolve the local hostname via LLMNR */
392 return DNS_SCOPE_MAYBE
;
397 assert_not_reached("Unknown scope protocol");
401 int dns_scope_good_key(DnsScope
*s
, DnsResourceKey
*key
) {
405 if (s
->protocol
== DNS_PROTOCOL_DNS
)
408 /* On mDNS and LLMNR, send A and AAAA queries only on the
409 * respective scopes */
411 if (s
->family
== AF_INET
&& key
->class == DNS_CLASS_IN
&& key
->type
== DNS_TYPE_AAAA
)
414 if (s
->family
== AF_INET6
&& key
->class == DNS_CLASS_IN
&& key
->type
== DNS_TYPE_A
)
420 int dns_scope_llmnr_membership(DnsScope
*s
, bool b
) {
425 if (s
->protocol
!= DNS_PROTOCOL_LLMNR
)
430 if (s
->family
== AF_INET
) {
431 struct ip_mreqn mreqn
= {
432 .imr_multiaddr
= LLMNR_MULTICAST_IPV4_ADDRESS
,
433 .imr_ifindex
= s
->link
->ifindex
,
436 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
440 /* Always first try to drop membership before we add
441 * one. This is necessary on some devices, such as
444 (void) setsockopt(fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreqn
, sizeof(mreqn
));
446 if (setsockopt(fd
, IPPROTO_IP
, b
? IP_ADD_MEMBERSHIP
: IP_DROP_MEMBERSHIP
, &mreqn
, sizeof(mreqn
)) < 0)
449 } else if (s
->family
== AF_INET6
) {
450 struct ipv6_mreq mreq
= {
451 .ipv6mr_multiaddr
= LLMNR_MULTICAST_IPV6_ADDRESS
,
452 .ipv6mr_interface
= s
->link
->ifindex
,
455 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
460 (void) setsockopt(fd
, IPPROTO_IPV6
, IPV6_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));
462 if (setsockopt(fd
, IPPROTO_IPV6
, b
? IPV6_ADD_MEMBERSHIP
: IPV6_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
)) < 0)
465 return -EAFNOSUPPORT
;
470 static int dns_scope_make_reply_packet(
480 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
487 if ((!q
|| q
->n_keys
<= 0)
488 && (!answer
|| answer
->n_rrs
<= 0)
489 && (!soa
|| soa
->n_rrs
<= 0))
492 r
= dns_packet_new(&p
, s
->protocol
, 0);
496 DNS_PACKET_HEADER(p
)->id
= id
;
497 DNS_PACKET_HEADER(p
)->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(
509 for (i
= 0; i
< q
->n_keys
; i
++) {
510 r
= dns_packet_append_key(p
, q
->keys
[i
], NULL
);
515 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(q
->n_keys
);
519 for (i
= 0; i
< answer
->n_rrs
; i
++) {
520 r
= dns_packet_append_rr(p
, answer
->items
[i
].rr
, NULL
);
525 DNS_PACKET_HEADER(p
)->ancount
= htobe16(answer
->n_rrs
);
529 for (i
= 0; i
< soa
->n_rrs
; i
++) {
530 r
= dns_packet_append_rr(p
, soa
->items
[i
].rr
, NULL
);
535 DNS_PACKET_HEADER(p
)->arcount
= htobe16(soa
->n_rrs
);
544 static void dns_scope_verify_conflicts(DnsScope
*s
, DnsPacket
*p
) {
551 for (n
= 0; n
< p
->question
->n_keys
; n
++)
552 dns_zone_verify_conflicts(&s
->zone
, p
->question
->keys
[n
]);
554 for (n
= 0; n
< p
->answer
->n_rrs
; n
++)
555 dns_zone_verify_conflicts(&s
->zone
, p
->answer
->items
[n
].rr
->key
);
558 void dns_scope_process_query(DnsScope
*s
, DnsStream
*stream
, DnsPacket
*p
) {
559 _cleanup_(dns_packet_unrefp
) DnsPacket
*reply
= NULL
;
560 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
, *soa
= NULL
;
561 DnsResourceKey
*key
= NULL
;
562 bool tentative
= false;
568 if (p
->protocol
!= DNS_PROTOCOL_LLMNR
)
571 if (p
->ipproto
== IPPROTO_UDP
) {
572 /* Don't accept UDP queries directed to anything but
573 * the LLMNR multicast addresses. See RFC 4795,
576 if (p
->family
== AF_INET
&& !in_addr_equal(AF_INET
, &p
->destination
, (union in_addr_union
*) &LLMNR_MULTICAST_IPV4_ADDRESS
))
579 if (p
->family
== AF_INET6
&& !in_addr_equal(AF_INET6
, &p
->destination
, (union in_addr_union
*) &LLMNR_MULTICAST_IPV6_ADDRESS
))
583 r
= dns_packet_extract(p
);
585 log_debug_errno(r
, "Failed to extract resources from incoming packet: %m");
589 if (DNS_PACKET_LLMNR_C(p
)) {
590 /* Somebody notified us about a possible conflict */
591 dns_scope_verify_conflicts(s
, p
);
595 assert(p
->question
->n_keys
== 1);
596 key
= p
->question
->keys
[0];
598 r
= dns_zone_lookup(&s
->zone
, key
, &answer
, &soa
, &tentative
);
600 log_debug_errno(r
, "Failed to lookup key: %m");
607 dns_answer_order_by_scope(answer
, in_addr_is_link_local(p
->family
, &p
->sender
) > 0);
609 r
= dns_scope_make_reply_packet(s
, DNS_PACKET_ID(p
), DNS_RCODE_SUCCESS
, p
->question
, answer
, soa
, tentative
, &reply
);
611 log_debug_errno(r
, "Failed to build reply packet: %m");
616 r
= dns_stream_write_packet(stream
, reply
);
618 if (!ratelimit_test(&s
->ratelimit
))
621 if (p
->family
== AF_INET
)
622 fd
= manager_llmnr_ipv4_udp_fd(s
->manager
);
623 else if (p
->family
== AF_INET6
)
624 fd
= manager_llmnr_ipv6_udp_fd(s
->manager
);
626 log_debug("Unknown protocol");
630 log_debug_errno(fd
, "Failed to get reply socket: %m");
634 /* Note that we always immediately reply to all LLMNR
635 * requests, and do not wait any time, since we
636 * verified uniqueness for all records. Also see RFC
637 * 4795, Section 2.7 */
639 r
= manager_send(s
->manager
, fd
, p
->ifindex
, p
->family
, &p
->sender
, p
->sender_port
, reply
);
643 log_debug_errno(r
, "Failed to send reply packet: %m");
648 DnsTransaction
*dns_scope_find_transaction(DnsScope
*scope
, DnsResourceKey
*key
, bool cache_ok
) {
654 /* Try to find an ongoing transaction that is a equal to the
655 * specified question */
656 t
= hashmap_get(scope
->transactions
, key
);
660 /* Refuse reusing transactions that completed based on cached
661 * data instead of a real packet, if that's requested. */
663 IN_SET(t
->state
, DNS_TRANSACTION_SUCCESS
, DNS_TRANSACTION_FAILURE
) &&
670 static int dns_scope_make_conflict_packet(
672 DnsResourceRecord
*rr
,
675 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
682 r
= dns_packet_new(&p
, s
->protocol
, 0);
686 DNS_PACKET_HEADER(p
)->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(
696 random_bytes(&DNS_PACKET_HEADER(p
)->id
, sizeof(uint16_t));
697 DNS_PACKET_HEADER(p
)->qdcount
= htobe16(1);
698 DNS_PACKET_HEADER(p
)->arcount
= htobe16(1);
700 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
704 r
= dns_packet_append_rr(p
, rr
, NULL
);
714 static int on_conflict_dispatch(sd_event_source
*es
, usec_t usec
, void *userdata
) {
715 DnsScope
*scope
= userdata
;
721 scope
->conflict_event_source
= sd_event_source_unref(scope
->conflict_event_source
);
724 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
725 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
727 rr
= ordered_hashmap_steal_first(scope
->conflict_queue
);
731 r
= dns_scope_make_conflict_packet(scope
, rr
, &p
);
733 log_error_errno(r
, "Failed to make conflict packet: %m");
737 r
= dns_scope_emit(scope
, -1, p
);
739 log_debug_errno(r
, "Failed to send conflict packet: %m");
745 int dns_scope_notify_conflict(DnsScope
*scope
, DnsResourceRecord
*rr
) {
752 /* We don't send these queries immediately. Instead, we queue
753 * them, and send them after some jitter delay. */
754 r
= ordered_hashmap_ensure_allocated(&scope
->conflict_queue
, &dns_resource_key_hash_ops
);
760 /* We only place one RR per key in the conflict
761 * messages, not all of them. That should be enough to
762 * indicate where there might be a conflict */
763 r
= ordered_hashmap_put(scope
->conflict_queue
, rr
->key
, rr
);
764 if (r
== -EEXIST
|| r
== 0)
767 return log_debug_errno(r
, "Failed to queue conflicting RR: %m");
769 dns_resource_record_ref(rr
);
771 if (scope
->conflict_event_source
)
774 random_bytes(&jitter
, sizeof(jitter
));
775 jitter
%= LLMNR_JITTER_INTERVAL_USEC
;
777 r
= sd_event_add_time(scope
->manager
->event
,
778 &scope
->conflict_event_source
,
779 clock_boottime_or_monotonic(),
780 now(clock_boottime_or_monotonic()) + jitter
,
781 LLMNR_JITTER_INTERVAL_USEC
,
782 on_conflict_dispatch
, scope
);
784 return log_debug_errno(r
, "Failed to add conflict dispatch event: %m");
789 void dns_scope_check_conflicts(DnsScope
*scope
, DnsPacket
*p
) {
796 if (p
->protocol
!= DNS_PROTOCOL_LLMNR
)
799 if (DNS_PACKET_RRCOUNT(p
) <= 0)
802 if (DNS_PACKET_LLMNR_C(p
) != 0)
805 if (DNS_PACKET_LLMNR_T(p
) != 0)
808 if (manager_our_packet(scope
->manager
, p
))
811 r
= dns_packet_extract(p
);
813 log_debug_errno(r
, "Failed to extract packet: %m");
817 log_debug("Checking for conflicts...");
819 for (i
= 0; i
< p
->answer
->n_rrs
; i
++) {
821 /* Check for conflicts against the local zone. If we
822 * found one, we won't check any further */
823 r
= dns_zone_check_conflicts(&scope
->zone
, p
->answer
->items
[i
].rr
);
827 /* Check for conflicts against the local cache. If so,
828 * send out an advisory query, to inform everybody */
829 r
= dns_cache_check_conflicts(&scope
->cache
, p
->answer
->items
[i
].rr
, p
->family
, &p
->sender
);
833 dns_scope_notify_conflict(scope
, p
->answer
->items
[i
].rr
);
837 void dns_scope_dump(DnsScope
*s
, FILE *f
) {
843 fputs("[Scope protocol=", f
);
844 fputs(dns_protocol_to_string(s
->protocol
), f
);
847 fputs(" interface=", f
);
848 fputs(s
->link
->name
, f
);
851 if (s
->family
!= AF_UNSPEC
) {
852 fputs(" family=", f
);
853 fputs(af_to_name(s
->family
), f
);
858 if (!dns_zone_is_empty(&s
->zone
)) {
860 dns_zone_dump(&s
->zone
, f
);
863 if (!dns_cache_is_empty(&s
->cache
)) {
864 fputs("CACHE:\n", f
);
865 dns_cache_dump(&s
->cache
, f
);
869 DnsSearchDomain
*dns_scope_get_search_domains(DnsScope
*s
) {
872 /* Returns the list of *local* search domains -- not the
875 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
879 return s
->link
->search_domains
;
884 bool dns_scope_has_search_domains(DnsScope
*s
) {
887 /* Tests if there are *any* search domains suitable for this
888 * scope. This means either local or global ones */
890 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
893 if (s
->manager
->search_domains
)
896 if (s
->link
&& s
->link
->search_domains
)
902 bool dns_scope_name_needs_search_domain(DnsScope
*s
, const char *name
) {
905 if (s
->protocol
!= DNS_PROTOCOL_DNS
)
908 return dns_name_is_single_label(name
);