From d815690a234fcb92342543ed0b3ebb67d8a9a7a2 Mon Sep 17 00:00:00 2001 From: Doralitze <doralitze@chaotikum.org> Date: Mon, 19 Jul 2021 17:34:37 +0200 Subject: [PATCH] add: max number of connected clients boundry for tcp server socket --- src/net/tcp_server_socket.cpp | 24 ++++++++++++++++++++---- src/net/tcp_server_socket.hpp | 22 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/net/tcp_server_socket.cpp b/src/net/tcp_server_socket.cpp index 1979e7e..d98d2ce 100644 --- a/src/net/tcp_server_socket.cpp +++ b/src/net/tcp_server_socket.cpp @@ -33,7 +33,9 @@ tcp_server_socket::tcp_server_socket( ) : ss{nullptr}, client_listener(client_listener_), - number_of_connected_clients(0) + overflow_client_listener(nullptr), + number_of_connected_clients(0), + max_number_of_simulataneusly_allowed_clients(0) { auto_fd socket_fd{socket(socket_identifier.family(), SOCK_STREAM, 0)}; @@ -108,12 +110,18 @@ void tcp_server_socket::await_raw_socket_incomming( // Generate client object from fd and announce it this->number_of_connected_clients++; - using namespace std::placeholders; - this->client_listener(tcp_client(std::bind(&tcp_server_socket::client_destructed_cb, this, _1), auto_fd(client_fd_raw), address, port)); + + if (this->max_number_of_simulataneusly_allowed_clients == 0 || this->get_number_of_connected_clients() <= this->max_number_of_simulataneusly_allowed_clients) { + this->client_listener(tcp_client(std::bind(&tcp_server_socket::client_destructed_cb, this, _1), auto_fd(client_fd_raw), address, port)); + } else { + if (this->overflow_client_listener != nullptr) { + this->overflow_client_listener(tcp_client(std::bind(&tcp_server_socket::client_destructed_cb, this, _1), auto_fd(client_fd_raw), address, port)); + } + } } -int tcp_server_socket::get_number_of_connected_clients() const { +unsigned int tcp_server_socket::get_number_of_connected_clients() const { return this->number_of_connected_clients; } @@ -123,4 +131,12 @@ void tcp_server_socket::client_destructed_cb(exit_status_t exit_status) { this->number_of_connected_clients--; } +void tcp_server_socket::set_client_overflow_handler(incoming_client_listener_type overflow_client_listener_) { + this->overflow_client_listener = overflow_client_listener_; +} + +void tcp_server_socket::set_maximum_concurrent_connections(unsigned int max_connections) { + this->max_number_of_simulataneusly_allowed_clients = max_connections; +} + } diff --git a/src/net/tcp_server_socket.hpp b/src/net/tcp_server_socket.hpp index a56ee7f..ffc2757 100644 --- a/src/net/tcp_server_socket.hpp +++ b/src/net/tcp_server_socket.hpp @@ -32,7 +32,9 @@ public: private: async_server_socket::self_ptr_type ss; incoming_client_listener_type client_listener; + incoming_client_listener_type overflow_client_listener; std::atomic_uint32_t number_of_connected_clients; + unsigned int max_number_of_simulataneusly_allowed_clients; public: /** @@ -59,7 +61,25 @@ public: * @brief Get the current number of connected clients. * @return The number of connected clients */ - int get_number_of_connected_clients() const; + unsigned int get_number_of_connected_clients() const; + + /** + * This method sets the overflow handler to use if the maximum number of allowed clients was reached. + * The purpose of said handler is to inform the connected client that the connection cant be established + * due to isufficient resources. It should transmit the appropriate error message and drop the client. + * @brief Set the client overflow handler + * @param overflow_client_listener The listener that handles clients that couldn't be accepted + */ + void set_client_overflow_handler(incoming_client_listener_type overflow_client_listener); + + /** + * Use this method in order to set the maximum number of allowed connections. Set it to + * 0 in order to disable the limit. If anything other than 0 is set it is highly recommended + * to also set an overflow handler. + * @brief Set the maximum allowed simultaneus connections. + * @param max_connections The maximum number of allowed connections. + */ + void set_maximum_concurrent_connections(unsigned int max_connections); private: void await_raw_socket_incomming(async_server_socket::self_ptr_type ass, const auto_fd& socket); -- GitLab