]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-scope.c
question: drop dns_question_is_superset() which we don't use anymore
[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
LP
105 LIST_REMOVE(scopes, s->manager->dns_scopes, s);
106 strv_free(s->domains);
107 free(s);
108
109 return NULL;
110}
111
2c27fbca 112DnsServer *dns_scope_get_dns_server(DnsScope *s) {
74b2466e
LP
113 assert(s);
114
1716f6dc
LP
115 if (s->protocol != DNS_PROTOCOL_DNS)
116 return NULL;
117
74b2466e
LP
118 if (s->link)
119 return link_get_dns_server(s->link);
120 else
121 return manager_get_dns_server(s->manager);
122}
123
124void dns_scope_next_dns_server(DnsScope *s) {
125 assert(s);
126
1716f6dc
LP
127 if (s->protocol != DNS_PROTOCOL_DNS)
128 return;
129
74b2466e
LP
130 if (s->link)
131 link_next_dns_server(s->link);
132 else
133 manager_next_dns_server(s->manager);
134}
135
9df3ba6c
TG
136void 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
146void 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
471d40d9 153int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) {
1716f6dc
LP
154 union in_addr_union addr;
155 int ifindex = 0, r;
0dd25fb9 156 int family;
1716f6dc
LP
157 uint16_t port;
158 uint32_t mtu;
74b2466e
LP
159
160 assert(s);
161 assert(p);
1716f6dc 162 assert(p->protocol == s->protocol);
471d40d9 163 assert((s->protocol == DNS_PROTOCOL_DNS) != (fd < 0));
ad867662
LP
164
165 if (s->link) {
1716f6dc 166 mtu = s->link->mtu;
74b2466e 167 ifindex = s->link->ifindex;
1716f6dc 168 } else
e1c95994 169 mtu = manager_find_mtu(s->manager);
74b2466e 170
106784eb
DM
171 switch (s->protocol) {
172 case DNS_PROTOCOL_DNS:
623a4c97 173 if (DNS_PACKET_QDCOUNT(p) > 1)
15411c0c 174 return -EOPNOTSUPP;
623a4c97 175
1716f6dc
LP
176 if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
177 return -EMSGSIZE;
178
a0166609 179 if (p->size + UDP_PACKET_HEADER_SIZE > mtu)
1716f6dc
LP
180 return -EMSGSIZE;
181
72290734
TG
182 r = manager_write(s->manager, fd, p);
183 if (r < 0)
184 return r;
185
106784eb 186 break;
1716f6dc 187
106784eb 188 case DNS_PROTOCOL_LLMNR:
1716f6dc 189 if (DNS_PACKET_QDCOUNT(p) > 1)
15411c0c 190 return -EOPNOTSUPP;
1716f6dc 191
aea2429d
LP
192 if (!ratelimit_test(&s->ratelimit))
193 return -EBUSY;
194
1716f6dc 195 family = s->family;
22a37591 196 port = LLMNR_PORT;
1716f6dc
LP
197
198 if (family == AF_INET) {
199 addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
1716f6dc
LP
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);
1716f6dc
LP
204 } else
205 return -EAFNOSUPPORT;
206 if (fd < 0)
207 return fd;
72290734
TG
208
209 r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
210 if (r < 0)
211 return r;
106784eb
DM
212
213 break;
214
215 default:
74b2466e 216 return -EAFNOSUPPORT;
106784eb 217 }
74b2466e 218
74b2466e
LP
219 return 1;
220}
221
0db64366 222static int dns_scope_socket(DnsScope *s, int type, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
8300ba21 223 DnsServer *srv = NULL;
ad867662
LP
224 _cleanup_close_ int fd = -1;
225 union sockaddr_union sa = {};
226 socklen_t salen;
623a4c97
LP
227 static const int one = 1;
228 int ret, r;
ad867662
LP
229
230 assert(s);
623a4c97 231 assert((family == AF_UNSPEC) == !address);
ad867662 232
623a4c97 233 if (family == AF_UNSPEC) {
2c27fbca 234 srv = dns_scope_get_dns_server(s);
623a4c97
LP
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 }
ad867662 265
0db64366 266 fd = socket(sa.sa.sa_family, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
ad867662
LP
267 if (fd < 0)
268 return -errno;
269
0db64366
TG
270 if (type == SOCK_STREAM) {
271 r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
272 if (r < 0)
273 return -errno;
274 }
623a4c97
LP
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) {
bf3f1271 291 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
623a4c97
LP
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 }
ad867662
LP
303
304 r = connect(fd, &sa.sa, salen);
305 if (r < 0 && errno != EINPROGRESS)
306 return -errno;
307
8300ba21
TG
308 if (server)
309 *server = srv;
310
ad867662
LP
311 ret = fd;
312 fd = -1;
623a4c97 313
ad867662
LP
314 return ret;
315}
316
0db64366
TG
317int dns_scope_udp_dns_socket(DnsScope *s, DnsServer **server) {
318 return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, 53, server);
319}
320
321int 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
51323288 325DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
74b2466e
LP
326 char **i;
327
328 assert(s);
329 assert(domain);
330
51323288
LP
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
faa133f3 337 if (dns_name_root(domain) != 0)
74b2466e
LP
338 return DNS_SCOPE_NO;
339
78c6a153
LP
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 ||
9436e8ca
LP
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
9b644bf9
LP
348 STRV_FOREACH(i, s->domains)
349 if (dns_name_endswith(domain, *i) > 0)
350 return DNS_SCOPE_YES;
351
106784eb
DM
352 switch (s->protocol) {
353 case DNS_PROTOCOL_DNS:
faa133f3
LP
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;
1716f6dc 358
faa133f3 359 return DNS_SCOPE_NO;
1716f6dc 360
106784eb 361 case DNS_PROTOCOL_MDNS:
78c6a153
LP
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 */
d8b7e75f 367 return DNS_SCOPE_MAYBE;
74b2466e
LP
368
369 return DNS_SCOPE_NO;
74b2466e 370
106784eb 371 case DNS_PROTOCOL_LLMNR:
78c6a153
LP
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 */
1716f6dc 377 return DNS_SCOPE_MAYBE;
74b2466e 378
1716f6dc 379 return DNS_SCOPE_NO;
74b2466e 380
106784eb
DM
381 default:
382 assert_not_reached("Unknown scope protocol");
383 }
1716f6dc
LP
384}
385
386int 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
405int dns_scope_llmnr_membership(DnsScope *s, bool b) {
406 int fd;
407
5ba73e9b 408 assert(s);
4de120ee
LP
409
410 if (s->protocol != DNS_PROTOCOL_LLMNR)
411 return 0;
412
5ba73e9b
LP
413 assert(s->link);
414
1716f6dc
LP
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
7b4c2ee7
LP
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)
dc751688 429 (void) setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
7b4c2ee7 430
1716f6dc
LP
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
7b4c2ee7 444 if (b)
dc751688 445 (void) setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
7b4c2ee7 446
1716f6dc
LP
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;
74b2466e 453}
623a4c97 454
ec2c5e43
LP
455static 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
623a4c97
LP
465 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
466 unsigned i;
467 int r;
468
469 assert(s);
a4076574 470 assert(ret);
623a4c97 471
75cd513e
TA
472 if ((!q || q->n_keys <= 0)
473 && (!answer || answer->n_rrs <= 0)
474 && (!soa || soa->n_rrs <= 0))
623a4c97
LP
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;
ea917db9
LP
482 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
483 1 /* qr */,
484 0 /* opcode */,
485 0 /* c */,
486 0 /* tc */,
ec2c5e43 487 tentative,
ea917db9
LP
488 0 /* (ra) */,
489 0 /* (ad) */,
490 0 /* (cd) */,
491 rcode));
623a4c97
LP
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
8bf52d3d
LP
503 if (answer) {
504 for (i = 0; i < answer->n_rrs; i++) {
78c6a153 505 r = dns_packet_append_rr(p, answer->items[i].rr, NULL);
623a4c97
LP
506 if (r < 0)
507 return r;
508 }
509
8bf52d3d
LP
510 DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
511 }
512
513 if (soa) {
514 for (i = 0; i < soa->n_rrs; i++) {
78c6a153 515 r = dns_packet_append_rr(p, soa->items[i].rr, NULL);
8bf52d3d
LP
516 if (r < 0)
517 return r;
518 }
519
520 DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
623a4c97
LP
521 }
522
523 *ret = p;
524 p = NULL;
525
526 return 0;
527}
528
a4076574
LP
529static 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++)
78c6a153 540 dns_zone_verify_conflicts(&s->zone, p->answer->items[n].rr->key);
a4076574
LP
541}
542
623a4c97
LP
543void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
544 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
8bf52d3d 545 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
5032b16d 546 DnsResourceKey *key = NULL;
ec2c5e43 547 bool tentative = false;
623a4c97
LP
548 int r, fd;
549
550 assert(s);
551 assert(p);
552
553 if (p->protocol != DNS_PROTOCOL_LLMNR)
554 return;
555
2442b93d
LP
556 if (p->ipproto == IPPROTO_UDP) {
557 /* Don't accept UDP queries directed to anything but
558 * the LLMNR multicast addresses. See RFC 4795,
d076c6f9 559 * section 2.5. */
2442b93d
LP
560
561 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
562 return;
563
564 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
565 return;
566 }
567
623a4c97
LP
568 r = dns_packet_extract(p);
569 if (r < 0) {
da927ba9 570 log_debug_errno(r, "Failed to extract resources from incoming packet: %m");
623a4c97
LP
571 return;
572 }
573
8b757a38 574 if (DNS_PACKET_LLMNR_C(p)) {
a4076574
LP
575 /* Somebody notified us about a possible conflict */
576 dns_scope_verify_conflicts(s, p);
ea917db9
LP
577 return;
578 }
579
5032b16d
LP
580 assert(p->question->n_keys == 1);
581 key = p->question->keys[0];
582
583 r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
623a4c97 584 if (r < 0) {
da927ba9 585 log_debug_errno(r, "Failed to lookup key: %m");
623a4c97
LP
586 return;
587 }
588 if (r == 0)
589 return;
590
fcf57f9c
LP
591 if (answer)
592 dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
af93291c 593
ec2c5e43 594 r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
623a4c97 595 if (r < 0) {
da927ba9 596 log_debug_errno(r, "Failed to build reply packet: %m");
623a4c97
LP
597 return;
598 }
599
600 if (stream)
601 r = dns_stream_write_packet(stream, reply);
602 else {
aea2429d
LP
603 if (!ratelimit_test(&s->ratelimit))
604 return;
605
623a4c97
LP
606 if (p->family == AF_INET)
607 fd = manager_llmnr_ipv4_udp_fd(s->manager);
608 else if (p->family == AF_INET6)
609 fd = manager_llmnr_ipv6_udp_fd(s->manager);
610 else {
611 log_debug("Unknown protocol");
612 return;
613 }
614 if (fd < 0) {
da927ba9 615 log_debug_errno(fd, "Failed to get reply socket: %m");
623a4c97
LP
616 return;
617 }
618
6e068472
LP
619 /* Note that we always immediately reply to all LLMNR
620 * requests, and do not wait any time, since we
621 * verified uniqueness for all records. Also see RFC
622 * 4795, Section 2.7 */
623
623a4c97
LP
624 r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
625 }
626
627 if (r < 0) {
da927ba9 628 log_debug_errno(r, "Failed to send reply packet: %m");
623a4c97
LP
629 return;
630 }
631}
ec2c5e43 632
f52e61da 633DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok) {
ec2c5e43
LP
634 DnsTransaction *t;
635
636 assert(scope);
f52e61da 637 assert(key);
ec2c5e43 638
da0c630e
LP
639 /* Try to find an ongoing transaction that is a equal to the
640 * specified question */
641 t = hashmap_get(scope->transactions, key);
642 if (!t)
643 return NULL;
dc4d47e2 644
da0c630e
LP
645 /* Refuse reusing transactions that completed based on cached
646 * data instead of a real packet, if that's requested. */
647 if (!cache_ok &&
648 IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE) &&
649 !t->received)
650 return NULL;
ec2c5e43 651
da0c630e 652 return t;
ec2c5e43 653}
a4076574
LP
654
655static int dns_scope_make_conflict_packet(
656 DnsScope *s,
657 DnsResourceRecord *rr,
658 DnsPacket **ret) {
659
660 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
661 int r;
662
663 assert(s);
664 assert(rr);
665 assert(ret);
666
667 r = dns_packet_new(&p, s->protocol, 0);
668 if (r < 0)
669 return r;
670
671 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
672 0 /* qr */,
673 0 /* opcode */,
674 1 /* conflict */,
675 0 /* tc */,
676 0 /* t */,
677 0 /* (ra) */,
678 0 /* (ad) */,
679 0 /* (cd) */,
680 0));
681 random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
682 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
683 DNS_PACKET_HEADER(p)->arcount = htobe16(1);
684
685 r = dns_packet_append_key(p, rr->key, NULL);
686 if (r < 0)
687 return r;
688
689 r = dns_packet_append_rr(p, rr, NULL);
690 if (r < 0)
691 return r;
692
693 *ret = p;
694 p = NULL;
695
696 return 0;
697}
698
699static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
700 DnsScope *scope = userdata;
701 int r;
702
703 assert(es);
704 assert(scope);
705
706 scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
707
708 for (;;) {
709 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
710 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
711
1e43061b 712 rr = ordered_hashmap_steal_first(scope->conflict_queue);
a4076574
LP
713 if (!rr)
714 break;
715
716 r = dns_scope_make_conflict_packet(scope, rr, &p);
717 if (r < 0) {
da927ba9 718 log_error_errno(r, "Failed to make conflict packet: %m");
a4076574
LP
719 return 0;
720 }
721
471d40d9 722 r = dns_scope_emit(scope, -1, p);
a4076574 723 if (r < 0)
da927ba9 724 log_debug_errno(r, "Failed to send conflict packet: %m");
a4076574
LP
725 }
726
727 return 0;
728}
729
730int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
731 usec_t jitter;
732 int r;
733
734 assert(scope);
735 assert(rr);
736
737 /* We don't send these queries immediately. Instead, we queue
738 * them, and send them after some jitter delay. */
1e43061b 739 r = ordered_hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
a4076574
LP
740 if (r < 0) {
741 log_oom();
742 return r;
743 }
744
745 /* We only place one RR per key in the conflict
746 * messages, not all of them. That should be enough to
747 * indicate where there might be a conflict */
1e43061b 748 r = ordered_hashmap_put(scope->conflict_queue, rr->key, rr);
a4076574
LP
749 if (r == -EEXIST || r == 0)
750 return 0;
f647962d
MS
751 if (r < 0)
752 return log_debug_errno(r, "Failed to queue conflicting RR: %m");
a4076574
LP
753
754 dns_resource_record_ref(rr);
755
756 if (scope->conflict_event_source)
757 return 0;
758
759 random_bytes(&jitter, sizeof(jitter));
760 jitter %= LLMNR_JITTER_INTERVAL_USEC;
761
762 r = sd_event_add_time(scope->manager->event,
763 &scope->conflict_event_source,
764 clock_boottime_or_monotonic(),
765 now(clock_boottime_or_monotonic()) + jitter,
766 LLMNR_JITTER_INTERVAL_USEC,
767 on_conflict_dispatch, scope);
f647962d
MS
768 if (r < 0)
769 return log_debug_errno(r, "Failed to add conflict dispatch event: %m");
a4076574
LP
770
771 return 0;
772}
773
774void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
775 unsigned i;
776 int r;
777
778 assert(scope);
779 assert(p);
780
781 if (p->protocol != DNS_PROTOCOL_LLMNR)
782 return;
783
784 if (DNS_PACKET_RRCOUNT(p) <= 0)
785 return;
786
8b757a38 787 if (DNS_PACKET_LLMNR_C(p) != 0)
a4076574
LP
788 return;
789
8b757a38 790 if (DNS_PACKET_LLMNR_T(p) != 0)
a4076574
LP
791 return;
792
793 if (manager_our_packet(scope->manager, p))
794 return;
795
796 r = dns_packet_extract(p);
797 if (r < 0) {
da927ba9 798 log_debug_errno(r, "Failed to extract packet: %m");
a4076574
LP
799 return;
800 }
801
802 log_debug("Checking for conflicts...");
803
804 for (i = 0; i < p->answer->n_rrs; i++) {
805
806 /* Check for conflicts against the local zone. If we
807 * found one, we won't check any further */
78c6a153 808 r = dns_zone_check_conflicts(&scope->zone, p->answer->items[i].rr);
a4076574
LP
809 if (r != 0)
810 continue;
811
812 /* Check for conflicts against the local cache. If so,
813 * send out an advisory query, to inform everybody */
78c6a153 814 r = dns_cache_check_conflicts(&scope->cache, p->answer->items[i].rr, p->family, &p->sender);
a4076574
LP
815 if (r <= 0)
816 continue;
817
78c6a153 818 dns_scope_notify_conflict(scope, p->answer->items[i].rr);
a4076574
LP
819 }
820}
4d506d6b
LP
821
822void dns_scope_dump(DnsScope *s, FILE *f) {
823 assert(s);
824
825 if (!f)
826 f = stdout;
827
828 fputs("[Scope protocol=", f);
829 fputs(dns_protocol_to_string(s->protocol), f);
830
831 if (s->link) {
832 fputs(" interface=", f);
833 fputs(s->link->name, f);
834 }
835
836 if (s->family != AF_UNSPEC) {
837 fputs(" family=", f);
838 fputs(af_to_name(s->family), f);
839 }
840
841 fputs("]\n", f);
842
843 if (!dns_zone_is_empty(&s->zone)) {
844 fputs("ZONE:\n", f);
845 dns_zone_dump(&s->zone, f);
846 }
847
848 if (!dns_cache_is_empty(&s->cache)) {
849 fputs("CACHE:\n", f);
850 dns_cache_dump(&s->cache, f);
851 }
852}