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>
26 #include "socket-util.h"
28 #include "resolved-dns-domain.h"
29 #include "resolved-dns-scope.h"
31 #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
32 #define MULTICAST_RATELIMIT_BURST 1000
34 int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
40 s = new0(DnsScope, 1);
46 s->protocol = protocol;
49 LIST_PREPEND(scopes, m->dns_scopes, s);
51 dns_scope_llmnr_membership(s, true);
53 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));
55 /* Enforce ratelimiting for the multicast protocols */
56 RATELIMIT_INIT(s->ratelimit, MULTICAST_RATELIMIT_INTERVAL_USEC, MULTICAST_RATELIMIT_BURST);
62 DnsScope* dns_scope_free(DnsScope *s) {
64 DnsResourceRecord *rr;
69 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));
71 dns_scope_llmnr_membership(s, false);
73 while ((t = s->transactions)) {
75 /* Abort the transaction, but make sure it is not
76 * freed while we still look at it */
79 dns_transaction_complete(t, DNS_TRANSACTION_ABORTED);
82 dns_transaction_free(t);
85 while ((rr = hashmap_steal_first(s->conflict_queue)))
86 dns_resource_record_unref(rr);
88 hashmap_free(s->conflict_queue);
89 sd_event_source_unref(s->conflict_event_source);
91 dns_cache_flush(&s->cache);
92 dns_zone_flush(&s->zone);
94 LIST_REMOVE(scopes, s->manager->dns_scopes, s);
95 strv_free(s->domains);
101 DnsServer *dns_scope_get_dns_server(DnsScope *s) {
104 if (s->protocol != DNS_PROTOCOL_DNS)
108 return link_get_dns_server(s->link);
110 return manager_get_dns_server(s->manager);
113 void dns_scope_next_dns_server(DnsScope *s) {
116 if (s->protocol != DNS_PROTOCOL_DNS)
120 link_next_dns_server(s->link);
122 manager_next_dns_server(s->manager);
125 int dns_scope_emit(DnsScope *s, DnsPacket *p) {
126 union in_addr_union addr;
135 assert(p->protocol == s->protocol);
139 ifindex = s->link->ifindex;
141 mtu = manager_find_mtu(s->manager);
143 if (s->protocol == DNS_PROTOCOL_DNS) {
146 if (DNS_PACKET_QDCOUNT(p) > 1)
149 srv = dns_scope_get_dns_server(s);
153 family = srv->family;
157 if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
163 if (family == AF_INET)
164 fd = manager_dns_ipv4_fd(s->manager);
165 else if (family == AF_INET6)
166 fd = manager_dns_ipv6_fd(s->manager);
168 return -EAFNOSUPPORT;
172 } else if (s->protocol == DNS_PROTOCOL_LLMNR) {
174 if (DNS_PACKET_QDCOUNT(p) > 1)
177 if (!ratelimit_test(&s->ratelimit))
183 if (family == AF_INET) {
184 addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
185 fd = manager_llmnr_ipv4_udp_fd(s->manager);
186 } else if (family == AF_INET6) {
187 addr.in6 = LLMNR_MULTICAST_IPV6_ADDRESS;
188 fd = manager_llmnr_ipv6_udp_fd(s->manager);
190 return -EAFNOSUPPORT;
194 return -EAFNOSUPPORT;
196 r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
203 int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port) {
204 _cleanup_close_ int fd = -1;
205 union sockaddr_union sa = {};
207 static const int one = 1;
211 assert((family == AF_UNSPEC) == !address);
213 if (family == AF_UNSPEC) {
216 srv = dns_scope_get_dns_server(s);
220 sa.sa.sa_family = srv->family;
221 if (srv->family == AF_INET) {
222 sa.in.sin_port = htobe16(port);
223 sa.in.sin_addr = srv->address.in;
224 salen = sizeof(sa.in);
225 } else if (srv->family == AF_INET6) {
226 sa.in6.sin6_port = htobe16(port);
227 sa.in6.sin6_addr = srv->address.in6;
228 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
229 salen = sizeof(sa.in6);
231 return -EAFNOSUPPORT;
233 sa.sa.sa_family = family;
235 if (family == AF_INET) {
236 sa.in.sin_port = htobe16(port);
237 sa.in.sin_addr = address->in;
238 salen = sizeof(sa.in);
239 } else if (family == AF_INET6) {
240 sa.in6.sin6_port = htobe16(port);
241 sa.in6.sin6_addr = address->in6;
242 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
243 salen = sizeof(sa.in6);
245 return -EAFNOSUPPORT;
248 fd = socket(sa.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
252 r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
257 uint32_t ifindex = htobe32(s->link->ifindex);
259 if (sa.sa.sa_family == AF_INET) {
260 r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
263 } else if (sa.sa.sa_family == AF_INET6) {
264 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
270 if (s->protocol == DNS_PROTOCOL_LLMNR) {
271 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
273 if (sa.sa.sa_family == AF_INET) {
274 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
277 } else if (sa.sa.sa_family == AF_INET6) {
278 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
284 r = connect(fd, &sa.sa, salen);
285 if (r < 0 && errno != EINPROGRESS)
294 DnsScopeMatch dns_scope_good_domain(DnsScope *s, const char *domain) {
300 STRV_FOREACH(i, s->domains)
301 if (dns_name_endswith(domain, *i) > 0)
302 return DNS_SCOPE_YES;
304 if (dns_name_root(domain) != 0)
307 if (is_localhost(domain))
310 if (s->protocol == DNS_PROTOCOL_DNS) {
311 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
312 dns_name_endswith(domain, "0.8.e.f.ip6.arpa") == 0 &&
313 dns_name_single_label(domain) == 0)
314 return DNS_SCOPE_MAYBE;
319 if (s->protocol == DNS_PROTOCOL_MDNS) {
320 if (dns_name_endswith(domain, "254.169.in-addr.arpa") > 0 ||
321 dns_name_endswith(domain, "0.8.e.f.ip6.arpa") > 0 ||
322 (dns_name_endswith(domain, "local") > 0 && dns_name_equal(domain, "local") == 0))
323 return DNS_SCOPE_MAYBE;
328 if (s->protocol == DNS_PROTOCOL_LLMNR) {
329 if (dns_name_endswith(domain, "in-addr.arpa") > 0 ||
330 dns_name_endswith(domain, "ip6.arpa") > 0 ||
331 dns_name_single_label(domain) > 0)
332 return DNS_SCOPE_MAYBE;
337 assert_not_reached("Unknown scope protocol");
340 int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
344 if (s->protocol == DNS_PROTOCOL_DNS)
347 /* On mDNS and LLMNR, send A and AAAA queries only on the
348 * respective scopes */
350 if (s->family == AF_INET && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_AAAA)
353 if (s->family == AF_INET6 && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_A)
359 int dns_scope_llmnr_membership(DnsScope *s, bool b) {
362 if (s->family == AF_INET) {
363 struct ip_mreqn mreqn = {
364 .imr_multiaddr = LLMNR_MULTICAST_IPV4_ADDRESS,
365 .imr_ifindex = s->link->ifindex,
368 fd = manager_llmnr_ipv4_udp_fd(s->manager);
372 /* Always first try to drop membership before we add
373 * one. This is necessary on some devices, such as
376 setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
378 if (setsockopt(fd, IPPROTO_IP, b ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0)
381 } else if (s->family == AF_INET6) {
382 struct ipv6_mreq mreq = {
383 .ipv6mr_multiaddr = LLMNR_MULTICAST_IPV6_ADDRESS,
384 .ipv6mr_interface = s->link->ifindex,
387 fd = manager_llmnr_ipv6_udp_fd(s->manager);
392 setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
394 if (setsockopt(fd, IPPROTO_IPV6, b ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
397 return -EAFNOSUPPORT;
402 int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union *address) {
406 if (s->protocol != DNS_PROTOCOL_DNS)
410 return !!link_find_dns_server(s->link, family, address);
412 return !!manager_find_dns_server(s->manager, family, address);
415 static int dns_scope_make_reply_packet(
425 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
432 if ((!q || q->n_keys <= 0)
433 && (!answer || answer->n_rrs <= 0)
434 && (!soa || soa->n_rrs <= 0))
437 r = dns_packet_new(&p, s->protocol, 0);
441 DNS_PACKET_HEADER(p)->id = id;
442 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
454 for (i = 0; i < q->n_keys; i++) {
455 r = dns_packet_append_key(p, q->keys[i], NULL);
460 DNS_PACKET_HEADER(p)->qdcount = htobe16(q->n_keys);
464 for (i = 0; i < answer->n_rrs; i++) {
465 r = dns_packet_append_rr(p, answer->rrs[i], NULL);
470 DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
474 for (i = 0; i < soa->n_rrs; i++) {
475 r = dns_packet_append_rr(p, soa->rrs[i], NULL);
480 DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
489 static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
496 for (n = 0; n < p->question->n_keys; n++)
497 dns_zone_verify_conflicts(&s->zone, p->question->keys[n]);
499 for (n = 0; n < p->answer->n_rrs; n++)
500 dns_zone_verify_conflicts(&s->zone, p->answer->rrs[n]->key);
503 void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
504 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
505 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
506 bool tentative = false;
512 if (p->protocol != DNS_PROTOCOL_LLMNR)
515 if (p->ipproto == IPPROTO_UDP) {
516 /* Don't accept UDP queries directed to anything but
517 * the LLMNR multicast addresses. See RFC 4795,
520 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
523 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
527 r = dns_packet_extract(p);
529 log_debug("Failed to extract resources from incoming packet: %s", strerror(-r));
533 if (DNS_PACKET_C(p)) {
534 /* Somebody notified us about a possible conflict */
535 dns_scope_verify_conflicts(s, p);
539 r = dns_zone_lookup(&s->zone, p->question, &answer, &soa, &tentative);
541 log_debug("Failed to lookup key: %s", strerror(-r));
548 dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
550 r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
552 log_debug("Failed to build reply packet: %s", strerror(-r));
557 r = dns_stream_write_packet(stream, reply);
559 if (!ratelimit_test(&s->ratelimit))
562 if (p->family == AF_INET)
563 fd = manager_llmnr_ipv4_udp_fd(s->manager);
564 else if (p->family == AF_INET6)
565 fd = manager_llmnr_ipv6_udp_fd(s->manager);
567 log_debug("Unknown protocol");
571 log_debug("Failed to get reply socket: %s", strerror(-fd));
575 /* Note that we always immediately reply to all LLMNR
576 * requests, and do not wait any time, since we
577 * verified uniqueness for all records. Also see RFC
578 * 4795, Section 2.7 */
580 r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
584 log_debug("Failed to send reply packet: %s", strerror(-r));
589 DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsQuestion *question, bool cache_ok) {
595 /* Try to find an ongoing transaction that is a equal or a
596 * superset of the specified question */
598 LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
600 /* Refuse reusing transactions that completed based on
601 * cached data instead of a real packet, if that's
604 IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE) &&
608 if (dns_question_is_superset(t->question, question) > 0)
615 static int dns_scope_make_conflict_packet(
617 DnsResourceRecord *rr,
620 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
627 r = dns_packet_new(&p, s->protocol, 0);
631 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
641 random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
642 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
643 DNS_PACKET_HEADER(p)->arcount = htobe16(1);
645 r = dns_packet_append_key(p, rr->key, NULL);
649 r = dns_packet_append_rr(p, rr, NULL);
659 static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
660 DnsScope *scope = userdata;
666 scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
669 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
670 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
672 rr = hashmap_steal_first(scope->conflict_queue);
676 r = dns_scope_make_conflict_packet(scope, rr, &p);
678 log_error("Failed to make conflict packet: %s", strerror(-r));
682 r = dns_scope_emit(scope, p);
684 log_debug("Failed to send conflict packet: %s", strerror(-r));
690 int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
697 /* We don't send these queries immediately. Instead, we queue
698 * them, and send them after some jitter delay. */
699 r = hashmap_ensure_allocated(&scope->conflict_queue, dns_resource_key_hash_func, dns_resource_key_compare_func);
705 /* We only place one RR per key in the conflict
706 * messages, not all of them. That should be enough to
707 * indicate where there might be a conflict */
708 r = hashmap_put(scope->conflict_queue, rr->key, rr);
709 if (r == -EEXIST || r == 0)
712 log_debug("Failed to queue conflicting RR: %s", strerror(-r));
716 dns_resource_record_ref(rr);
718 if (scope->conflict_event_source)
721 random_bytes(&jitter, sizeof(jitter));
722 jitter %= LLMNR_JITTER_INTERVAL_USEC;
724 r = sd_event_add_time(scope->manager->event,
725 &scope->conflict_event_source,
726 clock_boottime_or_monotonic(),
727 now(clock_boottime_or_monotonic()) + jitter,
728 LLMNR_JITTER_INTERVAL_USEC,
729 on_conflict_dispatch, scope);
731 log_debug("Failed to add conflict dispatch event: %s", strerror(-r));
738 void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
745 if (p->protocol != DNS_PROTOCOL_LLMNR)
748 if (DNS_PACKET_RRCOUNT(p) <= 0)
751 if (DNS_PACKET_C(p) != 0)
754 if (DNS_PACKET_T(p) != 0)
757 if (manager_our_packet(scope->manager, p))
760 r = dns_packet_extract(p);
762 log_debug("Failed to extract packet: %s", strerror(-r));
766 log_debug("Checking for conflicts...");
768 for (i = 0; i < p->answer->n_rrs; i++) {
770 /* Check for conflicts against the local zone. If we
771 * found one, we won't check any further */
772 r = dns_zone_check_conflicts(&scope->zone, p->answer->rrs[i]);
776 /* Check for conflicts against the local cache. If so,
777 * send out an advisory query, to inform everybody */
778 r = dns_cache_check_conflicts(&scope->cache, p->answer->rrs[i], p->family, &p->sender);
782 dns_scope_notify_conflict(scope, p->answer->rrs[i]);