474 } |
475 } |
475 listener->next = next; |
476 listener->next = next; |
476 } |
477 } |
477 |
478 |
478 |
479 |
|
480 |
|
481 void http_listener_shutdown_acceptors(HttpListener *listener) { |
|
482 // not implemented yet |
|
483 } |
|
484 |
|
485 |
479 Acceptor* acceptor_new(HttpListener *listener) { |
486 Acceptor* acceptor_new(HttpListener *listener) { |
480 Acceptor *acceptor = malloc(sizeof(Acceptor)); |
487 Acceptor *acceptor = malloc(sizeof(Acceptor)); |
481 acceptor->listener = listener; |
488 acceptor->listener = listener; |
482 acceptor->ipv6 = WS_FALSE; |
489 acceptor->ipv6 = WS_FALSE; |
|
490 acceptor->exit = WS_FALSE; |
483 return acceptor; |
491 return acceptor; |
484 } |
492 } |
485 |
493 |
486 void acceptor_start(Acceptor *a) { |
494 void acceptor_start(Acceptor *a) { |
487 cfg_ref(a->listener->cfg); |
495 cfg_ref(a->listener->cfg); |
489 &a->tid, |
497 &a->tid, |
490 NULL, |
498 NULL, |
491 (void*(*)(void*))acceptor_thread, |
499 (void*(*)(void*))acceptor_thread, |
492 a) != 0) |
500 a) != 0) |
493 { |
501 { |
494 log_ereport(LOG_FAILURE, "Listener %s: acceptor_start: %s", a->listener->name.ptr, strerror(errno)); |
502 log_ereport(LOG_FAILURE, "Listener %s: acceptor_start: %s acceptor", a->listener->name.ptr, strerror(errno)); |
495 cfg_unref(a->listener->cfg); |
503 cfg_unref(a->listener->cfg); |
496 } |
504 } |
497 } |
505 } |
498 |
506 |
499 void* acceptor_thread(Acceptor *acceptor) { |
507 void* acceptor_thread(Acceptor *acceptor) { |
501 WS_ASSERT(acceptor->listener); |
509 WS_ASSERT(acceptor->listener); |
502 WS_ASSERT(acceptor->listener->cfg); |
510 WS_ASSERT(acceptor->listener->cfg); |
503 WS_ASSERT(acceptor->listener->session_handler); |
511 WS_ASSERT(acceptor->listener->session_handler); |
504 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection); |
512 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection); |
505 |
513 |
|
514 acceptor->running = TRUE; |
506 HttpListener *listener = acceptor->listener; |
515 HttpListener *listener = acceptor->listener; |
507 |
516 |
508 int server_socket; |
517 int server_socket; |
509 |
518 |
510 ConnectionAddr ca; |
519 ConnectionAddr ca; |
521 ca_ptr = (struct sockaddr*)&ca.address_v4; |
530 ca_ptr = (struct sockaddr*)&ca.address_v4; |
522 ca_length = sizeof(ca.address_v4); |
531 ca_length = sizeof(ca.address_v4); |
523 addr_type = CONN_ADDR_IPV4; |
532 addr_type = CONN_ADDR_IPV4; |
524 } |
533 } |
525 |
534 |
|
535 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener); |
526 |
536 |
527 for (;;) { |
537 for (;;) { |
528 // accept connections |
538 // accept connections |
529 int clientfd; |
539 int clientfd; |
530 socklen_t length = ca_length; |
540 socklen_t length = ca_length; |
561 int flags; |
571 int flags; |
562 if((flags = fcntl(conn->fd, F_GETFL, 0)) == -1) { |
572 if((flags = fcntl(conn->fd, F_GETFL, 0)) == -1) { |
563 flags = 0; |
573 flags = 0; |
564 } |
574 } |
565 if(fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK)) { |
575 if(fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK)) { |
566 perror("Error: acceptor_thread: fcntl"); |
576 log_ereport(LOG_FAILURE, "acceptor: fcntl failed: %s", strerror(errno)); |
567 // TODO: error |
577 close(clientfd); |
|
578 free(conn); |
|
579 conn = NULL; |
|
580 } else { |
|
581 SSL *ssl = SSL_new(ls->ssl->sslctx); |
|
582 if(ssl) { |
|
583 SSL_set_fd(ssl, clientfd); |
|
584 |
|
585 conn->ssl = ssl; |
|
586 conn->read = connection_ssl_read; |
|
587 conn->write = connection_ssl_write; |
|
588 conn->close = connection_ssl_close; |
|
589 } else { |
|
590 log_ereport(LOG_FAILURE, "acceptor: %p listener: %p SSL_new() failed", acceptor, acceptor->listener); |
|
591 free(conn); |
|
592 close(clientfd); |
|
593 conn = NULL; |
|
594 } |
568 } |
595 } |
569 |
|
570 SSL *ssl = SSL_new(ls->ssl->sslctx); |
|
571 SSL_set_fd(ssl, clientfd); |
|
572 |
|
573 conn->ssl = ssl; |
|
574 conn->read = connection_ssl_read; |
|
575 conn->write = connection_ssl_write; |
|
576 conn->close = connection_ssl_close; |
|
577 } else { |
596 } else { |
578 conn->ssl = NULL; |
597 conn->ssl = NULL; |
579 conn->read = connection_read; |
598 conn->read = connection_read; |
580 conn->write = connection_write; |
599 conn->write = connection_write; |
581 conn->close = connection_close; |
600 conn->close = connection_close; |
590 conn); |
609 conn); |
591 } |
610 } |
592 |
611 |
593 // ready for new connection |
612 // ready for new connection |
594 |
613 |
595 if(acceptor_exit) { |
614 if(acceptor_exit || acceptor->exit) { |
596 // this acceptor is outdated |
615 // this acceptor is outdated |
597 log_ereport(LOG_VERBOSE, "acceptor thread %p: exit", (void*)acceptor->tid); |
616 log_ereport(LOG_VERBOSE, "acceptor thread %p: exit", (void*)acceptor->tid); |
598 break; |
617 break; |
599 } |
618 } |
600 } |
619 } |
|
620 |
|
621 acceptor->running = FALSE; |
|
622 log_ereport(LOG_DEBUG, "acceptor: %p listener %p exit thread", acceptor, acceptor->listener); |
601 |
623 |
602 cfg_unref(acceptor->listener->cfg); |
624 cfg_unref(acceptor->listener->cfg); |
603 |
625 |
604 return NULL; |
626 return NULL; |
605 } |
627 } |