nss: always explicitly reset all error variables
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
CommitLineData
091a364c
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
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
22#include <arpa/inet.h>
23#include <resolv.h>
1716f6dc 24#include <net/if.h>
74b2466e
LP
25#include <sys/ioctl.h>
26#include <sys/poll.h>
27#include <netinet/in.h>
091a364c 28
74b2466e 29#include "rtnl-util.h"
091a364c
TG
30#include "event-util.h"
31#include "network-util.h"
091a364c
TG
32#include "network-internal.h"
33#include "conf-parser.h"
74b2466e 34#include "socket-util.h"
a2a416f7 35#include "af-list.h"
74b2466e 36#include "resolved.h"
eb60f9cd
LP
37#include "utf8.h"
38#include "resolved-dns-domain.h"
74b2466e
LP
39
40#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
41
42static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
43 Manager *m = userdata;
44 uint16_t type;
45 Link *l;
46 int ifindex, r;
47
48 assert(rtnl);
49 assert(m);
50 assert(mm);
51
52 r = sd_rtnl_message_get_type(mm, &type);
53 if (r < 0)
54 goto fail;
55
56 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
57 if (r < 0)
58 goto fail;
59
60 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
61
62 switch (type) {
63
a2a416f7
LP
64 case RTM_NEWLINK:{
65 bool is_new = !l;
74b2466e 66
a2a416f7 67 if (!l) {
74b2466e
LP
68 r = link_new(m, &l, ifindex);
69 if (r < 0)
70 goto fail;
71 }
72
73 r = link_update_rtnl(l, mm);
74 if (r < 0)
75 goto fail;
76
a2a416f7
LP
77 if (is_new)
78 log_debug("Found new link %i/%s", ifindex, l->name);
79
74b2466e 80 break;
a2a416f7 81 }
74b2466e
LP
82
83 case RTM_DELLINK:
84 if (l) {
a2a416f7 85 log_debug("Removing link %i/%s", l->ifindex, l->name);
74b2466e
LP
86 link_free(l);
87 }
88
89 break;
90 }
91
92 return 0;
93
94fail:
95 log_warning("Failed to process RTNL link message: %s", strerror(-r));
96 return 0;
97}
98
99static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
100 Manager *m = userdata;
101 union in_addr_union address;
74b2466e 102 uint16_t type;
0dd25fb9 103 int r, ifindex, family;
74b2466e
LP
104 LinkAddress *a;
105 Link *l;
106
107 assert(rtnl);
108 assert(mm);
109 assert(m);
110
111 r = sd_rtnl_message_get_type(mm, &type);
112 if (r < 0)
113 goto fail;
114
115 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
116 if (r < 0)
117 goto fail;
118
119 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
120 if (!l)
121 return 0;
122
123 r = sd_rtnl_message_addr_get_family(mm, &family);
124 if (r < 0)
125 goto fail;
126
127 switch (family) {
128
129 case AF_INET:
130 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
131 if (r < 0) {
132 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
133 if (r < 0)
134 goto fail;
135 }
136
137 break;
138
139 case AF_INET6:
140 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
141 if (r < 0) {
142 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
143 if (r < 0)
144 goto fail;
145 }
146
147 break;
148
149 default:
150 return 0;
151 }
152
153 a = link_find_address(l, family, &address);
154
155 switch (type) {
156
157 case RTM_NEWADDR:
158
159 if (!a) {
160 r = link_address_new(l, &a, family, &address);
161 if (r < 0)
162 return r;
163 }
164
165 r = link_address_update_rtnl(a, mm);
166 if (r < 0)
167 return r;
168
169 break;
170
171 case RTM_DELADDR:
172 if (a)
173 link_address_free(a);
174 break;
175 }
176
177 return 0;
178
179fail:
180 log_warning("Failed to process RTNL address message: %s", strerror(-r));
181 return 0;
182}
183
184
185static int manager_rtnl_listen(Manager *m) {
186 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
187 sd_rtnl_message *i;
188 int r;
189
190 assert(m);
191
192 /* First, subscibe to interfaces coming and going */
193 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
194 if (r < 0)
195 return r;
196
197 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
198 if (r < 0)
199 return r;
200
201 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
202 if (r < 0)
203 return r;
204
205 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
206 if (r < 0)
207 return r;
208
209 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
210 if (r < 0)
211 return r;
091a364c 212
74b2466e
LP
213 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
214 if (r < 0)
215 return r;
216
217 /* Then, enumerate all links */
218 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
219 if (r < 0)
220 return r;
221
222 r = sd_rtnl_message_request_dump(req, true);
223 if (r < 0)
224 return r;
225
226 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
227 if (r < 0)
228 return r;
229
230 for (i = reply; i; i = sd_rtnl_message_next(i)) {
231 r = manager_process_link(m->rtnl, i, m);
232 if (r < 0)
233 return r;
234 }
235
236 req = sd_rtnl_message_unref(req);
237 reply = sd_rtnl_message_unref(reply);
238
239 /* Finally, enumerate all addresses, too */
240 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
241 if (r < 0)
242 return r;
243
244 r = sd_rtnl_message_request_dump(req, true);
245 if (r < 0)
246 return r;
247
248 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
249 if (r < 0)
250 return r;
251
252 for (i = reply; i; i = sd_rtnl_message_next(i)) {
253 r = manager_process_address(m->rtnl, i, m);
254 if (r < 0)
255 return r;
256 }
257
258 return r;
259}
260
261static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
262 Manager *m = userdata;
263 Iterator i;
264 Link *l;
265 int r;
266
267 assert(m);
268
269 sd_network_monitor_flush(m->network_monitor);
270
271 HASHMAP_FOREACH(l, m->links, i) {
272 r = link_update_monitor(l);
273 if (r < 0)
274 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
275 }
276
277 r = manager_write_resolv_conf(m);
278 if (r < 0)
279 log_warning("Could not update resolv.conf: %s", strerror(-r));
280
281 return 0;
282}
283
284static int manager_network_monitor_listen(Manager *m) {
285 int r, fd, events;
286
287 assert(m);
288
0014a4ad 289 r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e
LP
290 if (r < 0)
291 return r;
292
293 fd = sd_network_monitor_get_fd(m->network_monitor);
294 if (fd < 0)
295 return fd;
296
297 events = sd_network_monitor_get_events(m->network_monitor);
298 if (events < 0)
299 return events;
300
301 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
302 if (r < 0)
303 return r;
304
305 return 0;
306}
307
308static int parse_dns_server_string(Manager *m, const char *string) {
a2a5291b 309 const char *word, *state;
091a364c
TG
310 size_t length;
311 int r;
312
313 assert(m);
314 assert(string);
315
316 FOREACH_WORD_QUOTED(word, length, string, state) {
74b2466e 317 char buffer[length+1];
0dd25fb9 318 int family;
74b2466e 319 union in_addr_union addr;
091a364c 320
74b2466e
LP
321 memcpy(buffer, word, length);
322 buffer[length] = 0;
091a364c 323
74b2466e 324 r = in_addr_from_string_auto(buffer, &family, &addr);
091a364c 325 if (r < 0) {
74b2466e 326 log_warning("Ignoring invalid DNS address '%s'", buffer);
091a364c
TG
327 continue;
328 }
329
74b2466e
LP
330 /* filter out duplicates */
331 if (manager_find_dns_server(m, family, &addr))
332 continue;
333
6073b6f2 334 r = dns_server_new(m, NULL, NULL, family, &addr);
74b2466e
LP
335 if (r < 0)
336 return r;
091a364c 337 }
b2fadec6 338 /* do not warn about state here, since probably systemd already did */
091a364c
TG
339
340 return 0;
341}
342
343int config_parse_dnsv(
344 const char *unit,
345 const char *filename,
346 unsigned line,
347 const char *section,
348 unsigned section_line,
349 const char *lvalue,
350 int ltype,
351 const char *rvalue,
352 void *data,
353 void *userdata) {
354
355 Manager *m = userdata;
74b2466e 356 int r;
091a364c
TG
357
358 assert(filename);
359 assert(lvalue);
360 assert(rvalue);
361 assert(m);
362
74b2466e
LP
363 /* Empty assignment means clear the list */
364 if (isempty(rvalue)) {
365 while (m->dns_servers)
366 dns_server_free(m->dns_servers);
367
368 return 0;
091a364c
TG
369 }
370
74b2466e
LP
371 r = parse_dns_server_string(m, rvalue);
372 if (r < 0) {
373 log_error("Failed to parse DNS server string");
374 return r;
375 }
091a364c
TG
376
377 return 0;
378}
379
74b2466e 380int manager_parse_config_file(Manager *m) {
091a364c
TG
381 assert(m);
382
36f822c4
ZJS
383 return config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
384 "Resolve\0",
385 config_item_perf_lookup, resolved_gperf_lookup,
386 false, false, true, m);
091a364c
TG
387}
388
eb60f9cd
LP
389static int determine_hostname(char **ret) {
390 _cleanup_free_ char *h = NULL, *n = NULL;
391 int r;
392
393 assert(ret);
394
395 h = gethostname_malloc();
396 if (!h)
397 return log_oom();
398
399 if (!utf8_is_valid(h)) {
400 log_error("System hostname is not UTF-8 clean.");
401 return -EINVAL;
402 }
403
404 r = dns_name_normalize(h, &n);
405 if (r < 0) {
406 log_error("System hostname '%s' cannot be normalized.", h);
407 return r;
408 }
409
410 *ret = n;
411 n = NULL;
412
413 return 0;
414}
415
416static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
417 _cleanup_free_ char *h = NULL;
418 Manager *m = userdata;
419 int r;
420
421 assert(m);
422
423 r = determine_hostname(&h);
424 if (r < 0)
425 return 0; /* ignore invalid hostnames */
426
427 if (streq(h, m->hostname))
428 return 0;
429
430 log_info("System hostname changed to '%s'.", h);
431 free(m->hostname);
432 m->hostname = h;
433 h = NULL;
434
435 manager_refresh_rrs(m);
436
437 return 0;
438}
439
440static int manager_watch_hostname(Manager *m) {
441 _cleanup_free_ char *h = NULL;
442 int r;
443
444 assert(m);
445
446 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
447 if (m->hostname_fd < 0) {
448 log_warning("Failed to watch hostname: %m");
449 return 0;
450 }
451
452 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
453 if (r < 0) {
454 if (r == -EPERM)
455 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
456 m->hostname_fd = safe_close(m->hostname_fd);
457 else {
458 log_error("Failed to add hostname event source: %s", strerror(-r));
459 return r;
460 }
461 }
462
463 r = determine_hostname(&m->hostname);
464 if (r < 0) {
465 log_info("Defaulting to hostname 'linux'.");
466 m->hostname = strdup("linux");
467 if (!m->hostname)
468 return log_oom();
469 } else
470 log_info("Using system hostname '%s'.", m->hostname);
471
472 return 0;
473}
474
091a364c 475int manager_new(Manager **ret) {
74b2466e 476 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
477 int r;
478
c92e531c
LP
479 assert(ret);
480
091a364c
TG
481 m = new0(Manager, 1);
482 if (!m)
483 return -ENOMEM;
484
74b2466e 485 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
1716f6dc 486 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 487 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
eb60f9cd 488 m->hostname_fd = -1;
1716f6dc
LP
489
490 m->use_llmnr = true;
091a364c 491
faa133f3 492 r = parse_dns_server_string(m, DNS_SERVERS);
091a364c
TG
493 if (r < 0)
494 return r;
495
496 r = sd_event_default(&m->event);
497 if (r < 0)
498 return r;
499
500 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
501 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
502
503 sd_event_set_watchdog(m->event, true);
504
eb60f9cd
LP
505 r = manager_watch_hostname(m);
506 if (r < 0)
507 return r;
508
1716f6dc 509 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
510 if (r < 0)
511 return r;
512
513 r = manager_network_monitor_listen(m);
514 if (r < 0)
515 return r;
516
517 r = manager_rtnl_listen(m);
518 if (r < 0)
519 return r;
520
521 r = manager_connect_bus(m);
522 if (r < 0)
523 return r;
524
623a4c97
LP
525 r = manager_llmnr_ipv4_udp_fd(m);
526 if (r < 0)
527 return r;
528 r = manager_llmnr_ipv6_udp_fd(m);
529 if (r < 0)
530 return r;
531 r = manager_llmnr_ipv4_tcp_fd(m);
532 if (r < 0)
533 return r;
534 r = manager_llmnr_ipv6_tcp_fd(m);
535 if (r < 0)
536 return r;
537
091a364c
TG
538 *ret = m;
539 m = NULL;
540
541 return 0;
542}
543
74b2466e
LP
544Manager *manager_free(Manager *m) {
545 Link *l;
091a364c
TG
546
547 if (!m)
74b2466e
LP
548 return NULL;
549
550 while (m->dns_queries)
551 dns_query_free(m->dns_queries);
552
ec2c5e43 553 hashmap_free(m->dns_transactions);
74b2466e
LP
554
555 while ((l = hashmap_first(m->links)))
556 link_free(l);
557 hashmap_free(m->links);
558
559 dns_scope_free(m->unicast_scope);
560
561 while (m->dns_servers)
562 dns_server_free(m->dns_servers);
091a364c 563
096b6773
LP
564 sd_event_source_unref(m->network_event_source);
565 sd_network_monitor_unref(m->network_monitor);
091a364c 566
74b2466e
LP
567 sd_event_source_unref(m->dns_ipv4_event_source);
568 sd_event_source_unref(m->dns_ipv6_event_source);
74b2466e
LP
569 safe_close(m->dns_ipv4_fd);
570 safe_close(m->dns_ipv6_fd);
571
1716f6dc
LP
572 sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
573 sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
574 safe_close(m->llmnr_ipv4_udp_fd);
575 safe_close(m->llmnr_ipv6_udp_fd);
576
623a4c97
LP
577 sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
578 sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
579 safe_close(m->llmnr_ipv4_tcp_fd);
580 safe_close(m->llmnr_ipv6_tcp_fd);
581
74b2466e
LP
582 sd_event_source_unref(m->bus_retry_event_source);
583 sd_bus_unref(m->bus);
091a364c 584
74b2466e 585 sd_event_unref(m->event);
623a4c97
LP
586
587 dns_resource_key_unref(m->host_ipv4_key);
588 dns_resource_key_unref(m->host_ipv6_key);
eb60f9cd
LP
589
590 safe_close(m->hostname_fd);
591 sd_event_source_unref(m->hostname_event_source);
623a4c97 592 free(m->hostname);
eb60f9cd 593
091a364c 594 free(m);
74b2466e
LP
595
596 return NULL;
091a364c
TG
597}
598
74b2466e
LP
599static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
600 _cleanup_free_ char *t = NULL;
601 int r;
091a364c 602
74b2466e 603 assert(s);
091a364c 604 assert(f);
091a364c
TG
605 assert(count);
606
74b2466e 607 r = in_addr_to_string(s->family, &s->address, &t);
1716f6dc 608 if (r < 0) {
091a364c
TG
609 log_warning("Invalid DNS address. Ignoring.");
610 return;
611 }
612
613 if (*count == MAXNS)
74b2466e 614 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
091a364c 615
74b2466e 616 fprintf(f, "nameserver %s\n", t);
091a364c
TG
617 (*count) ++;
618}
619
74b2466e 620int manager_write_resolv_conf(Manager *m) {
b686acb2 621 const char *path = "/run/systemd/resolve/resolv.conf";
091a364c
TG
622 _cleanup_free_ char *temp_path = NULL;
623 _cleanup_fclose_ FILE *f = NULL;
091a364c 624 unsigned count = 0;
74b2466e
LP
625 DnsServer *s;
626 Iterator i;
627 Link *l;
628 int r;
091a364c
TG
629
630 assert(m);
631
b686acb2 632 r = fopen_temporary(path, &f, &temp_path);
091a364c
TG
633 if (r < 0)
634 return r;
635
636 fchmod(fileno(f), 0644);
637
638 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
639 "# Third party programs must not access this file directly, but\n"
640 "# only through the symlink at /etc/resolv.conf. To manage\n"
641 "# resolv.conf(5) in a different way, replace the symlink by a\n"
642 "# static file or a different symlink.\n\n", f);
643
6073b6f2
TG
644 HASHMAP_FOREACH(l, m->links, i)
645 LIST_FOREACH(servers, s, l->dns_servers)
74b2466e 646 write_resolve_conf_server(s, f, &count);
091a364c 647
74b2466e
LP
648 LIST_FOREACH(servers, s, m->dns_servers)
649 write_resolve_conf_server(s, f, &count);
091a364c 650
74b2466e
LP
651 r = fflush_and_check(f);
652 if (r < 0)
653 goto fail;
654
655 if (rename(temp_path, path) < 0) {
656 r = -errno;
657 goto fail;
658 }
091a364c 659
74b2466e 660 return 0;
091a364c 661
74b2466e
LP
662fail:
663 unlink(path);
664 unlink(temp_path);
665 return r;
666}
091a364c 667
1716f6dc 668int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 669 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
670 union {
671 struct cmsghdr header; /* For alignment */
672 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
673 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 674 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
675 } control;
676 union sockaddr_union sa;
74b2466e 677 struct msghdr mh = {};
1716f6dc 678 struct cmsghdr *cmsg;
74b2466e 679 struct iovec iov;
1716f6dc 680 int ms = 0, r;
74b2466e
LP
681 ssize_t l;
682
683 assert(m);
1716f6dc 684 assert(fd >= 0);
74b2466e
LP
685 assert(ret);
686
74b2466e
LP
687 r = ioctl(fd, FIONREAD, &ms);
688 if (r < 0)
689 return -errno;
690 if (ms < 0)
691 return -EIO;
692
1716f6dc 693 r = dns_packet_new(&p, protocol, ms);
74b2466e
LP
694 if (r < 0)
695 return r;
696
697 iov.iov_base = DNS_PACKET_DATA(p);
698 iov.iov_len = p->allocated;
699
1716f6dc
LP
700 mh.msg_name = &sa.sa;
701 mh.msg_namelen = sizeof(sa);
74b2466e
LP
702 mh.msg_iov = &iov;
703 mh.msg_iovlen = 1;
1716f6dc
LP
704 mh.msg_control = &control;
705 mh.msg_controllen = sizeof(control);
74b2466e
LP
706
707 l = recvmsg(fd, &mh, 0);
708 if (l < 0) {
ad867662 709 if (errno == EAGAIN || errno == EINTR)
74b2466e
LP
710 return 0;
711
712 return -errno;
091a364c
TG
713 }
714
74b2466e
LP
715 if (l <= 0)
716 return -EIO;
091a364c 717
1716f6dc
LP
718 assert(!(mh.msg_flags & MSG_CTRUNC));
719 assert(!(mh.msg_flags & MSG_TRUNC));
720
74b2466e 721 p->size = (size_t) l;
091a364c 722
1716f6dc 723 p->family = sa.sa.sa_family;
623a4c97
LP
724 p->ipproto = IPPROTO_UDP;
725 if (p->family == AF_INET) {
1716f6dc 726 p->sender.in = sa.in.sin_addr;
623a4c97
LP
727 p->sender_port = be16toh(sa.in.sin_port);
728 } else if (p->family == AF_INET6) {
1716f6dc 729 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
730 p->sender_port = be16toh(sa.in6.sin6_port);
731 p->ifindex = sa.in6.sin6_scope_id;
732 } else
1716f6dc 733 return -EAFNOSUPPORT;
74b2466e 734
1716f6dc 735 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
74b2466e 736
1716f6dc
LP
737 if (cmsg->cmsg_level == IPPROTO_IPV6) {
738 assert(p->family == AF_INET6);
74b2466e 739
1716f6dc 740 switch (cmsg->cmsg_type) {
74b2466e 741
1716f6dc
LP
742 case IPV6_PKTINFO: {
743 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 744
623a4c97
LP
745 if (p->ifindex <= 0)
746 p->ifindex = i->ipi6_ifindex;
747
1716f6dc
LP
748 p->destination.in6 = i->ipi6_addr;
749 break;
750 }
74b2466e 751
1716f6dc
LP
752 case IPV6_HOPLIMIT:
753 p->ttl = *(int *) CMSG_DATA(cmsg);
754 break;
74b2466e 755
1716f6dc
LP
756 }
757 } else if (cmsg->cmsg_level == IPPROTO_IP) {
758 assert(p->family == AF_INET);
74b2466e 759
1716f6dc 760 switch (cmsg->cmsg_type) {
74b2466e 761
1716f6dc
LP
762 case IP_PKTINFO: {
763 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 764
623a4c97
LP
765 if (p->ifindex <= 0)
766 p->ifindex = i->ipi_ifindex;
767
1716f6dc
LP
768 p->destination.in = i->ipi_addr;
769 break;
770 }
74b2466e 771
623a4c97 772 case IP_TTL:
1716f6dc
LP
773 p->ttl = *(int *) CMSG_DATA(cmsg);
774 break;
775 }
776 }
777 }
74b2466e 778
623a4c97
LP
779 /* The Linux kernel sets the interface index to the loopback
780 * device if the packet came from the local host since it
781 * avoids the routing table in such a case. Let's unset the
782 * interface index in such a case. */
783 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
784 p->ifindex = 0;
785
786 /* If we don't know the interface index still, we look for the
787 * first local interface with a matching address. Yuck! */
788 if (p->ifindex <= 0)
789 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
790
74b2466e
LP
791 *ret = p;
792 p = NULL;
793
794 return 1;
795}
796
1716f6dc 797static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e 798 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 799 DnsTransaction *t = NULL;
74b2466e
LP
800 Manager *m = userdata;
801 int r;
802
1716f6dc 803 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
74b2466e
LP
804 if (r <= 0)
805 return r;
806
623a4c97 807 if (dns_packet_validate_reply(p) > 0) {
ec2c5e43 808 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
809 if (!t)
810 return 0;
74b2466e 811
ec2c5e43 812 dns_transaction_process_reply(t, p);
623a4c97 813
1716f6dc 814 } else
623a4c97 815 log_debug("Invalid DNS packet.");
74b2466e 816
ad867662 817 return 0;
74b2466e
LP
818}
819
820int manager_dns_ipv4_fd(Manager *m) {
1716f6dc 821 const int one = 1;
74b2466e
LP
822 int r;
823
091a364c
TG
824 assert(m);
825
74b2466e
LP
826 if (m->dns_ipv4_fd >= 0)
827 return m->dns_ipv4_fd;
091a364c 828
74b2466e
LP
829 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
830 if (m->dns_ipv4_fd < 0)
831 return -errno;
091a364c 832
1716f6dc
LP
833 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
834 if (r < 0) {
835 r = -errno;
836 goto fail;
837 }
838
839 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
74b2466e 840 if (r < 0)
1716f6dc 841 goto fail;
74b2466e
LP
842
843 return m->dns_ipv4_fd;
1716f6dc
LP
844
845fail:
846 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
847 return r;
091a364c
TG
848}
849
74b2466e 850int manager_dns_ipv6_fd(Manager *m) {
1716f6dc 851 const int one = 1;
74b2466e
LP
852 int r;
853
854 assert(m);
091a364c 855
74b2466e
LP
856 if (m->dns_ipv6_fd >= 0)
857 return m->dns_ipv6_fd;
858
859 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
860 if (m->dns_ipv6_fd < 0)
861 return -errno;
862
1716f6dc
LP
863 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
864 if (r < 0) {
865 r = -errno;
866 goto fail;
867 }
868
869 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
091a364c 870 if (r < 0)
1716f6dc 871 goto fail;
091a364c 872
74b2466e 873 return m->dns_ipv6_fd;
1716f6dc
LP
874
875fail:
876 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
877 return r;
74b2466e
LP
878}
879
880static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
881 int r;
882
883 assert(fd >= 0);
884 assert(mh);
885
886 for (;;) {
887 if (sendmsg(fd, mh, flags) >= 0)
888 return 0;
889
890 if (errno == EINTR)
891 continue;
892
893 if (errno != EAGAIN)
894 return -errno;
895
896 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
897 if (r < 0)
898 return r;
899 if (r == 0)
900 return -ETIMEDOUT;
901 }
902}
903
623a4c97 904static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
905 union sockaddr_union sa = {
906 .in.sin_family = AF_INET,
74b2466e 907 };
1716f6dc
LP
908 union {
909 struct cmsghdr header; /* For alignment */
910 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
911 } control;
74b2466e
LP
912 struct msghdr mh = {};
913 struct iovec iov;
74b2466e
LP
914
915 assert(m);
1716f6dc
LP
916 assert(fd >= 0);
917 assert(addr);
918 assert(port > 0);
74b2466e
LP
919 assert(p);
920
74b2466e
LP
921 iov.iov_base = DNS_PACKET_DATA(p);
922 iov.iov_len = p->size;
091a364c 923
1716f6dc
LP
924 sa.in.sin_addr = *addr;
925 sa.in.sin_port = htobe16(port),
091a364c 926
74b2466e
LP
927 mh.msg_iov = &iov;
928 mh.msg_iovlen = 1;
929 mh.msg_name = &sa.sa;
930 mh.msg_namelen = sizeof(sa.in);
091a364c 931
74b2466e
LP
932 if (ifindex > 0) {
933 struct cmsghdr *cmsg;
934 struct in_pktinfo *pi;
935
936 zero(control);
937
1716f6dc 938 mh.msg_control = &control;
74b2466e
LP
939 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
940
941 cmsg = CMSG_FIRSTHDR(&mh);
942 cmsg->cmsg_len = mh.msg_controllen;
943 cmsg->cmsg_level = IPPROTO_IP;
944 cmsg->cmsg_type = IP_PKTINFO;
945
946 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
947 pi->ipi_ifindex = ifindex;
948 }
949
950 return sendmsg_loop(fd, &mh, 0);
951}
952
623a4c97 953static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
954 union sockaddr_union sa = {
955 .in6.sin6_family = AF_INET6,
74b2466e 956 };
1716f6dc
LP
957 union {
958 struct cmsghdr header; /* For alignment */
959 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
960 } control;
74b2466e
LP
961 struct msghdr mh = {};
962 struct iovec iov;
74b2466e
LP
963
964 assert(m);
1716f6dc
LP
965 assert(fd >= 0);
966 assert(addr);
967 assert(port > 0);
74b2466e
LP
968 assert(p);
969
74b2466e
LP
970 iov.iov_base = DNS_PACKET_DATA(p);
971 iov.iov_len = p->size;
972
1716f6dc
LP
973 sa.in6.sin6_addr = *addr;
974 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
975 sa.in6.sin6_scope_id = ifindex;
976
977 mh.msg_iov = &iov;
978 mh.msg_iovlen = 1;
979 mh.msg_name = &sa.sa;
980 mh.msg_namelen = sizeof(sa.in6);
981
982 if (ifindex > 0) {
983 struct cmsghdr *cmsg;
984 struct in6_pktinfo *pi;
985
986 zero(control);
987
1716f6dc 988 mh.msg_control = &control;
74b2466e
LP
989 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
990
991 cmsg = CMSG_FIRSTHDR(&mh);
992 cmsg->cmsg_len = mh.msg_controllen;
993 cmsg->cmsg_level = IPPROTO_IPV6;
994 cmsg->cmsg_type = IPV6_PKTINFO;
995
996 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
997 pi->ipi6_ifindex = ifindex;
998 }
999
1000 return sendmsg_loop(fd, &mh, 0);
1001}
1002
623a4c97 1003int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dc
LP
1004 assert(m);
1005 assert(fd >= 0);
1006 assert(addr);
1007 assert(port > 0);
1008 assert(p);
1009
a2a416f7
LP
1010 log_debug("Sending %s packet with id %u on interface %i/%s", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
1011
1716f6dc
LP
1012 if (family == AF_INET)
1013 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1014 else if (family == AF_INET6)
1015 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1016
1017 return -EAFNOSUPPORT;
1018}
1019
623a4c97 1020DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
74b2466e
LP
1021 DnsServer *s;
1022
1023 assert(m);
1024 assert(in_addr);
1025
1026 LIST_FOREACH(servers, s, m->dns_servers) {
1027
1028 if (s->family == family &&
1029 in_addr_equal(family, &s->address, in_addr))
1030 return s;
1031 }
1032
1033 return NULL;
1034}
1035
1036DnsServer *manager_get_dns_server(Manager *m) {
1037 assert(m);
1038
1039 if (!m->current_dns_server)
1040 m->current_dns_server = m->dns_servers;
1041
1042 return m->current_dns_server;
1043}
1044
1045void manager_next_dns_server(Manager *m) {
1046 assert(m);
1047
1048 if (!m->current_dns_server) {
1049 m->current_dns_server = m->dns_servers;
1050 return;
1051 }
1052
1053 if (!m->current_dns_server)
1054 return;
1055
1056 if (m->current_dns_server->servers_next) {
1057 m->current_dns_server = m->current_dns_server->servers_next;
1058 return;
1059 }
1060
1061 m->current_dns_server = m->dns_servers;
091a364c 1062}
e1c95994
LP
1063
1064uint32_t manager_find_mtu(Manager *m) {
1065 uint32_t mtu = 0;
1066 Link *l;
1067 Iterator i;
1068
1069 /* If we don't know on which link a DNS packet would be
1070 * delivered, let's find the largest MTU that works on all
1071 * interfaces we know of */
1072
1073 HASHMAP_FOREACH(l, m->links, i) {
1074 if (l->mtu <= 0)
1075 continue;
1076
1077 if (mtu <= 0 || l->mtu < mtu)
1078 mtu = l->mtu;
1079 }
1080
1081 return mtu;
1082}
1716f6dc
LP
1083
1084static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1085 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 1086 DnsTransaction *t = NULL;
1716f6dc
LP
1087 Manager *m = userdata;
1088 int r;
1089
1090 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1091 if (r <= 0)
1092 return r;
1093
623a4c97 1094 if (dns_packet_validate_reply(p) > 0) {
a2a416f7
LP
1095 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1096
ec2c5e43 1097 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
1098 if (!t)
1099 return 0;
1100
ec2c5e43 1101 dns_transaction_process_reply(t, p);
623a4c97
LP
1102
1103 } else if (dns_packet_validate_query(p) > 0) {
1104 Link *l;
1105
1106 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1107 if (l) {
1108 DnsScope *scope = NULL;
1109
1110 if (p->family == AF_INET)
1111 scope = l->llmnr_ipv4_scope;
1112 else if (p->family == AF_INET6)
1113 scope = l->llmnr_ipv6_scope;
1114
1115 if (scope)
1116 dns_scope_process_query(scope, NULL, p);
1117 }
1118 } else
1119 log_debug("Invalid LLMNR packet.");
1716f6dc
LP
1120
1121 return 0;
1122}
1123
1124int manager_llmnr_ipv4_udp_fd(Manager *m) {
1125 union sockaddr_union sa = {
1126 .in.sin_family = AF_INET,
1127 .in.sin_port = htobe16(5355),
1128 };
bf3f1271 1129 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1716f6dc
LP
1130 int r;
1131
1132 assert(m);
1133
1134 if (m->llmnr_ipv4_udp_fd >= 0)
1135 return m->llmnr_ipv4_udp_fd;
1136
1137 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1138 if (m->llmnr_ipv4_udp_fd < 0)
1139 return -errno;
1140
bf3f1271
LP
1141 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1142 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1143 if (r < 0) {
1144 r = -errno;
1145 goto fail;
1146 }
1147
bf3f1271 1148 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1149 if (r < 0) {
1150 r = -errno;
1151 goto fail;
1152 }
1153
1154 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1155 if (r < 0) {
1156 r = -errno;
1157 goto fail;
1158 }
1159
1160 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1161 if (r < 0) {
1162 r = -errno;
1163 goto fail;
1164 }
1165
1166 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1167 if (r < 0) {
1168 r = -errno;
1169 goto fail;
1170 }
1171
1172 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1173 if (r < 0) {
1174 r = -errno;
1175 goto fail;
1176 }
1177
1178 /* Disable Don't-Fragment bit in the IP header */
1179 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1180 if (r < 0) {
1181 r = -errno;
1182 goto fail;
1183 }
1184
1185 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1186 if (r < 0) {
1187 r = -errno;
1188 goto fail;
1189 }
1190
1191 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1192 if (r < 0)
1193 goto fail;
1194
1195 return m->llmnr_ipv4_udp_fd;
1196
1197fail:
1198 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1199 return r;
1200}
1201
1202int manager_llmnr_ipv6_udp_fd(Manager *m) {
1203 union sockaddr_union sa = {
1204 .in6.sin6_family = AF_INET6,
1205 .in6.sin6_port = htobe16(5355),
1206 };
bf3f1271 1207 static const int one = 1, ttl = 255;
1716f6dc
LP
1208 int r;
1209
1210 assert(m);
1211
1212 if (m->llmnr_ipv6_udp_fd >= 0)
1213 return m->llmnr_ipv6_udp_fd;
1214
1215 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1216 if (m->llmnr_ipv6_udp_fd < 0)
1217 return -errno;
1218
bf3f1271 1219 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1220 if (r < 0) {
1221 r = -errno;
1222 goto fail;
1223 }
1224
bf3f1271
LP
1225 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1226 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1227 if (r < 0) {
1228 r = -errno;
1229 goto fail;
1230 }
1231
1232 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1233 if (r < 0) {
1234 r = -errno;
1235 goto fail;
1236 }
1237
1238 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1239 if (r < 0) {
1240 r = -errno;
1241 goto fail;
1242 }
1243
1244 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1245 if (r < 0) {
1246 r = -errno;
1247 goto fail;
1248 }
1249
1250 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1251 if (r < 0) {
1252 r = -errno;
1253 goto fail;
1254 }
1255
1256 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1257 if (r < 0) {
1258 r = -errno;
1259 goto fail;
1260 }
1261
1262 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1263 if (r < 0) {
1264 r = -errno;
1265 goto fail;
1266 }
1267
1268 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1269 if (r < 0) {
1270 r = -errno;
1271 goto fail;
1272 }
1273
1274 return m->llmnr_ipv6_udp_fd;
1275
1276fail:
1277 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1278 return r;
1279}
623a4c97
LP
1280
1281static int on_llmnr_stream_packet(DnsStream *s) {
1282 assert(s);
1283
1284 if (dns_packet_validate_query(s->read_packet) > 0) {
1285 Link *l;
1286
1287 l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex));
1288 if (l) {
1289 DnsScope *scope = NULL;
1290
1291 if (s->read_packet->family == AF_INET)
1292 scope = l->llmnr_ipv4_scope;
1293 else if (s->read_packet->family == AF_INET6)
1294 scope = l->llmnr_ipv6_scope;
1295
1296 if (scope) {
1297 dns_scope_process_query(scope, s, s->read_packet);
1298
1299 /* If no reply packet was set, we free the stream */
1300 if (s->write_packet)
1301 return 0;
1302 }
1303 }
1304 }
1305
1306 dns_stream_free(s);
1307 return 0;
1308}
1309
1310static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1311 DnsStream *stream;
1312 Manager *m = userdata;
1313 int cfd, r;
1314
1315 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1316 if (cfd < 0) {
1317 if (errno == EAGAIN || errno == EINTR)
1318 return 0;
1319
1320 return -errno;
1321 }
1322
1323 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1324 if (r < 0) {
1325 safe_close(cfd);
1326 return r;
1327 }
1328
1329 stream->on_packet = on_llmnr_stream_packet;
1330 return 0;
1331}
1332
1333int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1334 union sockaddr_union sa = {
1335 .in.sin_family = AF_INET,
1336 .in.sin_port = htobe16(5355),
1337 };
1338 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1339 int r;
1340
1341 assert(m);
1342
1343 if (m->llmnr_ipv4_tcp_fd >= 0)
1344 return m->llmnr_ipv4_tcp_fd;
1345
1346 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1347 if (m->llmnr_ipv4_tcp_fd < 0)
1348 return -errno;
1349
bf3f1271 1350 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1351 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1352 if (r < 0) {
1353 r = -errno;
1354 goto fail;
1355 }
1356
1357 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1358 if (r < 0) {
1359 r = -errno;
1360 goto fail;
1361 }
1362
1363 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1364 if (r < 0) {
1365 r = -errno;
1366 goto fail;
1367 }
1368
1369 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1370 if (r < 0) {
1371 r = -errno;
1372 goto fail;
1373 }
1374
1375 /* Disable Don't-Fragment bit in the IP header */
1376 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1377 if (r < 0) {
1378 r = -errno;
1379 goto fail;
1380 }
1381
1382 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1383 if (r < 0) {
1384 r = -errno;
1385 goto fail;
1386 }
1387
1388 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1389 if (r < 0) {
1390 r = -errno;
1391 goto fail;
1392 }
1393
1394 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1395 if (r < 0)
1396 goto fail;
1397
1398 return m->llmnr_ipv4_tcp_fd;
1399
1400fail:
1401 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1402 return r;
1403}
1404
1405int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1406 union sockaddr_union sa = {
1407 .in6.sin6_family = AF_INET6,
1408 .in6.sin6_port = htobe16(5355),
1409 };
1410 static const int one = 1;
1411 int r;
1412
1413 assert(m);
1414
1415 if (m->llmnr_ipv6_tcp_fd >= 0)
1416 return m->llmnr_ipv6_tcp_fd;
1417
1418 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1419 if (m->llmnr_ipv6_tcp_fd < 0)
1420 return -errno;
1421
bf3f1271 1422 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1423 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1424 if (r < 0) {
1425 r = -errno;
1426 goto fail;
1427 }
1428
1429 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1430 if (r < 0) {
1431 r = -errno;
1432 goto fail;
1433 }
1434
1435 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1436 if (r < 0) {
1437 r = -errno;
1438 goto fail;
1439 }
1440
1441 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1442 if (r < 0) {
1443 r = -errno;
1444 goto fail;
1445 }
1446
1447 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1448 if (r < 0) {
1449 r = -errno;
1450 goto fail;
1451 }
1452
1453 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1454 if (r < 0) {
1455 r = -errno;
1456 goto fail;
1457 }
1458
1459 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1460 if (r < 0) {
1461 r = -errno;
1462 goto fail;
1463 }
1464
1465 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1466 if (r < 0) {
1467 r = -errno;
1468 goto fail;
1469 }
1470
1471 return m->llmnr_ipv6_tcp_fd;
1472
1473fail:
1474 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1475 return r;
1476}
1477
1478int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1479 Link *l;
1480 assert(m);
1481
1482 if (ifindex <= 0)
1483 return -EINVAL;
1484
1485 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1486 if (l->flags & IFF_LOOPBACK)
1487 return 1;
1488
1489 return 0;
1490}
1491
1492int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1493 LinkAddress *a;
1494
1495 assert(m);
1496
1497 a = manager_find_address(m, family, in_addr);
1498 if (a)
1499 return a->link->ifindex;
1500
1501 return 0;
1502}
1503
eb60f9cd
LP
1504void manager_refresh_rrs(Manager *m) {
1505 Iterator i;
1506 Link *l;
1507
1508 assert(m);
1509
1510 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1511 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1512
1513 HASHMAP_FOREACH(l, m->links, i) {
1514 link_add_rrs(l, true);
1515 link_add_rrs(l, false);
1516 }
1517}
1518
ec2c5e43
LP
1519int manager_next_hostname(Manager *m) {
1520 const char *p;
ec2c5e43
LP
1521 uint64_t u;
1522 char *h;
623a4c97
LP
1523
1524 assert(m);
1525
ec2c5e43
LP
1526 p = strchr(m->hostname, 0);
1527 assert(p);
1528
1529 while (p > m->hostname) {
1530 if (!strchr("0123456789", p[-1]))
1531 break;
1532
1533 p--;
1534 }
1535
1536 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1537 u = 1;
1538
1539 u++;
1540
1541 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1542 return -ENOMEM;
1543
eb60f9cd 1544 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
ec2c5e43
LP
1545
1546 free(m->hostname);
1547 m->hostname = h;
1548
eb60f9cd 1549 manager_refresh_rrs(m);
623a4c97
LP
1550
1551 return 0;
1552}
ec2c5e43
LP
1553
1554LinkAddress* manager_find_address(Manager *m, int family, const union in_addr_union *in_addr) {
1555 Iterator i;
1556 Link *l;
1557
1558 assert(m);
1559
1560 HASHMAP_FOREACH(l, m->links, i) {
1561 LinkAddress *a;
1562
1563 a = link_find_address(l, family, in_addr);
1564 if (a)
1565 return a;
1566 }
1567
1568 return NULL;
1569}
1570
1571int manager_our_packet(Manager *m, DnsPacket *p) {
1572 assert(m);
1573 assert(p);
1574
1575 return !!manager_find_address(m, p->family, &p->sender);
1576}