xref: /openbsd-src/sbin/unwind/frontend.c (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
1 /*	$OpenBSD: frontend.c,v 1.12 2019/02/10 14:10:22 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 
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/socket.h>
25 #include <sys/syslog.h>
26 #include <sys/uio.h>
27 
28 #include <netinet/in.h>
29 #include <net/if.h>
30 #include <net/route.h>
31 
32 #include <errno.h>
33 #include <event.h>
34 #include <imsg.h>
35 #include <netdb.h>
36 #include <pwd.h>
37 #include <signal.h>
38 #include <stdint.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <time.h>
43 #include <unistd.h>
44 
45 #include "libunbound/config.h"
46 #include "libunbound/sldns/pkthdr.h"
47 #include "libunbound/sldns/sbuffer.h"
48 #include "libunbound/sldns/str2wire.h"
49 #include "libunbound/sldns/wire2str.h"
50 
51 #include "uw_log.h"
52 #include "unwind.h"
53 #include "frontend.h"
54 #include "control.h"
55 
56 #define	ROUTE_SOCKET_BUF_SIZE   16384
57 
58 struct udp_ev {
59 	struct event		 ev;
60 	uint8_t			 query[65536];
61 	struct msghdr		 rcvmhdr;
62 	struct iovec		 rcviov[1];
63 	struct sockaddr_storage	 from;
64 } udp4ev, udp6ev;
65 
66 struct pending_query {
67 	TAILQ_ENTRY(pending_query)	 entry;
68 	struct sockaddr_storage		 from;
69 	uint8_t				*query;
70 	ssize_t				 len;
71 	uint64_t			 imsg_id;
72 	int				 fd;
73 	int				 bogus;
74 };
75 
76 TAILQ_HEAD(, pending_query)	 pending_queries;
77 
78 __dead void		 frontend_shutdown(void);
79 void			 frontend_sig_handler(int, short, void *);
80 void			 frontend_startup(void);
81 void			 udp_receive(int, short, void *);
82 void			 send_answer(struct pending_query *, uint8_t *,
83 			     ssize_t);
84 void			 route_receive(int, short, void *);
85 void			 handle_route_message(struct rt_msghdr *,
86 			     struct sockaddr **);
87 void			 get_rtaddrs(int, struct sockaddr *,
88 			     struct sockaddr **);
89 void			 rtmget_default(void);
90 struct pending_query	*find_pending_query(uint64_t);
91 void			 parse_dhcp_lease(int);
92 void			 parse_trust_anchor(struct trust_anchor_head *, int);
93 void			 send_trust_anchors(struct trust_anchor_head *);
94 void			 write_trust_anchors(struct trust_anchor_head *, int);
95 
96 struct unwind_conf	*frontend_conf;
97 struct imsgev		*iev_main;
98 struct imsgev		*iev_resolver;
99 struct imsgev		*iev_captiveportal;
100 struct event		 ev_route;
101 int			 udp4sock = -1, udp6sock = -1, routesock = -1;
102 int			 ta_fd = -1;
103 
104 static struct trust_anchor_head	 built_in_trust_anchors;
105 static struct trust_anchor_head	 trust_anchors, new_trust_anchors;
106 
107 void
108 frontend_sig_handler(int sig, short event, void *bula)
109 {
110 	/*
111 	 * Normal signal handler rules don't apply because libevent
112 	 * decouples for us.
113 	 */
114 
115 	switch (sig) {
116 	case SIGINT:
117 	case SIGTERM:
118 		frontend_shutdown();
119 	default:
120 		fatalx("unexpected signal");
121 	}
122 }
123 
124 void
125 frontend(int debug, int verbose)
126 {
127 	struct event		 ev_sigint, ev_sigterm;
128 	struct passwd		*pw;
129 	size_t			 rcvcmsglen, sndcmsgbuflen;
130 	uint8_t			*rcvcmsgbuf;
131 	uint8_t			*sndcmsgbuf = NULL;
132 
133 	frontend_conf = config_new_empty();
134 	control_state.fd = -1;
135 
136 	log_init(debug, LOG_DAEMON);
137 	log_setverbose(verbose);
138 
139 	if ((pw = getpwnam(UNWIND_USER)) == NULL)
140 		fatal("getpwnam");
141 
142 	if (chroot(pw->pw_dir) == -1)
143 		fatal("chroot");
144 	if (chdir("/") == -1)
145 		fatal("chdir(\"/\")");
146 
147 	unwind_process = PROC_FRONTEND;
148 	setproctitle("%s", log_procnames[unwind_process]);
149 	log_procinit(log_procnames[unwind_process]);
150 
151 	if (setgroups(1, &pw->pw_gid) ||
152 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
153 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
154 		fatal("can't drop privileges");
155 
156 	if (pledge("stdio unix recvfd", NULL) == -1)
157 		fatal("pledge");
158 
159 	event_init();
160 
161 	/* Setup signal handler. */
162 	signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL);
163 	signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL);
164 	signal_add(&ev_sigint, NULL);
165 	signal_add(&ev_sigterm, NULL);
166 	signal(SIGPIPE, SIG_IGN);
167 	signal(SIGHUP, SIG_IGN);
168 
169 	/* Setup pipe and event handler to the parent process. */
170 	if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
171 		fatal(NULL);
172 	imsg_init(&iev_main->ibuf, 3);
173 	iev_main->handler = frontend_dispatch_main;
174 	iev_main->events = EV_READ;
175 	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
176 	    iev_main->handler, iev_main);
177 	event_add(&iev_main->ev, NULL);
178 
179 	rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
180 	    CMSG_SPACE(sizeof(int));
181 	if((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL)
182 		fatal("malloc");
183 
184 	udp4ev.rcviov[0].iov_base = (caddr_t)udp4ev.query;
185 	udp4ev.rcviov[0].iov_len = sizeof(udp4ev.query);
186 	udp4ev.rcvmhdr.msg_name = (caddr_t)&udp4ev.from;
187 	udp4ev.rcvmhdr.msg_namelen = sizeof(udp4ev.from);
188 	udp4ev.rcvmhdr.msg_iov = udp4ev.rcviov;
189 	udp4ev.rcvmhdr.msg_iovlen = 1;
190 
191 	udp6ev.rcviov[0].iov_base = (caddr_t)udp6ev.query;
192 	udp6ev.rcviov[0].iov_len = sizeof(udp6ev.query);
193 	udp6ev.rcvmhdr.msg_name = (caddr_t)&udp6ev.from;
194 	udp6ev.rcvmhdr.msg_namelen = sizeof(udp6ev.from);
195 	udp6ev.rcvmhdr.msg_iov = udp6ev.rcviov;
196 	udp6ev.rcvmhdr.msg_iovlen = 1;
197 
198 	sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
199 	    CMSG_SPACE(sizeof(int));
200 	if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL)
201 		fatal("%s", __func__);
202 
203 	TAILQ_INIT(&pending_queries);
204 
205 	TAILQ_INIT(&built_in_trust_anchors);
206 	TAILQ_INIT(&trust_anchors);
207 	TAILQ_INIT(&new_trust_anchors);
208 
209 	add_new_ta(&built_in_trust_anchors, KSK2017);
210 
211 	event_dispatch();
212 
213 	frontend_shutdown();
214 }
215 
216 __dead void
217 frontend_shutdown(void)
218 {
219 	/* Close pipes. */
220 	msgbuf_write(&iev_resolver->ibuf.w);
221 	msgbuf_clear(&iev_resolver->ibuf.w);
222 	close(iev_resolver->ibuf.fd);
223 	msgbuf_write(&iev_captiveportal->ibuf.w);
224 	msgbuf_clear(&iev_captiveportal->ibuf.w);
225 	close(iev_captiveportal->ibuf.fd);
226 	msgbuf_write(&iev_main->ibuf.w);
227 	msgbuf_clear(&iev_main->ibuf.w);
228 	close(iev_main->ibuf.fd);
229 
230 	config_clear(frontend_conf);
231 
232 	free(iev_resolver);
233 	free(iev_captiveportal);
234 	free(iev_main);
235 
236 	log_info("frontend exiting");
237 	exit(0);
238 }
239 
240 int
241 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen)
242 {
243 	return (imsg_compose_event(iev_main, type, 0, pid, -1, data,
244 	    datalen));
245 }
246 
247 int
248 frontend_imsg_compose_resolver(int type, pid_t pid, void *data, uint16_t datalen)
249 {
250 	return (imsg_compose_event(iev_resolver, type, 0, pid, -1, data,
251 	    datalen));
252 }
253 
254 int
255 frontend_imsg_compose_captiveportal(int type, pid_t pid, void *data, uint16_t datalen)
256 {
257 	return (imsg_compose_event(iev_captiveportal, type, 0, pid, -1, data,
258 	    datalen));
259 }
260 
261 void
262 frontend_dispatch_main(int fd, short event, void *bula)
263 {
264 	static struct unwind_conf		*nconf;
265 	struct unwind_forwarder		*unwind_forwarder;
266 	struct imsg			 imsg;
267 	struct imsgev			*iev = bula;
268 	struct imsgbuf			*ibuf = &iev->ibuf;
269 	int				 n, shut = 0;
270 
271 	if (event & EV_READ) {
272 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
273 			fatal("imsg_read error");
274 		if (n == 0)	/* Connection closed. */
275 			shut = 1;
276 	}
277 	if (event & EV_WRITE) {
278 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
279 			fatal("msgbuf_write");
280 		if (n == 0)	/* Connection closed. */
281 			shut = 1;
282 	}
283 
284 	for (;;) {
285 		if ((n = imsg_get(ibuf, &imsg)) == -1)
286 			fatal("%s: imsg_get error", __func__);
287 		if (n == 0)	/* No more messages. */
288 			break;
289 
290 		switch (imsg.hdr.type) {
291 		case IMSG_SOCKET_IPC_RESOLVER:
292 			/*
293 			 * Setup pipe and event handler to the resolver
294 			 * process.
295 			 */
296 			if (iev_resolver) {
297 				fatalx("%s: received unexpected imsg fd "
298 				    "to frontend", __func__);
299 				break;
300 			}
301 			if ((fd = imsg.fd) == -1) {
302 				fatalx("%s: expected to receive imsg fd to "
303 				   "frontend but didn't receive any",
304 				   __func__);
305 				break;
306 			}
307 
308 			iev_resolver = malloc(sizeof(struct imsgev));
309 			if (iev_resolver == NULL)
310 				fatal(NULL);
311 
312 			imsg_init(&iev_resolver->ibuf, fd);
313 			iev_resolver->handler = frontend_dispatch_resolver;
314 			iev_resolver->events = EV_READ;
315 
316 			event_set(&iev_resolver->ev, iev_resolver->ibuf.fd,
317 			iev_resolver->events, iev_resolver->handler, iev_resolver);
318 			event_add(&iev_resolver->ev, NULL);
319 			break;
320 		case IMSG_SOCKET_IPC_CAPTIVEPORTAL:
321 			/*
322 			 * Setup pipe and event handler to the captiveportal
323 			 * process.
324 			 */
325 			if (iev_captiveportal) {
326 				fatalx("%s: received unexpected imsg fd "
327 				    "to frontend", __func__);
328 				break;
329 			}
330 			if ((fd = imsg.fd) == -1) {
331 				fatalx("%s: expected to receive imsg fd to "
332 				   "frontend but didn't receive any",
333 				   __func__);
334 				break;
335 			}
336 
337 			iev_captiveportal = malloc(sizeof(struct imsgev));
338 			if (iev_captiveportal == NULL)
339 				fatal(NULL);
340 
341 			imsg_init(&iev_captiveportal->ibuf, fd);
342 			iev_captiveportal->handler = frontend_dispatch_captiveportal;
343 			iev_captiveportal->events = EV_READ;
344 
345 			event_set(&iev_captiveportal->ev, iev_captiveportal->ibuf.fd,
346 			iev_captiveportal->events, iev_captiveportal->handler, iev_captiveportal);
347 			event_add(&iev_captiveportal->ev, NULL);
348 			break;
349 		case IMSG_RECONF_CONF:
350 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
351 			    sizeof(struct unwind_conf))
352 				fatalx("%s: IMSG_RECONF_CONF wrong length: %d",
353 				    __func__, imsg.hdr.len);
354 			if ((nconf = malloc(sizeof(struct unwind_conf))) ==
355 			    NULL)
356 				fatal(NULL);
357 			memcpy(nconf, imsg.data, sizeof(struct unwind_conf));
358 			nconf->captive_portal_host = NULL;
359 			nconf->captive_portal_path = NULL;
360 			nconf->captive_portal_expected_response = NULL;
361 			SIMPLEQ_INIT(&nconf->unwind_forwarder_list);
362 			SIMPLEQ_INIT(&nconf->unwind_dot_forwarder_list);
363 			break;
364 		case IMSG_RECONF_CAPTIVE_PORTAL_HOST:
365 			/* make sure this is a string */
366 			((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1]
367 			    = '\0';
368 			if ((nconf->captive_portal_host = strdup(imsg.data)) ==
369 			    NULL)
370 				fatal("%s: strdup", __func__);
371 			break;
372 		case IMSG_RECONF_CAPTIVE_PORTAL_PATH:
373 			/* make sure this is a string */
374 			((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1]
375 			    = '\0';
376 			if ((nconf->captive_portal_path = strdup(imsg.data)) ==
377 			    NULL)
378 				fatal("%s: strdup", __func__);
379 			break;
380 		case IMSG_RECONF_CAPTIVE_PORTAL_EXPECTED_RESPONSE:
381 			/* make sure this is a string */
382 			((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1]
383 			    = '\0';
384 			if ((nconf->captive_portal_expected_response =
385 			    strdup(imsg.data)) == NULL)
386 				fatal("%s: strdup", __func__);
387 			break;
388 		case IMSG_RECONF_FORWARDER:
389 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
390 			    sizeof(struct unwind_forwarder))
391 				fatalx("%s: IMSG_RECONF_FORWARDER wrong length:"
392 				    " %d", __func__, imsg.hdr.len);
393 			if ((unwind_forwarder = malloc(sizeof(struct
394 			    unwind_forwarder))) == NULL)
395 				fatal(NULL);
396 			memcpy(unwind_forwarder, imsg.data, sizeof(struct
397 			    unwind_forwarder));
398 			SIMPLEQ_INSERT_TAIL(&nconf->unwind_forwarder_list,
399 			    unwind_forwarder, entry);
400 			break;
401 		case IMSG_RECONF_DOT_FORWARDER:
402 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
403 			    sizeof(struct unwind_forwarder))
404 				fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong "
405 				    "length: %d", __func__, imsg.hdr.len);
406 			if ((unwind_forwarder = malloc(sizeof(struct
407 			    unwind_forwarder))) == NULL)
408 				fatal(NULL);
409 			memcpy(unwind_forwarder, imsg.data, sizeof(struct
410 			    unwind_forwarder));
411 			SIMPLEQ_INSERT_TAIL(&nconf->unwind_dot_forwarder_list,
412 			    unwind_forwarder, entry);
413 			break;
414 		case IMSG_RECONF_END:
415 			merge_config(frontend_conf, nconf);
416 			nconf = NULL;
417 			break;
418 		case IMSG_UDP6SOCK:
419 			if (udp6sock != -1)
420 				fatalx("%s: received unexpected udp6sock",
421 				    __func__);
422 			if ((udp6sock = imsg.fd) == -1)
423 				fatalx("%s: expected to receive imsg "
424 				    "UDP6 fd but didn't receive any",
425 				    __func__);
426 			event_set(&udp6ev.ev, udp6sock, EV_READ | EV_PERSIST,
427 			    udp_receive, &udp6ev);
428 			event_add(&udp6ev.ev, NULL);
429 			break;
430 		case IMSG_UDP4SOCK:
431 			if (udp4sock != -1)
432 				fatalx("%s: received unexpected udp4sock",
433 				    __func__);
434 			if ((udp4sock = imsg.fd) == -1)
435 				fatalx("%s: expected to receive imsg "
436 				    "UDP4 fd but didn't receive any",
437 				    __func__);
438 			event_set(&udp4ev.ev, udp4sock, EV_READ | EV_PERSIST,
439 			    udp_receive, &udp4ev);
440 			event_add(&udp4ev.ev, NULL);
441 			break;
442 		case IMSG_ROUTESOCK:
443 			if (routesock != -1)
444 				fatalx("%s: received unexpected routesock",
445 				    __func__);
446 			if ((fd = imsg.fd) == -1)
447 				fatalx("%s: expected to receive imsg "
448 				    "routesocket fd but didn't receive any",
449 				    __func__);
450 			routesock = fd;
451 			event_set(&ev_route, fd, EV_READ | EV_PERSIST,
452 			    route_receive, NULL);
453 			break;
454 		case IMSG_STARTUP:
455 			frontend_startup();
456 			break;
457 		case IMSG_CONTROLFD:
458 			if (control_state.fd != -1)
459 				fatalx("%s: received unexpected controlsock",
460 				    __func__);
461 			if ((fd = imsg.fd) == -1)
462 				fatalx("%s: expected to receive imsg "
463 				    "control fd but didn't receive any",
464 				    __func__);
465 			control_state.fd = fd;
466 			/* Listen on control socket. */
467 			TAILQ_INIT(&ctl_conns);
468 			control_listen();
469 			break;
470 		case IMSG_LEASEFD:
471 			if ((fd = imsg.fd) == -1)
472 				fatalx("%s: expected to receive imsg "
473 				    "dhcp lease fd but didn't receive any",
474 				    __func__);
475 			parse_dhcp_lease(fd);
476 			break;
477 		case IMSG_TAFD:
478 			if ((ta_fd = imsg.fd) != -1)
479 				parse_trust_anchor(&trust_anchors, ta_fd);
480 			if (!TAILQ_EMPTY(&trust_anchors))
481 				send_trust_anchors(&trust_anchors);
482 			else
483 				send_trust_anchors(&built_in_trust_anchors);
484 			break;
485 		default:
486 			log_debug("%s: error handling imsg %d", __func__,
487 			    imsg.hdr.type);
488 			break;
489 		}
490 		imsg_free(&imsg);
491 	}
492 	if (!shut)
493 		imsg_event_add(iev);
494 	else {
495 		/* This pipe is dead. Remove its event handler. */
496 		event_del(&iev->ev);
497 		event_loopexit(NULL);
498 	}
499 }
500 
501 void
502 frontend_dispatch_resolver(int fd, short event, void *bula)
503 {
504 	static struct pending_query	*pq;
505 	struct imsgev			*iev = bula;
506 	struct imsgbuf			*ibuf = &iev->ibuf;
507 	struct imsg			 imsg;
508 	struct query_imsg		*query_imsg;
509 	int				 n, shut = 0, chg;
510 	char				*ta;
511 
512 	if (event & EV_READ) {
513 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
514 			fatal("imsg_read error");
515 		if (n == 0)	/* Connection closed. */
516 			shut = 1;
517 	}
518 	if (event & EV_WRITE) {
519 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
520 			fatal("msgbuf_write");
521 		if (n == 0)	/* Connection closed. */
522 			shut = 1;
523 	}
524 
525 	for (;;) {
526 		if ((n = imsg_get(ibuf, &imsg)) == -1)
527 			fatal("%s: imsg_get error", __func__);
528 		if (n == 0)	/* No more messages. */
529 			break;
530 
531 		switch (imsg.hdr.type) {
532 		case IMSG_ANSWER_HEADER:
533 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
534 			    sizeof(*query_imsg))
535 				fatalx("%s: IMSG_ANSWER_HEADER wrong length: "
536 				    "%d", __func__, imsg.hdr.len);
537 			query_imsg = (struct query_imsg *)imsg.data;
538 			if ((pq = find_pending_query(query_imsg->id)) ==
539 			    NULL) {
540 				log_warnx("cannot find pending query %llu",
541 				    query_imsg->id);
542 				break;
543 			}
544 			if (query_imsg->err) {
545 				send_answer(pq, NULL, 0);
546 				pq = NULL;
547 				break;
548 			}
549 			pq->bogus = query_imsg->bogus;
550 			break;
551 		case IMSG_ANSWER:
552 			if (pq == NULL)
553 				fatalx("IMSG_ANSWER without HEADER");
554 			send_answer(pq, imsg.data, imsg.hdr.len -
555 			    IMSG_HEADER_SIZE);
556 			break;
557 		case IMSG_RESOLVER_DOWN:
558 			log_debug("%s: IMSG_RESOLVER_DOWN", __func__);
559 			if (udp4sock != -1) {
560 				event_del(&udp4ev.ev);
561 				close(udp4sock);
562 				udp4sock = -1;
563 			}
564 			if (udp6sock != -1) {
565 				event_del(&udp6ev.ev);
566 				close(udp6sock);
567 				udp6sock = -1;
568 			}
569 			break;
570 		case IMSG_RESOLVER_UP:
571 			log_debug("%s: IMSG_RESOLVER_UP", __func__);
572 			frontend_imsg_compose_main(IMSG_OPEN_PORTS, 0, NULL, 0);
573 			break;
574 		case IMSG_CTL_RESOLVER_INFO:
575 		case IMSG_CTL_CAPTIVEPORTAL_INFO:
576 		case IMSG_CTL_RESOLVER_WHY_BOGUS:
577 		case IMSG_CTL_RESOLVER_HISTOGRAM:
578 		case IMSG_CTL_END:
579 			control_imsg_relay(&imsg);
580 			break;
581 		case IMSG_NEW_TA:
582 			/* make sure this is a string */
583 			((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1]
584 			    = '\0';
585 			ta = imsg.data;
586 			add_new_ta(&new_trust_anchors, ta);
587 			break;
588 		case IMSG_NEW_TAS_ABORT:
589 			log_debug("%s: IMSG_NEW_TAS_ABORT", __func__);
590 			free_tas(&new_trust_anchors);
591 			break;
592 		case IMSG_NEW_TAS_DONE:
593 			chg = merge_tas(&new_trust_anchors, &trust_anchors);
594 			log_debug("%s: IMSG_NEW_TAS_DONE: change: %d",
595 			    __func__, chg);
596 			if (chg) {
597 				send_trust_anchors(&trust_anchors);
598 			}
599 			/*
600 			 * always write trust anchors, the modify date on
601 			 * the file is an indication when we made progress
602 			 */
603 			if (ta_fd != -1)
604 				write_trust_anchors(&trust_anchors, ta_fd);
605 			break;
606 		default:
607 			log_debug("%s: error handling imsg %d", __func__,
608 			    imsg.hdr.type);
609 			break;
610 		}
611 		imsg_free(&imsg);
612 	}
613 	if (!shut)
614 		imsg_event_add(iev);
615 	else {
616 		/* This pipe is dead. Remove its event handler. */
617 		event_del(&iev->ev);
618 		event_loopexit(NULL);
619 	}
620 }
621 
622 void
623 frontend_dispatch_captiveportal(int fd, short event, void *bula)
624 {
625 	struct imsgev			*iev = bula;
626 	struct imsgbuf			*ibuf = &iev->ibuf;
627 	struct imsg			 imsg;
628 	int				 n, shut = 0;
629 
630 	if (event & EV_READ) {
631 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
632 			fatal("imsg_read error");
633 		if (n == 0)	/* Connection closed. */
634 			shut = 1;
635 	}
636 	if (event & EV_WRITE) {
637 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
638 			fatal("msgbuf_write");
639 		if (n == 0)	/* Connection closed. */
640 			shut = 1;
641 	}
642 
643 	for (;;) {
644 		if ((n = imsg_get(ibuf, &imsg)) == -1)
645 			fatal("%s: imsg_get error", __func__);
646 		if (n == 0)	/* No more messages. */
647 			break;
648 
649 		switch (imsg.hdr.type) {
650 		default:
651 			log_debug("%s: error handling imsg %d", __func__,
652 			    imsg.hdr.type);
653 			break;
654 		}
655 		imsg_free(&imsg);
656 	}
657 	if (!shut)
658 		imsg_event_add(iev);
659 	else {
660 		/* This pipe is dead. Remove its event handler. */
661 		event_del(&iev->ev);
662 		event_loopexit(NULL);
663 	}
664 }
665 
666 void
667 frontend_startup(void)
668 {
669 	if (!event_initialized(&ev_route))
670 		fatalx("%s: did not receive a route socket from the main "
671 		    "process", __func__);
672 
673 	event_add(&ev_route, NULL);
674 
675 	frontend_imsg_compose_main(IMSG_STARTUP_DONE, 0, NULL, 0);
676 	rtmget_default();
677 }
678 
679 void
680 udp_receive(int fd, short events, void *arg)
681 {
682 	struct udp_ev		*udpev = (struct udp_ev *)arg;
683 	struct pending_query	*pq;
684 	struct query_imsg	*query_imsg;
685 	ssize_t			 len, rem_len, buf_len;
686 	uint16_t		 qdcount, ancount, nscount, arcount, t, c;
687 	uint8_t			*queryp;
688 	char			*str_from, *str, buf[1024], *bufp;
689 
690 	if ((len = recvmsg(fd, &udpev->rcvmhdr, 0)) < 0) {
691 		log_warn("recvmsg");
692 		return;
693 	}
694 
695 	bufp = buf;
696 	buf_len = sizeof(buf);
697 
698 	str_from = ip_port((struct sockaddr *)&udpev->from);
699 
700 	if (len < LDNS_HEADER_SIZE) {
701 		log_warnx("bad query: too short, from: %s", str_from);
702 		return;
703 	}
704 
705 	qdcount = LDNS_QDCOUNT(udpev->query);
706 	ancount = LDNS_ANCOUNT(udpev->query);
707 	nscount = LDNS_NSCOUNT(udpev->query);
708 	arcount = LDNS_ARCOUNT(udpev->query);
709 
710 	if (qdcount != 1 && ancount != 0 && nscount != 0 && arcount != 0) {
711 		log_warnx("invalid query from %s, qdcount: %d, ancount: %d "
712 		    "nscount: %d, arcount: %d", str_from, qdcount, ancount,
713 		    nscount, arcount);
714 		return;
715 	}
716 
717 	log_debug("query from %s", str_from);
718 	if ((str = sldns_wire2str_pkt(udpev->query, len)) != NULL) {
719 		log_debug("%s", str);
720 		free(str);
721 	}
722 
723 	queryp = udpev->query;
724 	rem_len = len;
725 
726 	queryp += LDNS_HEADER_SIZE;
727 	rem_len -= LDNS_HEADER_SIZE;
728 
729 	sldns_wire2str_dname_scan(&queryp, &rem_len, &bufp, &buf_len,
730 	     udpev->query, len);
731 
732 	if (rem_len < 4) {
733 		log_warnx("malformed query");
734 		return;
735 	}
736 
737 	t = sldns_read_uint16(queryp);
738 	c = sldns_read_uint16(queryp+2);
739 	queryp += 4;
740 	rem_len -= 4;
741 
742 	if ((pq = malloc(sizeof(*pq))) == NULL) {
743 		log_warn(NULL);
744 		return;
745 	}
746 
747 	if ((pq->query = malloc(len)) == NULL) {
748 		log_warn(NULL);
749 		free(pq);
750 		return;
751 	}
752 
753 	do {
754 		arc4random_buf(&pq->imsg_id, sizeof(pq->imsg_id));
755 	} while(find_pending_query(pq->imsg_id) != NULL);
756 
757 	memcpy(pq->query, udpev->query, len);
758 	pq->len = len;
759 	pq->from = udpev->from;
760 	pq->fd = fd;
761 
762 	if ((query_imsg = calloc(1, sizeof(*query_imsg))) == NULL) {
763 		log_warn(NULL);
764 		return;
765 	}
766 
767 	if (strlcpy(query_imsg->qname, buf, sizeof(query_imsg->qname)) >=
768 	    sizeof(buf)) {
769 		log_warnx("qname too long");
770 		free(query_imsg);
771 		/* XXX SERVFAIL */
772 		free(pq->query);
773 		free(pq);
774 		return;
775 	}
776 	query_imsg->id = pq->imsg_id;
777 	query_imsg->t = t;
778 	query_imsg->c = c;
779 
780 	if (frontend_imsg_compose_resolver(IMSG_QUERY, 0, query_imsg,
781 	    sizeof(*query_imsg)) != -1) {
782 		TAILQ_INSERT_TAIL(&pending_queries, pq, entry);
783 	} else {
784 		free(query_imsg);
785 		/* XXX SERVFAIL */
786 		free(pq->query);
787 		free(pq);
788 	}
789 
790 }
791 
792 void
793 send_answer(struct pending_query *pq, uint8_t *answer, ssize_t len)
794 {
795 	log_debug("result for %s",
796 	    ip_port((struct sockaddr*)&pq->from));
797 
798 	if (answer == NULL) {
799 		answer = pq->query;
800 		len = pq->len;
801 
802 		LDNS_QR_SET(answer);
803 		LDNS_RA_SET(answer);
804 		LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
805 	} else {
806 		if (pq->bogus) {
807 			if(LDNS_CD_WIRE(pq->query)) {
808 				LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
809 				LDNS_CD_SET(answer);
810 			} else {
811 				answer = pq->query;
812 				len = pq->len;
813 
814 				LDNS_QR_SET(answer);
815 				LDNS_RA_SET(answer);
816 				LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
817 			}
818 		} else {
819 			LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
820 		}
821 	}
822 
823 	if(sendto(pq->fd, answer, len, 0, (struct sockaddr *)
824 	   &pq->from, pq->from.ss_len) == -1)
825 		log_warn("sendto");
826 
827 	TAILQ_REMOVE(&pending_queries, pq, entry);
828 	free(pq->query);
829 	free(pq);
830 }
831 
832 char*
833 ip_port(struct sockaddr *sa)
834 {
835 	static char	 hbuf[NI_MAXHOST], buf[NI_MAXHOST];
836 
837 	if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
838 	    NI_NUMERICHOST) != 0) {
839 		snprintf(buf, sizeof(buf), "%s", "(unknown)");
840 		return buf;
841 	}
842 
843 	if (sa->sa_family == AF_INET6)
844 		snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs(
845 		    ((struct sockaddr_in6 *)sa)->sin6_port));
846 	if (sa->sa_family == AF_INET)
847 		snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs(
848 		    ((struct sockaddr_in *)sa)->sin_port));
849 
850 	return buf;
851 }
852 
853 struct pending_query*
854 find_pending_query(uint64_t id)
855 {
856 	struct pending_query	*pq;
857 
858 	TAILQ_FOREACH(pq, &pending_queries, entry)
859 		if (pq->imsg_id == id)
860 			return pq;
861 	return NULL;
862 }
863 
864 void
865 route_receive(int fd, short events, void *arg)
866 {
867 	static uint8_t			 *buf;
868 
869 	struct rt_msghdr		*rtm;
870 	struct sockaddr			*sa, *rti_info[RTAX_MAX];
871 	ssize_t				 n;
872 
873 	if (buf == NULL) {
874 		buf = malloc(ROUTE_SOCKET_BUF_SIZE);
875 		if (buf == NULL)
876 			fatal("malloc");
877 	}
878 	rtm = (struct rt_msghdr *)buf;
879 	if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) {
880 		if (errno == EAGAIN || errno == EINTR)
881 			return;
882 		log_warn("dispatch_rtmsg: read error");
883 		return;
884 	}
885 
886 	if (n == 0)
887 		fatal("routing socket closed");
888 
889 	if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) {
890 		log_warnx("partial rtm of %zd in buffer", n);
891 		return;
892 	}
893 
894 	if (rtm->rtm_version != RTM_VERSION)
895 		return;
896 
897 	sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen);
898 	get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
899 
900 	handle_route_message(rtm, rti_info);
901 }
902 
903 #define ROUNDUP(a) \
904 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
905 
906 void
907 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
908 {
909 	int	i;
910 
911 	for (i = 0; i < RTAX_MAX; i++) {
912 		if (addrs & (1 << i)) {
913 			rti_info[i] = sa;
914 			sa = (struct sockaddr *)((char *)(sa) +
915 			    ROUNDUP(sa->sa_len));
916 		} else
917 			rti_info[i] = NULL;
918 	}
919 }
920 
921 void
922 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
923 {
924 	char	buf[IF_NAMESIZE], *bufp;
925 
926 	switch (rtm->rtm_type) {
927 	case RTM_GET:
928 		if (rtm->rtm_errno != 0)
929 			break;
930 		if (!(rtm->rtm_flags & RTF_UP))
931 			break;
932 		if (!(rtm->rtm_addrs & RTA_DST))
933 			break;
934 		if (rti_info[RTAX_DST]->sa_family != AF_INET)
935 			break;
936 		if (((struct sockaddr_in *)rti_info[RTAX_DST])->sin_addr.
937 		    s_addr != INADDR_ANY)
938 			break;
939 		if (!(rtm->rtm_addrs & RTA_NETMASK))
940 			break;
941 		if (rti_info[RTAX_NETMASK]->sa_family != AF_INET)
942 			break;
943 		if (((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_addr.
944 		    s_addr != INADDR_ANY)
945 			break;
946 
947 		frontend_imsg_compose_main(IMSG_OPEN_DHCP_LEASE, 0,
948 		    &rtm->rtm_index, sizeof(rtm->rtm_index));
949 
950 		bufp = if_indextoname(rtm->rtm_index, buf);
951 		if (bufp)
952 			log_debug("default route is on %s", buf);
953 
954 		break;
955 	default:
956 		break;
957 	}
958 
959 }
960 
961 void
962 rtmget_default(void)
963 {
964 	static int		 rtm_seq;
965 	struct rt_msghdr	 rtm;
966 	struct sockaddr_in	 sin;
967 	struct iovec		 iov[5];
968 	long			 pad = 0;
969 	int			 iovcnt = 0, padlen;
970 
971 	memset(&sin, 0, sizeof(sin));
972 	sin.sin_family = AF_INET;
973 	sin.sin_len = sizeof(sin);
974 
975 	memset(&rtm, 0, sizeof(rtm));
976 
977 	rtm.rtm_version = RTM_VERSION;
978 	rtm.rtm_type = RTM_GET;
979 	rtm.rtm_msglen = sizeof(rtm);
980 	rtm.rtm_tableid = 0; /* XXX imsg->rdomain; */
981 	rtm.rtm_seq = ++rtm_seq;
982 	rtm.rtm_addrs = RTA_DST | RTA_NETMASK;
983 
984 	iov[iovcnt].iov_base = &rtm;
985 	iov[iovcnt++].iov_len = sizeof(rtm);
986 
987 	/* dst */
988 	iov[iovcnt].iov_base = &sin;
989 	iov[iovcnt++].iov_len = sizeof(sin);
990 	rtm.rtm_msglen += sizeof(sin);
991 	padlen = ROUNDUP(sizeof(sin)) - sizeof(sin);
992 	if (padlen > 0) {
993 		iov[iovcnt].iov_base = &pad;
994 		iov[iovcnt++].iov_len = padlen;
995 		rtm.rtm_msglen += padlen;
996 	}
997 
998 	/* mask */
999 	iov[iovcnt].iov_base = &sin;
1000 	iov[iovcnt++].iov_len = sizeof(sin);
1001 	rtm.rtm_msglen += sizeof(sin);
1002 	padlen = ROUNDUP(sizeof(sin)) - sizeof(sin);
1003 	if (padlen > 0) {
1004 		iov[iovcnt].iov_base = &pad;
1005 		iov[iovcnt++].iov_len = padlen;
1006 		rtm.rtm_msglen += padlen;
1007 	}
1008 
1009 	if (writev(routesock, iov, iovcnt) == -1)
1010 		log_warn("failed to send route message");
1011 }
1012 
1013 void
1014 parse_dhcp_lease(int fd)
1015 {
1016 	FILE	 *f;
1017 	char	 *line = NULL, *cur_ns = NULL, *ns = NULL;
1018 	size_t	  linesize = 0;
1019 	ssize_t	  linelen;
1020 	time_t	  epoch = 0, lease_time = 0, now;
1021 	char	**tok, *toks[4], *p;
1022 
1023 	if((f = fdopen(fd, "r")) == NULL) {
1024 		log_warn("cannot read dhcp lease");
1025 		close(fd);
1026 		return;
1027 	}
1028 
1029 	now = time(NULL);
1030 
1031 	while ((linelen = getline(&line, &linesize, f)) != -1) {
1032 		for (tok = toks; tok < &toks[3] && (*tok = strsep(&line, " \t"))
1033 		    != NULL;) {
1034 			if (**tok != '\0')
1035 				tok++;
1036 		}
1037 		*tok = NULL;
1038 		if (strcmp(toks[0], "option") == 0) {
1039 			if (strcmp(toks[1], "domain-name-servers") == 0) {
1040 				if((p = strchr(toks[2], ';')) != NULL) {
1041 					*p='\0';
1042 					cur_ns = strdup(toks[2]);
1043 				}
1044 			}
1045 			if (strcmp(toks[1], "dhcp-lease-time") == 0) {
1046 				if((p = strchr(toks[2], ';')) != NULL) {
1047 					*p='\0';
1048 					lease_time = strtonum(toks[2], 0,
1049 					    INT64_MAX, NULL);
1050 				}
1051 			}
1052 		} else if (strcmp(toks[0], "epoch") == 0) {
1053 			if((p = strchr(toks[1], ';')) != NULL) {
1054 				*p='\0';
1055 				epoch = strtonum(toks[1], 0,
1056 				    INT64_MAX, NULL);
1057 			}
1058 		}
1059 		else if (*toks[0] == '}') {
1060 			if (epoch + lease_time > now ) {
1061 				free(ns);
1062 				ns = cur_ns;
1063 			} else /* expired lease */
1064 				free(cur_ns);
1065 		}
1066 	}
1067 	free(line);
1068 
1069 	if (ferror(f))
1070 		log_warn("getline");
1071 	fclose(f);
1072 
1073 	if (ns != NULL) {
1074 		log_debug("%s: ns: %s", __func__, ns);
1075 		frontend_imsg_compose_resolver(IMSG_FORWARDER, 0, ns,
1076 		    strlen(ns) + 1);
1077 	}
1078 }
1079 
1080 
1081 void
1082 add_new_ta(struct trust_anchor_head *tah, char *val)
1083 {
1084 
1085 	struct trust_anchor	*ta, *i;
1086 	int			 cmp;
1087 
1088 	if ((ta = malloc(sizeof(*ta))) == NULL)
1089 		fatal("%s", __func__);
1090 	if ((ta->ta = strdup(val)) == NULL)
1091 		fatal("%s", __func__);
1092 
1093 	/* keep the list sorted to prevent churn if the order changes in DNS */
1094 	TAILQ_FOREACH(i, tah, entry) {
1095 		cmp = strcmp(i->ta, ta->ta);
1096 		if ( cmp == 0) {
1097 			/* duplicate */
1098 			free(ta->ta);
1099 			free(ta);
1100 			return;
1101 		} else if (cmp > 0) {
1102 			TAILQ_INSERT_BEFORE(i, ta, entry);
1103 			return;
1104 		}
1105 	}
1106 	TAILQ_INSERT_TAIL(tah, ta, entry);
1107 }
1108 
1109 void
1110 free_tas(struct trust_anchor_head *tah)
1111 {
1112 	struct trust_anchor	*ta;
1113 
1114 	while ((ta = TAILQ_FIRST(tah))) {
1115 		TAILQ_REMOVE(tah, ta, entry);
1116 		free(ta->ta);
1117 		free(ta);
1118 	}
1119 }
1120 
1121 int
1122 merge_tas(struct trust_anchor_head *newh, struct trust_anchor_head *oldh)
1123 {
1124 	struct trust_anchor	*i, *j;
1125 	int			 chg = 0;
1126 
1127 	j = TAILQ_FIRST(oldh);
1128 
1129 	TAILQ_FOREACH(i, newh, entry) {
1130 		if (j == NULL || strcmp(i->ta, j->ta) != 0) {
1131 			chg = 1;
1132 			break;
1133 		}
1134 		j = TAILQ_NEXT(j, entry);
1135 	}
1136 	if (j!= NULL)
1137 		chg = 1;
1138 
1139 	if (chg) {
1140 		free_tas(oldh);
1141 		while((i = TAILQ_FIRST(newh)) != NULL) {
1142 			TAILQ_REMOVE(newh, i, entry);
1143 			TAILQ_INSERT_TAIL(oldh, i, entry);
1144 		}
1145 	} else {
1146 		free_tas(newh);
1147 	}
1148 	return (chg);
1149 }
1150 
1151 void
1152 parse_trust_anchor(struct trust_anchor_head *tah, int fd)
1153 {
1154 	size_t	 len, dname_len;
1155 	ssize_t	 n, sz;
1156 	uint8_t	 rr[LDNS_RR_BUF_SIZE];
1157 	char	*str, *p, buf[512], *line;
1158 
1159 	sz = 0;
1160 	str = NULL;
1161 
1162 	while ((n = read(fd, buf, sizeof(buf))) > 0) {
1163 		p = recallocarray(str, sz, sz + n, 1);
1164 		if (p == NULL) {
1165 			log_warn("%s", __func__);
1166 			goto out;
1167 		}
1168 		str = p;
1169 		memcpy(str + sz, buf, n);
1170 		sz += n;
1171 	}
1172 
1173 	if (n == -1) {
1174 		log_warn("%s", __func__);
1175 		goto out;
1176 	}
1177 
1178 	/* make it a string */
1179 	p = recallocarray(str, sz, sz + 1, 1);
1180 	if (p == NULL) {
1181 		log_warn("%s", __func__);
1182 		goto out;
1183 	}
1184 	str = p;
1185 	sz++;
1186 
1187 	len = sizeof(rr);
1188 
1189 	while ((line = strsep(&str, "\n")) != NULL) {
1190 		if (sldns_str2wire_rr_buf(line, rr, &len, &dname_len,
1191 		    172800, NULL, 0, NULL, 0) != 0)
1192 			continue;
1193 		if (sldns_wirerr_get_type(rr, len, dname_len) ==
1194 		    LDNS_RR_TYPE_DNSKEY)
1195 			add_new_ta(tah, line);
1196 	}
1197 
1198 out:
1199 	free(str);
1200 	return;
1201 }
1202 
1203 void
1204 send_trust_anchors(struct trust_anchor_head *tah)
1205 {
1206 	struct trust_anchor	*ta;
1207 
1208 	TAILQ_FOREACH(ta, tah, entry)
1209 		frontend_imsg_compose_resolver(IMSG_NEW_TA, 0, ta->ta,
1210 		    strlen(ta->ta) + 1);
1211 	frontend_imsg_compose_resolver(IMSG_NEW_TAS_DONE, 0, NULL, 0);
1212 }
1213 
1214 void
1215 write_trust_anchors(struct trust_anchor_head *tah, int fd)
1216 {
1217 	struct trust_anchor	*ta;
1218 	size_t			 len = 0;
1219 	ssize_t			 n;
1220 	char			*str;
1221 
1222 	log_debug("%s", __func__);
1223 
1224 	if (lseek(fd, 0, SEEK_SET) == -1) {
1225 		log_warn("%s", __func__);
1226 		goto out;
1227 	}
1228 
1229 	TAILQ_FOREACH(ta, tah, entry) {
1230 		if ((n = asprintf(&str, "%s\n", ta->ta)) == -1) {
1231 			log_warn("%s", __func__);
1232 			len = 0;
1233 			goto out;
1234 		}
1235 		len += n;
1236 		if (write(fd, str, n) != n) {
1237 			log_warn("%s", __func__);
1238 			free(str);
1239 			len = 0;
1240 			goto out;
1241 		}
1242 		free(str);
1243 	}
1244 out:
1245 	ftruncate(fd, len);
1246 	fsync(fd);
1247 }
1248