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