[PATCH] suggested proxy connect patch

[PATCH] suggested proxy connect patch

am 17.05.2002 17:27:10 von billo

I have a patch which I created to simulate users on slow or asymmetric
connections. This patch adds two configuration settings to change the
speed of upload or download thru a tunnelling (CONNECT) proxy.

It's a bit rough, but I wanted to get a general feel about it before I
do much more work refining it. If people think it's useful, I'll do
whatever work is needed to make it clean enough to include in
mod_proxy. Or somebody else can take the basic idea and do it a
better way; whatever you think is best.

In a nutshell, I replace send and recv in proxy_connect.c to calculate
a delay between reading chunks of data. It's very much an
approximation, it doesn't simulate byte-by-byte throughput.

One big problem I know is that it uses usleep(), which I don't think is
available on win32, and maybe not even all unix variants.

Anyway, here's the patch, I welcome any comments or feedback. It's
off 1.3.22, but I don't think these files have changed much since then.

Thanks,

billo
Intuit, Inc. billo@billo.com bill_odonnell@intuit.com


--- /u/billo/src/apache_1.3.22/src/modules/proxy/mod_proxy.h 2001-10-05 04:19:15.000000000 -0400
+++ ./mod_proxy.h 2002-05-15 18:31:48.201857000 -0400
@@ -224,6 +224,10 @@
char viaopt_set;
size_t recv_buffer_size;
char recv_buffer_size_set;
+ int throttle_up_speed; /* billo dial-up simulator */
+ char throttle_up_set; /* billo dial-up simulator */
+ int throttle_down_speed; /* billo dial-up simulator */
+ char throttle_down_set; /* billo dial-up simulator */
} proxy_server_conf;

struct hdr_entry {

--- /u/billo/src/apache_1.3.22/src/modules/proxy/proxy_connect.c 2001-10-05 04:19:15.000000000 -0400
+++ ./proxy_connect.c 2002-05-15 18:37:24.476203000 -0400
@@ -96,6 +96,46 @@
* FIXME: no check for r->assbackwards, whatever that is.
*/

+static useconds_t sleep_calc(int speed, int len)
+{
+ useconds_t delay;
+ if (speed == 0) {
+ return 0;
+ }
+ delay = 1000000 / (speed / 8);
+
+ delay = delay * len;
+
+ return delay;
+}
+
+static ssize_t proxy_recv(int s, void *buf, size_t len, int flags, int choke, request_rec *r)
+{
+ if (choke > 0) {
+ ssize_t ret = recv(s, buf, len, flags);
+ useconds_t delay = sleep_calc(choke, ret);
+ /* ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: billo proxy recv delay %d", delay); */
+ usleep(delay);
+ return ret;
+ } else {
+ return recv(s, buf, len, flags);
+ }
+}
+
+static ssize_t proxy_send(int s, void *buf, size_t len, int flags, int choke, request_rec *r)
+{
+ /* ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: billo proxy send"); */
+ if (choke > 0) {
+ ssize_t ret = send(s, buf, len, flags);
+ useconds_t delay = sleep_calc(choke, ret);
+ usleep(delay);
+ return ret;
+ } else {
+ return send(s, buf, len, flags);
+ }
+}
+
+
static int
allowed_port(proxy_server_conf *conf, int port)
{
@@ -109,6 +149,7 @@
return 0;
}

+#define CONNECT_BUFFER_SIZE 256

int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
const char *proxyhost, int proxyport)
@@ -119,8 +160,10 @@
const char *host, *err;
char *p;
int port, sock;
- char buffer[HUGE_STRING_LEN];
+ char buffer[CONNECT_BUFFER_SIZE];
int nbytes, i, j;
+ int throttle_up = 0;
+ int throttle_down = 0;
fd_set fds;

void *sconf = r->server->module_config;
@@ -128,6 +171,12 @@
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;

+ if (conf->throttle_up_set) {
+ throttle_up = conf->throttle_up_speed;
+ }
+ if (conf->throttle_down_set) {
+ throttle_down = conf->throttle_down_speed;
+ }
memset(&server, '\0', sizeof(server));
server.sin_family = AF_INET;

@@ -260,10 +309,10 @@
if (i) {
if (FD_ISSET(sock, &fds)) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "sock was set");
- if ((nbytes = recv(sock, buffer, HUGE_STRING_LEN,0)) != 0) {
+ if ((nbytes = proxy_recv(sock, buffer, CONNECT_BUFFER_SIZE, 0, throttle_down, r)) != 0) {
if (nbytes == -1)
break;
- if (send(ap_bfileno(r->connection->client, B_WR), buffer, nbytes,0) == EOF)
+ if (proxy_send(ap_bfileno(r->connection->client, B_WR), buffer, nbytes,0, throttle_down, r) == EOF)
break;
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Wrote %d bytes to client", nbytes);
}
@@ -272,11 +321,11 @@
}
else if (FD_ISSET(ap_bfileno(r->connection->client, B_WR), &fds)) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "client->fd was set");
- if ((nbytes = recv(ap_bfileno(r->connection->client, B_WR), buffer,
- HUGE_STRING_LEN, 0)) != 0) {
+ if ((nbytes = proxy_recv(ap_bfileno(r->connection->client, B_WR), buffer,
+ CONNECT_BUFFER_SIZE, 0, throttle_up, r)) != 0) {
if (nbytes == -1)
break;
- if (send(sock, buffer, nbytes, 0) == EOF)
+ if (proxy_send(sock, buffer, nbytes, 0, throttle_up, r) == EOF)
break;
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Wrote %d bytes to server", nbytes);
}
@@ -294,3 +343,4 @@

return OK;
}
+
--- /u/billo/src/apache_1.3.22/src/modules/proxy/mod_proxy.c 2001-09-24 16:14:27.000000000 -0400
+++ ./mod_proxy.c 2002-05-17 10:45:04.454437000 -0400
@@ -442,6 +507,10 @@
ps->cache.dirlength_set = 0;
ps->cache.cache_completion = DEFAULT_CACHE_COMPLETION;
ps->cache.cache_completion_set = 0;
+ ps->throttle_up_speed = 0; /* default no choke billo 10-may-2002 */
+ ps->throttle_up_set = 0; /* default no choke billo 10-may-2002 */
+ ps->throttle_down_speed = 0; /* default no choke billo 10-may-2002 */
+ ps->throttle_down_set = 0; /* default no choke billo 10-may-2002 */

return ps;
}
@@ -842,6 +917,31 @@
return NULL;
}

+
+static const char *
+ set_throttle_up_speed(cmd_parms *parms, void *dummy, char *arg)
+{
+ proxy_server_conf *psf =
+ ap_get_module_config(parms->server->module_config, &proxy_module);
+ int s = atoi(arg);
+
+ psf->throttle_up_speed = s;
+ psf->throttle_up_set = 1;
+ return NULL;
+}
+
+static const char *
+ set_throttle_down_speed(cmd_parms *parms, void *dummy, char *arg)
+{
+ proxy_server_conf *psf =
+ ap_get_module_config(parms->server->module_config, &proxy_module);
+ int s = atoi(arg);
+
+ psf->throttle_down_speed = s;
+ psf->throttle_down_set = 1;
+ return NULL;
+}
+
static const char*
set_cache_completion(cmd_parms *parms, void *dummy, char *arg)
{
@@ -903,6 +1003,10 @@
"A list of names, hosts or domains to which the proxy will not connect"},
{"ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, TAKE1,
"Receive buffer size for outgoing HTTP and FTP connections in bytes"},
+ {"ProxyConnectThrottleUp", set_throttle_up_speed, NULL, RSRC_CONF, TAKE1,
+ "Reduce throughput of connect proxy (upload direction)"},
+ {"ProxyConnectThrottleDown", set_throttle_down_speed, NULL, RSRC_CONF, TAKE1,
+ "Reduce throughput of connect proxy (download direction)"},
{"NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, ITERATE,
"A list of domains, hosts, or subnets to which the proxy will connect directly"},
{"ProxyDomain", set_proxy_domain, NULL, RSRC_CONF, TAKE1,

Re: [PATCH] suggested proxy connect patch

am 18.05.2002 11:53:52 von Graham Leggett

Bill O'Donnell wrote:

> I have a patch which I created to simulate users on slow or asymmetric
> connections. This patch adds two configuration settings to change the
> speed of upload or download thru a tunnelling (CONNECT) proxy.

This is really useful functionality, however I don't think it's a good
idea to add it to proxy - as it means you can only use it with the
proxy.

A better idea would be to implement it as a filter, which will allow it
to be used anywhere in Apache. I do notice you implemented it in the
CONNECT part of the proxy - was there a reason for this? The CONNECT
part is one of the last bits that never used filters.

Regards,
Graham
--
-----------------------------------------
minfrin@sharp.fm "There's a moon
over Bourbon Street
tonight..."

Re: [PATCH] suggested proxy connect patch

am 19.05.2002 03:23:40 von billo

So, if I added this as a filter, I still *could* use it with proxy,
right?

I did it in the CONNECT part because wanted a generalized byte tunnel
that would throttle down connection speeds for any protocol, HTTP +
SSL usually, but also it could be used for telnet, ssh, whatever. I
also have a dedicated program to do this, but being able to configure
the security (connect) proxy makes the setup process transparent to
the user.

I'll look into filters, and see if I could get them to work with
CONNECT as well.

Thanks for the feedback.

-bill

From: Graham Leggett
Date: Sat, 18 May 2002 11:53:52 +0200

Bill O'Donnell wrote:

> I have a patch which I created to simulate users on slow or asymmetric
> connections. This patch adds two configuration settings to change the
> speed of upload or download thru a tunnelling (CONNECT) proxy.

This is really useful functionality, however I don't think it's a good
idea to add it to proxy - as it means you can only use it with the
proxy.

A better idea would be to implement it as a filter, which will allow it
to be used anywhere in Apache. I do notice you implemented it in the
CONNECT part of the proxy - was there a reason for this? The CONNECT
part is one of the last bits that never used filters.

Regards,
Graham
--
-----------------------------------------
minfrin@sharp.fm "There's a moon
over Bourbon Street
tonight..."

Re: [PATCH] suggested proxy connect patch

am 22.05.2002 20:08:25 von Graham Leggett

Bill O'Donnell wrote:

> So, if I added this as a filter, I still *could* use it with proxy,
> right?

Yes, in FTP, HTTP and HTTPS, but not CONNECT (yet).

> I did it in the CONNECT part because wanted a generalized byte tunnel
> that would throttle down connection speeds for any protocol, HTTP +
> SSL usually, but also it could be used for telnet, ssh, whatever. I
> also have a dedicated program to do this, but being able to configure
> the security (connect) proxy makes the setup process transparent to
> the user.

Keep in mind there is no security on the CONNECT part of the proxy - the
only restriction you can apply is to which port you will allow the
client to connect to.

Other than that, I can see how it would be useful for the other
protocols too.

Regards,
Graham
--
-----------------------------------------
minfrin@sharp.fm "There's a moon
over Bourbon Street
tonight..."