Ejemplo n.º 1
0
/* 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
}
Ejemplo n.º 2
0
/* 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
}