1 /* $OpenBSD: server.c,v 1.6 2014/07/16 10:25:28 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 51 int server_dispatch_parent(int, struct privsep_proc *, 52 struct imsg *); 53 void server_shutdown(void); 54 55 void server_init(struct privsep *, struct privsep_proc *p, void *); 56 void server_launch(void); 57 int server_socket(struct sockaddr_storage *, in_port_t, 58 struct server *, int, int); 59 int server_socket_listen(struct sockaddr_storage *, in_port_t, 60 struct server *); 61 62 void server_accept(int, short, void *); 63 void server_input(struct client *); 64 65 extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t, 66 size_t, void *); 67 68 volatile int server_clients; 69 volatile int server_inflight = 0; 70 u_int32_t server_cltid; 71 72 static struct httpd *env = NULL; 73 int proc_id; 74 75 static struct privsep_proc procs[] = { 76 { "parent", PROC_PARENT, server_dispatch_parent } 77 }; 78 79 pid_t 80 server(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 89 void 90 server_shutdown(void) 91 { 92 config_purge(env, CONFIG_ALL); 93 usleep(200); /* XXX server needs to shutdown last */ 94 } 95 96 int 97 server_privinit(struct server *srv) 98 { 99 log_debug("%s: adding server %s", __func__, srv->srv_conf.name); 100 101 if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss, 102 srv->srv_conf.port, srv)) == -1) 103 return (-1); 104 105 return (0); 106 } 107 108 void 109 server_init(struct privsep *ps, struct privsep_proc *p, void *arg) 110 { 111 server_http(ps->ps_env); 112 113 if (config_init(ps->ps_env) == -1) 114 fatal("failed to initialize configuration"); 115 116 /* Set to current prefork id */ 117 proc_id = p->p_instance; 118 119 /* We use a custom shutdown callback */ 120 p->p_shutdown = server_shutdown; 121 122 /* Unlimited file descriptors (use system limits) */ 123 socket_rlimit(-1); 124 125 #if 0 126 /* Schedule statistics timer */ 127 evtimer_set(&env->sc_statev, server_statistics, NULL); 128 memcpy(&tv, &env->sc_statinterval, sizeof(tv)); 129 evtimer_add(&env->sc_statev, &tv); 130 #endif 131 } 132 133 void 134 server_launch(void) 135 { 136 struct server *srv; 137 138 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { 139 server_http_init(srv); 140 141 log_debug("%s: running server %s", __func__, 142 srv->srv_conf.name); 143 144 event_set(&srv->srv_ev, srv->srv_s, EV_READ, 145 server_accept, srv); 146 event_add(&srv->srv_ev, NULL); 147 evtimer_set(&srv->srv_evt, server_accept, srv); 148 } 149 } 150 151 int 152 server_socket_af(struct sockaddr_storage *ss, in_port_t port) 153 { 154 switch (ss->ss_family) { 155 case AF_INET: 156 ((struct sockaddr_in *)ss)->sin_port = port; 157 ((struct sockaddr_in *)ss)->sin_len = 158 sizeof(struct sockaddr_in); 159 break; 160 case AF_INET6: 161 ((struct sockaddr_in6 *)ss)->sin6_port = port; 162 ((struct sockaddr_in6 *)ss)->sin6_len = 163 sizeof(struct sockaddr_in6); 164 break; 165 default: 166 return (-1); 167 } 168 169 return (0); 170 } 171 172 in_port_t 173 server_socket_getport(struct sockaddr_storage *ss) 174 { 175 switch (ss->ss_family) { 176 case AF_INET: 177 return (((struct sockaddr_in *)ss)->sin_port); 178 case AF_INET6: 179 return (((struct sockaddr_in6 *)ss)->sin6_port); 180 default: 181 return (0); 182 } 183 184 /* NOTREACHED */ 185 return (0); 186 } 187 188 int 189 server_socket(struct sockaddr_storage *ss, in_port_t port, 190 struct server *srv, int fd, int reuseport) 191 { 192 struct linger lng; 193 int s = -1, val; 194 195 if (server_socket_af(ss, port) == -1) 196 goto bad; 197 198 s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM, IPPROTO_TCP) : fd; 199 if (s == -1) 200 goto bad; 201 202 /* 203 * Socket options 204 */ 205 memset(&lng, 0, sizeof(lng)); 206 if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) 207 goto bad; 208 if (reuseport) { 209 val = 1; 210 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, 211 sizeof(int)) == -1) 212 goto bad; 213 } 214 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 215 goto bad; 216 if (srv->srv_tcpflags & TCPFLAG_BUFSIZ) { 217 val = srv->srv_tcpbufsiz; 218 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 219 &val, sizeof(val)) == -1) 220 goto bad; 221 val = srv->srv_tcpbufsiz; 222 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 223 &val, sizeof(val)) == -1) 224 goto bad; 225 } 226 227 /* 228 * IP options 229 */ 230 if (srv->srv_tcpflags & TCPFLAG_IPTTL) { 231 val = (int)srv->srv_tcpipttl; 232 if (setsockopt(s, IPPROTO_IP, IP_TTL, 233 &val, sizeof(val)) == -1) 234 goto bad; 235 } 236 if (srv->srv_tcpflags & TCPFLAG_IPMINTTL) { 237 val = (int)srv->srv_tcpipminttl; 238 if (setsockopt(s, IPPROTO_IP, IP_MINTTL, 239 &val, sizeof(val)) == -1) 240 goto bad; 241 } 242 243 /* 244 * TCP options 245 */ 246 if (srv->srv_tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) { 247 if (srv->srv_tcpflags & TCPFLAG_NNODELAY) 248 val = 0; 249 else 250 val = 1; 251 if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 252 &val, sizeof(val)) == -1) 253 goto bad; 254 } 255 if (srv->srv_tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) { 256 if (srv->srv_tcpflags & TCPFLAG_NSACK) 257 val = 0; 258 else 259 val = 1; 260 if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE, 261 &val, sizeof(val)) == -1) 262 goto bad; 263 } 264 265 return (s); 266 267 bad: 268 if (s != -1) 269 close(s); 270 return (-1); 271 } 272 273 int 274 server_socket_listen(struct sockaddr_storage *ss, in_port_t port, 275 struct server *srv) 276 { 277 int s; 278 279 if ((s = server_socket(ss, port, srv, -1, 1)) == -1) 280 return (-1); 281 282 if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1) 283 goto bad; 284 if (listen(s, srv->srv_tcpbacklog) == -1) 285 goto bad; 286 287 return (s); 288 289 bad: 290 close(s); 291 return (-1); 292 } 293 294 void 295 server_input(struct client *clt) 296 { 297 struct server *srv = clt->clt_server; 298 evbuffercb inrd = server_read; 299 evbuffercb inwr = server_write; 300 301 if (server_httpdesc_init(clt) == -1) { 302 server_close(clt, 303 "failed to allocate http descriptor"); 304 return; 305 } 306 307 clt->clt_toread = TOREAD_HTTP_HEADER; 308 inrd = server_read_http; 309 310 /* 311 * Client <-> Server 312 */ 313 clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr, 314 server_error, clt); 315 if (clt->clt_bev == NULL) { 316 server_close(clt, "failed to allocate input buffer event"); 317 return; 318 } 319 320 bufferevent_settimeout(clt->clt_bev, 321 srv->srv_conf.timeout.tv_sec, srv->srv_conf.timeout.tv_sec); 322 bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE); 323 } 324 325 void 326 server_write(struct bufferevent *bev, void *arg) 327 { 328 struct client *clt = arg; 329 struct evbuffer *dst = EVBUFFER_OUTPUT(bev); 330 331 if (EVBUFFER_LENGTH(dst) == 0 && 332 clt->clt_toread == TOREAD_HTTP_NONE) 333 goto done; 334 335 getmonotime(&clt->clt_tv_last); 336 337 if (clt->clt_done) 338 goto done; 339 return; 340 done: 341 server_close(clt, "done"); 342 return; 343 } 344 345 void 346 server_dump(struct client *clt, const void *buf, size_t len) 347 { 348 if (!len) 349 return; 350 351 /* 352 * This function will dump the specified message directly 353 * to the underlying client, without waiting for success 354 * of non-blocking events etc. This is useful to print an 355 * error message before gracefully closing the client. 356 */ 357 #if 0 358 if (cre->ssl != NULL) 359 (void)SSL_write(cre->ssl, buf, len); 360 else 361 #endif 362 (void)write(clt->clt_s, buf, len); 363 } 364 365 void 366 server_read(struct bufferevent *bev, void *arg) 367 { 368 struct client *clt = arg; 369 struct evbuffer *src = EVBUFFER_INPUT(bev); 370 371 getmonotime(&clt->clt_tv_last); 372 373 if (!EVBUFFER_LENGTH(src)) 374 return; 375 if (server_bufferevent_write_buffer(clt, src) == -1) 376 goto fail; 377 if (clt->clt_done) 378 goto done; 379 bufferevent_enable(bev, EV_READ); 380 return; 381 done: 382 server_close(clt, "done"); 383 return; 384 fail: 385 server_close(clt, strerror(errno)); 386 } 387 388 void 389 server_error(struct bufferevent *bev, short error, void *arg) 390 { 391 struct client *clt = arg; 392 393 if (error & EVBUFFER_TIMEOUT) { 394 server_close(clt, "buffer event timeout"); 395 return; 396 } 397 if (error & EVBUFFER_ERROR && errno == EFBIG) { 398 bufferevent_enable(bev, EV_READ); 399 return; 400 } 401 if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) { 402 bufferevent_disable(bev, EV_READ|EV_WRITE); 403 404 clt->clt_done = 1; 405 server_close(clt, "done"); 406 return; 407 } 408 server_close(clt, "buffer event error"); 409 return; 410 } 411 412 void 413 server_accept(int fd, short event, void *arg) 414 { 415 struct server *srv = arg; 416 struct client *clt = NULL; 417 socklen_t slen; 418 struct sockaddr_storage ss; 419 int s = -1; 420 421 event_add(&srv->srv_ev, NULL); 422 if ((event & EV_TIMEOUT)) 423 return; 424 425 slen = sizeof(ss); 426 if ((s = accept_reserve(fd, (struct sockaddr *)&ss, 427 &slen, FD_RESERVE, &server_inflight)) == -1) { 428 /* 429 * Pause accept if we are out of file descriptors, or 430 * libevent will haunt us here too. 431 */ 432 if (errno == ENFILE || errno == EMFILE) { 433 struct timeval evtpause = { 1, 0 }; 434 435 event_del(&srv->srv_ev); 436 evtimer_add(&srv->srv_evt, &evtpause); 437 log_debug("%s: deferring connections", __func__); 438 } 439 return; 440 } 441 if (server_clients >= SERVER_MAX_CLIENTS) 442 goto err; 443 444 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 445 goto err; 446 447 if ((clt = calloc(1, sizeof(*clt))) == NULL) 448 goto err; 449 450 clt->clt_s = s; 451 clt->clt_fd = -1; 452 clt->clt_toread = TOREAD_UNLIMITED; 453 clt->clt_server = srv; 454 clt->clt_id = ++server_cltid; 455 clt->clt_serverid = srv->srv_conf.id; 456 clt->clt_pid = getpid(); 457 clt->clt_inflight = 1; 458 switch (ss.ss_family) { 459 case AF_INET: 460 clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port; 461 break; 462 case AF_INET6: 463 clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port; 464 break; 465 } 466 memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss)); 467 468 getmonotime(&clt->clt_tv_start); 469 memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last)); 470 471 server_clients++; 472 SPLAY_INSERT(client_tree, &srv->srv_clients, clt); 473 474 /* Increment the per-relay client counter */ 475 //srv->srv_stats[proc_id].last++; 476 477 /* Pre-allocate output buffer */ 478 clt->clt_output = evbuffer_new(); 479 if (clt->clt_output == NULL) { 480 server_close(clt, "failed to allocate output buffer"); 481 return; 482 } 483 484 /* Pre-allocate log buffer */ 485 clt->clt_log = evbuffer_new(); 486 if (clt->clt_log == NULL) { 487 server_close(clt, "failed to allocate log buffer"); 488 return; 489 } 490 491 server_input(clt); 492 return; 493 494 err: 495 if (s != -1) { 496 close(s); 497 if (clt != NULL) 498 free(clt); 499 /* 500 * the client struct was not completly set up, but still 501 * counted as an inflight client. account for this. 502 */ 503 server_inflight_dec(clt, __func__); 504 } 505 } 506 507 void 508 server_inflight_dec(struct client *clt, const char *why) 509 { 510 if (clt != NULL) { 511 /* the flight already left inflight mode. */ 512 if (clt->clt_inflight == 0) 513 return; 514 clt->clt_inflight = 0; 515 } 516 517 /* the file was never opened, thus this was an inflight client. */ 518 server_inflight--; 519 log_debug("%s: inflight decremented, now %d, %s", 520 __func__, server_inflight, why); 521 } 522 523 void 524 server_close(struct client *clt, const char *msg) 525 { 526 char ibuf[128], obuf[128], *ptr = NULL; 527 struct server *srv = clt->clt_server; 528 529 SPLAY_REMOVE(client_tree, &srv->srv_clients, clt); 530 531 event_del(&clt->clt_ev); 532 if (clt->clt_bev != NULL) 533 bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); 534 if (clt->clt_file != NULL) 535 bufferevent_disable(clt->clt_file, EV_READ|EV_WRITE); 536 537 if ((env->sc_opts & HTTPD_OPT_LOGUPDATE) && msg != NULL) { 538 memset(&ibuf, 0, sizeof(ibuf)); 539 memset(&obuf, 0, sizeof(obuf)); 540 (void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf)); 541 (void)print_host(&srv->srv_conf.ss, obuf, sizeof(obuf)); 542 if (EVBUFFER_LENGTH(clt->clt_log) && 543 evbuffer_add_printf(clt->clt_log, "\r\n") != -1) 544 ptr = evbuffer_readline(clt->clt_log); 545 log_info("server %s, " 546 "client %d (%d active), %s -> %s:%d, " 547 "%s%s%s", srv->srv_conf.name, clt->clt_id, server_clients, 548 ibuf, obuf, ntohs(clt->clt_port), msg, 549 ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr); 550 if (ptr != NULL) 551 free(ptr); 552 } 553 554 if (clt->clt_bev != NULL) 555 bufferevent_free(clt->clt_bev); 556 else if (clt->clt_output != NULL) 557 evbuffer_free(clt->clt_output); 558 559 if (clt->clt_file != NULL) 560 bufferevent_free(clt->clt_file); 561 if (clt->clt_fd != -1) 562 close(clt->clt_fd); 563 if (clt->clt_s != -1) 564 close(clt->clt_s); 565 566 server_inflight_dec(clt, __func__); 567 568 if (clt->clt_log != NULL) 569 evbuffer_free(clt->clt_log); 570 571 free(clt); 572 server_clients--; 573 } 574 575 int 576 server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) 577 { 578 switch (imsg->hdr.type) { 579 case IMSG_CFG_MEDIA: 580 config_getmedia(env, imsg); 581 break; 582 case IMSG_CFG_SERVER: 583 config_getserver(env, imsg); 584 break; 585 case IMSG_CFG_DONE: 586 config_getcfg(env, imsg); 587 break; 588 case IMSG_CTL_START: 589 server_launch(); 590 break; 591 case IMSG_CTL_RESET: 592 config_getreset(env, imsg); 593 break; 594 default: 595 return (-1); 596 } 597 598 return (0); 599 } 600 601 int 602 server_bufferevent_add(struct event *ev, int timeout) 603 { 604 struct timeval tv, *ptv = NULL; 605 606 if (timeout) { 607 timerclear(&tv); 608 tv.tv_sec = timeout; 609 ptv = &tv; 610 } 611 612 return (event_add(ev, ptv)); 613 } 614 615 int 616 server_bufferevent_print(struct client *clt, const char *str) 617 { 618 if (clt->clt_bev == NULL) 619 return (evbuffer_add(clt->clt_output, str, strlen(str))); 620 return (bufferevent_write(clt->clt_bev, str, strlen(str))); 621 } 622 623 int 624 server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf) 625 { 626 if (clt->clt_bev == NULL) 627 return (evbuffer_add_buffer(clt->clt_output, buf)); 628 return (bufferevent_write_buffer(clt->clt_bev, buf)); 629 } 630 631 int 632 server_bufferevent_write_chunk(struct client *clt, 633 struct evbuffer *buf, size_t size) 634 { 635 int ret; 636 ret = server_bufferevent_write(clt, buf->buffer, size); 637 if (ret != -1) 638 evbuffer_drain(buf, size); 639 return (ret); 640 } 641 642 int 643 server_bufferevent_write(struct client *clt, void *data, size_t size) 644 { 645 if (clt->clt_bev == NULL) 646 return (evbuffer_add(clt->clt_output, data, size)); 647 return (bufferevent_write(clt->clt_bev, data, size)); 648 } 649 650 int 651 server_client_cmp(struct client *a, struct client *b) 652 { 653 return ((int)a->clt_id - b->clt_id); 654 } 655 656 SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp); 657