Blob


1 /* $OpenBSD: relay.c,v 1.263 2026/04/02 13:38:24 tb Exp $ */
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 */
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>
25 #include <netinet/in.h>
26 #include <netinet/tcp.h>
27 #include <arpa/inet.h>
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>
42 #include <tls.h>
44 #include "relayd.h"
45 #include "log.h"
47 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
49 void relay_statistics(int, short, void *);
50 int relay_dispatch_parent(int, struct privsep_proc *,
51 struct imsg *);
52 int relay_dispatch_pfe(int, struct privsep_proc *,
53 struct imsg *);
54 int relay_dispatch_ca(int, struct privsep_proc *,
55 struct imsg *);
56 int relay_dispatch_hce(int, struct privsep_proc *,
57 struct imsg *);
58 void relay_shutdown(void);
60 void relay_protodebug(struct relay *);
61 void relay_ruledebug(struct relay_rule *);
62 void relay_init(struct privsep *, struct privsep_proc *p, void *);
63 void relay_launch(void);
64 int relay_socket(struct sockaddr_storage *, in_port_t,
65 struct protocol *, int, int);
66 int relay_socket_listen(struct sockaddr_storage *, in_port_t,
67 struct protocol *);
68 int relay_socket_connect(struct sockaddr_storage *, in_port_t,
69 struct protocol *, int);
71 void relay_accept(int, short, void *);
72 void relay_input(struct rsession *);
74 void relay_hash_addr(SIPHASH_CTX *, struct sockaddr_storage *, int);
76 int relay_tls_ctx_create(struct relay *);
77 void relay_tls_transaction(struct rsession *,
78 struct ctl_relay_event *);
79 void relay_tls_handshake(int, short, void *);
80 void relay_tls_connected(struct ctl_relay_event *);
81 void relay_tls_readcb(int, short, void *);
82 void relay_tls_writecb(int, short, void *);
84 void relay_connect_retry(int, short, void *);
85 void relay_connect_state(struct rsession *,
86 struct ctl_relay_event *, enum relay_state);
88 extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t,
89 size_t, void *);
91 volatile int relay_sessions;
92 volatile int relay_inflight = 0;
93 objid_t relay_conid;
95 static struct relayd *env = NULL;
97 static struct privsep_proc procs[] = {
98 { "parent", PROC_PARENT, relay_dispatch_parent },
99 { "pfe", PROC_PFE, relay_dispatch_pfe },
100 { "ca", PROC_CA, relay_dispatch_ca },
101 { "hce", PROC_HCE, relay_dispatch_hce },
102 };
104 void
105 relay(struct privsep *ps, struct privsep_proc *p)
107 env = ps->ps_env;
108 proc_run(ps, p, procs, nitems(procs), relay_init, NULL);
109 relay_http(env);
112 void
113 relay_shutdown(void)
115 config_purge(env, CONFIG_ALL);
116 usleep(200); /* XXX relay needs to shutdown last */
119 void
120 relay_ruledebug(struct relay_rule *rule)
122 struct kv *kv = NULL;
123 u_int i;
124 char buf[NI_MAXHOST];
126 fprintf(stderr, "\t\t");
128 switch (rule->rule_action) {
129 case RULE_ACTION_MATCH:
130 fprintf(stderr, "match ");
131 break;
132 case RULE_ACTION_BLOCK:
133 fprintf(stderr, "block ");
134 break;
135 case RULE_ACTION_PASS:
136 fprintf(stderr, "pass ");
137 break;
140 switch (rule->rule_dir) {
141 case RELAY_DIR_ANY:
142 break;
143 case RELAY_DIR_REQUEST:
144 fprintf(stderr, "request ");
145 break;
146 case RELAY_DIR_RESPONSE:
147 fprintf(stderr, "response ");
148 break;
149 default:
150 return;
151 /* NOTREACHED */
152 break;
155 if (rule->rule_flags & RULE_FLAG_QUICK)
156 fprintf(stderr, "quick ");
158 switch (rule->rule_af) {
159 case AF_INET:
160 fprintf(stderr, "inet ");
161 break;
162 case AF_INET6:
163 fprintf(stderr, "inet6 ");
164 break;
167 if (rule->rule_src.addr.ss_family != AF_UNSPEC)
168 fprintf(stderr, "from %s/%d ",
169 print_host(&rule->rule_src.addr, buf, sizeof(buf)),
170 rule->rule_src.addr_mask);
172 if (rule->rule_dst.addr.ss_family != AF_UNSPEC)
173 fprintf(stderr, "to %s/%d ",
174 print_host(&rule->rule_dst.addr, buf, sizeof(buf)),
175 rule->rule_dst.addr_mask);
177 for (i = 1; i < KEY_TYPE_MAX; i++) {
178 kv = &rule->rule_kv[i];
179 if (kv->kv_type != i)
180 continue;
182 switch (kv->kv_type) {
183 case KEY_TYPE_COOKIE:
184 fprintf(stderr, "cookie ");
185 break;
186 case KEY_TYPE_HEADER:
187 fprintf(stderr, "header ");
188 break;
189 case KEY_TYPE_PATH:
190 fprintf(stderr, "path ");
191 break;
192 case KEY_TYPE_QUERY:
193 fprintf(stderr, "query ");
194 break;
195 case KEY_TYPE_URL:
196 fprintf(stderr, "url ");
197 break;
198 default:
199 continue;
202 switch (kv->kv_option) {
203 case KEY_OPTION_APPEND:
204 fprintf(stderr, "append ");
205 break;
206 case KEY_OPTION_SET:
207 fprintf(stderr, "set ");
208 break;
209 case KEY_OPTION_REMOVE:
210 fprintf(stderr, "remove ");
211 break;
212 case KEY_OPTION_HASH:
213 fprintf(stderr, "hash ");
214 break;
215 case KEY_OPTION_LOG:
216 fprintf(stderr, "log ");
217 break;
218 case KEY_OPTION_STRIP:
219 fprintf(stderr, "strip ");
220 break;
221 case KEY_OPTION_NONE:
222 break;
225 switch (kv->kv_digest) {
226 case DIGEST_SHA1:
227 case DIGEST_MD5:
228 fprintf(stderr, "digest ");
229 break;
230 default:
231 break;
234 int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
235 kv->kv_value == NULL);
236 fprintf(stderr, "%s%s%s%s%s%s ",
237 kv->kv_key == NULL ? "" : "\"",
238 kv->kv_key == NULL ? "" : kv->kv_key,
239 kv->kv_key == NULL ? "" : "\"",
240 kvv ? "" : " value \"",
241 kv->kv_value == NULL ? "" : kv->kv_value,
242 kvv ? "" : "\"");
245 if (rule->rule_tablename[0])
246 fprintf(stderr, "forward to <%s> ", rule->rule_tablename);
248 if (rule->rule_tag == -1)
249 fprintf(stderr, "no tag ");
250 else if (rule->rule_tag && rule->rule_tagname[0])
251 fprintf(stderr, "tag \"%s\" ",
252 rule->rule_tagname);
254 if (rule->rule_tagged && rule->rule_taggedname[0])
255 fprintf(stderr, "tagged \"%s\" ",
256 rule->rule_taggedname);
258 if (rule->rule_label == -1)
259 fprintf(stderr, "no label ");
260 else if (rule->rule_label && rule->rule_labelname[0])
261 fprintf(stderr, "label \"%s\" ",
262 rule->rule_labelname);
264 fprintf(stderr, "\n");
267 void
268 relay_protodebug(struct relay *rlay)
270 struct protocol *proto = rlay->rl_proto;
271 struct relay_rule *rule = NULL;
273 fprintf(stderr, "protocol %d: name %s\n",
274 proto->id, proto->name);
275 fprintf(stderr, "\tflags: %s, relay flags: %s\n",
276 printb_flags(proto->flags, F_BITS),
277 printb_flags(rlay->rl_conf.flags, F_BITS));
278 if (proto->tcpflags)
279 fprintf(stderr, "\ttcp flags: %s\n",
280 printb_flags(proto->tcpflags, TCPFLAG_BITS));
281 if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) && proto->tlsflags)
282 fprintf(stderr, "\ttls flags: %s\n",
283 printb_flags(proto->tlsflags, TLSFLAG_BITS));
284 fprintf(stderr, "\ttls session tickets: %s\n",
285 (proto->tickets == 1) ? "enabled" : "disabled");
286 fprintf(stderr, "\ttype: ");
287 switch (proto->type) {
288 case RELAY_PROTO_TCP:
289 fprintf(stderr, "tcp\n");
290 break;
291 case RELAY_PROTO_HTTP:
292 fprintf(stderr, "http\n");
293 break;
294 case RELAY_PROTO_DNS:
295 fprintf(stderr, "dns\n");
296 break;
299 rule = TAILQ_FIRST(&proto->rules);
300 while (rule != NULL) {
301 relay_ruledebug(rule);
302 rule = TAILQ_NEXT(rule, rule_entry);
306 int
307 relay_privinit(struct relay *rlay)
309 log_debug("%s: adding relay %s", __func__, rlay->rl_conf.name);
311 if (log_getverbose() > 1)
312 relay_protodebug(rlay);
314 switch (rlay->rl_proto->type) {
315 case RELAY_PROTO_DNS:
316 relay_udp_privinit(rlay);
317 break;
318 case RELAY_PROTO_TCP:
319 break;
320 case RELAY_PROTO_HTTP:
321 break;
324 if (rlay->rl_conf.flags & F_UDP)
325 rlay->rl_s = relay_udp_bind(&rlay->rl_conf.ss,
326 rlay->rl_conf.port, rlay->rl_proto);
327 else
328 rlay->rl_s = relay_socket_listen(&rlay->rl_conf.ss,
329 rlay->rl_conf.port, rlay->rl_proto);
330 if (rlay->rl_s == -1)
331 return (-1);
333 return (0);
336 void
337 relay_init(struct privsep *ps, struct privsep_proc *p, void *arg)
339 struct timeval tv;
341 if (config_init(ps->ps_env) == -1)
342 fatal("failed to initialize configuration");
344 /* We use a custom shutdown callback */
345 p->p_shutdown = relay_shutdown;
347 /* Unlimited file descriptors (use system limits) */
348 socket_rlimit(-1);
350 if (pledge("stdio recvfd inet", NULL) == -1)
351 fatal("pledge");
353 /* Schedule statistics timer */
354 evtimer_set(&env->sc_statev, relay_statistics, ps);
355 bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
356 evtimer_add(&env->sc_statev, &tv);
359 void
360 relay_session_publish(struct rsession *s)
362 proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_PUBLISH, s, sizeof(*s));
365 void
366 relay_session_unpublish(struct rsession *s)
368 proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_UNPUBLISH,
369 &s->se_id, sizeof(s->se_id));
372 void
373 relay_statistics(int fd, short events, void *arg)
375 struct privsep *ps = arg;
376 struct relay *rlay;
377 struct ctl_stats crs, *cur;
378 struct timeval tv, tv_now;
379 int resethour = 0, resetday = 0;
380 struct rsession *con, *next_con;
382 /*
383 * This is a hack to calculate some average statistics.
384 * It doesn't try to be very accurate, but could be improved...
385 */
387 timerclear(&tv);
388 getmonotime(&tv_now);
390 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
391 bzero(&crs, sizeof(crs));
392 resethour = resetday = 0;
394 cur = &rlay->rl_stats[ps->ps_instance];
395 cur->cnt += cur->last;
396 cur->tick++;
397 cur->avg = (cur->last + cur->avg) / 2;
398 cur->last_hour += cur->last;
399 if ((cur->tick %
400 (3600 / env->sc_conf.statinterval.tv_sec)) == 0) {
401 cur->avg_hour = (cur->last_hour + cur->avg_hour) / 2;
402 resethour++;
404 cur->last_day += cur->last;
405 if ((cur->tick %
406 (86400 / env->sc_conf.statinterval.tv_sec)) == 0) {
407 cur->avg_day = (cur->last_day + cur->avg_day) / 2;
408 resethour++;
410 bcopy(cur, &crs, sizeof(crs));
412 cur->last = 0;
413 if (resethour)
414 cur->last_hour = 0;
415 if (resetday)
416 cur->last_day = 0;
418 crs.id = rlay->rl_conf.id;
419 crs.proc = ps->ps_instance;
420 proc_compose(env->sc_ps, PROC_PFE, IMSG_STATISTICS,
421 &crs, sizeof(crs));
423 for (con = SPLAY_ROOT(&rlay->rl_sessions);
424 con != NULL; con = next_con) {
425 next_con = SPLAY_NEXT(session_tree,
426 &rlay->rl_sessions, con);
427 timersub(&tv_now, &con->se_tv_last, &tv);
428 if (timercmp(&tv, &rlay->rl_conf.timeout, >=))
429 relay_close(con, "hard timeout", 1);
433 /* Schedule statistics timer */
434 evtimer_set(&env->sc_statev, relay_statistics, ps);
435 bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
436 evtimer_add(&env->sc_statev, &tv);
439 void
440 relay_launch(void)
442 void (*callback)(int, short, void *);
443 struct relay *rlay;
444 struct host *host;
445 struct relay_table *rlt;
447 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
448 if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) &&
449 relay_tls_ctx_create(rlay) == -1)
450 fatalx("%s: failed to create TLS context", __func__);
452 TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
453 /*
454 * set rule->rule_table in advance and save time
455 * looking up for this later on rule/connection
456 * evalution
457 */
458 rule_settable(&rlay->rl_proto->rules, rlt);
460 rlt->rlt_index = 0;
461 rlt->rlt_nhosts = 0;
462 TAILQ_FOREACH(host, &rlt->rlt_table->hosts, entry) {
463 if (rlt->rlt_nhosts >= RELAY_MAXHOSTS)
464 fatal("%s: too many hosts in table",
465 __func__);
466 host->idx = rlt->rlt_nhosts;
467 rlt->rlt_host[rlt->rlt_nhosts++] = host;
469 log_info("adding %d hosts from table %s%s",
470 rlt->rlt_nhosts, rlt->rlt_table->conf.name,
471 rlt->rlt_table->conf.check ? "" : " (no check)");
474 switch (rlay->rl_proto->type) {
475 case RELAY_PROTO_DNS:
476 relay_udp_init(env, rlay);
477 break;
478 case RELAY_PROTO_TCP:
479 case RELAY_PROTO_HTTP:
480 relay_http_init(rlay);
481 /* Use defaults */
482 break;
485 log_debug("%s: running relay %s", __func__,
486 rlay->rl_conf.name);
488 rlay->rl_up = HOST_UP;
490 if (rlay->rl_conf.flags & F_UDP)
491 callback = relay_udp_server;
492 else
493 callback = relay_accept;
495 event_set(&rlay->rl_ev, rlay->rl_s, EV_READ,
496 callback, rlay);
497 event_add(&rlay->rl_ev, NULL);
498 evtimer_set(&rlay->rl_evt, callback, rlay);
502 int
503 relay_socket_af(struct sockaddr_storage *ss, in_port_t port)
505 switch (ss->ss_family) {
506 case AF_INET:
507 ((struct sockaddr_in *)ss)->sin_port = port;
508 ((struct sockaddr_in *)ss)->sin_len =
509 sizeof(struct sockaddr_in);
510 break;
511 case AF_INET6:
512 ((struct sockaddr_in6 *)ss)->sin6_port = port;
513 ((struct sockaddr_in6 *)ss)->sin6_len =
514 sizeof(struct sockaddr_in6);
515 break;
516 default:
517 return (-1);
520 return (0);
523 in_port_t
524 relay_socket_getport(struct sockaddr_storage *ss)
526 switch (ss->ss_family) {
527 case AF_INET:
528 return (((struct sockaddr_in *)ss)->sin_port);
529 case AF_INET6:
530 return (((struct sockaddr_in6 *)ss)->sin6_port);
531 default:
532 return (0);
535 /* NOTREACHED */
536 return (0);
539 int
540 relay_socket(struct sockaddr_storage *ss, in_port_t port,
541 struct protocol *proto, int fd, int reuseport)
543 struct linger lng;
544 int s = -1, val;
546 if (relay_socket_af(ss, port) == -1)
547 goto bad;
549 s = fd == -1 ? socket(ss->ss_family,
550 SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP) : fd;
551 if (s == -1)
552 goto bad;
554 /*
555 * Socket options
556 */
557 bzero(&lng, sizeof(lng));
558 if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
559 goto bad;
560 if (reuseport) {
561 val = 1;
562 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
563 sizeof(int)) == -1)
564 goto bad;
566 if (proto->tcpflags & TCPFLAG_BUFSIZ) {
567 val = proto->tcpbufsiz;
568 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
569 &val, sizeof(val)) == -1)
570 goto bad;
571 val = proto->tcpbufsiz;
572 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
573 &val, sizeof(val)) == -1)
574 goto bad;
577 /*
578 * IP options
579 */
580 if (proto->tcpflags & TCPFLAG_IPTTL) {
581 val = (int)proto->tcpipttl;
582 switch (ss->ss_family) {
583 case AF_INET:
584 if (setsockopt(s, IPPROTO_IP, IP_TTL,
585 &val, sizeof(val)) == -1)
586 goto bad;
587 break;
588 case AF_INET6:
589 if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
590 &val, sizeof(val)) == -1)
591 goto bad;
592 break;
595 if (proto->tcpflags & TCPFLAG_IPMINTTL) {
596 val = (int)proto->tcpipminttl;
597 switch (ss->ss_family) {
598 case AF_INET:
599 if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
600 &val, sizeof(val)) == -1)
601 goto bad;
602 break;
603 case AF_INET6:
604 if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
605 &val, sizeof(val)) == -1)
606 goto bad;
607 break;
611 /*
612 * TCP options
613 */
614 if (proto->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) {
615 if (proto->tcpflags & TCPFLAG_NNODELAY)
616 val = 0;
617 else
618 val = 1;
619 if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
620 &val, sizeof(val)) == -1)
621 goto bad;
623 if (proto->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) {
624 if (proto->tcpflags & TCPFLAG_NSACK)
625 val = 0;
626 else
627 val = 1;
628 if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE,
629 &val, sizeof(val)) == -1)
630 goto bad;
633 return (s);
635 bad:
636 if (s != -1)
637 close(s);
638 return (-1);
641 int
642 relay_socket_connect(struct sockaddr_storage *ss, in_port_t port,
643 struct protocol *proto, int fd)
645 int s;
647 if ((s = relay_socket(ss, port, proto, fd, 0)) == -1)
648 return (-1);
650 if (connect(s, (struct sockaddr *)ss, ss->ss_len) == -1) {
651 if (errno != EINPROGRESS)
652 goto bad;
655 return (s);
657 bad:
658 close(s);
659 return (-1);
662 int
663 relay_socket_listen(struct sockaddr_storage *ss, in_port_t port,
664 struct protocol *proto)
666 int s;
668 if ((s = relay_socket(ss, port, proto, -1, 1)) == -1)
669 return (-1);
671 if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
672 goto bad;
673 if (listen(s, proto->tcpbacklog) == -1)
674 goto bad;
676 return (s);
678 bad:
679 close(s);
680 return (-1);
683 void
684 relay_connected(int fd, short sig, void *arg)
686 char obuf[128];
687 struct rsession *con = arg;
688 struct relay *rlay = con->se_relay;
689 struct protocol *proto = rlay->rl_proto;
690 evbuffercb outrd = relay_read;
691 evbuffercb outwr = relay_write;
692 struct bufferevent *bev;
693 struct ctl_relay_event *out = &con->se_out;
694 char *msg;
695 socklen_t len;
696 int error;
698 if (sig == EV_TIMEOUT) {
699 relay_abort_http(con, 504, "connect timeout", 0);
700 return;
703 len = sizeof(error);
704 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
705 relay_abort_http(con, 500, "getsockopt failed", 0);
706 return;
708 if (error) {
709 errno = error;
710 if (asprintf(&msg, "socket error: %s",
711 strerror(error)) >= 0) {
712 relay_abort_http(con, 500, msg, 0);
713 free(msg);
714 return;
715 } else {
716 relay_abort_http(con, 500,
717 "socket error and asprintf failed", 0);
718 return;
722 if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls == NULL)) {
723 relay_tls_transaction(con, out);
724 return;
727 DPRINTF("%s: session %d: successful", __func__, con->se_id);
729 /* Log destination if it was changed in a keep-alive connection */
730 if ((con->se_table != con->se_table0) &&
731 (env->sc_conf.opts & (RELAYD_OPT_LOGCON|RELAYD_OPT_LOGCONERR))) {
732 con->se_table0 = con->se_table;
733 memset(&obuf, 0, sizeof(obuf));
734 (void)print_host(&con->se_out.ss, obuf, sizeof(obuf));
735 if (asprintf(&msg, " -> %s:%d",
736 obuf, ntohs(con->se_out.port)) == -1) {
737 relay_abort_http(con, 500,
738 "connection changed and asprintf failed", 0);
739 return;
741 relay_log(con, msg);
742 free(msg);
745 switch (rlay->rl_proto->type) {
746 case RELAY_PROTO_HTTP:
747 if (relay_httpdesc_init(out) == -1) {
748 relay_close(con,
749 "failed to allocate http descriptor", 1);
750 return;
752 con->se_out.toread = TOREAD_HTTP_HEADER;
753 outrd = relay_read_http;
754 break;
755 case RELAY_PROTO_TCP:
756 /* Use defaults */
757 break;
758 default:
759 fatalx("%s: unknown protocol", __func__);
762 /*
763 * Relay <-> Server
764 */
765 bev = bufferevent_new(fd, outrd, outwr, relay_error, &con->se_out);
766 if (bev == NULL) {
767 relay_abort_http(con, 500,
768 "failed to allocate output buffer event", 0);
769 return;
772 error = 0;
774 if (rlay->rl_conf.flags & F_PROXYV1)
775 error = proxy_protocol_v1(con, bev->output);
776 else if (rlay->rl_conf.flags & F_PROXYV2)
777 error = proxy_protocol_v2(con, bev->output);
779 if (error) {
780 relay_abort_http(con, 500, "failed to write PROXY header", 0);
781 return;
784 /* write pending output buffer now */
785 if (bufferevent_write_buffer(bev, con->se_out.output)) {
786 relay_abort_http(con, 500, strerror(errno), 0);
787 return;
789 con->se_out.bev = bev;
791 /* Initialize the TLS wrapper */
792 if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls != NULL))
793 relay_tls_connected(out);
795 bufferevent_settimeout(bev,
796 rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
797 bufferevent_setwatermark(bev, EV_WRITE,
798 RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
799 bufferevent_enable(bev, EV_READ|EV_WRITE);
800 if (con->se_in.bev)
801 bufferevent_enable(con->se_in.bev, EV_READ);
803 if (relay_splice(&con->se_out) == -1)
804 relay_close(con, strerror(errno), 1);
807 void
808 relay_input(struct rsession *con)
810 struct relay *rlay = con->se_relay;
811 struct protocol *proto = rlay->rl_proto;
812 evbuffercb inrd = relay_read;
813 evbuffercb inwr = relay_write;
815 switch (rlay->rl_proto->type) {
816 case RELAY_PROTO_HTTP:
817 if (relay_http_priv_init(con) == -1) {
818 relay_close(con,
819 "failed to allocate http descriptor", 1);
820 return;
822 con->se_in.toread = TOREAD_HTTP_HEADER;
823 inrd = relay_read_http;
824 break;
825 case RELAY_PROTO_TCP:
826 /* Use defaults */
827 break;
828 default:
829 fatalx("%s: unknown protocol", __func__);
832 /*
833 * Client <-> Relay
834 */
835 con->se_in.bev = bufferevent_new(con->se_in.s, inrd, inwr,
836 relay_error, &con->se_in);
837 if (con->se_in.bev == NULL) {
838 relay_close(con, "failed to allocate input buffer event", 1);
839 return;
842 /* Initialize the TLS wrapper */
843 if ((rlay->rl_conf.flags & F_TLS) && con->se_in.tls != NULL)
844 relay_tls_connected(&con->se_in);
846 bufferevent_settimeout(con->se_in.bev,
847 rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
848 bufferevent_setwatermark(con->se_in.bev, EV_WRITE,
849 RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
850 bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE);
852 if (relay_splice(&con->se_in) == -1)
853 relay_close(con, strerror(errno), 1);
856 void
857 relay_write(struct bufferevent *bev, void *arg)
859 struct ctl_relay_event *cre = arg;
860 struct rsession *con = cre->con;
862 getmonotime(&con->se_tv_last);
864 if (con->se_done && EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) == 0)
865 goto done;
866 if (cre->dst->bev)
867 bufferevent_enable(cre->dst->bev, EV_READ);
868 if (relay_splice(cre->dst) == -1)
869 goto fail;
871 return;
872 done:
873 relay_close(con, "last write (done)", 0);
874 return;
875 fail:
876 relay_close(con, strerror(errno), 1);
879 void
880 relay_dump(struct ctl_relay_event *cre, const void *buf, size_t len)
882 if (!len)
883 return;
885 /*
886 * This function will dump the specified message directly
887 * to the underlying session, without waiting for success
888 * of non-blocking events etc. This is useful to print an
889 * error message before gracefully closing the session.
890 */
891 if (cre->tls != NULL)
892 (void)tls_write(cre->tls, buf, len);
893 else
894 (void)write(cre->s, buf, len);
897 void
898 relay_read(struct bufferevent *bev, void *arg)
900 struct ctl_relay_event *cre = arg;
901 struct rsession *con = cre->con;
902 struct protocol *proto = con->se_relay->rl_proto;
903 struct evbuffer *src = EVBUFFER_INPUT(bev);
905 getmonotime(&con->se_tv_last);
906 cre->timedout = 0;
908 if (!EVBUFFER_LENGTH(src))
909 return;
910 if (relay_bufferevent_write_buffer(cre->dst, src) == -1)
911 goto fail;
912 if (con->se_done)
913 goto done;
914 if (cre->dst->bev)
915 bufferevent_enable(cre->dst->bev, EV_READ);
916 if (cre->dst->bev && EVBUFFER_LENGTH(EVBUFFER_OUTPUT(cre->dst->bev)) >
917 (size_t)RELAY_MAX_PREFETCH * proto->tcpbufsiz)
918 bufferevent_disable(bev, EV_READ);
920 return;
921 done:
922 relay_close(con, "last read (done)", 0);
923 return;
924 fail:
925 relay_close(con, strerror(errno), 1);
928 /*
929 * Splice sockets from cre to cre->dst if applicable. Returns:
930 * -1 socket splicing has failed
931 * 0 socket splicing is currently not possible
932 * 1 socket splicing was successful
933 */
934 int
935 relay_splice(struct ctl_relay_event *cre)
937 struct rsession *con = cre->con;
938 struct relay *rlay = con->se_relay;
939 struct protocol *proto = rlay->rl_proto;
940 struct splice sp;
942 if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ||
943 (proto->tcpflags & TCPFLAG_NSPLICE))
944 return (0);
946 if (cre->splicelen >= 0)
947 return (0);
949 /* still not connected */
950 if (cre->bev == NULL || cre->dst->bev == NULL)
951 return (0);
953 if (!(cre->toread == TOREAD_UNLIMITED || cre->toread > 0)) {
954 DPRINTF("%s: session %d: splice dir %d, nothing to read %lld",
955 __func__, con->se_id, cre->dir, cre->toread);
956 return (0);
959 /* do not splice before buffers have not been completely flushed */
960 if (EVBUFFER_LENGTH(cre->bev->input) ||
961 EVBUFFER_LENGTH(cre->dst->bev->output)) {
962 DPRINTF("%s: session %d: splice dir %d, dirty buffer",
963 __func__, con->se_id, cre->dir);
964 bufferevent_disable(cre->bev, EV_READ);
965 return (0);
968 bzero(&sp, sizeof(sp));
969 sp.sp_fd = cre->dst->s;
970 sp.sp_max = cre->toread > 0 ? cre->toread : 0;
971 bcopy(&rlay->rl_conf.timeout, &sp.sp_idle, sizeof(sp.sp_idle));
972 if (setsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)) == -1) {
973 log_debug("%s: session %d: splice dir %d failed: %s",
974 __func__, con->se_id, cre->dir, strerror(errno));
975 return (-1);
977 cre->splicelen = 0;
978 bufferevent_enable(cre->bev, EV_READ);
980 DPRINTF("%s: session %d: splice dir %d, maximum %lld, successful",
981 __func__, con->se_id, cre->dir, cre->toread);
983 return (1);
986 int
987 relay_splicelen(struct ctl_relay_event *cre)
989 struct rsession *con = cre->con;
990 off_t len;
991 socklen_t optlen;
993 if (cre->splicelen < 0)
994 return (0);
996 optlen = sizeof(len);
997 if (getsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &len, &optlen) == -1) {
998 log_debug("%s: session %d: splice dir %d get length failed: %s",
999 __func__, con->se_id, cre->dir, strerror(errno));
1000 return (-1);
1003 DPRINTF("%s: session %d: splice dir %d, length %lld",
1004 __func__, con->se_id, cre->dir, len);
1006 if (len > cre->splicelen) {
1007 getmonotime(&con->se_tv_last);
1009 cre->splicelen = len;
1010 return (1);
1013 return (0);
1016 int
1017 relay_spliceadjust(struct ctl_relay_event *cre)
1019 if (cre->splicelen < 0)
1020 return (0);
1021 if (relay_splicelen(cre) == -1)
1022 return (-1);
1023 if (cre->splicelen > 0 && cre->toread > 0)
1024 cre->toread -= cre->splicelen;
1025 cre->splicelen = -1;
1027 return (0);
1030 void
1031 relay_error(struct bufferevent *bev, short error, void *arg)
1033 struct ctl_relay_event *cre = arg;
1034 struct rsession *con = cre->con;
1035 struct evbuffer *dst;
1037 DPRINTF("%s: session %d: dir %d state %d to read %lld event error %x",
1038 __func__, con->se_id, cre->dir, cre->state, cre->toread, error);
1039 if (error & EVBUFFER_TIMEOUT) {
1040 if (cre->splicelen >= 0) {
1041 bufferevent_enable(bev, EV_READ);
1042 } else if (cre->dst->splicelen >= 0) {
1043 switch (relay_splicelen(cre->dst)) {
1044 case -1:
1045 goto fail;
1046 case 0:
1047 relay_close(con, "buffer event timeout", 1);
1048 break;
1049 case 1:
1050 cre->timedout = 1;
1051 bufferevent_enable(bev, EV_READ);
1052 break;
1054 } else {
1055 relay_close(con, "buffer event timeout", 1);
1057 return;
1059 if (error & EVBUFFER_ERROR && errno == ETIMEDOUT) {
1060 if (cre->dst->splicelen >= 0) {
1061 switch (relay_splicelen(cre->dst)) {
1062 case -1:
1063 goto fail;
1064 case 0:
1065 relay_close(con, "splice timeout", 1);
1066 return;
1067 case 1:
1068 bufferevent_enable(bev, EV_READ);
1069 break;
1071 } else if (cre->dst->timedout) {
1072 relay_close(con, "splice timeout", 1);
1073 return;
1075 if (relay_spliceadjust(cre) == -1)
1076 goto fail;
1077 if (relay_splice(cre) == -1)
1078 goto fail;
1079 return;
1081 if (error & EVBUFFER_ERROR && errno == EFBIG) {
1082 if (relay_spliceadjust(cre) == -1)
1083 goto fail;
1084 bufferevent_enable(cre->bev, EV_READ);
1085 return;
1087 if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) {
1088 bufferevent_disable(bev, EV_READ|EV_WRITE);
1090 con->se_done = 1;
1091 if (cre->dst->bev != NULL) {
1092 dst = EVBUFFER_OUTPUT(cre->dst->bev);
1093 if (EVBUFFER_LENGTH(dst))
1094 return;
1095 } else if (cre->toread == TOREAD_UNLIMITED || cre->toread == 0)
1096 return;
1098 relay_close(con, "done", 0);
1099 return;
1101 relay_close(con, "buffer event error", 1);
1102 return;
1103 fail:
1104 relay_close(con, strerror(errno), 1);
1107 void
1108 relay_accept(int fd, short event, void *arg)
1110 struct privsep *ps = env->sc_ps;
1111 struct relay *rlay = arg;
1112 struct rsession *con = NULL;
1113 struct ctl_natlook *cnl = NULL;
1114 socklen_t slen;
1115 struct timeval tv;
1116 struct sockaddr_storage ss;
1117 int s = -1;
1119 event_add(&rlay->rl_ev, NULL);
1120 if ((event & EV_TIMEOUT))
1121 return;
1123 slen = sizeof(ss);
1124 if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
1125 &slen, FD_RESERVE, &relay_inflight)) == -1) {
1127 * Pause accept if we are out of file descriptors, or
1128 * libevent will haunt us here too.
1130 if (errno == ENFILE || errno == EMFILE) {
1131 struct timeval evtpause = { 1, 0 };
1133 event_del(&rlay->rl_ev);
1134 evtimer_add(&rlay->rl_evt, &evtpause);
1135 log_debug("%s: deferring connections", __func__);
1137 return;
1139 if (rlay->rl_conf.flags & F_DISABLE)
1140 goto err;
1142 if ((con = calloc(1, sizeof(*con))) == NULL)
1143 goto err;
1145 /* Pre-allocate log buffer */
1146 con->se_haslog = 0;
1147 con->se_log = evbuffer_new();
1148 if (con->se_log == NULL)
1149 goto err;
1151 con->se_in.s = s;
1152 con->se_in.tls = NULL;
1153 con->se_out.s = -1;
1154 con->se_out.tls = NULL;
1155 con->se_in.dst = &con->se_out;
1156 con->se_out.dst = &con->se_in;
1157 con->se_in.con = con;
1158 con->se_out.con = con;
1159 con->se_in.splicelen = -1;
1160 con->se_out.splicelen = -1;
1161 con->se_in.toread = TOREAD_UNLIMITED;
1162 con->se_out.toread = TOREAD_UNLIMITED;
1163 con->se_relay = rlay;
1164 con->se_id = ++relay_conid;
1165 con->se_relayid = rlay->rl_conf.id;
1166 con->se_pid = getpid();
1167 con->se_in.dir = RELAY_DIR_REQUEST;
1168 con->se_out.dir = RELAY_DIR_RESPONSE;
1169 con->se_retry = rlay->rl_conf.dstretry;
1170 con->se_bnds = -1;
1171 con->se_out.port = rlay->rl_conf.dstport;
1172 switch (ss.ss_family) {
1173 case AF_INET:
1174 con->se_in.port = ((struct sockaddr_in *)&ss)->sin_port;
1175 break;
1176 case AF_INET6:
1177 con->se_in.port = ((struct sockaddr_in6 *)&ss)->sin6_port;
1178 break;
1180 memcpy(&con->se_in.ss, &ss, sizeof(con->se_in.ss));
1182 slen = sizeof(con->se_sockname);
1183 if (getsockname(s, (struct sockaddr *)&con->se_sockname, &slen) == -1) {
1184 relay_close(con, "sockname lookup failed", 1);
1185 return;
1188 getmonotime(&con->se_tv_start);
1189 bcopy(&con->se_tv_start, &con->se_tv_last, sizeof(con->se_tv_last));
1191 if (rlay->rl_conf.flags & F_HASHKEY) {
1192 SipHash24_Init(&con->se_siphashctx,
1193 &rlay->rl_conf.hashkey.siphashkey);
1196 relay_sessions++;
1197 SPLAY_INSERT(session_tree, &rlay->rl_sessions, con);
1198 relay_session_publish(con);
1200 /* Increment the per-relay session counter */
1201 rlay->rl_stats[ps->ps_instance].last++;
1203 /* Pre-allocate output buffer */
1204 con->se_out.output = evbuffer_new();
1205 if (con->se_out.output == NULL) {
1206 relay_close(con, "failed to allocate output buffer", 1);
1207 return;
1210 if (rlay->rl_conf.flags & F_DIVERT) {
1211 memcpy(&con->se_out.ss, &con->se_sockname,
1212 sizeof(con->se_out.ss));
1213 con->se_out.port = relay_socket_getport(&con->se_out.ss);
1215 /* Detect loop and fall back to the alternate forward target */
1216 if (bcmp(&rlay->rl_conf.ss, &con->se_out.ss,
1217 sizeof(con->se_out.ss)) == 0 &&
1218 con->se_out.port == rlay->rl_conf.port)
1219 con->se_out.ss.ss_family = AF_UNSPEC;
1220 } else if (rlay->rl_conf.flags & F_NATLOOK) {
1221 if ((cnl = calloc(1, sizeof(*cnl))) == NULL) {
1222 relay_close(con, "failed to allocate nat lookup", 1);
1223 return;
1226 con->se_cnl = cnl;
1227 bzero(cnl, sizeof(*cnl));
1228 cnl->in = -1;
1229 cnl->id = con->se_id;
1230 cnl->proc = ps->ps_instance;
1231 cnl->proto = IPPROTO_TCP;
1233 memcpy(&cnl->src, &con->se_in.ss, sizeof(cnl->src));
1234 memcpy(&cnl->dst, &con->se_sockname, sizeof(cnl->dst));
1236 proc_compose(env->sc_ps, PROC_PFE, IMSG_NATLOOK,
1237 cnl, sizeof(*cnl));
1239 /* Schedule timeout */
1240 evtimer_set(&con->se_ev, relay_natlook, con);
1241 bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv));
1242 evtimer_add(&con->se_ev, &tv);
1243 return;
1246 if (rlay->rl_conf.flags & F_TLSINSPECT) {
1247 relay_preconnect(con);
1248 return;
1251 relay_session(con);
1252 return;
1253 err:
1254 if (s != -1) {
1255 close(s);
1256 free(con);
1258 * the session struct was not completely set up, but still
1259 * counted as an inflight session. account for this.
1261 relay_inflight--;
1262 log_debug("%s: inflight decremented, now %d",
1263 __func__, relay_inflight);
1267 void
1268 relay_hash_addr(SIPHASH_CTX *ctx, struct sockaddr_storage *ss, int portset)
1270 struct sockaddr_in *sin4;
1271 struct sockaddr_in6 *sin6;
1272 in_port_t port;
1274 if (ss->ss_family == AF_INET) {
1275 sin4 = (struct sockaddr_in *)ss;
1276 SipHash24_Update(ctx, &sin4->sin_addr,
1277 sizeof(struct in_addr));
1278 } else {
1279 sin6 = (struct sockaddr_in6 *)ss;
1280 SipHash24_Update(ctx, &sin6->sin6_addr,
1281 sizeof(struct in6_addr));
1284 if (portset != -1) {
1285 port = (in_port_t)portset;
1286 SipHash24_Update(ctx, &port, sizeof(port));
1290 int
1291 relay_from_table(struct rsession *con)
1293 struct relay *rlay = con->se_relay;
1294 struct host *host = NULL;
1295 struct relay_table *rlt = NULL;
1296 struct table *table = NULL;
1297 int idx = -1;
1298 int cnt = 0;
1299 int maxtries;
1300 u_int64_t p = 0;
1302 /* the table is already selected */
1303 if (con->se_table != NULL) {
1304 rlt = con->se_table;
1305 table = rlt->rlt_table;
1306 if (table->conf.check && !table->up)
1307 table = NULL;
1308 goto gottable;
1311 /* otherwise grep the first active table */
1312 TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
1313 table = rlt->rlt_table;
1314 if ((rlt->rlt_flags & F_USED) == 0 ||
1315 (table->conf.check && !table->up))
1316 table = NULL;
1317 else
1318 break;
1321 gottable:
1322 if (table == NULL) {
1323 log_debug("%s: session %d: no active hosts",
1324 __func__, con->se_id);
1325 return (-1);
1328 switch (rlt->rlt_mode) {
1329 case RELAY_DSTMODE_ROUNDROBIN:
1330 if ((int)rlt->rlt_index >= rlt->rlt_nhosts)
1331 rlt->rlt_index = 0;
1332 idx = (int)rlt->rlt_index;
1333 break;
1334 case RELAY_DSTMODE_RANDOM:
1335 idx = (int)arc4random_uniform(rlt->rlt_nhosts);
1336 break;
1337 case RELAY_DSTMODE_SRCHASH:
1338 /* Source IP address without port */
1339 relay_hash_addr(&con->se_siphashctx, &con->se_in.ss, -1);
1340 break;
1341 case RELAY_DSTMODE_LOADBALANCE:
1342 /* Source IP address without port */
1343 relay_hash_addr(&con->se_siphashctx, &con->se_in.ss, -1);
1344 /* FALLTHROUGH */
1345 case RELAY_DSTMODE_HASH:
1346 /* Local "destination" IP address and port */
1347 relay_hash_addr(&con->se_siphashctx, &rlay->rl_conf.ss,
1348 rlay->rl_conf.port);
1349 break;
1350 default:
1351 fatalx("%s: unsupported mode", __func__);
1352 /* NOTREACHED */
1354 if (idx == -1) {
1355 /* handle all hashing algorithms */
1356 p = SipHash24_End(&con->se_siphashctx);
1358 /* Reset hash context */
1359 SipHash24_Init(&con->se_siphashctx,
1360 &rlay->rl_conf.hashkey.siphashkey);
1362 maxtries = (rlt->rlt_nhosts < RELAY_MAX_HASH_RETRIES ?
1363 rlt->rlt_nhosts : RELAY_MAX_HASH_RETRIES);
1364 for (cnt = 0; cnt < maxtries; cnt++) {
1365 if ((idx = p % rlt->rlt_nhosts) >= RELAY_MAXHOSTS)
1366 return (-1);
1368 host = rlt->rlt_host[idx];
1370 DPRINTF("%s: session %d: table %s host %s, "
1371 "p 0x%016llx, idx %d, cnt %d, max %d",
1372 __func__, con->se_id, table->conf.name,
1373 host->conf.name, p, idx, cnt, maxtries);
1375 if (!table->conf.check || host->up == HOST_UP)
1376 goto found;
1377 p = p >> 1;
1379 } else {
1380 /* handle all non-hashing algorithms */
1381 host = rlt->rlt_host[idx];
1382 DPRINTF("%s: session %d: table %s host %s, p 0x%016llx, idx %d",
1383 __func__, con->se_id, table->conf.name, host->conf.name,
1384 p, idx);
1387 while (host != NULL) {
1388 DPRINTF("%s: session %d: host %s", __func__,
1389 con->se_id, host->conf.name);
1390 if (!table->conf.check || host->up == HOST_UP)
1391 goto found;
1392 host = TAILQ_NEXT(host, entry);
1394 TAILQ_FOREACH(host, &table->hosts, entry) {
1395 DPRINTF("%s: session %d: next host %s",
1396 __func__, con->se_id, host->conf.name);
1397 if (!table->conf.check || host->up == HOST_UP)
1398 goto found;
1401 /* Should not happen */
1402 fatalx("%s: no active hosts, desynchronized", __func__);
1404 found:
1405 if (rlt->rlt_mode == RELAY_DSTMODE_ROUNDROBIN)
1406 rlt->rlt_index = host->idx + 1;
1407 con->se_retry = host->conf.retry;
1408 con->se_out.port = table->conf.port;
1409 bcopy(&host->conf.ss, &con->se_out.ss, sizeof(con->se_out.ss));
1411 return (0);
1414 void
1415 relay_natlook(int fd, short event, void *arg)
1417 struct rsession *con = arg;
1418 struct relay *rlay = con->se_relay;
1419 struct ctl_natlook *cnl = con->se_cnl;
1421 if (cnl == NULL)
1422 fatalx("invalid NAT lookup");
1424 if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 &&
1425 rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
1426 TAILQ_EMPTY(&rlay->rl_tables)) {
1427 relay_close(con, "session NAT lookup failed", 1);
1428 return;
1430 if (cnl->in != -1) {
1431 bcopy(&cnl->rdst, &con->se_out.ss, sizeof(con->se_out.ss));
1432 con->se_out.port = cnl->rdport;
1434 free(con->se_cnl);
1435 con->se_cnl = NULL;
1437 relay_session(con);
1440 void
1441 relay_session(struct rsession *con)
1443 struct relay *rlay = con->se_relay;
1444 struct ctl_relay_event *in = &con->se_in, *out = &con->se_out;
1446 if (bcmp(&rlay->rl_conf.ss, &out->ss, sizeof(out->ss)) == 0 &&
1447 out->port == rlay->rl_conf.port) {
1448 log_debug("%s: session %d: looping", __func__, con->se_id);
1449 relay_close(con, "session aborted", 1);
1450 return;
1453 if (rlay->rl_conf.flags & F_UDP) {
1455 * Call the UDP protocol-specific handler
1457 if (rlay->rl_proto->request == NULL)
1458 fatalx("invalid UDP session");
1459 if ((*rlay->rl_proto->request)(con) == -1)
1460 relay_close(con, "session failed", 1);
1461 return;
1464 if ((rlay->rl_conf.flags & F_TLS) && (in->tls == NULL)) {
1465 relay_tls_transaction(con, in);
1466 return;
1469 if (rlay->rl_proto->type != RELAY_PROTO_HTTP) {
1470 if (rlay->rl_conf.fwdmode == FWD_TRANS)
1471 relay_bindanyreq(con, 0, IPPROTO_TCP);
1472 else if (relay_connect(con) == -1) {
1473 relay_close(con, "session failed", 1);
1474 return;
1478 relay_input(con);
1481 void
1482 relay_bindanyreq(struct rsession *con, in_port_t port, int proto)
1484 struct privsep *ps = env->sc_ps;
1485 struct relay *rlay = con->se_relay;
1486 struct ctl_bindany bnd;
1487 struct timeval tv;
1489 bzero(&bnd, sizeof(bnd));
1490 bnd.bnd_id = con->se_id;
1491 bnd.bnd_proc = ps->ps_instance;
1492 bnd.bnd_port = port;
1493 bnd.bnd_proto = proto;
1494 bcopy(&con->se_in.ss, &bnd.bnd_ss, sizeof(bnd.bnd_ss));
1495 proc_compose(env->sc_ps, PROC_PARENT, IMSG_BINDANY,
1496 &bnd, sizeof(bnd));
1498 /* Schedule timeout */
1499 evtimer_set(&con->se_ev, relay_bindany, con);
1500 bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv));
1501 evtimer_add(&con->se_ev, &tv);
1504 void
1505 relay_bindany(int fd, short event, void *arg)
1507 struct rsession *con = arg;
1509 if (con->se_bnds == -1) {
1510 relay_close(con, "bindany failed, invalid socket", 1);
1511 return;
1513 if (relay_connect(con) == -1)
1514 relay_close(con, "session failed", 1);
1517 void
1518 relay_connect_state(struct rsession *con, struct ctl_relay_event *cre,
1519 enum relay_state new)
1521 DPRINTF("%s: session %d: %s state %s -> %s",
1522 __func__, con->se_id,
1523 cre->dir == RELAY_DIR_REQUEST ? "accept" : "connect",
1524 relay_state(cre->state), relay_state(new));
1525 cre->state = new;
1528 void
1529 relay_connect_retry(int fd, short sig, void *arg)
1531 struct timeval evtpause = { 1, 0 };
1532 struct rsession *con = arg;
1533 struct relay *rlay = con->se_relay;
1534 int bnds = -1;
1536 if (relay_inflight < 1) {
1537 log_warnx("%s: no connection in flight", __func__);
1538 relay_inflight = 1;
1541 DPRINTF("%s: retry %d of %d, inflight: %d",__func__,
1542 con->se_retrycount, con->se_retry, relay_inflight);
1544 if (sig != EV_TIMEOUT)
1545 fatalx("%s: called without timeout", __func__);
1547 evtimer_del(&con->se_inflightevt);
1550 * XXX we might want to check if the inbound socket is still
1551 * available: client could have closed it while we were waiting?
1554 DPRINTF("%s: got EV_TIMEOUT", __func__);
1556 if (getdtablecount() + FD_RESERVE +
1557 relay_inflight > getdtablesize()) {
1558 if (con->se_retrycount < RELAY_OUTOF_FD_RETRIES) {
1559 evtimer_add(&con->se_inflightevt, &evtpause);
1560 return;
1562 /* we waited for RELAY_OUTOF_FD_RETRIES seconds, give up */
1563 event_add(&rlay->rl_ev, NULL);
1564 relay_abort_http(con, 504, "connection timed out", 0);
1565 return;
1568 if (rlay->rl_conf.fwdmode == FWD_TRANS) {
1569 /* con->se_bnds cannot be unset */
1570 bnds = con->se_bnds;
1573 retry:
1574 if ((con->se_out.s = relay_socket_connect(&con->se_out.ss,
1575 con->se_out.port, rlay->rl_proto, bnds)) == -1) {
1576 log_debug("%s: session %d: "
1577 "forward failed: %s, %s", __func__,
1578 con->se_id, strerror(errno),
1579 con->se_retry ? "next retry" : "last retry");
1581 con->se_retrycount++;
1583 if ((errno == ENFILE || errno == EMFILE) &&
1584 (con->se_retrycount < con->se_retry)) {
1585 event_del(&rlay->rl_ev);
1586 evtimer_add(&con->se_inflightevt, &evtpause);
1587 evtimer_add(&rlay->rl_evt, &evtpause);
1588 return;
1589 } else if (con->se_retrycount < con->se_retry)
1590 goto retry;
1591 event_add(&rlay->rl_ev, NULL);
1592 relay_abort_http(con, 504, "connect failed", 0);
1593 return;
1596 if (rlay->rl_conf.flags & F_TLSINSPECT)
1597 relay_connect_state(con, &con->se_out, STATE_PRECONNECT);
1598 else
1599 relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1600 relay_inflight--;
1601 DPRINTF("%s: inflight decremented, now %d",__func__, relay_inflight);
1603 event_add(&rlay->rl_ev, NULL);
1605 if (errno == EINPROGRESS)
1606 event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT,
1607 relay_connected, &con->se_tv_start, &rlay->rl_conf.timeout,
1608 con);
1609 else
1610 relay_connected(con->se_out.s, EV_WRITE, con);
1612 return;
1615 int
1616 relay_preconnect(struct rsession *con)
1618 int rv;
1620 log_debug("%s: session %d: process %d", __func__,
1621 con->se_id, privsep_process);
1622 rv = relay_connect(con);
1623 if (con->se_out.state == STATE_CONNECTED)
1624 relay_connect_state(con, &con->se_out, STATE_PRECONNECT);
1625 return (rv);
1628 int
1629 relay_connect(struct rsession *con)
1631 struct relay *rlay = con->se_relay;
1632 struct timeval evtpause = { 1, 0 };
1633 int bnds = -1, ret;
1635 /* relay_connect should only be called once per relay */
1636 if (con->se_out.state == STATE_CONNECTED) {
1637 log_debug("%s: connect already called once", __func__);
1638 return (0);
1641 /* Connection is already established but session not active */
1642 if ((rlay->rl_conf.flags & F_TLSINSPECT) &&
1643 con->se_out.state == STATE_PRECONNECT) {
1644 if (con->se_out.tls == NULL) {
1645 log_debug("%s: tls connect failed", __func__);
1646 return (-1);
1648 relay_connected(con->se_out.s, EV_WRITE, con);
1649 relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1650 return (0);
1653 if (relay_inflight < 1) {
1654 log_warnx("relay_connect: no connection in flight");
1655 relay_inflight = 1;
1658 getmonotime(&con->se_tv_start);
1660 if (con->se_out.ss.ss_family == AF_UNSPEC &&
1661 !TAILQ_EMPTY(&rlay->rl_tables)) {
1662 if (relay_from_table(con) != 0)
1663 return (-1);
1664 } else if (con->se_out.ss.ss_family == AF_UNSPEC) {
1665 bcopy(&rlay->rl_conf.dstss, &con->se_out.ss,
1666 sizeof(con->se_out.ss));
1667 con->se_out.port = rlay->rl_conf.dstport;
1670 if (rlay->rl_conf.fwdmode == FWD_TRANS) {
1671 if (con->se_bnds == -1) {
1672 log_debug("%s: could not bind any sock", __func__);
1673 return (-1);
1675 bnds = con->se_bnds;
1678 /* Do the IPv4-to-IPv6 or IPv6-to-IPv4 translation if requested */
1679 if (rlay->rl_conf.dstaf.ss_family != AF_UNSPEC) {
1680 if (con->se_out.ss.ss_family == AF_INET &&
1681 rlay->rl_conf.dstaf.ss_family == AF_INET6)
1682 ret = map4to6(&con->se_out.ss, &rlay->rl_conf.dstaf);
1683 else if (con->se_out.ss.ss_family == AF_INET6 &&
1684 rlay->rl_conf.dstaf.ss_family == AF_INET)
1685 ret = map6to4(&con->se_out.ss);
1686 else
1687 ret = 0;
1688 if (ret != 0) {
1689 log_debug("%s: mapped to invalid address", __func__);
1690 return (-1);
1694 retry:
1695 if ((con->se_out.s = relay_socket_connect(&con->se_out.ss,
1696 con->se_out.port, rlay->rl_proto, bnds)) == -1) {
1697 if (errno == ENFILE || errno == EMFILE) {
1698 log_debug("%s: session %d: forward failed: %s",
1699 __func__, con->se_id, strerror(errno));
1700 evtimer_set(&con->se_inflightevt, relay_connect_retry,
1701 con);
1702 event_del(&rlay->rl_ev);
1703 evtimer_add(&con->se_inflightevt, &evtpause);
1704 evtimer_add(&rlay->rl_evt, &evtpause);
1706 /* this connect is pending */
1707 relay_connect_state(con, &con->se_out, STATE_PENDING);
1708 return (0);
1709 } else {
1710 if (con->se_retry) {
1711 con->se_retry--;
1712 log_debug("%s: session %d: "
1713 "forward failed: %s, %s", __func__,
1714 con->se_id, strerror(errno),
1715 con->se_retry ?
1716 "next retry" : "last retry");
1717 goto retry;
1719 log_debug("%s: session %d: forward failed: %s",
1720 __func__, con->se_id, strerror(errno));
1721 return (-1);
1725 relay_connect_state(con, &con->se_out, STATE_CONNECTED);
1726 relay_inflight--;
1727 DPRINTF("%s: inflight decremented, now %d",__func__,
1728 relay_inflight);
1730 if (errno == EINPROGRESS)
1731 event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT,
1732 relay_connected, &con->se_tv_start, &rlay->rl_conf.timeout,
1733 con);
1734 else
1735 relay_connected(con->se_out.s, EV_WRITE, con);
1737 return (0);
1740 void
1741 relay_close(struct rsession *con, const char *msg, int err)
1743 char ibuf[128], obuf[128], *ptr = NULL;
1744 struct relay *rlay = con->se_relay;
1745 struct protocol *proto = rlay->rl_proto;
1747 SPLAY_REMOVE(session_tree, &rlay->rl_sessions, con);
1748 relay_session_unpublish(con);
1750 event_del(&con->se_ev);
1752 if ((env->sc_conf.opts & (RELAYD_OPT_LOGCON|RELAYD_OPT_LOGCONERR)) &&
1753 msg != NULL) {
1754 bzero(&ibuf, sizeof(ibuf));
1755 bzero(&obuf, sizeof(obuf));
1756 (void)print_host(&con->se_in.ss, ibuf, sizeof(ibuf));
1757 (void)print_host(&con->se_out.ss, obuf, sizeof(obuf));
1758 if (EVBUFFER_LENGTH(con->se_log) &&
1759 evbuffer_add_printf(con->se_log, "\r\n") != -1) {
1760 ptr = evbuffer_readln(con->se_log, NULL,
1761 EVBUFFER_EOL_CRLF);
1763 if (err == 0 && (env->sc_conf.opts & RELAYD_OPT_LOGCON))
1764 log_info("relay %s, "
1765 "session %d (%d active), %s, %s -> %s:%d, "
1766 "%s%s%s", rlay->rl_conf.name, con->se_id,
1767 relay_sessions, con->se_tag != 0 ?
1768 tag_id2name(con->se_tag) : "0", ibuf, obuf,
1769 ntohs(con->se_out.port), msg, ptr == NULL ?
1770 "" : ",", ptr == NULL ? "" : ptr);
1771 if (err == 1 && (env->sc_conf.opts & RELAYD_OPT_LOGCONERR))
1772 log_warn("relay %s, "
1773 "session %d (%d active), %s, %s -> %s:%d, "
1774 "%s%s%s", rlay->rl_conf.name, con->se_id,
1775 relay_sessions, con->se_tag != 0 ?
1776 tag_id2name(con->se_tag) : "0", ibuf, obuf,
1777 ntohs(con->se_out.port), msg, ptr == NULL ?
1778 "" : ",", ptr == NULL ? "" : ptr);
1779 free(ptr);
1782 if (proto->close != NULL)
1783 (*proto->close)(con);
1785 free(con->se_priv);
1787 relay_connect_state(con, &con->se_in, STATE_DONE);
1788 if (relay_reset_event(con, &con->se_in)) {
1789 if (con->se_out.s == -1) {
1791 * the output was never connected,
1792 * thus this was an inflight session.
1794 relay_inflight--;
1795 log_debug("%s: sessions inflight decremented, now %d",
1796 __func__, relay_inflight);
1799 if (con->se_in.output != NULL)
1800 evbuffer_free(con->se_in.output);
1802 relay_connect_state(con, &con->se_out, STATE_DONE);
1803 if (relay_reset_event(con, &con->se_out)) {
1804 /* Some file descriptors are available again. */
1805 if (evtimer_pending(&rlay->rl_evt, NULL)) {
1806 evtimer_del(&rlay->rl_evt);
1807 event_add(&rlay->rl_ev, NULL);
1810 if (con->se_out.output != NULL)
1811 evbuffer_free(con->se_out.output);
1813 if (con->se_log != NULL)
1814 evbuffer_free(con->se_log);
1816 if (con->se_cnl != NULL) {
1817 #if 0
1818 proc_compose_imsg(env->sc_ps, PROC_PFE, -1, IMSG_KILLSTATES, -1,
1819 cnl, sizeof(*cnl));
1820 #endif
1821 free(con->se_cnl);
1824 free(con);
1825 relay_sessions--;
1828 int
1829 relay_reset_event(struct rsession *con, struct ctl_relay_event *cre)
1831 int rv = 0;
1833 if (cre->state != STATE_DONE)
1834 relay_connect_state(con, cre, STATE_CLOSED);
1835 if (cre->bev != NULL) {
1836 bufferevent_disable(cre->bev, EV_READ|EV_WRITE);
1837 bufferevent_free(cre->bev);
1839 if (cre->tls != NULL)
1840 tls_close(cre->tls);
1841 tls_free(cre->tls);
1842 tls_free(cre->tls_ctx);
1843 tls_config_free(cre->tls_cfg);
1844 free(cre->tlscert);
1845 if (cre->s != -1) {
1846 close(cre->s);
1847 rv = 1;
1849 cre->bev = NULL;
1850 cre->tls = NULL;
1851 cre->tls_cfg = NULL;
1852 cre->tlscert = NULL;
1853 cre->s = -1;
1855 return (rv);
1858 int
1859 relay_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
1861 struct relay *rlay;
1862 struct rsession *con, se;
1863 struct ctl_natlook cnl;
1864 struct timeval tv;
1865 struct host *host;
1866 struct table *table;
1867 struct ctl_status st;
1868 objid_t id;
1869 int cid;
1871 switch (imsg->hdr.type) {
1872 case IMSG_HOST_DISABLE:
1873 memcpy(&id, imsg->data, sizeof(id));
1874 if ((host = host_find(env, id)) == NULL)
1875 fatalx("%s: desynchronized", __func__);
1876 if ((table = table_find(env, host->conf.tableid)) ==
1877 NULL)
1878 fatalx("%s: invalid table id", __func__);
1879 if (host->up == HOST_UP)
1880 table->up--;
1881 host->flags |= F_DISABLE;
1882 host->up = HOST_UNKNOWN;
1883 break;
1884 case IMSG_HOST_ENABLE:
1885 memcpy(&id, imsg->data, sizeof(id));
1886 if ((host = host_find(env, id)) == NULL)
1887 fatalx("%s: desynchronized", __func__);
1888 host->flags &= ~(F_DISABLE);
1889 host->up = HOST_UNKNOWN;
1890 break;
1891 case IMSG_TABLE_DISABLE:
1892 memcpy(&id, imsg->data, sizeof(id));
1893 if ((table = table_find(env, id)) == NULL)
1894 fatalx("%s: desynchronized", __func__);
1895 table->conf.flags |= F_DISABLE;
1896 table->up = 0;
1897 TAILQ_FOREACH(host, &table->hosts, entry)
1898 host->up = HOST_UNKNOWN;
1899 break;
1900 case IMSG_TABLE_ENABLE:
1901 memcpy(&id, imsg->data, sizeof(id));
1902 if ((table = table_find(env, id)) == NULL)
1903 fatalx("%s: desynchronized", __func__);
1904 table->conf.flags &= ~(F_DISABLE);
1905 table->up = 0;
1906 TAILQ_FOREACH(host, &table->hosts, entry)
1907 host->up = HOST_UNKNOWN;
1908 break;
1909 case IMSG_HOST_STATUS:
1910 IMSG_SIZE_CHECK(imsg, &st);
1911 memcpy(&st, imsg->data, sizeof(st));
1912 if ((host = host_find(env, st.id)) == NULL)
1913 fatalx("%s: invalid host id", __func__);
1914 if (host->flags & F_DISABLE)
1915 break;
1916 if (host->up == st.up) {
1917 log_debug("%s: host %d => %d", __func__,
1918 host->conf.id, host->up);
1919 fatalx("%s: desynchronized", __func__);
1922 if ((table = table_find(env, host->conf.tableid))
1923 == NULL)
1924 fatalx("%s: invalid table id", __func__);
1926 DPRINTF("%s: [%d] state %d for "
1927 "host %u %s", __func__, p->p_ps->ps_instance, st.up,
1928 host->conf.id, host->conf.name);
1930 if ((st.up == HOST_UNKNOWN && host->up == HOST_DOWN) ||
1931 (st.up == HOST_DOWN && host->up == HOST_UNKNOWN)) {
1932 host->up = st.up;
1933 break;
1935 if (st.up == HOST_UP)
1936 table->up++;
1937 else
1938 table->up--;
1939 host->up = st.up;
1940 break;
1941 case IMSG_NATLOOK:
1942 bcopy(imsg->data, &cnl, sizeof(cnl));
1943 if ((con = session_find(env, cnl.id)) == NULL ||
1944 con->se_cnl == NULL) {
1945 log_debug("%s: session %d: expired",
1946 __func__, cnl.id);
1947 break;
1949 bcopy(&cnl, con->se_cnl, sizeof(*con->se_cnl));
1950 evtimer_del(&con->se_ev);
1951 evtimer_set(&con->se_ev, relay_natlook, con);
1952 bzero(&tv, sizeof(tv));
1953 evtimer_add(&con->se_ev, &tv);
1954 break;
1955 case IMSG_CTL_SESSION:
1956 IMSG_SIZE_CHECK(imsg, &cid);
1957 memcpy(&cid, imsg->data, sizeof(cid));
1958 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
1959 SPLAY_FOREACH(con, session_tree,
1960 &rlay->rl_sessions) {
1961 memcpy(&se, con, sizeof(se));
1962 se.se_cid = cid;
1963 proc_compose(env->sc_ps, p->p_id,
1964 IMSG_CTL_SESSION, &se, sizeof(se));
1967 proc_compose(env->sc_ps, p->p_id, IMSG_CTL_END,
1968 &cid, sizeof(cid));
1969 break;
1970 default:
1971 return (-1);
1974 return (0);
1977 int
1978 relay_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
1980 switch (imsg->hdr.type) {
1981 case IMSG_CA_PRIVENC:
1982 case IMSG_CA_PRIVDEC:
1983 log_warnx("%s: priv%s result after timeout", __func__,
1984 imsg->hdr.type == IMSG_CA_PRIVENC ? "enc" : "dec");
1985 return (0);
1988 return (-1);
1991 int
1992 relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
1994 struct relay_ticket_key ticket;
1995 struct relay *rlay;
1996 struct rsession *con;
1997 struct timeval tv;
1998 objid_t id;
2000 switch (imsg->hdr.type) {
2001 case IMSG_BINDANY:
2002 bcopy(imsg->data, &id, sizeof(id));
2003 if ((con = session_find(env, id)) == NULL) {
2004 log_debug("%s: session %d: expired",
2005 __func__, id);
2006 break;
2009 /* Will validate the result later */
2010 con->se_bnds = imsg_get_fd(imsg);
2012 evtimer_del(&con->se_ev);
2013 evtimer_set(&con->se_ev, relay_bindany, con);
2014 bzero(&tv, sizeof(tv));
2015 evtimer_add(&con->se_ev, &tv);
2016 break;
2017 case IMSG_CFG_TABLE:
2018 config_gettable(env, imsg);
2019 break;
2020 case IMSG_CFG_HOST:
2021 config_gethost(env, imsg);
2022 break;
2023 case IMSG_CFG_PROTO:
2024 config_getproto(env, imsg);
2025 break;
2026 case IMSG_CFG_RULE:
2027 config_getrule(env, imsg);
2028 break;
2029 case IMSG_CFG_RELAY:
2030 config_getrelay(env, imsg);
2031 break;
2032 case IMSG_CFG_RELAY_TABLE:
2033 config_getrelaytable(env, imsg);
2034 break;
2035 case IMSG_CFG_RELAY_FD:
2036 config_getrelayfd(env, imsg);
2037 break;
2038 case IMSG_CFG_DONE:
2039 config_getcfg(env, imsg);
2040 break;
2041 case IMSG_CTL_START:
2042 relay_launch();
2043 break;
2044 case IMSG_CTL_RESET:
2045 config_getreset(env, imsg);
2046 break;
2047 case IMSG_TLSTICKET_REKEY:
2048 IMSG_SIZE_CHECK(imsg, (&ticket));
2049 memcpy(&env->sc_ticket, imsg->data, sizeof(env->sc_ticket));
2050 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
2051 if (rlay->rl_conf.flags & F_TLS)
2052 tls_config_add_ticket_key(rlay->rl_tls_cfg,
2053 env->sc_ticket.tt_keyrev,
2054 env->sc_ticket.tt_key,
2055 sizeof(env->sc_ticket.tt_key));
2057 break;
2058 default:
2059 return (-1);
2062 return (0);
2065 int
2066 relay_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
2068 switch (imsg->hdr.type) {
2069 default:
2070 break;
2073 return (-1);
2076 static int
2077 relay_tls_ctx_create_proto(struct protocol *proto, struct tls_config *tls_cfg)
2079 uint32_t protocols = 0;
2081 /* Set the allowed TLS protocols */
2082 if (proto->tlsflags & TLSFLAG_TLSV1_2)
2083 protocols |= TLS_PROTOCOL_TLSv1_2;
2084 if (proto->tlsflags & TLSFLAG_TLSV1_3)
2085 protocols |= TLS_PROTOCOL_TLSv1_3;
2086 if (tls_config_set_protocols(tls_cfg, protocols) == -1) {
2087 log_warnx("could not set the TLS protocol: %s",
2088 tls_config_error(tls_cfg));
2089 return (-1);
2092 if (tls_config_set_ciphers(tls_cfg, proto->tlsciphers)) {
2093 log_warnx("could not set the TLS cypers: %s",
2094 tls_config_error(tls_cfg));
2095 return (-1);
2098 if ((proto->tlsflags & TLSFLAG_CIPHER_SERVER_PREF) == 0)
2099 tls_config_prefer_ciphers_client(tls_cfg);
2102 * Set session ID context to a random value. It needs to be the
2103 * same across all relay processes or session caching will fail.
2105 if (tls_config_set_session_id(tls_cfg, env->sc_conf.tls_sid,
2106 sizeof(env->sc_conf.tls_sid)) == -1) {
2107 log_warnx("could not set the TLS session ID: %s",
2108 tls_config_error(tls_cfg));
2109 return (-1);
2112 /* Set callback for TLS session tickets if enabled */
2113 if (proto->tickets == 1) {
2114 /* set timeout to the ticket rekey time */
2115 tls_config_set_session_lifetime(tls_cfg, TLS_SESSION_LIFETIME);
2117 tls_config_add_ticket_key(tls_cfg,
2118 env->sc_ticket.tt_keyrev, env->sc_ticket.tt_key,
2119 sizeof(env->sc_ticket.tt_key));
2122 if (tls_config_set_ecdhecurves(tls_cfg, proto->tlsecdhecurves) != 0) {
2123 log_warnx("failed to set ecdhe curves %s: %s",
2124 proto->tlsecdhecurves, tls_config_error(tls_cfg));
2125 return (-1);
2128 if (tls_config_set_dheparams(tls_cfg, proto->tlsdhparams) != 0) {
2129 log_warnx("failed to set dh params %s: %s",
2130 proto->tlsdhparams, tls_config_error(tls_cfg));
2131 return (-1);
2134 return (0);
2138 * This function is not publicy exported because it is a hack until libtls
2139 * has a proper privsep setup
2141 void tls_config_use_fake_private_key(struct tls_config *config);
2143 int
2144 relay_tls_ctx_create(struct relay *rlay)
2146 struct tls_config *tls_cfg, *tls_client_cfg;
2147 struct tls *tls = NULL;
2148 struct relay_cert *cert;
2149 int keyfound = 0;
2150 char *buf = NULL, *cabuf = NULL, *ocspbuf = NULL;
2151 off_t len = 0, calen = 0, ocsplen = 0;
2153 if ((tls_cfg = tls_config_new()) == NULL) {
2154 log_warnx("unable to allocate TLS config");
2155 return (-1);
2157 if ((tls_client_cfg = tls_config_new()) == NULL) {
2158 log_warnx("unable to allocate TLS config");
2159 goto err;
2162 if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_cfg) == -1)
2163 goto err;
2164 if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_client_cfg) == -1)
2165 goto err;
2167 /* Verify the server certificate if we have a CA chain */
2168 if (rlay->rl_conf.flags & F_TLSCLIENT) {
2170 * Currently relayd can't verify the name of certs and changing
2171 * this is non trivial. For now just disable name verification.
2173 tls_config_insecure_noverifyname(tls_client_cfg);
2175 if (rlay->rl_tls_ca_fd != -1) {
2176 if ((buf = relay_load_fd(rlay->rl_tls_ca_fd, &len)) == NULL) {
2177 log_warn("failed to read root certificates");
2178 goto err;
2180 rlay->rl_tls_ca_fd = -1;
2182 if (tls_config_set_ca_mem(tls_client_cfg, buf, len) !=
2183 0) {
2184 log_warnx("failed to set root certificates: %s",
2185 tls_config_error(tls_client_cfg));
2186 goto err;
2188 purge_key(&buf, len);
2189 } else {
2190 /* No root cert available so disable the checking */
2191 tls_config_insecure_noverifycert(tls_client_cfg);
2194 rlay->rl_tls_client_cfg = tls_client_cfg;
2197 if (rlay->rl_conf.flags & F_TLS) {
2198 log_debug("%s: loading certificate", __func__);
2200 * Use the public key as the "private" key - the secret key
2201 * parameters are hidden in an extra process that will be
2202 * contacted by the RSA engine. The TLS library needs at
2203 * least the public key parameters in the current process.
2205 tls_config_use_fake_private_key(tls_cfg);
2207 TAILQ_FOREACH(cert, env->sc_certs, cert_entry) {
2208 if (cert->cert_relayid != rlay->rl_conf.id ||
2209 cert->cert_fd == -1)
2210 continue;
2211 keyfound++;
2213 if ((buf = relay_load_fd(cert->cert_fd,
2214 &len)) == NULL) {
2215 log_warn("failed to load tls certificate");
2216 goto err;
2218 cert->cert_fd = -1;
2220 if (cert->cert_ocsp_fd != -1 &&
2221 (ocspbuf = relay_load_fd(cert->cert_ocsp_fd,
2222 &ocsplen)) == NULL) {
2223 log_warn("failed to load OCSP staplefile");
2224 goto err;
2226 if (ocsplen == 0)
2227 purge_key(&ocspbuf, ocsplen);
2228 cert->cert_ocsp_fd = -1;
2230 if (keyfound == 1 &&
2231 tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
2232 NULL, 0, ocspbuf, ocsplen) != 0) {
2233 log_warnx("failed to set tls certificate: %s",
2234 tls_config_error(tls_cfg));
2235 goto err;
2238 /* loading certificate public key */
2239 if (keyfound == 1 &&
2240 !ssl_load_pkey(buf, len, NULL, &rlay->rl_tls_pkey))
2241 goto err;
2243 if (tls_config_add_keypair_ocsp_mem(tls_cfg, buf, len,
2244 NULL, 0, ocspbuf, ocsplen) != 0) {
2245 log_warnx("failed to add tls certificate: %s",
2246 tls_config_error(tls_cfg));
2247 goto err;
2250 purge_key(&buf, len);
2251 purge_key(&ocspbuf, ocsplen);
2254 if (rlay->rl_tls_cacert_fd != -1) {
2255 if ((cabuf = relay_load_fd(rlay->rl_tls_cacert_fd,
2256 &calen)) == NULL) {
2257 log_warn("failed to load tls CA certificate");
2258 goto err;
2260 log_debug("%s: loading CA certificate", __func__);
2261 if (!ssl_load_pkey(cabuf, calen,
2262 &rlay->rl_tls_cacertx509, &rlay->rl_tls_capkey))
2263 goto err;
2265 rlay->rl_tls_cacert_fd = -1;
2267 if (rlay->rl_tls_client_ca_fd != -1) {
2268 if ((buf = relay_load_fd(rlay->rl_tls_client_ca_fd,
2269 &len)) == NULL) {
2270 log_warn(
2271 "failed to read tls client CA certificate");
2272 goto err;
2275 if (tls_config_set_ca_mem(tls_cfg, buf, len) != 0) {
2276 log_warnx(
2277 "failed to set tls client CA cert: %s",
2278 tls_config_error(tls_cfg));
2279 goto err;
2281 purge_key(&buf, len);
2283 tls_config_verify_client(tls_cfg);
2285 rlay->rl_tls_client_ca_fd = -1;
2287 tls = tls_server();
2288 if (tls == NULL) {
2289 log_warnx("unable to allocate TLS context");
2290 goto err;
2292 if (tls_configure(tls, tls_cfg) == -1) {
2293 log_warnx("could not configure the TLS context: %s",
2294 tls_error(tls));
2295 tls_free(tls);
2296 goto err;
2298 rlay->rl_tls_cfg = tls_cfg;
2299 rlay->rl_tls_ctx = tls;
2301 purge_key(&cabuf, calen);
2304 if (rlay->rl_tls_client_cfg == NULL)
2305 tls_config_free(tls_client_cfg);
2306 if (rlay->rl_tls_cfg == NULL)
2307 tls_config_free(tls_cfg);
2309 return (0);
2310 err:
2311 purge_key(&ocspbuf, ocsplen);
2312 purge_key(&cabuf, calen);
2313 purge_key(&buf, len);
2315 tls_config_free(tls_client_cfg);
2316 tls_config_free(tls_cfg);
2317 return (-1);
2320 static struct tls *
2321 relay_tls_inspect_create(struct relay *rlay, struct ctl_relay_event *cre)
2323 struct tls_config *tls_cfg;
2324 struct tls *tls = NULL;
2326 /* TLS inspection: use session-specific certificate */
2327 if ((tls_cfg = tls_config_new()) == NULL) {
2328 log_warnx("unable to allocate TLS config");
2329 goto err;
2331 if (relay_tls_ctx_create_proto(rlay->rl_proto, tls_cfg) == -1) {
2332 /* error already printed */
2333 goto err;
2336 tls_config_use_fake_private_key(tls_cfg);
2338 if (tls_config_set_keypair_ocsp_mem(tls_cfg,
2339 cre->tlscert, cre->tlscert_len, NULL, 0, NULL, 0) != 0) {
2340 log_warnx("failed to set tls certificate: %s",
2341 tls_config_error(tls_cfg));
2342 goto err;
2345 tls = tls_server();
2346 if (tls == NULL) {
2347 log_warnx("unable to allocate TLS context");
2348 goto err;
2350 if (tls_configure(tls, tls_cfg) == -1) {
2351 log_warnx("could not configure the TLS context: %s",
2352 tls_error(tls));
2353 tls_free(tls);
2354 goto err;
2357 cre->tls_cfg = tls_cfg;
2358 cre->tls_ctx = tls;
2359 return (tls);
2360 err:
2361 tls_config_free(tls_cfg);
2362 return (NULL);
2365 void
2366 relay_tls_transaction(struct rsession *con, struct ctl_relay_event *cre)
2368 struct relay *rlay = con->se_relay;
2369 struct tls *tls_server;
2370 const char *errstr;
2371 u_int flag;
2373 if (cre->dir == RELAY_DIR_REQUEST) {
2374 if (cre->tlscert != NULL)
2375 tls_server = relay_tls_inspect_create(rlay, cre);
2376 else
2377 tls_server = rlay->rl_tls_ctx;
2378 if (tls_server == NULL) {
2379 errstr = "no TLS server context available";
2380 goto err;
2383 if (tls_accept_socket(tls_server, &cre->tls, cre->s) == -1) {
2384 errstr = "could not accept the TLS connection";
2385 goto err;
2387 flag = EV_READ;
2388 } else {
2389 cre->tls = tls_client();
2390 if (cre->tls == NULL ||
2391 tls_configure(cre->tls, rlay->rl_tls_client_cfg) == -1) {
2392 errstr = "could not configure the TLS client context";
2393 goto err;
2395 if (tls_connect_socket(cre->tls, cre->s, NULL) == -1) {
2396 errstr = "could not connect the TLS connection";
2397 goto err;
2399 flag = EV_WRITE;
2402 log_debug("%s: session %d: scheduling on %s", __func__, con->se_id,
2403 (flag == EV_READ) ? "EV_READ" : "EV_WRITE");
2404 event_again(&con->se_ev, cre->s, EV_TIMEOUT|flag, relay_tls_handshake,
2405 &con->se_tv_start, &rlay->rl_conf.timeout, cre);
2406 return;
2408 err:
2409 relay_close(con, errstr, 1);
2412 void
2413 relay_tls_handshake(int fd, short event, void *arg)
2415 struct ctl_relay_event *cre = arg;
2416 struct rsession *con = cre->con;
2417 struct relay *rlay = con->se_relay;
2418 int retry_flag = 0;
2419 int ret;
2420 char *msg;
2422 if (event == EV_TIMEOUT) {
2423 relay_close(con, "TLS handshake timeout", 1);
2424 return;
2427 ret = tls_handshake(cre->tls);
2428 if (ret == 0) {
2429 #ifdef DEBUG
2430 log_info(
2431 #else
2432 log_debug(
2433 #endif
2434 "relay %s, tls session %d %s (%d active)",
2435 rlay->rl_conf.name, con->se_id,
2436 cre->dir == RELAY_DIR_REQUEST ? "established" : "connected",
2437 relay_sessions);
2439 if (cre->dir == RELAY_DIR_REQUEST) {
2440 relay_session(con);
2441 return;
2444 if (rlay->rl_conf.flags & F_TLSINSPECT) {
2445 const uint8_t *servercert;
2446 size_t len;
2448 servercert = tls_peer_cert_chain_pem(con->se_out.tls,
2449 &len);
2450 if (servercert != NULL) {
2451 con->se_in.tlscert = ssl_update_certificate(
2452 servercert, len,
2453 rlay->rl_tls_pkey, rlay->rl_tls_capkey,
2454 rlay->rl_tls_cacertx509,
2455 &con->se_in.tlscert_len);
2456 } else
2457 con->se_in.tlscert = NULL;
2458 if (con->se_in.tlscert == NULL)
2459 relay_close(con,
2460 "could not create certificate", 1);
2461 else
2462 relay_session(con);
2463 return;
2465 relay_connected(fd, EV_WRITE, con);
2466 return;
2467 } else if (ret == TLS_WANT_POLLIN) {
2468 retry_flag = EV_READ;
2469 } else if (ret == TLS_WANT_POLLOUT) {
2470 retry_flag = EV_WRITE;
2471 } else {
2472 if (asprintf(&msg, "TLS handshake error: %s",
2473 tls_error(cre->tls)) >= 0) {
2474 relay_close(con, msg, 1);
2475 free(msg);
2476 } else {
2477 relay_close(con, "TLS handshake error", 1);
2479 return;
2482 DPRINTF("%s: session %d: scheduling on %s", __func__, con->se_id,
2483 (retry_flag == EV_READ) ? "EV_READ" : "EV_WRITE");
2484 event_again(&con->se_ev, fd, EV_TIMEOUT|retry_flag, relay_tls_handshake,
2485 &con->se_tv_start, &rlay->rl_conf.timeout, cre);
2488 void
2489 relay_tls_connected(struct ctl_relay_event *cre)
2492 * Hack libevent - we overwrite the internal bufferevent I/O
2493 * functions to handle the TLS abstraction.
2495 event_del(&cre->bev->ev_read);
2496 event_del(&cre->bev->ev_write);
2498 event_set(&cre->bev->ev_read, cre->s, EV_READ,
2499 relay_tls_readcb, cre->bev);
2500 event_set(&cre->bev->ev_write, cre->s, EV_WRITE,
2501 relay_tls_writecb, cre->bev);
2504 void
2505 relay_tls_readcb(int fd, short event, void *arg)
2507 char rbuf[IBUF_READ_SIZE];
2508 struct bufferevent *bufev = arg;
2509 struct ctl_relay_event *cre = bufev->cbarg;
2510 short what = EVBUFFER_READ;
2511 int howmuch = IBUF_READ_SIZE;
2512 ssize_t ret;
2513 size_t len;
2515 if (event == EV_TIMEOUT) {
2516 what |= EVBUFFER_TIMEOUT;
2517 goto err;
2520 if (bufev->wm_read.high != 0)
2521 howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high);
2523 ret = tls_read(cre->tls, rbuf, howmuch);
2524 if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
2525 goto retry;
2526 } else if (ret == -1) {
2527 what |= EVBUFFER_ERROR;
2528 goto err;
2530 len = ret;
2532 if (len == 0) {
2533 what |= EVBUFFER_EOF;
2534 goto err;
2537 if (evbuffer_add(bufev->input, rbuf, ret) == -1) {
2538 what |= EVBUFFER_ERROR;
2539 goto err;
2542 relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
2544 len = EVBUFFER_LENGTH(bufev->input);
2545 if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
2546 return;
2547 if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
2548 struct evbuffer *buf = bufev->input;
2549 event_del(&bufev->ev_read);
2550 evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
2551 return;
2554 if (bufev->readcb != NULL)
2555 (*bufev->readcb)(bufev, bufev->cbarg);
2556 return;
2558 retry:
2559 relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
2560 return;
2562 err:
2563 (*bufev->errorcb)(bufev, what, bufev->cbarg);
2566 void
2567 relay_tls_writecb(int fd, short event, void *arg)
2569 struct bufferevent *bufev = arg;
2570 struct ctl_relay_event *cre = bufev->cbarg;
2571 ssize_t ret;
2572 size_t len;
2573 short what = EVBUFFER_WRITE;
2575 if (event == EV_TIMEOUT) {
2576 what |= EVBUFFER_TIMEOUT;
2577 goto err;
2580 if (EVBUFFER_LENGTH(bufev->output)) {
2581 ret = tls_write(cre->tls, EVBUFFER_DATA(bufev->output),
2582 EVBUFFER_LENGTH(bufev->output));
2583 if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
2584 goto retry;
2585 } else if (ret == -1) {
2586 what |= EVBUFFER_ERROR;
2587 goto err;
2589 len = ret;
2590 evbuffer_drain(bufev->output, len);
2593 if (EVBUFFER_LENGTH(bufev->output) != 0)
2594 relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
2596 if (bufev->writecb != NULL &&
2597 EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
2598 (*bufev->writecb)(bufev, bufev->cbarg);
2599 return;
2601 retry:
2602 relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
2603 return;
2605 err:
2606 (*bufev->errorcb)(bufev, what, bufev->cbarg);
2609 int
2610 relay_bufferevent_add(struct event *ev, int timeout)
2612 struct timeval tv, *ptv = NULL;
2614 if (timeout) {
2615 timerclear(&tv);
2616 tv.tv_sec = timeout;
2617 ptv = &tv;
2620 return (event_add(ev, ptv));
2623 #ifdef notyet
2624 int
2625 relay_bufferevent_printf(struct ctl_relay_event *cre, const char *fmt, ...)
2627 int ret;
2628 va_list ap;
2630 va_start(ap, fmt);
2631 ret = evbuffer_add_vprintf(cre->output, fmt, ap);
2632 va_end(ap);
2634 if (cre->bev != NULL &&
2635 ret != -1 && EVBUFFER_LENGTH(cre->output) > 0 &&
2636 (cre->bev->enabled & EV_WRITE))
2637 bufferevent_enable(cre->bev, EV_WRITE);
2639 return (ret);
2641 #endif
2643 int
2644 relay_bufferevent_print(struct ctl_relay_event *cre, const char *str)
2646 if (cre->bev == NULL)
2647 return (evbuffer_add(cre->output, str, strlen(str)));
2648 return (bufferevent_write(cre->bev, str, strlen(str)));
2651 int
2652 relay_bufferevent_write_buffer(struct ctl_relay_event *cre,
2653 struct evbuffer *buf)
2655 if (cre->bev == NULL)
2656 return (evbuffer_add_buffer(cre->output, buf));
2657 return (bufferevent_write_buffer(cre->bev, buf));
2660 int
2661 relay_bufferevent_write_chunk(struct ctl_relay_event *cre,
2662 struct evbuffer *buf, size_t size)
2664 int ret;
2665 ret = relay_bufferevent_write(cre, EVBUFFER_DATA(buf), size);
2666 if (ret != -1)
2667 evbuffer_drain(buf, size);
2668 return (ret);
2671 int
2672 relay_bufferevent_write(struct ctl_relay_event *cre, void *data, size_t size)
2674 if (cre->bev == NULL)
2675 return (evbuffer_add(cre->output, data, size));
2676 return (bufferevent_write(cre->bev, data, size));
2679 int
2680 relay_cmp_af(struct sockaddr_storage *a, struct sockaddr_storage *b)
2682 int ret = -1;
2683 struct sockaddr_in ia, ib;
2684 struct sockaddr_in6 ia6, ib6;
2686 switch (a->ss_family) {
2687 case AF_INET:
2688 bcopy(a, &ia, sizeof(struct sockaddr_in));
2689 bcopy(b, &ib, sizeof(struct sockaddr_in));
2691 ret = memcmp(&ia.sin_addr, &ib.sin_addr,
2692 sizeof(ia.sin_addr));
2693 if (ret == 0)
2694 ret = memcmp(&ia.sin_port, &ib.sin_port,
2695 sizeof(ia.sin_port));
2696 break;
2697 case AF_INET6:
2698 bcopy(a, &ia6, sizeof(struct sockaddr_in6));
2699 bcopy(b, &ib6, sizeof(struct sockaddr_in6));
2701 ret = memcmp(&ia6.sin6_addr, &ib6.sin6_addr,
2702 sizeof(ia6.sin6_addr));
2703 if (ret == 0)
2704 ret = memcmp(&ia6.sin6_port, &ib6.sin6_port,
2705 sizeof(ia6.sin6_port));
2706 break;
2707 default:
2708 break;
2711 return (ret);
2714 int
2715 relay_session_cmp(struct rsession *a, struct rsession *b)
2717 struct relay *rlay = b->se_relay;
2718 struct protocol *proto = rlay->rl_proto;
2720 if (proto != NULL && proto->cmp != NULL)
2721 return ((*proto->cmp)(a, b));
2723 return ((int)a->se_id - b->se_id);
2726 void
2727 relay_log(struct rsession *con, char *msg)
2729 if (con->se_haslog && con->se_log != NULL) {
2730 evbuffer_add(con->se_log, msg, strlen(msg));
2734 SPLAY_GENERATE(session_tree, rsession, se_nodes, relay_session_cmp);