Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <fcntl.h>
4 : : #include <netinet/in.h>
5 : : #include <poll.h>
6 : : #include <sys/ioctl.h>
7 : : #include <sys/stat.h>
8 : : #include <sys/types.h>
9 : : #include <unistd.h>
10 : :
11 : : #if HAVE_LIBIDN2
12 : : #include <idn2.h>
13 : : #endif
14 : :
15 : : #include "af-list.h"
16 : : #include "alloc-util.h"
17 : : #include "bus-util.h"
18 : : #include "dirent-util.h"
19 : : #include "dns-domain.h"
20 : : #include "fd-util.h"
21 : : #include "fileio.h"
22 : : #include "hostname-util.h"
23 : : #include "io-util.h"
24 : : #include "missing_network.h"
25 : : #include "netlink-util.h"
26 : : #include "network-internal.h"
27 : : #include "ordered-set.h"
28 : : #include "parse-util.h"
29 : : #include "random-util.h"
30 : : #include "resolved-bus.h"
31 : : #include "resolved-conf.h"
32 : : #include "resolved-dns-stub.h"
33 : : #include "resolved-dnssd.h"
34 : : #include "resolved-etc-hosts.h"
35 : : #include "resolved-llmnr.h"
36 : : #include "resolved-manager.h"
37 : : #include "resolved-mdns.h"
38 : : #include "resolved-resolv-conf.h"
39 : : #include "socket-util.h"
40 : : #include "string-table.h"
41 : : #include "string-util.h"
42 : : #include "utf8.h"
43 : :
44 : : #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
45 : :
46 : 0 : static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
47 : 0 : Manager *m = userdata;
48 : : uint16_t type;
49 : : Link *l;
50 : : int ifindex, r;
51 : :
52 [ # # ]: 0 : assert(rtnl);
53 [ # # ]: 0 : assert(m);
54 [ # # ]: 0 : assert(mm);
55 : :
56 : 0 : r = sd_netlink_message_get_type(mm, &type);
57 [ # # ]: 0 : if (r < 0)
58 : 0 : goto fail;
59 : :
60 : 0 : r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
61 [ # # ]: 0 : if (r < 0)
62 : 0 : goto fail;
63 : :
64 : 0 : l = hashmap_get(m->links, INT_TO_PTR(ifindex));
65 : :
66 [ # # # ]: 0 : switch (type) {
67 : :
68 : 0 : case RTM_NEWLINK:{
69 : 0 : bool is_new = !l;
70 : :
71 [ # # ]: 0 : if (!l) {
72 : 0 : r = link_new(m, &l, ifindex);
73 [ # # ]: 0 : if (r < 0)
74 : 0 : goto fail;
75 : : }
76 : :
77 : 0 : r = link_process_rtnl(l, mm);
78 [ # # ]: 0 : if (r < 0)
79 : 0 : goto fail;
80 : :
81 : 0 : r = link_update(l);
82 [ # # ]: 0 : if (r < 0)
83 : 0 : goto fail;
84 : :
85 [ # # ]: 0 : if (is_new)
86 [ # # ]: 0 : log_debug("Found new link %i/%s", ifindex, l->ifname);
87 : :
88 : 0 : break;
89 : : }
90 : :
91 : 0 : case RTM_DELLINK:
92 [ # # ]: 0 : if (l) {
93 [ # # ]: 0 : log_debug("Removing link %i/%s", l->ifindex, l->ifname);
94 : 0 : link_remove_user(l);
95 : 0 : link_free(l);
96 : : }
97 : :
98 : 0 : break;
99 : : }
100 : :
101 : 0 : return 0;
102 : :
103 : 0 : fail:
104 [ # # ]: 0 : log_warning_errno(r, "Failed to process RTNL link message: %m");
105 : 0 : return 0;
106 : : }
107 : :
108 : 0 : static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
109 : 0 : Manager *m = userdata;
110 : : union in_addr_union address;
111 : : uint16_t type;
112 : : int r, ifindex, family;
113 : : LinkAddress *a;
114 : : Link *l;
115 : :
116 [ # # ]: 0 : assert(rtnl);
117 [ # # ]: 0 : assert(mm);
118 [ # # ]: 0 : assert(m);
119 : :
120 : 0 : r = sd_netlink_message_get_type(mm, &type);
121 [ # # ]: 0 : if (r < 0)
122 : 0 : goto fail;
123 : :
124 : 0 : r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
125 [ # # ]: 0 : if (r < 0)
126 : 0 : goto fail;
127 : :
128 : 0 : l = hashmap_get(m->links, INT_TO_PTR(ifindex));
129 [ # # ]: 0 : if (!l)
130 : 0 : return 0;
131 : :
132 : 0 : r = sd_rtnl_message_addr_get_family(mm, &family);
133 [ # # ]: 0 : if (r < 0)
134 : 0 : goto fail;
135 : :
136 [ # # # ]: 0 : switch (family) {
137 : :
138 : 0 : case AF_INET:
139 : 0 : r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
140 [ # # ]: 0 : if (r < 0) {
141 : 0 : r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
142 [ # # ]: 0 : if (r < 0)
143 : 0 : goto fail;
144 : : }
145 : :
146 : 0 : break;
147 : :
148 : 0 : case AF_INET6:
149 : 0 : r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
150 [ # # ]: 0 : if (r < 0) {
151 : 0 : r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
152 [ # # ]: 0 : if (r < 0)
153 : 0 : goto fail;
154 : : }
155 : :
156 : 0 : break;
157 : :
158 : 0 : default:
159 : 0 : return 0;
160 : : }
161 : :
162 : 0 : a = link_find_address(l, family, &address);
163 : :
164 [ # # # ]: 0 : switch (type) {
165 : :
166 : 0 : case RTM_NEWADDR:
167 : :
168 [ # # ]: 0 : if (!a) {
169 : 0 : r = link_address_new(l, &a, family, &address);
170 [ # # ]: 0 : if (r < 0)
171 : 0 : return r;
172 : : }
173 : :
174 : 0 : r = link_address_update_rtnl(a, mm);
175 [ # # ]: 0 : if (r < 0)
176 : 0 : return r;
177 : :
178 : 0 : break;
179 : :
180 : 0 : case RTM_DELADDR:
181 : 0 : link_address_free(a);
182 : 0 : break;
183 : : }
184 : :
185 : 0 : return 0;
186 : :
187 : 0 : fail:
188 [ # # ]: 0 : log_warning_errno(r, "Failed to process RTNL address message: %m");
189 : 0 : return 0;
190 : : }
191 : :
192 : 0 : static int manager_rtnl_listen(Manager *m) {
193 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
194 : : sd_netlink_message *i;
195 : : int r;
196 : :
197 [ # # ]: 0 : assert(m);
198 : :
199 : : /* First, subscribe to interfaces coming and going */
200 : 0 : r = sd_netlink_open(&m->rtnl);
201 [ # # ]: 0 : if (r < 0)
202 : 0 : return r;
203 : :
204 : 0 : r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
205 [ # # ]: 0 : if (r < 0)
206 : 0 : return r;
207 : :
208 : 0 : r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, manager_process_link, NULL, m, "resolve-NEWLINK");
209 [ # # ]: 0 : if (r < 0)
210 : 0 : return r;
211 : :
212 : 0 : r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, manager_process_link, NULL, m, "resolve-DELLINK");
213 [ # # ]: 0 : if (r < 0)
214 : 0 : return r;
215 : :
216 : 0 : r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, manager_process_address, NULL, m, "resolve-NEWADDR");
217 [ # # ]: 0 : if (r < 0)
218 : 0 : return r;
219 : :
220 : 0 : r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, manager_process_address, NULL, m, "resolve-DELADDR");
221 [ # # ]: 0 : if (r < 0)
222 : 0 : return r;
223 : :
224 : : /* Then, enumerate all links */
225 : 0 : r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
226 [ # # ]: 0 : if (r < 0)
227 : 0 : return r;
228 : :
229 : 0 : r = sd_netlink_message_request_dump(req, true);
230 [ # # ]: 0 : if (r < 0)
231 : 0 : return r;
232 : :
233 : 0 : r = sd_netlink_call(m->rtnl, req, 0, &reply);
234 [ # # ]: 0 : if (r < 0)
235 : 0 : return r;
236 : :
237 [ # # ]: 0 : for (i = reply; i; i = sd_netlink_message_next(i)) {
238 : 0 : r = manager_process_link(m->rtnl, i, m);
239 [ # # ]: 0 : if (r < 0)
240 : 0 : return r;
241 : : }
242 : :
243 : 0 : req = sd_netlink_message_unref(req);
244 : 0 : reply = sd_netlink_message_unref(reply);
245 : :
246 : : /* Finally, enumerate all addresses, too */
247 : 0 : r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
248 [ # # ]: 0 : if (r < 0)
249 : 0 : return r;
250 : :
251 : 0 : r = sd_netlink_message_request_dump(req, true);
252 [ # # ]: 0 : if (r < 0)
253 : 0 : return r;
254 : :
255 : 0 : r = sd_netlink_call(m->rtnl, req, 0, &reply);
256 [ # # ]: 0 : if (r < 0)
257 : 0 : return r;
258 : :
259 [ # # ]: 0 : for (i = reply; i; i = sd_netlink_message_next(i)) {
260 : 0 : r = manager_process_address(m->rtnl, i, m);
261 [ # # ]: 0 : if (r < 0)
262 : 0 : return r;
263 : : }
264 : :
265 : 0 : return r;
266 : : }
267 : :
268 : 0 : static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
269 : 0 : Manager *m = userdata;
270 : : Iterator i;
271 : : Link *l;
272 : : int r;
273 : :
274 [ # # ]: 0 : assert(m);
275 : :
276 : 0 : sd_network_monitor_flush(m->network_monitor);
277 : :
278 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
279 : 0 : r = link_update(l);
280 [ # # ]: 0 : if (r < 0)
281 [ # # ]: 0 : log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
282 : : }
283 : :
284 : 0 : (void) manager_write_resolv_conf(m);
285 : :
286 : 0 : return 0;
287 : : }
288 : :
289 : 0 : static int manager_network_monitor_listen(Manager *m) {
290 : : int r, fd, events;
291 : :
292 [ # # ]: 0 : assert(m);
293 : :
294 : 0 : r = sd_network_monitor_new(&m->network_monitor, NULL);
295 [ # # ]: 0 : if (r < 0)
296 : 0 : return r;
297 : :
298 : 0 : fd = sd_network_monitor_get_fd(m->network_monitor);
299 [ # # ]: 0 : if (fd < 0)
300 : 0 : return fd;
301 : :
302 : 0 : events = sd_network_monitor_get_events(m->network_monitor);
303 [ # # ]: 0 : if (events < 0)
304 : 0 : return events;
305 : :
306 : 0 : r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
307 [ # # ]: 0 : if (r < 0)
308 : 0 : return r;
309 : :
310 : 0 : r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
311 [ # # ]: 0 : if (r < 0)
312 : 0 : return r;
313 : :
314 : 0 : (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
315 : :
316 : 0 : return 0;
317 : : }
318 : :
319 : 0 : static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
320 : 0 : _cleanup_free_ char *h = NULL, *n = NULL;
321 : : #if HAVE_LIBIDN2
322 : 0 : _cleanup_free_ char *utf8 = NULL;
323 : : #elif HAVE_LIBIDN
324 : : int k;
325 : : #endif
326 : : char label[DNS_LABEL_MAX];
327 : : const char *p, *decoded;
328 : : int r;
329 : :
330 [ # # ]: 0 : assert(full_hostname);
331 [ # # ]: 0 : assert(llmnr_hostname);
332 [ # # ]: 0 : assert(mdns_hostname);
333 : :
334 : : /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */
335 : :
336 : 0 : r = gethostname_strict(&h);
337 [ # # ]: 0 : if (r < 0)
338 [ # # ]: 0 : return log_debug_errno(r, "Can't determine system hostname: %m");
339 : :
340 : 0 : p = h;
341 : 0 : r = dns_label_unescape(&p, label, sizeof label, 0);
342 [ # # ]: 0 : if (r < 0)
343 [ # # ]: 0 : return log_error_errno(r, "Failed to unescape host name: %m");
344 [ # # ]: 0 : if (r == 0)
345 [ # # ]: 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
346 : : "Couldn't find a single label in hostname.");
347 : :
348 : : #if HAVE_LIBIDN2
349 : 0 : r = idn2_to_unicode_8z8z(label, &utf8, 0);
350 [ # # ]: 0 : if (r != IDN2_OK)
351 [ # # ]: 0 : return log_error("Failed to undo IDNA: %s", idn2_strerror(r));
352 [ # # ]: 0 : assert(utf8_is_valid(utf8));
353 : :
354 : 0 : r = strlen(utf8);
355 : 0 : decoded = utf8;
356 : : #elif HAVE_LIBIDN
357 : : k = dns_label_undo_idna(label, r, label, sizeof label);
358 : : if (k < 0)
359 : : return log_error_errno(k, "Failed to undo IDNA: %m");
360 : : if (k > 0)
361 : : r = k;
362 : :
363 : : if (!utf8_is_valid(label))
364 : : return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
365 : : "System hostname is not UTF-8 clean.");
366 : : decoded = label;
367 : : #else
368 : : decoded = label; /* no decoding */
369 : : #endif
370 : :
371 : 0 : r = dns_label_escape_new(decoded, r, &n);
372 [ # # ]: 0 : if (r < 0)
373 [ # # ]: 0 : return log_error_errno(r, "Failed to escape host name: %m");
374 : :
375 [ # # ]: 0 : if (is_localhost(n))
376 [ # # ]: 0 : return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
377 : : "System hostname is 'localhost', ignoring.");
378 : :
379 : 0 : r = dns_name_concat(n, "local", 0, mdns_hostname);
380 [ # # ]: 0 : if (r < 0)
381 [ # # ]: 0 : return log_error_errno(r, "Failed to determine mDNS hostname: %m");
382 : :
383 : 0 : *llmnr_hostname = TAKE_PTR(n);
384 : 0 : *full_hostname = TAKE_PTR(h);
385 : :
386 : 0 : return 0;
387 : : }
388 : :
389 : 0 : static const char *fallback_hostname(void) {
390 : :
391 : : /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
392 : : * "localhost" even if that's the compiled in hostname. In this case, let's revert to "linux" instead. */
393 : :
394 [ # # ]: 0 : if (is_localhost(FALLBACK_HOSTNAME))
395 : 0 : return "linux";
396 : :
397 : 0 : return FALLBACK_HOSTNAME;
398 : : }
399 : :
400 : 0 : static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
401 : 0 : _cleanup_free_ char *n = NULL, *m = NULL;
402 : : char label[DNS_LABEL_MAX], *h;
403 : : const char *p;
404 : : int r;
405 : :
406 [ # # ]: 0 : assert(full_hostname);
407 [ # # ]: 0 : assert(llmnr_hostname);
408 [ # # ]: 0 : assert(mdns_hostname);
409 : :
410 : 0 : p = fallback_hostname();
411 : 0 : r = dns_label_unescape(&p, label, sizeof label, 0);
412 [ # # ]: 0 : if (r < 0)
413 [ # # ]: 0 : return log_error_errno(r, "Failed to unescape fallback host name: %m");
414 : :
415 [ # # ]: 0 : assert(r > 0); /* The fallback hostname must have at least one label */
416 : :
417 : 0 : r = dns_label_escape_new(label, r, &n);
418 [ # # ]: 0 : if (r < 0)
419 [ # # ]: 0 : return log_error_errno(r, "Failed to escape fallback hostname: %m");
420 : :
421 : 0 : r = dns_name_concat(n, "local", 0, &m);
422 [ # # ]: 0 : if (r < 0)
423 [ # # ]: 0 : return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
424 : :
425 : 0 : h = strdup(fallback_hostname());
426 [ # # ]: 0 : if (!h)
427 : 0 : return log_oom();
428 : :
429 : 0 : *llmnr_hostname = TAKE_PTR(n);
430 : 0 : *mdns_hostname = TAKE_PTR(m);
431 : :
432 : 0 : *full_hostname = h;
433 : :
434 : 0 : return 0;
435 : : }
436 : :
437 : 0 : static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
438 : 0 : _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
439 : 0 : Manager *m = userdata;
440 : : int r;
441 : :
442 [ # # ]: 0 : assert(m);
443 : :
444 : 0 : r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
445 [ # # ]: 0 : if (r < 0)
446 : 0 : return 0; /* ignore invalid hostnames */
447 : :
448 [ # # ]: 0 : if (streq(full_hostname, m->full_hostname) &&
449 [ # # ]: 0 : streq(llmnr_hostname, m->llmnr_hostname) &&
450 [ # # ]: 0 : streq(mdns_hostname, m->mdns_hostname))
451 : 0 : return 0;
452 : :
453 [ # # ]: 0 : log_info("System hostname changed to '%s'.", full_hostname);
454 : :
455 : 0 : free_and_replace(m->full_hostname, full_hostname);
456 : 0 : free_and_replace(m->llmnr_hostname, llmnr_hostname);
457 : 0 : free_and_replace(m->mdns_hostname, mdns_hostname);
458 : :
459 : 0 : manager_refresh_rrs(m);
460 : :
461 : 0 : return 0;
462 : : }
463 : :
464 : 0 : static int manager_watch_hostname(Manager *m) {
465 : : int r;
466 : :
467 [ # # ]: 0 : assert(m);
468 : :
469 : 0 : m->hostname_fd = open("/proc/sys/kernel/hostname",
470 : : O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
471 [ # # ]: 0 : if (m->hostname_fd < 0) {
472 [ # # ]: 0 : log_warning_errno(errno, "Failed to watch hostname: %m");
473 : 0 : return 0;
474 : : }
475 : :
476 : 0 : r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
477 [ # # ]: 0 : if (r < 0) {
478 [ # # ]: 0 : if (r == -EPERM)
479 : : /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
480 : 0 : m->hostname_fd = safe_close(m->hostname_fd);
481 : : else
482 [ # # ]: 0 : return log_error_errno(r, "Failed to add hostname event source: %m");
483 : : }
484 : :
485 : 0 : (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
486 : :
487 : 0 : r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
488 [ # # ]: 0 : if (r < 0) {
489 [ # # ]: 0 : log_info("Defaulting to hostname '%s'.", fallback_hostname());
490 : :
491 : 0 : r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
492 [ # # ]: 0 : if (r < 0)
493 : 0 : return r;
494 : : } else
495 [ # # ]: 0 : log_info("Using system hostname '%s'.", m->full_hostname);
496 : :
497 : 0 : return 0;
498 : : }
499 : :
500 : 0 : static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
501 : 0 : _cleanup_free_ char *buffer = NULL;
502 : 0 : _cleanup_fclose_ FILE *f = NULL;
503 : 0 : Manager *m = userdata;
504 : : DnsServer *server;
505 : 0 : size_t size = 0;
506 : : DnsScope *scope;
507 : : Iterator i;
508 : : Link *l;
509 : :
510 [ # # ]: 0 : assert(s);
511 [ # # ]: 0 : assert(si);
512 [ # # ]: 0 : assert(m);
513 : :
514 : 0 : f = open_memstream_unlocked(&buffer, &size);
515 [ # # ]: 0 : if (!f)
516 : 0 : return log_oom();
517 : :
518 [ # # ]: 0 : LIST_FOREACH(scopes, scope, m->dns_scopes)
519 : 0 : dns_scope_dump(scope, f);
520 : :
521 [ # # ]: 0 : LIST_FOREACH(servers, server, m->dns_servers)
522 : 0 : dns_server_dump(server, f);
523 [ # # ]: 0 : LIST_FOREACH(servers, server, m->fallback_dns_servers)
524 : 0 : dns_server_dump(server, f);
525 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i)
526 [ # # ]: 0 : LIST_FOREACH(servers, server, l->dns_servers)
527 : 0 : dns_server_dump(server, f);
528 : :
529 [ # # ]: 0 : if (fflush_and_check(f) < 0)
530 : 0 : return log_oom();
531 : :
532 : 0 : log_dump(LOG_INFO, buffer);
533 : 0 : return 0;
534 : : }
535 : :
536 : 0 : static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
537 : 0 : Manager *m = userdata;
538 : :
539 [ # # ]: 0 : assert(s);
540 [ # # ]: 0 : assert(si);
541 [ # # ]: 0 : assert(m);
542 : :
543 : 0 : manager_flush_caches(m);
544 : :
545 : 0 : return 0;
546 : : }
547 : :
548 : 0 : static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
549 : 0 : Manager *m = userdata;
550 : :
551 [ # # ]: 0 : assert(s);
552 [ # # ]: 0 : assert(si);
553 [ # # ]: 0 : assert(m);
554 : :
555 : 0 : manager_reset_server_features(m);
556 : 0 : return 0;
557 : : }
558 : :
559 : 0 : int manager_new(Manager **ret) {
560 : 0 : _cleanup_(manager_freep) Manager *m = NULL;
561 : : int r;
562 : :
563 [ # # ]: 0 : assert(ret);
564 : :
565 : 0 : m = new(Manager, 1);
566 [ # # ]: 0 : if (!m)
567 : 0 : return -ENOMEM;
568 : :
569 : 0 : *m = (Manager) {
570 : : .llmnr_ipv4_udp_fd = -1,
571 : : .llmnr_ipv6_udp_fd = -1,
572 : : .llmnr_ipv4_tcp_fd = -1,
573 : : .llmnr_ipv6_tcp_fd = -1,
574 : : .mdns_ipv4_fd = -1,
575 : : .mdns_ipv6_fd = -1,
576 : : .dns_stub_udp_fd = -1,
577 : : .dns_stub_tcp_fd = -1,
578 : : .hostname_fd = -1,
579 : :
580 : : .llmnr_support = RESOLVE_SUPPORT_YES,
581 : : .mdns_support = RESOLVE_SUPPORT_YES,
582 : : .dnssec_mode = DEFAULT_DNSSEC_MODE,
583 : : .dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
584 : : .enable_cache = DNS_CACHE_MODE_YES,
585 : : .dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
586 : : .read_resolv_conf = true,
587 : : .need_builtin_fallbacks = true,
588 : : .etc_hosts_last = USEC_INFINITY,
589 : : .etc_hosts_mtime = USEC_INFINITY,
590 : : .read_etc_hosts = true,
591 : : };
592 : :
593 : 0 : r = dns_trust_anchor_load(&m->trust_anchor);
594 [ # # ]: 0 : if (r < 0)
595 : 0 : return r;
596 : :
597 : 0 : r = manager_parse_config_file(m);
598 [ # # ]: 0 : if (r < 0)
599 [ # # ]: 0 : log_warning_errno(r, "Failed to parse configuration file: %m");
600 : :
601 : : #if ENABLE_DNS_OVER_TLS
602 : 0 : r = dnstls_manager_init(m);
603 [ # # ]: 0 : if (r < 0)
604 : 0 : return r;
605 : : #endif
606 : :
607 : 0 : r = sd_event_default(&m->event);
608 [ # # ]: 0 : if (r < 0)
609 : 0 : return r;
610 : :
611 : 0 : (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
612 : 0 : (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
613 : :
614 : 0 : (void) sd_event_set_watchdog(m->event, true);
615 : :
616 : 0 : r = manager_watch_hostname(m);
617 [ # # ]: 0 : if (r < 0)
618 : 0 : return r;
619 : :
620 : 0 : r = dnssd_load(m);
621 [ # # ]: 0 : if (r < 0)
622 [ # # ]: 0 : log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
623 : :
624 : 0 : r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
625 [ # # ]: 0 : if (r < 0)
626 : 0 : return r;
627 : :
628 : 0 : r = manager_network_monitor_listen(m);
629 [ # # ]: 0 : if (r < 0)
630 : 0 : return r;
631 : :
632 : 0 : r = manager_rtnl_listen(m);
633 [ # # ]: 0 : if (r < 0)
634 : 0 : return r;
635 : :
636 : 0 : r = manager_connect_bus(m);
637 [ # # ]: 0 : if (r < 0)
638 : 0 : return r;
639 : :
640 : 0 : (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
641 : 0 : (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
642 : 0 : (void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);
643 : :
644 : 0 : manager_cleanup_saved_user(m);
645 : :
646 : 0 : *ret = TAKE_PTR(m);
647 : :
648 : 0 : return 0;
649 : : }
650 : :
651 : 0 : int manager_start(Manager *m) {
652 : : int r;
653 : :
654 [ # # ]: 0 : assert(m);
655 : :
656 : 0 : r = manager_dns_stub_start(m);
657 [ # # ]: 0 : if (r < 0)
658 : 0 : return r;
659 : :
660 : 0 : return 0;
661 : : }
662 : :
663 : 0 : Manager *manager_free(Manager *m) {
664 : : Link *l;
665 : : DnssdService *s;
666 : :
667 [ # # ]: 0 : if (!m)
668 : 0 : return NULL;
669 : :
670 : 0 : dns_server_unlink_all(m->dns_servers);
671 : 0 : dns_server_unlink_all(m->fallback_dns_servers);
672 : 0 : dns_search_domain_unlink_all(m->search_domains);
673 : :
674 [ # # ]: 0 : while ((l = hashmap_first(m->links)))
675 : 0 : link_free(l);
676 : :
677 [ # # ]: 0 : while (m->dns_queries)
678 : 0 : dns_query_free(m->dns_queries);
679 : :
680 : 0 : dns_scope_free(m->unicast_scope);
681 : :
682 : : /* At this point only orphaned streams should remain. All others should have been freed already by their
683 : : * owners */
684 [ # # ]: 0 : while (m->dns_streams)
685 : 0 : dns_stream_unref(m->dns_streams);
686 : :
687 : : #if ENABLE_DNS_OVER_TLS
688 : 0 : dnstls_manager_free(m);
689 : : #endif
690 : :
691 : 0 : hashmap_free(m->links);
692 : 0 : hashmap_free(m->dns_transactions);
693 : :
694 : 0 : sd_event_source_unref(m->network_event_source);
695 : 0 : sd_network_monitor_unref(m->network_monitor);
696 : :
697 : 0 : sd_netlink_unref(m->rtnl);
698 : 0 : sd_event_source_unref(m->rtnl_event_source);
699 : :
700 : 0 : manager_llmnr_stop(m);
701 : 0 : manager_mdns_stop(m);
702 : 0 : manager_dns_stub_stop(m);
703 : :
704 : 0 : bus_verify_polkit_async_registry_free(m->polkit_registry);
705 : :
706 : 0 : sd_bus_flush_close_unref(m->bus);
707 : :
708 : 0 : sd_event_source_unref(m->sigusr1_event_source);
709 : 0 : sd_event_source_unref(m->sigusr2_event_source);
710 : 0 : sd_event_source_unref(m->sigrtmin1_event_source);
711 : :
712 : 0 : sd_event_unref(m->event);
713 : :
714 : 0 : dns_resource_key_unref(m->llmnr_host_ipv4_key);
715 : 0 : dns_resource_key_unref(m->llmnr_host_ipv6_key);
716 : 0 : dns_resource_key_unref(m->mdns_host_ipv4_key);
717 : 0 : dns_resource_key_unref(m->mdns_host_ipv6_key);
718 : :
719 : 0 : sd_event_source_unref(m->hostname_event_source);
720 : 0 : safe_close(m->hostname_fd);
721 : :
722 : 0 : free(m->full_hostname);
723 : 0 : free(m->llmnr_hostname);
724 : 0 : free(m->mdns_hostname);
725 : :
726 [ # # ]: 0 : while ((s = hashmap_first(m->dnssd_services)))
727 : 0 : dnssd_service_free(s);
728 : 0 : hashmap_free(m->dnssd_services);
729 : :
730 : 0 : dns_trust_anchor_flush(&m->trust_anchor);
731 : 0 : manager_etc_hosts_flush(m);
732 : :
733 : 0 : return mfree(m);
734 : : }
735 : :
736 : 0 : int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
737 : 0 : _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
738 : : union {
739 : : struct cmsghdr header; /* For alignment */
740 : : uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
741 : : + CMSG_SPACE(int) /* ttl/hoplimit */
742 : : + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
743 : : } control;
744 : : union sockaddr_union sa;
745 : : struct iovec iov;
746 : 0 : struct msghdr mh = {
747 : : .msg_name = &sa.sa,
748 : : .msg_namelen = sizeof(sa),
749 : : .msg_iov = &iov,
750 : : .msg_iovlen = 1,
751 : : .msg_control = &control,
752 : : .msg_controllen = sizeof(control),
753 : : };
754 : : struct cmsghdr *cmsg;
755 : : ssize_t ms, l;
756 : : int r;
757 : :
758 [ # # ]: 0 : assert(m);
759 [ # # ]: 0 : assert(fd >= 0);
760 [ # # ]: 0 : assert(ret);
761 : :
762 : 0 : ms = next_datagram_size_fd(fd);
763 [ # # ]: 0 : if (ms < 0)
764 : 0 : return ms;
765 : :
766 : 0 : r = dns_packet_new(&p, protocol, ms, DNS_PACKET_SIZE_MAX);
767 [ # # ]: 0 : if (r < 0)
768 : 0 : return r;
769 : :
770 : 0 : iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->allocated);
771 : :
772 : 0 : l = recvmsg(fd, &mh, 0);
773 [ # # ]: 0 : if (l < 0) {
774 [ # # # # ]: 0 : if (IN_SET(errno, EAGAIN, EINTR))
775 : 0 : return 0;
776 : :
777 : 0 : return -errno;
778 : : }
779 [ # # ]: 0 : if (l == 0)
780 : 0 : return 0;
781 : :
782 [ # # ]: 0 : assert(!(mh.msg_flags & MSG_CTRUNC));
783 [ # # ]: 0 : assert(!(mh.msg_flags & MSG_TRUNC));
784 : :
785 : 0 : p->size = (size_t) l;
786 : :
787 : 0 : p->family = sa.sa.sa_family;
788 : 0 : p->ipproto = IPPROTO_UDP;
789 [ # # ]: 0 : if (p->family == AF_INET) {
790 : 0 : p->sender.in = sa.in.sin_addr;
791 : 0 : p->sender_port = be16toh(sa.in.sin_port);
792 [ # # ]: 0 : } else if (p->family == AF_INET6) {
793 : 0 : p->sender.in6 = sa.in6.sin6_addr;
794 : 0 : p->sender_port = be16toh(sa.in6.sin6_port);
795 : 0 : p->ifindex = sa.in6.sin6_scope_id;
796 : : } else
797 : 0 : return -EAFNOSUPPORT;
798 : :
799 [ # # # # ]: 0 : CMSG_FOREACH(cmsg, &mh) {
800 : :
801 [ # # ]: 0 : if (cmsg->cmsg_level == IPPROTO_IPV6) {
802 [ # # ]: 0 : assert(p->family == AF_INET6);
803 : :
804 [ # # # ]: 0 : switch (cmsg->cmsg_type) {
805 : :
806 : 0 : case IPV6_PKTINFO: {
807 : 0 : struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
808 : :
809 [ # # ]: 0 : if (p->ifindex <= 0)
810 : 0 : p->ifindex = i->ipi6_ifindex;
811 : :
812 : 0 : p->destination.in6 = i->ipi6_addr;
813 : 0 : break;
814 : : }
815 : :
816 : 0 : case IPV6_HOPLIMIT:
817 : 0 : p->ttl = *(int *) CMSG_DATA(cmsg);
818 : 0 : break;
819 : :
820 : : }
821 [ # # ]: 0 : } else if (cmsg->cmsg_level == IPPROTO_IP) {
822 [ # # ]: 0 : assert(p->family == AF_INET);
823 : :
824 [ # # # ]: 0 : switch (cmsg->cmsg_type) {
825 : :
826 : 0 : case IP_PKTINFO: {
827 : 0 : struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
828 : :
829 [ # # ]: 0 : if (p->ifindex <= 0)
830 : 0 : p->ifindex = i->ipi_ifindex;
831 : :
832 : 0 : p->destination.in = i->ipi_addr;
833 : 0 : break;
834 : : }
835 : :
836 : 0 : case IP_TTL:
837 : 0 : p->ttl = *(int *) CMSG_DATA(cmsg);
838 : 0 : break;
839 : : }
840 : 0 : }
841 : : }
842 : :
843 : : /* The Linux kernel sets the interface index to the loopback
844 : : * device if the packet came from the local host since it
845 : : * avoids the routing table in such a case. Let's unset the
846 : : * interface index in such a case. */
847 [ # # ]: 0 : if (p->ifindex == LOOPBACK_IFINDEX)
848 : 0 : p->ifindex = 0;
849 : :
850 [ # # ]: 0 : if (protocol != DNS_PROTOCOL_DNS) {
851 : : /* If we don't know the interface index still, we look for the
852 : : * first local interface with a matching address. Yuck! */
853 [ # # ]: 0 : if (p->ifindex <= 0)
854 : 0 : p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
855 : : }
856 : :
857 : 0 : *ret = TAKE_PTR(p);
858 : :
859 : 0 : return 1;
860 : : }
861 : :
862 : 0 : static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
863 : : int r;
864 : :
865 [ # # ]: 0 : assert(fd >= 0);
866 [ # # ]: 0 : assert(mh);
867 : :
868 : : for (;;) {
869 [ # # ]: 0 : if (sendmsg(fd, mh, flags) >= 0)
870 : 0 : return 0;
871 : :
872 [ # # ]: 0 : if (errno == EINTR)
873 : 0 : continue;
874 : :
875 [ # # ]: 0 : if (errno != EAGAIN)
876 : 0 : return -errno;
877 : :
878 : 0 : r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
879 [ # # ]: 0 : if (r < 0)
880 : 0 : return r;
881 [ # # ]: 0 : if (r == 0)
882 : 0 : return -ETIMEDOUT;
883 : : }
884 : : }
885 : :
886 : 0 : static int write_loop(int fd, void *message, size_t length) {
887 : : int r;
888 : :
889 [ # # ]: 0 : assert(fd >= 0);
890 [ # # ]: 0 : assert(message);
891 : :
892 : : for (;;) {
893 [ # # ]: 0 : if (write(fd, message, length) >= 0)
894 : 0 : return 0;
895 : :
896 [ # # ]: 0 : if (errno == EINTR)
897 : 0 : continue;
898 : :
899 [ # # ]: 0 : if (errno != EAGAIN)
900 : 0 : return -errno;
901 : :
902 : 0 : r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
903 [ # # ]: 0 : if (r < 0)
904 : 0 : return r;
905 [ # # ]: 0 : if (r == 0)
906 : 0 : return -ETIMEDOUT;
907 : : }
908 : : }
909 : :
910 : 0 : int manager_write(Manager *m, int fd, DnsPacket *p) {
911 : : int r;
912 : :
913 [ # # # # ]: 0 : log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
914 : :
915 : 0 : r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
916 [ # # ]: 0 : if (r < 0)
917 : 0 : return r;
918 : :
919 : 0 : return 0;
920 : : }
921 : :
922 : 0 : static int manager_ipv4_send(
923 : : Manager *m,
924 : : int fd,
925 : : int ifindex,
926 : : const struct in_addr *destination,
927 : : uint16_t port,
928 : : const struct in_addr *source,
929 : : DnsPacket *p) {
930 : : union {
931 : : struct cmsghdr header; /* For alignment */
932 : : uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
933 : 0 : } control = {};
934 : : union sockaddr_union sa;
935 : : struct iovec iov;
936 : 0 : struct msghdr mh = {
937 : : .msg_iov = &iov,
938 : : .msg_iovlen = 1,
939 : : .msg_name = &sa.sa,
940 : : .msg_namelen = sizeof(sa.in),
941 : : };
942 : :
943 [ # # ]: 0 : assert(m);
944 [ # # ]: 0 : assert(fd >= 0);
945 [ # # ]: 0 : assert(destination);
946 [ # # ]: 0 : assert(port > 0);
947 [ # # ]: 0 : assert(p);
948 : :
949 : 0 : iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);
950 : :
951 : 0 : sa = (union sockaddr_union) {
952 : : .in.sin_family = AF_INET,
953 : 0 : .in.sin_addr = *destination,
954 : 0 : .in.sin_port = htobe16(port),
955 : : };
956 : :
957 [ # # ]: 0 : if (ifindex > 0) {
958 : : struct cmsghdr *cmsg;
959 : : struct in_pktinfo *pi;
960 : :
961 : 0 : mh.msg_control = &control;
962 : 0 : mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
963 : :
964 [ # # ]: 0 : cmsg = CMSG_FIRSTHDR(&mh);
965 : 0 : cmsg->cmsg_len = mh.msg_controllen;
966 : 0 : cmsg->cmsg_level = IPPROTO_IP;
967 : 0 : cmsg->cmsg_type = IP_PKTINFO;
968 : :
969 : 0 : pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
970 : 0 : pi->ipi_ifindex = ifindex;
971 : :
972 [ # # ]: 0 : if (source)
973 : 0 : pi->ipi_spec_dst = *source;
974 : : }
975 : :
976 : 0 : return sendmsg_loop(fd, &mh, 0);
977 : : }
978 : :
979 : 0 : static int manager_ipv6_send(
980 : : Manager *m,
981 : : int fd,
982 : : int ifindex,
983 : : const struct in6_addr *destination,
984 : : uint16_t port,
985 : : const struct in6_addr *source,
986 : : DnsPacket *p) {
987 : :
988 : : union {
989 : : struct cmsghdr header; /* For alignment */
990 : : uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
991 : 0 : } control = {};
992 : : union sockaddr_union sa;
993 : : struct iovec iov;
994 : 0 : struct msghdr mh = {
995 : : .msg_iov = &iov,
996 : : .msg_iovlen = 1,
997 : : .msg_name = &sa.sa,
998 : : .msg_namelen = sizeof(sa.in6),
999 : : };
1000 : :
1001 [ # # ]: 0 : assert(m);
1002 [ # # ]: 0 : assert(fd >= 0);
1003 [ # # ]: 0 : assert(destination);
1004 [ # # ]: 0 : assert(port > 0);
1005 [ # # ]: 0 : assert(p);
1006 : :
1007 : 0 : iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);
1008 : :
1009 : 0 : sa = (union sockaddr_union) {
1010 : : .in6.sin6_family = AF_INET6,
1011 : 0 : .in6.sin6_addr = *destination,
1012 : 0 : .in6.sin6_port = htobe16(port),
1013 : : .in6.sin6_scope_id = ifindex,
1014 : : };
1015 : :
1016 [ # # ]: 0 : if (ifindex > 0) {
1017 : : struct cmsghdr *cmsg;
1018 : : struct in6_pktinfo *pi;
1019 : :
1020 : 0 : mh.msg_control = &control;
1021 : 0 : mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1022 : :
1023 [ # # ]: 0 : cmsg = CMSG_FIRSTHDR(&mh);
1024 : 0 : cmsg->cmsg_len = mh.msg_controllen;
1025 : 0 : cmsg->cmsg_level = IPPROTO_IPV6;
1026 : 0 : cmsg->cmsg_type = IPV6_PKTINFO;
1027 : :
1028 : 0 : pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1029 : 0 : pi->ipi6_ifindex = ifindex;
1030 : :
1031 [ # # ]: 0 : if (source)
1032 : 0 : pi->ipi6_addr = *source;
1033 : : }
1034 : :
1035 : 0 : return sendmsg_loop(fd, &mh, 0);
1036 : : }
1037 : :
1038 : 0 : int manager_send(
1039 : : Manager *m,
1040 : : int fd,
1041 : : int ifindex,
1042 : : int family,
1043 : : const union in_addr_union *destination,
1044 : : uint16_t port,
1045 : : const union in_addr_union *source,
1046 : : DnsPacket *p) {
1047 : :
1048 [ # # ]: 0 : assert(m);
1049 [ # # ]: 0 : assert(fd >= 0);
1050 [ # # ]: 0 : assert(destination);
1051 [ # # ]: 0 : assert(port > 0);
1052 [ # # ]: 0 : assert(p);
1053 : :
1054 [ # # # # ]: 0 : log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
1055 : :
1056 [ # # ]: 0 : if (family == AF_INET)
1057 [ # # ]: 0 : return manager_ipv4_send(m, fd, ifindex, &destination->in, port, source ? &source->in : NULL, p);
1058 [ # # ]: 0 : if (family == AF_INET6)
1059 [ # # ]: 0 : return manager_ipv6_send(m, fd, ifindex, &destination->in6, port, source ? &source->in6 : NULL, p);
1060 : :
1061 : 0 : return -EAFNOSUPPORT;
1062 : : }
1063 : :
1064 : 0 : uint32_t manager_find_mtu(Manager *m) {
1065 : 0 : 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 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
1074 [ # # ]: 0 : if (l->mtu <= 0)
1075 : 0 : continue;
1076 : :
1077 [ # # # # ]: 0 : if (mtu <= 0 || l->mtu < mtu)
1078 : 0 : mtu = l->mtu;
1079 : : }
1080 : :
1081 : 0 : return mtu;
1082 : : }
1083 : :
1084 : 0 : int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1085 : : LinkAddress *a;
1086 : :
1087 [ # # ]: 0 : assert(m);
1088 : :
1089 : 0 : a = manager_find_link_address(m, family, in_addr);
1090 [ # # ]: 0 : if (a)
1091 : 0 : return a->link->ifindex;
1092 : :
1093 : 0 : return 0;
1094 : : }
1095 : :
1096 : 0 : void manager_refresh_rrs(Manager *m) {
1097 : : Iterator i;
1098 : : Link *l;
1099 : : DnssdService *s;
1100 : :
1101 [ # # ]: 0 : assert(m);
1102 : :
1103 : 0 : m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
1104 : 0 : m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
1105 : 0 : m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
1106 : 0 : m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
1107 : :
1108 [ # # ]: 0 : if (m->mdns_support == RESOLVE_SUPPORT_YES)
1109 [ # # ]: 0 : HASHMAP_FOREACH(s, m->dnssd_services, i)
1110 [ # # ]: 0 : if (dnssd_update_rrs(s) < 0)
1111 [ # # ]: 0 : log_warning("Failed to refresh DNS-SD service '%s'", s->name);
1112 : :
1113 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
1114 : 0 : link_add_rrs(l, true);
1115 : 0 : link_add_rrs(l, false);
1116 : : }
1117 : 0 : }
1118 : :
1119 : 0 : static int manager_next_random_name(const char *old, char **ret_new) {
1120 : : const char *p;
1121 : : uint64_t u, a;
1122 : : char *n;
1123 : :
1124 : 0 : p = strchr(old, 0);
1125 [ # # ]: 0 : assert(p);
1126 : :
1127 [ # # ]: 0 : while (p > old) {
1128 [ # # ]: 0 : if (!strchr(DIGITS, p[-1]))
1129 : 0 : break;
1130 : :
1131 : 0 : p--;
1132 : : }
1133 : :
1134 [ # # # # : 0 : if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
# # ]
1135 : 0 : u = 1;
1136 : :
1137 : : /* Add a random number to the old value. This way we can avoid
1138 : : * that two hosts pick the same hostname, win on IPv4 and lose
1139 : : * on IPv6 (or vice versa), and pick the same hostname
1140 : : * replacement hostname, ad infinitum. We still want the
1141 : : * numbers to go up monotonically, hence we just add a random
1142 : : * value 1..10 */
1143 : :
1144 : 0 : random_bytes(&a, sizeof(a));
1145 : 0 : u += 1 + a % 10;
1146 : :
1147 [ # # ]: 0 : if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
1148 : 0 : return -ENOMEM;
1149 : :
1150 : 0 : *ret_new = n;
1151 : :
1152 : 0 : return 0;
1153 : : }
1154 : :
1155 : 0 : int manager_next_hostname(Manager *m) {
1156 : 0 : _cleanup_free_ char *h = NULL, *k = NULL;
1157 : : int r;
1158 : :
1159 [ # # ]: 0 : assert(m);
1160 : :
1161 : 0 : r = manager_next_random_name(m->llmnr_hostname, &h);
1162 [ # # ]: 0 : if (r < 0)
1163 : 0 : return r;
1164 : :
1165 : 0 : r = dns_name_concat(h, "local", 0, &k);
1166 [ # # ]: 0 : if (r < 0)
1167 : 0 : return r;
1168 : :
1169 [ # # ]: 0 : log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
1170 : :
1171 : 0 : free_and_replace(m->llmnr_hostname, h);
1172 : 0 : free_and_replace(m->mdns_hostname, k);
1173 : :
1174 : 0 : manager_refresh_rrs(m);
1175 : :
1176 : 0 : return 0;
1177 : : }
1178 : :
1179 : 0 : LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1180 : : Iterator i;
1181 : : Link *l;
1182 : :
1183 [ # # ]: 0 : assert(m);
1184 : :
1185 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
1186 : : LinkAddress *a;
1187 : :
1188 : 0 : a = link_find_address(l, family, in_addr);
1189 [ # # ]: 0 : if (a)
1190 : 0 : return a;
1191 : : }
1192 : :
1193 : 0 : return NULL;
1194 : : }
1195 : :
1196 : 0 : bool manager_our_packet(Manager *m, DnsPacket *p) {
1197 [ # # ]: 0 : assert(m);
1198 [ # # ]: 0 : assert(p);
1199 : :
1200 : 0 : return !!manager_find_link_address(m, p->family, &p->sender);
1201 : : }
1202 : :
1203 : 0 : DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1204 : : Link *l;
1205 : :
1206 [ # # ]: 0 : assert(m);
1207 [ # # ]: 0 : assert(p);
1208 : :
1209 : 0 : l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1210 [ # # ]: 0 : if (!l)
1211 : 0 : return NULL;
1212 : :
1213 [ # # # ]: 0 : switch (p->protocol) {
1214 : 0 : case DNS_PROTOCOL_LLMNR:
1215 [ # # ]: 0 : if (p->family == AF_INET)
1216 : 0 : return l->llmnr_ipv4_scope;
1217 [ # # ]: 0 : else if (p->family == AF_INET6)
1218 : 0 : return l->llmnr_ipv6_scope;
1219 : :
1220 : 0 : break;
1221 : :
1222 : 0 : case DNS_PROTOCOL_MDNS:
1223 [ # # ]: 0 : if (p->family == AF_INET)
1224 : 0 : return l->mdns_ipv4_scope;
1225 [ # # ]: 0 : else if (p->family == AF_INET6)
1226 : 0 : return l->mdns_ipv6_scope;
1227 : :
1228 : 0 : break;
1229 : :
1230 : 0 : default:
1231 : 0 : break;
1232 : : }
1233 : :
1234 : 0 : return NULL;
1235 : : }
1236 : :
1237 : 0 : void manager_verify_all(Manager *m) {
1238 : : DnsScope *s;
1239 : :
1240 [ # # ]: 0 : assert(m);
1241 : :
1242 [ # # ]: 0 : LIST_FOREACH(scopes, s, m->dns_scopes)
1243 : 0 : dns_zone_verify_all(&s->zone);
1244 : 0 : }
1245 : :
1246 : 0 : int manager_is_own_hostname(Manager *m, const char *name) {
1247 : : int r;
1248 : :
1249 [ # # ]: 0 : assert(m);
1250 [ # # ]: 0 : assert(name);
1251 : :
1252 [ # # ]: 0 : if (m->llmnr_hostname) {
1253 : 0 : r = dns_name_equal(name, m->llmnr_hostname);
1254 [ # # ]: 0 : if (r != 0)
1255 : 0 : return r;
1256 : : }
1257 : :
1258 [ # # ]: 0 : if (m->mdns_hostname) {
1259 : 0 : r = dns_name_equal(name, m->mdns_hostname);
1260 [ # # ]: 0 : if (r != 0)
1261 : 0 : return r;
1262 : : }
1263 : :
1264 [ # # ]: 0 : if (m->full_hostname)
1265 : 0 : return dns_name_equal(name, m->full_hostname);
1266 : :
1267 : 0 : return 0;
1268 : : }
1269 : :
1270 : 0 : int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
1271 : : DnsServer *s;
1272 : : Iterator i;
1273 : : Link *l;
1274 : : int r;
1275 : :
1276 [ # # ]: 0 : assert(m);
1277 [ # # ]: 0 : assert(dns);
1278 : :
1279 : 0 : r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
1280 [ # # ]: 0 : if (r < 0)
1281 : 0 : return r;
1282 : :
1283 : : /* First add the system-wide servers and domains */
1284 [ # # ]: 0 : LIST_FOREACH(servers, s, m->dns_servers) {
1285 : 0 : r = ordered_set_put(*dns, s);
1286 [ # # ]: 0 : if (r == -EEXIST)
1287 : 0 : continue;
1288 [ # # ]: 0 : if (r < 0)
1289 : 0 : return r;
1290 : : }
1291 : :
1292 : : /* Then, add the per-link servers */
1293 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
1294 [ # # ]: 0 : LIST_FOREACH(servers, s, l->dns_servers) {
1295 : 0 : r = ordered_set_put(*dns, s);
1296 [ # # ]: 0 : if (r == -EEXIST)
1297 : 0 : continue;
1298 [ # # ]: 0 : if (r < 0)
1299 : 0 : return r;
1300 : : }
1301 : : }
1302 : :
1303 : : /* If we found nothing, add the fallback servers */
1304 [ # # ]: 0 : if (ordered_set_isempty(*dns)) {
1305 [ # # ]: 0 : LIST_FOREACH(servers, s, m->fallback_dns_servers) {
1306 : 0 : r = ordered_set_put(*dns, s);
1307 [ # # ]: 0 : if (r == -EEXIST)
1308 : 0 : continue;
1309 [ # # ]: 0 : if (r < 0)
1310 : 0 : return r;
1311 : : }
1312 : : }
1313 : :
1314 : 0 : return 0;
1315 : : }
1316 : :
1317 : : /* filter_route is a tri-state:
1318 : : * < 0: no filtering
1319 : : * = 0 or false: return only domains which should be used for searching
1320 : : * > 0 or true: return only domains which are for routing only
1321 : : */
1322 : 0 : int manager_compile_search_domains(Manager *m, OrderedSet **domains, int filter_route) {
1323 : : DnsSearchDomain *d;
1324 : : Iterator i;
1325 : : Link *l;
1326 : : int r;
1327 : :
1328 [ # # ]: 0 : assert(m);
1329 [ # # ]: 0 : assert(domains);
1330 : :
1331 : 0 : r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
1332 [ # # ]: 0 : if (r < 0)
1333 : 0 : return r;
1334 : :
1335 [ # # ]: 0 : LIST_FOREACH(domains, d, m->search_domains) {
1336 : :
1337 [ # # ]: 0 : if (filter_route >= 0 &&
1338 [ # # ]: 0 : d->route_only != !!filter_route)
1339 : 0 : continue;
1340 : :
1341 : 0 : r = ordered_set_put(*domains, d->name);
1342 [ # # ]: 0 : if (r == -EEXIST)
1343 : 0 : continue;
1344 [ # # ]: 0 : if (r < 0)
1345 : 0 : return r;
1346 : : }
1347 : :
1348 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i) {
1349 : :
1350 [ # # ]: 0 : LIST_FOREACH(domains, d, l->search_domains) {
1351 : :
1352 [ # # ]: 0 : if (filter_route >= 0 &&
1353 [ # # ]: 0 : d->route_only != !!filter_route)
1354 : 0 : continue;
1355 : :
1356 : 0 : r = ordered_set_put(*domains, d->name);
1357 [ # # ]: 0 : if (r == -EEXIST)
1358 : 0 : continue;
1359 [ # # ]: 0 : if (r < 0)
1360 : 0 : return r;
1361 : : }
1362 : : }
1363 : :
1364 : 0 : return 0;
1365 : : }
1366 : :
1367 : 0 : DnssecMode manager_get_dnssec_mode(Manager *m) {
1368 [ # # ]: 0 : assert(m);
1369 : :
1370 [ # # ]: 0 : if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
1371 : 0 : return m->dnssec_mode;
1372 : :
1373 : 0 : return DNSSEC_NO;
1374 : : }
1375 : :
1376 : 0 : bool manager_dnssec_supported(Manager *m) {
1377 : : DnsServer *server;
1378 : : Iterator i;
1379 : : Link *l;
1380 : :
1381 [ # # ]: 0 : assert(m);
1382 : :
1383 [ # # ]: 0 : if (manager_get_dnssec_mode(m) == DNSSEC_NO)
1384 : 0 : return false;
1385 : :
1386 : 0 : server = manager_get_dns_server(m);
1387 [ # # # # ]: 0 : if (server && !dns_server_dnssec_supported(server))
1388 : 0 : return false;
1389 : :
1390 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i)
1391 [ # # ]: 0 : if (!link_dnssec_supported(l))
1392 : 0 : return false;
1393 : :
1394 : 0 : return true;
1395 : : }
1396 : :
1397 : 0 : DnsOverTlsMode manager_get_dns_over_tls_mode(Manager *m) {
1398 [ # # ]: 0 : assert(m);
1399 : :
1400 [ # # ]: 0 : if (m->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
1401 : 0 : return m->dns_over_tls_mode;
1402 : :
1403 : 0 : return DNS_OVER_TLS_NO;
1404 : : }
1405 : :
1406 : 0 : void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
1407 : :
1408 [ # # ]: 0 : assert(verdict >= 0);
1409 [ # # ]: 0 : assert(verdict < _DNSSEC_VERDICT_MAX);
1410 : :
1411 [ # # ]: 0 : if (DEBUG_LOGGING) {
1412 : : char s[DNS_RESOURCE_KEY_STRING_MAX];
1413 : :
1414 [ # # ]: 0 : log_debug("Found verdict for lookup %s: %s",
1415 : : dns_resource_key_to_string(key, s, sizeof s),
1416 : : dnssec_verdict_to_string(verdict));
1417 : : }
1418 : :
1419 : 0 : m->n_dnssec_verdict[verdict]++;
1420 : 0 : }
1421 : :
1422 : 0 : bool manager_routable(Manager *m, int family) {
1423 : : Iterator i;
1424 : : Link *l;
1425 : :
1426 [ # # ]: 0 : assert(m);
1427 : :
1428 : : /* Returns true if the host has at least one interface with a routable address of the specified type */
1429 : :
1430 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i)
1431 [ # # ]: 0 : if (link_relevant(l, family, false))
1432 : 0 : return true;
1433 : :
1434 : 0 : return false;
1435 : : }
1436 : :
1437 : 0 : void manager_flush_caches(Manager *m) {
1438 : : DnsScope *scope;
1439 : :
1440 [ # # ]: 0 : assert(m);
1441 : :
1442 [ # # ]: 0 : LIST_FOREACH(scopes, scope, m->dns_scopes)
1443 : 0 : dns_cache_flush(&scope->cache);
1444 : :
1445 [ # # ]: 0 : log_info("Flushed all caches.");
1446 : 0 : }
1447 : :
1448 : 0 : void manager_reset_server_features(Manager *m) {
1449 : : Iterator i;
1450 : : Link *l;
1451 : :
1452 : 0 : dns_server_reset_features_all(m->dns_servers);
1453 : 0 : dns_server_reset_features_all(m->fallback_dns_servers);
1454 : :
1455 [ # # ]: 0 : HASHMAP_FOREACH(l, m->links, i)
1456 : 0 : dns_server_reset_features_all(l->dns_servers);
1457 : :
1458 [ # # ]: 0 : log_info("Resetting learnt feature levels on all servers.");
1459 : 0 : }
1460 : :
1461 : 0 : void manager_cleanup_saved_user(Manager *m) {
1462 [ # # ]: 0 : _cleanup_closedir_ DIR *d = NULL;
1463 : : struct dirent *de;
1464 : : int r;
1465 : :
1466 [ # # ]: 0 : assert(m);
1467 : :
1468 : : /* Clean up all saved per-link files in /run/systemd/resolve/netif/ that don't have a matching interface
1469 : : * anymore. These files are created to persist settings pushed in by the user via the bus, so that resolved can
1470 : : * be restarted without losing this data. */
1471 : :
1472 : 0 : d = opendir("/run/systemd/resolve/netif/");
1473 [ # # ]: 0 : if (!d) {
1474 [ # # ]: 0 : if (errno == ENOENT)
1475 : 0 : return;
1476 : :
1477 [ # # ]: 0 : log_warning_errno(errno, "Failed to open interface directory: %m");
1478 : 0 : return;
1479 : : }
1480 : :
1481 [ # # # # : 0 : FOREACH_DIRENT_ALL(de, d, log_error_errno(errno, "Failed to read interface directory: %m")) {
# # ]
1482 [ # # # ]: 0 : _cleanup_free_ char *p = NULL;
1483 : : int ifindex;
1484 : : Link *l;
1485 : :
1486 [ # # # # ]: 0 : if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
1487 : 0 : continue;
1488 : :
1489 [ # # ]: 0 : if (dot_or_dot_dot(de->d_name))
1490 : 0 : continue;
1491 : :
1492 : 0 : r = parse_ifindex(de->d_name, &ifindex);
1493 [ # # ]: 0 : if (r < 0) /* Probably some temporary file from a previous run. Delete it */
1494 : 0 : goto rm;
1495 : :
1496 : 0 : l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1497 [ # # ]: 0 : if (!l) /* link vanished */
1498 : 0 : goto rm;
1499 : :
1500 [ # # ]: 0 : if (l->is_managed) /* now managed by networkd, hence the bus settings are useless */
1501 : 0 : goto rm;
1502 : :
1503 : 0 : continue;
1504 : :
1505 : 0 : rm:
1506 : 0 : p = path_join("/run/systemd/resolve/netif", de->d_name);
1507 [ # # ]: 0 : if (!p) {
1508 : 0 : log_oom();
1509 : 0 : return;
1510 : : }
1511 : :
1512 : 0 : (void) unlink(p);
1513 : : }
1514 : : }
1515 : :
1516 : 0 : bool manager_next_dnssd_names(Manager *m) {
1517 : : Iterator i;
1518 : : DnssdService *s;
1519 : 0 : bool tried = false;
1520 : : int r;
1521 : :
1522 [ # # ]: 0 : assert(m);
1523 : :
1524 [ # # ]: 0 : HASHMAP_FOREACH(s, m->dnssd_services, i) {
1525 [ # # ]: 0 : _cleanup_free_ char * new_name = NULL;
1526 : :
1527 [ # # ]: 0 : if (!s->withdrawn)
1528 : 0 : continue;
1529 : :
1530 : 0 : r = manager_next_random_name(s->name_template, &new_name);
1531 [ # # ]: 0 : if (r < 0) {
1532 [ # # ]: 0 : log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
1533 : 0 : continue;
1534 : : }
1535 : :
1536 : 0 : free_and_replace(s->name_template, new_name);
1537 : :
1538 : 0 : s->withdrawn = false;
1539 : :
1540 : 0 : tried = true;
1541 : : }
1542 : :
1543 [ # # ]: 0 : if (tried)
1544 : 0 : manager_refresh_rrs(m);
1545 : :
1546 : 0 : return tried;
1547 : : }
|