]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-scope.c
Merge pull request #2524 from poettering/bag-of-stuff
[thirdparty/systemd.git] / src / resolve / resolved-dns-scope.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <netinet/tcp.h>
23
24 #include "af-list.h"
25 #include "alloc-util.h"
26 #include "dns-domain.h"
27 #include "fd-util.h"
28 #include "hostname-util.h"
29 #include "missing.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"
35 #include "strv.h"
36
37 #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
38 #define MULTICAST_RATELIMIT_BURST 1000
39
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)
43
44 int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
45 DnsScope *s;
46
47 assert(m);
48 assert(ret);
49
50 s = new0(DnsScope, 1);
51 if (!s)
52 return -ENOMEM;
53
54 s->manager = m;
55 s->link = l;
56 s->protocol = protocol;
57 s->family = family;
58 s->resend_timeout = MULTICAST_RESEND_TIMEOUT_MIN_USEC;
59
60 if (protocol == DNS_PROTOCOL_DNS) {
61 /* Copy DNSSEC mode from the link if it is set there,
62 * otherwise take the manager's DNSSEC mode. Note that
63 * we copy this only at scope creation time, and do
64 * not update it from the on, even if the setting
65 * changes. */
66
67 if (l)
68 s->dnssec_mode = link_get_dnssec_mode(l);
69 else
70 s->dnssec_mode = manager_get_dnssec_mode(m);
71 } else
72 s->dnssec_mode = DNSSEC_NO;
73
74 LIST_PREPEND(scopes, m->dns_scopes, s);
75
76 dns_scope_llmnr_membership(s, true);
77 dns_scope_mdns_membership(s, true);
78
79 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));
80
81 /* Enforce ratelimiting for the multicast protocols */
82 RATELIMIT_INIT(s->ratelimit, MULTICAST_RATELIMIT_INTERVAL_USEC, MULTICAST_RATELIMIT_BURST);
83
84 *ret = s;
85 return 0;
86 }
87
88 static void dns_scope_abort_transactions(DnsScope *s) {
89 assert(s);
90
91 while (s->transactions) {
92 DnsTransaction *t = s->transactions;
93
94 /* Abort the transaction, but make sure it is not
95 * freed while we still look at it */
96
97 t->block_gc++;
98 if (DNS_TRANSACTION_IS_LIVE(t->state))
99 dns_transaction_complete(t, DNS_TRANSACTION_ABORTED);
100 t->block_gc--;
101
102 dns_transaction_free(t);
103 }
104 }
105
106 DnsScope* dns_scope_free(DnsScope *s) {
107 DnsResourceRecord *rr;
108
109 if (!s)
110 return NULL;
111
112 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));
113
114 dns_scope_llmnr_membership(s, false);
115 dns_scope_mdns_membership(s, false);
116 dns_scope_abort_transactions(s);
117
118 while (s->query_candidates)
119 dns_query_candidate_free(s->query_candidates);
120
121 hashmap_free(s->transactions_by_key);
122
123 while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
124 dns_resource_record_unref(rr);
125
126 ordered_hashmap_free(s->conflict_queue);
127 sd_event_source_unref(s->conflict_event_source);
128
129 dns_cache_flush(&s->cache);
130 dns_zone_flush(&s->zone);
131
132 LIST_REMOVE(scopes, s->manager->dns_scopes, s);
133 free(s);
134
135 return NULL;
136 }
137
138 DnsServer *dns_scope_get_dns_server(DnsScope *s) {
139 assert(s);
140
141 if (s->protocol != DNS_PROTOCOL_DNS)
142 return NULL;
143
144 if (s->link)
145 return link_get_dns_server(s->link);
146 else
147 return manager_get_dns_server(s->manager);
148 }
149
150 void dns_scope_next_dns_server(DnsScope *s) {
151 assert(s);
152
153 if (s->protocol != DNS_PROTOCOL_DNS)
154 return;
155
156 if (s->link)
157 link_next_dns_server(s->link);
158 else
159 manager_next_dns_server(s->manager);
160 }
161
162 void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
163 assert(s);
164
165 if (rtt <= s->max_rtt)
166 return;
167
168 s->max_rtt = rtt;
169 s->resend_timeout = MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC, s->max_rtt * 2), MULTICAST_RESEND_TIMEOUT_MAX_USEC);
170 }
171
172 void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
173 assert(s);
174
175 if (s->resend_timeout <= usec)
176 s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
177 }
178
179 static int dns_scope_emit_one(DnsScope *s, int fd, DnsPacket *p) {
180 union in_addr_union addr;
181 int ifindex = 0, r;
182 int family;
183 uint32_t mtu;
184
185 assert(s);
186 assert(p);
187 assert(p->protocol == s->protocol);
188
189 if (s->link) {
190 mtu = s->link->mtu;
191 ifindex = s->link->ifindex;
192 } else
193 mtu = manager_find_mtu(s->manager);
194
195 switch (s->protocol) {
196
197 case DNS_PROTOCOL_DNS:
198 assert(fd >= 0);
199
200 if (DNS_PACKET_QDCOUNT(p) > 1)
201 return -EOPNOTSUPP;
202
203 if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
204 return -EMSGSIZE;
205
206 if (p->size + UDP_PACKET_HEADER_SIZE > mtu)
207 return -EMSGSIZE;
208
209 r = manager_write(s->manager, fd, p);
210 if (r < 0)
211 return r;
212
213 break;
214
215 case DNS_PROTOCOL_LLMNR:
216 assert(fd < 0);
217
218 if (DNS_PACKET_QDCOUNT(p) > 1)
219 return -EOPNOTSUPP;
220
221 if (!ratelimit_test(&s->ratelimit))
222 return -EBUSY;
223
224 family = s->family;
225
226 if (family == AF_INET) {
227 addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
228 fd = manager_llmnr_ipv4_udp_fd(s->manager);
229 } else if (family == AF_INET6) {
230 addr.in6 = LLMNR_MULTICAST_IPV6_ADDRESS;
231 fd = manager_llmnr_ipv6_udp_fd(s->manager);
232 } else
233 return -EAFNOSUPPORT;
234 if (fd < 0)
235 return fd;
236
237 r = manager_send(s->manager, fd, ifindex, family, &addr, LLMNR_PORT, p);
238 if (r < 0)
239 return r;
240
241 break;
242
243 case DNS_PROTOCOL_MDNS:
244 assert(fd < 0);
245
246 if (!ratelimit_test(&s->ratelimit))
247 return -EBUSY;
248
249 family = s->family;
250
251 if (family == AF_INET) {
252 addr.in = MDNS_MULTICAST_IPV4_ADDRESS;
253 fd = manager_mdns_ipv4_fd(s->manager);
254 } else if (family == AF_INET6) {
255 addr.in6 = MDNS_MULTICAST_IPV6_ADDRESS;
256 fd = manager_mdns_ipv6_fd(s->manager);
257 } else
258 return -EAFNOSUPPORT;
259 if (fd < 0)
260 return fd;
261
262 r = manager_send(s->manager, fd, ifindex, family, &addr, MDNS_PORT, p);
263 if (r < 0)
264 return r;
265
266 break;
267
268 default:
269 return -EAFNOSUPPORT;
270 }
271
272 return 1;
273 }
274
275 int dns_scope_emit_udp(DnsScope *s, int fd, DnsPacket *p) {
276 int r;
277
278 assert(s);
279 assert(p);
280 assert(p->protocol == s->protocol);
281 assert((s->protocol == DNS_PROTOCOL_DNS) == (fd >= 0));
282
283 do {
284 /* If there are multiple linked packets, set the TC bit in all but the last of them */
285 if (p->more) {
286 assert(p->protocol == DNS_PROTOCOL_MDNS);
287 dns_packet_set_flags(p, true, true);
288 }
289
290 r = dns_scope_emit_one(s, fd, p);
291 if (r < 0)
292 return r;
293
294 p = p->more;
295 } while (p);
296
297 return 0;
298 }
299
300 static int dns_scope_socket(
301 DnsScope *s,
302 int type,
303 int family,
304 const union in_addr_union *address,
305 DnsServer *server,
306 uint16_t port) {
307
308 _cleanup_close_ int fd = -1;
309 union sockaddr_union sa = {};
310 socklen_t salen;
311 static const int one = 1;
312 int ret, r;
313
314 assert(s);
315
316 if (server) {
317 assert(family == AF_UNSPEC);
318 assert(!address);
319
320 sa.sa.sa_family = server->family;
321 if (server->family == AF_INET) {
322 sa.in.sin_port = htobe16(port);
323 sa.in.sin_addr = server->address.in;
324 salen = sizeof(sa.in);
325 } else if (server->family == AF_INET6) {
326 sa.in6.sin6_port = htobe16(port);
327 sa.in6.sin6_addr = server->address.in6;
328 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
329 salen = sizeof(sa.in6);
330 } else
331 return -EAFNOSUPPORT;
332 } else {
333 assert(family != AF_UNSPEC);
334 assert(address);
335
336 sa.sa.sa_family = family;
337
338 if (family == AF_INET) {
339 sa.in.sin_port = htobe16(port);
340 sa.in.sin_addr = address->in;
341 salen = sizeof(sa.in);
342 } else if (family == AF_INET6) {
343 sa.in6.sin6_port = htobe16(port);
344 sa.in6.sin6_addr = address->in6;
345 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
346 salen = sizeof(sa.in6);
347 } else
348 return -EAFNOSUPPORT;
349 }
350
351 fd = socket(sa.sa.sa_family, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
352 if (fd < 0)
353 return -errno;
354
355 if (type == SOCK_STREAM) {
356 r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
357 if (r < 0)
358 return -errno;
359 }
360
361 if (s->link) {
362 uint32_t ifindex = htobe32(s->link->ifindex);
363
364 if (sa.sa.sa_family == AF_INET) {
365 r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
366 if (r < 0)
367 return -errno;
368 } else if (sa.sa.sa_family == AF_INET6) {
369 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
370 if (r < 0)
371 return -errno;
372 }
373 }
374
375 if (s->protocol == DNS_PROTOCOL_LLMNR) {
376 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
377
378 if (sa.sa.sa_family == AF_INET) {
379 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
380 if (r < 0)
381 return -errno;
382 } else if (sa.sa.sa_family == AF_INET6) {
383 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
384 if (r < 0)
385 return -errno;
386 }
387 }
388
389 r = connect(fd, &sa.sa, salen);
390 if (r < 0 && errno != EINPROGRESS)
391 return -errno;
392
393 ret = fd;
394 fd = -1;
395
396 return ret;
397 }
398
399 int dns_scope_socket_udp(DnsScope *s, DnsServer *server, uint16_t port) {
400 return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, server, port);
401 }
402
403 int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *address, DnsServer *server, uint16_t port) {
404 return dns_scope_socket(s, SOCK_STREAM, family, address, server, port);
405 }
406
407 DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
408 DnsSearchDomain *d;
409
410 assert(s);
411 assert(domain);
412
413 /* Checks if the specified domain is something to look up on
414 * this scope. Note that this accepts non-qualified hostnames,
415 * i.e. those without any search path prefixed yet. */
416
417 if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
418 return DNS_SCOPE_NO;
419
420 if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, 0) & flags) == 0)
421 return DNS_SCOPE_NO;
422
423 /* Never resolve any loopback hostname or IP address via DNS,
424 * LLMNR or mDNS. Instead, always rely on synthesized RRs for
425 * these. */
426 if (is_localhost(domain) ||
427 dns_name_endswith(domain, "127.in-addr.arpa") > 0 ||
428 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)
429 return DNS_SCOPE_NO;
430
431 /* Never respond to some of the domains listed in RFC6303 */
432 if (dns_name_endswith(domain, "0.in-addr.arpa") > 0 ||
433 dns_name_equal(domain, "255.255.255.255.in-addr.arpa") > 0 ||
434 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)
435 return DNS_SCOPE_NO;
436
437 /* Never respond to some of the domains listed in RFC6761 */
438 if (dns_name_endswith(domain, "invalid") > 0)
439 return DNS_SCOPE_NO;
440
441 /* Always honour search domains for routing queries. Note that
442 * we return DNS_SCOPE_YES here, rather than just
443 * DNS_SCOPE_MAYBE, which means wildcard scopes won't be
444 * considered anymore. */
445 LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
446 if (dns_name_endswith(domain, d->name) > 0)
447 return DNS_SCOPE_YES;
448
449 switch (s->protocol) {
450
451 case DNS_PROTOCOL_DNS:
452
453 /* Exclude link-local IP ranges */
454 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
455 dns_name_endswith(domain, "8.e.f.ip6.arpa") == 0 &&
456 dns_name_endswith(domain, "9.e.f.ip6.arpa") == 0 &&
457 dns_name_endswith(domain, "a.e.f.ip6.arpa") == 0 &&
458 dns_name_endswith(domain, "b.e.f.ip6.arpa") == 0 &&
459 /* If networks use .local in their private setups, they are supposed to also add .local to their search
460 * domains, which we already checked above. Otherwise, we consider .local specific to mDNS and won't
461 * send such queries ordinary DNS servers. */
462 dns_name_endswith(domain, "local") == 0)
463 return DNS_SCOPE_MAYBE;
464
465 return DNS_SCOPE_NO;
466
467 case DNS_PROTOCOL_MDNS:
468 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
469 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
470 (dns_name_endswith(domain, "local") > 0 && /* only resolve names ending in .local via mDNS */
471 dns_name_equal(domain, "local") == 0 && /* but not the single-label "local" name itself */
472 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via mDNS */
473 return DNS_SCOPE_MAYBE;
474
475 return DNS_SCOPE_NO;
476
477 case DNS_PROTOCOL_LLMNR:
478 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
479 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
480 (dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */
481 !is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
482 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
483 return DNS_SCOPE_MAYBE;
484
485 return DNS_SCOPE_NO;
486
487 default:
488 assert_not_reached("Unknown scope protocol");
489 }
490 }
491
492 bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key) {
493 int key_family;
494
495 assert(s);
496 assert(key);
497
498 /* Check if it makes sense to resolve the specified key on
499 * this scope. Note that this call assumes as fully qualified
500 * name, i.e. the search suffixes already appended. */
501
502 if (key->class != DNS_CLASS_IN)
503 return false;
504
505 if (s->protocol == DNS_PROTOCOL_DNS) {
506
507 /* On classic DNS, looking up non-address RRs is always
508 * fine. (Specifically, we want to permit looking up
509 * DNSKEY and DS records on the root and top-level
510 * domains.) */
511 if (!dns_resource_key_is_address(key))
512 return true;
513
514 /* However, we refuse to look up A and AAAA RRs on the
515 * root and single-label domains, under the assumption
516 * that those should be resolved via LLMNR or search
517 * path only, and should not be leaked onto the
518 * internet. */
519 return !(dns_name_is_single_label(DNS_RESOURCE_KEY_NAME(key)) ||
520 dns_name_is_root(DNS_RESOURCE_KEY_NAME(key)));
521 }
522
523 /* On mDNS and LLMNR, send A and AAAA queries only on the
524 * respective scopes */
525
526 key_family = dns_type_to_af(key->type);
527 if (key_family < 0)
528 return true;
529
530 return key_family == s->family;
531 }
532
533 static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in, struct in6_addr in6) {
534 int fd;
535
536 assert(s);
537 assert(s->link);
538
539 if (s->family == AF_INET) {
540 struct ip_mreqn mreqn = {
541 .imr_multiaddr = in,
542 .imr_ifindex = s->link->ifindex,
543 };
544
545 fd = manager_llmnr_ipv4_udp_fd(s->manager);
546 if (fd < 0)
547 return fd;
548
549 /* Always first try to drop membership before we add
550 * one. This is necessary on some devices, such as
551 * veth. */
552 if (b)
553 (void) setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
554
555 if (setsockopt(fd, IPPROTO_IP, b ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0)
556 return -errno;
557
558 } else if (s->family == AF_INET6) {
559 struct ipv6_mreq mreq = {
560 .ipv6mr_multiaddr = in6,
561 .ipv6mr_interface = s->link->ifindex,
562 };
563
564 fd = manager_llmnr_ipv6_udp_fd(s->manager);
565 if (fd < 0)
566 return fd;
567
568 if (b)
569 (void) setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
570
571 if (setsockopt(fd, IPPROTO_IPV6, b ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
572 return -errno;
573 } else
574 return -EAFNOSUPPORT;
575
576 return 0;
577 }
578
579 int dns_scope_llmnr_membership(DnsScope *s, bool b) {
580
581 if (s->protocol != DNS_PROTOCOL_LLMNR)
582 return 0;
583
584 return dns_scope_multicast_membership(s, b, LLMNR_MULTICAST_IPV4_ADDRESS, LLMNR_MULTICAST_IPV6_ADDRESS);
585 }
586
587 int dns_scope_mdns_membership(DnsScope *s, bool b) {
588
589 if (s->protocol != DNS_PROTOCOL_MDNS)
590 return 0;
591
592 return dns_scope_multicast_membership(s, b, MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS);
593 }
594
595 static int dns_scope_make_reply_packet(
596 DnsScope *s,
597 uint16_t id,
598 int rcode,
599 DnsQuestion *q,
600 DnsAnswer *answer,
601 DnsAnswer *soa,
602 bool tentative,
603 DnsPacket **ret) {
604
605 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
606 unsigned i;
607 int r;
608
609 assert(s);
610 assert(ret);
611
612 if ((!q || q->n_keys <= 0)
613 && (!answer || answer->n_rrs <= 0)
614 && (!soa || soa->n_rrs <= 0))
615 return -EINVAL;
616
617 r = dns_packet_new(&p, s->protocol, 0);
618 if (r < 0)
619 return r;
620
621 DNS_PACKET_HEADER(p)->id = id;
622 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
623 1 /* qr */,
624 0 /* opcode */,
625 0 /* c */,
626 0 /* tc */,
627 tentative,
628 0 /* (ra) */,
629 0 /* (ad) */,
630 0 /* (cd) */,
631 rcode));
632
633 if (q) {
634 for (i = 0; i < q->n_keys; i++) {
635 r = dns_packet_append_key(p, q->keys[i], NULL);
636 if (r < 0)
637 return r;
638 }
639
640 DNS_PACKET_HEADER(p)->qdcount = htobe16(q->n_keys);
641 }
642
643 if (answer) {
644 for (i = 0; i < answer->n_rrs; i++) {
645 r = dns_packet_append_rr(p, answer->items[i].rr, NULL, NULL);
646 if (r < 0)
647 return r;
648 }
649
650 DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
651 }
652
653 if (soa) {
654 for (i = 0; i < soa->n_rrs; i++) {
655 r = dns_packet_append_rr(p, soa->items[i].rr, NULL, NULL);
656 if (r < 0)
657 return r;
658 }
659
660 DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
661 }
662
663 *ret = p;
664 p = NULL;
665
666 return 0;
667 }
668
669 static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
670 unsigned n;
671
672 assert(s);
673 assert(p);
674
675 if (p->question)
676 for (n = 0; n < p->question->n_keys; n++)
677 dns_zone_verify_conflicts(&s->zone, p->question->keys[n]);
678 if (p->answer)
679 for (n = 0; n < p->answer->n_rrs; n++)
680 dns_zone_verify_conflicts(&s->zone, p->answer->items[n].rr->key);
681 }
682
683 void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
684 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
685 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
686 DnsResourceKey *key = NULL;
687 bool tentative = false;
688 int r, fd;
689
690 assert(s);
691 assert(p);
692
693 if (p->protocol != DNS_PROTOCOL_LLMNR)
694 return;
695
696 if (p->ipproto == IPPROTO_UDP) {
697 /* Don't accept UDP queries directed to anything but
698 * the LLMNR multicast addresses. See RFC 4795,
699 * section 2.5. */
700
701 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
702 return;
703
704 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
705 return;
706 }
707
708 r = dns_packet_extract(p);
709 if (r < 0) {
710 log_debug_errno(r, "Failed to extract resources from incoming packet: %m");
711 return;
712 }
713
714 if (DNS_PACKET_LLMNR_C(p)) {
715 /* Somebody notified us about a possible conflict */
716 dns_scope_verify_conflicts(s, p);
717 return;
718 }
719
720 assert(p->question->n_keys == 1);
721 key = p->question->keys[0];
722
723 r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
724 if (r < 0) {
725 log_debug_errno(r, "Failed to lookup key: %m");
726 return;
727 }
728 if (r == 0)
729 return;
730
731 if (answer)
732 dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
733
734 r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
735 if (r < 0) {
736 log_debug_errno(r, "Failed to build reply packet: %m");
737 return;
738 }
739
740 if (stream)
741 r = dns_stream_write_packet(stream, reply);
742 else {
743 if (!ratelimit_test(&s->ratelimit))
744 return;
745
746 if (p->family == AF_INET)
747 fd = manager_llmnr_ipv4_udp_fd(s->manager);
748 else if (p->family == AF_INET6)
749 fd = manager_llmnr_ipv6_udp_fd(s->manager);
750 else {
751 log_debug("Unknown protocol");
752 return;
753 }
754 if (fd < 0) {
755 log_debug_errno(fd, "Failed to get reply socket: %m");
756 return;
757 }
758
759 /* Note that we always immediately reply to all LLMNR
760 * requests, and do not wait any time, since we
761 * verified uniqueness for all records. Also see RFC
762 * 4795, Section 2.7 */
763
764 r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
765 }
766
767 if (r < 0) {
768 log_debug_errno(r, "Failed to send reply packet: %m");
769 return;
770 }
771 }
772
773 DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok) {
774 DnsTransaction *t;
775
776 assert(scope);
777 assert(key);
778
779 /* Try to find an ongoing transaction that is a equal to the
780 * specified question */
781 t = hashmap_get(scope->transactions_by_key, key);
782 if (!t)
783 return NULL;
784
785 /* Refuse reusing transactions that completed based on cached
786 * data instead of a real packet, if that's requested. */
787 if (!cache_ok &&
788 IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_RCODE_FAILURE) &&
789 t->answer_source != DNS_TRANSACTION_NETWORK)
790 return NULL;
791
792 return t;
793 }
794
795 static int dns_scope_make_conflict_packet(
796 DnsScope *s,
797 DnsResourceRecord *rr,
798 DnsPacket **ret) {
799
800 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
801 int r;
802
803 assert(s);
804 assert(rr);
805 assert(ret);
806
807 r = dns_packet_new(&p, s->protocol, 0);
808 if (r < 0)
809 return r;
810
811 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
812 0 /* qr */,
813 0 /* opcode */,
814 1 /* conflict */,
815 0 /* tc */,
816 0 /* t */,
817 0 /* (ra) */,
818 0 /* (ad) */,
819 0 /* (cd) */,
820 0));
821
822 /* For mDNS, the transaction ID should always be 0 */
823 if (s->protocol != DNS_PROTOCOL_MDNS)
824 random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
825
826 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
827 DNS_PACKET_HEADER(p)->arcount = htobe16(1);
828
829 r = dns_packet_append_key(p, rr->key, NULL);
830 if (r < 0)
831 return r;
832
833 r = dns_packet_append_rr(p, rr, NULL, NULL);
834 if (r < 0)
835 return r;
836
837 *ret = p;
838 p = NULL;
839
840 return 0;
841 }
842
843 static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
844 DnsScope *scope = userdata;
845 int r;
846
847 assert(es);
848 assert(scope);
849
850 scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
851
852 for (;;) {
853 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
854 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
855
856 rr = ordered_hashmap_steal_first(scope->conflict_queue);
857 if (!rr)
858 break;
859
860 r = dns_scope_make_conflict_packet(scope, rr, &p);
861 if (r < 0) {
862 log_error_errno(r, "Failed to make conflict packet: %m");
863 return 0;
864 }
865
866 r = dns_scope_emit_udp(scope, -1, p);
867 if (r < 0)
868 log_debug_errno(r, "Failed to send conflict packet: %m");
869 }
870
871 return 0;
872 }
873
874 int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
875 usec_t jitter;
876 int r;
877
878 assert(scope);
879 assert(rr);
880
881 /* We don't send these queries immediately. Instead, we queue
882 * them, and send them after some jitter delay. */
883 r = ordered_hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
884 if (r < 0) {
885 log_oom();
886 return r;
887 }
888
889 /* We only place one RR per key in the conflict
890 * messages, not all of them. That should be enough to
891 * indicate where there might be a conflict */
892 r = ordered_hashmap_put(scope->conflict_queue, rr->key, rr);
893 if (r == -EEXIST || r == 0)
894 return 0;
895 if (r < 0)
896 return log_debug_errno(r, "Failed to queue conflicting RR: %m");
897
898 dns_resource_record_ref(rr);
899
900 if (scope->conflict_event_source)
901 return 0;
902
903 random_bytes(&jitter, sizeof(jitter));
904 jitter %= LLMNR_JITTER_INTERVAL_USEC;
905
906 r = sd_event_add_time(scope->manager->event,
907 &scope->conflict_event_source,
908 clock_boottime_or_monotonic(),
909 now(clock_boottime_or_monotonic()) + jitter,
910 LLMNR_JITTER_INTERVAL_USEC,
911 on_conflict_dispatch, scope);
912 if (r < 0)
913 return log_debug_errno(r, "Failed to add conflict dispatch event: %m");
914
915 (void) sd_event_source_set_description(scope->conflict_event_source, "scope-conflict");
916
917 return 0;
918 }
919
920 void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
921 unsigned i;
922 int r;
923
924 assert(scope);
925 assert(p);
926
927 if (p->protocol != DNS_PROTOCOL_LLMNR)
928 return;
929
930 if (DNS_PACKET_RRCOUNT(p) <= 0)
931 return;
932
933 if (DNS_PACKET_LLMNR_C(p) != 0)
934 return;
935
936 if (DNS_PACKET_LLMNR_T(p) != 0)
937 return;
938
939 if (manager_our_packet(scope->manager, p))
940 return;
941
942 r = dns_packet_extract(p);
943 if (r < 0) {
944 log_debug_errno(r, "Failed to extract packet: %m");
945 return;
946 }
947
948 log_debug("Checking for conflicts...");
949
950 for (i = 0; i < p->answer->n_rrs; i++) {
951
952 /* Check for conflicts against the local zone. If we
953 * found one, we won't check any further */
954 r = dns_zone_check_conflicts(&scope->zone, p->answer->items[i].rr);
955 if (r != 0)
956 continue;
957
958 /* Check for conflicts against the local cache. If so,
959 * send out an advisory query, to inform everybody */
960 r = dns_cache_check_conflicts(&scope->cache, p->answer->items[i].rr, p->family, &p->sender);
961 if (r <= 0)
962 continue;
963
964 dns_scope_notify_conflict(scope, p->answer->items[i].rr);
965 }
966 }
967
968 void dns_scope_dump(DnsScope *s, FILE *f) {
969 assert(s);
970
971 if (!f)
972 f = stdout;
973
974 fputs("[Scope protocol=", f);
975 fputs(dns_protocol_to_string(s->protocol), f);
976
977 if (s->link) {
978 fputs(" interface=", f);
979 fputs(s->link->name, f);
980 }
981
982 if (s->family != AF_UNSPEC) {
983 fputs(" family=", f);
984 fputs(af_to_name(s->family), f);
985 }
986
987 fputs("]\n", f);
988
989 if (!dns_zone_is_empty(&s->zone)) {
990 fputs("ZONE:\n", f);
991 dns_zone_dump(&s->zone, f);
992 }
993
994 if (!dns_cache_is_empty(&s->cache)) {
995 fputs("CACHE:\n", f);
996 dns_cache_dump(&s->cache, f);
997 }
998 }
999
1000 DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s) {
1001 assert(s);
1002
1003 if (s->protocol != DNS_PROTOCOL_DNS)
1004 return NULL;
1005
1006 if (s->link)
1007 return s->link->search_domains;
1008
1009 return s->manager->search_domains;
1010 }
1011
1012 bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) {
1013 assert(s);
1014
1015 if (s->protocol != DNS_PROTOCOL_DNS)
1016 return false;
1017
1018 return dns_name_is_single_label(name);
1019 }
1020
1021 bool dns_scope_network_good(DnsScope *s) {
1022 /* Checks whether the network is in good state for lookups on this scope. For mDNS/LLMNR/Classic DNS scopes
1023 * bound to links this is easy, as they don't even exist if the link isn't in a suitable state. For the global
1024 * DNS scope we check whether there are any links that are up and have an address. */
1025
1026 if (s->link)
1027 return true;
1028
1029 return manager_routable(s->manager, AF_UNSPEC);
1030 }