GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/relayd/relay.c Lines: 185 1341 13.8 %
Date: 2017-11-07 Branches: 98 884 11.1 %

Line Branch Exec Source
1
/*	$OpenBSD: relay.c,v 1.227 2017/09/23 11:56:57 bluhm 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/stat.h>
23
#include <sys/socket.h>
24
#include <sys/tree.h>
25
26
#include <netinet/in.h>
27
#include <netinet/tcp.h>
28
#include <arpa/inet.h>
29
30
#include <limits.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_connect_retry(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 *);
83
84
char		*relay_load_file(const char *, off_t *);
85
extern void	 bufferevent_read_pressure_cb(struct evbuffer *, size_t,
86
		    size_t, void *);
87
88
volatile int relay_sessions;
89
volatile int relay_inflight = 0;
90
objid_t relay_conid;
91
92
static struct relayd		*env = NULL;
93
94
static struct privsep_proc procs[] = {
95
	{ "parent",	PROC_PARENT,	relay_dispatch_parent },
96
	{ "pfe",	PROC_PFE,	relay_dispatch_pfe },
97
	{ "ca",		PROC_CA,	relay_dispatch_ca },
98
	{ "hce",	PROC_HCE,	relay_dispatch_hce },
99
};
100
101
void
102
relay(struct privsep *ps, struct privsep_proc *p)
103
{
104
	env = ps->ps_env;
105
	proc_run(ps, p, procs, nitems(procs), relay_init, NULL);
106
	relay_http(env);
107
}
108
109
void
110
relay_shutdown(void)
111
{
112
	config_purge(env, CONFIG_ALL);
113
	usleep(200);	/* XXX relay needs to shutdown last */
114
}
115
116
void
117
relay_ruledebug(struct relay_rule *rule)
118
{
119
	struct kv	*kv = NULL;
120
	u_int		 i;
121
122
4272
	fprintf(stderr, "\t\t");
123
124

2848
	switch (rule->rule_action) {
125
	case RULE_ACTION_MATCH:
126
1088
		fprintf(stderr, "match ");
127
1088
		break;
128
	case RULE_ACTION_BLOCK:
129
238
		fprintf(stderr, "block ");
130
238
		break;
131
	case RULE_ACTION_PASS:
132
98
		fprintf(stderr, "pass ");
133
98
		break;
134
	}
135
136

2848
	switch (rule->rule_dir) {
137
	case RELAY_DIR_ANY:
138
		break;
139
	case RELAY_DIR_REQUEST:
140
1020
		fprintf(stderr, "request ");
141
1020
		break;
142
	case RELAY_DIR_RESPONSE:
143
404
		fprintf(stderr, "response ");
144
404
		break;
145
	default:
146
		return;
147
		/* NOTREACHED */
148
		break;
149
	}
150
151
1424
	if (rule->rule_flags & RULE_FLAG_QUICK)
152
14
		fprintf(stderr, "quick ");
153
154
17088
	for (i = 1; i < KEY_TYPE_MAX; i++) {
155
7120
		kv = &rule->rule_kv[i];
156
7120
		if (kv->kv_type != i)
157
			continue;
158
159

1312
		switch (kv->kv_type) {
160
		case KEY_TYPE_COOKIE:
161
42
			fprintf(stderr, "cookie ");
162
42
			break;
163
		case KEY_TYPE_HEADER:
164
892
			fprintf(stderr, "header ");
165
892
			break;
166
		case KEY_TYPE_PATH:
167
238
			fprintf(stderr, "path ");
168
238
			break;
169
		case KEY_TYPE_QUERY:
170
56
			fprintf(stderr, "query ");
171
56
			break;
172
		case KEY_TYPE_URL:
173
84
			fprintf(stderr, "url ");
174
84
			break;
175
		default:
176
			continue;
177
		}
178
179

2456
		switch (kv->kv_option) {
180
		case KEY_OPTION_APPEND:
181
70
			fprintf(stderr, "append ");
182
70
			break;
183
		case KEY_OPTION_SET:
184
98
			fprintf(stderr, "set ");
185
98
			break;
186
		case KEY_OPTION_REMOVE:
187
14
			fprintf(stderr, "remove ");
188
14
			break;
189
		case KEY_OPTION_HASH:
190
14
			fprintf(stderr, "hash ");
191
14
			break;
192
		case KEY_OPTION_LOG:
193
948
			fprintf(stderr, "log ");
194
948
			break;
195
		case KEY_OPTION_NONE:
196
			break;
197
		}
198
199
1312
		switch (kv->kv_digest) {
200
		case DIGEST_SHA1:
201
		case DIGEST_MD5:
202
14
			fprintf(stderr, "digest ");
203
14
			break;
204
		default:
205
			break;
206
		}
207
208
1312
		fprintf(stderr, "%s%s%s%s%s%s ",
209
1312
		    kv->kv_key == NULL ? "" : "\"",
210
3936
		    kv->kv_key == NULL ? "" : kv->kv_key,
211
1312
		    kv->kv_key == NULL ? "" : "\"",
212
1312
		    kv->kv_value == NULL ? "" : " value \"",
213
3894
		    kv->kv_value == NULL ? "" : kv->kv_value,
214
1312
		    kv->kv_value == NULL ? "" : "\"");
215
1312
	}
216
217
1424
	if (rule->rule_tablename[0])
218
		fprintf(stderr, "forward to <%s> ", rule->rule_tablename);
219
220
1424
	if (rule->rule_tag == -1)
221
		fprintf(stderr, "no tag ");
222

1508
	else if (rule->rule_tag && rule->rule_tagname[0])
223
84
		fprintf(stderr, "tag \"%s\" ",
224
84
		    rule->rule_tagname);
225
226

1494
	if (rule->rule_tagged && rule->rule_taggedname[0])
227
70
		fprintf(stderr, "tagged \"%s\" ",
228
70
		    rule->rule_taggedname);
229
230
1424
	if (rule->rule_label == -1)
231
		fprintf(stderr, "no label ");
232

1480
	else if (rule->rule_label && rule->rule_labelname[0])
233
56
		fprintf(stderr, "label \"%s\" ",
234
56
		    rule->rule_labelname);
235
236
1424
	fprintf(stderr, "\n");
237
2848
}
238
239
void
240
relay_protodebug(struct relay *rlay)
241
{
242
1924
	struct protocol		*proto = rlay->rl_proto;
243
	struct relay_rule	*rule = NULL;
244
245
962
	fprintf(stderr, "protocol %d: name %s\n",
246
962
	    proto->id, proto->name);
247
962
	fprintf(stderr, "\tflags: %s, relay flags: %s\n",
248
962
	    printb_flags(proto->flags, F_BITS),
249
962
	    printb_flags(rlay->rl_conf.flags, F_BITS));
250
962
	if (proto->tcpflags)
251
490
		fprintf(stderr, "\ttcp flags: %s\n",
252
490
		    printb_flags(proto->tcpflags, TCPFLAG_BITS));
253

1210
	if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) && proto->tlsflags)
254
248
		fprintf(stderr, "\ttls flags: %s\n",
255
248
		    printb_flags(proto->tlsflags, TLSFLAG_BITS));
256
1924
	fprintf(stderr, "\ttls session tickets: %s\n",
257
1924
	    (proto->tickets == 1) ? "enabled" : "disabled");
258
1924
	fprintf(stderr, "\ttype: ");
259

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

262
		if (strlen(proto->tlscakey) && proto->tlscapass != NULL) {
2599
56
			if ((rlay->rl_tls_cakey =
2600
56
			    ssl_load_key(env, proto->tlscakey,
2601
28
			    &rlay->rl_conf.tls_cakey_len,
2602
28
			    proto->tlscapass)) == NULL)
2603
				return (-1);
2604
28
			log_debug("%s: using ca key %s", __func__,
2605
			    proto->tlscakey);
2606
28
		}
2607
	}
2608
2609
962
	if ((rlay->rl_conf.flags & F_TLS) == 0)
2610
728
		return (0);
2611
2612
234
	if (print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL)
2613
		return (-1);
2614
2615
468
	if (snprintf(certfile, sizeof(certfile),
2616
234
	    "/etc/ssl/%s:%u.crt", hbuf, useport) == -1)
2617
		return (-1);
2618
468
	if ((rlay->rl_tls_cert = relay_load_file(certfile,
2619
468
	    &rlay->rl_conf.tls_cert_len)) == NULL) {
2620
468
		if (snprintf(certfile, sizeof(certfile),
2621
234
		    "/etc/ssl/%s.crt", hbuf) == -1)
2622
			return (-1);
2623
468
		if ((rlay->rl_tls_cert = relay_load_file(certfile,
2624
234
		    &rlay->rl_conf.tls_cert_len)) == NULL)
2625
			return (-1);
2626
		useport = 0;
2627
234
	}
2628
234
	log_debug("%s: using certificate %s", __func__, certfile);
2629
2630
234
	if (useport) {
2631
		if (snprintf(certfile, sizeof(certfile),
2632
		    "/etc/ssl/private/%s:%u.key", hbuf, useport) == -1)
2633
			return -1;
2634
	} else {
2635
468
		if (snprintf(certfile, sizeof(certfile),
2636
234
		    "/etc/ssl/private/%s.key", hbuf) == -1)
2637
			return -1;
2638
	}
2639
702
	if ((rlay->rl_tls_key = ssl_load_key(env, certfile,
2640
468
	    &rlay->rl_conf.tls_key_len, NULL)) == NULL)
2641
		return (-1);
2642
234
	log_debug("%s: using private key %s", __func__, certfile);
2643
2644
234
	return (0);
2645
962
}
2646
2647
int
2648
relay_session_cmp(struct rsession *a, struct rsession *b)
2649
{
2650
	struct relay	*rlay = b->se_relay;
2651
	struct protocol	*proto = rlay->rl_proto;
2652
2653
	if (proto != NULL && proto->cmp != NULL)
2654
		return ((*proto->cmp)(a, b));
2655
2656
	return ((int)a->se_id - b->se_id);
2657
}
2658
2659
void
2660
relay_log(struct rsession *con, char *msg)
2661
{
2662
	if (con->se_haslog && con->se_log != NULL) {
2663
		evbuffer_add(con->se_log, msg, strlen(msg));
2664
	}
2665
}
2666
2667
SPLAY_GENERATE(session_tree, rsession, se_nodes, relay_session_cmp);