UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "../public/nsapi.h" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 34 #include <sys/shm.h> 35 #include <sys/ipc.h> 36 #include <sys/file.h> 37 #include <netinet/tcp.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <fcntl.h> 41 #include <unistd.h> 42 #include <strings.h> 43 #include <stdbool.h> 44 #include <signal.h> 45 #include <pthread.h> 46 47 #include <stdio.h> 48 #include <stdlib.h> 49 50 #include <openssl/rand.h> /* RAND_bytes, connection id */ 51 52 #include <cx/hash_map.h> 53 54 #include "../util/atomic.h" 55 #include "httplistener.h" 56 #include "netsite.h" 57 58 #include "session.h" 59 #include "configmanager.h" 60 #include "log.h" 61 62 #define LISTENER_MAX_PROTOCOL_TOKENS 1024 63 64 65 #define LISTENER_PROTO_IPV4 "ipv4" 66 #define LISTENER_PROTO_IPV6 "ipv6" 67 68 69 /* 70 * key: string format: <protocol>:<port> 71 * value: WSSocket* 72 * 73 * protocol: ipv4 | ipv6 74 * port: short 75 */ 76 static CxMap *listener_socket_map; 77 78 static pthread_mutex_t listener_mutex = PTHREAD_MUTEX_INITIALIZER; 79 80 81 int http_listener_global_init(void) { 82 listener_socket_map = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 4); 83 if(!listener_socket_map) { 84 return 1; 85 } 86 87 return 0; 88 } 89 90 int start_all_listener() { 91 ServerConfiguration *conf = cfgmgr_get_server_config(); 92 CxList *ls = conf->listeners; 93 CxIterator iter = cxListIterator(ls); 94 cx_foreach(HttpListener *, listener, iter) { 95 http_listener_start(listener); 96 } 97 98 return 0; 99 } 100 101 static HttpSSL* create_http_ssl(ListenerConfig *conf) { 102 SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); 103 if(!ctx) { 104 return NULL; 105 } 106 SSL_CTX_set_options( 107 ctx, 108 SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv3); 109 SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 110 SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); 111 112 int error = 0; 113 if(conf->disable_proto.ptr) { 114 cxstring *plist = NULL; 115 ssize_t n = cx_strsplit_a(cxDefaultAllocator, conf->disable_proto, cx_str(","), LISTENER_MAX_PROTOCOL_TOKENS, &plist); 116 if(plist) { 117 for(int i=0;i<n;i++) { 118 cxstring proto = plist[i]; 119 log_ereport( 120 LOG_VERBOSE, 121 "Listener %s: Disable protocol %s", 122 conf->name.ptr, 123 proto.ptr); 124 if(!cx_strcasecmp(cx_strtrim(proto), cx_str("SSLv2"))) { 125 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); 126 } else if(!cx_strcasecmp(cx_strtrim(proto), cx_str("SSLv3"))) { 127 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); 128 } else if(!cx_strcasecmp(cx_strtrim(proto), cx_str("TLSv1"))) { 129 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); 130 } else if(!cx_strcasecmp(cx_strtrim(proto), cx_str("TLSv1.1"))) { 131 #ifdef SSL_OP_NO_TLSv1_1 132 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1); 133 #else 134 log_ereport( 135 LOG_WARN, 136 "Listener: %s: TLSv1.1 not supported", 137 conf->name.ptr); 138 #endif 139 } else if(cx_strcasecmp(cx_strtrim(proto), cx_str("TLSv1.2"))) { 140 #ifdef SSL_OP_NO_TLSv1_2 141 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2); 142 #else 143 log_ereport( 144 LOG_WARN, 145 "Listener: %s: TLSv1.2 not supported", 146 conf->name.ptr); 147 #endif 148 } else if(cx_strcasecmp(cx_strtrim(proto), cx_str("TLSv1.3"))) { 149 #ifdef SSL_OP_NO_TLSv1_3 150 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); 151 #else 152 log_ereport( 153 LOG_WARN, 154 "Listener: %s: TLSv1.3 not supported", 155 conf->name.ptr); 156 #endif 157 } else { 158 error = 1; 159 log_ereport( 160 LOG_MISCONFIG, 161 "Listener: %s: Unknown protocol %s", 162 conf->name.ptr, 163 proto.ptr); 164 } 165 } 166 free(plist); 167 } 168 } 169 170 if(error) { 171 SSL_CTX_free(ctx); 172 return NULL; 173 } 174 175 int ret; 176 char errbuf[512]; 177 178 // get TLS cert 179 error = 0; 180 if(conf->chainfile.ptr) { 181 ret = SSL_CTX_use_certificate_chain_file(ctx, conf->chainfile.ptr); 182 if(!ret) { 183 ERR_error_string(ERR_get_error(), errbuf); 184 log_ereport(LOG_MISCONFIG, "Cannot load ssl cert file: %s", errbuf); 185 error = 1; 186 } 187 } else if(conf->certfile.ptr) { 188 ret = SSL_CTX_use_certificate_file(ctx, conf->certfile.ptr, SSL_FILETYPE_PEM); 189 if(!ret) { 190 ERR_error_string(ERR_get_error(), errbuf); 191 log_ereport(LOG_MISCONFIG, "Cannot load ssl chain file: %s", errbuf); 192 error = 1; 193 } 194 } else { 195 log_ereport(LOG_MISCONFIG, "Listener %s: no CertChain/Cert specified", conf->name.ptr); 196 error = 1; 197 } 198 199 // get private key 200 ret = SSL_CTX_use_PrivateKey_file(ctx, conf->privkeyfile.ptr, SSL_FILETYPE_PEM); 201 if(!ret) { 202 ERR_error_string(ERR_get_error(), errbuf); 203 log_ereport(LOG_MISCONFIG, "Cannot load ssl key file: %s", errbuf); 204 error = 1; 205 } 206 207 if(error) { 208 SSL_CTX_free(ctx); 209 return NULL; 210 } 211 212 HttpSSL *ssl = pool_malloc(conf->cfg->pool, sizeof(HttpSSL)); 213 if(!ssl) { 214 SSL_CTX_free(ctx); 215 return NULL; 216 } 217 ZERO(ssl, sizeof(HttpSSL)); 218 ssl->sslctx = ctx; 219 220 return ssl; 221 } 222 223 static WSSocket* create_socket(ListenerConfig *conf, const char *protocol) { 224 WSBool ipv4 = !strcmp(protocol, "ipv4") ? TRUE : FALSE; 225 226 int s = -1; 227 if(ipv4) { 228 // ipv4 socket 229 s = socket(AF_INET, SOCK_STREAM, 0); 230 } else { 231 // ipv6 socket 232 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 233 } 234 if(s < 0) { 235 log_ereport( 236 LOG_FAILURE, 237 "cannot create socket: protocol: %s port: %d error: %s", 238 protocol, 239 conf->port, 240 strerror(errno)); 241 return NULL; 242 } 243 244 // socket options 245 int o = 1; 246 setsockopt( 247 s, 248 SOL_SOCKET, SO_REUSEADDR, 249 &o, 250 sizeof(int)); 251 252 #ifdef LINUX 253 if(!ipv4) { 254 o = 1; 255 setsockopt( 256 s, 257 IPPROTO_IPV6, 258 IPV6_V6ONLY, 259 &o, 260 sizeof(int)); 261 } 262 #endif 263 264 // bind server socket to address 265 union ws_socketaddr addr; 266 struct sockaddr *servaddr; 267 size_t servaddr_size; 268 if(ipv4) { 269 // ipv4 270 memset(&addr.addr4, 0, sizeof(addr.addr4)); 271 addr.addr4.sin_family = AF_INET; 272 addr.addr4.sin_addr.s_addr = htonl(INADDR_ANY); 273 addr.addr4.sin_port = htons(conf->port); 274 servaddr = (struct sockaddr *)&addr.addr4; 275 servaddr_size = sizeof(addr.addr4); 276 } else { 277 // ipv6 278 memset(&addr.addr6, 0, sizeof(addr.addr6)); 279 addr.addr6.sin6_family = AF_INET6; 280 addr.addr6.sin6_addr = in6addr_any; 281 addr.addr6.sin6_port = htons(conf->port); 282 servaddr = (struct sockaddr *)&addr.addr6; 283 servaddr_size = sizeof(addr.addr6); 284 } 285 286 if(bind(s, servaddr, servaddr_size)) { 287 log_ereport( 288 LOG_FAILURE, 289 "cannot bind socket: protocol: %s port: %d error: %s", 290 protocol, 291 conf->port, 292 strerror(errno)); 293 close(s); 294 return NULL; 295 } 296 297 // everything is ok, create WSSocket object 298 WSSocket *wssocket = malloc(sizeof(WSSocket)); 299 if(!wssocket) { 300 close(s); 301 return NULL; 302 } 303 ZERO(wssocket, sizeof(WSSocket)); 304 wssocket->socket = s; 305 wssocket->addr = addr; 306 if(ipv4) { 307 wssocket->sockaddr = (struct sockaddr *)&wssocket->addr.addr4; 308 } else { 309 wssocket->sockaddr = (struct sockaddr *)&wssocket->addr.addr6; 310 } 311 wssocket->sockaddr_size = servaddr_size; 312 313 return wssocket; 314 } 315 316 static WSSocket* get_socket(ListenerConfig *conf, const char *protocol) { 317 char key_data[32]; 318 size_t key_len = snprintf(key_data, 32, "%s:%d", protocol, conf->port); 319 CxHashKey key = cx_hash_key(key_data, key_len); 320 321 WSSocket *sock = cxMapGet(listener_socket_map, key); 322 if(!sock) { 323 sock = create_socket(conf, protocol); 324 if(sock) { 325 cxMapPut(listener_socket_map, key, sock); 326 } 327 } 328 return sock; 329 } 330 331 /* 332 * returns HttpSSL of socket1 or socket2 if ssl is available 333 */ 334 static HttpSSL* socket_get_ssl(WSSocket *socket1, WSSocket *socket2) { 335 if(socket1 && socket1->ssl) { 336 return socket1->ssl; 337 } 338 if(socket2 && socket2->ssl) { 339 return socket2->ssl; 340 } 341 return NULL; 342 } 343 344 static HttpListener* listener_create(ListenerConfig *conf) { 345 pool_handle_t *pool = conf->cfg->pool; 346 HttpListener *listener = pool_malloc(pool, sizeof(HttpListener)); 347 if(!listener) { 348 return NULL; 349 } 350 ZERO(listener, sizeof(HttpListener)); 351 352 listener->running = 0; 353 listener->cfg = conf->cfg; 354 listener->name = cx_strdup_a(pool_allocator(pool), cx_strcast(conf->name)); 355 listener->default_vs.vs_name = pool_strdup(pool, conf->vs.ptr); 356 listener->threadpool = NULL; 357 if(conf->threadpool.ptr != NULL) { 358 listener->threadpool = get_threadpool(cx_strcast(conf->threadpool)); 359 } 360 if(listener->threadpool == NULL) { 361 listener->threadpool = get_default_threadpool(); 362 } 363 if(conf->blockingio) { 364 listener->session_handler = create_basic_session_handler(pool); 365 } else { 366 listener->session_handler = create_event_session_handler(pool); 367 } 368 listener->nacceptors = conf->nacceptors; 369 listener->port = conf->port; 370 listener->next = NULL; 371 //listener->ssl = NULL; 372 373 // create sockets 374 listener->server_socket = get_socket(conf, LISTENER_PROTO_IPV4); 375 listener->server_socket6 = get_socket(conf, LISTENER_PROTO_IPV6); 376 if(!listener->server_socket && !listener->server_socket6) { 377 log_ereport(LOG_FAILURE, "Listener %s: no server socket", conf->name.ptr); 378 return NULL; 379 } 380 381 if(listener->server_socket) { 382 wssocket_ref(listener->server_socket); 383 } 384 if(listener->server_socket6) { 385 wssocket_ref(listener->server_socket6); 386 } 387 388 // create SSL context 389 if(conf->ssl) { 390 HttpSSL *ssl = socket_get_ssl(listener->server_socket, listener->server_socket6); 391 if(!ssl) { 392 ssl = create_http_ssl(conf); 393 if(!ssl) { 394 log_ereport(LOG_FAILURE, "Listener %s: cannot create SSL context", conf->name.ptr); 395 return NULL; 396 } 397 } 398 if(listener->server_socket) { 399 listener->server_socket->ssl = ssl; 400 } 401 if(listener->server_socket6) { 402 listener->server_socket6->ssl = ssl; 403 } 404 } 405 406 // create acceptors 407 listener->acceptors = calloc(listener->nacceptors, sizeof(void*)); 408 listener->acceptors6 = calloc(listener->nacceptors, sizeof(void*)); 409 for (int i=0;i<listener->nacceptors;i++) { 410 listener->acceptors[i] = acceptor_new(listener); 411 listener->acceptors6[i] = acceptor_new(listener); 412 listener->acceptors6[i]->ipv6 = TRUE; 413 } 414 415 return listener; 416 } 417 418 HttpListener* http_listener_create(ListenerConfig *conf) { 419 pthread_mutex_lock(&listener_mutex); 420 HttpListener *listener = listener_create(conf); 421 pthread_mutex_unlock(&listener_mutex); 422 return listener; 423 } 424 425 void http_listener_destroy(HttpListener *listener) { 426 log_ereport(LOG_DEBUG, "destroy http listener: %s config: %p", listener->name.ptr, listener->cfg); 427 428 if(listener->shutdown) { 429 pthread_mutex_destroy(&listener->shutdown_mutex); 430 pthread_cond_destroy(&listener->shutdown_cond); 431 } 432 } 433 434 int http_listener_start(HttpListener *listener) { 435 if(listener->running) { 436 return 0; 437 } 438 log_ereport(LOG_INFORM, "start listener on port %d", listener->port); 439 440 WSBool ipv4 = listener->server_socket ? TRUE : FALSE; 441 WSBool ipv6 = listener->server_socket6 ? TRUE: FALSE; 442 443 if (ipv4 && !listener->server_socket->listening && listen(listener->server_socket->socket, 256) == -1) { 444 log_ereport(LOG_FAILURE, "http_listener_start: listen failed: %s", strerror(errno)); 445 return -1; 446 } else { 447 listener->server_socket->listening = TRUE; 448 } 449 if (ipv6 && !listener->server_socket6->listening && listen(listener->server_socket6->socket, 256) == -1) { 450 log_ereport(LOG_FAILURE, "http_listener_start: listen v6 failed: %s", strerror(errno)); 451 return -1; 452 } else { 453 listener->server_socket6->listening = TRUE; 454 } 455 456 // start acceptor threads 457 for (int i=0;i<listener->nacceptors;i++) { 458 if(ipv4) { 459 acceptor_start(listener->acceptors[i]); 460 } 461 if(ipv6) { 462 acceptor_start(listener->acceptors6[i]); 463 } 464 } 465 listener->running = TRUE; 466 467 return 0; 468 } 469 470 int http_listener_socket_eq(HttpListener *l1, HttpListener *l2) { 471 if(l1->server_socket && l2->server_socket && l1->server_socket == l2->server_socket) { 472 return TRUE; 473 } 474 if(l1->server_socket6 && l2->server_socket6 && l1->server_socket6 == l2->server_socket6) { 475 return TRUE; 476 } 477 return FALSE; 478 } 479 480 void http_listener_set_next(HttpListener *listener, HttpListener *next) { 481 while(listener->next) { 482 listener = listener->next; 483 } 484 listener->next = next; 485 } 486 487 int http_listener_connect(HttpListener *listener, WSBool ipv6) { 488 int domain = ipv6 ? AF_INET6 : AF_INET; 489 int client = socket(domain, SOCK_STREAM, 0); 490 if(client < 0) { 491 return -1; 492 } 493 494 struct sockaddr *sockaddr; 495 size_t sockaddr_size; 496 if(ipv6) { 497 sockaddr = listener->server_socket6->sockaddr; 498 sockaddr_size = listener->server_socket6->sockaddr_size; 499 } else { 500 sockaddr = listener->server_socket->sockaddr; 501 sockaddr_size = listener->server_socket->sockaddr_size; 502 } 503 504 if(connect(client, sockaddr, sockaddr_size) < 0) { 505 close(client); 506 return -1; 507 } 508 509 return client; 510 } 511 512 513 void http_listener_shutdown_acceptors(HttpListener *listener) { 514 if(pthread_mutex_init(&listener->shutdown_mutex, NULL)) { 515 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: pthread_mutex_init failed: %s", strerror(errno)); 516 return; 517 } 518 if(pthread_cond_init(&listener->shutdown_cond, NULL)) { 519 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: pthread_cond_init failed: %s", strerror(errno)); 520 return; 521 } 522 listener->shutdown = TRUE; 523 524 log_ereport(LOG_INFORM, "shutdown http listener %s", listener->name.ptr); 525 526 pthread_mutex_lock(&listener->shutdown_mutex); 527 528 // shut down acceptors by connecting to the server socket, to make sure 529 // accept() returns 530 // the acceptor will handle this as a normal connection, but this should 531 // not be a problem 532 for(int i=0;i<listener->nacceptors;i++) { 533 listener->acceptors[i]->exit = TRUE; 534 int client4 = http_listener_connect(listener, FALSE); 535 if(client4 < 0) { 536 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: cannot connect to ipv4 server socket: %s", strerror(errno)); 537 } else { 538 close(client4); 539 } 540 541 listener->acceptors6[i]->exit = TRUE; 542 int client6 = http_listener_connect(listener, TRUE); 543 if(client6 < 0) { 544 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: cannot connect to ipv6 server socket: %s", strerror(errno)); 545 } else { 546 close(client6); 547 } 548 } 549 550 // The last acceptor will notify listener_shutdown.cond 551 // It is not really necessary to wait for acceptors to shut down, 552 // we do it mostly for nicer log messages. The timeout is there 553 // for making sure, this function never blocks forever. 554 struct timespec ts; 555 ts.tv_sec = time(NULL) + 60; 556 pthread_cond_timedwait(&listener->shutdown_cond, &listener->shutdown_mutex, &ts); 557 558 pthread_mutex_unlock(&listener->shutdown_mutex); 559 } 560 561 562 Acceptor* acceptor_new(HttpListener *listener) { 563 Acceptor *acceptor = malloc(sizeof(Acceptor)); 564 acceptor->listener = listener; 565 acceptor->ipv6 = WS_FALSE; 566 acceptor->exit = WS_FALSE; 567 return acceptor; 568 } 569 570 void acceptor_start(Acceptor *a) { 571 cfg_ref(a->listener->cfg); 572 if(pthread_create( 573 &a->tid, 574 NULL, 575 (void*(*)(void*))acceptor_thread, 576 a) != 0) 577 { 578 log_ereport(LOG_FAILURE, "Listener %s: acceptor_start: %s acceptor", a->listener->name.ptr, strerror(errno)); 579 cfg_unref(a->listener->cfg); 580 } else { 581 (void)pthread_detach(a->tid); 582 } 583 } 584 585 void* acceptor_thread(Acceptor *acceptor) { 586 WS_ASSERT(acceptor); 587 WS_ASSERT(acceptor->listener); 588 WS_ASSERT(acceptor->listener->cfg); 589 WS_ASSERT(acceptor->listener->session_handler); 590 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection); 591 592 acceptor->running = TRUE; 593 HttpListener *listener = acceptor->listener; 594 595 int server_socket; 596 uint32_t *acceptors_running = &listener->nacceptors_running; 597 598 ConnectionAddr ca; 599 struct sockaddr *ca_ptr; 600 socklen_t ca_length; 601 ConnectionAddrType addr_type; 602 HttpSSL *socket_ssl = NULL; 603 if(acceptor->ipv6) { 604 server_socket = listener->server_socket6->socket; 605 ca_ptr = (struct sockaddr*)&ca.address_v6; 606 ca_length = sizeof(ca.address_v6); 607 addr_type = CONN_ADDR_IPV6; 608 socket_ssl = listener->server_socket6->ssl; 609 } else { 610 server_socket = listener->server_socket->socket; 611 ca_ptr = (struct sockaddr*)&ca.address_v4; 612 ca_length = sizeof(ca.address_v4); 613 addr_type = CONN_ADDR_IPV4; 614 socket_ssl = listener->server_socket->ssl; 615 } 616 617 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener); 618 ws_atomic_inc32(acceptors_running); 619 620 for (;;) { 621 // accept connections 622 int clientfd; 623 socklen_t length = ca_length; 624 625 // accept a connection 626 clientfd = accept( 627 server_socket, 628 ca_ptr, 629 &length); 630 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd); 631 if (clientfd == -1) { 632 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); 633 634 if(acceptor->exit) { 635 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); 636 break; 637 } 638 continue; 639 } 640 641 //if(http_listener_apply_keep_alive_settings(listener, clientfd)) { 642 // close(clientfd); 643 // continue; 644 //} 645 646 // check listener 647 HttpListener *ls = listener; 648 int acceptor_exit = 0; 649 while(ls->next) { 650 ls = ls->next; 651 acceptor_exit = 1; 652 } 653 654 // create Connection object 655 Connection *conn = malloc(sizeof(Connection)); 656 uint32_t conn_id; 657 RAND_bytes((unsigned char*)&conn->id, sizeof(conn->id)); 658 conn->id <<= 16; 659 conn->address = ca; 660 conn->addr_type = addr_type; 661 conn->fd = clientfd; 662 conn->listener = ls; 663 conn->ssl_accepted = 0; 664 conn->ssl_error = 0; 665 log_ereport(LOG_DEBUG, "trace reqid: %016llx connection accepted", (unsigned long long int)conn->id); 666 if(socket_ssl) { 667 // SSL connections are always non-blocking 668 // set socket non blocking 669 int flags; 670 if((flags = fcntl(conn->fd, F_GETFL, 0)) == -1) { 671 flags = 0; 672 } 673 if(fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK)) { 674 log_ereport(LOG_DEBUG, "trace reqid: %016llx connection destroyed | fcntl error", (unsigned long long int)conn->id); 675 log_ereport(LOG_FAILURE, "acceptor: fcntl failed: %s", strerror(errno)); 676 close(clientfd); 677 free(conn); 678 conn = NULL; 679 } else { 680 SSL *ssl = SSL_new(socket_ssl->sslctx); 681 if(ssl) { 682 SSL_set_fd(ssl, clientfd); 683 684 conn->ssl = ssl; 685 conn->read = connection_ssl_read; 686 conn->write = connection_ssl_write; 687 conn->close = connection_ssl_close; 688 } else { 689 log_ereport(LOG_DEBUG, "trace reqid: %016llx connection destroyed | SSL init error", (unsigned long long int)conn->id); 690 log_ereport(LOG_FAILURE, "acceptor: %p listener: %p SSL_new() failed", acceptor, acceptor->listener); 691 free(conn); 692 close(clientfd); 693 conn = NULL; 694 } 695 } 696 } else { 697 conn->ssl = NULL; 698 conn->read = connection_read; 699 conn->write = connection_write; 700 conn->close = connection_close; 701 } 702 703 if(conn) { 704 cfg_ref(ls->cfg); 705 706 // enqueue the connection 707 ls->session_handler->enqueue_connection( 708 ls->session_handler, 709 conn); 710 } 711 712 // ready for new connection 713 714 if(acceptor_exit || acceptor->exit) { 715 // this acceptor is outdated 716 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); 717 break; 718 } 719 } 720 721 if(ws_atomic_dec32(acceptors_running) == 0) { 722 // notify 723 if(listener->shutdown) { 724 log_ereport(LOG_DEBUG, "last acceptor shutdown: notify cfgmgr"); 725 pthread_mutex_lock(&listener->shutdown_mutex); 726 pthread_cond_signal(&listener->shutdown_cond); 727 pthread_mutex_unlock(&listener->shutdown_mutex); 728 } 729 } 730 731 acceptor->running = FALSE; 732 733 cfg_unref(acceptor->listener->cfg); 734 735 return NULL; 736 } 737 738 void wssocket_ref(WSSocket *ws) { 739 ws_atomic_inc32(&ws->ref); 740 } 741 742 void wssocket_unref(WSSocket *ws) { 743 // does nothing yet, because maybe it is not a good idea to destroy 744 // a socket 745 ws_atomic_dec32(&ws->ref); 746 } 747 748 749 int http_listener_apply_keep_alive_settings(HttpListener *listener, int fd) { 750 // TODO: all these values should be configurable 751 int optval = 1; 752 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval))) { 753 log_ereport(LOG_FAILURE, "listener: cannot set SO_KEEPALIVE: %s", strerror(errno)); 754 return 1; 755 } 756 757 int keepidle = 240; 758 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle))) { 759 log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPIDLE to value %d: %s", keepidle, strerror(errno)); 760 return 1; 761 } 762 763 int keepintvl = 10; 764 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl))) { 765 log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPINTVL to value %d: %s", keepintvl, strerror(errno)); 766 return 1; 767 } 768 769 int keepcnt = 3; 770 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt))) { 771 log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPCNT to value %d: %s", keepcnt, strerror(errno)); 772 return 1; 773 } 774 775 return 0; 776 } 777