diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2016-02-08 21:14:48 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2016-02-08 21:14:48 +0100 |
commit | 45a1174000c23d0bfce5479835a831845ea951f3 (patch) | |
tree | d892b21359b6e4e5b88ecff36316b4eae7b6fef5 /src/plugins | |
parent | c9a8f23cc78546412bc645d68b344d867ee85bc6 (diff) | |
download | weechat-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/plugins')
-rw-r--r-- | src/plugins/relay/relay-client.c | 30 | ||||
-rw-r--r-- | src/plugins/relay/relay-client.h | 2 | ||||
-rw-r--r-- | src/plugins/relay/relay-config.c | 4 | ||||
-rw-r--r-- | src/plugins/relay/relay-server.c | 64 |
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, |