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