--- 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 Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel