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