xref: /openbsd-src/sbin/unwind/unwind.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: unwind.c,v 1.46 2019/12/20 08:30:27 florian 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 __dead void	usage(void);
54 __dead void	main_shutdown(void);
55 
56 void		main_sig_handler(int, short, void *);
57 
58 static pid_t	start_child(int, char *, int, int, int);
59 
60 void		main_dispatch_frontend(int, short, void *);
61 void		main_dispatch_resolver(int, short, void *);
62 
63 static int	main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
64 static int	main_imsg_send_config(struct uw_conf *);
65 
66 int		main_reload(void);
67 int		main_sendall(enum imsg_type, void *, uint16_t);
68 void		open_ports(void);
69 void		solicit_dns_proposals(void);
70 void		send_blocklist_fd(void);
71 
72 struct uw_conf	*main_conf;
73 struct imsgev	*iev_frontend;
74 struct imsgev	*iev_resolver;
75 char		*conffile;
76 
77 pid_t		 frontend_pid;
78 pid_t		 resolver_pid;
79 
80 uint32_t	 cmd_opts;
81 
82 int		 routesock;
83 
84 void
85 main_sig_handler(int sig, short event, void *arg)
86 {
87 	/*
88 	 * Normal signal handler rules don't apply because libevent
89 	 * decouples for us.
90 	 */
91 
92 	switch (sig) {
93 	case SIGTERM:
94 	case SIGINT:
95 		main_shutdown();
96 		break;
97 	case SIGHUP:
98 		if (main_reload() == -1)
99 			log_warnx("configuration reload failed");
100 		else
101 			log_debug("configuration reloaded");
102 		break;
103 	default:
104 		fatalx("unexpected signal");
105 	}
106 }
107 
108 __dead void
109 usage(void)
110 {
111 	extern char *__progname;
112 
113 	fprintf(stderr, "usage: %s [-dnv] [-f file] [-s socket]\n",
114 	    __progname);
115 	exit(1);
116 }
117 
118 int
119 main(int argc, char *argv[])
120 {
121 	struct event	 ev_sigint, ev_sigterm, ev_sighup;
122 	int		 ch, debug = 0, resolver_flag = 0, frontend_flag = 0;
123 	int		 frontend_routesock, rtfilter;
124 	int		 pipe_main2frontend[2], pipe_main2resolver[2];
125 	int		 control_fd, ta_fd;
126 	char		*csock, *saved_argv0;
127 
128 	csock = UNWIND_SOCKET;
129 
130 	log_init(1, LOG_DAEMON);	/* Log to stderr until daemonized. */
131 	log_setverbose(1);
132 
133 	saved_argv0 = argv[0];
134 	if (saved_argv0 == NULL)
135 		saved_argv0 = "unwind";
136 
137 	while ((ch = getopt(argc, argv, "dEFf:ns:v")) != -1) {
138 		switch (ch) {
139 		case 'd':
140 			debug = 1;
141 			break;
142 		case 'E':
143 			resolver_flag = 1;
144 			break;
145 		case 'F':
146 			frontend_flag = 1;
147 			break;
148 		case 'f':
149 			conffile = optarg;
150 			break;
151 		case 'n':
152 			cmd_opts |= OPT_NOACTION;
153 			break;
154 		case 's':
155 			csock = optarg;
156 			break;
157 		case 'v':
158 			if (cmd_opts & OPT_VERBOSE2)
159 				cmd_opts |= OPT_VERBOSE3;
160 			if (cmd_opts & OPT_VERBOSE)
161 				cmd_opts |= OPT_VERBOSE2;
162 			cmd_opts |= OPT_VERBOSE;
163 			break;
164 		default:
165 			usage();
166 		}
167 	}
168 
169 	argc -= optind;
170 	argv += optind;
171 	if (argc > 0 || (resolver_flag && frontend_flag))
172 		usage();
173 
174 	if (resolver_flag)
175 		resolver(debug, cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 |
176 		    OPT_VERBOSE3));
177 	else if (frontend_flag)
178 		frontend(debug, cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 |
179 		    OPT_VERBOSE3));
180 
181 	if ((main_conf = parse_config(conffile)) == NULL)
182 		exit(1);
183 
184 	if (cmd_opts & OPT_NOACTION) {
185 		if (cmd_opts & OPT_VERBOSE)
186 			print_config(main_conf);
187 		else
188 			fprintf(stderr, "configuration OK\n");
189 		exit(0);
190 	}
191 
192 	/* Check for root privileges. */
193 	if (geteuid())
194 		errx(1, "need root privileges");
195 
196 	/* Check for assigned daemon user */
197 	if (getpwnam(UNWIND_USER) == NULL)
198 		errx(1, "unknown user %s", UNWIND_USER);
199 
200 	log_init(debug, LOG_DAEMON);
201 	log_setverbose(cmd_opts & (OPT_VERBOSE | OPT_VERBOSE2 | OPT_VERBOSE3));
202 
203 	if (!debug)
204 		daemon(1, 0);
205 
206 	log_info("startup");
207 
208 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
209 	    PF_UNSPEC, pipe_main2frontend) == -1)
210 		fatal("main2frontend socketpair");
211 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
212 	    PF_UNSPEC, pipe_main2resolver) == -1)
213 		fatal("main2resolver socketpair");
214 
215 	/* Start children. */
216 	resolver_pid = start_child(PROC_RESOLVER, saved_argv0,
217 	    pipe_main2resolver[1], debug, cmd_opts & (OPT_VERBOSE |
218 	    OPT_VERBOSE2 | OPT_VERBOSE3));
219 	frontend_pid = start_child(PROC_FRONTEND, saved_argv0,
220 	    pipe_main2frontend[1], debug, cmd_opts & (OPT_VERBOSE |
221 	    OPT_VERBOSE2 | OPT_VERBOSE3));
222 
223 	uw_process = PROC_MAIN;
224 	log_procinit(log_procnames[uw_process]);
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 	imsg_init(&iev_frontend->ibuf, pipe_main2frontend[0]);
243 	iev_frontend->handler = main_dispatch_frontend;
244 	imsg_init(&iev_resolver->ibuf, pipe_main2resolver[0]);
245 	iev_resolver->handler = main_dispatch_resolver;
246 
247 	/* Setup event handlers for pipes. */
248 	iev_frontend->events = EV_READ;
249 	event_set(&iev_frontend->ev, iev_frontend->ibuf.fd,
250 	    iev_frontend->events, iev_frontend->handler, iev_frontend);
251 	event_add(&iev_frontend->ev, NULL);
252 
253 	iev_resolver->events = EV_READ;
254 	event_set(&iev_resolver->ev, iev_resolver->ibuf.fd,
255 	    iev_resolver->events, iev_resolver->handler, iev_resolver);
256 	event_add(&iev_resolver->ev, NULL);
257 
258 	if (main_imsg_send_ipc_sockets(&iev_frontend->ibuf,
259 	    &iev_resolver->ibuf))
260 		fatal("could not establish imsg links");
261 
262 	open_ports();
263 
264 	if ((control_fd = control_init(csock)) == -1)
265 		fatalx("control socket setup failed");
266 
267 	if ((frontend_routesock = socket(AF_ROUTE, SOCK_RAW | SOCK_CLOEXEC,
268 	    AF_INET)) == -1)
269 		fatal("route socket");
270 
271 	rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_PROPOSAL);
272 	if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_MSGFILTER,
273 	    &rtfilter, sizeof(rtfilter)) == -1)
274 		fatal("setsockopt(ROUTE_MSGFILTER)");
275 
276 	if ((routesock = socket(AF_ROUTE, SOCK_RAW | SOCK_CLOEXEC |
277 	    SOCK_NONBLOCK, AF_INET6)) == -1)
278 		fatal("route socket");
279 	shutdown(SHUT_RD, routesock);
280 
281 	if ((ta_fd = open(TRUST_ANCHOR_FILE, O_RDWR | O_CREAT, 0644)) == -1)
282 		log_warn("%s", TRUST_ANCHOR_FILE);
283 
284 	/* receiver handles failed open correctly */
285 	main_imsg_compose_frontend_fd(IMSG_TAFD, 0, ta_fd);
286 
287 	main_imsg_compose_frontend_fd(IMSG_CONTROLFD, 0, control_fd);
288 	main_imsg_compose_frontend_fd(IMSG_ROUTESOCK, 0, frontend_routesock);
289 	main_imsg_send_config(main_conf);
290 
291 	if (main_conf->blocklist_file != NULL)
292 		send_blocklist_fd();
293 
294 	if (pledge("stdio rpath sendfd", NULL) == -1)
295 		fatal("pledge");
296 
297 	main_imsg_compose_frontend(IMSG_STARTUP, 0, NULL, 0);
298 	main_imsg_compose_resolver(IMSG_STARTUP, 0, NULL, 0);
299 
300 	event_dispatch();
301 
302 	main_shutdown();
303 	return (0);
304 }
305 
306 __dead void
307 main_shutdown(void)
308 {
309 	pid_t	 pid;
310 	int	 status;
311 
312 	/* Close pipes. */
313 	msgbuf_clear(&iev_frontend->ibuf.w);
314 	close(iev_frontend->ibuf.fd);
315 	msgbuf_clear(&iev_resolver->ibuf.w);
316 	close(iev_resolver->ibuf.fd);
317 
318 	config_clear(main_conf);
319 
320 	log_debug("waiting for children to terminate");
321 	do {
322 		pid = wait(&status);
323 		if (pid == -1) {
324 			if (errno != EINTR && errno != ECHILD)
325 				fatal("wait");
326 		} else if (WIFSIGNALED(status))
327 			log_warnx("%s terminated; signal %d",
328 			    (pid == resolver_pid) ? "resolver" :
329 			    "frontend", WTERMSIG(status));
330 	} while (pid != -1 || (pid == -1 && errno == EINTR));
331 
332 	free(iev_frontend);
333 	free(iev_resolver);
334 
335 	log_info("terminating");
336 	exit(0);
337 }
338 
339 static pid_t
340 start_child(int p, char *argv0, int fd, int debug, int verbose)
341 {
342 	char	*argv[7];
343 	int	 argc = 0;
344 	pid_t	 pid;
345 
346 	switch (pid = fork()) {
347 	case -1:
348 		fatal("cannot fork");
349 	case 0:
350 		break;
351 	default:
352 		close(fd);
353 		return (pid);
354 	}
355 
356 	if (fd != 3) {
357 		if (dup2(fd, 3) == -1)
358 			fatal("cannot setup imsg fd");
359 	} else if (fcntl(fd, F_SETFD, 0) == -1)
360 		fatal("cannot setup imsg fd");
361 
362 	argv[argc++] = argv0;
363 	switch (p) {
364 	case PROC_MAIN:
365 		fatalx("Can not start main process");
366 	case PROC_RESOLVER:
367 		argv[argc++] = "-E";
368 		break;
369 	case PROC_FRONTEND:
370 		argv[argc++] = "-F";
371 		break;
372 	}
373 	if (debug)
374 		argv[argc++] = "-d";
375 	if (verbose & OPT_VERBOSE)
376 		argv[argc++] = "-v";
377 	if (verbose & OPT_VERBOSE2)
378 		argv[argc++] = "-v";
379 	if (verbose & OPT_VERBOSE3)
380 		argv[argc++] = "-v";
381 	argv[argc++] = NULL;
382 
383 	execvp(argv0, argv);
384 	fatal("execvp");
385 }
386 
387 void
388 main_dispatch_frontend(int fd, short event, void *bula)
389 {
390 	struct imsgev	*iev = bula;
391 	struct imsgbuf	*ibuf;
392 	struct imsg	 imsg;
393 	ssize_t		 n;
394 	int		 shut = 0, verbose;
395 
396 	ibuf = &iev->ibuf;
397 
398 	if (event & EV_READ) {
399 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
400 			fatal("imsg_read error");
401 		if (n == 0)	/* Connection closed. */
402 			shut = 1;
403 	}
404 	if (event & EV_WRITE) {
405 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
406 			fatal("msgbuf_write");
407 		if (n == 0)	/* Connection closed. */
408 			shut = 1;
409 	}
410 
411 	for (;;) {
412 		if ((n = imsg_get(ibuf, &imsg)) == -1)
413 			fatal("imsg_get");
414 		if (n == 0)	/* No more messages. */
415 			break;
416 
417 		switch (imsg.hdr.type) {
418 		case IMSG_STARTUP_DONE:
419 			solicit_dns_proposals();
420 			break;
421 		case IMSG_CTL_RELOAD:
422 			if (main_reload() == -1)
423 				log_warnx("configuration reload failed");
424 			else
425 				log_warnx("configuration reloaded");
426 			break;
427 		case IMSG_CTL_LOG_VERBOSE:
428 			if (IMSG_DATA_SIZE(imsg) != sizeof(verbose))
429 				fatalx("%s: IMSG_CTL_LOG_VERBOSE wrong length: "
430 				    "%lu", __func__, IMSG_DATA_SIZE(imsg));
431 			memcpy(&verbose, imsg.data, sizeof(verbose));
432 			log_setverbose(verbose);
433 			break;
434 		default:
435 			log_debug("%s: error handling imsg %d", __func__,
436 			    imsg.hdr.type);
437 			break;
438 		}
439 		imsg_free(&imsg);
440 	}
441 	if (!shut)
442 		imsg_event_add(iev);
443 	else {
444 		/* This pipe is dead. Remove its event handler */
445 		event_del(&iev->ev);
446 		event_loopexit(NULL);
447 	}
448 }
449 
450 void
451 main_dispatch_resolver(int fd, short event, void *bula)
452 {
453 	struct imsgev		*iev = bula;
454 	struct imsgbuf		*ibuf;
455 	struct imsg		 imsg;
456 	ssize_t			 n;
457 	int			 shut = 0;
458 
459 	ibuf = &iev->ibuf;
460 
461 	if (event & EV_READ) {
462 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
463 			fatal("imsg_read error");
464 		if (n == 0)	/* Connection closed. */
465 			shut = 1;
466 	}
467 	if (event & EV_WRITE) {
468 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
469 			fatal("msgbuf_write");
470 		if (n == 0)	/* Connection closed. */
471 			shut = 1;
472 	}
473 
474 	for (;;) {
475 		if ((n = imsg_get(ibuf, &imsg)) == -1)
476 			fatal("imsg_get");
477 		if (n == 0)	/* No more messages. */
478 			break;
479 
480 		switch (imsg.hdr.type) {
481 		default:
482 			log_debug("%s: error handling imsg %d", __func__,
483 			    imsg.hdr.type);
484 			break;
485 		}
486 		imsg_free(&imsg);
487 	}
488 	if (!shut)
489 		imsg_event_add(iev);
490 	else {
491 		/* This pipe is dead. Remove its event handler. */
492 		event_del(&iev->ev);
493 		event_loopexit(NULL);
494 	}
495 }
496 
497 void
498 main_imsg_compose_frontend(int type, pid_t pid, void *data, uint16_t datalen)
499 {
500 	if (iev_frontend)
501 		imsg_compose_event(iev_frontend, type, 0, pid, -1, data,
502 		    datalen);
503 }
504 
505 void
506 main_imsg_compose_frontend_fd(int type, pid_t pid, int fd)
507 {
508 	if (iev_frontend)
509 		imsg_compose_event(iev_frontend, type, 0, pid, fd, NULL, 0);
510 }
511 
512 void
513 main_imsg_compose_resolver(int type, pid_t pid, void *data, uint16_t datalen)
514 {
515 	if (iev_resolver)
516 		imsg_compose_event(iev_resolver, type, 0, pid, -1, data,
517 		    datalen);
518 }
519 
520 void
521 imsg_event_add(struct imsgev *iev)
522 {
523 	iev->events = EV_READ;
524 	if (iev->ibuf.w.queued)
525 		iev->events |= EV_WRITE;
526 
527 	event_del(&iev->ev);
528 	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
529 	event_add(&iev->ev, NULL);
530 }
531 
532 int
533 imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
534     pid_t pid, int fd, void *data, uint16_t datalen)
535 {
536 	int	ret;
537 
538 	if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data,
539 	    datalen)) != -1)
540 		imsg_event_add(iev);
541 
542 	return (ret);
543 }
544 
545 static int
546 main_imsg_send_ipc_sockets(struct imsgbuf *frontend_buf,
547     struct imsgbuf *resolver_buf)
548 {
549 	int pipe_frontend2resolver[2];
550 
551 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
552 	    PF_UNSPEC, pipe_frontend2resolver) == -1)
553 		return (-1);
554 
555 	if (imsg_compose(frontend_buf, IMSG_SOCKET_IPC_RESOLVER, 0, 0,
556 	    pipe_frontend2resolver[0], NULL, 0) == -1)
557 		return (-1);
558 	if (imsg_compose(resolver_buf, IMSG_SOCKET_IPC_FRONTEND, 0, 0,
559 	    pipe_frontend2resolver[1], NULL, 0) == -1)
560 		return (-1);
561 
562 	return (0);
563 }
564 
565 int
566 main_reload(void)
567 {
568 	struct uw_conf	*xconf;
569 
570 	if ((xconf = parse_config(conffile)) == NULL)
571 		return (-1);
572 
573 	if (main_imsg_send_config(xconf) == -1)
574 		return (-1);
575 
576 	merge_config(main_conf, xconf);
577 
578 	if (main_conf->blocklist_file != NULL)
579 		send_blocklist_fd();
580 
581 	return (0);
582 }
583 
584 int
585 main_imsg_send_config(struct uw_conf *xconf)
586 {
587 	struct uw_forwarder		*uw_forwarder;
588 	struct force_tree_entry	*force_entry;
589 
590 	/* Send fixed part of config to children. */
591 	if (main_sendall(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
592 		return (-1);
593 
594 	if (xconf->blocklist_file != NULL) {
595 		if (main_sendall(IMSG_RECONF_BLOCKLIST_FILE,
596 		    xconf->blocklist_file, strlen(xconf->blocklist_file) + 1)
597 		    == -1)
598 			return (-1);
599 	}
600 
601 	/* send static forwarders to children */
602 	TAILQ_FOREACH(uw_forwarder, &xconf->uw_forwarder_list, entry) {
603 		if (main_sendall(IMSG_RECONF_FORWARDER, uw_forwarder,
604 		    sizeof(*uw_forwarder)) == -1)
605 			return (-1);
606 	}
607 
608 	/* send static DoT forwarders to children */
609 	TAILQ_FOREACH(uw_forwarder, &xconf->uw_dot_forwarder_list,
610 	    entry) {
611 		if (main_sendall(IMSG_RECONF_DOT_FORWARDER, uw_forwarder,
612 		    sizeof(*uw_forwarder)) == -1)
613 			return (-1);
614 	}
615 	RB_FOREACH(force_entry, force_tree, &xconf->force) {
616 		if (main_sendall(IMSG_RECONF_FORCE, force_entry,
617 		    sizeof(*force_entry)) == -1)
618 			return (-1);
619 	}
620 
621 	/* Tell children the revised config is now complete. */
622 	if (main_sendall(IMSG_RECONF_END, NULL, 0) == -1)
623 		return (-1);
624 
625 	return (0);
626 }
627 
628 int
629 main_sendall(enum imsg_type type, void *buf, uint16_t len)
630 {
631 	if (imsg_compose_event(iev_frontend, type, 0, 0, -1, buf, len) == -1)
632 		return (-1);
633 	if (imsg_compose_event(iev_resolver, type, 0, 0, -1, buf, len) == -1)
634 		return (-1);
635 	return (0);
636 }
637 
638 void
639 merge_config(struct uw_conf *conf, struct uw_conf *xconf)
640 {
641 	struct uw_forwarder		*uw_forwarder;
642 	struct force_tree_entry	*n, *nxt;
643 
644 	/* Remove & discard existing forwarders. */
645 	while ((uw_forwarder = TAILQ_FIRST(&conf->uw_forwarder_list)) !=
646 	    NULL) {
647 		TAILQ_REMOVE(&conf->uw_forwarder_list, uw_forwarder, entry);
648 		free(uw_forwarder);
649 	}
650 	while ((uw_forwarder = TAILQ_FIRST(&conf->uw_dot_forwarder_list)) !=
651 	    NULL) {
652 		TAILQ_REMOVE(&conf->uw_dot_forwarder_list, uw_forwarder, entry);
653 		free(uw_forwarder);
654 	}
655 
656 	/* Remove & discard existing force tree. */
657 	for (n = RB_MIN(force_tree, &conf->force); n != NULL; n = nxt) {
658 		nxt = RB_NEXT(force_tree, &conf->force, n);
659 		RB_REMOVE(force_tree, &conf->force, n);
660 		free(n);
661 	}
662 
663 	memcpy(&conf->res_pref, &xconf->res_pref,
664 	    sizeof(conf->res_pref));
665 
666 	free(conf->blocklist_file);
667 	conf->blocklist_file = xconf->blocklist_file;
668 	conf->blocklist_log = xconf->blocklist_log;
669 
670 	/* Add new forwarders. */
671 	TAILQ_CONCAT(&conf->uw_forwarder_list, &xconf->uw_forwarder_list,
672 	    entry);
673 	TAILQ_CONCAT(&conf->uw_dot_forwarder_list,
674 	    &xconf->uw_dot_forwarder_list, entry);
675 
676 	for (n = RB_MIN(force_tree, &xconf->force); n != NULL; n = nxt) {
677 		nxt = RB_NEXT(force_tree, &xconf->force, n);
678 		RB_REMOVE(force_tree, &xconf->force, n);
679 		RB_INSERT(force_tree, &conf->force, n);
680 	}
681 
682 	free(xconf);
683 }
684 
685 struct uw_conf *
686 config_new_empty(void)
687 {
688 	static enum uw_resolver_type	 default_res_pref[] = {
689 	    UW_RES_DOT,
690 	    UW_RES_ODOT_FORWARDER,
691 	    UW_RES_FORWARDER,
692 	    UW_RES_RECURSOR,
693 	    UW_RES_ODOT_DHCP,
694 	    UW_RES_DHCP,
695 	    UW_RES_ASR};
696 	struct uw_conf			*xconf;
697 
698 	xconf = calloc(1, sizeof(*xconf));
699 	if (xconf == NULL)
700 		fatal(NULL);
701 
702 	memcpy(&xconf->res_pref.types, &default_res_pref,
703 	    sizeof(default_res_pref));
704 	xconf->res_pref.len = nitems(default_res_pref);
705 
706 	TAILQ_INIT(&xconf->uw_forwarder_list);
707 	TAILQ_INIT(&xconf->uw_dot_forwarder_list);
708 
709 	RB_INIT(&xconf->force);
710 
711 	return (xconf);
712 }
713 
714 void
715 config_clear(struct uw_conf *conf)
716 {
717 	struct uw_conf	*xconf;
718 
719 	/* Merge current config with an empty config. */
720 	xconf = config_new_empty();
721 	merge_config(conf, xconf);
722 
723 	free(conf);
724 }
725 
726 void
727 open_ports(void)
728 {
729 	struct addrinfo	 hints, *res0;
730 	int		 udp4sock = -1, udp6sock = -1, error;
731 
732 	memset(&hints, 0, sizeof(hints));
733 	hints.ai_family = AF_INET;
734 	hints.ai_socktype = SOCK_DGRAM;
735 	hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
736 
737 	error = getaddrinfo("127.0.0.1", "domain", &hints, &res0);
738 	if (!error && res0) {
739 		if ((udp4sock = socket(res0->ai_family, res0->ai_socktype,
740 		    res0->ai_protocol)) != -1) {
741 			if (bind(udp4sock, res0->ai_addr, res0->ai_addrlen)
742 			    == -1) {
743 				close(udp4sock);
744 				udp4sock = -1;
745 			}
746 		}
747 	}
748 	if (res0)
749 		freeaddrinfo(res0);
750 
751 	hints.ai_family = AF_INET6;
752 	error = getaddrinfo("::1", "domain", &hints, &res0);
753 	if (!error && res0) {
754 		if ((udp6sock = socket(res0->ai_family, res0->ai_socktype,
755 		    res0->ai_protocol)) != -1) {
756 			if (bind(udp6sock, res0->ai_addr, res0->ai_addrlen)
757 			    == -1) {
758 				close(udp6sock);
759 				udp6sock = -1;
760 			}
761 		}
762 	}
763 	if (res0)
764 		freeaddrinfo(res0);
765 
766 	if (udp4sock == -1 && udp6sock == -1)
767 		fatal("could not bind to 127.0.0.1 or ::1 on port 53");
768 
769 	if (udp4sock != -1)
770 		main_imsg_compose_frontend_fd(IMSG_UDP4SOCK, 0, udp4sock);
771 	if (udp6sock != -1)
772 		main_imsg_compose_frontend_fd(IMSG_UDP6SOCK, 0, udp6sock);
773 }
774 
775 void
776 solicit_dns_proposals(void)
777 {
778 	struct rt_msghdr		 rtm;
779 	struct iovec			 iov[1];
780 	int				 iovcnt = 0;
781 
782 	memset(&rtm, 0, sizeof(rtm));
783 
784 	rtm.rtm_version = RTM_VERSION;
785 	rtm.rtm_type = RTM_PROPOSAL;
786 	rtm.rtm_msglen = sizeof(rtm);
787 	rtm.rtm_tableid = 0;
788 	rtm.rtm_index = 0;
789 	rtm.rtm_seq = arc4random();
790 	rtm.rtm_priority = RTP_PROPOSAL_SOLICIT;
791 
792 	iov[iovcnt].iov_base = &rtm;
793 	iov[iovcnt++].iov_len = sizeof(rtm);
794 
795 	if (writev(routesock, iov, iovcnt) == -1)
796 		log_warn("failed to send solicitation");
797 }
798 
799 void
800 send_blocklist_fd(void)
801 {
802 	int	bl_fd;
803 
804 	if ((bl_fd = open(main_conf->blocklist_file, O_RDONLY)) != -1)
805 		main_imsg_compose_frontend_fd(IMSG_BLFD, 0, bl_fd);
806 	else
807 		log_warn("%s", main_conf->blocklist_file);
808 }
809 
810 void
811 imsg_receive_config(struct imsg *imsg, struct uw_conf **xconf)
812 {
813 	struct uw_conf			*nconf;
814 	struct uw_forwarder		*uw_forwarder;
815 	struct force_tree_entry	*force_entry;
816 
817 	nconf = *xconf;
818 
819 	switch (imsg->hdr.type) {
820 	case IMSG_RECONF_CONF:
821 		if (nconf != NULL)
822 			fatalx("%s: IMSG_RECONF_CONF already in "
823 			    "progress", __func__);
824 		if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_conf))
825 			fatalx("%s: IMSG_RECONF_CONF wrong length: %lu",
826 			    __func__, IMSG_DATA_SIZE(*imsg));
827 		if ((*xconf = malloc(sizeof(struct uw_conf))) == NULL)
828 			fatal(NULL);
829 		nconf = *xconf;
830 		memcpy(nconf, imsg->data, sizeof(struct uw_conf));
831 		TAILQ_INIT(&nconf->uw_forwarder_list);
832 		TAILQ_INIT(&nconf->uw_dot_forwarder_list);
833 		RB_INIT(&nconf->force);
834 		break;
835 	case IMSG_RECONF_BLOCKLIST_FILE:
836 		/* make sure this is a string */
837 		((char *)imsg->data)[IMSG_DATA_SIZE(*imsg) - 1] = '\0';
838 		if ((nconf->blocklist_file = strdup(imsg->data)) ==
839 		    NULL)
840 			fatal("%s: strdup", __func__);
841 		break;
842 	case IMSG_RECONF_FORWARDER:
843 		if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_forwarder))
844 			fatalx("%s: IMSG_RECONF_FORWARDER wrong length:"
845 			    " %lu", __func__, IMSG_DATA_SIZE(*imsg));
846 		if ((uw_forwarder = malloc(sizeof(struct
847 		    uw_forwarder))) == NULL)
848 			fatal(NULL);
849 		memcpy(uw_forwarder, imsg->data, sizeof(struct
850 		    uw_forwarder));
851 		TAILQ_INSERT_TAIL(&nconf->uw_forwarder_list,
852 		    uw_forwarder, entry);
853 		break;
854 	case IMSG_RECONF_DOT_FORWARDER:
855 		if (IMSG_DATA_SIZE(*imsg) != sizeof(struct uw_forwarder))
856 			fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong "
857 			    "length: %lu", __func__,
858 			    IMSG_DATA_SIZE(*imsg));
859 		if ((uw_forwarder = malloc(sizeof(struct
860 		    uw_forwarder))) == NULL)
861 			fatal(NULL);
862 		memcpy(uw_forwarder, imsg->data, sizeof(struct
863 		    uw_forwarder));
864 		TAILQ_INSERT_TAIL(&nconf->uw_dot_forwarder_list,
865 		    uw_forwarder, entry);
866 		break;
867 	case IMSG_RECONF_FORCE:
868 		if (IMSG_DATA_SIZE(*imsg) != sizeof(struct force_tree_entry))
869 			fatalx("%s: IMSG_RECONF_FORCE wrong "
870 			    "length: %lu", __func__,
871 			    IMSG_DATA_SIZE(*imsg));
872 		if ((force_entry = malloc(sizeof(struct
873 		    force_tree_entry))) == NULL)
874 			fatal(NULL);
875 		memcpy(force_entry, imsg->data, sizeof(struct
876 		    force_tree_entry));
877 		RB_INSERT(force_tree, &nconf->force, force_entry);
878 		break;
879 	default:
880 		log_debug("%s: error handling imsg %d", __func__,
881 		    imsg->hdr.type);
882 		break;
883 	}
884 }
885