]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-scope.c
Merge pull request #1691 from poettering/util-lib-3
[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 "socket-util.h"
34 #include "strv.h"
35
36 #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
37 #define MULTICAST_RATELIMIT_BURST 1000
38
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)
42
43 int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
44 DnsScope *s;
45
46 assert(m);
47 assert(ret);
48
49 s = new0(DnsScope, 1);
50 if (!s)
51 return -ENOMEM;
52
53 s->manager = m;
54 s->link = l;
55 s->protocol = protocol;
56 s->family = family;
57 s->resend_timeout = MULTICAST_RESEND_TIMEOUT_MIN_USEC;
58
59 LIST_PREPEND(scopes, m->dns_scopes, s);
60
61 dns_scope_llmnr_membership(s, true);
62
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));
64
65 /* Enforce ratelimiting for the multicast protocols */
66 RATELIMIT_INIT(s->ratelimit, MULTICAST_RATELIMIT_INTERVAL_USEC, MULTICAST_RATELIMIT_BURST);
67
68 *ret = s;
69 return 0;
70 }
71
72 DnsScope* dns_scope_free(DnsScope *s) {
73 DnsTransaction *t;
74 DnsResourceRecord *rr;
75
76 if (!s)
77 return NULL;
78
79 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));
80
81 dns_scope_llmnr_membership(s, false);
82
83 while ((t = hashmap_steal_first(s->transactions))) {
84 /* Abort the transaction, but make sure it is not
85 * freed while we still look at it */
86
87 t->block_gc++;
88 dns_transaction_complete(t, DNS_TRANSACTION_ABORTED);
89 t->block_gc--;
90
91 dns_transaction_free(t);
92 }
93
94 hashmap_free(s->transactions);
95
96 while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
97 dns_resource_record_unref(rr);
98
99 ordered_hashmap_free(s->conflict_queue);
100 sd_event_source_unref(s->conflict_event_source);
101
102 dns_cache_flush(&s->cache);
103 dns_zone_flush(&s->zone);
104
105 LIST_REMOVE(scopes, s->manager->dns_scopes, s);
106 strv_free(s->domains);
107 free(s);
108
109 return NULL;
110 }
111
112 DnsServer *dns_scope_get_dns_server(DnsScope *s) {
113 assert(s);
114
115 if (s->protocol != DNS_PROTOCOL_DNS)
116 return NULL;
117
118 if (s->link)
119 return link_get_dns_server(s->link);
120 else
121 return manager_get_dns_server(s->manager);
122 }
123
124 void dns_scope_next_dns_server(DnsScope *s) {
125 assert(s);
126
127 if (s->protocol != DNS_PROTOCOL_DNS)
128 return;
129
130 if (s->link)
131 link_next_dns_server(s->link);
132 else
133 manager_next_dns_server(s->manager);
134 }
135
136 void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
137 assert(s);
138
139 if (rtt > s->max_rtt) {
140 s->max_rtt = rtt;
141 s->resend_timeout = MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC, s->max_rtt * 2),
142 MULTICAST_RESEND_TIMEOUT_MAX_USEC);
143 }
144 }
145
146 void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
147 assert(s);
148
149 if (s->resend_timeout <= usec)
150 s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
151 }
152
153 int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) {
154 union in_addr_union addr;
155 int ifindex = 0, r;
156 int family;
157 uint16_t port;
158 uint32_t mtu;
159
160 assert(s);
161 assert(p);
162 assert(p->protocol == s->protocol);
163 assert((s->protocol == DNS_PROTOCOL_DNS) != (fd < 0));
164
165 if (s->link) {
166 mtu = s->link->mtu;
167 ifindex = s->link->ifindex;
168 } else
169 mtu = manager_find_mtu(s->manager);
170
171 switch (s->protocol) {
172 case DNS_PROTOCOL_DNS:
173 if (DNS_PACKET_QDCOUNT(p) > 1)
174 return -EOPNOTSUPP;
175
176 if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
177 return -EMSGSIZE;
178
179 if (p->size + UDP_PACKET_HEADER_SIZE > mtu)
180 return -EMSGSIZE;
181
182 r = manager_write(s->manager, fd, p);
183 if (r < 0)
184 return r;
185
186 break;
187
188 case DNS_PROTOCOL_LLMNR:
189 if (DNS_PACKET_QDCOUNT(p) > 1)
190 return -EOPNOTSUPP;
191
192 if (!ratelimit_test(&s->ratelimit))
193 return -EBUSY;
194
195 family = s->family;
196 port = LLMNR_PORT;
197
198 if (family == AF_INET) {
199 addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
200 fd = manager_llmnr_ipv4_udp_fd(s->manager);
201 } else if (family == AF_INET6) {
202 addr.in6 = LLMNR_MULTICAST_IPV6_ADDRESS;
203 fd = manager_llmnr_ipv6_udp_fd(s->manager);
204 } else
205 return -EAFNOSUPPORT;
206 if (fd < 0)
207 return fd;
208
209 r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
210 if (r < 0)
211 return r;
212
213 break;
214
215 default:
216 return -EAFNOSUPPORT;
217 }
218
219 return 1;
220 }
221
222 static int dns_scope_socket(DnsScope *s, int type, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
223 DnsServer *srv = NULL;
224 _cleanup_close_ int fd = -1;
225 union sockaddr_union sa = {};
226 socklen_t salen;
227 static const int one = 1;
228 int ret, r;
229
230 assert(s);
231 assert((family == AF_UNSPEC) == !address);
232
233 if (family == AF_UNSPEC) {
234 srv = dns_scope_get_dns_server(s);
235 if (!srv)
236 return -ESRCH;
237
238 sa.sa.sa_family = srv->family;
239 if (srv->family == AF_INET) {
240 sa.in.sin_port = htobe16(port);
241 sa.in.sin_addr = srv->address.in;
242 salen = sizeof(sa.in);
243 } else if (srv->family == AF_INET6) {
244 sa.in6.sin6_port = htobe16(port);
245 sa.in6.sin6_addr = srv->address.in6;
246 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
247 salen = sizeof(sa.in6);
248 } else
249 return -EAFNOSUPPORT;
250 } else {
251 sa.sa.sa_family = family;
252
253 if (family == AF_INET) {
254 sa.in.sin_port = htobe16(port);
255 sa.in.sin_addr = address->in;
256 salen = sizeof(sa.in);
257 } else if (family == AF_INET6) {
258 sa.in6.sin6_port = htobe16(port);
259 sa.in6.sin6_addr = address->in6;
260 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
261 salen = sizeof(sa.in6);
262 } else
263 return -EAFNOSUPPORT;
264 }
265
266 fd = socket(sa.sa.sa_family, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
267 if (fd < 0)
268 return -errno;
269
270 if (type == SOCK_STREAM) {
271 r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
272 if (r < 0)
273 return -errno;
274 }
275
276 if (s->link) {
277 uint32_t ifindex = htobe32(s->link->ifindex);
278
279 if (sa.sa.sa_family == AF_INET) {
280 r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
281 if (r < 0)
282 return -errno;
283 } else if (sa.sa.sa_family == AF_INET6) {
284 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
285 if (r < 0)
286 return -errno;
287 }
288 }
289
290 if (s->protocol == DNS_PROTOCOL_LLMNR) {
291 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
292
293 if (sa.sa.sa_family == AF_INET) {
294 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
295 if (r < 0)
296 return -errno;
297 } else if (sa.sa.sa_family == AF_INET6) {
298 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
299 if (r < 0)
300 return -errno;
301 }
302 }
303
304 r = connect(fd, &sa.sa, salen);
305 if (r < 0 && errno != EINPROGRESS)
306 return -errno;
307
308 if (server)
309 *server = srv;
310
311 ret = fd;
312 fd = -1;
313
314 return ret;
315 }
316
317 int dns_scope_udp_dns_socket(DnsScope *s, DnsServer **server) {
318 return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, 53, server);
319 }
320
321 int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
322 return dns_scope_socket(s, SOCK_STREAM, family, address, port, server);
323 }
324
325 DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
326 char **i;
327
328 assert(s);
329 assert(domain);
330
331 if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
332 return DNS_SCOPE_NO;
333
334 if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family) & flags) == 0)
335 return DNS_SCOPE_NO;
336
337 if (dns_name_root(domain) != 0)
338 return DNS_SCOPE_NO;
339
340 /* Never resolve any loopback hostname or IP address via DNS,
341 * LLMNR or mDNS. Instead, always rely on synthesized RRs for
342 * these. */
343 if (is_localhost(domain) ||
344 dns_name_endswith(domain, "127.in-addr.arpa") > 0 ||
345 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)
346 return DNS_SCOPE_NO;
347
348 STRV_FOREACH(i, s->domains)
349 if (dns_name_endswith(domain, *i) > 0)
350 return DNS_SCOPE_YES;
351
352 switch (s->protocol) {
353 case DNS_PROTOCOL_DNS:
354 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
355 dns_name_endswith(domain, "0.8.e.f.ip6.arpa") == 0 &&
356 dns_name_single_label(domain) == 0)
357 return DNS_SCOPE_MAYBE;
358
359 return DNS_SCOPE_NO;
360
361 case DNS_PROTOCOL_MDNS:
362 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
363 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
364 (dns_name_endswith(domain, "local") > 0 && /* only resolve names ending in .local via mDNS */
365 dns_name_equal(domain, "local") == 0 && /* but not the single-label "local" name itself */
366 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via mDNS */
367 return DNS_SCOPE_MAYBE;
368
369 return DNS_SCOPE_NO;
370
371 case DNS_PROTOCOL_LLMNR:
372 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
373 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
374 (dns_name_single_label(domain) > 0 && /* only resolve single label names via LLMNR */
375 !is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
376 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
377 return DNS_SCOPE_MAYBE;
378
379 return DNS_SCOPE_NO;
380
381 default:
382 assert_not_reached("Unknown scope protocol");
383 }
384 }
385
386 int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
387 assert(s);
388 assert(key);
389
390 if (s->protocol == DNS_PROTOCOL_DNS)
391 return true;
392
393 /* On mDNS and LLMNR, send A and AAAA queries only on the
394 * respective scopes */
395
396 if (s->family == AF_INET && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_AAAA)
397 return false;
398
399 if (s->family == AF_INET6 && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_A)
400 return false;
401
402 return true;
403 }
404
405 int dns_scope_llmnr_membership(DnsScope *s, bool b) {
406 int fd;
407
408 assert(s);
409
410 if (s->protocol != DNS_PROTOCOL_LLMNR)
411 return 0;
412
413 assert(s->link);
414
415 if (s->family == AF_INET) {
416 struct ip_mreqn mreqn = {
417 .imr_multiaddr = LLMNR_MULTICAST_IPV4_ADDRESS,
418 .imr_ifindex = s->link->ifindex,
419 };
420
421 fd = manager_llmnr_ipv4_udp_fd(s->manager);
422 if (fd < 0)
423 return fd;
424
425 /* Always first try to drop membership before we add
426 * one. This is necessary on some devices, such as
427 * veth. */
428 if (b)
429 (void) setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
430
431 if (setsockopt(fd, IPPROTO_IP, b ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0)
432 return -errno;
433
434 } else if (s->family == AF_INET6) {
435 struct ipv6_mreq mreq = {
436 .ipv6mr_multiaddr = LLMNR_MULTICAST_IPV6_ADDRESS,
437 .ipv6mr_interface = s->link->ifindex,
438 };
439
440 fd = manager_llmnr_ipv6_udp_fd(s->manager);
441 if (fd < 0)
442 return fd;
443
444 if (b)
445 (void) setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
446
447 if (setsockopt(fd, IPPROTO_IPV6, b ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
448 return -errno;
449 } else
450 return -EAFNOSUPPORT;
451
452 return 0;
453 }
454
455 static int dns_scope_make_reply_packet(
456 DnsScope *s,
457 uint16_t id,
458 int rcode,
459 DnsQuestion *q,
460 DnsAnswer *answer,
461 DnsAnswer *soa,
462 bool tentative,
463 DnsPacket **ret) {
464
465 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
466 unsigned i;
467 int r;
468
469 assert(s);
470 assert(ret);
471
472 if ((!q || q->n_keys <= 0)
473 && (!answer || answer->n_rrs <= 0)
474 && (!soa || soa->n_rrs <= 0))
475 return -EINVAL;
476
477 r = dns_packet_new(&p, s->protocol, 0);
478 if (r < 0)
479 return r;
480
481 DNS_PACKET_HEADER(p)->id = id;
482 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
483 1 /* qr */,
484 0 /* opcode */,
485 0 /* c */,
486 0 /* tc */,
487 tentative,
488 0 /* (ra) */,
489 0 /* (ad) */,
490 0 /* (cd) */,
491 rcode));
492
493 if (q) {
494 for (i = 0; i < q->n_keys; i++) {
495 r = dns_packet_append_key(p, q->keys[i], NULL);
496 if (r < 0)
497 return r;
498 }
499
500 DNS_PACKET_HEADER(p)->qdcount = htobe16(q->n_keys);
501 }
502
503 if (answer) {
504 for (i = 0; i < answer->n_rrs; i++) {
505 r = dns_packet_append_rr(p, answer->items[i].rr, NULL);
506 if (r < 0)
507 return r;
508 }
509
510 DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
511 }
512
513 if (soa) {
514 for (i = 0; i < soa->n_rrs; i++) {
515 r = dns_packet_append_rr(p, soa->items[i].rr, NULL);
516 if (r < 0)
517 return r;
518 }
519
520 DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
521 }
522
523 *ret = p;
524 p = NULL;
525
526 return 0;
527 }
528
529 static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
530 unsigned n;
531
532 assert(s);
533 assert(p);
534
535 if (p->question)
536 for (n = 0; n < p->question->n_keys; n++)
537 dns_zone_verify_conflicts(&s->zone, p->question->keys[n]);
538 if (p->answer)
539 for (n = 0; n < p->answer->n_rrs; n++)
540 dns_zone_verify_conflicts(&s->zone, p->answer->items[n].rr->key);
541 }
542
543 void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
544 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
545 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
546 bool tentative = false;
547 int r, fd;
548
549 assert(s);
550 assert(p);
551
552 if (p->protocol != DNS_PROTOCOL_LLMNR)
553 return;
554
555 if (p->ipproto == IPPROTO_UDP) {
556 /* Don't accept UDP queries directed to anything but
557 * the LLMNR multicast addresses. See RFC 4795,
558 * section 2.5. */
559
560 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
561 return;
562
563 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
564 return;
565 }
566
567 r = dns_packet_extract(p);
568 if (r < 0) {
569 log_debug_errno(r, "Failed to extract resources from incoming packet: %m");
570 return;
571 }
572
573 if (DNS_PACKET_LLMNR_C(p)) {
574 /* Somebody notified us about a possible conflict */
575 dns_scope_verify_conflicts(s, p);
576 return;
577 }
578
579 r = dns_zone_lookup(&s->zone, p->question, &answer, &soa, &tentative);
580 if (r < 0) {
581 log_debug_errno(r, "Failed to lookup key: %m");
582 return;
583 }
584 if (r == 0)
585 return;
586
587 if (answer)
588 dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
589
590 r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
591 if (r < 0) {
592 log_debug_errno(r, "Failed to build reply packet: %m");
593 return;
594 }
595
596 if (stream)
597 r = dns_stream_write_packet(stream, reply);
598 else {
599 if (!ratelimit_test(&s->ratelimit))
600 return;
601
602 if (p->family == AF_INET)
603 fd = manager_llmnr_ipv4_udp_fd(s->manager);
604 else if (p->family == AF_INET6)
605 fd = manager_llmnr_ipv6_udp_fd(s->manager);
606 else {
607 log_debug("Unknown protocol");
608 return;
609 }
610 if (fd < 0) {
611 log_debug_errno(fd, "Failed to get reply socket: %m");
612 return;
613 }
614
615 /* Note that we always immediately reply to all LLMNR
616 * requests, and do not wait any time, since we
617 * verified uniqueness for all records. Also see RFC
618 * 4795, Section 2.7 */
619
620 r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
621 }
622
623 if (r < 0) {
624 log_debug_errno(r, "Failed to send reply packet: %m");
625 return;
626 }
627 }
628
629 DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok) {
630 DnsTransaction *t;
631
632 assert(scope);
633 assert(key);
634
635 /* Try to find an ongoing transaction that is a equal to the
636 * specified question */
637 t = hashmap_get(scope->transactions, key);
638 if (!t)
639 return NULL;
640
641 /* Refuse reusing transactions that completed based on cached
642 * data instead of a real packet, if that's requested. */
643 if (!cache_ok &&
644 IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE) &&
645 !t->received)
646 return NULL;
647
648 return t;
649 }
650
651 static int dns_scope_make_conflict_packet(
652 DnsScope *s,
653 DnsResourceRecord *rr,
654 DnsPacket **ret) {
655
656 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
657 int r;
658
659 assert(s);
660 assert(rr);
661 assert(ret);
662
663 r = dns_packet_new(&p, s->protocol, 0);
664 if (r < 0)
665 return r;
666
667 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
668 0 /* qr */,
669 0 /* opcode */,
670 1 /* conflict */,
671 0 /* tc */,
672 0 /* t */,
673 0 /* (ra) */,
674 0 /* (ad) */,
675 0 /* (cd) */,
676 0));
677 random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
678 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
679 DNS_PACKET_HEADER(p)->arcount = htobe16(1);
680
681 r = dns_packet_append_key(p, rr->key, NULL);
682 if (r < 0)
683 return r;
684
685 r = dns_packet_append_rr(p, rr, NULL);
686 if (r < 0)
687 return r;
688
689 *ret = p;
690 p = NULL;
691
692 return 0;
693 }
694
695 static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
696 DnsScope *scope = userdata;
697 int r;
698
699 assert(es);
700 assert(scope);
701
702 scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
703
704 for (;;) {
705 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
706 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
707
708 rr = ordered_hashmap_steal_first(scope->conflict_queue);
709 if (!rr)
710 break;
711
712 r = dns_scope_make_conflict_packet(scope, rr, &p);
713 if (r < 0) {
714 log_error_errno(r, "Failed to make conflict packet: %m");
715 return 0;
716 }
717
718 r = dns_scope_emit(scope, -1, p);
719 if (r < 0)
720 log_debug_errno(r, "Failed to send conflict packet: %m");
721 }
722
723 return 0;
724 }
725
726 int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
727 usec_t jitter;
728 int r;
729
730 assert(scope);
731 assert(rr);
732
733 /* We don't send these queries immediately. Instead, we queue
734 * them, and send them after some jitter delay. */
735 r = ordered_hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
736 if (r < 0) {
737 log_oom();
738 return r;
739 }
740
741 /* We only place one RR per key in the conflict
742 * messages, not all of them. That should be enough to
743 * indicate where there might be a conflict */
744 r = ordered_hashmap_put(scope->conflict_queue, rr->key, rr);
745 if (r == -EEXIST || r == 0)
746 return 0;
747 if (r < 0)
748 return log_debug_errno(r, "Failed to queue conflicting RR: %m");
749
750 dns_resource_record_ref(rr);
751
752 if (scope->conflict_event_source)
753 return 0;
754
755 random_bytes(&jitter, sizeof(jitter));
756 jitter %= LLMNR_JITTER_INTERVAL_USEC;
757
758 r = sd_event_add_time(scope->manager->event,
759 &scope->conflict_event_source,
760 clock_boottime_or_monotonic(),
761 now(clock_boottime_or_monotonic()) + jitter,
762 LLMNR_JITTER_INTERVAL_USEC,
763 on_conflict_dispatch, scope);
764 if (r < 0)
765 return log_debug_errno(r, "Failed to add conflict dispatch event: %m");
766
767 return 0;
768 }
769
770 void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
771 unsigned i;
772 int r;
773
774 assert(scope);
775 assert(p);
776
777 if (p->protocol != DNS_PROTOCOL_LLMNR)
778 return;
779
780 if (DNS_PACKET_RRCOUNT(p) <= 0)
781 return;
782
783 if (DNS_PACKET_LLMNR_C(p) != 0)
784 return;
785
786 if (DNS_PACKET_LLMNR_T(p) != 0)
787 return;
788
789 if (manager_our_packet(scope->manager, p))
790 return;
791
792 r = dns_packet_extract(p);
793 if (r < 0) {
794 log_debug_errno(r, "Failed to extract packet: %m");
795 return;
796 }
797
798 log_debug("Checking for conflicts...");
799
800 for (i = 0; i < p->answer->n_rrs; i++) {
801
802 /* Check for conflicts against the local zone. If we
803 * found one, we won't check any further */
804 r = dns_zone_check_conflicts(&scope->zone, p->answer->items[i].rr);
805 if (r != 0)
806 continue;
807
808 /* Check for conflicts against the local cache. If so,
809 * send out an advisory query, to inform everybody */
810 r = dns_cache_check_conflicts(&scope->cache, p->answer->items[i].rr, p->family, &p->sender);
811 if (r <= 0)
812 continue;
813
814 dns_scope_notify_conflict(scope, p->answer->items[i].rr);
815 }
816 }
817
818 void dns_scope_dump(DnsScope *s, FILE *f) {
819 assert(s);
820
821 if (!f)
822 f = stdout;
823
824 fputs("[Scope protocol=", f);
825 fputs(dns_protocol_to_string(s->protocol), f);
826
827 if (s->link) {
828 fputs(" interface=", f);
829 fputs(s->link->name, f);
830 }
831
832 if (s->family != AF_UNSPEC) {
833 fputs(" family=", f);
834 fputs(af_to_name(s->family), f);
835 }
836
837 fputs("]\n", f);
838
839 if (!dns_zone_is_empty(&s->zone)) {
840 fputs("ZONE:\n", f);
841 dns_zone_dump(&s->zone, f);
842 }
843
844 if (!dns_cache_is_empty(&s->cache)) {
845 fputs("CACHE:\n", f);
846 dns_cache_dump(&s->cache, f);
847 }
848 }