summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2016-02-08 21:14:48 +0100
committerSébastien Helleu <flashcode@flashtux.org>2016-02-08 21:14:48 +0100
commit45a1174000c23d0bfce5479835a831845ea951f3 (patch)
treed892b21359b6e4e5b88ecff36316b4eae7b6fef5 /src
parentc9a8f23cc78546412bc645d68b344d867ee85bc6 (diff)
downloadweechat-45a1174000c23d0bfce5479835a831845ea951f3.zip
relay: fix the max number of clients connected on a port, allow value 0 for "no limit" (closes #669)
Diffstat (limited to 'src')
-rw-r--r--src/plugins/relay/relay-client.c30
-rw-r--r--src/plugins/relay/relay-client.h2
-rw-r--r--src/plugins/relay/relay-config.c4
-rw-r--r--src/plugins/relay/relay-server.c64
4 files changed, 86 insertions, 14 deletions
diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c
index 28aea18d5..76d66d263 100644
--- a/src/plugins/relay/relay-client.c
+++ b/src/plugins/relay/relay-client.c
@@ -162,6 +162,31 @@ relay_client_status_search (const char *name)
}
/*
+ * 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);
diff --git a/src/plugins/relay/relay-client.h b/src/plugins/relay/relay-client.h
index 670c001d0..89f3166cd 100644
--- a/src/plugins/relay/relay-client.h
+++ b/src/plugins/relay/relay-client.h
@@ -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,
diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c
index ec1ec0474..6d12a24d4 100644
--- a/src/plugins/relay/relay-config.c
+++ b/src/plugins/relay/relay-config.c
@@ -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,
diff --git a/src/plugins/relay/relay-server.c b/src/plugins/relay/relay-server.c
index 56fd8da12..c454a6250 100644
--- a/src/plugins/relay/relay-server.c
+++ b/src/plugins/relay/relay-server.c
@@ -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,