Index: src/cache_cf.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/cache_cf.c,v retrieving revision 1.465 diff -u -r1.465 cache_cf.c --- src/cache_cf.c 25 Feb 2007 11:09:18 -0000 1.465 +++ src/cache_cf.c 14 Mar 2007 01:40:14 -0000 @@ -2721,6 +2721,8 @@ s->name = xstrdup(token + 5); } else if (strcmp(token, "transparent") == 0) { s->transparent = 1; + } else if (strncmp(token, "tport=", 6) == 0) { + s->tport = xatos(token + 6); } else if (strcmp(token, "vhost") == 0) { s->vhost = 1; s->accel = 1; Index: src/cf.data.pre =================================================================== RCS file: /server/cvs-server/squid/squid/src/cf.data.pre,v retrieving revision 1.385 diff -u -r1.385 cf.data.pre --- src/cf.data.pre 25 Feb 2007 11:09:18 -0000 1.385 +++ src/cf.data.pre 14 Mar 2007 01:40:20 -0000 @@ -87,6 +87,12 @@ transparent Support for transparent interception of outgoing requests without browser settings + tport= Port to "tunnel" non-http transparently + intercepted requests to. + - Depends on the "transparent" option being set + - This port needs to be in an ACL to allow + CONNECT requests to go to this port + accel Accelerator mode. Also needs at least one of vhost/vport/defaultsite. Index: src/client_side.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/client_side.c,v retrieving revision 1.714 diff -u -r1.714 client_side.c --- src/client_side.c 12 Mar 2007 21:56:55 -0000 1.714 +++ src/client_side.c 14 Mar 2007 01:40:37 -0000 @@ -3415,8 +3415,32 @@ /* Parse the request line */ ret = httpMsgParseRequestLine(hmsg); - if (ret == -1) - return parseHttpRequestAbort(conn, "error:invalid-request"); + if (ret == -1) { + /* If this is a transparent request that has been natted, try converting + it to a CONNECT request if configured to do so */ + if(conn->port->transparent && conn->port->tport && clientNatLookup(conn) == 0) { + conn->transparent = 1; + + /* Create a dummy URL for the connect request */ + snprintf(url,MAX_URL-1,"%s:%hu",inet_ntoa(conn->me.sin_addr),conn->port->tport); + + http = cbdataAlloc(clientHttpRequest); + http->conn = conn; + http->start = current_time; + http->req_sz = conn->in.offset; + http->uri = xstrdup(url); + http->range_iter.boundary = StringNull; + httpBuildVersion(&http->http_ver, 1, 0); + dlinkAdd(http, &http->active, &ClientActiveRequests); + + *method_p = METHOD_CONNECT; + *status = 0; + + return http; + } else { + return parseHttpRequestAbort(conn, "error:invalid-request"); + } + } if (ret == 0) { debug(33, 5) ("Incomplete request, waiting for end of request line\n"); *status = 0; Index: src/ssl.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/ssl.c,v retrieving revision 1.136 diff -u -r1.136 ssl.c --- src/ssl.c 2 Feb 2007 12:22:16 -0000 1.136 +++ src/ssl.c 14 Mar 2007 01:40:38 -0000 @@ -34,6 +34,9 @@ */ #include "squid.h" +#if LINUX_TPROXY +#include +#endif typedef struct { char *url; @@ -52,6 +55,7 @@ delay_id delay_id; #endif int connected; + int transparent; } SslStateData; static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n"; @@ -392,8 +396,10 @@ SslStateData *sslState = data; debug(26, 3) ("sslConnected: FD %d sslState=%p\n", fd, sslState); *sslState->status_ptr = HTTP_OK; - xstrncpy(sslState->server.buf, conn_established, SQUID_TCP_SO_RCVBUF); - sslState->server.len = strlen(conn_established); + if (!(sslState->transparent)) { + xstrncpy(sslState->server.buf, conn_established, SQUID_TCP_SO_RCVBUF); + sslState->server.len = strlen(conn_established); + } sslSetSelect(sslState); } @@ -539,6 +545,9 @@ sslState->delay_id = delayClient(http); delayRegisterDelayIdPtr(&sslState->delay_id); #endif + sslState->transparent = http->conn->transparent; + if (http->conn->transparent) + http->conn->in.offset += http->req_sz; sslState->url = xstrdup(url); sslState->request = requestLink(request); sslState->size_ptr = size_ptr; @@ -567,6 +576,33 @@ Config.Timeout.lifetime, sslTimeout, sslState); +#if LINUX_TPROXY + if(http->conn->port->tproxy) { + struct in_tproxy itp; + + itp.v.addr.faddr.s_addr = http->conn->peer.sin_addr.s_addr; + itp.v.addr.fport = 0; + + /* If these syscalls fail then we just fallback to connecting + * normally by simply ignoring the errors... + */ + itp.op = TPROXY_ASSIGN; + if (setsockopt(sslState->server.fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { + debug(20, 1) ("tproxy ip=%s,0x%x,port=%d ERROR ASSIGN\n", + inet_ntoa(itp.v.addr.faddr), + itp.v.addr.faddr.s_addr, + itp.v.addr.fport); + } else { + itp.op = TPROXY_FLAGS; + itp.v.flags = ITP_CONNECT; + if (setsockopt(sslState->server.fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { + debug(20, 1) ("tproxy ip=%x,port=%d ERROR CONNECT\n", + itp.v.addr.faddr.s_addr, + itp.v.addr.fport); + } + } + } +#endif sslSetSelect(sslState); peerSelect(request, NULL, Index: src/structs.h =================================================================== RCS file: /server/cvs-server/squid/squid/src/structs.h,v retrieving revision 1.511 diff -u -r1.511 structs.h --- src/structs.h 27 Feb 2007 01:06:12 -0000 1.511 +++ src/structs.h 14 Mar 2007 01:40:40 -0000 @@ -364,6 +364,7 @@ char *defaultsite; /* default web site */ char *urlgroup; /* default urlgroup */ unsigned int transparent; /* transparent proxy */ + unsigned short tport; /* transparent tunnel port */ unsigned int accel; /* HTTP accelerator */ unsigned int vhost; /* uses host header */ unsigned int vport; /* virtual port support */