diff -uNr ffproxy-1.5/ChangeLog ffproxy-1.5.1/ChangeLog --- ffproxy-1.5/ChangeLog Fri Aug 8 22:32:15 2003 +++ ffproxy-1.5.1/ChangeLog Sun Aug 17 19:42:46 2003 @@ -1,3 +1,17 @@ +Version 1.5.1 +============= + + * allow transparent operation + (see section TRANSPARENT OPERATION + in ffproxy(8) or ffproxy.quick(7)) + + * allow client to proxy keep alive + connections + + * new configuration option use_keep_alive + + * updated documentation accordingly + Version 1.5 =========== diff -uNr ffproxy-1.5/README ffproxy-1.5.1/README --- ffproxy-1.5/README Fri Aug 8 22:37:58 2003 +++ ffproxy-1.5.1/README Sun Aug 17 20:35:26 2003 @@ -5,6 +5,7 @@ url, and header. Custom header entries can be filtered and added. It can even drop its privileges and chroot(2) to some directory. Logging to syslogd(8) is supported, as is using another auxiliary proxy server. +It is able to serve as a HTTP accelerator (front-end to a HTTP server). IPv6 is fully supported and allows IPv6 HTTP over IPv4 tunneling (and vice versa). diff -uNr ffproxy-1.5/cfg.h ffproxy-1.5.1/cfg.h --- ffproxy-1.5/cfg.h Sat Aug 9 02:02:22 2003 +++ ffproxy-1.5.1/cfg.h Sun Aug 17 19:11:07 2003 @@ -32,6 +32,8 @@ char accelhost[256]; unsigned int accelport; + int kalive; + int nowarn; int first; }; diff -uNr ffproxy-1.5/db.c ffproxy-1.5.1/db.c --- ffproxy-1.5/db.c Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/db.c Sun Aug 17 19:57:52 2003 @@ -3,7 +3,7 @@ * * http://faith.eu.org * - * $Id: db.c,v 1.23 2003/08/09 03:38:04 niklas Exp $ + * $Id: db.c,v 1.23.2.1 2003/08/17 19:57:52 niklas Exp $ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -351,6 +351,12 @@ config.accelusrhost = 1; else config.accelusrhost = 0; + continue; + } else if (strcmp("use_keep_alive", obuf) == 0) { + if (strcmp(abuf, "yes") == 0) + config.kalive = 1; + else + config.kalive = 0; continue; } else if (!config.first) { continue; diff -uNr ffproxy-1.5/ffproxy.8 ffproxy-1.5.1/ffproxy.8 --- ffproxy-1.5/ffproxy.8 Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/ffproxy.8 Sun Aug 17 20:10:22 2003 @@ -1,8 +1,8 @@ -.\" $Id: ffproxy.8,v 1.8 2003/08/09 00:41:31 niklas Exp $ +.\" $Id: ffproxy.8,v 1.8.2.2 2003/08/17 20:10:22 niklas Exp $ .\" Copyright (c) 2002, 2003 Niklas Olmes .\" See COPYING for license (GNU GPL) .\" http://faith.eu.org -.Dd August 9, 2003 +.Dd August 18, 2003 .Dt ffproxy 8 .Sh NAME .Nm ffproxy @@ -82,7 +82,7 @@ and html/ files in .Pa /var/ffproxy/html/ . .It Fl a Ar ip|hostname -Auxiliary forward HTTP server to use (see section ACCELERATOR). +Auxiliary forward HTTP server to use (see section HTTP ACCELERATOR). .It Fl A Ar port Port to use for above. Defaults to 80. .It Fl f Ar configfile @@ -258,6 +258,28 @@ of course). To change this, use `accel_user_host no' in configuration file. ``Host: accel_host:accel_port'' will be used then. +.Sh TRANSPARENT OPERATION +It is possible to redirect all HTTP traffic, that is, +traffic to port 80, to the proxy's listening port. It will +then transparently act as a HTTP proxy, the client not +even knowing it is connecting to a proxy. +.Pp +On OpenBSD one could enable this by +adding a line like +.Bd -literal -offset indent +rdr on rl0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080 +.Ed +.Pp +to +.Pa /etc/pf.conf . +In this example, rl0 is the local interface. All traffic +coming from rl0 directed to port 80 (HTTP standard port) +is sent to 127.0.0.1:8080 where ffproxy is supposed +to be listening. +.Sh KEEP ALIVE +The program supports keep alive on client to proxy connections. +This is used automatically by default and may be disabled +by setting `use_keep_alive no' in the configuration file. .Sh RELOADING CONFIGURATION Send a SIGHUP to the pid of the ffproxy master process to let it reload db/ files, html/ files, *and* configuration file. @@ -326,7 +348,7 @@ Dobrica Pavlinusic provided patches for http accelerator feature .Sh VERSION -This manual documents ffproxy 1.5 (2003-08-09). +This manual documents ffproxy 1.5.1 (2003-08-18). .Pp Send bug reports, comments, suggestions to .Sh AUTHOR diff -uNr ffproxy-1.5/ffproxy.conf.5 ffproxy-1.5.1/ffproxy.conf.5 --- ffproxy-1.5/ffproxy.conf.5 Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/ffproxy.conf.5 Sun Aug 17 19:57:52 2003 @@ -1,8 +1,8 @@ -.\" $Id: ffproxy.conf.5,v 1.9 2003/08/09 12:18:58 niklas Exp $ +.\" $Id: ffproxy.conf.5,v 1.9.2.1 2003/08/17 19:57:52 niklas Exp $ .\" Copyright (c) 2002, 2003 Niklas Olmes .\" See COPYING for license (GNU GPL) .\" http://faith.eu.org -.Dd August 9, 2003 +.Dd August 18, 2003 .Dt ffproxy.conf 5 .Sh NAME .Nm ffproxy.conf @@ -55,6 +55,7 @@ accel_host accel_port accel_user_host +use_keep_alive backlog_size .Ed .Pp @@ -181,13 +182,18 @@ #accel_user_host no #accel_user_host yes +# keep alive on client to proxy connections +# (enabled by default) +#use_keep_alive no +#use_keep_alive yes + # backlog size for accept() # (default: 4) #backlog_size 16 #backlog_size 4 .Ed .Sh VERSION -This manual documents ffproxy 1.5 (2003-08-09). +This manual documents ffproxy 1.5.1 (2003-08-18). .Sh FILES .Pa /etc/ffproxy.conf default configuration file diff -uNr ffproxy-1.5/ffproxy.quick.7 ffproxy-1.5.1/ffproxy.quick.7 --- ffproxy-1.5/ffproxy.quick.7 Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/ffproxy.quick.7 Sun Aug 17 19:57:52 2003 @@ -1,8 +1,8 @@ -.\" $Id: ffproxy.quick.7,v 1.5 2003/08/09 00:15:33 niklas Exp $ +.\" $Id: ffproxy.quick.7,v 1.5.2.1 2003/08/17 19:57:52 niklas Exp $ .\" Copyright (c) 2002, 2003 Niklas Olmes .\" See COPYING for license (GNU GPL) .\" http://faith.eu.org -.Dd August 9, 2003 +.Dd August 18, 2003 .Dt ffproxy.quick 7 .Sh NAME .Nm ffproxy.quick @@ -123,5 +123,23 @@ seems to work, simply shut down the proxy by pressing CTRL-C, set `daemonize yes' in the configuration file and start ffproxy again. +.Sh TRANSPARENT OPERATION +The proxy allows transparent operation, that is, HTTP +traffic is redirect to the proxy which simulates a HTTP +server so that the users don't have to specify a +proxy server. Consider forced usage of a proxy server as well. +To do that, you will have to configure your NAT accordingly. +On OpenBSD you'll want a line like +.Bd -literal -offset indent +rdr on rl0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080 +.Ed +.Pp +in +.Pa /etc/pf.conf . +See your NAT's documentation for details on how to do this. .Sh VERSION -This manual documents ffproxy 1.5 (2003-08-09). +This manual documents ffproxy 1.5.1 (2003-08-18). +.Sh SEE ALSO +.Xr ffproxy 8 , +.Xr ffproxy.conf 5 , +.Xr pf.conf 5 diff -uNr ffproxy-1.5/filter.c ffproxy-1.5.1/filter.c --- ffproxy-1.5/filter.c Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/filter.c Sun Aug 17 19:57:52 2003 @@ -3,7 +3,7 @@ * * http://faith.eu.org * - * $Id: filter.c,v 1.10 2003/08/08 14:10:28 niklas Exp $ + * $Id: filter.c,v 1.10.2.1 2003/08/17 19:57:52 niklas Exp $ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -116,10 +116,14 @@ return 0; } +static const char http_pkalive[] = "Proxy-Connection: keep-alive"; +static const char http_kalive[] = "Connection: keep-alive"; + int filter_remote(struct req * r) { - int i, j; + size_t i; + int j; i = 0; start_over: @@ -159,6 +163,15 @@ skip: i++; + } + if(r->kalive && i - 2 < sizeof(r->header)) { + r->header[i] = (char *) my_alloc(strlen(http_pkalive) + 1); + (void) strcpy(r->header[i], http_pkalive); + r->header[++i] = (char *) my_alloc(strlen(http_kalive) + 1); + (void) strcpy(r->header[i], http_kalive); + r->header[++i] = NULL; + } else if(r->kalive) { + r->kalive = 0; } DEBUG(("filter_remote() => done, request ok")); diff -uNr ffproxy-1.5/http.c ffproxy-1.5.1/http.c --- ffproxy-1.5/http.c Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/http.c Sun Aug 17 19:57:52 2003 @@ -3,7 +3,7 @@ * * http://faith.eu.org * - * $Id: http.c,v 1.7 2003/08/08 22:44:47 niklas Exp $ + * $Id: http.c,v 1.7.2.1 2003/08/17 19:57:52 niklas Exp $ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -63,20 +63,20 @@ DEBUG(("http_url() => got url part (%s)", s)); + i = 0; if (config.accel) { + r->relative = 0; DEBUG(("http_url() => using as accelerator proxy")); DEBUG(("http_url() => accelhost (%s) port %d", config.accelhost, config.accelport)); i = snprintf(r->url, sizeof(r->url), "%s%s:%d", http, config.accelhost, config.accelport); if (i < 1) fatal_n("http_url() => accelhost is too long, can't create r->url"); DEBUG(("http_url() => created url (%s) length (%d)", r->url, i)); + } else if (strncmp(s, http, strlen(http)) != 0) { + r->relative = 1; } else { - if (strncmp(s, http, strlen(http)) != 0) { - r->type = UNKNOWN; - return -1; - } + r->relative = 0; - i = 0; while (i < strlen(http)) { r->url[i] = http[i]; i++, s++; @@ -143,6 +143,9 @@ p = r->url; p += strlen(http); + if(r->relative) + return 0; + i = 0; while ((isalnum(*p) || *p == '-' || *p == '.') && i < sizeof(r->host) - 1) r->host[i++] = tolower(*(p++)); @@ -179,8 +182,68 @@ return 0; } +static const char h_host[] = "Host: "; + +int +http_rel(struct req * r, const char *s) +{ + size_t i; + + i = 0; + if (r->relative && strncmp(s, h_host, strlen(h_host)) == 0) { + r->relative = 0; + + s += strlen(h_host); + while (*s == ' ') + s++; + while ((isalnum(*s) || *s == '-' || *s == '.') && i < sizeof(r->host) - 1) + r->host[i++] = tolower(*(s++)); + r->host[i] = '\0'; + if (i >= sizeof(r->host) || (*s != ':' && *s != '\0')) { + DEBUG(("http_rel() => invalid host header (%s)", r->host)); + r->host[0] = '\0'; + return 1; + } + DEBUG(("http_rel() => extracted host (%s)", r->host)); + if (*s == ':') { + i = 0; + r->port = 0; + s++; + while (isdigit(*s) && i++ < 6) + r->port = r->port * 10 + *(s++) - '0'; + if (i > 5 && i == 0) { + DEBUG(("http_rel() => bad port number")); + r->port = 0; + return 1; + } + DEBUG(("http_rel() => extracted port %d", r->port)); + } else { + r->port = 80; + } + if (strlen(r->url) + strlen(http) + strlen(r->host) + 7 >= sizeof(r->url)) { + DEBUG(("http_rel() => URL will get too long")); + return 1; + } else { + char o_url[sizeof(r->url)]; + (void) strncpy(o_url, r->url, sizeof(o_url) - 1); + o_url[sizeof(o_url) - 1] = '\0'; + if (r->port == 80) + (void) snprintf(r->url, sizeof(r->url), "http://%s%s", r->host, o_url); + else + (void) snprintf(r->url, sizeof(r->url), "http://%s:%d%s", r->host, r->port, o_url); + DEBUG(("http_rel() => extracted URL (%s)", r->url)); + } + } + + return 0; +} + static const char http_clen[] = "Content-Length: "; +static const char http_pkalive[] = "Proxy-Connection: keep-alive"; +static const char http_kalive[] = "Connection: keep-alive"; +#ifdef TSTAMP static const char http_tstamp[] = "Last-Modified: "; +#endif int http_parse(struct req * r, const char *s) @@ -211,6 +274,7 @@ } DEBUG(("http_parse() => clen: %ld bytes", r->clen)); return 0; +#ifdef TSTAMP } else if (strncasecmp(http_tstamp, s, strlen(http_tstamp)) == 0) { DEBUG(("http_parse() => found tstamp header (%s)", s)); @@ -231,6 +295,12 @@ } DEBUG(("http_parse() => tstamp: extracted (%s)", r->tstamp)); return 0; +#endif + } else if (strncasecmp(http_pkalive, s, strlen(http_pkalive)) == 0 + || strncasecmp(http_kalive, s, strlen(http_kalive)) == 0) { + DEBUG(("http_parse() => keep alive header found")); + r->kalive = 1; + return 1; } return 1; } diff -uNr ffproxy-1.5/http.h ffproxy-1.5.1/http.h --- ffproxy-1.5/http.h Thu Jul 25 12:07:39 2002 +++ ffproxy-1.5.1/http.h Sun Aug 17 03:13:29 2003 @@ -1,2 +1,3 @@ int http_url(struct req *, const char *); +int http_rel(struct req *, const char *); int http_parse(struct req *, const char *); diff -uNr ffproxy-1.5/main.c ffproxy-1.5.1/main.c --- ffproxy-1.5/main.c Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/main.c Sun Aug 17 19:57:52 2003 @@ -3,7 +3,7 @@ * * http://faith.eu.org * - * $Id: main.c,v 1.26 2003/08/09 12:30:50 niklas Exp $ + * $Id: main.c,v 1.26.2.2 2003/08/17 19:57:52 niklas Exp $ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -60,8 +60,8 @@ static void usage(void); static void drop_privileges(void); -static const char version[] = "1.5"; -static const char rcsid[] = "$Id: main.c,v 1.26 2003/08/09 12:30:50 niklas Exp $"; +static const char version[] = "1.5.1"; +static const char rcsid[] = "$Id: main.c,v 1.26.2.2 2003/08/17 19:57:52 niklas Exp $"; char loop_header[100]; struct cfg config; @@ -102,6 +102,7 @@ config.accelusrhost = 1; *config.accelhost = '\0'; config.accelport = 80; + config.kalive = 1; config.first = 1; while ((c = getopt(argc, argv, "vdbBc:C:p:x:X:l:u:g:r:D:F:f:s4a:A:h")) != -1) { @@ -241,6 +242,7 @@ setup_log_master(); info("started, initializing"); load_databases(); + (void) resolve("localhost"); drop_privileges(); if (config.daemon) { diff -uNr ffproxy-1.5/req.h ffproxy-1.5.1/req.h --- ffproxy-1.5/req.h Thu Aug 7 01:54:17 2003 +++ ffproxy-1.5.1/req.h Sun Aug 17 04:46:50 2003 @@ -12,6 +12,8 @@ unsigned int port; int type; + int relative; + int kalive; int vmajor; int vminor; diff -uNr ffproxy-1.5/request.c ffproxy-1.5.1/request.c --- ffproxy-1.5/request.c Sat Aug 9 15:13:01 2003 +++ ffproxy-1.5.1/request.c Sun Aug 17 19:57:52 2003 @@ -3,7 +3,7 @@ * * http://faith.eu.org * - * $Id: request.c,v 1.25 2003/08/08 22:44:47 niklas Exp $ + * $Id: request.c,v 1.25.2.1 2003/08/17 19:57:52 niklas Exp $ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -50,6 +50,7 @@ struct req r; char buf[2048]; +keep_alive: (void) memset(&r, 0, sizeof(r)); r.cl = clinfo; @@ -104,11 +105,25 @@ default: i = 0; } - if (i != 0) + if (i != 0) { err_msg(cl, &r, i); + r.kalive = 0; + } + + i = 0; + while (r.header[i] != NULL) + free(r.header[i++]); + r.header[0] = NULL; + + if (config.kalive && r.kalive && r.clen > 0L) + goto keep_alive; } } else { - info("invalid request from (%s) [%s]", clinfo->name, clinfo->ip); + if (*buf == '\0') { + ; + } else { + info("invalid request from (%s) [%s]", clinfo->name, clinfo->ip); + } } } @@ -133,6 +148,11 @@ DEBUG(("read_header() => entry %d (%s)", i, r->header[i])); i++; + + if (r->relative && http_rel(r, p) != 0) { + r->header[i] = NULL; + return 1; + } } r->header[i] = NULL; diff -uNr ffproxy-1.5/sample.config ffproxy-1.5.1/sample.config --- ffproxy-1.5/sample.config Sat Aug 9 12:14:52 2003 +++ ffproxy-1.5.1/sample.config Sun Aug 17 19:53:25 2003 @@ -1,6 +1,6 @@ # # sample configuration file for ffproxy(8) -# (version 1.5) +# (version 1.5.1) # # lines starting with '#' are comments @@ -115,6 +115,11 @@ # (default: yes) #accel_user_host no #accel_user_host yes + +# keep alive on client to proxy connections +# (enabled by default) +#use_keep_alive no +#use_keep_alive yes # backlog size for accept() # (default: 4)