/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG sad.thread_id = session->thread_id; session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case SSL_HANDSHAKE_NO_MATCH: log_system(session, "No cypher overlap during SSL handshake."); break; case SSL_HANDSHAKE_TIMEOUT: handle_timeout(session); break; case SSL_HANDSHAKE_OKE: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_connection(session); } #endif do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_TOMAHAWK if (session->parsing_oke) { show_request_to_admins(session->method, session->request_uri, session->http_version, &(session->ip_address), session->http_headers, session->return_code, session->bytes_sent); } #endif #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { /* Flush the output-buffer */ if (send_buffer(session, NULL, 0) == -1) { session->keep_alive = false; } } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_host(session); } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } #ifdef ENABLE_DEBUG /* Show memory usage by thread */ memdbg_print_log(false); #endif /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }
/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_MONITOR int connections; #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif connections = ++open_connections; if (session->config->monitor_enabled) { if (connections > session->config->monitor_stats.simultaneous_connections) { session->config->monitor_stats.simultaneous_connections = connections; } } #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case -2: handle_timeout(session); break; case 0: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { send_buffer(session, NULL, 0); /* Flush the output-buffer */ } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_request(session); if (session->host->monitor_requests && (result > 0)) { monitor_request(session); } } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } #ifdef ENABLE_MONITOR open_connections--; #endif if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }