]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-scope.c
resolved: add code to join/leave mDNS multicast groups
[thirdparty/systemd.git] / src / resolve / resolved-dns-scope.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
ad867662
LP
22#include <netinet/tcp.h>
23
46f08bea 24#include "af-list.h"
b5efdb8a 25#include "alloc-util.h"
4ad7f276 26#include "dns-domain.h"
3ffd4af2
LP
27#include "fd-util.h"
28#include "hostname-util.h"
29#include "missing.h"
30#include "random-util.h"
74b2466e 31#include "resolved-dns-scope.h"
3ffd4af2
LP
32#include "resolved-llmnr.h"
33#include "socket-util.h"
34#include "strv.h"
74b2466e 35
aea2429d
LP
36#define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
37#define MULTICAST_RATELIMIT_BURST 1000
38
9df3ba6c
TG
39/* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
40#define MULTICAST_RESEND_TIMEOUT_MIN_USEC (100 * USEC_PER_MSEC)
41#define MULTICAST_RESEND_TIMEOUT_MAX_USEC (1 * USEC_PER_SEC)
42
0dd25fb9 43int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
74b2466e
LP
44 DnsScope *s;
45
46 assert(m);
47 assert(ret);
48
49 s = new0(DnsScope, 1);
50 if (!s)
51 return -ENOMEM;
52
53 s->manager = m;
1716f6dc
LP
54 s->link = l;
55 s->protocol = protocol;
56 s->family = family;
9df3ba6c 57 s->resend_timeout = MULTICAST_RESEND_TIMEOUT_MIN_USEC;
74b2466e
LP
58
59 LIST_PREPEND(scopes, m->dns_scopes, s);
60
1716f6dc 61 dns_scope_llmnr_membership(s, true);
0db4c90a 62 dns_scope_mdns_membership(s, true);
1716f6dc 63
46f08bea 64 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 65
aea2429d
LP
66 /* Enforce ratelimiting for the multicast protocols */
67 RATELIMIT_INIT(s->ratelimit, MULTICAST_RATELIMIT_INTERVAL_USEC, MULTICAST_RATELIMIT_BURST);
68
74b2466e
LP
69 *ret = s;
70 return 0;
71}
72
801ad6a6 73static void dns_scope_abort_transactions(DnsScope *s) {
801ad6a6 74 assert(s);
1716f6dc 75
f9ebb22a
LP
76 while (s->transactions) {
77 DnsTransaction *t = s->transactions;
78
faa133f3
LP
79 /* Abort the transaction, but make sure it is not
80 * freed while we still look at it */
74b2466e 81
faa133f3 82 t->block_gc++;
ec2c5e43 83 dns_transaction_complete(t, DNS_TRANSACTION_ABORTED);
faa133f3 84 t->block_gc--;
74b2466e 85
ec2c5e43 86 dns_transaction_free(t);
74b2466e 87 }
801ad6a6
LP
88}
89
90DnsScope* dns_scope_free(DnsScope *s) {
91 DnsResourceRecord *rr;
92
93 if (!s)
94 return NULL;
95
96 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));
97
98 dns_scope_llmnr_membership(s, false);
0db4c90a 99 dns_scope_mdns_membership(s, false);
801ad6a6
LP
100 dns_scope_abort_transactions(s);
101
102 while (s->query_candidates)
103 dns_query_candidate_free(s->query_candidates);
74b2466e 104
f9ebb22a 105 hashmap_free(s->transactions_by_key);
da0c630e 106
1e43061b 107 while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
a4076574
LP
108 dns_resource_record_unref(rr);
109
1e43061b 110 ordered_hashmap_free(s->conflict_queue);
a4076574
LP
111 sd_event_source_unref(s->conflict_event_source);
112
322345fd 113 dns_cache_flush(&s->cache);
623a4c97 114 dns_zone_flush(&s->zone);
322345fd 115
74b2466e 116 LIST_REMOVE(scopes, s->manager->dns_scopes, s);
74b2466e
LP
117 free(s);
118
119 return NULL;
120}
121
2c27fbca 122DnsServer *dns_scope_get_dns_server(DnsScope *s) {
74b2466e
LP
123 assert(s);
124
1716f6dc
LP
125 if (s->protocol != DNS_PROTOCOL_DNS)
126 return NULL;
127
74b2466e
LP
128 if (s->link)
129 return link_get_dns_server(s->link);
130 else
131 return manager_get_dns_server(s->manager);
132}
133
134void dns_scope_next_dns_server(DnsScope *s) {
135 assert(s);
136
1716f6dc
LP
137 if (s->protocol != DNS_PROTOCOL_DNS)
138 return;
139
74b2466e
LP
140 if (s->link)
141 link_next_dns_server(s->link);
142 else
143 manager_next_dns_server(s->manager);
144}
145
9df3ba6c
TG
146void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
147 assert(s);
148
84129d46
LP
149 if (rtt <= s->max_rtt)
150 return;
151
152 s->max_rtt = rtt;
153 s->resend_timeout = MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC, s->max_rtt * 2), MULTICAST_RESEND_TIMEOUT_MAX_USEC);
9df3ba6c
TG
154}
155
156void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
157 assert(s);
158
159 if (s->resend_timeout <= usec)
160 s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
161}
162
9c5e12a4 163int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
1716f6dc
LP
164 union in_addr_union addr;
165 int ifindex = 0, r;
0dd25fb9 166 int family;
1716f6dc
LP
167 uint16_t port;
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;
22a37591 233 port = LLMNR_PORT;
1716f6dc
LP
234
235 if (family == AF_INET) {
236 addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
1716f6dc
LP
237 fd = manager_llmnr_ipv4_udp_fd(s->manager);
238 } else if (family == AF_INET6) {
239 addr.in6 = LLMNR_MULTICAST_IPV6_ADDRESS;
240 fd = manager_llmnr_ipv6_udp_fd(s->manager);
1716f6dc
LP
241 } else
242 return -EAFNOSUPPORT;
243 if (fd < 0)
244 return fd;
72290734
TG
245
246 r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
247 if (r < 0)
248 return r;
106784eb
DM
249
250 break;
251
252 default:
74b2466e 253 return -EAFNOSUPPORT;
106784eb 254 }
74b2466e 255
74b2466e
LP
256 return 1;
257}
258
0db64366 259static int dns_scope_socket(DnsScope *s, int type, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
8300ba21 260 DnsServer *srv = NULL;
ad867662
LP
261 _cleanup_close_ int fd = -1;
262 union sockaddr_union sa = {};
263 socklen_t salen;
623a4c97
LP
264 static const int one = 1;
265 int ret, r;
ad867662
LP
266
267 assert(s);
623a4c97 268 assert((family == AF_UNSPEC) == !address);
ad867662 269
623a4c97 270 if (family == AF_UNSPEC) {
2c27fbca 271 srv = dns_scope_get_dns_server(s);
623a4c97
LP
272 if (!srv)
273 return -ESRCH;
274
be808ea0
TG
275 srv->possible_features = dns_server_possible_features(srv);
276
277 if (type == SOCK_DGRAM && srv->possible_features < DNS_SERVER_FEATURE_LEVEL_UDP)
278 return -EAGAIN;
279
623a4c97
LP
280 sa.sa.sa_family = srv->family;
281 if (srv->family == AF_INET) {
282 sa.in.sin_port = htobe16(port);
283 sa.in.sin_addr = srv->address.in;
284 salen = sizeof(sa.in);
285 } else if (srv->family == AF_INET6) {
286 sa.in6.sin6_port = htobe16(port);
287 sa.in6.sin6_addr = srv->address.in6;
288 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
289 salen = sizeof(sa.in6);
290 } else
291 return -EAFNOSUPPORT;
292 } else {
293 sa.sa.sa_family = family;
294
295 if (family == AF_INET) {
296 sa.in.sin_port = htobe16(port);
297 sa.in.sin_addr = address->in;
298 salen = sizeof(sa.in);
299 } else if (family == AF_INET6) {
300 sa.in6.sin6_port = htobe16(port);
301 sa.in6.sin6_addr = address->in6;
302 sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
303 salen = sizeof(sa.in6);
304 } else
305 return -EAFNOSUPPORT;
306 }
ad867662 307
0db64366 308 fd = socket(sa.sa.sa_family, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
ad867662
LP
309 if (fd < 0)
310 return -errno;
311
0db64366
TG
312 if (type == SOCK_STREAM) {
313 r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
314 if (r < 0)
315 return -errno;
316 }
623a4c97
LP
317
318 if (s->link) {
319 uint32_t ifindex = htobe32(s->link->ifindex);
320
321 if (sa.sa.sa_family == AF_INET) {
322 r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
323 if (r < 0)
324 return -errno;
325 } else if (sa.sa.sa_family == AF_INET6) {
326 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
327 if (r < 0)
328 return -errno;
329 }
330 }
331
332 if (s->protocol == DNS_PROTOCOL_LLMNR) {
bf3f1271 333 /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
623a4c97
LP
334
335 if (sa.sa.sa_family == AF_INET) {
336 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
337 if (r < 0)
338 return -errno;
339 } else if (sa.sa.sa_family == AF_INET6) {
340 r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
341 if (r < 0)
342 return -errno;
343 }
344 }
ad867662
LP
345
346 r = connect(fd, &sa.sa, salen);
347 if (r < 0 && errno != EINPROGRESS)
348 return -errno;
349
8300ba21
TG
350 if (server)
351 *server = srv;
352
ad867662
LP
353 ret = fd;
354 fd = -1;
623a4c97 355
ad867662
LP
356 return ret;
357}
358
0db64366
TG
359int dns_scope_udp_dns_socket(DnsScope *s, DnsServer **server) {
360 return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, 53, server);
361}
362
363int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
364 return dns_scope_socket(s, SOCK_STREAM, family, address, port, server);
365}
366
51323288 367DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
a51c1048 368 DnsSearchDomain *d;
74b2466e
LP
369
370 assert(s);
371 assert(domain);
372
28b9b764
LP
373 /* Checks if the specified domain is something to look up on
374 * this scope. Note that this accepts non-qualified hostnames,
375 * i.e. those without any search path prefixed yet. */
376
51323288
LP
377 if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
378 return DNS_SCOPE_NO;
379
931851e8 380 if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, 0) & flags) == 0)
51323288
LP
381 return DNS_SCOPE_NO;
382
78c6a153
LP
383 /* Never resolve any loopback hostname or IP address via DNS,
384 * LLMNR or mDNS. Instead, always rely on synthesized RRs for
385 * these. */
386 if (is_localhost(domain) ||
387 dns_name_endswith(domain, "127.in-addr.arpa") > 0 ||
9436e8ca
LP
388 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)
389 return DNS_SCOPE_NO;
390
c9ad0edb
LP
391 /* Never respond to some of the domains listed in RFC6303 */
392 if (dns_name_endswith(domain, "0.in-addr.arpa") > 0 ||
393 dns_name_equal(domain, "255.255.255.255.in-addr.arpa") > 0 ||
394 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)
395 return DNS_SCOPE_NO;
396
801ad6a6
LP
397 /* Always honour search domains for routing queries. Note that
398 * we return DNS_SCOPE_YES here, rather than just
399 * DNS_SCOPE_MAYBE, which means wildcard scopes won't be
400 * considered anymore. */
a51c1048
LP
401 LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
402 if (dns_name_endswith(domain, d->name) > 0)
9b644bf9
LP
403 return DNS_SCOPE_YES;
404
106784eb 405 switch (s->protocol) {
801ad6a6 406
dc477e73 407 case DNS_PROTOCOL_DNS:
801ad6a6 408
28b9b764
LP
409 /* Exclude link-local IP ranges */
410 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
c9ad0edb
LP
411 dns_name_endswith(domain, "8.e.f.ip6.arpa") == 0 &&
412 dns_name_endswith(domain, "9.e.f.ip6.arpa") == 0 &&
413 dns_name_endswith(domain, "a.e.f.ip6.arpa") == 0 &&
414 dns_name_endswith(domain, "b.e.f.ip6.arpa") == 0)
faa133f3 415 return DNS_SCOPE_MAYBE;
1716f6dc 416
faa133f3 417 return DNS_SCOPE_NO;
1716f6dc 418
106784eb 419 case DNS_PROTOCOL_MDNS:
78c6a153
LP
420 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
421 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
422 (dns_name_endswith(domain, "local") > 0 && /* only resolve names ending in .local via mDNS */
423 dns_name_equal(domain, "local") == 0 && /* but not the single-label "local" name itself */
424 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via mDNS */
d8b7e75f 425 return DNS_SCOPE_MAYBE;
74b2466e
LP
426
427 return DNS_SCOPE_NO;
74b2466e 428
106784eb 429 case DNS_PROTOCOL_LLMNR:
78c6a153
LP
430 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
431 (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) ||
dc477e73 432 (dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */
78c6a153
LP
433 !is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
434 manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
1716f6dc 435 return DNS_SCOPE_MAYBE;
74b2466e 436
1716f6dc 437 return DNS_SCOPE_NO;
74b2466e 438
106784eb
DM
439 default:
440 assert_not_reached("Unknown scope protocol");
441 }
1716f6dc
LP
442}
443
444int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
445 assert(s);
446 assert(key);
447
28b9b764
LP
448 /* Check if it makes sense to resolve the specified key on
449 * this scope. Note that this call assumes as fully qualified
450 * name, i.e. the search suffixes already appended. */
451
452 if (s->protocol == DNS_PROTOCOL_DNS) {
453
454 /* On classic DNS, lookin up non-address RRs is always
455 * fine. (Specifically, we want to permit looking up
456 * DNSKEY and DS records on the root and top-level
457 * domains.) */
458 if (!dns_resource_key_is_address(key))
459 return true;
460
461 /* However, we refuse to look up A and AAAA RRs on the
462 * root and single-label domains, under the assumption
463 * that those should be resolved via LLMNR or search
464 * path only, and should not be leaked onto the
465 * internet. */
466 return !(dns_name_is_single_label(DNS_RESOURCE_KEY_NAME(key)) ||
467 dns_name_is_root(DNS_RESOURCE_KEY_NAME(key)));
468 }
1716f6dc
LP
469
470 /* On mDNS and LLMNR, send A and AAAA queries only on the
471 * respective scopes */
472
473 if (s->family == AF_INET && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_AAAA)
474 return false;
475
476 if (s->family == AF_INET6 && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_A)
477 return false;
478
479 return true;
480}
481
0db4c90a 482static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in, struct in6_addr in6) {
1716f6dc
LP
483 int fd;
484
5ba73e9b 485 assert(s);
5ba73e9b
LP
486 assert(s->link);
487
1716f6dc
LP
488 if (s->family == AF_INET) {
489 struct ip_mreqn mreqn = {
0db4c90a 490 .imr_multiaddr = in,
1716f6dc
LP
491 .imr_ifindex = s->link->ifindex,
492 };
493
494 fd = manager_llmnr_ipv4_udp_fd(s->manager);
495 if (fd < 0)
496 return fd;
497
7b4c2ee7
LP
498 /* Always first try to drop membership before we add
499 * one. This is necessary on some devices, such as
500 * veth. */
501 if (b)
dc751688 502 (void) setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
7b4c2ee7 503
1716f6dc
LP
504 if (setsockopt(fd, IPPROTO_IP, b ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0)
505 return -errno;
506
507 } else if (s->family == AF_INET6) {
508 struct ipv6_mreq mreq = {
0db4c90a 509 .ipv6mr_multiaddr = in6,
1716f6dc
LP
510 .ipv6mr_interface = s->link->ifindex,
511 };
512
513 fd = manager_llmnr_ipv6_udp_fd(s->manager);
514 if (fd < 0)
515 return fd;
516
7b4c2ee7 517 if (b)
dc751688 518 (void) setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
7b4c2ee7 519
1716f6dc
LP
520 if (setsockopt(fd, IPPROTO_IPV6, b ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
521 return -errno;
522 } else
523 return -EAFNOSUPPORT;
524
525 return 0;
74b2466e 526}
623a4c97 527
0db4c90a
DM
528int dns_scope_llmnr_membership(DnsScope *s, bool b) {
529
530 if (s->protocol != DNS_PROTOCOL_LLMNR)
531 return 0;
532
533 return dns_scope_multicast_membership(s, b, LLMNR_MULTICAST_IPV4_ADDRESS, LLMNR_MULTICAST_IPV6_ADDRESS);
534}
535
536int dns_scope_mdns_membership(DnsScope *s, bool b) {
537
538 if (s->protocol != DNS_PROTOCOL_MDNS)
539 return 0;
540
541 return dns_scope_multicast_membership(s, b, MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS);
542}
543
ec2c5e43
LP
544static int dns_scope_make_reply_packet(
545 DnsScope *s,
546 uint16_t id,
547 int rcode,
548 DnsQuestion *q,
549 DnsAnswer *answer,
550 DnsAnswer *soa,
551 bool tentative,
552 DnsPacket **ret) {
553
623a4c97
LP
554 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
555 unsigned i;
556 int r;
557
558 assert(s);
a4076574 559 assert(ret);
623a4c97 560
75cd513e
TA
561 if ((!q || q->n_keys <= 0)
562 && (!answer || answer->n_rrs <= 0)
563 && (!soa || soa->n_rrs <= 0))
623a4c97
LP
564 return -EINVAL;
565
566 r = dns_packet_new(&p, s->protocol, 0);
567 if (r < 0)
568 return r;
569
570 DNS_PACKET_HEADER(p)->id = id;
ea917db9
LP
571 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
572 1 /* qr */,
573 0 /* opcode */,
574 0 /* c */,
575 0 /* tc */,
ec2c5e43 576 tentative,
ea917db9
LP
577 0 /* (ra) */,
578 0 /* (ad) */,
579 0 /* (cd) */,
580 rcode));
623a4c97
LP
581
582 if (q) {
583 for (i = 0; i < q->n_keys; i++) {
584 r = dns_packet_append_key(p, q->keys[i], NULL);
585 if (r < 0)
586 return r;
587 }
588
589 DNS_PACKET_HEADER(p)->qdcount = htobe16(q->n_keys);
590 }
591
8bf52d3d
LP
592 if (answer) {
593 for (i = 0; i < answer->n_rrs; i++) {
a8812dd7 594 r = dns_packet_append_rr(p, answer->items[i].rr, NULL, NULL);
623a4c97
LP
595 if (r < 0)
596 return r;
597 }
598
8bf52d3d
LP
599 DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
600 }
601
602 if (soa) {
603 for (i = 0; i < soa->n_rrs; i++) {
a8812dd7 604 r = dns_packet_append_rr(p, soa->items[i].rr, NULL, NULL);
8bf52d3d
LP
605 if (r < 0)
606 return r;
607 }
608
609 DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
623a4c97
LP
610 }
611
612 *ret = p;
613 p = NULL;
614
615 return 0;
616}
617
a4076574
LP
618static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
619 unsigned n;
620
621 assert(s);
622 assert(p);
623
624 if (p->question)
625 for (n = 0; n < p->question->n_keys; n++)
626 dns_zone_verify_conflicts(&s->zone, p->question->keys[n]);
627 if (p->answer)
628 for (n = 0; n < p->answer->n_rrs; n++)
78c6a153 629 dns_zone_verify_conflicts(&s->zone, p->answer->items[n].rr->key);
a4076574
LP
630}
631
623a4c97
LP
632void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
633 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
8bf52d3d 634 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
5032b16d 635 DnsResourceKey *key = NULL;
ec2c5e43 636 bool tentative = false;
623a4c97
LP
637 int r, fd;
638
639 assert(s);
640 assert(p);
641
642 if (p->protocol != DNS_PROTOCOL_LLMNR)
643 return;
644
2442b93d
LP
645 if (p->ipproto == IPPROTO_UDP) {
646 /* Don't accept UDP queries directed to anything but
647 * the LLMNR multicast addresses. See RFC 4795,
d076c6f9 648 * section 2.5. */
2442b93d
LP
649
650 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
651 return;
652
653 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
654 return;
655 }
656
623a4c97
LP
657 r = dns_packet_extract(p);
658 if (r < 0) {
da927ba9 659 log_debug_errno(r, "Failed to extract resources from incoming packet: %m");
623a4c97
LP
660 return;
661 }
662
8b757a38 663 if (DNS_PACKET_LLMNR_C(p)) {
a4076574
LP
664 /* Somebody notified us about a possible conflict */
665 dns_scope_verify_conflicts(s, p);
ea917db9
LP
666 return;
667 }
668
5032b16d
LP
669 assert(p->question->n_keys == 1);
670 key = p->question->keys[0];
671
672 r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
623a4c97 673 if (r < 0) {
da927ba9 674 log_debug_errno(r, "Failed to lookup key: %m");
623a4c97
LP
675 return;
676 }
677 if (r == 0)
678 return;
679
fcf57f9c
LP
680 if (answer)
681 dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
af93291c 682
ec2c5e43 683 r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
623a4c97 684 if (r < 0) {
da927ba9 685 log_debug_errno(r, "Failed to build reply packet: %m");
623a4c97
LP
686 return;
687 }
688
689 if (stream)
690 r = dns_stream_write_packet(stream, reply);
691 else {
aea2429d
LP
692 if (!ratelimit_test(&s->ratelimit))
693 return;
694
623a4c97
LP
695 if (p->family == AF_INET)
696 fd = manager_llmnr_ipv4_udp_fd(s->manager);
697 else if (p->family == AF_INET6)
698 fd = manager_llmnr_ipv6_udp_fd(s->manager);
699 else {
700 log_debug("Unknown protocol");
701 return;
702 }
703 if (fd < 0) {
da927ba9 704 log_debug_errno(fd, "Failed to get reply socket: %m");
623a4c97
LP
705 return;
706 }
707
6e068472
LP
708 /* Note that we always immediately reply to all LLMNR
709 * requests, and do not wait any time, since we
710 * verified uniqueness for all records. Also see RFC
711 * 4795, Section 2.7 */
712
623a4c97
LP
713 r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
714 }
715
716 if (r < 0) {
da927ba9 717 log_debug_errno(r, "Failed to send reply packet: %m");
623a4c97
LP
718 return;
719 }
720}
ec2c5e43 721
f52e61da 722DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok) {
ec2c5e43
LP
723 DnsTransaction *t;
724
725 assert(scope);
f52e61da 726 assert(key);
ec2c5e43 727
da0c630e
LP
728 /* Try to find an ongoing transaction that is a equal to the
729 * specified question */
f9ebb22a 730 t = hashmap_get(scope->transactions_by_key, key);
da0c630e
LP
731 if (!t)
732 return NULL;
dc4d47e2 733
da0c630e
LP
734 /* Refuse reusing transactions that completed based on cached
735 * data instead of a real packet, if that's requested. */
736 if (!cache_ok &&
737 IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE) &&
c3bc53e6 738 t->answer_source != DNS_TRANSACTION_NETWORK)
da0c630e 739 return NULL;
ec2c5e43 740
da0c630e 741 return t;
ec2c5e43 742}
a4076574
LP
743
744static int dns_scope_make_conflict_packet(
745 DnsScope *s,
746 DnsResourceRecord *rr,
747 DnsPacket **ret) {
748
749 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
750 int r;
751
752 assert(s);
753 assert(rr);
754 assert(ret);
755
756 r = dns_packet_new(&p, s->protocol, 0);
757 if (r < 0)
758 return r;
759
760 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
761 0 /* qr */,
762 0 /* opcode */,
763 1 /* conflict */,
764 0 /* tc */,
765 0 /* t */,
766 0 /* (ra) */,
767 0 /* (ad) */,
768 0 /* (cd) */,
769 0));
770 random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
771 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
772 DNS_PACKET_HEADER(p)->arcount = htobe16(1);
773
774 r = dns_packet_append_key(p, rr->key, NULL);
775 if (r < 0)
776 return r;
777
a8812dd7 778 r = dns_packet_append_rr(p, rr, NULL, NULL);
a4076574
LP
779 if (r < 0)
780 return r;
781
782 *ret = p;
783 p = NULL;
784
785 return 0;
786}
787
788static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
789 DnsScope *scope = userdata;
790 int r;
791
792 assert(es);
793 assert(scope);
794
795 scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
796
797 for (;;) {
798 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
799 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
800
1e43061b 801 rr = ordered_hashmap_steal_first(scope->conflict_queue);
a4076574
LP
802 if (!rr)
803 break;
804
805 r = dns_scope_make_conflict_packet(scope, rr, &p);
806 if (r < 0) {
da927ba9 807 log_error_errno(r, "Failed to make conflict packet: %m");
a4076574
LP
808 return 0;
809 }
810
9c5e12a4 811 r = dns_scope_emit(scope, -1, NULL, p);
a4076574 812 if (r < 0)
da927ba9 813 log_debug_errno(r, "Failed to send conflict packet: %m");
a4076574
LP
814 }
815
816 return 0;
817}
818
819int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
820 usec_t jitter;
821 int r;
822
823 assert(scope);
824 assert(rr);
825
826 /* We don't send these queries immediately. Instead, we queue
827 * them, and send them after some jitter delay. */
1e43061b 828 r = ordered_hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
a4076574
LP
829 if (r < 0) {
830 log_oom();
831 return r;
832 }
833
834 /* We only place one RR per key in the conflict
835 * messages, not all of them. That should be enough to
836 * indicate where there might be a conflict */
1e43061b 837 r = ordered_hashmap_put(scope->conflict_queue, rr->key, rr);
a4076574
LP
838 if (r == -EEXIST || r == 0)
839 return 0;
f647962d
MS
840 if (r < 0)
841 return log_debug_errno(r, "Failed to queue conflicting RR: %m");
a4076574
LP
842
843 dns_resource_record_ref(rr);
844
845 if (scope->conflict_event_source)
846 return 0;
847
848 random_bytes(&jitter, sizeof(jitter));
849 jitter %= LLMNR_JITTER_INTERVAL_USEC;
850
851 r = sd_event_add_time(scope->manager->event,
852 &scope->conflict_event_source,
853 clock_boottime_or_monotonic(),
854 now(clock_boottime_or_monotonic()) + jitter,
855 LLMNR_JITTER_INTERVAL_USEC,
856 on_conflict_dispatch, scope);
f647962d
MS
857 if (r < 0)
858 return log_debug_errno(r, "Failed to add conflict dispatch event: %m");
a4076574
LP
859
860 return 0;
861}
862
863void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
864 unsigned i;
865 int r;
866
867 assert(scope);
868 assert(p);
869
870 if (p->protocol != DNS_PROTOCOL_LLMNR)
871 return;
872
873 if (DNS_PACKET_RRCOUNT(p) <= 0)
874 return;
875
8b757a38 876 if (DNS_PACKET_LLMNR_C(p) != 0)
a4076574
LP
877 return;
878
8b757a38 879 if (DNS_PACKET_LLMNR_T(p) != 0)
a4076574
LP
880 return;
881
882 if (manager_our_packet(scope->manager, p))
883 return;
884
885 r = dns_packet_extract(p);
886 if (r < 0) {
da927ba9 887 log_debug_errno(r, "Failed to extract packet: %m");
a4076574
LP
888 return;
889 }
890
891 log_debug("Checking for conflicts...");
892
893 for (i = 0; i < p->answer->n_rrs; i++) {
894
895 /* Check for conflicts against the local zone. If we
896 * found one, we won't check any further */
78c6a153 897 r = dns_zone_check_conflicts(&scope->zone, p->answer->items[i].rr);
a4076574
LP
898 if (r != 0)
899 continue;
900
901 /* Check for conflicts against the local cache. If so,
902 * send out an advisory query, to inform everybody */
78c6a153 903 r = dns_cache_check_conflicts(&scope->cache, p->answer->items[i].rr, p->family, &p->sender);
a4076574
LP
904 if (r <= 0)
905 continue;
906
78c6a153 907 dns_scope_notify_conflict(scope, p->answer->items[i].rr);
a4076574
LP
908 }
909}
4d506d6b
LP
910
911void dns_scope_dump(DnsScope *s, FILE *f) {
912 assert(s);
913
914 if (!f)
915 f = stdout;
916
917 fputs("[Scope protocol=", f);
918 fputs(dns_protocol_to_string(s->protocol), f);
919
920 if (s->link) {
921 fputs(" interface=", f);
922 fputs(s->link->name, f);
923 }
924
925 if (s->family != AF_UNSPEC) {
926 fputs(" family=", f);
927 fputs(af_to_name(s->family), f);
928 }
929
930 fputs("]\n", f);
931
932 if (!dns_zone_is_empty(&s->zone)) {
933 fputs("ZONE:\n", f);
934 dns_zone_dump(&s->zone, f);
935 }
936
937 if (!dns_cache_is_empty(&s->cache)) {
938 fputs("CACHE:\n", f);
939 dns_cache_dump(&s->cache, f);
940 }
941}
a51c1048
LP
942
943DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s) {
801ad6a6
LP
944 assert(s);
945
a51c1048
LP
946 if (s->protocol != DNS_PROTOCOL_DNS)
947 return NULL;
948
949 if (s->link)
950 return s->link->search_domains;
951
28b9b764 952 return s->manager->search_domains;
801ad6a6
LP
953}
954
dc477e73 955bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) {
801ad6a6
LP
956 assert(s);
957
958 if (s->protocol != DNS_PROTOCOL_DNS)
dc477e73 959 return false;
801ad6a6 960
dc477e73 961 return dns_name_is_single_label(name);
801ad6a6 962}