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