xref: /openbsd-src/sbin/unwind/frontend.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$OpenBSD: frontend.c,v 1.18 2019/03/24 17:55:58 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 "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 uw_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 	uw_process = PROC_FRONTEND;
148 	setproctitle("%s", log_procnames[uw_process]);
149 	log_procinit(log_procnames[uw_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, datalen));
244 }
245 
246 int
247 frontend_imsg_compose_resolver(int type, pid_t pid, void *data,
248     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,
256     uint16_t datalen)
257 {
258 	return (imsg_compose_event(iev_captiveportal, type, 0, pid, -1, data,
259 	    datalen));
260 }
261 
262 void
263 frontend_dispatch_main(int fd, short event, void *bula)
264 {
265 	static struct uw_conf	*nconf;
266 	struct uw_forwarder	*uw_forwarder;
267 	struct imsg		 imsg;
268 	struct imsgev		*iev = bula;
269 	struct imsgbuf		*ibuf = &iev->ibuf;
270 	int			 n, shut = 0;
271 
272 	if (event & EV_READ) {
273 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
274 			fatal("imsg_read error");
275 		if (n == 0)	/* Connection closed. */
276 			shut = 1;
277 	}
278 	if (event & EV_WRITE) {
279 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
280 			fatal("msgbuf_write");
281 		if (n == 0)	/* Connection closed. */
282 			shut = 1;
283 	}
284 
285 	for (;;) {
286 		if ((n = imsg_get(ibuf, &imsg)) == -1)
287 			fatal("%s: imsg_get error", __func__);
288 		if (n == 0)	/* No more messages. */
289 			break;
290 
291 		switch (imsg.hdr.type) {
292 		case IMSG_SOCKET_IPC_RESOLVER:
293 			/*
294 			 * Setup pipe and event handler to the resolver
295 			 * process.
296 			 */
297 			if (iev_resolver) {
298 				fatalx("%s: received unexpected imsg fd "
299 				    "to frontend", __func__);
300 				break;
301 			}
302 			if ((fd = imsg.fd) == -1) {
303 				fatalx("%s: expected to receive imsg fd to "
304 				   "frontend but didn't receive any",
305 				   __func__);
306 				break;
307 			}
308 
309 			iev_resolver = malloc(sizeof(struct imsgev));
310 			if (iev_resolver == NULL)
311 				fatal(NULL);
312 
313 			imsg_init(&iev_resolver->ibuf, fd);
314 			iev_resolver->handler = frontend_dispatch_resolver;
315 			iev_resolver->events = EV_READ;
316 
317 			event_set(&iev_resolver->ev, iev_resolver->ibuf.fd,
318 			    iev_resolver->events, iev_resolver->handler,
319 			    iev_resolver);
320 			event_add(&iev_resolver->ev, NULL);
321 			break;
322 		case IMSG_SOCKET_IPC_CAPTIVEPORTAL:
323 			/*
324 			 * Setup pipe and event handler to the captiveportal
325 			 * process.
326 			 */
327 			if (iev_captiveportal) {
328 				fatalx("%s: received unexpected imsg fd "
329 				    "to frontend", __func__);
330 				break;
331 			}
332 			if ((fd = imsg.fd) == -1) {
333 				fatalx("%s: expected to receive imsg fd to "
334 				   "frontend but didn't receive any",
335 				   __func__);
336 				break;
337 			}
338 
339 			iev_captiveportal = malloc(sizeof(struct imsgev));
340 			if (iev_captiveportal == NULL)
341 				fatal(NULL);
342 
343 			imsg_init(&iev_captiveportal->ibuf, fd);
344 			iev_captiveportal->handler =
345 			    frontend_dispatch_captiveportal;
346 			iev_captiveportal->events = EV_READ;
347 
348 			event_set(&iev_captiveportal->ev,
349 			    iev_captiveportal->ibuf.fd,
350 			    iev_captiveportal->events,
351 			    iev_captiveportal->handler, iev_captiveportal);
352 			event_add(&iev_captiveportal->ev, NULL);
353 			break;
354 		case IMSG_RECONF_CONF:
355 			if (nconf != NULL)
356 				fatalx("%s: IMSG_RECONF_CONF already in "
357 				    "progress", __func__);
358 			if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_conf))
359 				fatalx("%s: IMSG_RECONF_CONF wrong length: %lu",
360 				    __func__, IMSG_DATA_SIZE(imsg));
361 			if ((nconf = malloc(sizeof(struct uw_conf))) == NULL)
362 				fatal(NULL);
363 			memcpy(nconf, imsg.data, sizeof(struct uw_conf));
364 			nconf->captive_portal_host = NULL;
365 			nconf->captive_portal_path = NULL;
366 			nconf->captive_portal_expected_response = NULL;
367 			SIMPLEQ_INIT(&nconf->uw_forwarder_list);
368 			SIMPLEQ_INIT(&nconf->uw_dot_forwarder_list);
369 			break;
370 		case IMSG_RECONF_CAPTIVE_PORTAL_HOST:
371 			/* make sure this is a string */
372 			((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0';
373 			if ((nconf->captive_portal_host = strdup(imsg.data)) ==
374 			    NULL)
375 				fatal("%s: strdup", __func__);
376 			break;
377 		case IMSG_RECONF_CAPTIVE_PORTAL_PATH:
378 			/* make sure this is a string */
379 			((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0';
380 			if ((nconf->captive_portal_path = strdup(imsg.data)) ==
381 			    NULL)
382 				fatal("%s: strdup", __func__);
383 			break;
384 		case IMSG_RECONF_CAPTIVE_PORTAL_EXPECTED_RESPONSE:
385 			/* make sure this is a string */
386 			((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0';
387 			if ((nconf->captive_portal_expected_response =
388 			    strdup(imsg.data)) == NULL)
389 				fatal("%s: strdup", __func__);
390 			break;
391 		case IMSG_RECONF_FORWARDER:
392 			if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_forwarder))
393 				fatalx("%s: IMSG_RECONF_FORWARDER wrong length:"
394 				    " %lu", __func__, IMSG_DATA_SIZE(imsg));
395 			if ((uw_forwarder = malloc(sizeof(struct
396 			    uw_forwarder))) == NULL)
397 				fatal(NULL);
398 			memcpy(uw_forwarder, imsg.data, sizeof(struct
399 			    uw_forwarder));
400 			SIMPLEQ_INSERT_TAIL(&nconf->uw_forwarder_list,
401 			    uw_forwarder, entry);
402 			break;
403 		case IMSG_RECONF_DOT_FORWARDER:
404 			if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_forwarder))
405 				fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong "
406 				    "length: %lu", __func__,
407 				    IMSG_DATA_SIZE(imsg));
408 			if ((uw_forwarder = malloc(sizeof(struct
409 			    uw_forwarder))) == NULL)
410 				fatal(NULL);
411 			memcpy(uw_forwarder, imsg.data, sizeof(struct
412 			    uw_forwarder));
413 			SIMPLEQ_INSERT_TAIL(&nconf->uw_dot_forwarder_list,
414 			    uw_forwarder, entry);
415 			break;
416 		case IMSG_RECONF_END:
417 			if (nconf == NULL)
418 				fatalx("%s: IMSG_RECONF_END without "
419 				    "IMSG_RECONF_CONF", __func__);
420 			merge_config(frontend_conf, nconf);
421 			nconf = NULL;
422 			break;
423 		case IMSG_UDP6SOCK:
424 			if (udp6sock != -1)
425 				fatalx("%s: received unexpected udp6sock",
426 				    __func__);
427 			if ((udp6sock = imsg.fd) == -1)
428 				fatalx("%s: expected to receive imsg "
429 				    "UDP6 fd but didn't receive any", __func__);
430 			event_set(&udp6ev.ev, udp6sock, EV_READ | EV_PERSIST,
431 			    udp_receive, &udp6ev);
432 			event_add(&udp6ev.ev, NULL);
433 			break;
434 		case IMSG_UDP4SOCK:
435 			if (udp4sock != -1)
436 				fatalx("%s: received unexpected udp4sock",
437 				    __func__);
438 			if ((udp4sock = imsg.fd) == -1)
439 				fatalx("%s: expected to receive imsg "
440 				    "UDP4 fd but didn't receive any", __func__);
441 			event_set(&udp4ev.ev, udp4sock, EV_READ | EV_PERSIST,
442 			    udp_receive, &udp4ev);
443 			event_add(&udp4ev.ev, NULL);
444 			break;
445 		case IMSG_ROUTESOCK:
446 			if (routesock != -1)
447 				fatalx("%s: received unexpected routesock",
448 				    __func__);
449 			if ((fd = imsg.fd) == -1)
450 				fatalx("%s: expected to receive imsg "
451 				    "routesocket fd but didn't receive any",
452 				    __func__);
453 			routesock = fd;
454 			event_set(&ev_route, fd, EV_READ | EV_PERSIST,
455 			    route_receive, NULL);
456 			break;
457 		case IMSG_STARTUP:
458 			frontend_startup();
459 			break;
460 		case IMSG_CONTROLFD:
461 			if (control_state.fd != -1)
462 				fatalx("%s: received unexpected controlsock",
463 				    __func__);
464 			if ((fd = imsg.fd) == -1)
465 				fatalx("%s: expected to receive imsg control "
466 				    "fd but didn't receive any", __func__);
467 			control_state.fd = fd;
468 			/* Listen on control socket. */
469 			TAILQ_INIT(&ctl_conns);
470 			control_listen();
471 			break;
472 		case IMSG_LEASEFD:
473 			if ((fd = imsg.fd) == -1)
474 				fatalx("%s: expected to receive imsg dhcp "
475 				   "lease fd but didn't receive any", __func__);
476 			parse_dhcp_lease(fd);
477 			break;
478 		case IMSG_TAFD:
479 			if ((ta_fd = imsg.fd) != -1)
480 				parse_trust_anchor(&trust_anchors, ta_fd);
481 			if (!TAILQ_EMPTY(&trust_anchors))
482 				send_trust_anchors(&trust_anchors);
483 			else
484 				send_trust_anchors(&built_in_trust_anchors);
485 			break;
486 		default:
487 			log_debug("%s: error handling imsg %d", __func__,
488 			    imsg.hdr.type);
489 			break;
490 		}
491 		imsg_free(&imsg);
492 	}
493 	if (!shut)
494 		imsg_event_add(iev);
495 	else {
496 		/* This pipe is dead. Remove its event handler. */
497 		event_del(&iev->ev);
498 		event_loopexit(NULL);
499 	}
500 }
501 
502 void
503 frontend_dispatch_resolver(int fd, short event, void *bula)
504 {
505 	static struct pending_query	*pq;
506 	struct imsgev			*iev = bula;
507 	struct imsgbuf			*ibuf = &iev->ibuf;
508 	struct imsg			 imsg;
509 	struct query_imsg		*query_imsg;
510 	int				 n, shut = 0, chg;
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_DATA_SIZE(imsg) != sizeof(*query_imsg))
534 				fatalx("%s: IMSG_ANSWER_HEADER wrong length: "
535 				    "%lu", __func__, IMSG_DATA_SIZE(imsg));
536 			query_imsg = (struct query_imsg *)imsg.data;
537 			if ((pq = find_pending_query(query_imsg->id)) ==
538 			    NULL) {
539 				log_warnx("cannot find pending query %llu",
540 				    query_imsg->id);
541 				break;
542 			}
543 			if (query_imsg->err) {
544 				send_answer(pq, NULL, 0);
545 				pq = NULL;
546 				break;
547 			}
548 			pq->bogus = query_imsg->bogus;
549 			break;
550 		case IMSG_ANSWER:
551 			if (pq == NULL)
552 				fatalx("IMSG_ANSWER without HEADER");
553 			send_answer(pq, imsg.data, IMSG_DATA_SIZE(imsg));
554 			break;
555 		case IMSG_RESOLVER_DOWN:
556 			log_debug("%s: IMSG_RESOLVER_DOWN", __func__);
557 			if (udp4sock != -1) {
558 				event_del(&udp4ev.ev);
559 				close(udp4sock);
560 				udp4sock = -1;
561 			}
562 			if (udp6sock != -1) {
563 				event_del(&udp6ev.ev);
564 				close(udp6sock);
565 				udp6sock = -1;
566 			}
567 			break;
568 		case IMSG_RESOLVER_UP:
569 			log_debug("%s: IMSG_RESOLVER_UP", __func__);
570 			frontend_imsg_compose_main(IMSG_OPEN_PORTS, 0, NULL, 0);
571 			break;
572 		case IMSG_CTL_RESOLVER_INFO:
573 		case IMSG_CTL_CAPTIVEPORTAL_INFO:
574 		case IMSG_CTL_RESOLVER_WHY_BOGUS:
575 		case IMSG_CTL_RESOLVER_HISTOGRAM:
576 		case IMSG_CTL_END:
577 			control_imsg_relay(&imsg);
578 			break;
579 		case IMSG_NEW_TA:
580 			/* make sure this is a string */
581 			((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0';
582 			add_new_ta(&new_trust_anchors, imsg.data);
583 			break;
584 		case IMSG_NEW_TAS_ABORT:
585 			log_debug("%s: IMSG_NEW_TAS_ABORT", __func__);
586 			free_tas(&new_trust_anchors);
587 			break;
588 		case IMSG_NEW_TAS_DONE:
589 			chg = merge_tas(&new_trust_anchors, &trust_anchors);
590 			log_debug("%s: IMSG_NEW_TAS_DONE: change: %d",
591 			    __func__, chg);
592 			if (chg) {
593 				send_trust_anchors(&trust_anchors);
594 			}
595 			/*
596 			 * always write trust anchors, the modify date on
597 			 * the file is an indication when we made progress
598 			 */
599 			if (ta_fd != -1)
600 				write_trust_anchors(&trust_anchors, ta_fd);
601 			break;
602 		default:
603 			log_debug("%s: error handling imsg %d", __func__,
604 			    imsg.hdr.type);
605 			break;
606 		}
607 		imsg_free(&imsg);
608 	}
609 	if (!shut)
610 		imsg_event_add(iev);
611 	else {
612 		/* This pipe is dead. Remove its event handler. */
613 		event_del(&iev->ev);
614 		event_loopexit(NULL);
615 	}
616 }
617 
618 void
619 frontend_dispatch_captiveportal(int fd, short event, void *bula)
620 {
621 	struct imsgev	*iev = bula;
622 	struct imsgbuf	*ibuf = &iev->ibuf;
623 	struct imsg	 imsg;
624 	int		 n, shut = 0;
625 
626 	if (event & EV_READ) {
627 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
628 			fatal("imsg_read error");
629 		if (n == 0)	/* Connection closed. */
630 			shut = 1;
631 	}
632 	if (event & EV_WRITE) {
633 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
634 			fatal("msgbuf_write");
635 		if (n == 0)	/* Connection closed. */
636 			shut = 1;
637 	}
638 
639 	for (;;) {
640 		if ((n = imsg_get(ibuf, &imsg)) == -1)
641 			fatal("%s: imsg_get error", __func__);
642 		if (n == 0)	/* No more messages. */
643 			break;
644 
645 		switch (imsg.hdr.type) {
646 		default:
647 			log_debug("%s: error handling imsg %d", __func__,
648 			    imsg.hdr.type);
649 			break;
650 		}
651 		imsg_free(&imsg);
652 	}
653 	if (!shut)
654 		imsg_event_add(iev);
655 	else {
656 		/* This pipe is dead. Remove its event handler. */
657 		event_del(&iev->ev);
658 		event_loopexit(NULL);
659 	}
660 }
661 
662 void
663 frontend_startup(void)
664 {
665 	if (!event_initialized(&ev_route))
666 		fatalx("%s: did not receive a route socket from the main "
667 		    "process", __func__);
668 
669 	event_add(&ev_route, NULL);
670 
671 	frontend_imsg_compose_main(IMSG_STARTUP_DONE, 0, NULL, 0);
672 	rtmget_default();
673 }
674 
675 void
676 udp_receive(int fd, short events, void *arg)
677 {
678 	struct udp_ev		*udpev = (struct udp_ev *)arg;
679 	struct pending_query	*pq;
680 	struct query_imsg	*query_imsg;
681 	ssize_t			 len, rem_len, buf_len;
682 	uint16_t		 qdcount, ancount, nscount, arcount, t, c;
683 	uint8_t			*queryp;
684 	char			*str_from, *str, buf[1024], *bufp;
685 
686 	if ((len = recvmsg(fd, &udpev->rcvmhdr, 0)) < 0) {
687 		log_warn("recvmsg");
688 		return;
689 	}
690 
691 	bufp = buf;
692 	buf_len = sizeof(buf);
693 
694 	str_from = ip_port((struct sockaddr *)&udpev->from);
695 
696 	if (len < LDNS_HEADER_SIZE) {
697 		log_warnx("bad query: too short, from: %s", str_from);
698 		return;
699 	}
700 
701 	qdcount = LDNS_QDCOUNT(udpev->query);
702 	ancount = LDNS_ANCOUNT(udpev->query);
703 	nscount = LDNS_NSCOUNT(udpev->query);
704 	arcount = LDNS_ARCOUNT(udpev->query);
705 
706 	if (qdcount != 1 && ancount != 0 && nscount != 0 && arcount != 0) {
707 		log_warnx("invalid query from %s, qdcount: %d, ancount: %d "
708 		    "nscount: %d, arcount: %d", str_from, qdcount, ancount,
709 		    nscount, arcount);
710 		return;
711 	}
712 
713 	log_debug("query from %s", str_from);
714 	if ((str = sldns_wire2str_pkt(udpev->query, len)) != NULL) {
715 		log_debug("%s", str);
716 		free(str);
717 	}
718 
719 	queryp = udpev->query;
720 	rem_len = len;
721 
722 	queryp += LDNS_HEADER_SIZE;
723 	rem_len -= LDNS_HEADER_SIZE;
724 
725 	sldns_wire2str_dname_scan(&queryp, &rem_len, &bufp, &buf_len,
726 	     udpev->query, len);
727 
728 	if (rem_len < 4) {
729 		log_warnx("malformed query");
730 		return;
731 	}
732 
733 	t = sldns_read_uint16(queryp);
734 	c = sldns_read_uint16(queryp+2);
735 	queryp += 4;
736 	rem_len -= 4;
737 
738 	if ((pq = malloc(sizeof(*pq))) == NULL) {
739 		log_warn(NULL);
740 		return;
741 	}
742 
743 	if ((pq->query = malloc(len)) == NULL) {
744 		log_warn(NULL);
745 		free(pq);
746 		return;
747 	}
748 
749 	do {
750 		arc4random_buf(&pq->imsg_id, sizeof(pq->imsg_id));
751 	} while(find_pending_query(pq->imsg_id) != NULL);
752 
753 	memcpy(pq->query, udpev->query, len);
754 	pq->len = len;
755 	pq->from = udpev->from;
756 	pq->fd = fd;
757 
758 	if ((query_imsg = calloc(1, sizeof(*query_imsg))) == NULL) {
759 		log_warn(NULL);
760 		return;
761 	}
762 
763 	if (strlcpy(query_imsg->qname, buf, sizeof(query_imsg->qname)) >=
764 	    sizeof(buf)) {
765 		log_warnx("qname too long");
766 		free(query_imsg);
767 		/* XXX SERVFAIL */
768 		free(pq->query);
769 		free(pq);
770 		return;
771 	}
772 	query_imsg->id = pq->imsg_id;
773 	query_imsg->t = t;
774 	query_imsg->c = c;
775 
776 	if (frontend_imsg_compose_resolver(IMSG_QUERY, 0, query_imsg,
777 	    sizeof(*query_imsg)) != -1) {
778 		TAILQ_INSERT_TAIL(&pending_queries, pq, entry);
779 	} else {
780 		free(query_imsg);
781 		/* XXX SERVFAIL */
782 		free(pq->query);
783 		free(pq);
784 	}
785 }
786 
787 void
788 send_answer(struct pending_query *pq, uint8_t *answer, ssize_t len)
789 {
790 	log_debug("result for %s", ip_port((struct sockaddr*)&pq->from));
791 
792 	if (answer == NULL) {
793 		answer = pq->query;
794 		len = pq->len;
795 
796 		LDNS_QR_SET(answer);
797 		LDNS_RA_SET(answer);
798 		LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
799 	} else {
800 		if (pq->bogus) {
801 			if(LDNS_CD_WIRE(pq->query)) {
802 				LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
803 				LDNS_CD_SET(answer);
804 			} else {
805 				answer = pq->query;
806 				len = pq->len;
807 
808 				LDNS_QR_SET(answer);
809 				LDNS_RA_SET(answer);
810 				LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
811 			}
812 		} else {
813 			LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
814 		}
815 	}
816 
817 	if(sendto(pq->fd, answer, len, 0, (struct sockaddr *)&pq->from,
818 	    pq->from.ss_len) == -1)
819 		log_warn("sendto");
820 
821 	TAILQ_REMOVE(&pending_queries, pq, entry);
822 	free(pq->query);
823 	free(pq);
824 }
825 
826 char*
827 ip_port(struct sockaddr *sa)
828 {
829 	static char	 hbuf[NI_MAXHOST], buf[NI_MAXHOST];
830 
831 	if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
832 	    NI_NUMERICHOST) != 0) {
833 		snprintf(buf, sizeof(buf), "%s", "(unknown)");
834 		return buf;
835 	}
836 
837 	if (sa->sa_family == AF_INET6)
838 		snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs(
839 		    ((struct sockaddr_in6 *)sa)->sin6_port));
840 	if (sa->sa_family == AF_INET)
841 		snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs(
842 		    ((struct sockaddr_in *)sa)->sin_port));
843 
844 	return buf;
845 }
846 
847 struct pending_query*
848 find_pending_query(uint64_t id)
849 {
850 	struct pending_query	*pq;
851 
852 	TAILQ_FOREACH(pq, &pending_queries, entry)
853 		if (pq->imsg_id == id)
854 			return pq;
855 	return NULL;
856 }
857 
858 void
859 route_receive(int fd, short events, void *arg)
860 {
861 	static uint8_t		*buf;
862 
863 	struct rt_msghdr	*rtm;
864 	struct sockaddr		*sa, *rti_info[RTAX_MAX];
865 	ssize_t			 n;
866 
867 	if (buf == NULL) {
868 		buf = malloc(ROUTE_SOCKET_BUF_SIZE);
869 		if (buf == NULL)
870 			fatal("malloc");
871 	}
872 	rtm = (struct rt_msghdr *)buf;
873 	if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) {
874 		if (errno == EAGAIN || errno == EINTR)
875 			return;
876 		log_warn("dispatch_rtmsg: read error");
877 		return;
878 	}
879 
880 	if (n == 0)
881 		fatal("routing socket closed");
882 
883 	if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) {
884 		log_warnx("partial rtm of %zd in buffer", n);
885 		return;
886 	}
887 
888 	if (rtm->rtm_version != RTM_VERSION)
889 		return;
890 
891 	sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen);
892 	get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
893 
894 	handle_route_message(rtm, rti_info);
895 }
896 
897 #define ROUNDUP(a) \
898 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
899 
900 void
901 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
902 {
903 	int	i;
904 
905 	for (i = 0; i < RTAX_MAX; i++) {
906 		if (addrs & (1 << i)) {
907 			rti_info[i] = sa;
908 			sa = (struct sockaddr *)((char *)(sa) +
909 			    ROUNDUP(sa->sa_len));
910 		} else
911 			rti_info[i] = NULL;
912 	}
913 }
914 
915 void
916 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
917 {
918 	char	buf[IF_NAMESIZE], *bufp;
919 
920 	switch (rtm->rtm_type) {
921 	case RTM_GET:
922 		if (rtm->rtm_errno != 0)
923 			break;
924 		if (!(rtm->rtm_flags & RTF_UP))
925 			break;
926 		if (!(rtm->rtm_addrs & RTA_DST))
927 			break;
928 		if (rti_info[RTAX_DST]->sa_family != AF_INET)
929 			break;
930 		if (((struct sockaddr_in *)rti_info[RTAX_DST])->sin_addr.
931 		    s_addr != INADDR_ANY)
932 			break;
933 		if (!(rtm->rtm_addrs & RTA_NETMASK))
934 			break;
935 		if (rti_info[RTAX_NETMASK]->sa_family != AF_INET)
936 			break;
937 		if (((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_addr.
938 		    s_addr != INADDR_ANY)
939 			break;
940 
941 		frontend_imsg_compose_main(IMSG_OPEN_DHCP_LEASE, 0,
942 		    &rtm->rtm_index, sizeof(rtm->rtm_index));
943 
944 		bufp = if_indextoname(rtm->rtm_index, buf);
945 		if (bufp)
946 			log_debug("default route is on %s", buf);
947 
948 		break;
949 	case RTM_IFINFO:
950 		frontend_imsg_compose_resolver(IMSG_RECHECK_RESOLVERS, 0, NULL,
951 		    0);
952 		break;
953 	default:
954 		break;
955 	}
956 }
957 
958 void
959 rtmget_default(void)
960 {
961 	static int		 rtm_seq;
962 	struct rt_msghdr	 rtm;
963 	struct sockaddr_in	 sin;
964 	struct iovec		 iov[5];
965 	long			 pad = 0;
966 	int			 iovcnt = 0, padlen;
967 
968 	memset(&sin, 0, sizeof(sin));
969 	sin.sin_family = AF_INET;
970 	sin.sin_len = sizeof(sin);
971 
972 	memset(&rtm, 0, sizeof(rtm));
973 
974 	rtm.rtm_version = RTM_VERSION;
975 	rtm.rtm_type = RTM_GET;
976 	rtm.rtm_msglen = sizeof(rtm);
977 	rtm.rtm_tableid = 0; /* XXX imsg->rdomain; */
978 	rtm.rtm_seq = ++rtm_seq;
979 	rtm.rtm_addrs = RTA_DST | RTA_NETMASK;
980 
981 	iov[iovcnt].iov_base = &rtm;
982 	iov[iovcnt++].iov_len = sizeof(rtm);
983 
984 	/* dst */
985 	iov[iovcnt].iov_base = &sin;
986 	iov[iovcnt++].iov_len = sizeof(sin);
987 	rtm.rtm_msglen += sizeof(sin);
988 	padlen = ROUNDUP(sizeof(sin)) - sizeof(sin);
989 	if (padlen > 0) {
990 		iov[iovcnt].iov_base = &pad;
991 		iov[iovcnt++].iov_len = padlen;
992 		rtm.rtm_msglen += padlen;
993 	}
994 
995 	/* mask */
996 	iov[iovcnt].iov_base = &sin;
997 	iov[iovcnt++].iov_len = sizeof(sin);
998 	rtm.rtm_msglen += sizeof(sin);
999 	padlen = ROUNDUP(sizeof(sin)) - sizeof(sin);
1000 	if (padlen > 0) {
1001 		iov[iovcnt].iov_base = &pad;
1002 		iov[iovcnt++].iov_len = padlen;
1003 		rtm.rtm_msglen += padlen;
1004 	}
1005 
1006 	if (writev(routesock, iov, iovcnt) == -1)
1007 		log_warn("failed to send route message");
1008 }
1009 
1010 void
1011 parse_dhcp_lease(int fd)
1012 {
1013 	FILE	 *f;
1014 	char	 *line = NULL, *cur_ns = NULL, *ns = NULL;
1015 	size_t	  linesize = 0;
1016 	ssize_t	  linelen;
1017 	time_t	  epoch = 0, lease_time = 0, now;
1018 	char	**tok, *toks[4], *p;
1019 
1020 	if((f = fdopen(fd, "r")) == NULL) {
1021 		log_warn("cannot read dhcp lease");
1022 		close(fd);
1023 		return;
1024 	}
1025 
1026 	now = time(NULL);
1027 
1028 	while ((linelen = getline(&line, &linesize, f)) != -1) {
1029 		for (tok = toks; tok < &toks[3] && (*tok = strsep(&line, " \t"))
1030 		    != NULL;) {
1031 			if (**tok != '\0')
1032 				tok++;
1033 		}
1034 		*tok = NULL;
1035 		if (strcmp(toks[0], "option") == 0) {
1036 			if (strcmp(toks[1], "domain-name-servers") == 0) {
1037 				if((p = strchr(toks[2], ';')) != NULL) {
1038 					*p='\0';
1039 					cur_ns = strdup(toks[2]);
1040 				}
1041 			}
1042 			if (strcmp(toks[1], "dhcp-lease-time") == 0) {
1043 				if((p = strchr(toks[2], ';')) != NULL) {
1044 					*p='\0';
1045 					lease_time = strtonum(toks[2], 0,
1046 					    INT64_MAX, NULL);
1047 				}
1048 			}
1049 		} else if (strcmp(toks[0], "epoch") == 0) {
1050 			if((p = strchr(toks[1], ';')) != NULL) {
1051 				*p='\0';
1052 				epoch = strtonum(toks[1], 0,
1053 				    INT64_MAX, NULL);
1054 			}
1055 		}
1056 		else if (*toks[0] == '}') {
1057 			if (epoch + lease_time > now ) {
1058 				free(ns);
1059 				ns = cur_ns;
1060 			} else /* expired lease */
1061 				free(cur_ns);
1062 		}
1063 	}
1064 	free(line);
1065 
1066 	if (ferror(f))
1067 		log_warn("getline");
1068 	fclose(f);
1069 
1070 	if (ns != NULL) {
1071 		log_debug("%s: ns: %s", __func__, ns);
1072 		frontend_imsg_compose_resolver(IMSG_FORWARDER, 0, ns,
1073 		    strlen(ns) + 1);
1074 	}
1075 }
1076 
1077 
1078 void
1079 add_new_ta(struct trust_anchor_head *tah, char *val)
1080 {
1081 	struct trust_anchor	*ta, *i;
1082 	int			 cmp;
1083 
1084 	if ((ta = malloc(sizeof(*ta))) == NULL)
1085 		fatal("%s", __func__);
1086 	if ((ta->ta = strdup(val)) == NULL)
1087 		fatal("%s", __func__);
1088 
1089 	/* keep the list sorted to prevent churn if the order changes in DNS */
1090 	TAILQ_FOREACH(i, tah, entry) {
1091 		cmp = strcmp(i->ta, ta->ta);
1092 		if ( cmp == 0) {
1093 			/* duplicate */
1094 			free(ta->ta);
1095 			free(ta);
1096 			return;
1097 		} else if (cmp > 0) {
1098 			TAILQ_INSERT_BEFORE(i, ta, entry);
1099 			return;
1100 		}
1101 	}
1102 	TAILQ_INSERT_TAIL(tah, ta, entry);
1103 }
1104 
1105 void
1106 free_tas(struct trust_anchor_head *tah)
1107 {
1108 	struct trust_anchor	*ta;
1109 
1110 	while ((ta = TAILQ_FIRST(tah))) {
1111 		TAILQ_REMOVE(tah, ta, entry);
1112 		free(ta->ta);
1113 		free(ta);
1114 	}
1115 }
1116 
1117 int
1118 merge_tas(struct trust_anchor_head *newh, struct trust_anchor_head *oldh)
1119 {
1120 	struct trust_anchor	*i, *j;
1121 	int			 chg = 0;
1122 
1123 	j = TAILQ_FIRST(oldh);
1124 
1125 	TAILQ_FOREACH(i, newh, entry) {
1126 		if (j == NULL || strcmp(i->ta, j->ta) != 0) {
1127 			chg = 1;
1128 			break;
1129 		}
1130 		j = TAILQ_NEXT(j, entry);
1131 	}
1132 	if (j != NULL)
1133 		chg = 1;
1134 
1135 	if (chg) {
1136 		free_tas(oldh);
1137 		while((i = TAILQ_FIRST(newh)) != NULL) {
1138 			TAILQ_REMOVE(newh, i, entry);
1139 			TAILQ_INSERT_TAIL(oldh, i, entry);
1140 		}
1141 	} else {
1142 		free_tas(newh);
1143 	}
1144 	return (chg);
1145 }
1146 
1147 void
1148 parse_trust_anchor(struct trust_anchor_head *tah, int fd)
1149 {
1150 	size_t	 len, dname_len;
1151 	ssize_t	 n, sz;
1152 	uint8_t	 rr[LDNS_RR_BUF_SIZE];
1153 	char	*str, *p, buf[512], *line;
1154 
1155 	sz = 0;
1156 	str = NULL;
1157 
1158 	while ((n = read(fd, buf, sizeof(buf))) > 0) {
1159 		p = recallocarray(str, sz, sz + n, 1);
1160 		if (p == NULL) {
1161 			log_warn("%s", __func__);
1162 			goto out;
1163 		}
1164 		str = p;
1165 		memcpy(str + sz, buf, n);
1166 		sz += n;
1167 	}
1168 
1169 	if (n == -1) {
1170 		log_warn("%s", __func__);
1171 		goto out;
1172 	}
1173 
1174 	/* make it a string */
1175 	p = recallocarray(str, sz, sz + 1, 1);
1176 	if (p == NULL) {
1177 		log_warn("%s", __func__);
1178 		goto out;
1179 	}
1180 	str = p;
1181 	sz++;
1182 
1183 	len = sizeof(rr);
1184 
1185 	while ((line = strsep(&str, "\n")) != NULL) {
1186 		if (sldns_str2wire_rr_buf(line, rr, &len, &dname_len,
1187 		    ROOT_DNSKEY_TTL, NULL, 0, NULL, 0) != 0)
1188 			continue;
1189 		if (sldns_wirerr_get_type(rr, len, dname_len) ==
1190 		    LDNS_RR_TYPE_DNSKEY)
1191 			add_new_ta(tah, line);
1192 	}
1193 
1194 out:
1195 	free(str);
1196 	return;
1197 }
1198 
1199 void
1200 send_trust_anchors(struct trust_anchor_head *tah)
1201 {
1202 	struct trust_anchor	*ta;
1203 
1204 	TAILQ_FOREACH(ta, tah, entry)
1205 		frontend_imsg_compose_resolver(IMSG_NEW_TA, 0, ta->ta,
1206 		    strlen(ta->ta) + 1);
1207 	frontend_imsg_compose_resolver(IMSG_NEW_TAS_DONE, 0, NULL, 0);
1208 }
1209 
1210 void
1211 write_trust_anchors(struct trust_anchor_head *tah, int fd)
1212 {
1213 	struct trust_anchor	*ta;
1214 	size_t			 len = 0;
1215 	ssize_t			 n;
1216 	char			*str;
1217 
1218 	log_debug("%s", __func__);
1219 
1220 	if (lseek(fd, 0, SEEK_SET) == -1) {
1221 		log_warn("%s", __func__);
1222 		goto out;
1223 	}
1224 
1225 	TAILQ_FOREACH(ta, tah, entry) {
1226 		if ((n = asprintf(&str, "%s\n", ta->ta)) == -1) {
1227 			log_warn("%s", __func__);
1228 			len = 0;
1229 			goto out;
1230 		}
1231 		len += n;
1232 		if (write(fd, str, n) != n) {
1233 			log_warn("%s", __func__);
1234 			free(str);
1235 			len = 0;
1236 			goto out;
1237 		}
1238 		free(str);
1239 	}
1240 out:
1241 	ftruncate(fd, len);
1242 	fsync(fd);
1243 }
1244