1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-07 18:23:13 +02:00

relay: fix the max number of clients connected on a port, allow value 0 for "no limit" (closes #669)

This commit is contained in:
Sébastien Helleu
2016-02-08 21:14:48 +01:00
parent c9a8f23cc7
commit 45a1174000
23 changed files with 318 additions and 71 deletions
+30
View File
@@ -161,6 +161,31 @@ relay_client_status_search (const char *name)
return -1;
}
/*
* Returns the number of active clients (connecting or connected) on a given
* server port.
*/
int
relay_client_count_active_by_port (int server_port)
{
struct t_relay_client *ptr_client;
int count;
count = 0;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
if ((ptr_client->server_port == server_port)
&& !RELAY_CLIENT_HAS_ENDED(ptr_client))
{
count++;
}
}
return count;
}
/*
* Sends a signal with the status of client ("relay_client_xxx").
*/
@@ -1163,6 +1188,7 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
new_client->id = (relay_clients) ? relay_clients->id + 1 : 1;
new_client->desc = NULL;
new_client->sock = sock;
new_client->server_port = server->port;
new_client->ssl = server->ssl;
#ifdef HAVE_GNUTLS
new_client->hook_timer_handshake = NULL;
@@ -1330,6 +1356,7 @@ relay_client_new_with_infolist (struct t_infolist *infolist)
new_client->id = weechat_infolist_integer (infolist, "id");
new_client->desc = NULL;
new_client->sock = weechat_infolist_integer (infolist, "sock");
new_client->server_port = weechat_infolist_integer (infolist, "server_port");
new_client->ssl = weechat_infolist_integer (infolist, "ssl");
#ifdef HAVE_GNUTLS
new_client->gnutls_sess = NULL;
@@ -1636,6 +1663,8 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "sock", client->sock))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "server_port", client->server_port))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "ssl", client->ssl))
return 0;
#ifdef HAVE_GNUTLS
@@ -1715,6 +1744,7 @@ relay_client_print_log ()
weechat_log_printf (" id. . . . . . . . . . : %d", ptr_client->id);
weechat_log_printf (" desc. . . . . . . . . : '%s'", ptr_client->desc);
weechat_log_printf (" sock. . . . . . . . . : %d", ptr_client->sock);
weechat_log_printf (" server_port . . . . . : %d", ptr_client->server_port);
weechat_log_printf (" ssl . . . . . . . . . : %d", ptr_client->ssl);
#ifdef HAVE_GNUTLS
weechat_log_printf (" gnutls_sess . . . . . : 0x%lx", ptr_client->gnutls_sess);
+2
View File
@@ -87,6 +87,7 @@ struct t_relay_client
int id; /* unique id (diff. for each client) */
char *desc; /* description, used for display */
int sock; /* socket for connection */
int server_port; /* port used for connection */
int ssl; /* 1 if SSL is enabled */
#ifdef HAVE_GNUTLS
gnutls_session_t gnutls_sess; /* gnutls session (only if SSL used) */
@@ -128,6 +129,7 @@ extern int relay_client_valid (struct t_relay_client *client);
extern struct t_relay_client *relay_client_search_by_number (int number);
extern struct t_relay_client *relay_client_search_by_id (int id);
extern int relay_client_status_search (const char *name);
extern int relay_client_count_active_by_port (int server_port);
extern void relay_client_set_desc (struct t_relay_client *client);
extern int relay_client_recv_cb (void *arg_client, int fd);
extern int relay_client_send (struct t_relay_client *client,
+2 -2
View File
@@ -748,8 +748,8 @@ relay_config_init ()
relay_config_network_max_clients = weechat_config_new_option (
relay_config_file, ptr_section,
"max_clients", "integer",
N_("maximum number of clients connecting to a port"),
NULL, 1, 1024, "5", NULL, 0,
N_("maximum number of clients connecting to a port (0 = no limit)"),
NULL, 0, INT_MAX, "5", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL);
relay_config_network_password = weechat_config_new_option (
relay_config_file, ptr_section,
+52 -12
View File
@@ -226,7 +226,7 @@ relay_server_sock_cb (void *data, int fd)
struct sockaddr_in6 client_addr6;
socklen_t client_addr_size;
void *ptr_addr;
int client_fd, flags, set;
int client_fd, flags, set, max_clients, num_clients_on_port;
char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
char *ptr_ip_address;
@@ -260,6 +260,28 @@ relay_server_sock_cb (void *data, int fd)
return WEECHAT_RC_OK;
}
/* check if we have reached the max number of clients on this port */
max_clients = weechat_config_integer (relay_config_network_max_clients);
if (max_clients > 0)
{
num_clients_on_port = relay_client_count_active_by_port (server->port);
if (num_clients_on_port >= max_clients)
{
weechat_printf (
NULL,
NG_("%s%s: client not allowed (max %d client is "
"allowed at same time)",
"%s%s: client not allowed (max %d clients are "
"allowed at same time)",
max_clients),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
max_clients);
close (client_fd);
return WEECHAT_RC_OK;
}
}
/* get the IP address */
ptr_ip_address = NULL;
if (server->ipv6)
{
@@ -474,9 +496,11 @@ relay_server_create_socket (struct t_relay_server *server)
return 0;
}
max_clients = weechat_config_integer (relay_config_network_max_clients);
if (listen (server->sock, max_clients) != 0)
#ifdef SOMAXCONN
if (listen (server->sock, SOMAXCONN) != 0)
#else
if (listen (server->sock, 1) != 0)
#endif
{
weechat_printf (NULL,
_("%s%s: cannot \"listen\" on port %d (%s): error %d %s"),
@@ -488,14 +512,30 @@ relay_server_create_socket (struct t_relay_server *server)
return 0;
}
weechat_printf (NULL,
_("%s: listening on port %d (relay: %s, %s, max %d clients)"),
RELAY_PLUGIN_NAME,
server->port,
server->protocol_string,
((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")),
max_clients);
max_clients = weechat_config_integer (relay_config_network_max_clients);
if (max_clients > 0)
{
weechat_printf (
NULL,
NG_("%s: listening on port %d (relay: %s, %s, max %d client)",
"%s: listening on port %d (relay: %s, %s, max %d clients)",
max_clients),
RELAY_PLUGIN_NAME,
server->port,
server->protocol_string,
((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")),
max_clients);
}
else
{
weechat_printf (
NULL,
_("%s: listening on port %d (relay: %s, %s)"),
RELAY_PLUGIN_NAME,
server->port,
server->protocol_string,
((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")));
}
server->hook_fd = weechat_hook_fd (server->sock,
1, 0, 0,
&relay_server_sock_cb,