xref: /openbsd-src/usr.sbin/relayd/relayd.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: relayd.c,v 1.108 2012/05/08 15:10:15 benno Exp $	*/
2 
3 /*
4  * Copyright (c) 2007, 2008 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 <err.h>
37 #include <errno.h>
38 #include <event.h>
39 #include <unistd.h>
40 #include <ctype.h>
41 #include <pwd.h>
42 #include <sha1.h>
43 #include <md5.h>
44 
45 #include <openssl/ssl.h>
46 
47 #include "relayd.h"
48 
49 __dead void	 usage(void);
50 
51 int		 parent_configure(struct relayd *);
52 void		 parent_configure_done(struct relayd *);
53 void		 parent_reload(struct relayd *, u_int, const char *);
54 void		 parent_sig_handler(int, short, void *);
55 void		 parent_shutdown(struct relayd *);
56 int		 parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *);
57 int		 parent_dispatch_hce(int, struct privsep_proc *, struct imsg *);
58 int		 parent_dispatch_relay(int, struct privsep_proc *,
59 		    struct imsg *);
60 int		 bindany(struct ctl_bindany *);
61 
62 struct relayd			*relayd_env;
63 
64 static struct privsep_proc procs[] = {
65 	{ "pfe",	PROC_PFE, parent_dispatch_pfe, pfe },
66 	{ "hce",	PROC_HCE, parent_dispatch_hce, hce },
67 	{ "relay",	PROC_RELAY, parent_dispatch_relay, relay }
68 };
69 
70 void
71 parent_sig_handler(int sig, short event, void *arg)
72 {
73 	struct privsep	*ps = arg;
74 	int		 die = 0, status, fail, id;
75 	pid_t		 pid;
76 	char		*cause;
77 
78 	switch (sig) {
79 	case SIGTERM:
80 	case SIGINT:
81 		die = 1;
82 		/* FALLTHROUGH */
83 	case SIGCHLD:
84 		do {
85 			pid = waitpid(WAIT_ANY, &status, WNOHANG);
86 			if (pid <= 0)
87 				continue;
88 
89 			fail = 0;
90 			if (WIFSIGNALED(status)) {
91 				fail = 1;
92 				asprintf(&cause, "terminated; signal %d",
93 				    WTERMSIG(status));
94 			} else if (WIFEXITED(status)) {
95 				if (WEXITSTATUS(status) != 0) {
96 					fail = 1;
97 					asprintf(&cause, "exited abnormally");
98 				} else
99 					asprintf(&cause, "exited okay");
100 			} else
101 				fatalx("unexpected cause of SIGCHLD");
102 
103 			die = 1;
104 
105 			for (id = 0; id < PROC_MAX; id++)
106 				if (pid == ps->ps_pid[id]) {
107 					log_warnx("lost child: %s %s",
108 					    ps->ps_title[id], cause);
109 					break;
110 				}
111 
112 			free(cause);
113 		} while (pid > 0 || (pid == -1 && errno == EINTR));
114 
115 		if (die)
116 			parent_shutdown(ps->ps_env);
117 		break;
118 	case SIGHUP:
119 		log_info("%s: reload requested with SIGHUP", __func__);
120 
121 		/*
122 		 * This is safe because libevent uses async signal handlers
123 		 * that run in the event loop and not in signal context.
124 		 */
125 		parent_reload(ps->ps_env, CONFIG_RELOAD, NULL);
126 		break;
127 	case SIGPIPE:
128 		/* ignore */
129 		break;
130 	default:
131 		fatalx("unexpected signal");
132 	}
133 }
134 
135 /* __dead is for lint */
136 __dead void
137 usage(void)
138 {
139 	extern char	*__progname;
140 
141 	fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
142 	    __progname);
143 	exit(1);
144 }
145 
146 int
147 main(int argc, char *argv[])
148 {
149 	int			 c;
150 	int			 debug = 0, verbose = 0;
151 	u_int32_t		 opts = 0;
152 	struct relayd		*env;
153 	struct privsep		*ps;
154 	const char		*conffile = CONF_FILE;
155 
156 	while ((c = getopt(argc, argv, "dD:nf:v")) != -1) {
157 		switch (c) {
158 		case 'd':
159 			debug = 2;
160 			break;
161 		case 'D':
162 			if (cmdline_symset(optarg) < 0)
163 				log_warnx("could not parse macro definition %s",
164 				    optarg);
165 			break;
166 		case 'n':
167 			debug = 2;
168 			opts |= RELAYD_OPT_NOACTION;
169 			break;
170 		case 'f':
171 			conffile = optarg;
172 			break;
173 		case 'v':
174 			verbose++;
175 			opts |= RELAYD_OPT_VERBOSE;
176 			break;
177 		default:
178 			usage();
179 		}
180 	}
181 
182 	log_init(debug ? debug : 1);	/* log to stderr until daemonized */
183 
184 	argc -= optind;
185 	argv += optind;
186 	if (argc > 0)
187 		usage();
188 
189 	if ((env = calloc(1, sizeof(*env))) == NULL ||
190 	    (ps = calloc(1, sizeof(*ps))) == NULL)
191 		exit(1);
192 
193 	relayd_env = env;
194 	env->sc_ps = ps;
195 	ps->ps_env = env;
196 	env->sc_conffile = conffile;
197 	env->sc_opts = opts;
198 
199 	if (parse_config(env->sc_conffile, env) == -1)
200 		exit(1);
201 
202 	if (debug)
203 		env->sc_opts |= RELAYD_OPT_LOGUPDATE;
204 
205 	if (geteuid())
206 		errx(1, "need root privileges");
207 
208 	if ((ps->ps_pw =  getpwnam(RELAYD_USER)) == NULL)
209 		errx(1, "unknown user %s", RELAYD_USER);
210 
211 	/* Configure the control socket */
212 	ps->ps_csock.cs_name = RELAYD_SOCKET;
213 
214 	log_init(debug);
215 	log_verbose(verbose);
216 
217 	if (!debug && daemon(1, 0) == -1)
218 		err(1, "failed to daemonize");
219 
220 	if (env->sc_opts & RELAYD_OPT_NOACTION)
221 		ps->ps_noaction = 1;
222 	else
223 		log_info("startup");
224 
225 	ps->ps_instances[PROC_RELAY] = env->sc_prefork_relay;
226 	proc_init(ps, procs, nitems(procs));
227 
228 	setproctitle("parent");
229 
230 	event_init();
231 
232 	signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
233 	signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
234 	signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps);
235 	signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
236 	signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
237 
238 	signal_add(&ps->ps_evsigint, NULL);
239 	signal_add(&ps->ps_evsigterm, NULL);
240 	signal_add(&ps->ps_evsigchld, NULL);
241 	signal_add(&ps->ps_evsighup, NULL);
242 	signal_add(&ps->ps_evsigpipe, NULL);
243 
244 	proc_config(ps, procs, nitems(procs));
245 
246 	if (load_config(env->sc_conffile, env) == -1) {
247 		proc_kill(env->sc_ps);
248 		exit(1);
249 	}
250 
251 	if (env->sc_opts & RELAYD_OPT_NOACTION) {
252 		fprintf(stderr, "configuration OK\n");
253 		proc_kill(env->sc_ps);
254 		exit(0);
255 	}
256 
257 	if (env->sc_flags & (F_SSL|F_SSLCLIENT))
258 		ssl_init(env);
259 
260 	if (parent_configure(env) == -1)
261 		fatalx("configuration failed");
262 
263 	init_routes(env);
264 
265 	event_dispatch();
266 
267 	parent_shutdown(env);
268 	/* NOTREACHED */
269 
270 	return (0);
271 }
272 
273 int
274 parent_configure(struct relayd *env)
275 {
276 	struct table		*tb;
277 	struct rdr		*rdr;
278 	struct router		*rt;
279 	struct protocol		*proto;
280 	struct relay		*rlay;
281 	int			 id;
282 	struct ctl_flags	 cf;
283 	int			 s, ret = -1;
284 
285 	TAILQ_FOREACH(tb, env->sc_tables, entry)
286 		config_settable(env, tb);
287 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
288 		config_setrdr(env, rdr);
289 	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
290 		config_setrt(env, rt);
291 	TAILQ_FOREACH(proto, env->sc_protos, entry)
292 		config_setproto(env, proto);
293 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
294 		config_setrelay(env, rlay);
295 
296 	/* HCE, PFE and the preforked relays need to reload their config. */
297 	env->sc_reload = 2 + env->sc_prefork_relay;
298 
299 	for (id = 0; id < PROC_MAX; id++) {
300 		if (id == privsep_process)
301 			continue;
302 		cf.cf_opts = env->sc_opts;
303 		cf.cf_flags = env->sc_flags;
304 
305 		if ((env->sc_flags & F_NEEDPF) && id == PROC_PFE) {
306 			/* Send pf socket to the pf engine */
307 			if ((s = open(PF_SOCKET, O_RDWR)) == -1) {
308 				log_debug("%s: cannot open pf socket",
309 				    __func__);
310 				goto done;
311 			}
312 		} else
313 			s = -1;
314 
315 		proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, s,
316 		    &cf, sizeof(cf));
317 	}
318 
319 	ret = 0;
320 
321  done:
322 	config_purge(env, CONFIG_ALL);
323 	return (ret);
324 }
325 
326 void
327 parent_reload(struct relayd *env, u_int reset, const char *filename)
328 {
329 	if (env->sc_reload) {
330 		log_debug("%s: already in progress: %d pending",
331 		    __func__, env->sc_reload);
332 		return;
333 	}
334 
335 	/* Switch back to the default config file */
336 	if (filename == NULL || *filename == '\0')
337 		filename = env->sc_conffile;
338 
339 	log_debug("%s: level %d config file %s", __func__, reset, filename);
340 
341 	config_purge(env, CONFIG_ALL);
342 
343 	if (reset == CONFIG_RELOAD) {
344 		if (load_config(filename, env) == -1) {
345 			log_debug("%s: failed to load config file %s",
346 			    __func__, filename);
347 		}
348 
349 		config_setreset(env, CONFIG_ALL);
350 
351 		if (parent_configure(env) == -1) {
352 			log_debug("%s: failed to commit config from %s",
353 			    __func__, filename);
354 		}
355 	} else
356 		config_setreset(env, reset);
357 }
358 
359 void
360 parent_configure_done(struct relayd *env)
361 {
362 	int	 id;
363 
364 	if (env->sc_reload == 0) {
365 		log_warnx("%s: configuration already finished", __func__);
366 		return;
367 	}
368 
369 	env->sc_reload--;
370 	if (env->sc_reload == 0) {
371 		for (id = 0; id < PROC_MAX; id++) {
372 			if (id == privsep_process)
373 				continue;
374 
375 			proc_compose_imsg(env->sc_ps, id, -1, IMSG_CTL_START,
376 			    -1, NULL, 0);
377 		}
378 	}
379 }
380 
381 void
382 parent_shutdown(struct relayd *env)
383 {
384 	config_purge(env, CONFIG_ALL);
385 
386 	proc_kill(env->sc_ps);
387 	control_cleanup(&env->sc_ps->ps_csock);
388 	carp_demote_shutdown();
389 
390 	free(env->sc_ps);
391 	free(env);
392 
393 	log_info("parent terminating, pid %d", getpid());
394 
395 	exit(0);
396 }
397 
398 int
399 parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
400 {
401 	struct relayd		*env = p->p_env;
402 	struct ctl_demote	 demote;
403 	struct ctl_netroute	 crt;
404 	u_int			 v;
405 	char			*str = NULL;
406 
407 	switch (imsg->hdr.type) {
408 	case IMSG_DEMOTE:
409 		IMSG_SIZE_CHECK(imsg, &demote);
410 		memcpy(&demote, imsg->data, sizeof(demote));
411 		carp_demote_set(demote.group, demote.level);
412 		break;
413 	case IMSG_RTMSG:
414 		IMSG_SIZE_CHECK(imsg, &crt);
415 		memcpy(&crt, imsg->data, sizeof(crt));
416 		pfe_route(env, &crt);
417 		break;
418 	case IMSG_CTL_RESET:
419 		IMSG_SIZE_CHECK(imsg, &v);
420 		memcpy(&v, imsg->data, sizeof(v));
421 		parent_reload(env, v, NULL);
422 		break;
423 	case IMSG_CTL_RELOAD:
424 		if (IMSG_DATA_SIZE(imsg) > 0)
425 			str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
426 		parent_reload(env, CONFIG_RELOAD, str);
427 		if (str != NULL)
428 			free(str);
429 		break;
430 	case IMSG_CTL_SHUTDOWN:
431 		parent_shutdown(env);
432 		break;
433 	case IMSG_CFG_DONE:
434 		parent_configure_done(env);
435 		break;
436 	default:
437 		return (-1);
438 	}
439 
440 	return (0);
441 }
442 
443 int
444 parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
445 {
446 	struct relayd		*env = p->p_env;
447 	struct privsep		*ps = env->sc_ps;
448 	struct ctl_script	 scr;
449 
450 	switch (imsg->hdr.type) {
451 	case IMSG_SCRIPT:
452 		IMSG_SIZE_CHECK(imsg, &scr);
453 		bcopy(imsg->data, &scr, sizeof(scr));
454 		scr.retval = script_exec(env, &scr);
455 		proc_compose_imsg(ps, PROC_HCE, -1, IMSG_SCRIPT,
456 		    -1, &scr, sizeof(scr));
457 		break;
458 	case IMSG_SNMPSOCK:
459 		(void)snmp_setsock(env, p->p_id);
460 		break;
461 	case IMSG_CFG_DONE:
462 		parent_configure_done(env);
463 		break;
464 	default:
465 		return (-1);
466 	}
467 
468 	return (0);
469 }
470 
471 int
472 parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
473 {
474 	struct relayd		*env = p->p_env;
475 	struct privsep		*ps = env->sc_ps;
476 	struct ctl_bindany	 bnd;
477 	int			 s;
478 
479 	switch (imsg->hdr.type) {
480 	case IMSG_BINDANY:
481 		IMSG_SIZE_CHECK(imsg, &bnd);
482 		bcopy(imsg->data, &bnd, sizeof(bnd));
483 		if (bnd.bnd_proc > env->sc_prefork_relay)
484 			fatalx("pfe_dispatch_relay: "
485 			    "invalid relay proc");
486 		switch (bnd.bnd_proto) {
487 		case IPPROTO_TCP:
488 		case IPPROTO_UDP:
489 			break;
490 		default:
491 			fatalx("pfe_dispatch_relay: requested socket "
492 			    "for invalid protocol");
493 			/* NOTREACHED */
494 		}
495 		s = bindany(&bnd);
496 		proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc,
497 		    IMSG_BINDANY, s, &bnd.bnd_id, sizeof(bnd.bnd_id));
498 		break;
499 	case IMSG_CFG_DONE:
500 		parent_configure_done(env);
501 		break;
502 	default:
503 		return (-1);
504 	}
505 
506 	return (0);
507 }
508 
509 void
510 purge_tree(struct proto_tree *tree)
511 {
512 	struct protonode	*proot, *pn;
513 
514 	while ((proot = RB_ROOT(tree)) != NULL) {
515 		RB_REMOVE(proto_tree, tree, proot);
516 		if (proot->key != NULL)
517 			free(proot->key);
518 		if (proot->value != NULL)
519 			free(proot->value);
520 		while ((pn = SIMPLEQ_FIRST(&proot->head)) != NULL) {
521 			SIMPLEQ_REMOVE_HEAD(&proot->head, entry);
522 			if (pn->key != NULL)
523 				free(pn->key);
524 			if (pn->value != NULL)
525 				free(pn->value);
526 			if (pn->labelname != NULL)
527 				free(pn->labelname);
528 			if (pn->label != 0)
529 				pn_unref(pn->label);
530 			free(pn);
531 		}
532 		free(proot);
533 	}
534 }
535 
536 void
537 purge_table(struct tablelist *head, struct table *table)
538 {
539 	struct host		*host;
540 
541 	while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
542 		TAILQ_REMOVE(&table->hosts, host, entry);
543 		if (event_initialized(&host->cte.ev)) {
544 			event_del(&host->cte.ev);
545 			close(host->cte.s);
546 		}
547 		if (host->cte.buf != NULL)
548 			ibuf_free(host->cte.buf);
549 		if (host->cte.ssl != NULL)
550 			SSL_free(host->cte.ssl);
551 		free(host);
552 	}
553 	if (table->sendbuf != NULL)
554 		free(table->sendbuf);
555 	if (table->conf.flags & F_SSL)
556 		SSL_CTX_free(table->ssl_ctx);
557 
558 	if (head != NULL)
559 		TAILQ_REMOVE(head, table, entry);
560 	free(table);
561 }
562 
563 void
564 purge_relay(struct relayd *env, struct relay *rlay)
565 {
566 	struct rsession		*con;
567 
568 	/* shutdown and remove relay */
569 	if (event_initialized(&rlay->rl_ev))
570 		event_del(&rlay->rl_ev);
571 	close(rlay->rl_s);
572 	TAILQ_REMOVE(env->sc_relays, rlay, rl_entry);
573 
574 	/* cleanup sessions */
575 	while ((con =
576 	    SPLAY_ROOT(&rlay->rl_sessions)) != NULL)
577 		relay_close(con, NULL);
578 
579 	/* cleanup relay */
580 	if (rlay->rl_bev != NULL)
581 		bufferevent_free(rlay->rl_bev);
582 	if (rlay->rl_dstbev != NULL)
583 		bufferevent_free(rlay->rl_dstbev);
584 
585 	if (rlay->rl_ssl_ctx != NULL)
586 		SSL_CTX_free(rlay->rl_ssl_ctx);
587 	if (rlay->rl_ssl_cert != NULL)
588 		free(rlay->rl_ssl_cert);
589 	if (rlay->rl_ssl_key != NULL)
590 		free(rlay->rl_ssl_key);
591 	if (rlay->rl_ssl_ca != NULL)
592 		free(rlay->rl_ssl_ca);
593 
594 	free(rlay);
595 }
596 
597 /*
598  * Utility functions
599  */
600 
601 struct host *
602 host_find(struct relayd *env, objid_t id)
603 {
604 	struct table	*table;
605 	struct host	*host;
606 
607 	TAILQ_FOREACH(table, env->sc_tables, entry)
608 		TAILQ_FOREACH(host, &table->hosts, entry)
609 			if (host->conf.id == id)
610 				return (host);
611 	return (NULL);
612 }
613 
614 struct table *
615 table_find(struct relayd *env, objid_t id)
616 {
617 	struct table	*table;
618 
619 	TAILQ_FOREACH(table, env->sc_tables, entry)
620 		if (table->conf.id == id)
621 			return (table);
622 	return (NULL);
623 }
624 
625 struct rdr *
626 rdr_find(struct relayd *env, objid_t id)
627 {
628 	struct rdr	*rdr;
629 
630 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
631 		if (rdr->conf.id == id)
632 			return (rdr);
633 	return (NULL);
634 }
635 
636 struct relay *
637 relay_find(struct relayd *env, objid_t id)
638 {
639 	struct relay	*rlay;
640 
641 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
642 		if (rlay->rl_conf.id == id)
643 			return (rlay);
644 	return (NULL);
645 }
646 
647 struct protocol *
648 proto_find(struct relayd *env, objid_t id)
649 {
650 	struct protocol	*p;
651 
652 	TAILQ_FOREACH(p, env->sc_protos, entry)
653 		if (p->id == id)
654 			return (p);
655 	return (NULL);
656 }
657 
658 struct rsession *
659 session_find(struct relayd *env, objid_t id)
660 {
661 	struct relay		*rlay;
662 	struct rsession		*con;
663 
664 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
665 		SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions)
666 			if (con->se_id == id)
667 				return (con);
668 	return (NULL);
669 }
670 
671 struct netroute *
672 route_find(struct relayd *env, objid_t id)
673 {
674 	struct netroute	*nr;
675 
676 	TAILQ_FOREACH(nr, env->sc_routes, nr_route)
677 		if (nr->nr_conf.id == id)
678 			return (nr);
679 	return (NULL);
680 }
681 
682 struct router *
683 router_find(struct relayd *env, objid_t id)
684 {
685 	struct router	*rt;
686 
687 	TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
688 		if (rt->rt_conf.id == id)
689 			return (rt);
690 	return (NULL);
691 }
692 
693 struct host *
694 host_findbyname(struct relayd *env, const char *name)
695 {
696 	struct table	*table;
697 	struct host	*host;
698 
699 	TAILQ_FOREACH(table, env->sc_tables, entry)
700 		TAILQ_FOREACH(host, &table->hosts, entry)
701 			if (strcmp(host->conf.name, name) == 0)
702 				return (host);
703 	return (NULL);
704 }
705 
706 struct table *
707 table_findbyname(struct relayd *env, const char *name)
708 {
709 	struct table	*table;
710 
711 	TAILQ_FOREACH(table, env->sc_tables, entry)
712 		if (strcmp(table->conf.name, name) == 0)
713 			return (table);
714 	return (NULL);
715 }
716 
717 struct table *
718 table_findbyconf(struct relayd *env, struct table *tb)
719 {
720 	struct table		*table;
721 	struct table_config	 a, b;
722 
723 	bcopy(&tb->conf, &a, sizeof(a));
724 	a.id = a.rdrid = 0;
725 	a.flags &= ~(F_USED|F_BACKUP);
726 
727 	TAILQ_FOREACH(table, env->sc_tables, entry) {
728 		bcopy(&table->conf, &b, sizeof(b));
729 		b.id = b.rdrid = 0;
730 		b.flags &= ~(F_USED|F_BACKUP);
731 
732 		/*
733 		 * Compare two tables and return the existing table if
734 		 * the configuration seems to be the same.
735 		 */
736 		if (bcmp(&a, &b, sizeof(b)) == 0 &&
737 		    ((tb->sendbuf == NULL && table->sendbuf == NULL) ||
738 		    (tb->sendbuf != NULL && table->sendbuf != NULL &&
739 		    strcmp(tb->sendbuf, table->sendbuf) == 0)))
740 			return (table);
741 	}
742 	return (NULL);
743 }
744 
745 struct rdr *
746 rdr_findbyname(struct relayd *env, const char *name)
747 {
748 	struct rdr	*rdr;
749 
750 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
751 		if (strcmp(rdr->conf.name, name) == 0)
752 			return (rdr);
753 	return (NULL);
754 }
755 
756 struct relay *
757 relay_findbyname(struct relayd *env, const char *name)
758 {
759 	struct relay	*rlay;
760 
761 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
762 		if (strcmp(rlay->rl_conf.name, name) == 0)
763 			return (rlay);
764 	return (NULL);
765 }
766 
767 struct relay *
768 relay_findbyaddr(struct relayd *env, struct relay_config *rc)
769 {
770 	struct relay	*rlay;
771 
772 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
773 		if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 &&
774 		    rlay->rl_conf.port == rc->port)
775 			return (rlay);
776 	return (NULL);
777 }
778 
779 void
780 event_again(struct event *ev, int fd, short event,
781     void (*fn)(int, short, void *),
782     struct timeval *start, struct timeval *end, void *arg)
783 {
784 	struct timeval tv_next, tv_now, tv;
785 
786 	if (gettimeofday(&tv_now, NULL) == -1)
787 		fatal("event_again: gettimeofday");
788 
789 	bcopy(end, &tv_next, sizeof(tv_next));
790 	timersub(&tv_now, start, &tv_now);
791 	timersub(&tv_next, &tv_now, &tv_next);
792 
793 	bzero(&tv, sizeof(tv));
794 	if (timercmp(&tv_next, &tv, >))
795 		bcopy(&tv_next, &tv, sizeof(tv));
796 
797 	event_del(ev);
798 	event_set(ev, fd, event, fn, arg);
799 	event_add(ev, &tv);
800 }
801 
802 int
803 expand_string(char *label, size_t len, const char *srch, const char *repl)
804 {
805 	char *tmp;
806 	char *p, *q;
807 
808 	if ((tmp = calloc(1, len)) == NULL) {
809 		log_debug("%s: calloc", __func__);
810 		return (-1);
811 	}
812 	p = q = label;
813 	while ((q = strstr(p, srch)) != NULL) {
814 		*q = '\0';
815 		if ((strlcat(tmp, p, len) >= len) ||
816 		    (strlcat(tmp, repl, len) >= len)) {
817 			log_debug("%s: string too long", __func__);
818 			free(tmp);
819 			return (-1);
820 		}
821 		q += strlen(srch);
822 		p = q;
823 	}
824 	if (strlcat(tmp, p, len) >= len) {
825 		log_debug("%s: string too long", __func__);
826 		free(tmp);
827 		return (-1);
828 	}
829 	(void)strlcpy(label, tmp, len);	/* always fits */
830 	free(tmp);
831 
832 	return (0);
833 }
834 
835 void
836 translate_string(char *str)
837 {
838 	char	*reader;
839 	char	*writer;
840 
841 	reader = writer = str;
842 
843 	while (*reader) {
844 		if (*reader == '\\') {
845 			reader++;
846 			switch (*reader) {
847 			case 'n':
848 				*writer++ = '\n';
849 				break;
850 			case 'r':
851 				*writer++ = '\r';
852 				break;
853 			default:
854 				*writer++ = *reader;
855 			}
856 		} else
857 			*writer++ = *reader;
858 		reader++;
859 	}
860 	*writer = '\0';
861 }
862 
863 char *
864 digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf)
865 {
866 	switch (type) {
867 	case DIGEST_SHA1:
868 		return (SHA1Data(data, len, buf));
869 		break;
870 	case DIGEST_MD5:
871 		return (MD5Data(data, len, buf));
872 		break;
873 	default:
874 		break;
875 	}
876 	return (NULL);
877 }
878 
879 const char *
880 canonicalize_host(const char *host, char *name, size_t len)
881 {
882 	struct sockaddr_in	 sin4;
883 	struct sockaddr_in6	 sin6;
884 	u_int			 i, j;
885 	size_t			 plen;
886 	char			 c;
887 
888 	if (len < 2)
889 		goto fail;
890 
891 	/*
892 	 * Canonicalize an IPv4/6 address
893 	 */
894 	if (inet_pton(AF_INET, host, &sin4) == 1)
895 		return (inet_ntop(AF_INET, &sin4, name, len));
896 	if (inet_pton(AF_INET6, host, &sin6) == 1)
897 		return (inet_ntop(AF_INET6, &sin6, name, len));
898 
899 	/*
900 	 * Canonicalize a hostname
901 	 */
902 
903 	/* 1. remove repeated dots and convert upper case to lower case */
904 	plen = strlen(host);
905 	bzero(name, len);
906 	for (i = j = 0; i < plen; i++) {
907 		if (j >= (len - 1))
908 			goto fail;
909 		c = tolower(host[i]);
910 		if ((c == '.') && (j == 0 || name[j - 1] == '.'))
911 			continue;
912 		name[j++] = c;
913 	}
914 
915 	/* 2. remove trailing dots */
916 	for (i = j; i > 0; i--) {
917 		if (name[i - 1] != '.')
918 			break;
919 		name[i - 1] = '\0';
920 		j--;
921 	}
922 	if (j <= 0)
923 		goto fail;
924 
925 	return (name);
926 
927  fail:
928 	errno = EINVAL;
929 	return (NULL);
930 }
931 
932 struct protonode *
933 protonode_header(enum direction dir, struct protocol *proto,
934     struct protonode *pk)
935 {
936 	struct protonode	*pn;
937 	struct proto_tree	*tree;
938 
939 	if (dir == RELAY_DIR_RESPONSE)
940 		tree = &proto->response_tree;
941 	else
942 		tree = &proto->request_tree;
943 
944 	pn = RB_FIND(proto_tree, tree, pk);
945 	if (pn != NULL)
946 		return (pn);
947 	if ((pn = (struct protonode *)calloc(1, sizeof(*pn))) == NULL) {
948 		log_warn("%s: calloc", __func__);
949 		return (NULL);
950 	}
951 	pn->key = strdup(pk->key);
952 	if (pn->key == NULL) {
953 		free(pn);
954 		log_warn("%s: strdup", __func__);
955 		return (NULL);
956 	}
957 	pn->value = NULL;
958 	pn->action = NODE_ACTION_NONE;
959 	pn->type = pk->type;
960 	SIMPLEQ_INIT(&pn->head);
961 	if (dir == RELAY_DIR_RESPONSE)
962 		pn->id =
963 		    proto->response_nodes++;
964 	else
965 		pn->id = proto->request_nodes++;
966 	if (pn->id == INT_MAX) {
967 		log_warnx("%s: too many protocol "
968 		    "nodes defined", __func__);
969 		return (NULL);
970 	}
971 	RB_INSERT(proto_tree, tree, pn);
972 	return (pn);
973 }
974 
975 int
976 protonode_add(enum direction dir, struct protocol *proto,
977     struct protonode *node)
978 {
979 	struct protonode	*pn, *proot, pk;
980 	struct proto_tree	*tree;
981 
982 	if (dir == RELAY_DIR_RESPONSE)
983 		tree = &proto->response_tree;
984 	else
985 		tree = &proto->request_tree;
986 
987 	if ((pn = calloc(1, sizeof (*pn))) == NULL) {
988 		log_warn("%s: calloc", __func__);
989 		return (-1);
990 	}
991 	bcopy(node, pn, sizeof(*pn));
992 	pn->key = node->key;
993 	pn->value = node->value;
994 	pn->labelname = NULL;
995 	if (node->labelname != NULL)
996 		pn->label = pn_name2id(node->labelname);
997 	SIMPLEQ_INIT(&pn->head);
998 	if (dir == RELAY_DIR_RESPONSE)
999 		pn->id = proto->response_nodes++;
1000 	else
1001 		pn->id = proto->request_nodes++;
1002 	if (pn->id == INT_MAX) {
1003 		log_warnx("%s: too many protocol nodes defined", __func__);
1004 		free(pn);
1005 		return (-1);
1006 	}
1007 	if ((proot =
1008 	    RB_INSERT(proto_tree, tree, pn)) != NULL) {
1009 		/*
1010 		 * A protocol node with the same key already
1011 		 * exists, append it to a queue behind the
1012 		 * existing node->
1013 		 */
1014 		if (SIMPLEQ_EMPTY(&proot->head))
1015 			SIMPLEQ_NEXT(proot, entry) = pn;
1016 		SIMPLEQ_INSERT_TAIL(&proot->head, pn, entry);
1017 	}
1018 	if (node->type == NODE_TYPE_COOKIE)
1019 		pk.key = "Cookie";
1020 	else if (node->type == NODE_TYPE_URL)
1021 		pk.key = "Host";
1022 	else
1023 		pk.key = "GET";
1024 	if (node->type != NODE_TYPE_HEADER) {
1025 		pk.type = NODE_TYPE_HEADER;
1026 		pn = protonode_header(dir, proto, &pk);
1027 		if (pn == NULL)
1028 			return (-1);
1029 		switch (node->type) {
1030 		case NODE_TYPE_QUERY:
1031 			pn->flags |= PNFLAG_LOOKUP_QUERY;
1032 			break;
1033 		case NODE_TYPE_COOKIE:
1034 			pn->flags |= PNFLAG_LOOKUP_COOKIE;
1035 			break;
1036 		case NODE_TYPE_URL:
1037 			if (node->flags &
1038 			    PNFLAG_LOOKUP_URL_DIGEST)
1039 				pn->flags |= node->flags &
1040 				    PNFLAG_LOOKUP_URL_DIGEST;
1041 			else
1042 				pn->flags |=
1043 				    PNFLAG_LOOKUP_DIGEST(0);
1044 			break;
1045 		default:
1046 			break;
1047 		}
1048 	}
1049 
1050 	return (0);
1051 }
1052 
1053 int
1054 protonode_load(enum direction dir, struct protocol *proto,
1055     struct protonode *node, const char *name)
1056 {
1057 	FILE			*fp;
1058 	char			 buf[BUFSIZ];
1059 	int			 ret = -1;
1060 	struct protonode	 pn;
1061 
1062 	bcopy(node, &pn, sizeof(pn));
1063 	pn.key = pn.value = NULL;
1064 
1065 	if ((fp = fopen(name, "r")) == NULL)
1066 		return (-1);
1067 
1068 	while (fgets(buf, sizeof(buf), fp) != NULL) {
1069 		/* strip whitespace and newline characters */
1070 		buf[strcspn(buf, "\r\n\t ")] = '\0';
1071 		if (!strlen(buf) || buf[0] == '#')
1072 			continue;
1073 		pn.key = strdup(buf);
1074 		if (node->value != NULL)
1075 			pn.value = strdup(node->value);
1076 		if (pn.key == NULL ||
1077 		    (node->value != NULL && pn.value == NULL))
1078 			goto fail;
1079 		if (protonode_add(dir, proto, &pn) == -1)
1080 			goto fail;
1081 		pn.key = pn.value = NULL;
1082 	}
1083 
1084 	ret = 0;
1085  fail:
1086 	if (pn.key != NULL)
1087 		free(pn.key);
1088 	if (pn.value != NULL)
1089 		free(pn.value);
1090 	fclose(fp);
1091 	return (ret);
1092 }
1093 
1094 int
1095 bindany(struct ctl_bindany *bnd)
1096 {
1097 	int	s, v;
1098 
1099 	s = -1;
1100 	v = 1;
1101 
1102 	if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1)
1103 		goto fail;
1104 	if ((s = socket(bnd->bnd_ss.ss_family,
1105 	    bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM,
1106 	    bnd->bnd_proto)) == -1)
1107 		goto fail;
1108 	if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
1109 	    &v, sizeof(v)) == -1)
1110 		goto fail;
1111 	if (bind(s, (struct sockaddr *)&bnd->bnd_ss,
1112 	    bnd->bnd_ss.ss_len) == -1)
1113 		goto fail;
1114 
1115 	return (s);
1116 
1117  fail:
1118 	if (s != -1)
1119 		close(s);
1120 	return (-1);
1121 }
1122 
1123 int
1124 map6to4(struct sockaddr_storage *in6)
1125 {
1126 	struct sockaddr_storage	 out4;
1127 	struct sockaddr_in	*sin4 = (struct sockaddr_in *)&out4;
1128 	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)in6;
1129 
1130 	bzero(sin4, sizeof(*sin4));
1131 	sin4->sin_len = sizeof(*sin4);
1132 	sin4->sin_family = AF_INET;
1133 	sin4->sin_port = sin6->sin6_port;
1134 
1135 	bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr,
1136 	    sizeof(sin4->sin_addr));
1137 
1138 	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1139 	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1140 	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1141 		return (-1);
1142 
1143 	bcopy(&out4, in6, sizeof(*in6));
1144 
1145 	return (0);
1146 }
1147 
1148 int
1149 map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map)
1150 {
1151 	struct sockaddr_storage	 out6;
1152 	struct sockaddr_in	*sin4 = (struct sockaddr_in *)in4;
1153 	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)&out6;
1154 	struct sockaddr_in6	*map6 = (struct sockaddr_in6 *)map;
1155 
1156 	if (sin4->sin_addr.s_addr == INADDR_ANY ||
1157 	    sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1158 	    IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1159 		return (-1);
1160 
1161 	bcopy(map6, sin6, sizeof(*sin6));
1162 	sin6->sin6_len = sizeof(*sin6);
1163 	sin6->sin6_family = AF_INET6;
1164 	sin6->sin6_port = sin4->sin_port;
1165 
1166 	bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12],
1167 	    sizeof(sin4->sin_addr));
1168 
1169 	bcopy(&out6, in4, sizeof(*in4));
1170 
1171 	return (0);
1172 }
1173 
1174 void
1175 socket_rlimit(int maxfd)
1176 {
1177 	struct rlimit	 rl;
1178 
1179 	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
1180 		fatal("socket_rlimit: failed to get resource limit");
1181 	log_debug("%s: max open files %d", __func__, rl.rlim_max);
1182 
1183 	/*
1184 	 * Allow the maximum number of open file descriptors for this
1185 	 * login class (which should be the class "daemon" by default).
1186 	 */
1187 	if (maxfd == -1)
1188 		rl.rlim_cur = rl.rlim_max;
1189 	else
1190 		rl.rlim_cur = MAX(rl.rlim_max, (rlim_t)maxfd);
1191 	if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
1192 		fatal("socket_rlimit: failed to set resource limit");
1193 }
1194 
1195 char *
1196 get_string(u_int8_t *ptr, size_t len)
1197 {
1198 	size_t	 i;
1199 	char	*str;
1200 
1201 	for (i = 0; i < len; i++)
1202 		if (!(isprint((char)ptr[i]) || isspace((char)ptr[i])))
1203 			break;
1204 
1205 	if ((str = calloc(1, i + 1)) == NULL)
1206 		return (NULL);
1207 	memcpy(str, ptr, i);
1208 
1209 	return (str);
1210 }
1211 
1212 void *
1213 get_data(u_int8_t *ptr, size_t len)
1214 {
1215 	u_int8_t	*data;
1216 
1217 	if ((data = calloc(1, len)) == NULL)
1218 		return (NULL);
1219 	memcpy(data, ptr, len);
1220 
1221 	return (data);
1222 }
1223