mirror of
https://github.com/yrutschle/sslh.git
synced 2026-10-22 18:12:10 +03:00
add setting for maximum connection per protocol
This commit is contained in:
1 parent
28ea73301e
commit
feaf528a60
12 files changed
+85
-7
No files matched your search
@@ -595,6 +595,37 @@ void dump_connection(struct connection *cnx)
|
||||
}
|
||||
|
||||
|
||||
/* *cnx must have its proto field probed already.
|
||||
* If required, increment the connection count for this protocol.
|
||||
* Returns 1 if connection count is exceeded, 0 otherwise */
|
||||
int inc_connections(struct connection* cnx)
|
||||
{
|
||||
if (cnx->proto->max_connections_is_present) {
|
||||
cnx->proto->num_connections++;
|
||||
print_message(msg_connections, "Proto %s +1: %d/%d cnx\n",
|
||||
cnx->proto->name,
|
||||
cnx->proto->num_connections,
|
||||
cnx->proto->max_connections);
|
||||
if (cnx->proto->num_connections > cnx->proto->max_connections) {
|
||||
print_message(msg_connections_error, "%s: too many connections, dropping", cnx->proto->name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dec_connections(struct connection* cnx)
|
||||
{
|
||||
if (cnx->proto) {
|
||||
cnx->proto->num_connections--;
|
||||
print_message(msg_connections, "Proto %s -1: %d/%d cnx\n",
|
||||
cnx->proto->name,
|
||||
cnx->proto->num_connections,
|
||||
cnx->proto->max_connections);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* moves data from one fd to other
|
||||
*
|
||||
|
||||
@@ -174,6 +174,8 @@ void drop_privileges(const char* user_name, const char* chroot_path);
|
||||
void set_capabilities(int cap_net_admin);
|
||||
void write_pid_file(const char* pidfile);
|
||||
void dump_connection(struct connection *cnx);
|
||||
int inc_connections(struct connection* cnx);
|
||||
void dec_connections(struct connection* cnx);
|
||||
int resolve_split_name(struct addrinfo **out, char* hostname, char* port);
|
||||
|
||||
int start_listen_sockets(struct listen_endpoint *sockfd[]);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 6 11:44:59 2025.
|
||||
* on Wed Jul 16 17:59:23 2025.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2024 Yves Rutschle
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 6 11:44:59 2025.
|
||||
* on Wed Jul 16 17:59:23 2025.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2024 Yves Rutschle
|
||||
|
||||
+5
-1
@@ -70,7 +70,11 @@ listen:
|
||||
# keepalive: Should TCP keepalive be on or off for that
|
||||
# connection (default is off)
|
||||
# fork: Should a new process be forked for this protocol?
|
||||
# (only useful for sslh-select)
|
||||
# (only useful for sslh-select and sslh-ev)
|
||||
# max_connections: further connections for this protocol
|
||||
# will be rejected once the limit is reached. Does not
|
||||
# work when fork is used (either in sslh-fork or if the
|
||||
# previous option is set).
|
||||
# tfo_ok: Set to true if the server supports TCP FAST OPEN
|
||||
# resolve_on_forward: Set to true if server address should be resolved on
|
||||
# (every) newly incoming connection (again)
|
||||
|
||||
@@ -49,6 +49,8 @@ int tidy_connection(struct connection *cnx, struct loop_info* fd_info)
|
||||
if (gap_remove_ptr(fd_info->probing_list, cnx, fd_info->num_probing) != -1)
|
||||
fd_info->num_probing--;
|
||||
|
||||
dec_connections(cnx);
|
||||
|
||||
collection_remove_cnx(fd_info->collection, cnx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+23
-2
@@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 6 11:44:58 2025.
|
||||
* on Wed Jul 16 17:59:23 2025.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2024 Yves Rutschle
|
||||
@@ -500,7 +500,7 @@ struct arg_file* sslhcfg_conffile;
|
||||
struct arg_str* sslhcfg_anyprot;
|
||||
struct arg_end* sslhcfg_end;
|
||||
|
||||
|
||||
|
||||
static struct config_desc table_sslhcfg_protocols[] = {
|
||||
|
||||
|
||||
@@ -712,6 +712,22 @@ static struct config_desc table_sslhcfg_protocols[] = {
|
||||
/* default_val*/ .default_val.def_bool = 0
|
||||
},
|
||||
|
||||
{
|
||||
/* name */ "max_connections",
|
||||
/* type */ CFG_INT,
|
||||
/* sub_group*/ NULL,
|
||||
/* arg_cl */ NULL,
|
||||
/* base_addr */ NULL,
|
||||
/* offset */ offsetof(struct sslhcfg_protocols_item, max_connections),
|
||||
/* offset_len */ 0,
|
||||
/* offset_present */ offsetof(struct sslhcfg_protocols_item, max_connections_is_present),
|
||||
/* size */ sizeof(int),
|
||||
/* array_type */ -1,
|
||||
/* mandatory */ 0,
|
||||
/* optional */ 1,
|
||||
/* default_val*/ .default_val.def_int = 0
|
||||
},
|
||||
|
||||
{
|
||||
/* name */ "sni_hostnames",
|
||||
/* type */ CFG_ARRAY,
|
||||
@@ -2421,6 +2437,11 @@ static void sslhcfg_protocols_fprint(
|
||||
fprintf(out, "keepalive: %d", sslhcfg_protocols->keepalive);
|
||||
fprintf(out, "\n");
|
||||
indent(out, depth);
|
||||
fprintf(out, "max_connections: %d", sslhcfg_protocols->max_connections);
|
||||
if (! sslhcfg_protocols->max_connections_is_present)
|
||||
fprintf(out, " <unset>");
|
||||
fprintf(out, "\n");
|
||||
indent(out, depth);
|
||||
fprintf(out, "sni_hostnames [%zu]:\n", sslhcfg_protocols->sni_hostnames_len);
|
||||
for (i = 0; i < sslhcfg_protocols->sni_hostnames_len; i++) {
|
||||
indent(out, depth+1);
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 6 11:44:58 2025.
|
||||
* on Wed Jul 16 17:59:23 2025.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2024 Yves Rutschle
|
||||
@@ -63,6 +63,8 @@ struct sslhcfg_protocols_item {
|
||||
int resolve_on_forward;
|
||||
int log_level;
|
||||
int keepalive;
|
||||
int max_connections_is_present;
|
||||
int max_connections;
|
||||
size_t sni_hostnames_len;
|
||||
char** sni_hostnames;
|
||||
size_t alpn_protocols_len;
|
||||
@@ -76,6 +78,7 @@ struct sslhcfg_protocols_item {
|
||||
T_PROBE* probe;
|
||||
struct addrinfo* saddr;
|
||||
void* data;
|
||||
unsigned int num_connections;
|
||||
dl_list timeouts;
|
||||
};
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ config: {
|
||||
description: "Set to true if server address should be resolved on (every) newly incoming connection (again)" },
|
||||
{ name: "log_level"; type: "int"; default: 1 },
|
||||
{ name: "keepalive"; type: "bool"; default: false },
|
||||
{ name: "max_connections"; type: "int"; optional: true },
|
||||
{ name: "sni_hostnames",
|
||||
type: "array",
|
||||
element_type: "string"
|
||||
@@ -142,6 +143,7 @@ config: {
|
||||
{ name: "probe"; type: "runtime"; c_type: "T_PROBE*" },
|
||||
{ name: "saddr"; type: "runtime"; c_type: "struct addrinfo*" },
|
||||
{ name: "data"; type: "runtime"; c_type: "void*" },
|
||||
{ name: "num_connections"; type: "runtime"; c_type: "unsigned int" },
|
||||
{ name: "timeouts"; type: "runtime"; c_type: "dl_list" }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -276,6 +276,11 @@ void probing_read_process(struct connection* cnx,
|
||||
remove_probing_cnx(fd_info, cnx);
|
||||
cnx->state = ST_SHOVELING;
|
||||
|
||||
if (inc_connections(cnx)) {
|
||||
tidy_connection(cnx, fd_info);
|
||||
return;
|
||||
}
|
||||
|
||||
/* libwrap check if required for this protocol */
|
||||
if (cnx->proto->service &&
|
||||
check_access_rights(cnx->q[0].fd, cnx->proto->service)) {
|
||||
|
||||
@@ -43,7 +43,8 @@ listen:
|
||||
|
||||
protocols:
|
||||
(
|
||||
{ name: "ssh"; host: "localhost"; port: "9000"; fork: true; transparent: true; resolve_on_forward: true; },
|
||||
{ name: "ssh"; host: "localhost"; port: "9000"; fork: true; transparent: true; resolve_on_forward: true;
|
||||
max_connections: 1; },
|
||||
{ name: "socks5"; host: "localhost"; port: "9001"; },
|
||||
{ name: "http"; host: "localhost"; port: "80"; proxyprotocol: 2; },
|
||||
{ name: "tinc"; host: "localhost"; port: "9003"; },
|
||||
@@ -52,6 +53,7 @@ protocols:
|
||||
{ name: "adb"; host: "localhost"; port: "9010"; },
|
||||
{ name: "syslog"; host: "localhost"; port: "9013"; },
|
||||
{ name: "regex"; host: "ip4-localhost"; is_udp: true; port: "9020";
|
||||
max_connections: 1;
|
||||
udp_timeout: 30;
|
||||
regex_patterns: [ "^foo" ];
|
||||
resolve_on_forward: true;
|
||||
@@ -72,6 +74,7 @@ protocols:
|
||||
{ name: "tls"; host: "localhost"; port: "9023"; alpn_protocols: [ "alpn3" ]; },
|
||||
{ name: "tls"; host: "localhost"; port: "9024"; sni_hostnames: [ "sni3" ]; },
|
||||
{ name: "tls"; host: "localhost"; port: "9025"; },
|
||||
{ name: "anyprot"; host: "ip4-localhost"; is_udp: true; port: "9999"; },
|
||||
{ name: "anyprot"; host: "localhost"; port: "9099"; }
|
||||
);
|
||||
|
||||
|
||||
@@ -302,6 +302,11 @@ struct connection* udp_c2s_forward(int sockfd, struct loop_info* fd_info)
|
||||
cnx->addrlen = addrlen;
|
||||
cnx->local_endpoint = sockfd;
|
||||
|
||||
if (inc_connections(cnx)) {
|
||||
tidy_connection(cnx, fd_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = new_source(fd_info->hash_sources, cnx);
|
||||
if (res == -1) {
|
||||
print_message(msg_connections_error, "Out of hash space for new incoming UDP connection -- increase udp_max_connections");
|
||||
|
||||
Reference in new issue
Block a user