1 /* $OpenBSD: unwind.c,v 1.75 2024/11/21 13:35:20 claudio Exp $ */
2
3 /*
4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/socket.h>
24 #include <sys/stat.h>
25 #include <sys/syslog.h>
26 #include <sys/wait.h>
27
28 #include <net/if.h>
29 #include <net/route.h>
30
31 #include <err.h>
32 #include <errno.h>
33 #include <event.h>
34 #include <fcntl.h>
35 #include <imsg.h>
36 #include <netdb.h>
37 #include <asr.h>
38 #include <pwd.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44
45 #include "log.h"
46 #include "unwind.h"
47 #include "frontend.h"
48 #include "resolver.h"
49 #include "control.h"
50
51 #define TRUST_ANCHOR_FILE "/var/db/unwind.key"
52
53 enum uw_process {
54 PROC_MAIN,
55 PROC_RESOLVER,
56 PROC_FRONTEND,
57 };
58
59 __dead void usage(void);
60 __dead void main_shutdown(void);
61
62 void main_sig_handler(int, short, void *);
63
64 static pid_t start_child(enum uw_process, char *, int, int, int);
65
66 void main_dispatch_frontend(int, short, void *);
67 void main_dispatch_resolver(int, short, void *);
68
69 static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
70 static int main_imsg_send_config(struct uw_conf *);
71
72 int main_reload(void);
73 int main_sendall(enum imsg_type, void *, uint16_t);
74 void open_ports(void);
75 void solicit_dns_proposals(void);
76 void send_blocklist_fd(void);
77
78 struct uw_conf *main_conf;
79 static struct imsgev *iev_frontend;
80 static struct imsgev *iev_resolver;
81 char *conffile;
82 pid_t frontend_pid;
83 pid_t resolver_pid;
84 uint32_t cmd_opts;
85 int routesock;
86
87 void
main_sig_handler(int sig,short event,void * arg)88 main_sig_handler(int sig, short event, void *arg)
89 {
90 /*
91 * Normal signal handler rules don't apply because libevent
92 * decouples for us.
93 */
94
95 switch (sig) {
96 case SIGTERM:
97 case SIGINT:
98 main_shutdown();
99 break;
100 case SIGHUP:
101 if (main_reload() == -1)
102 log_warnx("configuration reload failed");
103 else
104 log_debug("configuration reloaded");
105 break;
106 default:
107 fatalx("unexpected signal");
108 }
109 }
110
111 __dead void
usage(void)112 usage(void)
113 {
114 extern char *__progname;
115
116 fprintf(stderr, "usage: %s [-dnv] [-f file] [-s socket]\n",
117 __progname);
118 exit(1);
119 }
120
121 int
main(int argc,char * argv[])122 main(int argc, char *argv[])
123 {
124 struct event ev_sigint, ev_sigterm, ev_sighup;
125 int ch, debug = 0, resolver_flag = 0, frontend_flag = 0;
126 int frontend_routesock, rtfilter;
127 int pipe_main2frontend[2], pipe_main2resolver[2];
128 int control_fd, ta_fd;
129 char *csock, *saved_argv0;
130
131 csock = _PATH_UNWIND_SOCKET;
132
133 log_init(1, LOG_DAEMON); /* Log to stderr until daemonized. */
134 log_setverbose(1);
135
136 saved_argv0 = argv[0];
137 if (saved_argv0 == NULL)
138 saved_argv0 = "unwind";
139
140 while ((ch = getopt(argc, argv, "dEFf:ns:v")) != -1) {
141 switch (ch) {
142 case 'd':
143 debug = 1;
144 break;
145 case 'E':
146 resolver_flag = 1;
147 break;
148 case 'F':
149 frontend_flag = 1;
150 break;
151 case 'f':
152 conffile = optarg;
153 break;
154 case 'n':
155 cmd_opts |= OPT_NOACTION;
156 break;
157 case 's':
158 csock = optarg;
159 break;
160 case 'v':
161 if (cmd_opts & OPT_VERBOSE2)
162 cmd_opts |= OPT_VERBOSE3;
163 if (cmd_opts & OPT_VERBOSE)
164 cmd_opts |= OPT_VERBOSE2;
165 cmd_opts |= OPT_VERBOSE;
166 break;
167 default:
168 usage();
169 }
170 }
171
172 argc -= optind;
173 argv += optind;
174 if (argc > 0 || (resolver_flag && frontend_flag))
175 usage();
176
177 if (resolver_flag)
178 resolver(debug, cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 |
179 OPT_VERBOSE3));
180 else if (frontend_flag)
181 frontend(debug, cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 |
182 OPT_VERBOSE3));
183
184 if ((main_conf = parse_config(conffile)) == NULL)
185 exit(1);
186
187 if (cmd_opts & OPT_NOACTION) {
188 if (cmd_opts & OPT_VERBOSE)
189 print_config(main_conf);
190 else
191 fprintf(stderr, "configuration OK\n");
192 exit(0);
193 }
194
195 /* Check for root privileges. */
196 if (geteuid())
197 errx(1, "need root privileges");
198
199 /* Check for assigned daemon user */
200 if (getpwnam(UNWIND_USER) == NULL)
201 errx(1, "unknown user %s", UNWIND_USER);
202
203 log_init(debug, LOG_DAEMON);
204 log_setverbose(cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 | OPT_VERBOSE3));
205
206 if (!debug)
207 daemon(1, 0);
208
209 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
210 PF_UNSPEC, pipe_main2frontend) == -1)
211 fatal("main2frontend socketpair");
212 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
213 PF_UNSPEC, pipe_main2resolver) == -1)
214 fatal("main2resolver socketpair");
215
216 /* Start children. */
217 resolver_pid = start_child(PROC_RESOLVER, saved_argv0,
218 pipe_main2resolver[1], debug, cmd_opts & (OPT_VERBOSE |
219 OPT_VERBOSE2 | OPT_VERBOSE3));
220 frontend_pid = start_child(PROC_FRONTEND, saved_argv0,
221 pipe_main2frontend[1], debug, cmd_opts & (OPT_VERBOSE |
222 OPT_VERBOSE2 | OPT_VERBOSE3));
223
224 log_procinit("main");
225
226 event_init();
227
228 /* Setup signal handler. */
229 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL);
230 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL);
231 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL);
232 signal_add(&ev_sigint, NULL);
233 signal_add(&ev_sigterm, NULL);
234 signal_add(&ev_sighup, NULL);
235 signal(SIGPIPE, SIG_IGN);
236
237 /* Setup pipes to children. */
238
239 if ((iev_frontend = malloc(sizeof(struct imsgev))) == NULL ||
240 (iev_resolver = malloc(sizeof(struct imsgev))) == NULL)
241 fatal(NULL);
242 if (imsgbuf_init(&iev_frontend->ibuf, pipe_main2frontend[0]) == -1)
243 fatal(NULL);
244 imsgbuf_allow_fdpass(&iev_frontend->ibuf);
245 iev_frontend->handler = main_dispatch_frontend;
246 if (imsgbuf_init(&iev_resolver->ibuf, pipe_main2resolver[0]) == -1)
247 fatal(NULL);
248 imsgbuf_allow_fdpass(&iev_resolver->ibuf);
249 iev_resolver->handler = main_dispatch_resolver;
250
251 /* Setup event handlers for pipes. */
252 iev_frontend->events = EV_READ;
253 event_set(&iev_frontend->ev, iev_frontend->ibuf.fd,
254 iev_frontend->events, iev_frontend->handler, iev_frontend);
255 event_add(&iev_frontend->ev, NULL);
256
257 iev_resolver->events = EV_READ;
258 event_set(&iev_resolver->ev, iev_resolver->ibuf.fd,
259 iev_resolver->events, iev_resolver->handler, iev_resolver);
260 event_add(&iev_resolver->ev, NULL);
261
262 if (main_imsg_send_ipc_sockets(&iev_frontend->ibuf,
263 &iev_resolver->ibuf))
264 fatal("could not establish imsg links");
265
266 open_ports();
267
268 if ((control_fd = control_init(csock)) == -1)
269 fatalx("control socket setup failed");
270
271 if ((frontend_routesock = socket(AF_ROUTE, SOCK_RAW | SOCK_CLOEXEC |
272 SOCK_NONBLOCK, 0)) == -1)
273 fatal("route socket");
274
275 rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_PROPOSAL)
276 | ROUTE_FILTER(RTM_IFANNOUNCE) | ROUTE_FILTER(RTM_NEWADDR)
277 | ROUTE_FILTER(RTM_DELADDR);
278 if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_MSGFILTER,
279 &rtfilter, sizeof(rtfilter)) == -1)
280 fatal("setsockopt(ROUTE_MSGFILTER)");
281
282 if ((routesock = socket(AF_ROUTE, SOCK_RAW | SOCK_CLOEXEC |
283 SOCK_NONBLOCK, 0)) == -1)
284 fatal("route socket");
285 shutdown(routesock, SHUT_RD);
286
287 if ((ta_fd = open(TRUST_ANCHOR_FILE, O_RDWR | O_CREAT, 0644)) == -1)
288 log_warn("%s", TRUST_ANCHOR_FILE);
289
290 /* receiver handles failed open correctly */
291 main_imsg_compose_frontend_fd(IMSG_TAFD, 0, ta_fd);
292
293 main_imsg_compose_frontend_fd(IMSG_CONTROLFD, 0, control_fd);
294 main_imsg_compose_frontend_fd(IMSG_ROUTESOCK, 0, frontend_routesock);
295 main_imsg_send_config(main_conf);
296
297 if (main_conf->blocklist_file != NULL)
298 send_blocklist_fd();
299
300 if (pledge("stdio rpath sendfd", NULL) == -1)
301 fatal("pledge");
302
303 main_imsg_compose_frontend(IMSG_STARTUP, 0, NULL, 0);
304 main_imsg_compose_resolver(IMSG_STARTUP, 0, NULL, 0);
305
306 event_dispatch();
307
308 main_shutdown();
309 return (0);
310 }
311
312 __dead void
main_shutdown(void)313 main_shutdown(void)
314 {
315 pid_t pid;
316 int status;
317
318 /* Close pipes. */
319 imsgbuf_clear(&iev_frontend->ibuf);
320 close(iev_frontend->ibuf.fd);
321 imsgbuf_clear(&iev_resolver->ibuf);
322 close(iev_resolver->ibuf.fd);
323
324 config_clear(main_conf);
325
326 log_debug("waiting for children to terminate");
327 do {
328 pid = wait(&status);
329 if (pid == -1) {
330 if (errno != EINTR && errno != ECHILD)
331 fatal("wait");
332 } else if (WIFSIGNALED(status))
333 log_warnx("%s terminated; signal %d",
334 (pid == resolver_pid) ? "resolver" :
335 "frontend", WTERMSIG(status));
336 } while (pid != -1 || (pid == -1 && errno == EINTR));
337
338 free(iev_frontend);
339 free(iev_resolver);
340
341 log_info("terminating");
342 exit(0);
343 }
344
345 static pid_t
start_child(enum uw_process p,char * argv0,int fd,int debug,int verbose)346 start_child(enum uw_process p, char *argv0, int fd, int debug, int verbose)
347 {
348 char *argv[7];
349 int argc = 0;
350 pid_t pid;
351
352 switch (pid = fork()) {
353 case -1:
354 fatal("cannot fork");
355 case 0:
356 break;
357 default:
358 close(fd);
359 return (pid);
360 }
361
362 if (fd != 3) {
363 if (dup2(fd, 3) == -1)
364 fatal("cannot setup imsg fd");
365 } else if (fcntl(fd, F_SETFD, 0) == -1)
366 fatal("cannot setup imsg fd");
367
368 argv[argc++] = argv0;
369 switch (p) {
370 case PROC_MAIN:
371 fatalx("Can not start main process");
372 case PROC_RESOLVER:
373 argv[argc++] = "-E";
374 break;
375 case PROC_FRONTEND:
376 argv[argc++] = "-F";
377 break;
378 }
379 if (debug)
380 argv[argc++] = "-d";
381 if (verbose & OPT_VERBOSE)
382 argv[argc++] = "-v";
383 if (verbose & OPT_VERBOSE2)
384 argv[argc++] = "-v";
385 if (verbose & OPT_VERBOSE3)
386 argv[argc++] = "-v";
387 argv[argc++] = NULL;
388
389 execvp(argv0, argv);
390 fatal("execvp");
391 }
392
393 void
main_dispatch_frontend(int fd,short event,void * bula)394 main_dispatch_frontend(int fd, short event, void *bula)
395 {
396 struct imsgev *iev = bula;
397 struct imsgbuf *ibuf;
398 struct imsg imsg;
399 ssize_t n;
400 int shut = 0, verbose;
401
402 ibuf = &iev->ibuf;
403
404 if (event & EV_READ) {
405 if ((n = imsgbuf_read(ibuf)) == -1)
406 fatal("imsgbuf_read error");
407 if (n == 0) /* Connection closed. */
408 shut = 1;
409 }
410 if (event & EV_WRITE) {
411 if (imsgbuf_write(ibuf) == -1) {
412 if (errno == EPIPE) /* Connection closed. */
413 shut = 1;
414 else
415 fatal("imsgbuf_write");
416 }
417 }
418
419 for (;;) {
420 if ((n = imsg_get(ibuf, &imsg)) == -1)
421 fatal("imsg_get");
422 if (n == 0) /* No more messages. */
423 break;
424
425 switch (imsg.hdr.type) {
426 case IMSG_STARTUP_DONE:
427 solicit_dns_proposals();
428 break;
429 case IMSG_CTL_RELOAD:
430 if (main_reload() == -1)
431 log_warnx("configuration reload failed");
432 else
433 log_warnx("configuration reloaded");
434 break;
435 case IMSG_CTL_LOG_VERBOSE:
436 if (IMSG_DATA_SIZE(imsg) != sizeof(verbose))
437 fatalx("%s: IMSG_CTL_LOG_VERBOSE wrong length: "
438 "%lu", __func__, IMSG_DATA_SIZE(imsg));
439 memcpy(&verbose, imsg.data, sizeof(verbose));
440 log_setverbose(verbose);
441 break;
442 default:
443 log_debug("%s: error handling imsg %d", __func__,
444 imsg.hdr.type);
445 break;
446 }
447 imsg_free(&imsg);
448 }
449 if (!shut)
450 imsg_event_add(iev);
451 else {
452 /* This pipe is dead. Remove its event handler */
453 event_del(&iev->ev);
454 event_loopexit(NULL);
455 }
456 }
457
458 void
main_dispatch_resolver(int fd,short event,void * bula)459 main_dispatch_resolver(int fd, short event, void *bula)
460 {
461 struct imsgev *iev = bula;
462 struct imsgbuf *ibuf;
463 struct imsg imsg;
464 ssize_t n;
465 int shut = 0;
466
467 ibuf = &iev->ibuf;
468
469 if (event & EV_READ) {
470 if ((n = imsgbuf_read(ibuf)) == -1)
471 fatal("imsgbuf_read error");
472 if (n == 0) /* Connection closed. */
473 shut = 1;
474 }
475 if (event & EV_WRITE) {
476 if (imsgbuf_write(ibuf) == -1) {
477 if (errno == EPIPE) /* Connection closed. */
478 shut = 1;
479 else
480 fatal("imsgbuf_write");
481 }
482 }
483
484 for (;;) {
485 if ((n = imsg_get(ibuf, &imsg)) == -1)
486 fatal("imsg_get");
487 if (n == 0) /* No more messages. */
488 break;
489
490 switch (imsg.hdr.type) {
491 default:
492 log_debug("%s: error handling imsg %d", __func__,
493 imsg.hdr.type);
494 break;
495 }
496 imsg_free(&imsg);
497 }
498 if (!shut)
499 imsg_event_add(iev);
500 else {
501 /* This pipe is dead. Remove its event handler. */
502 event_del(&iev->ev);
503 event_loopexit(NULL);
504 }
505 }
506
507 void
main_imsg_compose_frontend(int type,pid_t pid,void * data,uint16_t datalen)508 main_imsg_compose_frontend(int type, pid_t pid, void *data, uint16_t datalen)
509 {
510 if (iev_frontend)
511 imsg_compose_event(iev_frontend, type, 0, pid, -1, data,
512 datalen);
513 }
514
515 void
main_imsg_compose_frontend_fd(int type,pid_t pid,int fd)516 main_imsg_compose_frontend_fd(int type, pid_t pid, int fd)
517 {
518 if (iev_frontend)
519 imsg_compose_event(iev_frontend, type, 0, pid, fd, NULL, 0);
520 }
521
522 void
main_imsg_compose_resolver(int type,pid_t pid,void * data,uint16_t datalen)523 main_imsg_compose_resolver(int type, pid_t pid, void *data, uint16_t datalen)
524 {
525 if (iev_resolver)
526 imsg_compose_event(iev_resolver, type, 0, pid, -1, data,
527 datalen);
528 }
529
530 void
imsg_event_add(struct imsgev * iev)531 imsg_event_add(struct imsgev *iev)
532 {
533 iev->events = EV_READ;
534 if (imsgbuf_queuelen(&iev->ibuf) > 0)
535 iev->events |= EV_WRITE;
536
537 event_del(&iev->ev);
538 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
539 event_add(&iev->ev, NULL);
540 }
541
542 int
imsg_compose_event(struct imsgev * iev,uint16_t type,uint32_t peerid,pid_t pid,int fd,void * data,uint16_t datalen)543 imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
544 pid_t pid, int fd, void *data, uint16_t datalen)
545 {
546 int ret;
547
548 if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data,
549 datalen)) != -1)
550 imsg_event_add(iev);
551
552 return (ret);
553 }
554
555 static int
main_imsg_send_ipc_sockets(struct imsgbuf * frontend_buf,struct imsgbuf * resolver_buf)556 main_imsg_send_ipc_sockets(struct imsgbuf *frontend_buf,
557 struct imsgbuf *resolver_buf)
558 {
559 int pipe_frontend2resolver[2];
560
561 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
562 PF_UNSPEC, pipe_frontend2resolver) == -1)
563 return (-1);
564
565 if (imsg_compose(frontend_buf, IMSG_SOCKET_IPC_RESOLVER, 0, 0,
566 pipe_frontend2resolver[0], NULL, 0) == -1)
567 return (-1);
568 if (imsg_compose(resolver_buf, IMSG_SOCKET_IPC_FRONTEND, 0, 0,
569 pipe_frontend2resolver[1], NULL, 0) == -1)
570 return (-1);
571
572 return (0);
573 }
574
575 int
main_reload(void)576 main_reload(void)
577 {
578 struct uw_conf *xconf;
579
580 if ((xconf = parse_config(conffile)) == NULL)
581 return (-1);
582
583 if (main_imsg_send_config(xconf) == -1)
584 return (-1);
585
586 merge_config(main_conf, xconf);
587
588 if (main_conf->blocklist_file != NULL)
589 send_blocklist_fd();
590
591 return (0);
592 }
593
594 int
main_imsg_send_config(struct uw_conf * xconf)595 main_imsg_send_config(struct uw_conf *xconf)
596 {
597 struct uw_forwarder *uw_forwarder;
598 struct force_tree_entry *force_entry;
599
600 /* Send fixed part of config to children. */
601 if (main_sendall(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
602 return (-1);
603
604 if (xconf->blocklist_file != NULL) {
605 if (main_sendall(IMSG_RECONF_BLOCKLIST_FILE,
606 xconf->blocklist_file, strlen(xconf->blocklist_file) + 1)
607 == -1)
608 return (-1);
609 }
610
611 /* send static forwarders to children */
612 TAILQ_FOREACH(uw_forwarder, &xconf->uw_forwarder_list, entry) {
613 if (main_sendall(IMSG_RECONF_FORWARDER, uw_forwarder,
614 sizeof(*uw_forwarder)) == -1)
615 return (-1);
616 }
617
618 /* send static DoT forwarders to children */
619 TAILQ_FOREACH(uw_forwarder, &xconf->uw_dot_forwarder_list,
620 entry) {
621 if (main_sendall(IMSG_RECONF_DOT_FORWARDER, uw_forwarder,
622 sizeof(*uw_forwarder)) == -1)
623 return (-1);
624 }
625 RB_FOREACH(force_entry, force_tree, &xconf->force) {
626 if (main_sendall(IMSG_RECONF_FORCE, force_entry,
627 sizeof(*force_entry)) == -1)
628 return (-1);
629 }
630
631 /* Tell children the revised config is now complete. */
632 if (main_sendall(IMSG_RECONF_END, NULL, 0) == -1)
633 return (-1);
634
635 return (0);
636 }
637
638 int
main_sendall(enum imsg_type type,void * buf,uint16_t len)639 main_sendall(enum imsg_type type, void *buf, uint16_t len)
640 {
641 if (imsg_compose_event(iev_frontend, type, 0, 0, -1, buf, len) == -1)
642 return (-1);
643 if (imsg_compose_event(iev_resolver, type, 0, 0, -1, buf, len) == -1)
644 return (-1);
645 return (0);
646 }
647
648 void
merge_config(struct uw_conf * conf,struct uw_conf * xconf)649 merge_config(struct uw_conf *conf, struct uw_conf *xconf)
650 {
651 struct uw_forwarder *uw_forwarder;
652 struct force_tree_entry *n, *nxt;
653
654 /* Remove & discard existing forwarders. */
655 while ((uw_forwarder = TAILQ_FIRST(&conf->uw_forwarder_list)) !=
656 NULL) {
657 TAILQ_REMOVE(&conf->uw_forwarder_list, uw_forwarder, entry);
658 free(uw_forwarder);
659 }
660 while ((uw_forwarder = TAILQ_FIRST(&conf->uw_dot_forwarder_list)) !=
661 NULL) {
662 TAILQ_REMOVE(&conf->uw_dot_forwarder_list, uw_forwarder, entry);
663 free(uw_forwarder);
664 }
665
666 /* Remove & discard existing force tree. */
667 RB_FOREACH_SAFE(n, force_tree, &conf->force, nxt) {
668 RB_REMOVE(force_tree, &conf->force, n);
669 free(n);
670 }
671
672 memcpy(&conf->enabled_resolvers, &xconf->enabled_resolvers,
673 sizeof(conf->enabled_resolvers));
674
675 memcpy(&conf->res_pref, &xconf->res_pref,
676 sizeof(conf->res_pref));
677
678 free(conf->blocklist_file);
679 conf->blocklist_file = xconf->blocklist_file;
680 conf->blocklist_log = xconf->blocklist_log;
681
682 /* Add new forwarders. */
683 TAILQ_CONCAT(&conf->uw_forwarder_list, &xconf->uw_forwarder_list,
684 entry);
685 TAILQ_CONCAT(&conf->uw_dot_forwarder_list,
686 &xconf->uw_dot_forwarder_list, entry);
687
688 RB_FOREACH_SAFE(n, force_tree, &xconf->force, nxt) {
689 RB_REMOVE(force_tree, &xconf->force, n);
690 RB_INSERT(force_tree, &conf->force, n);
691 }
692
693 free(xconf);
694 }
695
696 struct uw_conf *
config_new_empty(void)697 config_new_empty(void)
698 {
699 struct uw_conf *xconf;
700
701 xconf = calloc(1, sizeof(*xconf));
702 if (xconf == NULL)
703 fatal(NULL);
704
705 TAILQ_INIT(&xconf->uw_forwarder_list);
706 TAILQ_INIT(&xconf->uw_dot_forwarder_list);
707
708 RB_INIT(&xconf->force);
709
710 return (xconf);
711 }
712
713 void
config_clear(struct uw_conf * conf)714 config_clear(struct uw_conf *conf)
715 {
716 struct uw_conf *xconf;
717
718 /* Merge current config with an empty config. */
719 xconf = config_new_empty();
720 merge_config(conf, xconf);
721
722 free(conf);
723 }
724
725 void
open_ports(void)726 open_ports(void)
727 {
728 struct addrinfo hints, *res0;
729 int udp4sock = -1, udp6sock = -1, error, bsize = 65535;
730 int tcp4sock = -1, tcp6sock = -1;
731 int opt = 1;
732
733 memset(&hints, 0, sizeof(hints));
734 hints.ai_family = AF_INET;
735 hints.ai_socktype = SOCK_DGRAM;
736 hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
737
738 error = getaddrinfo("127.0.0.1", "domain", &hints, &res0);
739 if (!error && res0) {
740 if ((udp4sock = socket(res0->ai_family, res0->ai_socktype,
741 res0->ai_protocol)) != -1) {
742 if (setsockopt(udp4sock, SOL_SOCKET, SO_REUSEADDR,
743 &opt, sizeof(opt)) == -1)
744 log_warn("setting SO_REUSEADDR on socket");
745 if (setsockopt(udp4sock, SOL_SOCKET, SO_SNDBUF, &bsize,
746 sizeof(bsize)) == -1)
747 log_warn("setting SO_SNDBUF on socket");
748 if (bind(udp4sock, res0->ai_addr, res0->ai_addrlen)
749 == -1) {
750 close(udp4sock);
751 udp4sock = -1;
752 }
753 }
754 }
755 if (res0)
756 freeaddrinfo(res0);
757
758 hints.ai_family = AF_INET6;
759 error = getaddrinfo("::1", "domain", &hints, &res0);
760 if (!error && res0) {
761 if ((udp6sock = socket(res0->ai_family, res0->ai_socktype,
762 res0->ai_protocol)) != -1) {
763 if (setsockopt(udp6sock, SOL_SOCKET, SO_REUSEADDR,
764 &opt, sizeof(opt)) == -1)
765 log_warn("setting SO_REUSEADDR on socket");
766 if (setsockopt(udp6sock, SOL_SOCKET, SO_SNDBUF, &bsize,
767 sizeof(bsize)) == -1)
768 log_warn("setting SO_SNDBUF on socket");
769 if (bind(udp6sock, res0->ai_addr, res0->ai_addrlen)
770 == -1) {
771 close(udp6sock);
772 udp6sock = -1;
773 }
774 }
775 }
776 if (res0)
777 freeaddrinfo(res0);
778
779 hints.ai_family = AF_INET;
780 hints.ai_socktype = SOCK_STREAM;
781
782 error = getaddrinfo("127.0.0.1", "domain", &hints, &res0);
783 if (!error && res0) {
784 if ((tcp4sock = socket(res0->ai_family,
785 res0->ai_socktype | SOCK_NONBLOCK,
786 res0->ai_protocol)) != -1) {
787 if (setsockopt(tcp4sock, SOL_SOCKET, SO_REUSEADDR,
788 &opt, sizeof(opt)) == -1)
789 log_warn("setting SO_REUSEADDR on socket");
790 if (setsockopt(tcp4sock, SOL_SOCKET, SO_SNDBUF, &bsize,
791 sizeof(bsize)) == -1)
792 log_warn("setting SO_SNDBUF on socket");
793 if (bind(tcp4sock, res0->ai_addr, res0->ai_addrlen)
794 == -1) {
795 close(tcp4sock);
796 tcp4sock = -1;
797 }
798 if (listen(tcp4sock, 5) == -1) {
799 close(tcp4sock);
800 tcp4sock = -1;
801 }
802 }
803 }
804 if (res0)
805 freeaddrinfo(res0);
806
807 hints.ai_family = AF_INET6;
808 error = getaddrinfo("::1", "domain", &hints, &res0);
809 if (!error && res0) {
810 if ((tcp6sock = socket(res0->ai_family,
811 res0->ai_socktype | SOCK_NONBLOCK,
812 res0->ai_protocol)) != -1) {
813 if (setsockopt(tcp6sock, SOL_SOCKET, SO_REUSEADDR,
814 &opt, sizeof(opt)) == -1)
815 log_warn("setting SO_REUSEADDR on socket");
816 if (setsockopt(tcp6sock, SOL_SOCKET, SO_SNDBUF, &bsize,
817 sizeof(bsize)) == -1)
818 log_warn("setting SO_SNDBUF on socket");
819 if (bind(tcp6sock, res0->ai_addr, res0->ai_addrlen)
820 == -1) {
821 close(tcp6sock);
822 tcp6sock = -1;
823 }
824 if (listen(tcp6sock, 5) == -1) {
825 close(tcp6sock);
826 tcp6sock = -1;
827 }
828 }
829 }
830 if (res0)
831 freeaddrinfo(res0);
832
833 if ((udp4sock == -1 || tcp4sock == -1) && (udp6sock == -1 ||
834 tcp6sock == -1))
835 fatalx("could not bind to 127.0.0.1 or ::1 on port 53");
836
837 if (udp4sock != -1)
838 main_imsg_compose_frontend_fd(IMSG_UDP4SOCK, 0, udp4sock);
839 if (udp6sock != -1)
840 main_imsg_compose_frontend_fd(IMSG_UDP6SOCK, 0, udp6sock);
841 if (tcp4sock != -1)
842 main_imsg_compose_frontend_fd(IMSG_TCP4SOCK, 0, tcp4sock);
843 if (tcp6sock != -1)
844 main_imsg_compose_frontend_fd(IMSG_TCP6SOCK, 0, tcp6sock);
845 }
846
847 void
solicit_dns_proposals(void)848 solicit_dns_proposals(void)
849 {
850 struct rt_msghdr rtm;
851 struct iovec iov[1];
852 int iovcnt = 0;
853
854 memset(&rtm, 0, sizeof(rtm));
855
856 rtm.rtm_version = RTM_VERSION;
857 rtm.rtm_type = RTM_PROPOSAL;
858 rtm.rtm_msglen = sizeof(rtm);
859 rtm.rtm_tableid = 0;
860 rtm.rtm_index = 0;
861 rtm.rtm_seq = arc4random();
862 rtm.rtm_priority = RTP_PROPOSAL_SOLICIT;
863
864 iov[iovcnt].iov_base = &rtm;
865 iov[iovcnt++].iov_len = sizeof(rtm);
866
867 if (writev(routesock, iov, iovcnt) == -1)
868 log_warn("failed to send solicitation");
869 }
870
871 void
send_blocklist_fd(void)872 send_blocklist_fd(void)
873 {
874 int bl_fd;
875
876 if ((bl_fd = open(main_conf->blocklist_file, O_RDONLY)) != -1)
877 main_imsg_compose_frontend_fd(IMSG_BLFD, 0, bl_fd);
878 else
879 log_warn("%s", main_conf->blocklist_file);
880 }
881
882 void
imsg_receive_config(struct imsg * imsg,struct uw_conf ** xconf)883 imsg_receive_config(struct imsg *imsg, struct uw_conf **xconf)
884 {
885 struct uw_conf *nconf;
886 struct uw_forwarder *uw_forwarder;
887 struct force_tree_entry *force_entry;
888
889 nconf = *xconf;
890
891 switch (imsg->hdr.type) {
892 case IMSG_RECONF_CONF:
893 if (nconf != NULL)
894 fatalx("%s: IMSG_RECONF_CONF already in "
895 "progress", __func__);
896 if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_conf))
897 fatalx("%s: IMSG_RECONF_CONF wrong length: %lu",
898 __func__, IMSG_DATA_SIZE(*imsg));
899 if ((*xconf = malloc(sizeof(struct uw_conf))) == NULL)
900 fatal(NULL);
901 nconf = *xconf;
902 memcpy(nconf, imsg->data, sizeof(struct uw_conf));
903 TAILQ_INIT(&nconf->uw_forwarder_list);
904 TAILQ_INIT(&nconf->uw_dot_forwarder_list);
905 RB_INIT(&nconf->force);
906 break;
907 case IMSG_RECONF_BLOCKLIST_FILE:
908 if (((char *)imsg->data)[IMSG_DATA_SIZE(*imsg) - 1] != '\0')
909 fatalx("Invalid blocklist file");
910 if ((nconf->blocklist_file = strdup(imsg->data)) ==
911 NULL)
912 fatal("%s: strdup", __func__);
913 break;
914 case IMSG_RECONF_FORWARDER:
915 if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_forwarder))
916 fatalx("%s: IMSG_RECONF_FORWARDER wrong length:"
917 " %lu", __func__, IMSG_DATA_SIZE(*imsg));
918 if ((uw_forwarder = malloc(sizeof(struct
919 uw_forwarder))) == NULL)
920 fatal(NULL);
921 memcpy(uw_forwarder, imsg->data, sizeof(struct
922 uw_forwarder));
923 TAILQ_INSERT_TAIL(&nconf->uw_forwarder_list,
924 uw_forwarder, entry);
925 break;
926 case IMSG_RECONF_DOT_FORWARDER:
927 if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_forwarder))
928 fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong "
929 "length: %lu", __func__,
930 IMSG_DATA_SIZE(*imsg));
931 if ((uw_forwarder = malloc(sizeof(struct
932 uw_forwarder))) == NULL)
933 fatal(NULL);
934 memcpy(uw_forwarder, imsg->data, sizeof(struct
935 uw_forwarder));
936 TAILQ_INSERT_TAIL(&nconf->uw_dot_forwarder_list,
937 uw_forwarder, entry);
938 break;
939 case IMSG_RECONF_FORCE:
940 if (IMSG_DATA_SIZE(*imsg) != sizeof(struct force_tree_entry))
941 fatalx("%s: IMSG_RECONF_FORCE wrong "
942 "length: %lu", __func__,
943 IMSG_DATA_SIZE(*imsg));
944 if ((force_entry = malloc(sizeof(struct
945 force_tree_entry))) == NULL)
946 fatal(NULL);
947 memcpy(force_entry, imsg->data, sizeof(struct
948 force_tree_entry));
949 if (RB_INSERT(force_tree, &nconf->force, force_entry) != NULL) {
950 free(force_entry);
951 fatalx("%s: IMSG_RECONF_FORCE duplicate entry",
952 __func__);
953 }
954 break;
955 default:
956 log_debug("%s: error handling imsg %d", __func__,
957 imsg->hdr.type);
958 break;
959 }
960 }
961