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