---
src/openvpn/init.c | 3 ++-
src/openvpn/options.c | 9 +++++++++
src/openvpn/options.h | 1 +
src/openvpn/ps.c | 54 +++++++++++++++++++++++++++++++++++++++++----------
src/openvpn/ps.h | 3 ++-
5 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 56bdbe3..5745556 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -576,7 +576,8 @@ init_port_share (struct context *c)
port_share = port_share_open (c->options.port_share_host,
c->options.port_share_port,
MAX_RW_SIZE_LINK (&c->c2.frame),
- c->options.port_share_journal_dir);
+ c->options.port_share_journal_dir,
+
c->options.port_share_max_concurrent_connections);
if (port_share == NULL)
msg (M_FATAL, "Fatal error: Port sharing failed");
}
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 79f861b..0d81479 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -480,6 +480,7 @@ static const char usage_message[] =
"--port-share host port [dir] : When run in TCP mode, proxy incoming HTTPS\n"
" sessions to a web server at host:port. dir specifies
an\n"
" optional directory to write origin IP:port data.\n"
+ "--port-share-max N : Max number of port-share concurrent connections\n"
#endif
#endif
"\n"
@@ -878,6 +879,9 @@ init_options (struct options *o, const bool init_gc)
}
#endif /* WIN32 */
#endif /* P2MP_SERVER */
+#if PORT_SHARE
+ o->port_share_max_concurrent_connections = 512;
+#endif
o->allow_recursive_routing = false;
}
@@ -5892,6 +5896,11 @@ add_option (struct options *options,
options->port_share_port = port;
options->port_share_journal_dir = p[3];
}
+ else if (streq (p[0], "port-share-max") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->port_share_max_concurrent_connections = atoi (p[1]);
+ }
#endif
else if (streq (p[0], "client-to-client"))
{
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index e4235e9..c9b6dd8 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -454,6 +454,7 @@ struct options
char *port_share_host;
int port_share_port;
const char *port_share_journal_dir;
+ int port_share_max_concurrent_connections;
#endif
#endif
diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index cd96257..59ce7f3 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -78,6 +78,15 @@ struct proxy_connection {
char *jfn;
};
+/*
+ * Keep track of concurrent connections, and enforce
+ * a maximum limit.
+ */
+struct proxy_limits {
+ int half_connections;
+ int max_half_connections;
+};
+
#if 0
static const char *
headc (const struct buffer *buf)
@@ -285,9 +294,10 @@ proxy_entry_mark_for_close (struct proxy_connection *pc,
struct event_set *es)
* Run through the proxy entry list and delete all entries marked
* for close.
*/
-static void
+static int
proxy_list_housekeeping (struct proxy_connection **list)
{
+ int count = 0;
if (list)
{
struct proxy_connection *prev = NULL;
@@ -305,10 +315,14 @@ proxy_list_housekeeping (struct proxy_connection **list)
*list = next;
}
else
- prev = pc;
+ {
+ ++count;
+ prev = pc;
+ }
pc = next;
}
}
+ return count;
}
/*
@@ -407,7 +421,8 @@ proxy_entry_new (struct proxy_connection **list,
const int server_port,
const socket_descriptor_t sd_client,
struct buffer *initial_data,
- const char *journal_dir)
+ const char *journal_dir,
+ struct proxy_limits *limits)
{
struct openvpn_sockaddr osaddr;
socket_descriptor_t sd_server;
@@ -415,6 +430,15 @@ proxy_entry_new (struct proxy_connection **list,
struct proxy_connection *pc;
struct proxy_connection *cp;
+ /* check concurrent connections limit */
+ if (limits->half_connections >= limits->max_half_connections)
+ {
+ msg (M_WARN, "PORT SHARE PROXY: concurrent connections limit (%d/%d) has
been reached",
+ limits->half_connections / 2,
+ limits->max_half_connections / 2);
+ return false;
+ }
+
/* connect to port share server */
sock_addr_set (&osaddr, server_addr, server_port);
if ((sd_server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
@@ -469,6 +493,7 @@ proxy_entry_new (struct proxy_connection **list,
proxy_connection_io_requeue (pc, EVENT_READ, es);
proxy_connection_io_requeue (cp, EVENT_READ|EVENT_WRITE, es);
+ ++limits->half_connections;
return true;
}
@@ -485,7 +510,8 @@ control_message_from_parent (const socket_descriptor_t
sd_control,
const in_addr_t server_addr,
const int server_port,
const int max_initial_buf,
- const char *journal_dir)
+ const char *journal_dir,
+ struct proxy_limits *limits)
{
/* this buffer needs to be large enough to handle the largest buffer
that might be returned by the link_socket_read call in
read_incoming_link. */
@@ -542,7 +568,8 @@ control_message_from_parent (const socket_descriptor_t
sd_control,
server_port,
received_fd,
&buf,
- journal_dir))
+ journal_dir,
+ limits))
{
CLEAR (buf); /* we gave the buffer to proxy_entry_new */
}
@@ -720,7 +747,8 @@ port_share_proxy (const in_addr_t hostaddr,
const int port,
const socket_descriptor_t sd_control,
const int max_initial_buf,
- const char *journal_dir)
+ const char *journal_dir,
+ struct proxy_limits *limits)
{
if (send_control (sd_control, RESPONSE_INIT_SUCCEEDED) >= 0)
{
@@ -754,7 +782,7 @@ port_share_proxy (const in_addr_t hostaddr,
const struct event_set_return *e = &esr[i];
if (e->arg == sd_control_marker)
{
- if (!control_message_from_parent (sd_control, &list, es,
hostaddr, port, max_initial_buf, journal_dir))
+ if (!control_message_from_parent (sd_control, &list, es,
hostaddr, port, max_initial_buf, journal_dir, limits))
goto done;
}
else
@@ -771,7 +799,7 @@ port_share_proxy (const in_addr_t hostaddr,
}
if (current > last_housekeeping)
{
- proxy_list_housekeeping (&list);
+ limits->half_connections = proxy_list_housekeeping (&list);
last_housekeeping = current;
}
}
@@ -791,12 +819,18 @@ struct port_share *
port_share_open (const char *host,
const int port,
const int max_initial_buf,
- const char *journal_dir)
+ const char *journal_dir,
+ const int max_concurrent_connections)
{
pid_t pid;
socket_descriptor_t fd[2];
in_addr_t hostaddr;
struct port_share *ps;
+ struct proxy_limits limits;
+
+ /* concurrent connection limits */
+ limits.half_connections = 0;
+ limits.max_half_connections = max_concurrent_connections * 2;
ALLOC_OBJ_CLEAR (ps, struct port_share);
ps->foreground_fd = -1;
@@ -881,7 +915,7 @@ port_share_open (const char *host,
prng_init (NULL, 0);
/* execute the event loop */
- port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir);
+ port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir,
&limits);
openvpn_close_socket (fd[1]);
diff --git a/src/openvpn/ps.h b/src/openvpn/ps.h
index 62af8b5..0c913bf 100644
--- a/src/openvpn/ps.h
+++ b/src/openvpn/ps.h
@@ -46,7 +46,8 @@ extern struct port_share *port_share;
struct port_share *port_share_open (const char *host,
const int port,
const int max_initial_buf,
- const char *journal_dir);
+ const char *journal_dir,
+ const int max_concurrent_connections);
void port_share_close (struct port_share *ps);
void port_share_abort (struct port_share *ps);
--
2.11.0
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel