server.c revision 1.21
1/* $OpenBSD: server.c,v 1.21 2014/08/01 22:24:05 reyk Exp $ */ 2 3/* 4 * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20#include <sys/queue.h> 21#include <sys/time.h> 22#include <sys/stat.h> 23#include <sys/socket.h> 24#include <sys/un.h> 25#include <sys/tree.h> 26#include <sys/hash.h> 27 28#include <net/if.h> 29#include <netinet/in_systm.h> 30#include <netinet/in.h> 31#include <netinet/ip.h> 32#include <netinet/tcp.h> 33#include <arpa/inet.h> 34 35#include <errno.h> 36#include <fcntl.h> 37#include <stdlib.h> 38#include <string.h> 39#include <unistd.h> 40#include <stdio.h> 41#include <err.h> 42#include <pwd.h> 43#include <event.h> 44#include <fnmatch.h> 45 46#include <openssl/dh.h> 47#include <openssl/ssl.h> 48 49#include "httpd.h" 50 51int server_dispatch_parent(int, struct privsep_proc *, 52 struct imsg *); 53void server_shutdown(void); 54 55void server_init(struct privsep *, struct privsep_proc *p, void *); 56void server_launch(void); 57int server_socket(struct sockaddr_storage *, in_port_t, 58 struct server_config *, int, int); 59int server_socket_listen(struct sockaddr_storage *, in_port_t, 60 struct server_config *); 61 62void server_accept(int, short, void *); 63void server_input(struct client *); 64 65extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t, 66 size_t, void *); 67 68volatile int server_clients; 69volatile int server_inflight = 0; 70u_int32_t server_cltid; 71 72static struct httpd *env = NULL; 73int proc_id; 74 75static struct privsep_proc procs[] = { 76 { "parent", PROC_PARENT, server_dispatch_parent } 77}; 78 79pid_t 80server(struct privsep *ps, struct privsep_proc *p) 81{ 82 pid_t pid; 83 env = ps->ps_env; 84 pid = proc_run(ps, p, procs, nitems(procs), server_init, NULL); 85 server_http(env); 86 return (pid); 87} 88 89void 90server_shutdown(void) 91{ 92 config_purge(env, CONFIG_ALL); 93 usleep(200); /* XXX server needs to shutdown last */ 94} 95 96int 97server_privinit(struct server *srv) 98{ 99 if (srv->srv_conf.flags & SRVFLAG_LOCATION) 100 return (0); 101 102 log_debug("%s: adding server %s", __func__, srv->srv_conf.name); 103 104 if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss, 105 srv->srv_conf.port, &srv->srv_conf)) == -1) 106 return (-1); 107 108 return (0); 109} 110 111void 112server_init(struct privsep *ps, struct privsep_proc *p, void *arg) 113{ 114 server_http(ps->ps_env); 115 116 if (config_init(ps->ps_env) == -1) 117 fatal("failed to initialize configuration"); 118 119 /* Set to current prefork id */ 120 proc_id = p->p_instance; 121 122 /* We use a custom shutdown callback */ 123 p->p_shutdown = server_shutdown; 124 125 /* Unlimited file descriptors (use system limits) */ 126 socket_rlimit(-1); 127 128#if 0 129 /* Schedule statistics timer */ 130 evtimer_set(&env->sc_statev, server_statistics, NULL); 131 memcpy(&tv, &env->sc_statinterval, sizeof(tv)); 132 evtimer_add(&env->sc_statev, &tv); 133#endif 134} 135 136void 137server_launch(void) 138{ 139 struct server *srv; 140 141 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { 142 server_http_init(srv); 143 144 log_debug("%s: running server %s", __func__, 145 srv->srv_conf.name); 146 147 event_set(&srv->srv_ev, srv->srv_s, EV_READ, 148 server_accept, srv); 149 event_add(&srv->srv_ev, NULL); 150 evtimer_set(&srv->srv_evt, server_accept, srv); 151 } 152} 153 154void 155server_purge(struct server *srv) 156{ 157 struct client *clt; 158 struct server_config *srv_conf; 159 160 /* shutdown and remove server */ 161 if (event_initialized(&srv->srv_ev)) 162 event_del(&srv->srv_ev); 163 if (evtimer_initialized(&srv->srv_evt)) 164 evtimer_del(&srv->srv_evt); 165 166 close(srv->srv_s); 167 TAILQ_REMOVE(env->sc_servers, srv, srv_entry); 168 169 /* cleanup sessions */ 170 while ((clt = 171 SPLAY_ROOT(&srv->srv_clients)) != NULL) 172 server_close(clt, NULL); 173 174 /* cleanup hosts */ 175 while ((srv_conf = 176 TAILQ_FIRST(&srv->srv_hosts)) != NULL) { 177 TAILQ_REMOVE(&srv->srv_hosts, srv_conf, entry); 178 179 /* It might point to our own "default" entry */ 180 if (srv_conf != &srv->srv_conf) 181 free(srv_conf); 182 } 183 184 free(srv); 185} 186 187struct server * 188server_byaddr(struct sockaddr *addr, in_port_t port) 189{ 190 struct server *srv; 191 192 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { 193 if (port == srv->srv_conf.port && 194 sockaddr_cmp((struct sockaddr *)&srv->srv_conf.ss, 195 addr, srv->srv_conf.prefixlen) == 0) 196 return (srv); 197 } 198 199 return (NULL); 200} 201 202int 203server_socket_af(struct sockaddr_storage *ss, in_port_t port) 204{ 205 switch (ss->ss_family) { 206 case AF_INET: 207 ((struct sockaddr_in *)ss)->sin_port = port; 208 ((struct sockaddr_in *)ss)->sin_len = 209 sizeof(struct sockaddr_in); 210 break; 211 case AF_INET6: 212 ((struct sockaddr_in6 *)ss)->sin6_port = port; 213 ((struct sockaddr_in6 *)ss)->sin6_len = 214 sizeof(struct sockaddr_in6); 215 break; 216 default: 217 return (-1); 218 } 219 220 return (0); 221} 222 223in_port_t 224server_socket_getport(struct sockaddr_storage *ss) 225{ 226 switch (ss->ss_family) { 227 case AF_INET: 228 return (((struct sockaddr_in *)ss)->sin_port); 229 case AF_INET6: 230 return (((struct sockaddr_in6 *)ss)->sin6_port); 231 default: 232 return (0); 233 } 234 235 /* NOTREACHED */ 236 return (0); 237} 238 239int 240server_socket(struct sockaddr_storage *ss, in_port_t port, 241 struct server_config *srv_conf, int fd, int reuseport) 242{ 243 struct linger lng; 244 int s = -1, val; 245 246 if (server_socket_af(ss, port) == -1) 247 goto bad; 248 249 s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM, IPPROTO_TCP) : fd; 250 if (s == -1) 251 goto bad; 252 253 /* 254 * Socket options 255 */ 256 memset(&lng, 0, sizeof(lng)); 257 if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) 258 goto bad; 259 if (reuseport) { 260 val = 1; 261 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, 262 sizeof(int)) == -1) 263 goto bad; 264 } 265 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 266 goto bad; 267 if (srv_conf->tcpflags & TCPFLAG_BUFSIZ) { 268 val = srv_conf->tcpbufsiz; 269 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 270 &val, sizeof(val)) == -1) 271 goto bad; 272 val = srv_conf->tcpbufsiz; 273 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 274 &val, sizeof(val)) == -1) 275 goto bad; 276 } 277 278 /* 279 * IP options 280 */ 281 if (srv_conf->tcpflags & TCPFLAG_IPTTL) { 282 val = (int)srv_conf->tcpipttl; 283 if (setsockopt(s, IPPROTO_IP, IP_TTL, 284 &val, sizeof(val)) == -1) 285 goto bad; 286 } 287 if (srv_conf->tcpflags & TCPFLAG_IPMINTTL) { 288 val = (int)srv_conf->tcpipminttl; 289 if (setsockopt(s, IPPROTO_IP, IP_MINTTL, 290 &val, sizeof(val)) == -1) 291 goto bad; 292 } 293 294 /* 295 * TCP options 296 */ 297 if (srv_conf->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) { 298 if (srv_conf->tcpflags & TCPFLAG_NNODELAY) 299 val = 0; 300 else 301 val = 1; 302 if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 303 &val, sizeof(val)) == -1) 304 goto bad; 305 } 306 if (srv_conf->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) { 307 if (srv_conf->tcpflags & TCPFLAG_NSACK) 308 val = 0; 309 else 310 val = 1; 311 if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE, 312 &val, sizeof(val)) == -1) 313 goto bad; 314 } 315 316 return (s); 317 318 bad: 319 if (s != -1) 320 close(s); 321 return (-1); 322} 323 324int 325server_socket_listen(struct sockaddr_storage *ss, in_port_t port, 326 struct server_config *srv_conf) 327{ 328 int s; 329 330 if ((s = server_socket(ss, port, srv_conf, -1, 1)) == -1) 331 return (-1); 332 333 if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1) 334 goto bad; 335 if (listen(s, srv_conf->tcpbacklog) == -1) 336 goto bad; 337 338 return (s); 339 340 bad: 341 close(s); 342 return (-1); 343} 344 345void 346server_input(struct client *clt) 347{ 348 struct server_config *srv_conf = clt->clt_srv_conf; 349 evbuffercb inrd = server_read; 350 evbuffercb inwr = server_write; 351 352 if (server_httpdesc_init(clt) == -1) { 353 server_close(clt, 354 "failed to allocate http descriptor"); 355 return; 356 } 357 358 clt->clt_toread = TOREAD_HTTP_HEADER; 359 inrd = server_read_http; 360 361 /* 362 * Client <-> Server 363 */ 364 clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr, 365 server_error, clt); 366 if (clt->clt_bev == NULL) { 367 server_close(clt, "failed to allocate input buffer event"); 368 return; 369 } 370 371 bufferevent_settimeout(clt->clt_bev, 372 srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec); 373 bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE); 374} 375 376void 377server_write(struct bufferevent *bev, void *arg) 378{ 379 struct client *clt = arg; 380 struct evbuffer *dst = EVBUFFER_OUTPUT(bev); 381 382 if (EVBUFFER_LENGTH(dst) == 0 && 383 clt->clt_toread == TOREAD_HTTP_NONE) 384 goto done; 385 386 getmonotime(&clt->clt_tv_last); 387 388 if (clt->clt_done) 389 goto done; 390 return; 391 done: 392 server_close(clt, "done"); 393 return; 394} 395 396void 397server_dump(struct client *clt, const void *buf, size_t len) 398{ 399 if (!len) 400 return; 401 402 /* 403 * This function will dump the specified message directly 404 * to the underlying client, without waiting for success 405 * of non-blocking events etc. This is useful to print an 406 * error message before gracefully closing the client. 407 */ 408#if 0 409 if (cre->ssl != NULL) 410 (void)SSL_write(cre->ssl, buf, len); 411 else 412#endif 413 (void)write(clt->clt_s, buf, len); 414} 415 416void 417server_read(struct bufferevent *bev, void *arg) 418{ 419 struct client *clt = arg; 420 struct evbuffer *src = EVBUFFER_INPUT(bev); 421 422 getmonotime(&clt->clt_tv_last); 423 424 if (!EVBUFFER_LENGTH(src)) 425 return; 426 if (server_bufferevent_write_buffer(clt, src) == -1) 427 goto fail; 428 if (clt->clt_done) 429 goto done; 430 bufferevent_enable(bev, EV_READ); 431 return; 432 done: 433 server_close(clt, "done"); 434 return; 435 fail: 436 server_close(clt, strerror(errno)); 437} 438 439void 440server_error(struct bufferevent *bev, short error, void *arg) 441{ 442 struct client *clt = arg; 443 444 if (error & EVBUFFER_TIMEOUT) { 445 server_close(clt, "buffer event timeout"); 446 return; 447 } 448 if (error & EVBUFFER_ERROR && errno == EFBIG) { 449 bufferevent_enable(bev, EV_READ); 450 return; 451 } 452 if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) { 453 bufferevent_disable(bev, EV_READ|EV_WRITE); 454 455 clt->clt_done = 1; 456 server_close(clt, "done"); 457 return; 458 } 459 server_close(clt, "buffer event error"); 460 return; 461} 462 463void 464server_accept(int fd, short event, void *arg) 465{ 466 struct server *srv = arg; 467 struct client *clt = NULL; 468 socklen_t slen; 469 struct sockaddr_storage ss; 470 int s = -1; 471 472 event_add(&srv->srv_ev, NULL); 473 if ((event & EV_TIMEOUT)) 474 return; 475 476 slen = sizeof(ss); 477 if ((s = accept_reserve(fd, (struct sockaddr *)&ss, 478 &slen, FD_RESERVE, &server_inflight)) == -1) { 479 /* 480 * Pause accept if we are out of file descriptors, or 481 * libevent will haunt us here too. 482 */ 483 if (errno == ENFILE || errno == EMFILE) { 484 struct timeval evtpause = { 1, 0 }; 485 486 event_del(&srv->srv_ev); 487 evtimer_add(&srv->srv_evt, &evtpause); 488 log_debug("%s: deferring connections", __func__); 489 } 490 return; 491 } 492 if (server_clients >= SERVER_MAX_CLIENTS) 493 goto err; 494 495 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 496 goto err; 497 498 if ((clt = calloc(1, sizeof(*clt))) == NULL) 499 goto err; 500 501 clt->clt_s = s; 502 clt->clt_fd = -1; 503 clt->clt_toread = TOREAD_UNLIMITED; 504 clt->clt_srv = srv; 505 clt->clt_srv_conf = &srv->srv_conf; 506 clt->clt_id = ++server_cltid; 507 clt->clt_srv_id = srv->srv_conf.id; 508 clt->clt_pid = getpid(); 509 clt->clt_inflight = 1; 510 511 /* get local address */ 512 slen = sizeof(clt->clt_srv_ss); 513 if (getsockname(s, (struct sockaddr *)&clt->clt_srv_ss, 514 &slen) == -1) { 515 server_close(clt, "listen address lookup failed"); 516 return; 517 } 518 519 /* get client address */ 520 memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss)); 521 522 /* get ports */ 523 switch (ss.ss_family) { 524 case AF_INET: 525 clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port; 526 break; 527 case AF_INET6: 528 clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port; 529 break; 530 } 531 532 getmonotime(&clt->clt_tv_start); 533 memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last)); 534 535 server_clients++; 536 SPLAY_INSERT(client_tree, &srv->srv_clients, clt); 537 538 /* Increment the per-relay client counter */ 539 //srv->srv_stats[proc_id].last++; 540 541 /* Pre-allocate output buffer */ 542 clt->clt_output = evbuffer_new(); 543 if (clt->clt_output == NULL) { 544 server_close(clt, "failed to allocate output buffer"); 545 return; 546 } 547 548 /* Pre-allocate log buffer */ 549 clt->clt_log = evbuffer_new(); 550 if (clt->clt_log == NULL) { 551 server_close(clt, "failed to allocate log buffer"); 552 return; 553 } 554 555 server_input(clt); 556 return; 557 558 err: 559 if (s != -1) { 560 close(s); 561 if (clt != NULL) 562 free(clt); 563 /* 564 * the client struct was not completly set up, but still 565 * counted as an inflight client. account for this. 566 */ 567 server_inflight_dec(clt, __func__); 568 } 569} 570 571void 572server_inflight_dec(struct client *clt, const char *why) 573{ 574 if (clt != NULL) { 575 /* the flight already left inflight mode. */ 576 if (clt->clt_inflight == 0) 577 return; 578 clt->clt_inflight = 0; 579 } 580 581 /* the file was never opened, thus this was an inflight client. */ 582 server_inflight--; 583 DPRINTF("%s: inflight decremented, now %d, %s", 584 __func__, server_inflight, why); 585} 586 587void 588server_log(struct client *clt) 589{ 590 char *ptr = NULL; 591 592 if (!EVBUFFER_LENGTH(clt->clt_log)) 593 return; 594 595 while ((ptr = evbuffer_readline(clt->clt_log)) != NULL) { 596 log_info("%s", ptr); 597 free(ptr); 598 } 599} 600 601void 602server_close(struct client *clt, const char *msg) 603{ 604 char ibuf[MAXHOSTNAMELEN], obuf[MAXHOSTNAMELEN]; 605 struct server *srv = clt->clt_srv; 606 struct server_config *srv_conf = clt->clt_srv_conf; 607 extern int debug; 608 609 SPLAY_REMOVE(client_tree, &srv->srv_clients, clt); 610 611 /* free the HTTP descriptors incl. headers */ 612 server_close_http(clt); 613 614 event_del(&clt->clt_ev); 615 if (clt->clt_bev != NULL) 616 bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); 617 if (clt->clt_srvbev != NULL) 618 bufferevent_disable(clt->clt_srvbev, EV_READ|EV_WRITE); 619 620 server_log(clt); 621 622 if (debug && msg != NULL) { 623 memset(&ibuf, 0, sizeof(ibuf)); 624 memset(&obuf, 0, sizeof(obuf)); 625 (void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf)); 626 (void)server_http_host(&clt->clt_srv_ss, obuf, sizeof(obuf)); 627 log_debug("server %s, " 628 "client %d (%d active), %s:%u -> %s, " 629 "%s", srv_conf->name, clt->clt_id, server_clients, 630 ibuf, ntohs(clt->clt_port), obuf, msg); 631 } 632 633 if (clt->clt_bev != NULL) 634 bufferevent_free(clt->clt_bev); 635 if (clt->clt_output != NULL) 636 evbuffer_free(clt->clt_output); 637 if (clt->clt_srvevb != NULL) 638 evbuffer_free(clt->clt_srvevb); 639 640 if (clt->clt_srvbev != NULL) 641 bufferevent_free(clt->clt_srvbev); 642 if (clt->clt_fd != -1) 643 close(clt->clt_fd); 644 if (clt->clt_s != -1) 645 close(clt->clt_s); 646 647 server_inflight_dec(clt, __func__); 648 649 if (clt->clt_log != NULL) 650 evbuffer_free(clt->clt_log); 651 652 free(clt); 653 server_clients--; 654} 655 656int 657server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) 658{ 659 switch (imsg->hdr.type) { 660 case IMSG_CFG_MEDIA: 661 config_getmedia(env, imsg); 662 break; 663 case IMSG_CFG_SERVER: 664 config_getserver(env, imsg); 665 break; 666 case IMSG_CFG_DONE: 667 config_getcfg(env, imsg); 668 break; 669 case IMSG_CTL_START: 670 server_launch(); 671 break; 672 case IMSG_CTL_RESET: 673 config_getreset(env, imsg); 674 break; 675 default: 676 return (-1); 677 } 678 679 return (0); 680} 681 682int 683server_bufferevent_add(struct event *ev, int timeout) 684{ 685 struct timeval tv, *ptv = NULL; 686 687 if (timeout) { 688 timerclear(&tv); 689 tv.tv_sec = timeout; 690 ptv = &tv; 691 } 692 693 return (event_add(ev, ptv)); 694} 695 696int 697server_bufferevent_print(struct client *clt, const char *str) 698{ 699 if (clt->clt_bev == NULL) 700 return (evbuffer_add(clt->clt_output, str, strlen(str))); 701 return (bufferevent_write(clt->clt_bev, str, strlen(str))); 702} 703 704int 705server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf) 706{ 707 if (clt->clt_bev == NULL) 708 return (evbuffer_add_buffer(clt->clt_output, buf)); 709 return (bufferevent_write_buffer(clt->clt_bev, buf)); 710} 711 712int 713server_bufferevent_write_chunk(struct client *clt, 714 struct evbuffer *buf, size_t size) 715{ 716 int ret; 717 ret = server_bufferevent_write(clt, buf->buffer, size); 718 if (ret != -1) 719 evbuffer_drain(buf, size); 720 return (ret); 721} 722 723int 724server_bufferevent_write(struct client *clt, void *data, size_t size) 725{ 726 if (clt->clt_bev == NULL) 727 return (evbuffer_add(clt->clt_output, data, size)); 728 return (bufferevent_write(clt->clt_bev, data, size)); 729} 730 731int 732server_client_cmp(struct client *a, struct client *b) 733{ 734 return ((int)a->clt_id - b->clt_id); 735} 736 737SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp); 738