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