xref: /openbsd-src/usr.sbin/relayd/relay.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: relay.c,v 1.251 2020/05/14 17:27:38 pvk Exp $	*/
2 
3 /*
4  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/time.h>
22 #include <sys/socket.h>
23 #include <sys/tree.h>
24 
25 #include <netinet/in.h>
26 #include <netinet/tcp.h>
27 #include <arpa/inet.h>
28 
29 #include <limits.h>
30 #include <netdb.h>
31 #include <poll.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <event.h>
39 #include <siphash.h>
40 #include <imsg.h>
41 
42 #include <tls.h>
43 
44 #include "relayd.h"
45 
46 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
47 
48 void		 relay_statistics(int, short, void *);
49 int		 relay_dispatch_parent(int, struct privsep_proc *,
50 		    struct imsg *);
51 int		 relay_dispatch_pfe(int, struct privsep_proc *,
52 		    struct imsg *);
53 int		 relay_dispatch_ca(int, struct privsep_proc *,
54 		    struct imsg *);
55 int		 relay_dispatch_hce(int, struct privsep_proc *,
56 		    struct imsg *);
57 void		 relay_shutdown(void);
58 
59 void		 relay_protodebug(struct relay *);
60 void		 relay_ruledebug(struct relay_rule *);
61 void		 relay_init(struct privsep *, struct privsep_proc *p, void *);
62 void		 relay_launch(void);
63 int		 relay_socket(struct sockaddr_storage *, in_port_t,
64 		    struct protocol *, int, int);
65 int		 relay_socket_listen(struct sockaddr_storage *, in_port_t,
66 		    struct protocol *);
67 int		 relay_socket_connect(struct sockaddr_storage *, in_port_t,
68 		    struct protocol *, int);
69 
70 void		 relay_accept(int, short, void *);
71 void		 relay_input(struct rsession *);
72 
73 void		 relay_hash_addr(SIPHASH_CTX *, struct sockaddr_storage *, int);
74 
75 int		 relay_tls_ctx_create(struct relay *);
76 void		 relay_tls_transaction(struct rsession *,
77 		    struct ctl_relay_event *);
78 void		 relay_tls_handshake(int, short, void *);
79 void		 relay_tls_connected(struct ctl_relay_event *);
80 void		 relay_tls_readcb(int, short, void *);
81 void		 relay_tls_writecb(int, short, void *);
82 
83 void		 relay_connect_retry(int, short, void *);
84 void		 relay_connect_state(struct rsession *,
85 		    struct ctl_relay_event *, enum relay_state);
86 
87 extern void	 bufferevent_read_pressure_cb(struct evbuffer *, size_t,
88 		    size_t, void *);
89 
90 volatile int relay_sessions;
91 volatile int relay_inflight = 0;
92 objid_t relay_conid;
93 
94 static struct relayd		*env = NULL;
95 
96 static struct privsep_proc procs[] = {
97 	{ "parent",	PROC_PARENT,	relay_dispatch_parent },
98 	{ "pfe",	PROC_PFE,	relay_dispatch_pfe },
99 	{ "ca",		PROC_CA,	relay_dispatch_ca },
100 	{ "hce",	PROC_HCE,	relay_dispatch_hce },
101 };
102 
103 void
104 relay(struct privsep *ps, struct privsep_proc *p)
105 {
106 	env = ps->ps_env;
107 	proc_run(ps, p, procs, nitems(procs), relay_init, NULL);
108 	relay_http(env);
109 }
110 
111 void
112 relay_shutdown(void)
113 {
114 	config_purge(env, CONFIG_ALL);
115 	usleep(200);	/* XXX relay needs to shutdown last */
116 }
117 
118 void
119 relay_ruledebug(struct relay_rule *rule)
120 {
121 	struct kv	*kv = NULL;
122 	u_int		 i;
123 	char		 buf[NI_MAXHOST];
124 
125 	fprintf(stderr, "\t\t");
126 
127 	switch (rule->rule_action) {
128 	case RULE_ACTION_MATCH:
129 		fprintf(stderr, "match ");
130 		break;
131 	case RULE_ACTION_BLOCK:
132 		fprintf(stderr, "block ");
133 		break;
134 	case RULE_ACTION_PASS:
135 		fprintf(stderr, "pass ");
136 		break;
137 	}
138 
139 	switch (rule->rule_dir) {
140 	case RELAY_DIR_ANY:
141 		break;
142 	case RELAY_DIR_REQUEST:
143 		fprintf(stderr, "request ");
144 		break;
145 	case RELAY_DIR_RESPONSE:
146 		fprintf(stderr, "response ");
147 		break;
148 	default:
149 		return;
150 		/* NOTREACHED */
151 		break;
152 	}
153 
154 	if (rule->rule_flags & RULE_FLAG_QUICK)
155 		fprintf(stderr, "quick ");
156 
157 	switch (rule->rule_af) {
158 	case AF_INET:
159 		fprintf(stderr, "inet ");
160 		break;
161 	case AF_INET6:
162 		fprintf(stderr, "inet6 ");
163 		break;
164 	}
165 
166 	if (rule->rule_src.addr.ss_family != AF_UNSPEC)
167 		fprintf(stderr, "from %s/%d ",
168 		    print_host(&rule->rule_src.addr, buf, sizeof(buf)),
169 		    rule->rule_src.addr_mask);
170 
171 	if (rule->rule_dst.addr.ss_family != AF_UNSPEC)
172 		fprintf(stderr, "to %s/%d ",
173 		    print_host(&rule->rule_dst.addr, buf, sizeof(buf)),
174 		    rule->rule_dst.addr_mask);
175 
176 	for (i = 1; i < KEY_TYPE_MAX; i++) {
177 		kv = &rule->rule_kv[i];
178 		if (kv->kv_type != i)
179 			continue;
180 
181 		switch (kv->kv_type) {
182 		case KEY_TYPE_COOKIE:
183 			fprintf(stderr, "cookie ");
184 			break;
185 		case KEY_TYPE_HEADER:
186 			fprintf(stderr, "header ");
187 			break;
188 		case KEY_TYPE_PATH:
189 			fprintf(stderr, "path ");
190 			break;
191 		case KEY_TYPE_QUERY:
192 			fprintf(stderr, "query ");
193 			break;
194 		case KEY_TYPE_URL:
195 			fprintf(stderr, "url ");
196 			break;
197 		default:
198 			continue;
199 		}
200 
201 		switch (kv->kv_option) {
202 		case KEY_OPTION_APPEND:
203 			fprintf(stderr, "append ");
204 			break;
205 		case KEY_OPTION_SET:
206 			fprintf(stderr, "set ");
207 			break;
208 		case KEY_OPTION_REMOVE:
209 			fprintf(stderr, "remove ");
210 			break;
211 		case KEY_OPTION_HASH:
212 			fprintf(stderr, "hash ");
213 			break;
214 		case KEY_OPTION_LOG:
215 			fprintf(stderr, "log ");
216 			break;
217 		case KEY_OPTION_NONE:
218 			break;
219 		}
220 
221 		switch (kv->kv_digest) {
222 		case DIGEST_SHA1:
223 		case DIGEST_MD5:
224 			fprintf(stderr, "digest ");
225 			break;
226 		default:
227 			break;
228 		}
229 
230 		fprintf(stderr, "%s%s%s%s%s%s ",
231 		    kv->kv_key == NULL ? "" : "\"",
232 		    kv->kv_key == NULL ? "" : kv->kv_key,
233 		    kv->kv_key == NULL ? "" : "\"",
234 		    kv->kv_value == NULL ? "" : " value \"",
235 		    kv->kv_value == NULL ? "" : kv->kv_value,
236 		    kv->kv_value == NULL ? "" : "\"");
237 	}
238 
239 	if (rule->rule_tablename[0])
240 		fprintf(stderr, "forward to <%s> ", rule->rule_tablename);
241 
242 	if (rule->rule_tag == -1)
243 		fprintf(stderr, "no tag ");
244 	else if (rule->rule_tag && rule->rule_tagname[0])
245 		fprintf(stderr, "tag \"%s\" ",
246 		    rule->rule_tagname);
247 
248 	if (rule->rule_tagged && rule->rule_taggedname[0])
249 		fprintf(stderr, "tagged \"%s\" ",
250 		    rule->rule_taggedname);
251 
252 	if (rule->rule_label == -1)
253 		fprintf(stderr, "no label ");
254 	else if (rule->rule_label && rule->rule_labelname[0])
255 		fprintf(stderr, "label \"%s\" ",
256 		    rule->rule_labelname);
257 
258 	fprintf(stderr, "\n");
259 }
260 
261 void
262 relay_protodebug(struct relay *rlay)
263 {
264 	struct protocol		*proto = rlay->rl_proto;
265 	struct relay_rule	*rule = NULL;
266 
267 	fprintf(stderr, "protocol %d: name %s\n",
268 	    proto->id, proto->name);
269 	fprintf(stderr, "\tflags: %s, relay flags: %s\n",
270 	    printb_flags(proto->flags, F_BITS),
271 	    printb_flags(rlay->rl_conf.flags, F_BITS));
272 	if (proto->tcpflags)
273 		fprintf(stderr, "\ttcp flags: %s\n",
274 		    printb_flags(proto->tcpflags, TCPFLAG_BITS));
275 	if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) && proto->tlsflags)
276 		fprintf(stderr, "\ttls flags: %s\n",
277 		    printb_flags(proto->tlsflags, TLSFLAG_BITS));
278 	fprintf(stderr, "\ttls session tickets: %s\n",
279 	    (proto->tickets == 1) ? "enabled" : "disabled");
280 	fprintf(stderr, "\ttype: ");
281 	switch (proto->type) {
282 	case RELAY_PROTO_TCP:
283 		fprintf(stderr, "tcp\n");
284 		break;
285 	case RELAY_PROTO_HTTP:
286 		fprintf(stderr, "http\n");
287 		break;
288 	case RELAY_PROTO_DNS:
289 		fprintf(stderr, "dns\n");
290 		break;
291 	}
292 
293 	rule = TAILQ_FIRST(&proto->rules);
294 	while (rule != NULL) {
295 		relay_ruledebug(rule);
296 		rule = TAILQ_NEXT(rule, rule_entry);
297 	}
298 }
299 
300 int
301 relay_privinit(struct relay *rlay)
302 {
303 	log_debug("%s: adding relay %s", __func__, rlay->rl_conf.name);
304 
305 	if (log_getverbose() > 1)
306 		relay_protodebug(rlay);
307 
308 	switch (rlay->rl_proto->type) {
309 	case RELAY_PROTO_DNS:
310 		relay_udp_privinit(rlay);
311 		break;
312 	case RELAY_PROTO_TCP:
313 		break;
314 	case RELAY_PROTO_HTTP:
315 		break;
316 	}
317 
318 	if (rlay->rl_conf.flags & F_UDP)
319 		rlay->rl_s = relay_udp_bind(&rlay->rl_conf.ss,
320 		    rlay->rl_conf.port, rlay->rl_proto);
321 	else
322 		rlay->rl_s = relay_socket_listen(&rlay->rl_conf.ss,
323 		    rlay->rl_conf.port, rlay->rl_proto);
324 	if (rlay->rl_s == -1)
325 		return (-1);
326 
327 	return (0);
328 }
329 
330 void
331 relay_init(struct privsep *ps, struct privsep_proc *p, void *arg)
332 {
333 	struct timeval	 tv;
334 
335 	if (config_init(ps->ps_env) == -1)
336 		fatal("failed to initialize configuration");
337 
338 	/* We use a custom shutdown callback */
339 	p->p_shutdown = relay_shutdown;
340 
341 	/* Unlimited file descriptors (use system limits) */
342 	socket_rlimit(-1);
343 
344 	if (pledge("stdio recvfd inet", NULL) == -1)
345 		fatal("pledge");
346 
347 	/* Schedule statistics timer */
348 	evtimer_set(&env->sc_statev, relay_statistics, ps);
349 	bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
350 	evtimer_add(&env->sc_statev, &tv);
351 }
352 
353 void
354 relay_session_publish(struct rsession *s)
355 {
356 	proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_PUBLISH, s, sizeof(*s));
357 }
358 
359 void
360 relay_session_unpublish(struct rsession *s)
361 {
362 	proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_UNPUBLISH,
363 	    &s->se_id, sizeof(s->se_id));
364 }
365 
366 void
367 relay_statistics(int fd, short events, void *arg)
368 {
369 	struct privsep		*ps = arg;
370 	struct relay		*rlay;
371 	struct ctl_stats	 crs, *cur;
372 	struct timeval		 tv, tv_now;
373 	int			 resethour = 0, resetday = 0;
374 	struct rsession		*con, *next_con;
375 
376 	/*
377 	 * This is a hack to calculate some average statistics.
378 	 * It doesn't try to be very accurate, but could be improved...
379 	 */
380 
381 	timerclear(&tv);
382 	getmonotime(&tv_now);
383 
384 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
385 		bzero(&crs, sizeof(crs));
386 		resethour = resetday = 0;
387 
388 		cur = &rlay->rl_stats[ps->ps_instance];
389 		cur->cnt += cur->last;
390 		cur->tick++;
391 		cur->avg = (cur->last + cur->avg) / 2;
392 		cur->last_hour += cur->last;
393 		if ((cur->tick %
394 		    (3600 / env->sc_conf.statinterval.tv_sec)) == 0) {
395 			cur->avg_hour = (cur->last_hour + cur->avg_hour) / 2;
396 			resethour++;
397 		}
398 		cur->last_day += cur->last;
399 		if ((cur->tick %
400 		    (86400 / env->sc_conf.statinterval.tv_sec)) == 0) {
401 			cur->avg_day = (cur->last_day + cur->avg_day) / 2;
402 			resethour++;
403 		}
404 		bcopy(cur, &crs, sizeof(crs));
405 
406 		cur->last = 0;
407 		if (resethour)
408 			cur->last_hour = 0;
409 		if (resetday)
410 			cur->last_day = 0;
411 
412 		crs.id = rlay->rl_conf.id;
413 		crs.proc = ps->ps_instance;
414 		proc_compose(env->sc_ps, PROC_PFE, IMSG_STATISTICS,
415 		    &crs, sizeof(crs));
416 
417 		for (con = SPLAY_ROOT(&rlay->rl_sessions);
418 		    con != NULL; con = next_con) {
419 			next_con = SPLAY_NEXT(session_tree,
420 			    &rlay->rl_sessions, con);
421 			timersub(&tv_now, &con->se_tv_last, &tv);
422 			if (timercmp(&tv, &rlay->rl_conf.timeout, >=))
423 				relay_close(con, "hard timeout", 1);
424 		}
425 	}
426 
427 	/* Schedule statistics timer */
428 	evtimer_set(&env->sc_statev, relay_statistics, ps);
429 	bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
430 	evtimer_add(&env->sc_statev, &tv);
431 }
432 
433 void
434 relay_launch(void)
435 {
436 	void			(*callback)(int, short, void *);
437 	struct relay		*rlay;
438 	struct host		*host;
439 	struct relay_table	*rlt;
440 
441 	TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
442 		if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) &&
443 		    relay_tls_ctx_create(rlay) == -1)
444 			fatalx("%s: failed to create TLS context", __func__);
445 
446 		TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
447 			/*
448 			 * set rule->rule_table in advance and save time
449 			 * looking up for this later on rule/connection
450 			 * evalution
451 			 */
452 			rule_settable(&rlay->rl_proto->rules, rlt);
453 
454 			rlt->rlt_index = 0;
455 			rlt->rlt_nhosts = 0;
456 			TAILQ_FOREACH(host, &rlt->rlt_table->hosts, entry) {
457 				if (rlt->rlt_nhosts >= RELAY_MAXHOSTS)
458 					fatal("%s: too many hosts in table",
459 					    __func__);
460 				host->idx = rlt->rlt_nhosts;
461 				rlt->rlt_host[rlt->rlt_nhosts++] = host;
462 			}
463 			log_info("adding %d hosts from table %s%s",
464 			    rlt->rlt_nhosts, rlt->rlt_table->conf.name,
465 			    rlt->rlt_table->conf.check ? "" : " (no check)");
466 		}
467 
468 		switch (rlay->rl_proto->type) {
469 		case RELAY_PROTO_DNS:
470 			relay_udp_init(env, rlay);
471 			break;
472 		case RELAY_PROTO_TCP:
473 		case RELAY_PROTO_HTTP:
474 			relay_http_init(rlay);
475 			/* Use defaults */
476 			break;
477 		}
478 
479 		log_debug("%s: running relay %s", __func__,
480 		    rlay->rl_conf.name);
481 
482 		rlay->rl_up = HOST_UP;
483 
484 		if (rlay->rl_conf.flags & F_UDP)
485 			callback = relay_udp_server;
486 		else
487 			callback = relay_accept;
488 
489 		event_set(&rlay->rl_ev, rlay->rl_s, EV_READ,
490 		    callback, rlay);
491 		event_add(&rlay->rl_ev, NULL);
492 		evtimer_set(&rlay->rl_evt, callback, rlay);
493 	}
494 }
495 
496 int
497 relay_socket_af(struct sockaddr_storage *ss, in_port_t port)
498 {
499 	switch (ss->ss_family) {
500 	case AF_INET:
501 		((struct sockaddr_in *)ss)->sin_port = port;
502 		((struct sockaddr_in *)ss)->sin_len =
503 		    sizeof(struct sockaddr_in);
504 		break;
505 	case AF_INET6:
506 		((struct sockaddr_in6 *)ss)->sin6_port = port;
507 		((struct sockaddr_in6 *)ss)->sin6_len =
508 		    sizeof(struct sockaddr_in6);
509 		break;
510 	default:
511 		return (-1);
512 	}
513 
514 	return (0);
515 }
516 
517 in_port_t
518 relay_socket_getport(struct sockaddr_storage *ss)
519 {
520 	switch (ss->ss_family) {
521 	case AF_INET:
522 		return (((struct sockaddr_in *)ss)->sin_port);
523 	case AF_INET6:
524 		return (((struct sockaddr_in6 *)ss)->sin6_port);
525 	default:
526 		return (0);
527 	}
528 
529 	/* NOTREACHED */
530 	return (0);
531 }
532 
533 int
534 relay_socket(struct sockaddr_storage *ss, in_port_t port,
535     struct protocol *proto, int fd, int reuseport)
536 {
537 	struct linger	lng;
538 	int		s = -1, val;
539 
540 	if (relay_socket_af(ss, port) == -1)
541 		goto bad;
542 
543 	s = fd == -1 ? socket(ss->ss_family,
544 	    SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP) : fd;
545 	if (s == -1)
546 		goto bad;
547 
548 	/*
549 	 * Socket options
550 	 */
551 	bzero(&lng, sizeof(lng));
552 	if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
553 		goto bad;
554 	if (reuseport) {
555 		val = 1;
556 		if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
557 			sizeof(int)) == -1)
558 			goto bad;
559 	}
560 	if (proto->tcpflags & TCPFLAG_BUFSIZ) {
561 		val = proto->tcpbufsiz;
562 		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
563 		    &val, sizeof(val)) == -1)
564 			goto bad;
565 		val = proto->tcpbufsiz;
566 		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
567 		    &val, sizeof(val)) == -1)
568 			goto bad;
569 	}
570 
571 	/*
572 	 * IP options
573 	 */
574 	if (proto->tcpflags & TCPFLAG_IPTTL) {
575 		val = (int)proto->tcpipttl;
576 		switch (ss->ss_family) {
577 		case AF_INET:
578 			if (setsockopt(s, IPPROTO_IP, IP_TTL,
579 			    &val, sizeof(val)) == -1)
580 				goto bad;
581 			break;
582 		case AF_INET6:
583 			if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
584 			    &val, sizeof(val)) == -1)
585 				goto bad;
586 			break;
587 		}
588 	}
589 	if (proto->tcpflags & TCPFLAG_IPMINTTL) {
590 		val = (int)proto->tcpipminttl;
591 		switch (ss->ss_family) {
592 		case AF_INET:
593 			if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
594 			    &val, sizeof(val)) == -1)
595 				goto bad;
596 			break;
597 		case AF_INET6:
598 			if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
599 			    &val, sizeof(val)) == -1)
600 				goto bad;
601 			break;
602 		}
603 	}
604 
605 	/*
606 	 * TCP options
607 	 */
608 	if (proto->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) {
609 		if (proto->tcpflags & TCPFLAG_NNODELAY)
610 			val = 0;
611 		else
612 			val = 1;
613 		if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
614 		    &val, sizeof(val)) == -1)
615 			goto bad;
616 	}
617 	if (proto->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) {
618 		if (proto->tcpflags & TCPFLAG_NSACK)
619 			val = 0;
620 		else
621 			val = 1;
622 		if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE,
623 		    &val, sizeof(val)) == -1)
624 			goto bad;
625 	}
626 
627 	return (s);
628 
629  bad:
630 	if (s != -1)
631 		close(s);
632 	return (-1);
633 }
634 
635 int
636 relay_socket_connect(struct sockaddr_storage *ss, in_port_t port,
637     struct protocol *proto, int fd)
638 {
639 	int	s;
640 
641 	if ((s = relay_socket(ss, port, proto, fd, 0)) == -1)
642 		return (-1);
643 
644 	if (connect(s, (struct sockaddr *)ss, ss->ss_len) == -1) {
645 		if (errno != EINPROGRESS)
646 			goto bad;
647 	}
648 
649 	return (s);
650 
651  bad:
652 	close(s);
653 	return (-1);
654 }
655 
656 int
657 relay_socket_listen(struct sockaddr_storage *ss, in_port_t port,
658     struct protocol *proto)
659 {
660 	int s;
661 
662 	if ((s = relay_socket(ss, port, proto, -1, 1)) == -1)
663 		return (-1);
664 
665 	if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
666 		goto bad;
667 	if (listen(s, proto->tcpbacklog) == -1)
668 		goto bad;
669 
670 	return (s);
671 
672  bad:
673 	close(s);
674 	return (-1);
675 }
676 
677 void
678 relay_connected(int fd, short sig, void *arg)
679 {
680 	char			 obuf[128];
681 	struct rsession		*con = arg;
682 	struct relay		*rlay = con->se_relay;
683 	struct protocol		*proto = rlay->rl_proto;
684 	evbuffercb		 outrd = relay_read;
685 	evbuffercb		 outwr = relay_write;
686 	struct bufferevent	*bev;
687 	struct ctl_relay_event	*out = &con->se_out;
688 	char			*msg;
689 	socklen_t		 len;
690 	int			 error;
691 
692 	if (sig == EV_TIMEOUT) {
693 		relay_abort_http(con, 504, "connect timeout", 0);
694 		return;
695 	}
696 
697 	len = sizeof(error);
698 	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
699 		relay_abort_http(con, 500, "getsockopt failed", 0);
700 		return;
701 	}
702 	if (error) {
703 		errno = error;
704 		if (asprintf(&msg, "socket error: %s",
705 		    strerror(error)) >= 0) {
706 			relay_abort_http(con, 500, msg, 0);
707 			free(msg);
708 			return;
709 		} else {
710 			relay_abort_http(con, 500,
711 			    "socket error and asprintf failed", 0);
712 			return;
713 		}
714 	}
715 
716 	if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls == NULL)) {
717 		relay_tls_transaction(con, out);
718 		return;
719 	}
720 
721 	DPRINTF("%s: session %d: successful", __func__, con->se_id);
722 
723 	/* Log destination if it was changed in a keep-alive connection */
724 	if ((con->se_table != con->se_table0) &&
725 	    (env->sc_conf.opts & (RELAYD_OPT_LOGCON|RELAYD_OPT_LOGCONERR))) {
726 		con->se_table0 = con->se_table;
727 		memset(&obuf, 0, sizeof(obuf));
728 		(void)print_host(&con->se_out.ss, obuf, sizeof(obuf));
729 		if (asprintf(&msg, " -> %s:%d",
730 		    obuf, ntohs(con->se_out.port)) == -1) {
731 			relay_abort_http(con, 500,
732 			    "connection changed and asprintf failed", 0);
733 			return;
734 		}
735 		relay_log(con, msg);
736 		free(msg);
737 	}
738 
739 	switch (rlay->rl_proto->type) {
740 	case RELAY_PROTO_HTTP:
741 		if (relay_httpdesc_init(out) == -1) {
742 			relay_close(con,
743 			    "failed to allocate http descriptor", 1);
744 			return;
745 		}
746 		con->se_out.toread = TOREAD_HTTP_HEADER;
747 		outrd = relay_read_http;
748 		break;
749 	case RELAY_PROTO_TCP:
750 		/* Use defaults */
751 		break;
752 	default:
753 		fatalx("%s: unknown protocol", __func__);
754 	}
755 
756 	/*
757 	 * Relay <-> Server
758 	 */
759 	bev = bufferevent_new(fd, outrd, outwr, relay_error, &con->se_out);
760 	if (bev == NULL) {
761 		relay_abort_http(con, 500,
762 		    "failed to allocate output buffer event", 0);
763 		return;
764 	}
765 	/* write pending output buffer now */
766 	if (bufferevent_write_buffer(bev, con->se_out.output)) {
767 		relay_abort_http(con, 500, strerror(errno), 0);
768 		return;
769 	}
770 	con->se_out.bev = bev;
771 
772 	/* Initialize the TLS wrapper */
773 	if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls != NULL))
774 		relay_tls_connected(out);
775 
776 	bufferevent_settimeout(bev,
777 	    rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
778 	bufferevent_setwatermark(bev, EV_WRITE,
779 		RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
780 	bufferevent_enable(bev, EV_READ|EV_WRITE);
781 	if (con->se_in.bev)
782 		bufferevent_enable(con->se_in.bev, EV_READ);
783 
784 	if (relay_splice(&con->se_out) == -1)
785 		relay_close(con, strerror(errno), 1);
786 }
787 
788 void
789 relay_input(struct rsession *con)
790 {
791 	struct relay	*rlay = con->se_relay;
792 	struct protocol	*proto = rlay->rl_proto;
793 	evbuffercb	 inrd = relay_read;
794 	evbuffercb	 inwr = relay_write;
795 
796 	switch (rlay->rl_proto->type) {
797 	case RELAY_PROTO_HTTP:
798 		if (relay_httpdesc_init(&con->se_in) == -1) {
799 			relay_close(con,
800 			    "failed to allocate http descriptor", 1);
801 			return;
802 		}
803 		con->se_in.toread = TOREAD_HTTP_HEADER;
804 		inrd = relay_read_http;
805 		break;
806 	case RELAY_PROTO_TCP:
807 		/* Use defaults */
808 		break;
809 	default:
810 		fatalx("%s: unknown protocol", __func__);
811 	}
812 
813 	/*
814 	 * Client <-> Relay
815 	 */
816 	con->se_in.bev = bufferevent_new(con->se_in.s, inrd, inwr,
817 	    relay_error, &con->se_in);
818 	if (con->se_in.bev == NULL) {
819 		relay_close(con, "failed to allocate input buffer event", 1);
820 		return;
821 	}
822 
823 	/* Initialize the TLS wrapper */
824 	if ((rlay->rl_conf.flags & F_TLS) && con->se_in.tls != NULL)
825 		relay_tls_connected(&con->se_in);
826 
827 	bufferevent_settimeout(con->se_in.bev,
828 	    rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
829 	bufferevent_setwatermark(con->se_in.bev, EV_WRITE,
830 		RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
831 	bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE);
832 
833 	if (relay_splice(&con->se_in) == -1)
834 		relay_close(con, strerror(errno), 1);
835 }
836 
837 void
838 relay_write(struct bufferevent *bev, void *arg)
839 {
840 	struct ctl_relay_event	*cre = arg;
841 	struct rsession		*con = cre->con;
842 
843 	getmonotime(&con->se_tv_last);
844 
845 	if (con->se_done && EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) == 0)
846 		goto done;
847 	if (cre->dst->bev)
848 		bufferevent_enable(cre->dst->bev, EV_READ);
849 	if (relay_splice(cre->dst) == -1)
850 		goto fail;
851 
852 	return;
853  done:
854 	relay_close(con, "last write (done)", 0);
855 	return;
856  fail:
857 	relay_close(con, strerror(errno), 1);
858 }
859 
860 void
861 relay_dump(struct ctl_relay_event *cre, const void *buf, size_t len)
862 {
863 	if (!len)
864 		return;
865 
866 	/*
867 	 * This function will dump the specified message directly
868 	 * to the underlying session, without waiting for success
869 	 * of non-blocking events etc. This is useful to print an
870 	 * error message before gracefully closing the session.
871 	 */
872 	if (cre->tls != NULL)
873 		(void)tls_write(cre->tls, buf, len);
874 	else
875 		(void)write(cre->s, buf, len);
876 }
877 
878 void
879 relay_read(struct bufferevent *bev, void *arg)
880 {
881 	struct ctl_relay_event	*cre = arg;
882 	struct rsession		*con = cre->con;
883 	struct protocol		*proto = con->se_relay->rl_proto;
884 	struct evbuffer		*src = EVBUFFER_INPUT(bev);
885 
886 	getmonotime(&con->se_tv_last);
887 	cre->timedout = 0;
888 
889 	if (!EVBUFFER_LENGTH(src))
890 		return;
891 	if (relay_bufferevent_write_buffer(cre->dst, src) == -1)
892 		goto fail;
893 	if (con->se_done)
894 		goto done;
895 	if (cre->dst->bev)
896 		bufferevent_enable(cre->dst->bev, EV_READ);
897 	if (cre->dst->bev && EVBUFFER_LENGTH(EVBUFFER_OUTPUT(cre->dst->bev)) >
898 	    (size_t)RELAY_MAX_PREFETCH * proto->tcpbufsiz)
899 		bufferevent_disable(bev, EV_READ);
900 
901 	return;
902  done:
903 	relay_close(con, "last read (done)", 0);
904 	return;
905  fail:
906 	relay_close(con, strerror(errno), 1);
907 }
908 
909 /*
910  * Splice sockets from cre to cre->dst if applicable.  Returns:
911  * -1 socket splicing has failed
912  * 0 socket splicing is currently not possible
913  * 1 socket splicing was successful
914  */
915 int
916 relay_splice(struct ctl_relay_event *cre)
917 {
918 	struct rsession		*con = cre->con;
919 	struct relay		*rlay = con->se_relay;
920 	struct protocol		*proto = rlay->rl_proto;
921 	struct splice		 sp;
922 
923 	if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ||
924 	    (proto->tcpflags & TCPFLAG_NSPLICE))
925 		return (0);
926 
927 	if (cre->splicelen >= 0)
928 		return (0);
929 
930 	/* still not connected */
931 	if (cre->bev == NULL || cre->dst->bev == NULL)
932 		return (0);
933 
934 	if (!(cre->toread == TOREAD_UNLIMITED || cre->toread > 0)) {
935 		DPRINTF("%s: session %d: splice dir %d, nothing to read %lld",
936 		    __func__, con->se_id, cre->dir, cre->toread);
937 		return (0);
938 	}
939 
940 	/* do not splice before buffers have not been completely flushed */
941 	if (EVBUFFER_LENGTH(cre->bev->input) ||
942 	    EVBUFFER_LENGTH(cre->dst->bev->output)) {
943 		DPRINTF("%s: session %d: splice dir %d, dirty buffer",
944 		    __func__, con->se_id, cre->dir);
945 		bufferevent_disable(cre->bev, EV_READ);
946 		return (0);
947 	}
948 
949 	bzero(&sp, sizeof(sp));
950 	sp.sp_fd = cre->dst->s;
951 	sp.sp_max = cre->toread > 0 ? cre->toread : 0;
952 	bcopy(&rlay->rl_conf.timeout, &sp.sp_idle, sizeof(sp.sp_idle));
953 	if (setsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)) == -1) {
954 		log_debug("%s: session %d: splice dir %d failed: %s",
955 		    __func__, con->se_id, cre->dir, strerror(errno));
956 		return (-1);
957 	}
958 	cre->splicelen = 0;
959 	bufferevent_enable(cre->bev, EV_READ);
960 
961 	DPRINTF("%s: session %d: splice dir %d, maximum %lld, successful",
962 	    __func__, con->se_id, cre->dir, cre->toread);
963 
964 	return (1);
965 }
966 
967 int
968 relay_splicelen(struct ctl_relay_event *cre)
969 {
970 	struct rsession		*con = cre->con;
971 	off_t			 len;
972 	socklen_t		 optlen;
973 
974 	if (cre->splicelen < 0)
975 		return (0);
976 
977 	optlen = sizeof(len);
978 	if (getsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &len, &optlen) == -1) {
979 		log_debug("%s: session %d: splice dir %d get length failed: %s",
980 		    __func__, con->se_id, cre->dir, strerror(errno));
981 		return (-1);
982 	}
983 
984 	DPRINTF("%s: session %d: splice dir %d, length %lld",
985 	    __func__, con->se_id, cre->dir, len);
986 
987 	if (len > cre->splicelen) {
988 		getmonotime(&con->se_tv_last);
989 
990 		cre->splicelen = len;
991 		return (1);
992 	}
993 
994 	return (0);
995 }
996 
997 int
998 relay_spliceadjust(struct ctl_relay_event *cre)
999 {
1000 	if (cre->splicelen < 0)
1001 		return (0);
1002 	if (relay_splicelen(cre) == -1)
1003 		return (-1);
1004 	if (cre->splicelen > 0 && cre->toread > 0)
1005 		cre->toread -= cre->splicelen;
1006 	cre->splicelen = -1;
1007 
1008 	return (0);
1009 }
1010 
1011 void
1012 relay_error(struct bufferevent *bev, short error, void *arg)
1013 {
1014 	struct ctl_relay_event	*cre = arg;
1015 	struct rsession		*con = cre->con;
1016 	struct evbuffer		*dst;
1017 
1018 	DPRINTF("%s: session %d: dir %d state %d to read %lld event error %x",
1019 		__func__, con->se_id, cre->dir, cre->state, cre->toread, error);
1020 	if (error & EVBUFFER_TIMEOUT) {
1021 		if (cre->splicelen >= 0) {
1022 			bufferevent_enable(bev, EV_READ);
1023 		} else if (cre->dst->splicelen >= 0) {
1024 			switch (relay_splicelen(cre->dst)) {
1025 			case -1:
1026 				goto fail;
1027 			case 0:
1028 				relay_close(con, "buffer event timeout", 1);
1029 				break;
1030 			case 1:
1031 				cre->timedout = 1;
1032 				bufferevent_enable(bev, EV_READ);
1033 				break;
1034 			}
1035 		} else {
1036 			relay_close(con, "buffer event timeout", 1);
1037 		}
1038 		return;
1039 	}
1040 	if (error & EVBUFFER_ERROR && errno == ETIMEDOUT) {
1041 		if (cre->dst->splicelen >= 0) {
1042 			switch (relay_splicelen(cre->dst)) {
1043 			case -1:
1044 				goto fail;
1045 			case 0:
1046 				relay_close(con, "splice timeout", 1);
1047 				return;
1048 			case 1:
1049 				bufferevent_enable(bev, EV_READ);
1050 				break;
1051 			}
1052 		} else if (cre->dst->timedout) {
1053 			relay_close(con, "splice timeout", 1);
1054 			return;
1055 		}
1056 		if (relay_spliceadjust(cre) == -1)
1057 			goto fail;
1058 		if (relay_splice(cre) == -1)
1059 			goto fail;
1060 		return;
1061 	}
1062 	if (error & EVBUFFER_ERROR && errno == EFBIG) {
1063 		if (relay_spliceadjust(cre) == -1)
1064 			goto fail;
1065 		bufferevent_enable(cre->bev, EV_READ);
1066 		return;
1067 	}
1068 	if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) {
1069 		bufferevent_disable(bev, EV_READ|EV_WRITE);
1070 
1071 		con->se_done = 1;
1072 		if (cre->dst->bev != NULL) {
1073 			dst = EVBUFFER_OUTPUT(cre->dst->bev);
1074 			if (EVBUFFER_LENGTH(dst))
1075 				return;
1076 		} else if (cre->toread == TOREAD_UNLIMITED || cre->toread == 0)
1077 			return;
1078 
1079 		relay_close(con, "done", 0);
1080 		return;
1081 	}
1082 	relay_close(con, "buffer event error", 1);
1083 	return;
1084  fail:
1085 	relay_close(con, strerror(errno), 1);
1086 }
1087 
1088 void
1089 relay_accept(int fd, short event, void *arg)
1090 {
1091 	struct privsep		*ps = env->sc_ps;
1092 	struct relay		*rlay = arg;
1093 	struct rsession		*con = NULL;
1094 	struct ctl_natlook	*cnl = NULL;
1095 	socklen_t		 slen;
1096 	struct timeval		 tv;
1097 	struct sockaddr_storage	 ss;
1098 	int			 s = -1;
1099 
1100 	event_add(&rlay->rl_ev, NULL);
1101 	if ((event & EV_TIMEOUT))
1102 		return;
1103 
1104 	slen = sizeof(ss);
1105 	if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
1106 	    &slen, FD_RESERVE, &relay_inflight)) == -1) {
1107 		/*
1108 		 * Pause accept if we are out of file descriptors, or
1109 		 * libevent will haunt us here too.
1110 		 */
1111 		if (errno == ENFILE || errno == EMFILE) {
1112 			struct timeval evtpause = { 1, 0 };
1113 
1114 			event_del(&rlay->rl_ev);
1115 			evtimer_add(&rlay->rl_evt, &evtpause);
1116 			log_debug("%s: deferring connections", __func__);
1117 		}
1118 		return;
1119 	}
1120 	if (rlay->rl_conf.flags & F_DISABLE)
1121 		goto err;
1122 
1123 	if ((con = calloc(1, sizeof(*con))) == NULL)
1124 		goto err;
1125 
1126 	/* Pre-allocate log buffer */
1127 	con->se_haslog = 0;
1128 	con->se_log = evbuffer_new();
1129 	if (con->se_log == NULL)
1130 		goto err;
1131 
1132 	con->se_in.s = s;
1133 	con->se_in.tls = NULL;
1134 	con->se_out.s = -1;
1135 	con->se_out.tls = NULL;
1136 	con->se_in.dst = &con->se_out;
1137 	con->se_out.dst = &con->se_in;
1138 	con->se_in.con = con;
1139 	con->se_out.con = con;
1140 	con->se_in.splicelen = -1;
1141 	con->se_out.splicelen = -1;
1142 	con->se_in.toread = TOREAD_UNLIMITED;
1143 	con->se_out.toread = TOREAD_UNLIMITED;
1144 	con->se_relay = rlay;
1145 	con->se_id = ++relay_conid;
1146 	con->se_relayid = rlay->rl_conf.id;
1147 	con->se_pid = getpid();
1148 	con->se_in.dir = RELAY_DIR_REQUEST;
1149 	con->se_out.dir = RELAY_DIR_RESPONSE;
1150 	con->se_retry = rlay->rl_conf.dstretry;
1151 	con->se_bnds = -1;
1152 	con->se_out.port = rlay->rl_conf.dstport;
1153 	switch (ss.ss_family) {
1154 	case AF_INET:
1155 		con->se_in.port = ((struct sockaddr_in *)&ss)->sin_port;
1156 		break;
1157 	case AF_INET6:
1158 		con->se_in.port = ((struct sockaddr_in6 *)&ss)->sin6_port;
1159 		break;
1160 	}
1161 	memcpy(&con->se_in.ss, &ss, sizeof(con->se_in.ss));
1162 
1163 	slen = sizeof(con->se_sockname);
1164 	if (getsockname(s, (struct sockaddr *)&con->se_sockname, &slen) == -1) {
1165 		relay_close(con, "sockname lookup failed", 1);
1166 		return;
1167 	}
1168 
1169 	getmonotime(&con->se_tv_start);
1170 	bcopy(&con->se_tv_start, &con->se_tv_last, sizeof(con->se_tv_last));
1171 
1172 	if (rlay->rl_conf.flags & F_HASHKEY) {
1173 		SipHash24_Init(&con->se_siphashctx,
1174 		    &rlay->rl_conf.hashkey.siphashkey);
1175 	}
1176 
1177 	relay_sessions++;
1178 	SPLAY_INSERT(session_tree, &rlay->rl_sessions, con);
1179 	relay_session_publish(con);
1180 
1181 	/* Increment the per-relay session counter */
1182 	rlay->rl_stats[ps->ps_instance].last++;
1183 
1184 	/* Pre-allocate output buffer */
1185 	con->se_out.output = evbuffer_new();
1186 	if (con->se_out.output == NULL) {
1187 		relay_close(con, "failed to allocate output buffer", 1);
1188 		return;
1189 	}
1190 
1191 	if (rlay->rl_conf.flags & F_DIVERT) {
1192 		memcpy(&con->se_out.ss, &con->se_sockname,
1193 		    sizeof(con->se_out.ss));
1194 		con->se_out.port = relay_socket_getport(&con->se_out.ss);
1195 
1196 		/* Detect loop and fall back to the alternate forward target */
1197 		if (bcmp(&rlay->rl_conf.ss, &con->se_out.ss,
1198 		    sizeof(con->se_out.ss)) == 0 &&
1199 		    con->se_out.port == rlay->rl_conf.port)
1200 			con->se_out.ss.ss_family = AF_UNSPEC;
1201 	} else if (rlay->rl_conf.flags & F_NATLOOK) {
1202 		if ((cnl = calloc(1, sizeof(*cnl))) == NULL) {
1203 			relay_close(con, "failed to allocate nat lookup", 1);
1204 			return;
1205 		}
1206 
1207 		con->se_cnl = cnl;
1208 		bzero(cnl, sizeof(*cnl));
1209 		cnl->in = -1;
1210 		cnl->id = con->se_id;
1211 		cnl->proc = ps->ps_instance;
1212 		cnl->proto = IPPROTO_TCP;
1213 
1214 		memcpy(&cnl->src, &con->se_in.ss, sizeof(cnl->src));
1215 		memcpy(&cnl->dst, &con->se_sockname, sizeof(cnl->dst));
1216 
1217 		proc_compose(env->sc_ps, PROC_PFE, IMSG_NATLOOK,
1218 		    cnl, sizeof(*cnl));
1219 
1220 		/* Schedule timeout */
1221 		evtimer_set(&con->se_ev, relay_natlook, con);
1222 		bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv));
1223 		evtimer_add(&con->se_ev, &tv);
1224 		return;
1225 	}
1226 
1227 	if (rlay->rl_conf.flags & F_TLSINSPECT) {
1228 		relay_preconnect(con);
1229 		return;
1230 	}
1231 
1232 	relay_session(con);
1233 	return;
1234  err:
1235 	if (s != -1) {
1236 		close(s);
1237 		free(con);
1238 		/*
1239 		 * the session struct was not completely set up, but still
1240 		 * counted as an inflight session. account for this.
1241 		 */
1242 		relay_inflight--;
1243 		log_debug("%s: inflight decremented, now %d",
1244 		    __func__, relay_inflight);
1245 	}
1246 }
1247 
1248 void
1249 relay_hash_addr(SIPHASH_CTX *ctx, struct sockaddr_storage *ss, int portset)
1250 {
1251 	struct sockaddr_in	*sin4;
1252 	struct sockaddr_in6	*sin6;
1253 	in_port_t		 port;
1254 
1255 	if (ss->ss_family == AF_INET) {
1256 		sin4 = (struct sockaddr_in *)ss;
1257 		SipHash24_Update(ctx, &sin4->sin_addr,
1258 		    sizeof(struct in_addr));
1259 	} else {
1260 		sin6 = (struct sockaddr_in6 *)ss;
1261 		SipHash24_Update(ctx, &sin6->sin6_addr,
1262 		    sizeof(struct in6_addr));
1263 	}
1264 
1265 	if (portset != -1) {
1266 		port = (in_port_t)portset;
1267 		SipHash24_Update(ctx, &port, sizeof(port));
1268 	}
1269 }
1270 
1271 int
1272 relay_from_table(struct rsession *con)
1273 {
1274 	struct relay		*rlay = con->se_relay;
1275 	struct host		*host = NULL;
1276 	struct relay_table	*rlt = NULL;
1277 	struct table		*table = NULL;
1278 	int			 idx = -1;
1279 	int			 cnt = 0;
1280 	int			 maxtries;
1281 	u_int64_t		 p = 0;
1282 
1283 	/* the table is already selected */
1284 	if (con->se_table != NULL) {
1285 		rlt = con->se_table;
1286 		table = rlt->rlt_table;
1287 		if (table->conf.check && !table->up)
1288 			table = NULL;
1289 		goto gottable;
1290 	}
1291 
1292 	/* otherwise grep the first active table */
1293 	TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
1294 		table = rlt->rlt_table;
1295 		if ((rlt->rlt_flags & F_USED) == 0 ||
1296 		    (table->conf.check && !table->up))
1297 			table = NULL;
1298 		else
1299 			break;
1300 	}
1301 
1302  gottable:
1303 	if (table == NULL) {
1304 		log_debug("%s: session %d: no active hosts",
1305 		    __func__, con->se_id);
1306 		return (-1);
1307 	}
1308 
1309 	switch (rlt->rlt_mode) {
1310 	case RELAY_DSTMODE_ROUNDROBIN:
1311 		if ((int)rlt->rlt_index >= rlt->rlt_nhosts)
1312 			rlt->rlt_index = 0;
1313 		idx = (int)rlt->rlt_index;
1314 		break;
1315 	case RELAY_DSTMODE_RANDOM:
1316 		idx = (int)arc4random_uniform(rlt->rlt_nhosts);
1317 		break;
1318 	case RELAY_DSTMODE_SRCHASH:
1319 		/* Source IP address without port */
1320 		relay_hash_addr(&con->se_siphashctx, &con->se_in.ss, -1);
1321 		break;
1322 	case RELAY_DSTMODE_LOADBALANCE:
1323 		/* Source IP address without port */
1324 		relay_hash_addr(&con->se_siphashctx, &con->se_in.ss, -1);
1325 		/* FALLTHROUGH */
1326 	case RELAY_DSTMODE_HASH:
1327 		/* Local "destination" IP address and port */
1328 		relay_hash_addr(&con->se_siphashctx, &rlay->rl_conf.ss,
1329 		    rlay->rl_conf.port);
1330 		break;
1331 	default:
1332 		fatalx("%s: unsupported mode", __func__);
1333 		/* NOTREACHED */
1334 	}
1335 	if (idx == -1) {
1336 		/* handle all hashing algorithms */
1337 		p = SipHash24_End(&con->se_siphashctx);
1338 
1339 		/* Reset hash context */
1340 		SipHash24_Init(&con->se_siphashctx,
1341 		    &rlay->rl_conf.hashkey.siphashkey);
1342 
1343 		maxtries = (rlt->rlt_nhosts < RELAY_MAX_HASH_RETRIES ?
1344 		    rlt->rlt_nhosts : RELAY_MAX_HASH_RETRIES);
1345 		for (cnt = 0; cnt < maxtries; cnt++) {
1346 			if ((idx = p % rlt->rlt_nhosts) >= RELAY_MAXHOSTS)
1347 				return (-1);
1348 
1349 			host = rlt->rlt_host[idx];
1350 
1351 			DPRINTF("%s: session %d: table %s host %s, "
1352 			    "p 0x%016llx, idx %d, cnt %d, max %d",
1353 			    __func__, con->se_id, table->conf.name,
1354 			    host->conf.name, p, idx, cnt, maxtries);
1355 
1356 			if (!table->conf.check || host->up == HOST_UP)
1357 				goto found;
1358 			p = p >> 1;
1359 		}
1360 	} else {
1361 		/* handle all non-hashing algorithms */
1362 		host = rlt->rlt_host[idx];
1363 		DPRINTF("%s: session %d: table %s host %s, p 0x%016llx, idx %d",
1364 		    __func__, con->se_id, table->conf.name, host->conf.name,
1365 		    p, idx);
1366 	}
1367 
1368 	while (host != NULL) {
1369 		DPRINTF("%s: session %d: host %s", __func__,
1370 		    con->se_id, host->conf.name);
1371 		if (!table->conf.check || host->up == HOST_UP)
1372 			goto found;
1373 		host = TAILQ_NEXT(host, entry);
1374 	}
1375 	TAILQ_FOREACH(host, &table->hosts, entry) {
1376 		DPRINTF("%s: session %d: next host %s",
1377 		    __func__, con->se_id, host->conf.name);
1378 		if (!table->conf.check || host->up == HOST_UP)
1379 			goto found;
1380 	}
1381 
1382 	/* Should not happen */
1383 	fatalx("%s: no active hosts, desynchronized", __func__);
1384 
1385  found:
1386 	if (rlt->rlt_mode == RELAY_DSTMODE_ROUNDROBIN)
1387 		rlt->rlt_index = host->idx + 1;
1388 	con->se_retry = host->conf.retry;
1389 	con->se_out.port = table->conf.port;
1390 	bcopy(&host->conf.ss, &con->se_out.ss, sizeof(con->se_out.ss));
1391 
1392 	return (0);
1393 }
1394 
1395 void
1396 relay_natlook(int fd, short event, void *arg)
1397 {
1398 	struct rsession		*con = arg;
1399 	struct relay		*rlay = con->se_relay;
1400 	struct ctl_natlook	*cnl = con->se_cnl;
1401 
1402 	if (cnl == NULL)
1403 		fatalx("invalid NAT lookup");
1404 
1405 	if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 &&
1406 	    rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
1407 	    TAILQ_EMPTY(&rlay->rl_tables)) {
1408 		relay_close(con, "session NAT lookup failed", 1);
1409 		return;
1410 	}
1411 	if (cnl->in != -1) {
1412 		bcopy(&cnl->rdst, &con->se_out.ss, sizeof(con->se_out.ss));
1413 		con->se_out.port = cnl->rdport;
1414 	}
1415 	free(con->se_cnl);
1416 	con->se_cnl = NULL;
1417 
1418 	relay_session(con);
1419 }
1420 
1421 void
1422 relay_session(struct rsession *con)
1423 {
1424 	struct relay		*rlay = con->se_relay;
1425 	struct ctl_relay_event	*in = &con->se_in, *out = &con->se_out;
1426 
1427 	if (bcmp(&rlay->rl_conf.ss, &out->ss, sizeof(out->ss)) == 0 &&
1428 	    out->port == rlay->rl_conf.port) {
1429 		log_debug("%s: session %d: looping", __func__, con->se_id);
1430 		relay_close(con, "session aborted", 1);
1431 		return;
1432 	}
1433 
1434 	if (rlay->rl_conf.flags & F_UDP) {
1435 		/*
1436 		 * Call the UDP protocol-specific handler
1437 		 */
1438 		if (rlay->rl_proto->request == NULL)
1439 			fatalx("invalide UDP session");
1440 		if ((*rlay->rl_proto->request)(con) == -1)
1441 			relay_close(con, "session failed", 1);
1442 		return;
1443 	}
1444 
1445 	if ((rlay->rl_conf.flags & F_TLS) && (in->tls == NULL)) {
1446 		relay_tls_transaction(con, in);
1447 		return;
1448 	}
1449 
1450 	if (rlay->rl_proto->type != RELAY_PROTO_HTTP) {
1451 		if (rlay->rl_conf.fwdmode == FWD_TRANS)
1452 			relay_bindanyreq(con, 0, IPPROTO_TCP);
1453 		else if (relay_connect(con) == -1) {
1454 			relay_close(con, "session failed", 1);
1455 			return;
1456 		}
1457 	}
1458 
1459 	relay_input(con);
1460 }
1461 
1462 void
1463 relay_bindanyreq(struct rsession *con, in_port_t port, int proto)
1464 {
1465 	struct privsep		*ps = env->sc_ps;
1466 	struct relay		*rlay = con->se_relay;
1467 	struct ctl_bindany	 bnd;
1468 	struct timeval		 tv;
1469 
1470 	bzero(&bnd, sizeof(bnd));
1471 	bnd.bnd_id = con->se_id;
1472 	bnd.bnd_proc = ps->ps_instance;
1473 	bnd.bnd_port = port;
1474 	bnd.bnd_proto = proto;
1475 	bcopy(&con->se_in.ss, &bnd.bnd_ss, sizeof(bnd.bnd_ss));
1476 	proc_compose(env->sc_ps, PROC_PARENT, IMSG_BINDANY,
1477 	    &bnd, sizeof(bnd));
1478 
1479 	/* Schedule timeout */
1480 	evtimer_set(&con->se_ev, relay_bindany, con);
1481 	bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv));
1482 	evtimer_add(&con->se_ev, &tv);
1483 }
1484 
1485 void
1486 relay_bindany(int fd, short event, void *arg)
1487 {
1488 	struct rsession	*con = arg;
1489 
1490 	if (con->se_bnds == -1) {
1491 		relay_close(con, "bindany failed, invalid socket", 1);
1492 		return;
1493 	}
1494 	if (relay_connect(con) == -1)
1495 		relay_close(con, "session failed", 1);
1496 }
1497 
1498 void
1499 relay_connect_state(struct rsession *con, struct ctl_relay_event *cre,
1500     enum relay_state new)
1501 {
1502 	DPRINTF("%s: session %d: %s state %s -> %s",
1503 	    __func__, con->se_id,
1504 	    cre->dir == RELAY_DIR_REQUEST ? "accept" : "connect",
1505 	    relay_state(cre->state), relay_state(new));
1506 	cre->state = new;
1507 }
1508 
1509 void
1510 relay_connect_retry(int fd, short sig, void *arg)
1511 {
1512 	struct timeval	 evtpause = { 1, 0 };
1513 	struct rsession	*con = arg;
1514 	struct relay	*rlay = con->se_relay;
1515 	int		 bnds = -1;
1516 
1517 	if (relay_inflight < 1) {
1518 		log_warnx("%s: no connection in flight", __func__);
1519 		relay_inflight = 1;
1520 	}
1521 
1522 	DPRINTF("%s: retry %d of %d, inflight: %d",__func__,
1523 	    con->se_retrycount, con->se_retry, relay_inflight);
1524 
1525 	if (sig != EV_TIMEOUT)
1526 		fatalx("%s: called without timeout", __func__);
1527 
1528 	evtimer_del(&con->se_inflightevt);
1529 
1530 	/*
1531 	 * XXX we might want to check if the inbound socket is still
1532 	 * available: client could have closed it while we were waiting?
1533 	 */
1534 
1535 	DPRINTF("%s: got EV_TIMEOUT", __func__);
1536 
1537 	if (getdtablecount() + FD_RESERVE +
1538 	    relay_inflight > getdtablesize()) {
1539 		if (con->se_retrycount < RELAY_OUTOF_FD_RETRIES) {
1540 			evtimer_add(&con->se_inflightevt, &evtpause);
1541 			return;
1542 		}
1543 		/* we waited for RELAY_OUTOF_FD_RETRIES seconds, give up */
1544 		event_add(&rlay->rl_ev, NULL);
1545 		relay_abort_http(con, 504, "connection timed out", 0);
1546 		return;
1547 	}
1548 
1549 	if (rlay->rl_conf.fwdmode == FWD_TRANS) {
1550 		/* con->se_bnds cannot be unset */
1551 		bnds = con->se_bnds;
1552 	}
1553 
1554  retry:
1555 	if ((con->se_out.s = relay_socket_connect(&con->se_out.ss,
1556 	    con->se_out.port, rlay->rl_proto, bnds)) == -1) {
1557 		log_debug("%s: session %d: "
1558 		    "forward failed: %s, %s", __func__,
1559 		    con->se_id, strerror(errno),
1560 		    con->se_retry ? "next retry" : "last retry");
1561 
1562 		con->se_retrycount++;
1563 
1564 		if ((errno == ENFILE || errno == EMFILE) &&
1565 		    (con->se_retrycount < con->se_retry)) {
1566 			event_del(&rlay->rl_ev);
1567 			evtimer_add(&con->se_inflightevt, &evtpause);
1568 			evtimer_add(&rlay->rl_evt, &evtpause);
1569 			return;
1570 		} else if (con->se_retrycount < con->se_retry)
1571 			goto retry;
1572 		event_add(&rlay->rl_ev, NULL);
1573 		relay_abort_http(con, 504, "connect failed", 0);
1574 		return;
1575 	}
1576 
1577 	if (rlay->rl_conf.flags & F_TLSINSPECT)
1578 		relay_connect_state(con, &con->se_out, STATE_PRECONNECT);
1579 	else
1580 		relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1581 	relay_inflight--;
1582 	DPRINTF("%s: inflight decremented, now %d",__func__, relay_inflight);
1583 
1584 	event_add(&rlay->rl_ev, NULL);
1585 
1586 	if (errno == EINPROGRESS)
1587 		event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT,
1588 		    relay_connected, &con->se_tv_start, &rlay->rl_conf.timeout,
1589 		    con);
1590 	else
1591 		relay_connected(con->se_out.s, EV_WRITE, con);
1592 
1593 	return;
1594 }
1595 
1596 int
1597 relay_preconnect(struct rsession *con)
1598 {
1599 	int rv;
1600 
1601 	log_debug("%s: session %d: process %d", __func__,
1602 	    con->se_id, privsep_process);
1603 	rv = relay_connect(con);
1604 	if (con->se_out.state == STATE_CONNECTED)
1605 		relay_connect_state(con, &con->se_out, STATE_PRECONNECT);
1606 	return (rv);
1607 }
1608 
1609 int
1610 relay_connect(struct rsession *con)
1611 {
1612 	struct relay	*rlay = con->se_relay;
1613 	struct timeval	 evtpause = { 1, 0 };
1614 	int		 bnds = -1, ret;
1615 
1616 	/* relay_connect should only be called once per relay */
1617 	if (con->se_out.state == STATE_CONNECTED) {
1618 		log_debug("%s: connect already called once", __func__);
1619 		return (0);
1620 	}
1621 
1622 	/* Connection is already established but session not active */
1623 	if ((rlay->rl_conf.flags & F_TLSINSPECT) &&
1624 	    con->se_out.state == STATE_PRECONNECT) {
1625 		if (con->se_out.tls == NULL) {
1626 			log_debug("%s: tls connect failed", __func__);
1627 			return (-1);
1628 		}
1629 		relay_connected(con->se_out.s, EV_WRITE, con);
1630 		relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1631 		return (0);
1632 	}
1633 
1634 	if (relay_inflight < 1) {
1635 		log_warnx("relay_connect: no connection in flight");
1636 		relay_inflight = 1;
1637 	}
1638 
1639 	getmonotime(&con->se_tv_start);
1640 
1641 	if (con->se_out.ss.ss_family == AF_UNSPEC &&
1642 	    !TAILQ_EMPTY(&rlay->rl_tables)) {
1643 		if (relay_from_table(con) != 0)
1644 			return (-1);
1645 	} else if (con->se_out.ss.ss_family == AF_UNSPEC) {
1646 		bcopy(&rlay->rl_conf.dstss, &con->se_out.ss,
1647 		    sizeof(con->se_out.ss));
1648 		con->se_out.port = rlay->rl_conf.dstport;
1649 	}
1650 
1651 	if (rlay->rl_conf.fwdmode == FWD_TRANS) {
1652 		if (con->se_bnds == -1) {
1653 			log_debug("%s: could not bind any sock", __func__);
1654 			return (-1);
1655 		}
1656 		bnds = con->se_bnds;
1657 	}
1658 
1659 	/* Do the IPv4-to-IPv6 or IPv6-to-IPv4 translation if requested */
1660 	if (rlay->rl_conf.dstaf.ss_family != AF_UNSPEC) {
1661 		if (con->se_out.ss.ss_family == AF_INET &&
1662 		    rlay->rl_conf.dstaf.ss_family == AF_INET6)
1663 			ret = map4to6(&con->se_out.ss, &rlay->rl_conf.dstaf);
1664 		else if (con->se_out.ss.ss_family == AF_INET6 &&
1665 		    rlay->rl_conf.dstaf.ss_family == AF_INET)
1666 			ret = map6to4(&con->se_out.ss);
1667 		else
1668 			ret = 0;
1669 		if (ret != 0) {
1670 			log_debug("%s: mapped to invalid address", __func__);
1671 			return (-1);
1672 		}
1673 	}
1674 
1675  retry:
1676 	if ((con->se_out.s = relay_socket_connect(&con->se_out.ss,
1677 	    con->se_out.port, rlay->rl_proto, bnds)) == -1) {
1678 		if (errno == ENFILE || errno == EMFILE) {
1679 			log_debug("%s: session %d: forward failed: %s",
1680 			    __func__, con->se_id, strerror(errno));
1681 			evtimer_set(&con->se_inflightevt, relay_connect_retry,
1682 			    con);
1683 			event_del(&rlay->rl_ev);
1684 			evtimer_add(&con->se_inflightevt, &evtpause);
1685 			evtimer_add(&rlay->rl_evt, &evtpause);
1686 
1687 			/* this connect is pending */
1688 			relay_connect_state(con, &con->se_out, STATE_PENDING);
1689 			return (0);
1690 		} else {
1691 			if (con->se_retry) {
1692 				con->se_retry--;
1693 				log_debug("%s: session %d: "
1694 				    "forward failed: %s, %s", __func__,
1695 				    con->se_id, strerror(errno),
1696 				    con->se_retry ?
1697 				    "next retry" : "last retry");
1698 				goto retry;
1699 			}
1700 			log_debug("%s: session %d: forward failed: %s",
1701 			    __func__, con->se_id, strerror(errno));
1702 			return (-1);
1703 		}
1704 	}
1705 
1706 	relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1707 	relay_inflight--;
1708 	DPRINTF("%s: inflight decremented, now %d",__func__,
1709 	    relay_inflight);
1710 
1711 	if (errno == EINPROGRESS)
1712 		event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT,
1713 		    relay_connected, &con->se_tv_start, &rlay->rl_conf.timeout,
1714 		    con);
1715 	else
1716 		relay_connected(con->se_out.s, EV_WRITE, con);
1717 
1718 	return (0);
1719 }
1720 
1721 void
1722 relay_close(struct rsession *con, const char *msg, int err)
1723 {
1724 	char		 ibuf[128], obuf[128], *ptr = NULL;
1725 	struct relay	*rlay = con->se_relay;
1726 	struct protocol	*proto = rlay->rl_proto;
1727 
1728 	SPLAY_REMOVE(session_tree, &rlay->rl_sessions, con);
1729 	relay_session_unpublish(con);
1730 
1731 	event_del(&con->se_ev);
1732 
1733 	if ((env->sc_conf.opts & (RELAYD_OPT_LOGCON|RELAYD_OPT_LOGCONERR)) &&
1734 	    msg != NULL) {
1735 		bzero(&ibuf, sizeof(ibuf));
1736 		bzero(&obuf, sizeof(obuf));
1737 		(void)print_host(&con->se_in.ss, ibuf, sizeof(ibuf));
1738 		(void)print_host(&con->se_out.ss, obuf, sizeof(obuf));
1739 		if (EVBUFFER_LENGTH(con->se_log) &&
1740 		    evbuffer_add_printf(con->se_log, "\r\n") != -1) {
1741 			ptr = evbuffer_readln(con->se_log, NULL,
1742 			    EVBUFFER_EOL_CRLF);
1743 		}
1744 		if (err == 0 && (env->sc_conf.opts & RELAYD_OPT_LOGCON))
1745 			log_info("relay %s, "
1746 			    "session %d (%d active), %s, %s -> %s:%d, "
1747 			    "%s%s%s", rlay->rl_conf.name, con->se_id,
1748 			    relay_sessions, con->se_tag != 0 ?
1749 			    tag_id2name(con->se_tag) : "0", ibuf, obuf,
1750 			    ntohs(con->se_out.port), msg, ptr == NULL ?
1751 			    "" : ",", ptr == NULL ? "" : ptr);
1752 		if (err == 1 && (env->sc_conf.opts & RELAYD_OPT_LOGCONERR))
1753 			log_warn("relay %s, "
1754 			    "session %d (%d active), %s, %s -> %s:%d, "
1755 			    "%s%s%s", rlay->rl_conf.name, con->se_id,
1756 			    relay_sessions, con->se_tag != 0 ?
1757 			    tag_id2name(con->se_tag) : "0", ibuf, obuf,
1758 			    ntohs(con->se_out.port), msg, ptr == NULL ?
1759 			    "" : ",", ptr == NULL ? "" : ptr);
1760 		free(ptr);
1761 	}
1762 
1763 	if (proto->close != NULL)
1764 		(*proto->close)(con);
1765 
1766 	free(con->se_priv);
1767 
1768 	relay_connect_state(con, &con->se_in, STATE_DONE);
1769 	if (relay_reset_event(con, &con->se_in)) {
1770 		if (con->se_out.s == -1) {
1771 			/*
1772 			 * the output was never connected,
1773 			 * thus this was an inflight session.
1774 			 */
1775 			relay_inflight--;
1776 			log_debug("%s: sessions inflight decremented, now %d",
1777 			    __func__, relay_inflight);
1778 		}
1779 	}
1780 	if (con->se_in.output != NULL)
1781 		evbuffer_free(con->se_in.output);
1782 
1783 	relay_connect_state(con, &con->se_out, STATE_DONE);
1784 	if (relay_reset_event(con, &con->se_out)) {
1785 		/* Some file descriptors are available again. */
1786 		if (evtimer_pending(&rlay->rl_evt, NULL)) {
1787 			evtimer_del(&rlay->rl_evt);
1788 			event_add(&rlay->rl_ev, NULL);
1789 		}
1790 	}
1791 	if (con->se_out.output != NULL)
1792 		evbuffer_free(con->se_out.output);
1793 
1794 	if (con->se_log != NULL)
1795 		evbuffer_free(con->se_log);
1796 
1797 	if (con->se_cnl != NULL) {
1798 #if 0
1799 		proc_compose_imsg(env->sc_ps, PROC_PFE, -1, IMSG_KILLSTATES, -1,
1800 		    cnl, sizeof(*cnl));
1801 #endif
1802 		free(con->se_cnl);
1803 	}
1804 
1805 	free(con);
1806 	relay_sessions--;
1807 }
1808 
1809 int
1810 relay_reset_event(struct rsession *con, struct ctl_relay_event *cre)
1811 {
1812 	int		 rv = 0;
1813 
1814 	if (cre->state != STATE_DONE)
1815 		relay_connect_state(con, cre, STATE_CLOSED);
1816 	if (cre->bev != NULL) {
1817 		bufferevent_disable(cre->bev, EV_READ|EV_WRITE);
1818 		bufferevent_free(cre->bev);
1819 	}
1820 	if (cre->tls != NULL)
1821 		tls_close(cre->tls);
1822 	tls_free(cre->tls);
1823 	tls_free(cre->tls_ctx);
1824 	tls_config_free(cre->tls_cfg);
1825 	free(cre->tlscert);
1826 	if (cre->s != -1) {
1827 		close(cre->s);
1828 		rv = 1;
1829 	}
1830 	cre->bev = NULL;
1831 	cre->tls = NULL;
1832 	cre->tls_cfg = NULL;
1833 	cre->tlscert = NULL;
1834 	cre->s = -1;
1835 
1836 	return (rv);
1837 }
1838 
1839 int
1840 relay_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
1841 {
1842 	struct relay		*rlay;
1843 	struct rsession		*con, se;
1844 	struct ctl_natlook	 cnl;
1845 	struct timeval		 tv;
1846 	struct host		*host;
1847 	struct table		*table;
1848 	struct ctl_status	 st;
1849 	objid_t			 id;
1850 	int			 cid;
1851 
1852 	switch (imsg->hdr.type) {
1853 	case IMSG_HOST_DISABLE:
1854 		memcpy(&id, imsg->data, sizeof(id));
1855 		if ((host = host_find(env, id)) == NULL)
1856 			fatalx("%s: desynchronized", __func__);
1857 		if ((table = table_find(env, host->conf.tableid)) ==
1858 		    NULL)
1859 			fatalx("%s: invalid table id", __func__);
1860 		if (host->up == HOST_UP)
1861 			table->up--;
1862 		host->flags |= F_DISABLE;
1863 		host->up = HOST_UNKNOWN;
1864 		break;
1865 	case IMSG_HOST_ENABLE:
1866 		memcpy(&id, imsg->data, sizeof(id));
1867 		if ((host = host_find(env, id)) == NULL)
1868 			fatalx("%s: desynchronized", __func__);
1869 		host->flags &= ~(F_DISABLE);
1870 		host->up = HOST_UNKNOWN;
1871 		break;
1872 	case IMSG_TABLE_DISABLE:
1873 		memcpy(&id, imsg->data, sizeof(id));
1874 		if ((table = table_find(env, id)) == NULL)
1875 			fatalx("%s: desynchronized", __func__);
1876 		table->conf.flags |= F_DISABLE;
1877 		table->up = 0;
1878 		TAILQ_FOREACH(host, &table->hosts, entry)
1879 			host->up = HOST_UNKNOWN;
1880 		break;
1881 	case IMSG_TABLE_ENABLE:
1882 		memcpy(&id, imsg->data, sizeof(id));
1883 		if ((table = table_find(env, id)) == NULL)
1884 			fatalx("%s: desynchronized", __func__);
1885 		table->conf.flags &= ~(F_DISABLE);
1886 		table->up = 0;
1887 		TAILQ_FOREACH(host, &table->hosts, entry)
1888 			host->up = HOST_UNKNOWN;
1889 		break;
1890 	case IMSG_HOST_STATUS:
1891 		IMSG_SIZE_CHECK(imsg, &st);
1892 		memcpy(&st, imsg->data, sizeof(st));
1893 		if ((host = host_find(env, st.id)) == NULL)
1894 			fatalx("%s: invalid host id", __func__);
1895 		if (host->flags & F_DISABLE)
1896 			break;
1897 		if (host->up == st.up) {
1898 			log_debug("%s: host %d => %d", __func__,
1899 			    host->conf.id, host->up);
1900 			fatalx("%s: desynchronized", __func__);
1901 		}
1902 
1903 		if ((table = table_find(env, host->conf.tableid))
1904 		    == NULL)
1905 			fatalx("%s: invalid table id", __func__);
1906 
1907 		DPRINTF("%s: [%d] state %d for "
1908 		    "host %u %s", __func__, p->p_ps->ps_instance, st.up,
1909 		    host->conf.id, host->conf.name);
1910 
1911 		if ((st.up == HOST_UNKNOWN && host->up == HOST_DOWN) ||
1912 		    (st.up == HOST_DOWN && host->up == HOST_UNKNOWN)) {
1913 			host->up = st.up;
1914 			break;
1915 		}
1916 		if (st.up == HOST_UP)
1917 			table->up++;
1918 		else
1919 			table->up--;
1920 		host->up = st.up;
1921 		break;
1922 	case IMSG_NATLOOK:
1923 		bcopy(imsg->data, &cnl, sizeof(cnl));
1924 		if ((con = session_find(env, cnl.id)) == NULL ||
1925 		    con->se_cnl == NULL) {
1926 			log_debug("%s: session %d: expired",
1927 			    __func__, cnl.id);
1928 			break;
1929 		}
1930 		bcopy(&cnl, con->se_cnl, sizeof(*con->se_cnl));
1931 		evtimer_del(&con->se_ev);
1932 		evtimer_set(&con->se_ev, relay_natlook, con);
1933 		bzero(&tv, sizeof(tv));
1934 		evtimer_add(&con->se_ev, &tv);
1935 		break;
1936 	case IMSG_CTL_SESSION:
1937 		IMSG_SIZE_CHECK(imsg, &cid);
1938 		memcpy(&cid, imsg->data, sizeof(cid));
1939 		TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
1940 			SPLAY_FOREACH(con, session_tree,
1941 			    &rlay->rl_sessions) {
1942 				memcpy(&se, con, sizeof(se));
1943 				se.se_cid = cid;
1944 				proc_compose(env->sc_ps, p->p_id,
1945 				    IMSG_CTL_SESSION, &se, sizeof(se));
1946 			}
1947 		}
1948 		proc_compose(env->sc_ps, p->p_id, IMSG_CTL_END,
1949 		    &cid, sizeof(cid));
1950 		break;
1951 	default:
1952 		return (-1);
1953 	}
1954 
1955 	return (0);
1956 }
1957 
1958 int
1959 relay_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
1960 {
1961 	switch (imsg->hdr.type) {
1962 	case IMSG_CA_PRIVENC:
1963 	case IMSG_CA_PRIVDEC:
1964 		log_warnx("%s: priv%s result after timeout", __func__,
1965 		    imsg->hdr.type == IMSG_CA_PRIVENC ? "enc" : "dec");
1966 		return (0);
1967 	}
1968 
1969 	return (-1);
1970 }
1971 
1972 int
1973 relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
1974 {
1975 	struct relay_ticket_key	 ticket;
1976 	struct relay		*rlay;
1977 	struct rsession		*con;
1978 	struct timeval		 tv;
1979 	objid_t			 id;
1980 
1981 	switch (imsg->hdr.type) {
1982 	case IMSG_BINDANY:
1983 		bcopy(imsg->data, &id, sizeof(id));
1984 		if ((con = session_find(env, id)) == NULL) {
1985 			log_debug("%s: session %d: expired",
1986 			    __func__, id);
1987 			break;
1988 		}
1989 
1990 		/* Will validate the result later */
1991 		con->se_bnds = imsg->fd;
1992 
1993 		evtimer_del(&con->se_ev);
1994 		evtimer_set(&con->se_ev, relay_bindany, con);
1995 		bzero(&tv, sizeof(tv));
1996 		evtimer_add(&con->se_ev, &tv);
1997 		break;
1998 	case IMSG_CFG_TABLE:
1999 		config_gettable(env, imsg);
2000 		break;
2001 	case IMSG_CFG_HOST:
2002 		config_gethost(env, imsg);
2003 		break;
2004 	case IMSG_CFG_PROTO:
2005 		config_getproto(env, imsg);
2006 		break;
2007 	case IMSG_CFG_RULE:
2008 		config_getrule(env, imsg);
2009 		break;
2010 	case IMSG_CFG_RELAY:
2011 		config_getrelay(env, imsg);
2012 		break;
2013 	case IMSG_CFG_RELAY_TABLE:
2014 		config_getrelaytable(env, imsg);
2015 		break;
2016 	case IMSG_CFG_RELAY_FD:
2017 		config_getrelayfd(env, imsg);
2018 		break;
2019 	case IMSG_CFG_DONE:
2020 		config_getcfg(env, imsg);
2021 		break;
2022 	case IMSG_CTL_START:
2023 		relay_launch();
2024 		break;
2025 	case IMSG_CTL_RESET:
2026 		config_getreset(env, imsg);
2027 		break;
2028 	case IMSG_TLSTICKET_REKEY:
2029 		IMSG_SIZE_CHECK(imsg, (&ticket));
2030 		memcpy(&env->sc_ticket, imsg->data, sizeof(env->sc_ticket));
2031 		TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
2032 			if (rlay->rl_conf.flags & F_TLS)
2033 				tls_config_add_ticket_key(rlay->rl_tls_cfg,
2034 				    env->sc_ticket.tt_keyrev,
2035 				    env->sc_ticket.tt_key,
2036 				    sizeof(env->sc_ticket.tt_key));
2037 		}
2038 		break;
2039 	default:
2040 		return (-1);
2041 	}
2042 
2043 	return (0);
2044 }
2045 
2046 int
2047 relay_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
2048 {
2049 	switch (imsg->hdr.type) {
2050 	default:
2051 		break;
2052 	}
2053 
2054 	return (-1);
2055 }
2056 
2057 static int
2058 relay_tls_ctx_create_proto(struct protocol *proto, struct tls_config *tls_cfg)
2059 {
2060 	uint32_t		 protocols = 0;
2061 
2062 	/* Set the allowed SSL protocols */
2063 	if (proto->tlsflags & TLSFLAG_TLSV1_0)
2064 		protocols |= TLS_PROTOCOL_TLSv1_0;
2065 	if (proto->tlsflags & TLSFLAG_TLSV1_1)
2066 		protocols |= TLS_PROTOCOL_TLSv1_1;
2067 	if (proto->tlsflags & TLSFLAG_TLSV1_2)
2068 		protocols |= TLS_PROTOCOL_TLSv1_2;
2069 	if (proto->tlsflags & TLSFLAG_TLSV1_3)
2070 		protocols |= TLS_PROTOCOL_TLSv1_3;
2071 	if (tls_config_set_protocols(tls_cfg, protocols) == -1) {
2072 		log_warnx("could not set the TLS protocol: %s",
2073 		    tls_config_error(tls_cfg));
2074 		return (-1);
2075 	}
2076 
2077 	if (tls_config_set_ciphers(tls_cfg, proto->tlsciphers)) {
2078 		log_warnx("could not set the TLS cypers: %s",
2079 		    tls_config_error(tls_cfg));
2080 		return (-1);
2081 	}
2082 
2083 	if ((proto->tlsflags & TLSFLAG_CIPHER_SERVER_PREF) == 0)
2084 		tls_config_prefer_ciphers_client(tls_cfg);
2085 
2086 	/*
2087 	 * Set session ID context to a random value. It needs to be the
2088 	 * same accross all relay processes or session caching will fail.
2089 	 */
2090 	if (tls_config_set_session_id(tls_cfg, env->sc_conf.tls_sid,
2091 	    sizeof(env->sc_conf.tls_sid)) == -1) {
2092 		log_warnx("could not set the TLS session ID: %s",
2093 		    tls_config_error(tls_cfg));
2094 		return (-1);
2095 	}
2096 
2097 	/* Set callback for TLS session tickets if enabled */
2098 	if (proto->tickets == 1) {
2099 		/* set timeout to the ticket rekey time */
2100 		tls_config_set_session_lifetime(tls_cfg, TLS_SESSION_LIFETIME);
2101 
2102 		tls_config_add_ticket_key(tls_cfg,
2103 		    env->sc_ticket.tt_keyrev, env->sc_ticket.tt_key,
2104 		    sizeof(env->sc_ticket.tt_key));
2105 	}
2106 
2107 	if (tls_config_set_ecdhecurves(tls_cfg, proto->tlsecdhecurves) != 0) {
2108 		log_warnx("failed to set ecdhe curves %s: %s",
2109 		    proto->tlsecdhecurves, tls_config_error(tls_cfg));
2110 		return (-1);
2111 	}
2112 
2113 	if (tls_config_set_dheparams(tls_cfg, proto->tlsdhparams) != 0) {
2114 		log_warnx("failed to set dh params %s: %s",
2115 		    proto->tlsdhparams, tls_config_error(tls_cfg));
2116 		return (-1);
2117 	}
2118 
2119 	return (0);
2120 }
2121 
2122 /*
2123  * This function is not publicy exported because it is a hack until libtls
2124  * has a proper privsep setup
2125  */
2126 void tls_config_skip_private_key_check(struct tls_config *config);
2127 
2128 int
2129 relay_tls_ctx_create(struct relay *rlay)
2130 {
2131 	struct tls_config	*tls_cfg, *tls_client_cfg;
2132 	struct tls		*tls = NULL;
2133 	struct relay_cert	*cert;
2134 	const char		*fake_key;
2135 	int			 fake_keylen, keyfound = 0;
2136 	char			*buf = NULL, *cabuf = NULL, *ocspbuf = NULL;
2137 	off_t			 len = 0, calen = 0, ocsplen = 0;
2138 
2139 	if ((tls_cfg = tls_config_new()) == NULL) {
2140 		log_warnx("unable to allocate TLS config");
2141 		return (-1);
2142 	}
2143 	if ((tls_client_cfg = tls_config_new()) == NULL) {
2144 		log_warnx("unable to allocate TLS config");
2145 		return (-1);
2146 	}
2147 
2148 	if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_cfg) == -1)
2149 		goto err;
2150 	if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_client_cfg) == -1)
2151 		goto err;
2152 
2153 	/* Verify the server certificate if we have a CA chain */
2154 	if (rlay->rl_conf.flags & F_TLSCLIENT) {
2155 		/*
2156 		 * Currently relayd can't verify the name of certs and changing
2157 		 * this is non trivial. For now just disable name verification.
2158 		 */
2159 		tls_config_insecure_noverifyname(tls_client_cfg);
2160 
2161 		if (rlay->rl_tls_ca_fd != -1) {
2162 			if ((buf = relay_load_fd(rlay->rl_tls_ca_fd, &len)) ==
2163 			    NULL) {
2164 				log_warn("failed to read root certificates");
2165 				goto err;
2166 			}
2167 			rlay->rl_tls_ca_fd = -1;
2168 
2169 			if (tls_config_set_ca_mem(tls_client_cfg, buf, len) !=
2170 			    0) {
2171 				log_warnx("failed to set root certificates: %s",
2172 				    tls_config_error(tls_client_cfg));
2173 				goto err;
2174 			}
2175 			purge_key(&buf, len);
2176 		} else {
2177 			/* No root cert available so disable the checking */
2178 			tls_config_insecure_noverifycert(tls_client_cfg);
2179 		}
2180 
2181 		rlay->rl_tls_client_cfg = tls_client_cfg;
2182 	}
2183 
2184 	if (rlay->rl_conf.flags & F_TLS) {
2185 		log_debug("%s: loading certificate", __func__);
2186 		/*
2187 		 * Use the public key as the "private" key - the secret key
2188 		 * parameters are hidden in an extra process that will be
2189 		 * contacted by the RSA engine.  The SSL/TLS library needs at
2190 		 * least the public key parameters in the current process.
2191 		 * For this we need to skip the private key check done by
2192 		 * libtls.
2193 		 */
2194 		tls_config_skip_private_key_check(tls_cfg);
2195 
2196 		TAILQ_FOREACH(cert, env->sc_certs, cert_entry) {
2197 			if (cert->cert_relayid != rlay->rl_conf.id ||
2198 			    cert->cert_fd == -1)
2199 				continue;
2200 			keyfound++;
2201 
2202 			if ((buf = relay_load_fd(cert->cert_fd,
2203 			    &len)) == NULL) {
2204 				log_warn("failed to load tls certificate");
2205 				goto err;
2206 			}
2207 			cert->cert_fd = -1;
2208 
2209 			if (cert->cert_ocsp_fd != -1 &&
2210 			    (ocspbuf = relay_load_fd(cert->cert_ocsp_fd,
2211 			    &ocsplen)) == NULL) {
2212 				log_warn("failed to load OCSP staplefile");
2213 				goto err;
2214 			}
2215 			if (ocsplen == 0)
2216 				purge_key(&ocspbuf, ocsplen);
2217 			cert->cert_ocsp_fd = -1;
2218 
2219 			if ((fake_keylen = ssl_ctx_fake_private_key(buf, len,
2220 			    &fake_key)) == -1) {
2221 				/* error already printed */
2222 				goto err;
2223 			}
2224 
2225 			if (keyfound == 1 &&
2226 			    tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
2227 			    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
2228 				log_warnx("failed to set tls certificate: %s",
2229 				    tls_config_error(tls_cfg));
2230 				goto err;
2231 			}
2232 
2233 			/* loading certificate public key */
2234 			if (keyfound == 1 &&
2235 			    !ssl_load_pkey(buf, len, NULL, &rlay->rl_tls_pkey))
2236 				goto err;
2237 
2238 			if (tls_config_add_keypair_ocsp_mem(tls_cfg, buf, len,
2239 			    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
2240 				log_warnx("failed to add tls certificate: %s",
2241 				    tls_config_error(tls_cfg));
2242 				goto err;
2243 			}
2244 
2245 			purge_key(&buf, len);
2246 			purge_key(&ocspbuf, ocsplen);
2247 		}
2248 
2249 		if (rlay->rl_tls_cacert_fd != -1) {
2250 			if ((cabuf = relay_load_fd(rlay->rl_tls_cacert_fd,
2251 			    &calen)) == NULL) {
2252 				log_warn("failed to load tls CA certificate");
2253 				goto err;
2254 			}
2255 			log_debug("%s: loading CA certificate", __func__);
2256 			if (!ssl_load_pkey(cabuf, calen,
2257 			    &rlay->rl_tls_cacertx509, &rlay->rl_tls_capkey))
2258 				goto err;
2259 		}
2260 		rlay->rl_tls_cacert_fd = -1;
2261 
2262 		tls = tls_server();
2263 		if (tls == NULL) {
2264 			log_warnx("unable to allocate TLS context");
2265 			goto err;
2266 		}
2267 		if (tls_configure(tls, tls_cfg) == -1) {
2268 			log_warnx("could not configure the TLS context: %s",
2269 			    tls_error(tls));
2270 			tls_free(tls);
2271 			goto err;
2272 		}
2273 		rlay->rl_tls_cfg = tls_cfg;
2274 		rlay->rl_tls_ctx = tls;
2275 
2276 		purge_key(&cabuf, calen);
2277 	}
2278 
2279 	if (rlay->rl_tls_client_cfg == NULL)
2280 		tls_config_free(tls_client_cfg);
2281 	if (rlay->rl_tls_cfg == NULL)
2282 		tls_config_free(tls_cfg);
2283 
2284 	return (0);
2285  err:
2286 	purge_key(&ocspbuf, ocsplen);
2287 	purge_key(&cabuf, calen);
2288 	purge_key(&buf, len);
2289 
2290 	tls_config_free(tls_client_cfg);
2291 	tls_config_free(tls_cfg);
2292 	return (-1);
2293 }
2294 
2295 static struct tls *
2296 relay_tls_inspect_create(struct relay *rlay, struct ctl_relay_event *cre)
2297 {
2298 	struct tls_config	*tls_cfg;
2299 	struct tls		*tls = NULL;
2300 	const char		*fake_key;
2301 	int			 fake_keylen;
2302 
2303 	/* TLS inspection: use session-specific certificate */
2304 	if ((tls_cfg = tls_config_new()) == NULL) {
2305 		log_warnx("unable to allocate TLS config");
2306 		goto err;
2307 	}
2308 	if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_cfg) == -1) {
2309 		/* error already printed */
2310 		goto err;
2311 	}
2312 
2313 	tls_config_skip_private_key_check(tls_cfg);
2314 
2315 	log_debug("%s: loading intercepted certificate", __func__);
2316 	if ((fake_keylen = ssl_ctx_fake_private_key(cre->tlscert,
2317 	    cre->tlscert_len, &fake_key)) == -1) {
2318 		/* error already printed */
2319 		goto err;
2320 	}
2321 	if (tls_config_set_keypair_ocsp_mem(tls_cfg,
2322 	    cre->tlscert, cre->tlscert_len, fake_key, fake_keylen,
2323 	    NULL, 0) != 0) {
2324 		log_warnx("failed to set tls certificate: %s",
2325 		    tls_config_error(tls_cfg));
2326 		goto err;
2327 	}
2328 
2329 	tls = tls_server();
2330 	if (tls == NULL) {
2331 		log_warnx("unable to allocate TLS context");
2332 		goto err;
2333 	}
2334 	if (tls_configure(tls, tls_cfg) == -1) {
2335 		log_warnx("could not configure the TLS context: %s",
2336 		    tls_error(tls));
2337 		tls_free(tls);
2338 		goto err;
2339 	}
2340 
2341 	cre->tls_cfg = tls_cfg;
2342 	cre->tls_ctx = tls;
2343 	return (tls);
2344  err:
2345 	tls_config_free(tls_cfg);
2346 	return (NULL);
2347 }
2348 
2349 void
2350 relay_tls_transaction(struct rsession *con, struct ctl_relay_event *cre)
2351 {
2352 	struct relay		*rlay = con->se_relay;
2353 	struct tls		*tls_server;
2354 	const char		*errstr;
2355 	u_int			 flag;
2356 
2357 	if (cre->dir == RELAY_DIR_REQUEST) {
2358 		if (cre->tlscert != NULL)
2359 			tls_server = relay_tls_inspect_create(rlay, cre);
2360 		else
2361 			tls_server = rlay->rl_tls_ctx;
2362 		if (tls_server == NULL) {
2363 			errstr = "no TLS server context available";
2364 			goto err;
2365 		}
2366 
2367 		if (tls_accept_socket(tls_server, &cre->tls, cre->s) == -1) {
2368 			errstr = "could not accept the TLS connection";
2369 			goto err;
2370 		}
2371 		flag = EV_READ;
2372 	} else {
2373 		cre->tls = tls_client();
2374 		if (cre->tls == NULL ||
2375 		    tls_configure(cre->tls, rlay->rl_tls_client_cfg) == -1) {
2376 			errstr = "could not configure the TLS client context";
2377 			goto err;
2378 		}
2379 		if (tls_connect_socket(cre->tls, cre->s, NULL) == -1) {
2380 			errstr = "could not connect the TLS connection";
2381 			goto err;
2382 		}
2383 		flag = EV_WRITE;
2384 	}
2385 
2386 	log_debug("%s: session %d: scheduling on %s", __func__, con->se_id,
2387 	    (flag == EV_READ) ? "EV_READ" : "EV_WRITE");
2388 	event_again(&con->se_ev, cre->s, EV_TIMEOUT|flag, relay_tls_handshake,
2389 	    &con->se_tv_start, &rlay->rl_conf.timeout, cre);
2390 	return;
2391 
2392  err:
2393 	relay_close(con, errstr, 1);
2394 }
2395 
2396 void
2397 relay_tls_handshake(int fd, short event, void *arg)
2398 {
2399 	struct ctl_relay_event	*cre = arg;
2400 	struct rsession		*con = cre->con;
2401 	struct relay		*rlay = con->se_relay;
2402 	int			 retry_flag = 0;
2403 	int			 ret;
2404 	char			*msg;
2405 
2406 	if (event == EV_TIMEOUT) {
2407 		relay_close(con, "TLS handshake timeout", 1);
2408 		return;
2409 	}
2410 
2411 	ret = tls_handshake(cre->tls);
2412 	if (ret == 0) {
2413 #ifdef DEBUG
2414 		log_info(
2415 #else
2416 		log_debug(
2417 #endif
2418 		    "relay %s, tls session %d %s (%d active)",
2419 		    rlay->rl_conf.name, con->se_id,
2420 		    cre->dir == RELAY_DIR_REQUEST ? "established" : "connected",
2421 		    relay_sessions);
2422 
2423 		if (cre->dir == RELAY_DIR_REQUEST) {
2424 			relay_session(con);
2425 			return;
2426 		}
2427 
2428 		if (rlay->rl_conf.flags & F_TLSINSPECT) {
2429 			const uint8_t	*servercert;
2430 			size_t		 len;
2431 
2432 			servercert = tls_peer_cert_chain_pem(con->se_out.tls,
2433 			    &len);
2434 			if (servercert != NULL) {
2435 				con->se_in.tlscert = ssl_update_certificate(
2436 				    servercert, len,
2437 				    rlay->rl_tls_pkey, rlay->rl_tls_capkey,
2438 				    rlay->rl_tls_cacertx509,
2439 				    &con->se_in.tlscert_len);
2440 			} else
2441 				con->se_in.tlscert = NULL;
2442 			if (con->se_in.tlscert == NULL)
2443 				relay_close(con,
2444 				    "could not create certificate", 1);
2445 			else
2446 				relay_session(con);
2447 			return;
2448 		}
2449 		relay_connected(fd, EV_WRITE, con);
2450 		return;
2451 	} else if (ret == TLS_WANT_POLLIN) {
2452 		retry_flag = EV_READ;
2453 	} else if (ret == TLS_WANT_POLLOUT) {
2454 		retry_flag = EV_WRITE;
2455 	} else {
2456 		if (asprintf(&msg, "TLS handshake error: %s",
2457 		    tls_error(cre->tls)) >= 0) {
2458 			relay_close(con, msg, 1);
2459 			free(msg);
2460 		} else {
2461 			relay_close(con, "TLS handshake error", 1);
2462 		}
2463 		return;
2464 	}
2465 
2466 	DPRINTF("%s: session %d: scheduling on %s", __func__, con->se_id,
2467 	    (retry_flag == EV_READ) ? "EV_READ" : "EV_WRITE");
2468 	event_again(&con->se_ev, fd, EV_TIMEOUT|retry_flag, relay_tls_handshake,
2469 	    &con->se_tv_start, &rlay->rl_conf.timeout, cre);
2470 }
2471 
2472 void
2473 relay_tls_connected(struct ctl_relay_event *cre)
2474 {
2475 	/*
2476 	 * Hack libevent - we overwrite the internal bufferevent I/O
2477 	 * functions to handle the TLS abstraction.
2478 	 */
2479 	event_del(&cre->bev->ev_read);
2480 	event_del(&cre->bev->ev_write);
2481 
2482 	event_set(&cre->bev->ev_read, cre->s, EV_READ,
2483 	    relay_tls_readcb, cre->bev);
2484 	event_set(&cre->bev->ev_write, cre->s, EV_WRITE,
2485 	    relay_tls_writecb, cre->bev);
2486 }
2487 
2488 void
2489 relay_tls_readcb(int fd, short event, void *arg)
2490 {
2491 	char			 rbuf[IBUF_READ_SIZE];
2492 	struct bufferevent	*bufev = arg;
2493 	struct ctl_relay_event	*cre = bufev->cbarg;
2494 	short			 what = EVBUFFER_READ;
2495 	int			 howmuch = IBUF_READ_SIZE;
2496 	ssize_t			 ret;
2497 	size_t			 len;
2498 
2499 	if (event == EV_TIMEOUT) {
2500 		what |= EVBUFFER_TIMEOUT;
2501 		goto err;
2502 	}
2503 
2504 	if (bufev->wm_read.high != 0)
2505 		howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high);
2506 
2507 	ret = tls_read(cre->tls, rbuf, howmuch);
2508 	if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
2509 		goto retry;
2510 	} else if (ret == -1) {
2511 		what |= EVBUFFER_ERROR;
2512 		goto err;
2513 	}
2514 	len = ret;
2515 
2516 	if (len == 0) {
2517 		what |= EVBUFFER_EOF;
2518 		goto err;
2519 	}
2520 
2521 	if (evbuffer_add(bufev->input, rbuf, ret) == -1) {
2522 		what |= EVBUFFER_ERROR;
2523 		goto err;
2524 	}
2525 
2526 	relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
2527 
2528 	len = EVBUFFER_LENGTH(bufev->input);
2529 	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
2530 		return;
2531 	if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
2532 		struct evbuffer *buf = bufev->input;
2533 		event_del(&bufev->ev_read);
2534 		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
2535 		return;
2536 	}
2537 
2538 	if (bufev->readcb != NULL)
2539 		(*bufev->readcb)(bufev, bufev->cbarg);
2540 	return;
2541 
2542  retry:
2543 	relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
2544 	return;
2545 
2546  err:
2547 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
2548 }
2549 
2550 void
2551 relay_tls_writecb(int fd, short event, void *arg)
2552 {
2553 	struct bufferevent	*bufev = arg;
2554 	struct ctl_relay_event	*cre = bufev->cbarg;
2555 	ssize_t			 ret;
2556 	size_t			 len;
2557 	short			 what = EVBUFFER_WRITE;
2558 
2559 	if (event == EV_TIMEOUT) {
2560 		what |= EVBUFFER_TIMEOUT;
2561 		goto err;
2562 	}
2563 
2564 	if (EVBUFFER_LENGTH(bufev->output)) {
2565 		ret = tls_write(cre->tls, EVBUFFER_DATA(bufev->output),
2566 		    EVBUFFER_LENGTH(bufev->output));
2567 		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
2568 			goto retry;
2569 		} else if (ret == -1) {
2570 			what |= EVBUFFER_ERROR;
2571 			goto err;
2572 		}
2573 		len = ret;
2574 		evbuffer_drain(bufev->output, len);
2575 	}
2576 
2577 	if (EVBUFFER_LENGTH(bufev->output) != 0)
2578 		relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
2579 
2580 	if (bufev->writecb != NULL &&
2581 	    EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
2582 		(*bufev->writecb)(bufev, bufev->cbarg);
2583 	return;
2584 
2585  retry:
2586 	relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
2587 	return;
2588 
2589  err:
2590 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
2591 }
2592 
2593 int
2594 relay_bufferevent_add(struct event *ev, int timeout)
2595 {
2596 	struct timeval tv, *ptv = NULL;
2597 
2598 	if (timeout) {
2599 		timerclear(&tv);
2600 		tv.tv_sec = timeout;
2601 		ptv = &tv;
2602 	}
2603 
2604 	return (event_add(ev, ptv));
2605 }
2606 
2607 #ifdef notyet
2608 int
2609 relay_bufferevent_printf(struct ctl_relay_event *cre, const char *fmt, ...)
2610 {
2611 	int	ret;
2612 	va_list	ap;
2613 
2614 	va_start(ap, fmt);
2615 	ret = evbuffer_add_vprintf(cre->output, fmt, ap);
2616 	va_end(ap);
2617 
2618 	if (cre->bev != NULL &&
2619 	    ret != -1 && EVBUFFER_LENGTH(cre->output) > 0 &&
2620 	    (cre->bev->enabled & EV_WRITE))
2621 		bufferevent_enable(cre->bev, EV_WRITE);
2622 
2623 	return (ret);
2624 }
2625 #endif
2626 
2627 int
2628 relay_bufferevent_print(struct ctl_relay_event *cre, const char *str)
2629 {
2630 	if (cre->bev == NULL)
2631 		return (evbuffer_add(cre->output, str, strlen(str)));
2632 	return (bufferevent_write(cre->bev, str, strlen(str)));
2633 }
2634 
2635 int
2636 relay_bufferevent_write_buffer(struct ctl_relay_event *cre,
2637     struct evbuffer *buf)
2638 {
2639 	if (cre->bev == NULL)
2640 		return (evbuffer_add_buffer(cre->output, buf));
2641 	return (bufferevent_write_buffer(cre->bev, buf));
2642 }
2643 
2644 int
2645 relay_bufferevent_write_chunk(struct ctl_relay_event *cre,
2646     struct evbuffer *buf, size_t size)
2647 {
2648 	int ret;
2649 	ret = relay_bufferevent_write(cre, buf->buffer, size);
2650 	if (ret != -1)
2651 		evbuffer_drain(buf, size);
2652 	return (ret);
2653 }
2654 
2655 int
2656 relay_bufferevent_write(struct ctl_relay_event *cre, void *data, size_t size)
2657 {
2658 	if (cre->bev == NULL)
2659 		return (evbuffer_add(cre->output, data, size));
2660 	return (bufferevent_write(cre->bev, data, size));
2661 }
2662 
2663 int
2664 relay_cmp_af(struct sockaddr_storage *a, struct sockaddr_storage *b)
2665 {
2666 	int			ret = -1;
2667 	struct sockaddr_in	ia, ib;
2668 	struct sockaddr_in6	ia6, ib6;
2669 
2670 	switch (a->ss_family) {
2671 	case AF_INET:
2672 		bcopy(a, &ia, sizeof(struct sockaddr_in));
2673 		bcopy(b, &ib, sizeof(struct sockaddr_in));
2674 
2675 		ret = memcmp(&ia.sin_addr, &ib.sin_addr,
2676 		    sizeof(ia.sin_addr));
2677 		if (ret == 0)
2678 			ret = memcmp(&ia.sin_port, &ib.sin_port,
2679 			    sizeof(ia.sin_port));
2680 		break;
2681 	case AF_INET6:
2682 		bcopy(a, &ia6, sizeof(struct sockaddr_in6));
2683 		bcopy(b, &ib6, sizeof(struct sockaddr_in6));
2684 
2685 		ret = memcmp(&ia6.sin6_addr, &ib6.sin6_addr,
2686 		    sizeof(ia6.sin6_addr));
2687 		if (ret == 0)
2688 			ret = memcmp(&ia6.sin6_port, &ib6.sin6_port,
2689 			    sizeof(ia6.sin6_port));
2690 		break;
2691 	default:
2692 		break;
2693 	}
2694 
2695 	return (ret);
2696 }
2697 
2698 int
2699 relay_session_cmp(struct rsession *a, struct rsession *b)
2700 {
2701 	struct relay	*rlay = b->se_relay;
2702 	struct protocol	*proto = rlay->rl_proto;
2703 
2704 	if (proto != NULL && proto->cmp != NULL)
2705 		return ((*proto->cmp)(a, b));
2706 
2707 	return ((int)a->se_id - b->se_id);
2708 }
2709 
2710 void
2711 relay_log(struct rsession *con, char *msg)
2712 {
2713 	if (con->se_haslog && con->se_log != NULL) {
2714 		evbuffer_add(con->se_log, msg, strlen(msg));
2715 	}
2716 }
2717 
2718 SPLAY_GENERATE(session_tree, rsession, se_nodes, relay_session_cmp);
2719