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