xref: /openbsd-src/usr.sbin/relayd/relayd.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: relayd.c,v 1.130 2014/07/13 00:32:08 benno Exp $	*/
2 
3 /*
4  * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
5  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/wait.h>
24 #include <sys/resource.h>
25 #include <sys/hash.h>
26 
27 #include <net/if.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <fcntl.h>
35 #include <getopt.h>
36 #include <fnmatch.h>
37 #include <err.h>
38 #include <errno.h>
39 #include <event.h>
40 #include <unistd.h>
41 #include <ctype.h>
42 #include <pwd.h>
43 #include <sha1.h>
44 #include <md5.h>
45 
46 #include <openssl/ssl.h>
47 
48 #include "relayd.h"
49 
50 __dead void	 usage(void);
51 
52 int		 parent_configure(struct relayd *);
53 void		 parent_configure_done(struct relayd *);
54 void		 parent_reload(struct relayd *, u_int, const char *);
55 void		 parent_sig_handler(int, short, void *);
56 void		 parent_shutdown(struct relayd *);
57 int		 parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *);
58 int		 parent_dispatch_hce(int, struct privsep_proc *, struct imsg *);
59 int		 parent_dispatch_relay(int, struct privsep_proc *,
60 		    struct imsg *);
61 int		 parent_dispatch_ca(int, struct privsep_proc *,
62 		    struct imsg *);
63 int		 bindany(struct ctl_bindany *);
64 
65 struct relayd			*relayd_env;
66 
67 static struct privsep_proc procs[] = {
68 	{ "pfe",	PROC_PFE, parent_dispatch_pfe, pfe },
69 	{ "hce",	PROC_HCE, parent_dispatch_hce, hce },
70 	{ "relay",	PROC_RELAY, parent_dispatch_relay, relay },
71 	{ "ca",		PROC_CA, parent_dispatch_ca, ca }
72 };
73 
74 void
75 parent_sig_handler(int sig, short event, void *arg)
76 {
77 	struct privsep	*ps = arg;
78 	int		 die = 0, status, fail, id;
79 	pid_t		 pid;
80 	char		*cause;
81 
82 	switch (sig) {
83 	case SIGTERM:
84 	case SIGINT:
85 		die = 1;
86 		/* FALLTHROUGH */
87 	case SIGCHLD:
88 		do {
89 			pid = waitpid(WAIT_ANY, &status, WNOHANG);
90 			if (pid <= 0)
91 				continue;
92 
93 			fail = 0;
94 			if (WIFSIGNALED(status)) {
95 				fail = 1;
96 				asprintf(&cause, "terminated; signal %d",
97 				    WTERMSIG(status));
98 			} else if (WIFEXITED(status)) {
99 				if (WEXITSTATUS(status) != 0) {
100 					fail = 1;
101 					asprintf(&cause, "exited abnormally");
102 				} else
103 					asprintf(&cause, "exited okay");
104 			} else
105 				fatalx("unexpected cause of SIGCHLD");
106 
107 			die = 1;
108 
109 			for (id = 0; id < PROC_MAX; id++)
110 				if (pid == ps->ps_pid[id]) {
111 					if (fail)
112 						log_warnx("lost child: %s %s",
113 						    ps->ps_title[id], cause);
114 					break;
115 				}
116 
117 			free(cause);
118 		} while (pid > 0 || (pid == -1 && errno == EINTR));
119 
120 		if (die)
121 			parent_shutdown(ps->ps_env);
122 		break;
123 	case SIGHUP:
124 		log_info("%s: reload requested with SIGHUP", __func__);
125 
126 		/*
127 		 * This is safe because libevent uses async signal handlers
128 		 * that run in the event loop and not in signal context.
129 		 */
130 		parent_reload(ps->ps_env, CONFIG_RELOAD, NULL);
131 		break;
132 	case SIGPIPE:
133 		/* ignore */
134 		break;
135 	default:
136 		fatalx("unexpected signal");
137 	}
138 }
139 
140 __dead void
141 usage(void)
142 {
143 	extern char	*__progname;
144 
145 	fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
146 	    __progname);
147 	exit(1);
148 }
149 
150 int
151 main(int argc, char *argv[])
152 {
153 	int			 c;
154 	int			 debug = 0, verbose = 0;
155 	u_int32_t		 opts = 0;
156 	struct relayd		*env;
157 	struct privsep		*ps;
158 	const char		*conffile = CONF_FILE;
159 
160 	while ((c = getopt(argc, argv, "dD:nf:v")) != -1) {
161 		switch (c) {
162 		case 'd':
163 			debug = 2;
164 			break;
165 		case 'D':
166 			if (cmdline_symset(optarg) < 0)
167 				log_warnx("could not parse macro definition %s",
168 				    optarg);
169 			break;
170 		case 'n':
171 			debug = 2;
172 			opts |= RELAYD_OPT_NOACTION;
173 			break;
174 		case 'f':
175 			conffile = optarg;
176 			break;
177 		case 'v':
178 			verbose++;
179 			opts |= RELAYD_OPT_VERBOSE;
180 			break;
181 		default:
182 			usage();
183 		}
184 	}
185 
186 	log_init(debug ? debug : 1);	/* log to stderr until daemonized */
187 
188 	argc -= optind;
189 	if (argc > 0)
190 		usage();
191 
192 	if ((env = calloc(1, sizeof(*env))) == NULL ||
193 	    (ps = calloc(1, sizeof(*ps))) == NULL)
194 		exit(1);
195 
196 	relayd_env = env;
197 	env->sc_ps = ps;
198 	ps->ps_env = env;
199 	TAILQ_INIT(&ps->ps_rcsocks);
200 	env->sc_conffile = conffile;
201 	env->sc_opts = opts;
202 
203 	if (parse_config(env->sc_conffile, env) == -1)
204 		exit(1);
205 
206 	if (debug)
207 		env->sc_opts |= RELAYD_OPT_LOGUPDATE;
208 
209 	if (geteuid())
210 		errx(1, "need root privileges");
211 
212 	if ((ps->ps_pw =  getpwnam(RELAYD_USER)) == NULL)
213 		errx(1, "unknown user %s", RELAYD_USER);
214 
215 	/* Configure the control socket */
216 	ps->ps_csock.cs_name = RELAYD_SOCKET;
217 
218 	log_init(debug);
219 	log_verbose(verbose);
220 
221 	if (!debug && daemon(1, 0) == -1)
222 		err(1, "failed to daemonize");
223 
224 	if (env->sc_opts & RELAYD_OPT_NOACTION)
225 		ps->ps_noaction = 1;
226 	else
227 		log_info("startup");
228 
229 	ps->ps_instances[PROC_RELAY] = env->sc_prefork_relay;
230 	ps->ps_instances[PROC_CA] = env->sc_prefork_relay;
231 	ps->ps_ninstances = env->sc_prefork_relay;
232 
233 	proc_init(ps, procs, nitems(procs));
234 
235 	setproctitle("parent");
236 
237 	event_init();
238 
239 	signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
240 	signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
241 	signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps);
242 	signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
243 	signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
244 
245 	signal_add(&ps->ps_evsigint, NULL);
246 	signal_add(&ps->ps_evsigterm, NULL);
247 	signal_add(&ps->ps_evsigchld, NULL);
248 	signal_add(&ps->ps_evsighup, NULL);
249 	signal_add(&ps->ps_evsigpipe, NULL);
250 
251 	proc_listen(ps, procs, nitems(procs));
252 
253 	if (load_config(env->sc_conffile, env) == -1) {
254 		proc_kill(env->sc_ps);
255 		exit(1);
256 	}
257 
258 	if (env->sc_opts & RELAYD_OPT_NOACTION) {
259 		fprintf(stderr, "configuration OK\n");
260 		proc_kill(env->sc_ps);
261 		exit(0);
262 	}
263 
264 	if (env->sc_flags & (F_SSL|F_SSLCLIENT))
265 		ssl_init(env);
266 
267 	if (parent_configure(env) == -1)
268 		fatalx("configuration failed");
269 
270 	init_routes(env);
271 
272 	event_dispatch();
273 
274 	parent_shutdown(env);
275 	/* NOTREACHED */
276 
277 	return (0);
278 }
279 
280 int
281 parent_configure(struct relayd *env)
282 {
283 	struct table		*tb;
284 	struct rdr		*rdr;
285 	struct router		*rt;
286 	struct protocol		*proto;
287 	struct relay		*rlay;
288 	int			 id;
289 	struct ctl_flags	 cf;
290 	int			 s, ret = -1;
291 
292 	TAILQ_FOREACH(tb, env->sc_tables, entry)
293 		config_settable(env, tb);
294 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
295 		config_setrdr(env, rdr);
296 	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
297 		config_setrt(env, rt);
298 	TAILQ_FOREACH(proto, env->sc_protos, entry)
299 		config_setproto(env, proto);
300 	TAILQ_FOREACH(proto, env->sc_protos, entry)
301 		config_setrule(env, proto);
302 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
303 		/* Check for SSL Inspection */
304 		if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) ==
305 		    (F_SSL|F_SSLCLIENT) &&
306 		    rlay->rl_conf.ssl_cacert_len &&
307 		    rlay->rl_conf.ssl_cakey_len)
308 			rlay->rl_conf.flags |= F_SSLINSPECT;
309 
310 		config_setrelay(env, rlay);
311 	}
312 
313 	/* HCE, PFE, CA and the relays need to reload their config. */
314 	env->sc_reload = 2 + (2 * env->sc_prefork_relay);
315 
316 	for (id = 0; id < PROC_MAX; id++) {
317 		if (id == privsep_process)
318 			continue;
319 		cf.cf_opts = env->sc_opts;
320 		cf.cf_flags = env->sc_flags;
321 
322 		if ((env->sc_flags & F_NEEDPF) && id == PROC_PFE) {
323 			/* Send pf socket to the pf engine */
324 			if ((s = open(PF_SOCKET, O_RDWR)) == -1) {
325 				log_debug("%s: cannot open pf socket",
326 				    __func__);
327 				goto done;
328 			}
329 		} else
330 			s = -1;
331 
332 		proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, s,
333 		    &cf, sizeof(cf));
334 	}
335 
336 	ret = 0;
337 
338  done:
339 	config_purge(env, CONFIG_ALL & ~CONFIG_RELAYS);
340 	return (ret);
341 }
342 
343 void
344 parent_reload(struct relayd *env, u_int reset, const char *filename)
345 {
346 	if (env->sc_reload) {
347 		log_debug("%s: already in progress: %d pending",
348 		    __func__, env->sc_reload);
349 		return;
350 	}
351 
352 	/* Switch back to the default config file */
353 	if (filename == NULL || *filename == '\0')
354 		filename = env->sc_conffile;
355 
356 	log_debug("%s: level %d config file %s", __func__, reset, filename);
357 
358 	config_purge(env, CONFIG_ALL);
359 
360 	if (reset == CONFIG_RELOAD) {
361 		if (load_config(filename, env) == -1) {
362 			log_debug("%s: failed to load config file %s",
363 			    __func__, filename);
364 		}
365 
366 		config_setreset(env, CONFIG_ALL);
367 
368 		if (parent_configure(env) == -1) {
369 			log_debug("%s: failed to commit config from %s",
370 			    __func__, filename);
371 		}
372 	} else
373 		config_setreset(env, reset);
374 }
375 
376 void
377 parent_configure_done(struct relayd *env)
378 {
379 	int	 id;
380 
381 	if (env->sc_reload == 0) {
382 		log_warnx("%s: configuration already finished", __func__);
383 		return;
384 	}
385 
386 	env->sc_reload--;
387 	if (env->sc_reload == 0) {
388 		for (id = 0; id < PROC_MAX; id++) {
389 			if (id == privsep_process)
390 				continue;
391 
392 			proc_compose_imsg(env->sc_ps, id, -1, IMSG_CTL_START,
393 			    -1, NULL, 0);
394 		}
395 	}
396 }
397 
398 void
399 parent_shutdown(struct relayd *env)
400 {
401 	config_purge(env, CONFIG_ALL);
402 
403 	proc_kill(env->sc_ps);
404 	control_cleanup(&env->sc_ps->ps_csock);
405 	carp_demote_shutdown();
406 
407 	free(env->sc_ps);
408 	free(env);
409 
410 	log_info("parent terminating, pid %d", getpid());
411 
412 	exit(0);
413 }
414 
415 int
416 parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
417 {
418 	struct relayd		*env = p->p_env;
419 	struct ctl_demote	 demote;
420 	struct ctl_netroute	 crt;
421 	u_int			 v;
422 	char			*str = NULL;
423 
424 	switch (imsg->hdr.type) {
425 	case IMSG_DEMOTE:
426 		IMSG_SIZE_CHECK(imsg, &demote);
427 		memcpy(&demote, imsg->data, sizeof(demote));
428 		carp_demote_set(demote.group, demote.level);
429 		break;
430 	case IMSG_RTMSG:
431 		IMSG_SIZE_CHECK(imsg, &crt);
432 		memcpy(&crt, imsg->data, sizeof(crt));
433 		pfe_route(env, &crt);
434 		break;
435 	case IMSG_CTL_RESET:
436 		IMSG_SIZE_CHECK(imsg, &v);
437 		memcpy(&v, imsg->data, sizeof(v));
438 		parent_reload(env, v, NULL);
439 		break;
440 	case IMSG_CTL_RELOAD:
441 		if (IMSG_DATA_SIZE(imsg) > 0)
442 			str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
443 		parent_reload(env, CONFIG_RELOAD, str);
444 		if (str != NULL)
445 			free(str);
446 		break;
447 	case IMSG_CTL_SHUTDOWN:
448 		parent_shutdown(env);
449 		break;
450 	case IMSG_CFG_DONE:
451 		parent_configure_done(env);
452 		break;
453 	default:
454 		return (-1);
455 	}
456 
457 	return (0);
458 }
459 
460 int
461 parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
462 {
463 	struct relayd		*env = p->p_env;
464 	struct privsep		*ps = env->sc_ps;
465 	struct ctl_script	 scr;
466 
467 	switch (imsg->hdr.type) {
468 	case IMSG_SCRIPT:
469 		IMSG_SIZE_CHECK(imsg, &scr);
470 		bcopy(imsg->data, &scr, sizeof(scr));
471 		scr.retval = script_exec(env, &scr);
472 		proc_compose_imsg(ps, PROC_HCE, -1, IMSG_SCRIPT,
473 		    -1, &scr, sizeof(scr));
474 		break;
475 	case IMSG_SNMPSOCK:
476 		(void)snmp_setsock(env, p->p_id);
477 		break;
478 	case IMSG_CFG_DONE:
479 		parent_configure_done(env);
480 		break;
481 	default:
482 		return (-1);
483 	}
484 
485 	return (0);
486 }
487 
488 int
489 parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
490 {
491 	struct relayd		*env = p->p_env;
492 	struct privsep		*ps = env->sc_ps;
493 	struct ctl_bindany	 bnd;
494 	int			 s;
495 
496 	switch (imsg->hdr.type) {
497 	case IMSG_BINDANY:
498 		IMSG_SIZE_CHECK(imsg, &bnd);
499 		bcopy(imsg->data, &bnd, sizeof(bnd));
500 		if (bnd.bnd_proc > env->sc_prefork_relay)
501 			fatalx("pfe_dispatch_relay: "
502 			    "invalid relay proc");
503 		switch (bnd.bnd_proto) {
504 		case IPPROTO_TCP:
505 		case IPPROTO_UDP:
506 			break;
507 		default:
508 			fatalx("pfe_dispatch_relay: requested socket "
509 			    "for invalid protocol");
510 			/* NOTREACHED */
511 		}
512 		s = bindany(&bnd);
513 		proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc,
514 		    IMSG_BINDANY, s, &bnd.bnd_id, sizeof(bnd.bnd_id));
515 		break;
516 	case IMSG_CFG_DONE:
517 		parent_configure_done(env);
518 		break;
519 	default:
520 		return (-1);
521 	}
522 
523 	return (0);
524 }
525 
526 int
527 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
528 {
529 	struct relayd		*env = p->p_env;
530 
531 	switch (imsg->hdr.type) {
532 	case IMSG_CFG_DONE:
533 		parent_configure_done(env);
534 		break;
535 	default:
536 		return (-1);
537 	}
538 
539 	return (0);
540 }
541 
542 void
543 purge_table(struct tablelist *head, struct table *table)
544 {
545 	struct host		*host;
546 
547 	while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
548 		TAILQ_REMOVE(&table->hosts, host, entry);
549 		if (event_initialized(&host->cte.ev)) {
550 			event_del(&host->cte.ev);
551 			close(host->cte.s);
552 		}
553 		if (host->cte.buf != NULL)
554 			ibuf_free(host->cte.buf);
555 		if (host->cte.ssl != NULL)
556 			SSL_free(host->cte.ssl);
557 		free(host);
558 	}
559 	if (table->sendbuf != NULL)
560 		free(table->sendbuf);
561 	if (table->conf.flags & F_SSL)
562 		SSL_CTX_free(table->ssl_ctx);
563 
564 	if (head != NULL)
565 		TAILQ_REMOVE(head, table, entry);
566 	free(table);
567 }
568 
569 void
570 purge_key(char **ptr, off_t len)
571 {
572 	char	*key = *ptr;
573 
574 	if (key == NULL || len == 0)
575 		return;
576 
577 	explicit_bzero(key, len);
578 	free(key);
579 
580 	*ptr = NULL;
581 }
582 
583 void
584 purge_relay(struct relayd *env, struct relay *rlay)
585 {
586 	struct rsession		*con;
587 	struct relay_table	*rlt;
588 
589 	/* shutdown and remove relay */
590 	if (event_initialized(&rlay->rl_ev))
591 		event_del(&rlay->rl_ev);
592 	close(rlay->rl_s);
593 	TAILQ_REMOVE(env->sc_relays, rlay, rl_entry);
594 
595 	/* cleanup sessions */
596 	while ((con =
597 	    SPLAY_ROOT(&rlay->rl_sessions)) != NULL)
598 		relay_close(con, NULL);
599 
600 	/* cleanup relay */
601 	if (rlay->rl_bev != NULL)
602 		bufferevent_free(rlay->rl_bev);
603 	if (rlay->rl_dstbev != NULL)
604 		bufferevent_free(rlay->rl_dstbev);
605 
606 	purge_key(&rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len);
607 	purge_key(&rlay->rl_ssl_key, rlay->rl_conf.ssl_key_len);
608 	purge_key(&rlay->rl_ssl_ca, rlay->rl_conf.ssl_ca_len);
609 	purge_key(&rlay->rl_ssl_cakey, rlay->rl_conf.ssl_cakey_len);
610 
611 	if (rlay->rl_ssl_x509 != NULL) {
612 		X509_free(rlay->rl_ssl_x509);
613 		rlay->rl_ssl_x509 = NULL;
614 	}
615 	if (rlay->rl_ssl_pkey != NULL) {
616 		EVP_PKEY_free(rlay->rl_ssl_pkey);
617 		rlay->rl_ssl_pkey = NULL;
618 	}
619 	if (rlay->rl_ssl_cacertx509 != NULL) {
620 		X509_free(rlay->rl_ssl_cacertx509);
621 		rlay->rl_ssl_cacertx509 = NULL;
622 	}
623 	if (rlay->rl_ssl_capkey != NULL) {
624 		EVP_PKEY_free(rlay->rl_ssl_capkey);
625 		rlay->rl_ssl_capkey = NULL;
626 	}
627 
628 	if (rlay->rl_ssl_ctx != NULL)
629 		SSL_CTX_free(rlay->rl_ssl_ctx);
630 
631 	while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
632 		TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
633 		free(rlt);
634 	}
635 
636 	free(rlay);
637 }
638 
639 
640 struct kv *
641 kv_add(struct kvtree *keys, char *key, char *value)
642 {
643 	struct kv	*kv, *oldkv;
644 
645 	if (key == NULL)
646 		return (NULL);
647 	if ((kv = calloc(1, sizeof(*kv))) == NULL)
648 		return (NULL);
649 	if ((kv->kv_key = strdup(key)) == NULL) {
650 		free(kv);
651 		return (NULL);
652 	}
653 	if (value != NULL &&
654 	    (kv->kv_value = strdup(value)) == NULL) {
655 		free(kv->kv_key);
656 		free(kv);
657 		return (NULL);
658 	}
659 	TAILQ_INIT(&kv->kv_children);
660 
661 	if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) {
662 		TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry);
663 		kv->kv_parent = oldkv;
664 	}
665 
666 	return (kv);
667 }
668 
669 int
670 kv_set(struct kv *kv, char *fmt, ...)
671 {
672 	va_list		  ap;
673 	char		*value = NULL;
674 	struct kv	*ckv;
675 
676 	va_start(ap, fmt);
677 	if (vasprintf(&value, fmt, ap) == -1)
678 		return (-1);
679 	va_end(ap);
680 
681 	/* Remove all children */
682 	while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
683 		TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
684 		kv_free(ckv);
685 		free(ckv);
686 	}
687 
688 	/* Set the new value */
689 	if (kv->kv_value != NULL)
690 		free(kv->kv_value);
691 	kv->kv_value = value;
692 
693 	return (0);
694 }
695 
696 int
697 kv_setkey(struct kv *kv, char *fmt, ...)
698 {
699 	va_list  ap;
700 	char	*key = NULL;
701 
702 	va_start(ap, fmt);
703 	if (vasprintf(&key, fmt, ap) == -1)
704 		return (-1);
705 	va_end(ap);
706 
707 	if (kv->kv_key != NULL)
708 		free(kv->kv_key);
709 	kv->kv_key = key;
710 
711 	return (0);
712 }
713 
714 void
715 kv_delete(struct kvtree *keys, struct kv *kv)
716 {
717 	struct kv	*ckv;
718 
719 	RB_REMOVE(kvtree, keys, kv);
720 
721 	/* Remove all children */
722 	while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
723 		TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
724 		kv_free(ckv);
725 		free(ckv);
726 	}
727 
728 	kv_free(kv);
729 	free(kv);
730 }
731 
732 struct kv *
733 kv_extend(struct kvtree *keys, struct kv *kv, char *value)
734 {
735 	char		*newvalue;
736 
737 	if (kv == NULL) {
738 		return (NULL);
739 	} else if (kv->kv_value != NULL) {
740 		if (asprintf(&newvalue, "%s%s", kv->kv_value, value) == -1)
741 			return (NULL);
742 
743 		free(kv->kv_value);
744 		kv->kv_value = newvalue;
745 	} else if ((kv->kv_value = strdup(value)) == NULL)
746 		return (NULL);
747 
748 	return (kv);
749 }
750 
751 void
752 kv_purge(struct kvtree *keys)
753 {
754 	struct kv	*kv;
755 
756 	while ((kv = RB_MIN(kvtree, keys)) != NULL)
757 		kv_delete(keys, kv);
758 }
759 
760 void
761 kv_free(struct kv *kv)
762 {
763 	if (kv->kv_type == KEY_TYPE_NONE)
764 		return;
765 	if (kv->kv_key != NULL) {
766 		free(kv->kv_key);
767 	}
768 	kv->kv_key = NULL;
769 	if (kv->kv_value != NULL) {
770 		free(kv->kv_value);
771 	}
772 	kv->kv_value = NULL;
773 	kv->kv_matchtree = NULL;
774 	kv->kv_match = NULL;
775 	memset(kv, 0, sizeof(*kv));
776 }
777 
778 struct kv *
779 kv_inherit(struct kv *dst, struct kv *src)
780 {
781 	memset(dst, 0, sizeof(*dst));
782 	memcpy(dst, src, sizeof(*dst));
783 	TAILQ_INIT(&dst->kv_children);
784 
785 	if (src->kv_key != NULL) {
786 		if ((dst->kv_key = strdup(src->kv_key)) == NULL) {
787 			kv_free(dst);
788 			return (NULL);
789 		}
790 	}
791 	if (src->kv_value != NULL) {
792 		if ((dst->kv_value = strdup(src->kv_value)) == NULL) {
793 			kv_free(dst);
794 			return (NULL);
795 		}
796 	}
797 
798 	if (src->kv_match != NULL)
799 		dst->kv_match = src->kv_match;
800 	if (src->kv_matchtree != NULL)
801 		dst->kv_matchtree = src->kv_matchtree;
802 
803 	return (dst);
804 }
805 
806 int
807 kv_log(struct rsession *con, struct kv *kv, u_int16_t labelid,
808     enum direction dir)
809 {
810 	char	*msg;
811 
812 	if (con->se_log == NULL)
813 		return (0);
814 	if (asprintf(&msg, " %s%s%s%s%s%s%s",
815 	    dir == RELAY_DIR_REQUEST ? "[" : "{",
816 	    labelid == 0 ? "" : label_id2name(labelid),
817 	    labelid == 0 ? "" : ", ",
818 	    kv->kv_key == NULL ? "(unknown)" : kv->kv_key,
819 	    kv->kv_value == NULL ? "" : ": ",
820 	    kv->kv_value == NULL ? "" : kv->kv_value,
821 	    dir == RELAY_DIR_REQUEST ? "]" : "}") == -1)
822 		return (-1);
823 	if (evbuffer_add(con->se_log, msg, strlen(msg)) == -1) {
824 		free(msg);
825 		return (-1);
826 	}
827 	free(msg);
828 	con->se_haslog = 1;
829 	return (0);
830 }
831 
832 struct kv *
833 kv_find(struct kvtree *keys, struct kv *kv)
834 {
835 	struct kv	*match;
836 	const char	*key;
837 
838 	if (kv->kv_flags & KV_FLAG_GLOBBING) {
839 		/* Test header key using shell globbing rules */
840 		key = kv->kv_key == NULL ? "" : kv->kv_key;
841 		RB_FOREACH(match, kvtree, keys) {
842 			if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0)
843 				break;
844 		}
845 	} else {
846 		/* Fast tree-based lookup only works without globbing */
847 		match = RB_FIND(kvtree, keys, kv);
848 	}
849 
850 	return (match);
851 }
852 
853 int
854 kv_cmp(struct kv *a, struct kv *b)
855 {
856 	return (strcasecmp(a->kv_key, b->kv_key));
857 }
858 
859 RB_GENERATE(kvtree, kv, kv_node, kv_cmp);
860 
861 int
862 rule_add(struct protocol *proto, struct relay_rule *rule, const char *rulefile)
863 {
864 	struct relay_rule	*r = NULL;
865 	struct kv		*kv = NULL;
866 	FILE			*fp = NULL;
867 	char			 buf[BUFSIZ];
868 	int			 ret = -1;
869 	u_int			 i;
870 
871 	for (i = 0; i < KEY_TYPE_MAX; i++) {
872 		kv = &rule->rule_kv[i];
873 		if (kv->kv_type != i)
874 			continue;
875 
876 		switch (kv->kv_option) {
877 		case KEY_OPTION_LOG:
878 			/* log action needs a key or a file to be specified */
879 			if (kv->kv_key == NULL && rulefile == NULL &&
880 			    (kv->kv_key = strdup("*")) == NULL)
881 				goto fail;
882 			break;
883 		default:
884 			break;
885 		}
886 
887 		switch (kv->kv_type) {
888 		case KEY_TYPE_QUERY:
889 		case KEY_TYPE_PATH:
890 		case KEY_TYPE_URL:
891 			if (rule->rule_dir != RELAY_DIR_REQUEST)
892 				goto fail;
893 			break;
894 		default:
895 			break;
896 		}
897 
898 		if (kv->kv_value != NULL && strchr(kv->kv_value, '$') != NULL)
899 			kv->kv_flags |= KV_FLAG_MACRO;
900 		if (kv->kv_key != NULL && strpbrk(kv->kv_key, "*?[") != NULL)
901 			kv->kv_flags |= KV_FLAG_GLOBBING;
902 	}
903 
904 	if (rulefile == NULL) {
905 		TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
906 		return (0);
907 	}
908 
909 	if ((fp = fopen(rulefile, "r")) == NULL)
910 		goto fail;
911 
912 	while (fgets(buf, sizeof(buf), fp) != NULL) {
913 		/* strip whitespace and newline characters */
914 		buf[strcspn(buf, "\r\n\t ")] = '\0';
915 		if (!strlen(buf) || buf[0] == '#')
916 			continue;
917 
918 		if ((r = rule_inherit(rule)) == NULL)
919 			goto fail;
920 
921 		for (i = 0; i < KEY_TYPE_MAX; i++) {
922 			kv = &r->rule_kv[i];
923 			if (kv->kv_type != i)
924 				continue;
925 			if (kv->kv_key != NULL)
926 				free(kv->kv_key);
927 			if ((kv->kv_key = strdup(buf)) == NULL) {
928 				rule_free(r);
929 				free(r);
930 				goto fail;
931 			}
932 		}
933 
934 		TAILQ_INSERT_TAIL(&proto->rules, r, rule_entry);
935 	}
936 
937 	ret = 0;
938 	rule_free(rule);
939 	free(rule);
940 
941  fail:
942 	if (fp != NULL)
943 		fclose(fp);
944 	return (ret);
945 }
946 
947 struct relay_rule *
948 rule_inherit(struct relay_rule *rule)
949 {
950 	struct relay_rule	*r;
951 	u_int			 i;
952 	struct kv		*kv;
953 
954 	if ((r = calloc(1, sizeof(*r))) == NULL)
955 		return (NULL);
956 	memcpy(r, rule, sizeof(*r));
957 
958 	for (i = 0; i < KEY_TYPE_MAX; i++) {
959 		kv = &rule->rule_kv[i];
960 		if (kv->kv_type != i)
961 			continue;
962 		if (kv_inherit(&r->rule_kv[i], kv) == NULL) {
963 			free(r);
964 			return(NULL);
965 		}
966 	}
967 
968 	if (r->rule_label > 0)
969 		label_ref(r->rule_label);
970 	if (r->rule_tag > 0)
971 		tag_ref(r->rule_tag);
972 	if (r->rule_tagged > 0)
973 		tag_ref(r->rule_tagged);
974 
975 	return (r);
976 }
977 
978 void
979 rule_free(struct relay_rule *rule)
980 {
981 	u_int	i;
982 
983 	for (i = 0; i < KEY_TYPE_MAX; i++)
984 		kv_free(&rule->rule_kv[i]);
985 	if (rule->rule_label > 0)
986 		label_unref(rule->rule_label);
987 	if (rule->rule_tag > 0)
988 		tag_unref(rule->rule_tag);
989 	if (rule->rule_tagged > 0)
990 		tag_unref(rule->rule_tagged);
991 }
992 
993 void
994 rule_delete(struct relay_rules *rules, struct relay_rule *rule)
995 {
996 	TAILQ_REMOVE(rules, rule, rule_entry);
997 	rule_free(rule);
998 	free(rule);
999 }
1000 
1001 void
1002 rule_settable(struct relay_rules *rules, struct relay_table *rlt)
1003 {
1004 	struct relay_rule	*r;
1005 	char		 	 pname[TABLE_NAME_SIZE];
1006 
1007 	if (rlt->rlt_table == NULL || strlcpy(pname, rlt->rlt_table->conf.name,
1008 	    sizeof(pname)) >= sizeof(pname))
1009 		return;
1010 
1011 	pname[strcspn(pname, ":")] = '\0';
1012 
1013 	TAILQ_FOREACH(r, rules, rule_entry) {
1014 		if (r->rule_tablename[0] &&
1015 		    strcmp(pname, r->rule_tablename) == 0) {
1016 			r->rule_table = rlt;
1017 		} else {
1018 			r->rule_table = NULL;
1019 		}
1020 	}
1021 }
1022 
1023 /*
1024  * Utility functions
1025  */
1026 
1027 struct host *
1028 host_find(struct relayd *env, objid_t id)
1029 {
1030 	struct table	*table;
1031 	struct host	*host;
1032 
1033 	TAILQ_FOREACH(table, env->sc_tables, entry)
1034 		TAILQ_FOREACH(host, &table->hosts, entry)
1035 			if (host->conf.id == id)
1036 				return (host);
1037 	return (NULL);
1038 }
1039 
1040 struct table *
1041 table_find(struct relayd *env, objid_t id)
1042 {
1043 	struct table	*table;
1044 
1045 	TAILQ_FOREACH(table, env->sc_tables, entry)
1046 		if (table->conf.id == id)
1047 			return (table);
1048 	return (NULL);
1049 }
1050 
1051 struct rdr *
1052 rdr_find(struct relayd *env, objid_t id)
1053 {
1054 	struct rdr	*rdr;
1055 
1056 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1057 		if (rdr->conf.id == id)
1058 			return (rdr);
1059 	return (NULL);
1060 }
1061 
1062 struct relay *
1063 relay_find(struct relayd *env, objid_t id)
1064 {
1065 	struct relay	*rlay;
1066 
1067 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1068 		if (rlay->rl_conf.id == id)
1069 			return (rlay);
1070 	return (NULL);
1071 }
1072 
1073 struct protocol *
1074 proto_find(struct relayd *env, objid_t id)
1075 {
1076 	struct protocol	*p;
1077 
1078 	TAILQ_FOREACH(p, env->sc_protos, entry)
1079 		if (p->id == id)
1080 			return (p);
1081 	return (NULL);
1082 }
1083 
1084 struct rsession *
1085 session_find(struct relayd *env, objid_t id)
1086 {
1087 	struct relay		*rlay;
1088 	struct rsession		*con;
1089 
1090 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1091 		SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions)
1092 			if (con->se_id == id)
1093 				return (con);
1094 	return (NULL);
1095 }
1096 
1097 struct netroute *
1098 route_find(struct relayd *env, objid_t id)
1099 {
1100 	struct netroute	*nr;
1101 
1102 	TAILQ_FOREACH(nr, env->sc_routes, nr_route)
1103 		if (nr->nr_conf.id == id)
1104 			return (nr);
1105 	return (NULL);
1106 }
1107 
1108 struct router *
1109 router_find(struct relayd *env, objid_t id)
1110 {
1111 	struct router	*rt;
1112 
1113 	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
1114 		if (rt->rt_conf.id == id)
1115 			return (rt);
1116 	return (NULL);
1117 }
1118 
1119 struct host *
1120 host_findbyname(struct relayd *env, const char *name)
1121 {
1122 	struct table	*table;
1123 	struct host	*host;
1124 
1125 	TAILQ_FOREACH(table, env->sc_tables, entry)
1126 		TAILQ_FOREACH(host, &table->hosts, entry)
1127 			if (strcmp(host->conf.name, name) == 0)
1128 				return (host);
1129 	return (NULL);
1130 }
1131 
1132 struct table *
1133 table_findbyname(struct relayd *env, const char *name)
1134 {
1135 	struct table	*table;
1136 
1137 	TAILQ_FOREACH(table, env->sc_tables, entry)
1138 		if (strcmp(table->conf.name, name) == 0)
1139 			return (table);
1140 	return (NULL);
1141 }
1142 
1143 struct table *
1144 table_findbyconf(struct relayd *env, struct table *tb)
1145 {
1146 	struct table		*table;
1147 	struct table_config	 a, b;
1148 
1149 	bcopy(&tb->conf, &a, sizeof(a));
1150 	a.id = a.rdrid = 0;
1151 	a.flags &= ~(F_USED|F_BACKUP);
1152 
1153 	TAILQ_FOREACH(table, env->sc_tables, entry) {
1154 		bcopy(&table->conf, &b, sizeof(b));
1155 		b.id = b.rdrid = 0;
1156 		b.flags &= ~(F_USED|F_BACKUP);
1157 
1158 		/*
1159 		 * Compare two tables and return the existing table if
1160 		 * the configuration seems to be the same.
1161 		 */
1162 		if (bcmp(&a, &b, sizeof(b)) == 0 &&
1163 		    ((tb->sendbuf == NULL && table->sendbuf == NULL) ||
1164 		    (tb->sendbuf != NULL && table->sendbuf != NULL &&
1165 		    strcmp(tb->sendbuf, table->sendbuf) == 0)))
1166 			return (table);
1167 	}
1168 	return (NULL);
1169 }
1170 
1171 struct rdr *
1172 rdr_findbyname(struct relayd *env, const char *name)
1173 {
1174 	struct rdr	*rdr;
1175 
1176 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1177 		if (strcmp(rdr->conf.name, name) == 0)
1178 			return (rdr);
1179 	return (NULL);
1180 }
1181 
1182 struct relay *
1183 relay_findbyname(struct relayd *env, const char *name)
1184 {
1185 	struct relay	*rlay;
1186 
1187 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1188 		if (strcmp(rlay->rl_conf.name, name) == 0)
1189 			return (rlay);
1190 	return (NULL);
1191 }
1192 
1193 struct relay *
1194 relay_findbyaddr(struct relayd *env, struct relay_config *rc)
1195 {
1196 	struct relay	*rlay;
1197 
1198 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1199 		if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 &&
1200 		    rlay->rl_conf.port == rc->port)
1201 			return (rlay);
1202 	return (NULL);
1203 }
1204 
1205 EVP_PKEY *
1206 pkey_find(struct relayd *env, objid_t id)
1207 {
1208 	struct ca_pkey	*pkey;
1209 
1210 	TAILQ_FOREACH(pkey, env->sc_pkeys, pkey_entry)
1211 		if (pkey->pkey_id == id)
1212 			return (pkey->pkey);
1213 	return (NULL);
1214 }
1215 
1216 struct ca_pkey *
1217 pkey_add(struct relayd *env, EVP_PKEY *pkey, objid_t id)
1218 {
1219 	struct ca_pkey	*ca_pkey;
1220 
1221 	if (env->sc_pkeys == NULL)
1222 		fatalx("pkeys");
1223 
1224 	if ((ca_pkey = calloc(1, sizeof(*ca_pkey))) == NULL)
1225 		return (NULL);
1226 
1227 	ca_pkey->pkey = pkey;
1228 	ca_pkey->pkey_id = id;
1229 
1230 	TAILQ_INSERT_TAIL(env->sc_pkeys, ca_pkey, pkey_entry);
1231 
1232 	return (ca_pkey);
1233 }
1234 
1235 void
1236 event_again(struct event *ev, int fd, short event,
1237     void (*fn)(int, short, void *),
1238     struct timeval *start, struct timeval *end, void *arg)
1239 {
1240 	struct timeval tv_next, tv_now, tv;
1241 
1242 	getmonotime(&tv_now);
1243 	bcopy(end, &tv_next, sizeof(tv_next));
1244 	timersub(&tv_now, start, &tv_now);
1245 	timersub(&tv_next, &tv_now, &tv_next);
1246 
1247 	bzero(&tv, sizeof(tv));
1248 	if (timercmp(&tv_next, &tv, >))
1249 		bcopy(&tv_next, &tv, sizeof(tv));
1250 
1251 	event_del(ev);
1252 	event_set(ev, fd, event, fn, arg);
1253 	event_add(ev, &tv);
1254 }
1255 
1256 int
1257 expand_string(char *label, size_t len, const char *srch, const char *repl)
1258 {
1259 	char *tmp;
1260 	char *p, *q;
1261 
1262 	if ((tmp = calloc(1, len)) == NULL) {
1263 		log_debug("%s: calloc", __func__);
1264 		return (-1);
1265 	}
1266 	p = q = label;
1267 	while ((q = strstr(p, srch)) != NULL) {
1268 		*q = '\0';
1269 		if ((strlcat(tmp, p, len) >= len) ||
1270 		    (strlcat(tmp, repl, len) >= len)) {
1271 			log_debug("%s: string too long", __func__);
1272 			free(tmp);
1273 			return (-1);
1274 		}
1275 		q += strlen(srch);
1276 		p = q;
1277 	}
1278 	if (strlcat(tmp, p, len) >= len) {
1279 		log_debug("%s: string too long", __func__);
1280 		free(tmp);
1281 		return (-1);
1282 	}
1283 	(void)strlcpy(label, tmp, len);	/* always fits */
1284 	free(tmp);
1285 
1286 	return (0);
1287 }
1288 
1289 void
1290 translate_string(char *str)
1291 {
1292 	char	*reader;
1293 	char	*writer;
1294 
1295 	reader = writer = str;
1296 
1297 	while (*reader) {
1298 		if (*reader == '\\') {
1299 			reader++;
1300 			switch (*reader) {
1301 			case 'n':
1302 				*writer++ = '\n';
1303 				break;
1304 			case 'r':
1305 				*writer++ = '\r';
1306 				break;
1307 			default:
1308 				*writer++ = *reader;
1309 			}
1310 		} else
1311 			*writer++ = *reader;
1312 		reader++;
1313 	}
1314 	*writer = '\0';
1315 }
1316 
1317 char *
1318 digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf)
1319 {
1320 	switch (type) {
1321 	case DIGEST_SHA1:
1322 		return (SHA1Data(data, len, buf));
1323 		break;
1324 	case DIGEST_MD5:
1325 		return (MD5Data(data, len, buf));
1326 		break;
1327 	default:
1328 		break;
1329 	}
1330 	return (NULL);
1331 }
1332 
1333 const char *
1334 canonicalize_host(const char *host, char *name, size_t len)
1335 {
1336 	struct sockaddr_in	 sin4;
1337 	struct sockaddr_in6	 sin6;
1338 	u_int			 i, j;
1339 	size_t			 plen;
1340 	char			 c;
1341 
1342 	if (len < 2)
1343 		goto fail;
1344 
1345 	/*
1346 	 * Canonicalize an IPv4/6 address
1347 	 */
1348 	if (inet_pton(AF_INET, host, &sin4) == 1)
1349 		return (inet_ntop(AF_INET, &sin4, name, len));
1350 	if (inet_pton(AF_INET6, host, &sin6) == 1)
1351 		return (inet_ntop(AF_INET6, &sin6, name, len));
1352 
1353 	/*
1354 	 * Canonicalize a hostname
1355 	 */
1356 
1357 	/* 1. remove repeated dots and convert upper case to lower case */
1358 	plen = strlen(host);
1359 	bzero(name, len);
1360 	for (i = j = 0; i < plen; i++) {
1361 		if (j >= (len - 1))
1362 			goto fail;
1363 		c = tolower(host[i]);
1364 		if ((c == '.') && (j == 0 || name[j - 1] == '.'))
1365 			continue;
1366 		name[j++] = c;
1367 	}
1368 
1369 	/* 2. remove trailing dots */
1370 	for (i = j; i > 0; i--) {
1371 		if (name[i - 1] != '.')
1372 			break;
1373 		name[i - 1] = '\0';
1374 		j--;
1375 	}
1376 	if (j <= 0)
1377 		goto fail;
1378 
1379 	return (name);
1380 
1381  fail:
1382 	errno = EINVAL;
1383 	return (NULL);
1384 }
1385 
1386 int
1387 bindany(struct ctl_bindany *bnd)
1388 {
1389 	int	s, v;
1390 
1391 	s = -1;
1392 	v = 1;
1393 
1394 	if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1)
1395 		goto fail;
1396 	if ((s = socket(bnd->bnd_ss.ss_family,
1397 	    bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM,
1398 	    bnd->bnd_proto)) == -1)
1399 		goto fail;
1400 	if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
1401 	    &v, sizeof(v)) == -1)
1402 		goto fail;
1403 	if (bind(s, (struct sockaddr *)&bnd->bnd_ss,
1404 	    bnd->bnd_ss.ss_len) == -1)
1405 		goto fail;
1406 
1407 	return (s);
1408 
1409  fail:
1410 	if (s != -1)
1411 		close(s);
1412 	return (-1);
1413 }
1414 
1415 int
1416 map6to4(struct sockaddr_storage *in6)
1417 {
1418 	struct sockaddr_storage	 out4;
1419 	struct sockaddr_in	*sin4 = (struct sockaddr_in *)&out4;
1420 	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)in6;
1421 
1422 	bzero(sin4, sizeof(*sin4));
1423 	sin4->sin_len = sizeof(*sin4);
1424 	sin4->sin_family = AF_INET;
1425 	sin4->sin_port = sin6->sin6_port;
1426 
1427 	bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr,
1428 	    sizeof(sin4->sin_addr));
1429 
1430 	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1431 	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1432 	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1433 		return (-1);
1434 
1435 	bcopy(&out4, in6, sizeof(*in6));
1436 
1437 	return (0);
1438 }
1439 
1440 int
1441 map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map)
1442 {
1443 	struct sockaddr_storage	 out6;
1444 	struct sockaddr_in	*sin4 = (struct sockaddr_in *)in4;
1445 	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)&out6;
1446 	struct sockaddr_in6	*map6 = (struct sockaddr_in6 *)map;
1447 
1448 	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1449 	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1450 	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1451 		return (-1);
1452 
1453 	bcopy(map6, sin6, sizeof(*sin6));
1454 	sin6->sin6_len = sizeof(*sin6);
1455 	sin6->sin6_family = AF_INET6;
1456 	sin6->sin6_port = sin4->sin_port;
1457 
1458 	bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12],
1459 	    sizeof(sin4->sin_addr));
1460 
1461 	bcopy(&out6, in4, sizeof(*in4));
1462 
1463 	return (0);
1464 }
1465 
1466 void
1467 socket_rlimit(int maxfd)
1468 {
1469 	struct rlimit	 rl;
1470 
1471 	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
1472 		fatal("socket_rlimit: failed to get resource limit");
1473 	log_debug("%s: max open files %llu", __func__, rl.rlim_max);
1474 
1475 	/*
1476 	 * Allow the maximum number of open file descriptors for this
1477 	 * login class (which should be the class "daemon" by default).
1478 	 */
1479 	if (maxfd == -1)
1480 		rl.rlim_cur = rl.rlim_max;
1481 	else
1482 		rl.rlim_cur = MAX(rl.rlim_max, (rlim_t)maxfd);
1483 	if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
1484 		fatal("socket_rlimit: failed to set resource limit");
1485 }
1486 
1487 char *
1488 get_string(u_int8_t *ptr, size_t len)
1489 {
1490 	size_t	 i;
1491 	char	*str;
1492 
1493 	for (i = 0; i < len; i++)
1494 		if (!(isprint(ptr[i]) || isspace(ptr[i])))
1495 			break;
1496 
1497 	if ((str = calloc(1, i + 1)) == NULL)
1498 		return (NULL);
1499 	memcpy(str, ptr, i);
1500 
1501 	return (str);
1502 }
1503 
1504 void *
1505 get_data(u_int8_t *ptr, size_t len)
1506 {
1507 	u_int8_t	*data;
1508 
1509 	if ((data = calloc(1, len)) == NULL)
1510 		return (NULL);
1511 	memcpy(data, ptr, len);
1512 
1513 	return (data);
1514 }
1515 
1516 int
1517 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
1518 {
1519 	struct sockaddr_in	*a4, *b4;
1520 	struct sockaddr_in6	*a6, *b6;
1521 	u_int32_t		 av[4], bv[4], mv[4];
1522 
1523 	if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
1524 		return (0);
1525 	else if (a->sa_family > b->sa_family)
1526 		return (1);
1527 	else if (a->sa_family < b->sa_family)
1528 		return (-1);
1529 
1530 	if (prefixlen == -1)
1531 		memset(&mv, 0xff, sizeof(mv));
1532 
1533 	switch (a->sa_family) {
1534 	case AF_INET:
1535 		a4 = (struct sockaddr_in *)a;
1536 		b4 = (struct sockaddr_in *)b;
1537 
1538 		av[0] = a4->sin_addr.s_addr;
1539 		bv[0] = b4->sin_addr.s_addr;
1540 		if (prefixlen != -1)
1541 			mv[0] = prefixlen2mask(prefixlen);
1542 
1543 		if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1544 			return (1);
1545 		if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1546 			return (-1);
1547 		break;
1548 	case AF_INET6:
1549 		a6 = (struct sockaddr_in6 *)a;
1550 		b6 = (struct sockaddr_in6 *)b;
1551 
1552 		memcpy(&av, &a6->sin6_addr.s6_addr, 16);
1553 		memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
1554 		if (prefixlen != -1)
1555 			prefixlen2mask6(prefixlen, mv);
1556 
1557 		if ((av[3] & mv[3]) > (bv[3] & mv[3]))
1558 			return (1);
1559 		if ((av[3] & mv[3]) < (bv[3] & mv[3]))
1560 			return (-1);
1561 		if ((av[2] & mv[2]) > (bv[2] & mv[2]))
1562 			return (1);
1563 		if ((av[2] & mv[2]) < (bv[2] & mv[2]))
1564 			return (-1);
1565 		if ((av[1] & mv[1]) > (bv[1] & mv[1]))
1566 			return (1);
1567 		if ((av[1] & mv[1]) < (bv[1] & mv[1]))
1568 			return (-1);
1569 		if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1570 			return (1);
1571 		if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1572 			return (-1);
1573 		break;
1574 	}
1575 
1576 	return (0);
1577 }
1578 
1579 u_int32_t
1580 prefixlen2mask(u_int8_t prefixlen)
1581 {
1582 	if (prefixlen == 0)
1583 		return (0);
1584 
1585 	if (prefixlen > 32)
1586 		prefixlen = 32;
1587 
1588 	return (htonl(0xffffffff << (32 - prefixlen)));
1589 }
1590 
1591 struct in6_addr *
1592 prefixlen2mask6(u_int8_t prefixlen, u_int32_t *mask)
1593 {
1594 	static struct in6_addr  s6;
1595 	int			i;
1596 
1597 	if (prefixlen > 128)
1598 		prefixlen = 128;
1599 
1600 	bzero(&s6, sizeof(s6));
1601 	for (i = 0; i < prefixlen / 8; i++)
1602 		s6.s6_addr[i] = 0xff;
1603 	i = prefixlen % 8;
1604 	if (i)
1605 		s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
1606 
1607 	memcpy(mask, &s6, sizeof(s6));
1608 
1609 	return (&s6);
1610 }
1611 
1612 int
1613 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
1614     int reserve, volatile int *counter)
1615 {
1616 	int ret;
1617 	if (getdtablecount() + reserve +
1618 	    *counter >= getdtablesize()) {
1619 		errno = EMFILE;
1620 		return (-1);
1621 	}
1622 
1623 	if ((ret = accept(sockfd, addr, addrlen)) > -1) {
1624 		(*counter)++;
1625 		DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
1626 	}
1627 	return (ret);
1628 }
1629