Hi Henrik, squid hackers, I've updated the patch to HEAD (couldn't test due to missing headers from CVS snapshot tarball, DelayPools.h or something).
I have added support back for server persistent connections. Is this code useful to you? How will you need to access records in the pconn hash table? Can you describe in terms of what types of lookups you need to do eg: lookup with (svr_ip, svr_port, client_ip) then fallback to (svr_ip, svr_port) ? I would like to further hack pconn code to key on the binary structures to get a little more memory efficiency, or at least use a better string hashing function. The 2.5 patch has all the same features and is attached because that is fully tested. -- // Gianni Tedesco (gianni at scaramanga dot co dot uk) lynx --source www.scaramanga.co.uk/gianni-at-ecsc.asc | gpg --import 8646BE7D: 6D9F 2287 870E A2C9 8F60 3A3C 91B5 7669 8646 BE7D
diff -ur --exclude configure squid-2.5.STABLE1.orig/acconfig.h squid-2.5.STABLE1/acconfig.h
--- squid-2.5.STABLE1.orig/acconfig.h Mon Jul 1 09:55:11 2002
+++ squid-2.5.STABLE1/acconfig.h Mon Mar 10 16:54:46 2003
@@ -331,6 +331,11 @@
*/
#undef LINUX_NETFILTER
+/*
+ * Enable real Transparent Proxy support for Netfilter TPROXY.
+ */
+#undef LINUX_TPROXY
+
/*
* Do we have unix sockets? (required for the winbind ntlm helper
*/
diff -ur --exclude configure squid-2.5.STABLE1.orig/configure.in squid-2.5.STABLE1/configure.in
--- squid-2.5.STABLE1.orig/configure.in Tue Sep 24 21:00:03 2002
+++ squid-2.5.STABLE1/configure.in Mon Mar 10 16:07:42 2003
@@ -746,6 +746,17 @@
fi
])
+dnl Enable Linux transparent proxy support
+AC_ARG_ENABLE(linux-tproxy,
+[ --enable-linux-tproxy
+ Enable real Transparent Proxy support for Netfilter TPROXY.],
+[ if test "$enableval" = "yes" ; then
+ echo "Linux Netfilter/TPROXY enabled"
+ AC_DEFINE(LINUX_TPROXY)
+ LINUX_TPROXY="yes"
+ fi
+])
+
AM_CONDITIONAL(MAKE_LEAKFINDER, false)
dnl Enable Leak Finding Functions
AC_ARG_ENABLE(leakfinder,
@@ -1153,6 +1164,7 @@
libc.h \
limits.h \
linux/netfilter_ipv4.h \
+ linux/netfilter_ipv4/ip_tproxy.h \
malloc.h \
math.h \
memory.h \
@@ -1764,6 +1776,27 @@
sleep 10
fi
+dnl Linux Netfilter/TPROXY support requires some specific header files
+dnl Shamelessly copied from shamelessly copied from above
+if test "$LINUX_TPROXY" ; then
+ AC_MSG_CHECKING(if TPROXY header files are installed)
+ # hold on to your hats...
+ if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes"; then
+ LINUX_TPROXY="yes"
+ AC_DEFINE(LINUX_TPROXY, 1)
+ else
+ LINUX_TPROXY="no"
+ AC_DEFINE(LINUX_TPROXY, 0)
+ fi
+ AC_MSG_RESULT($LINUX_TPROXY)
+fi
+if test "$LINUX_TPROXY" = "no" ; then
+ echo "WARNING: Cannot find TPROXY headers, you need to install the"
+ echo "tproxy package from:"
+ echo " - lynx http://www.balabit.com/downloads/tproxy/linux-2.4/"
+ sleep 10
+fi
+
if test -z "$USE_GNUREGEX" ; then
case "$host" in
*-sun-solaris2.[[0-4]])
diff -ur --exclude configure squid-2.5.STABLE1.orig/include/autoconf.h.in squid-2.5.STABLE1/include/autoconf.h.in
--- squid-2.5.STABLE1.orig/include/autoconf.h.in Mon Jul 15 22:29:47 2002
+++ squid-2.5.STABLE1/include/autoconf.h.in Tue Mar 11 11:46:33 2003
@@ -350,6 +350,11 @@
*/
#undef LINUX_NETFILTER
+/*
+ * Enable real Transparent Proxy support for Netfilter TPROXY.
+ */
+#undef LINUX_TPROXY
+
/*
* Do we have unix sockets? (required for the winbind ntlm helper
*/
@@ -645,6 +650,9 @@
/* Define if you have the <linux/netfilter_ipv4.h> header file. */
#undef HAVE_LINUX_NETFILTER_IPV4_H
+/* Define if you have the <linux/netfilter_ipv4/ip_tproxy.h> header file. */
+#undef HAVE_LINUX_NETFILTER_IPV4_IP_TPROXY_H
+
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/cf.data.pre squid-2.5.STABLE1/src/cf.data.pre
--- squid-2.5.STABLE1.orig/src/cf.data.pre Wed Sep 4 14:35:01 2002
+++ squid-2.5.STABLE1/src/cf.data.pre Tue Mar 11 11:48:48 2003
@@ -3837,4 +3837,20 @@
until all the child processes have been started.
DOC_END
+NAME: linux_tproxy
+IFDEF: LINUX_TPROXY
+COMMENT: on|off
+TYPE: onoff
+LOC: Config.onoff.linux_tproxy
+DEFAULT: off
+DOC_START
+ If you have Linux 2.4 with netfilter and TPROXY support and you
+ have compiled squid with the correct options then you can enable
+ this option to allow squid to spoof the source address of
+ outgoing connections to servers so that they see connections from
+ the original client IP addresses. Enable this only if you know
+ what you are doing. You will need to set a valid
+ tcp_outgoing_address.
+DOC_END
+
EOF
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/client_side.c squid-2.5.STABLE1/src/client_side.c
--- squid-2.5.STABLE1.orig/src/client_side.c Mon Sep 23 05:04:03 2002
+++ squid-2.5.STABLE1/src/client_side.c Mon Mar 10 16:06:03 2003
@@ -322,6 +322,7 @@
new_request->http_ver = old_request->http_ver;
httpHeaderAppend(&new_request->header, &old_request->header);
new_request->client_addr = old_request->client_addr;
+ new_request->client_port = old_request->client_port;
new_request->my_addr = old_request->my_addr;
new_request->my_port = old_request->my_port;
new_request->flags.redirected = 1;
@@ -2977,6 +2978,7 @@
safe_free(http->log_uri);
http->log_uri = xstrdup(urlCanonicalClean(request));
request->client_addr = conn->peer.sin_addr;
+ request->client_port = conn->peer.sin_port;
request->my_addr = conn->me.sin_addr;
request->my_port = ntohs(conn->me.sin_port);
request->http_ver = http->http_ver;
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/forward.c squid-2.5.STABLE1/src/forward.c
--- squid-2.5.STABLE1.orig/src/forward.c Mon Apr 1 13:51:27 2002
+++ squid-2.5.STABLE1/src/forward.c Wed Mar 12 15:18:20 2003
@@ -36,6 +36,13 @@
#include "squid.h"
+#if LINUX_NETFILTER
+#include <linux/netfilter_ipv4.h>
+#endif
+#if LINUX_TPROXY
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#endif
+
static PSC fwdStartComplete;
static void fwdDispatch(FwdState *);
static void fwdConnectStart(void *); /* should be same as EVH */
@@ -331,6 +338,15 @@
time_t ctimeout;
struct in_addr outgoing;
unsigned short tos;
+ struct in_addr *local=NULL;
+#if LINUX_TPROXY
+ int f=ITP_CONNECT;
+ struct in_tproxy itp;
+
+ if ( Config.onoff.linux_tproxy )
+ local=&fwdState->src.sin_addr;
+#endif
+
assert(fs);
assert(fwdState->server_fd == -1);
debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -349,7 +365,7 @@
port = fwdState->request->port;
ctimeout = Config.Timeout.connect;
}
- if ((fd = pconnPop(host, port)) >= 0) {
+ if ((fd = pconnPop(host, port, local)) >= 0) {
debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
fwdState->server_fd = fd;
fwdState->n_tries++;
@@ -396,6 +412,18 @@
ctimeout,
fwdConnectTimeout,
fwdState);
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy ) {
+ itp.itp_faddr.s_addr = fwdState->src.sin_addr.s_addr;
+ itp.itp_fport = fwdState->src.sin_port;
+
+ /* If these syscalls fail then we just fallback to connecting
+ * normally by simply ignoring the errors...
+ */
+ setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, sizeof(itp));
+ setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &f, sizeof(f));
+ }
+#endif
commConnectStart(fd, host, port, fwdConnectDone, fwdState);
}
@@ -610,6 +638,15 @@
fwdState->server_fd = -1;
fwdState->request = requestLink(r);
fwdState->start = squid_curtime;
+
+#if LINUX_TPROXY
+ /* If we need to transparently proxy the request
+ * then we need the client source address and port */
+ fwdState->src.sin_family = AF_INET;
+ fwdState->src.sin_addr = r->client_addr;
+ fwdState->src.sin_port = r->client_port;
+#endif
+
storeLockObject(e);
EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
storeRegisterAbort(e, fwdAbort, fwdState);
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/http.c squid-2.5.STABLE1/src/http.c
--- squid-2.5.STABLE1.orig/src/http.c Sat Sep 7 23:52:10 2002
+++ squid-2.5.STABLE1/src/http.c Wed Mar 12 13:50:50 2003
@@ -542,6 +542,7 @@
int bin;
int clen;
size_t read_sz;
+ struct in_addr *local=NULL;
#if DELAY_POOLS
delay_id delay_id;
@@ -551,6 +552,12 @@
else
delay_id = delayMostBytesAllowed(entry->mem_obj);
#endif
+
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy )
+ local=&httpState->request->client_addr;
+#endif
+
if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
comm_close(fd);
return;
@@ -657,7 +664,7 @@
#endif
comm_remove_close_handler(fd, httpStateFree, httpState);
fwdUnregister(fd, httpState->fwd);
- pconnPush(fd, request->host, request->port);
+ pconnPush(fd, request->host, request->port, local);
fwdComplete(httpState->fwd);
httpState->fd = -1;
httpStateFree(fd, httpState);
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/main.c squid-2.5.STABLE1/src/main.c
--- squid-2.5.STABLE1.orig/src/main.c Sun Jul 14 18:20:49 2002
+++ squid-2.5.STABLE1/src/main.c Tue Mar 11 11:48:18 2003
@@ -422,6 +422,16 @@
#ifdef _SQUID_OS2_
return;
#endif
+
+ /* Transparent proxy support requires squid to run as root which
+ * kinda sucks. I will look towards implementing a solution in
+ * kernel space to combat this, perhaps a sysctl to set a certain
+ * GID to be able to use the TPROXY stuff */
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy )
+ return;
+#endif
+
if (geteuid() == 0) {
debug(0, 0) ("Squid is not safe to run as root! If you must\n");
debug(0, 0) ("start Squid as root, then you must configure\n");
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/pconn.c squid-2.5.STABLE1/src/pconn.c
--- squid-2.5.STABLE1.orig/src/pconn.c Sat Apr 14 01:03:23 2001
+++ squid-2.5.STABLE1/src/pconn.c Wed Mar 12 15:20:04 2003
@@ -49,7 +49,6 @@
static PF pconnRead;
static PF pconnTimeout;
-static const char *pconnKey(const char *host, u_short port);
static hash_table *table = NULL;
static struct _pconn *pconnNew(const char *key);
static void pconnDelete(struct _pconn *p);
@@ -58,12 +57,17 @@
static MemPool *pconn_data_pool = NULL;
static MemPool *pconn_fds_pool = NULL;
-static const char *
-pconnKey(const char *host, u_short port)
+#define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 24)
+
+static inline const int
+pconnKey(char *buf, const char *peer, u_short port, struct in_addr *local)
{
- LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN + 10);
- snprintf(buf, SQUIDHOSTNAMELEN + 10, "%s.%d", host, (int) port);
- return buf;
+ if ( local == NULL ) {
+ return snprintf(buf, PCONN_KEYLEN, "%s.%d", peer, (int) port);
+ }else{
+ return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s",
+ peer, (int) port, inet_ntoa(*local));
+ }
}
static struct _pconn *
@@ -184,11 +188,11 @@
}
void
-pconnPush(int fd, const char *host, u_short port)
+pconnPush(int fd, const char *peer, u_short port, struct in_addr *local)
{
struct _pconn *p;
int *old;
- LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
+ LOCAL_ARRAY(char, key, PCONN_KEYLEN);
LOCAL_ARRAY(char, desc, FD_DESC_SZ);
if (fdNFree() < (RESERVED_FD << 1)) {
debug(48, 3) ("pconnPush: Not many unused FDs\n");
@@ -199,7 +203,7 @@
return;
}
assert(table != NULL);
- strcpy(key, pconnKey(host, port));
+ pconnKey(key, peer, port, local);
p = (struct _pconn *) hash_lookup(table, key);
if (p == NULL)
p = pconnNew(key);
@@ -217,20 +221,20 @@
p->fds[p->nfds++] = fd;
commSetSelect(fd, COMM_SELECT_READ, pconnRead, p, 0);
commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);
- snprintf(desc, FD_DESC_SZ, "%s idle connection", host);
+ snprintf(desc, FD_DESC_SZ, "%s idle connection", peer);
fd_note(fd, desc);
debug(48, 3) ("pconnPush: pushed FD %d for %s\n", fd, key);
}
int
-pconnPop(const char *host, u_short port)
+pconnPop(const char *peer, u_short port, struct in_addr *local)
{
struct _pconn *p;
hash_link *hptr;
int fd = -1;
- LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
+ LOCAL_ARRAY(char, key, PCONN_KEYLEN);
assert(table != NULL);
- strcpy(key, pconnKey(host, port));
+ pconnKey(key, peer, port, local);
hptr = hash_lookup(table, key);
if (hptr != NULL) {
p = (struct _pconn *) hptr;
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/protos.h squid-2.5.STABLE1/src/protos.h
--- squid-2.5.STABLE1.orig/src/protos.h Sat Sep 7 16:13:05 2002
+++ squid-2.5.STABLE1/src/protos.h Wed Mar 12 13:37:31 2003
@@ -1142,8 +1142,8 @@
extern int errorReservePageId(const char *page_name);
extern ErrorState *errorCon(err_type type, http_status);
-extern void pconnPush(int, const char *host, u_short port);
-extern int pconnPop(const char *host, u_short port);
+extern void pconnPush(int, const char *peer, u_short port, struct in_addr *local);
+extern int pconnPop(const char *peer, u_short port, struct in_addr *local);
extern void pconnInit(void);
extern int asnMatchIp(void *, struct in_addr);
diff -ur --exclude configure squid-2.5.STABLE1.orig/src/structs.h squid-2.5.STABLE1/src/structs.h
--- squid-2.5.STABLE1.orig/src/structs.h Sun Sep 8 00:11:23 2002
+++ squid-2.5.STABLE1/src/structs.h Mon Mar 10 16:06:03 2003
@@ -585,6 +585,9 @@
int ie_refresh;
int vary_ignore_expire;
int pipeline_prefetch;
+#if LINUX_NETFILTER
+ int linux_tproxy;
+#endif
} onoff;
acl *aclList;
struct {
@@ -1645,6 +1648,7 @@
int imslen;
int max_forwards;
/* these in_addr's could probably be sockaddr_in's */
+ in_port_t client_port;
struct in_addr client_addr;
struct in_addr my_addr;
unsigned short my_port;
@@ -1962,6 +1966,9 @@
unsigned int dont_retry:1;
unsigned int ftp_pasv_failed:1;
} flags;
+#if LINUX_NETFILTER
+ struct sockaddr_in src;
+#endif
};
#if USE_HTCP
diff -urN squid-3.0-DEVEL-20030310/configure.in squid-3.0-DEVEL-tproxy/configure.in
--- squid-3.0-DEVEL-20030310/configure.in 2003-03-10 01:11:12.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/configure.in 2003-03-12 15:26:01.000000000 +0000
@@ -880,6 +880,17 @@
fi
])
+dnl Enable Linux transparent proxy support
+AC_ARG_ENABLE(linux-tproxy,
+[ --enable-linux-tproxy
+ Enable real Transparent Proxy support for Netfilter TPROXY.],
+[ if test "$enableval" = "yes" ; then
+ echo "Linux Netfilter/TPROXY enabled"
+ AC_DEFINE(LINUX_TPROXY)
+ LINUX_TPROXY="yes"
+ fi
+])
+
dnl Enable Large file support
AC_ARG_ENABLE(large-files,
[ --enable-large-files Enable support for large files (>2GB). Still
@@ -1435,6 +1446,7 @@
utime.h \
varargs.h \
byteswap.h \
+ linux/netfilter_ipv4/ip_tproxy.h \
glib.h \
stdint.h \
inttypes.h \
@@ -2031,6 +2043,27 @@
sleep 10
fi
+dnl Linux Netfilter/TPROXY support requires some specific header files
+dnl Shamelessly copied from shamelessly copied from above
+if test "$LINUX_TPROXY" ; then
+ AC_MSG_CHECKING(if TPROXY header files are installed)
+ # hold on to your hats...
+ if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes"; then
+ LINUX_TPROXY="yes"
+ AC_DEFINE(LINUX_TPROXY, 1)
+ else
+ LINUX_TPROXY="no"
+ AC_DEFINE(LINUX_TPROXY, 0)
+ fi
+ AC_MSG_RESULT($LINUX_TPROXY)
+fi
+if test "$LINUX_TPROXY" = "no" ; then
+ echo "WARNING: Cannot find TPROXY headers, you need to install the"
+ echo "tproxy package from:"
+ echo " - lynx http://www.balabit.com/downloads/tproxy/linux-2.4/"
+ sleep 10
+fi
+
if test -z "$USE_GNUREGEX" ; then
case "$host" in
*-sun-solaris2.[[0-4]])
diff -urN squid-3.0-DEVEL-20030310/src/cf.data.pre squid-3.0-DEVEL-tproxy/src/cf.data.pre
--- squid-3.0-DEVEL-20030310/src/cf.data.pre 2003-02-22 14:59:33.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/cf.data.pre 2003-03-12 15:27:16.000000000 +0000
@@ -4096,4 +4096,20 @@
until all the child processes have been started.
DOC_END
+NAME: linux_tproxy
+IFDEF: LINUX_TPROXY
+COMMENT: on|off
+TYPE: onoff
+LOC: Config.onoff.linux_tproxy
+DEFAULT: off
+DOC_START
+ If you have Linux 2.4 with netfilter and TPROXY support and you
+ have compiled squid with the correct options then you can enable
+ this option to allow squid to spoof the source address of
+ outgoing connections to servers so that they see connections from
+ the original client IP addresses. Enable this only if you know
+ what you are doing. You will need to set a valid
+ tcp_outgoing_address.
+DOC_END
+
EOF
diff -urN squid-3.0-DEVEL-20030310/src/client_side.cc squid-3.0-DEVEL-tproxy/src/client_side.cc
--- squid-3.0-DEVEL-20030310/src/client_side.cc 2003-03-07 04:40:59.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/client_side.cc 2003-03-12 15:27:57.000000000 +0000
@@ -2086,6 +2086,7 @@
request->flags.internal = http->flags.internal;
setLogUri (http, urlCanonicalClean(request));
request->client_addr = conn->peer.sin_addr;
+ request->client_port = conn->peer.sin_port;
request->my_addr = conn->me.sin_addr;
request->my_port = ntohs(conn->me.sin_port);
request->http_ver = http->http_ver;
diff -urN squid-3.0-DEVEL-20030310/src/forward.cc squid-3.0-DEVEL-tproxy/src/forward.cc
--- squid-3.0-DEVEL-20030310/src/forward.cc 2003-03-02 23:13:49.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/forward.cc 2003-03-12 15:32:31.000000000 +0000
@@ -42,6 +42,10 @@
#include "ACLChecklist.h"
#include "ACL.h"
+#if LINUX_TPROXY
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#endif
+
static PSC fwdStartComplete;
static void fwdDispatch(FwdState *);
static void fwdConnectStart(void *); /* should be same as EVH */
@@ -522,6 +526,15 @@
struct in_addr outgoing;
unsigned short tos;
+ struct in_addr *local=NULL;
+#if LINUX_TPROXY
+ int f=ITP_CONNECT;
+ struct in_tproxy itp;
+
+ if ( Config.onoff.linux_tproxy )
+ local=&fwdState->src.sin_addr;
+#endif
+
assert(fs);
assert(fwdState->server_fd == -1);
debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -537,7 +550,7 @@
ctimeout = Config.Timeout.connect;
}
- if ((fd = pconnPop(host, port)) >= 0) {
+ if ((fd = pconnPop(host, port, local)) >= 0) {
debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
fwdState->server_fd = fd;
fwdState->n_tries++;
@@ -595,6 +608,18 @@
fwdConnectTimeout,
fwdState);
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy ) {
+ itp.itp_faddr.s_addr = fwdState->src.sin_addr.s_addr;
+ itp.itp_fport = fwdState->src.sin_port;
+
+ /* If these syscalls fail then we just fallback to connecting
+ * normally by simply ignoring the errors...
+ */
+ setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, sizeof(itp));
+ setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &f, sizeof(f));
+ }
+#endif
commConnectStart(fd, host, port, fwdConnectDone, fwdState);
}
@@ -867,6 +892,15 @@
fwdState->server_fd = -1;
fwdState->request = requestLink(r);
fwdState->start = squid_curtime;
+
+#if LINUX_TPROXY
+ /* If we need to transparently proxy the request
+ * then we need the client source address and port */
+ fwdState->src.sin_family = AF_INET;
+ fwdState->src.sin_addr = r->client_addr;
+ fwdState->src.sin_port = r->client_port;
+#endif
+
storeLockObject(e);
EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
storeRegisterAbort(e, fwdAbort, fwdState);
diff -urN squid-3.0-DEVEL-20030310/src/http.cc squid-3.0-DEVEL-tproxy/src/http.cc
--- squid-3.0-DEVEL-20030310/src/http.cc 2003-03-06 06:21:38.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/http.cc 2003-03-12 15:34:37.000000000 +0000
@@ -902,6 +902,12 @@
void
HttpStateData::processReplyData(const char *buf, size_t len)
{
+ struct in_addr *local=NULL;
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy )
+ local=&request->client_addr;
+#endif
+
if (reply_hdr_state < 2) {
do_next_read = 1;
maybeReadData();
@@ -957,7 +963,7 @@
comm_remove_close_handler(fd, httpStateFree, this);
fwdUnregister(fd, fwd);
- pconnPush(fd, request->host, request->port);
+ pconnPush(fd, request->host, request->port, local);
fwdComplete(fwd);
fd = -1;
httpStateFree(fd, this);
diff -urN squid-3.0-DEVEL-20030310/src/main.cc squid-3.0-DEVEL-tproxy/src/main.cc
--- squid-3.0-DEVEL-20030310/src/main.cc 2003-02-25 12:24:35.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/main.cc 2003-03-12 15:35:17.000000000 +0000
@@ -509,6 +509,15 @@
return;
#endif
+ /* Transparent proxy support requires squid to run as root which
+ * kinda sucks. I will look towards implementing a solution in
+ * kernel space to combat this, perhaps a sysctl to set a certain
+ * GID to be able to use the TPROXY stuff */
+#if LINUX_TPROXY
+ if ( Config.onoff.linux_tproxy )
+ return;
+#endif
+
if (geteuid() == 0) {
debug(0, 0) ("Squid is not safe to run as root! If you must\n");
debug(0, 0) ("start Squid as root, then you must configure\n");
diff -urN squid-3.0-DEVEL-20030310/src/pconn.cc squid-3.0-DEVEL-tproxy/src/pconn.cc
--- squid-3.0-DEVEL-20030310/src/pconn.cc 2003-02-21 22:50:10.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/pconn.cc 2003-03-12 15:39:02.000000000 +0000
@@ -55,7 +55,6 @@
static IOCB pconnRead;
static PF pconnTimeout;
-static const char *pconnKey(const char *host, u_short port);
static hash_table *table = NULL;
static struct _pconn *pconnNew(const char *key);
@@ -67,14 +66,17 @@
static MemPool *pconn_fds_pool = NULL;
CBDATA_TYPE(pconn);
+#define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 24)
-
-static const char *
-pconnKey(const char *host, u_short port)
+static inline const int
+pconnKey(char *buf, const char *peer, u_short port, struct in_addr *local)
{
- LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN + 10);
- snprintf(buf, SQUIDHOSTNAMELEN + 10, "%s.%d", host, (int) port);
- return buf;
+ if ( local == NULL ) {
+ return snprintf(buf, PCONN_KEYLEN, "%s.%d", peer, (int) port);
+ }else{
+ return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s",
+ peer, (int) port, inet_ntoa(*local));
+ }
}
static struct _pconn *
@@ -238,12 +240,12 @@
}
void
-pconnPush(int fd, const char *host, u_short port)
+pconnPush(int fd, const char *peer, u_short port, struct in_addr *local)
{
struct _pconn *p;
int *old;
- LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
+ LOCAL_ARRAY(char, key, PCONN_KEYLEN);
LOCAL_ARRAY(char, desc, FD_DESC_SZ);
if (fdNFree() < (RESERVED_FD << 1)) {
@@ -256,7 +258,7 @@
}
assert(table != NULL);
- strcpy(key, pconnKey(host, port));
+ pconnkey(key, peer, port, local);
p = (struct _pconn *) hash_lookup(table, key);
@@ -279,7 +281,7 @@
p->fds[p->nfds++] = fd;
comm_read(fd, p->buf, BUFSIZ, pconnRead, p);
commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);
- snprintf(desc, FD_DESC_SZ, "%s idle connection", host);
+ snprintf(desc, FD_DESC_SZ, "%s idle connection", peer);
fd_note(fd, desc);
debug(48, 3) ("pconnPush: pushed FD %d for %s\n", fd, key);
}
@@ -295,15 +297,15 @@
* quite a bit of CPU. Just keep it in mind.
*/
int
-pconnPop(const char *host, u_short port)
+pconnPop(const char *peer, u_short port, struct in_addr *local)
{
struct _pconn *p;
hash_link *hptr;
int fd = -1;
- LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
+ LOCAL_ARRAY(char, key, PCONN_KEYLEN);
assert(table != NULL);
- strcpy(key, pconnKey(host, port));
+ pconnKey(key, peer, port, local);
hptr = (hash_link *)hash_lookup(table, key);
if (hptr != NULL) {
diff -urN squid-3.0-DEVEL-20030310/src/protos.h squid-3.0-DEVEL-tproxy/src/protos.h
--- squid-3.0-DEVEL-20030310/src/protos.h 2003-03-08 09:35:15.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/protos.h 2003-03-12 15:39:34.000000000 +0000
@@ -907,8 +907,8 @@
SQUIDCEXTERN err_type errorReservePageId(const char *page_name);
SQUIDCEXTERN ErrorState *errorCon(err_type type, http_status);
-SQUIDCEXTERN void pconnPush(int, const char *host, u_short port);
-SQUIDCEXTERN int pconnPop(const char *host, u_short port);
+SQUIDCEXTERN void pconnPush(int, const char *peer, u_short port, struct in_addr *local);
+SQUIDCEXTERN int pconnPop(const char *peer, u_short port, struct in_addr *local);
SQUIDCEXTERN void pconnInit(void);
/* tools.c */
diff -urN squid-3.0-DEVEL-20030310/src/structs.h squid-3.0-DEVEL-tproxy/src/structs.h
--- squid-3.0-DEVEL-20030310/src/structs.h 2003-03-08 09:35:16.000000000 +0000
+++ squid-3.0-DEVEL-tproxy/src/structs.h 2003-03-12 15:41:24.000000000 +0000
@@ -538,6 +538,9 @@
int check_hostnames;
int via;
int emailErrData;
+#if LINUX_NETFILTER
+ int linux_tproxy;
+#endif
}
onoff;
@@ -1645,6 +1648,7 @@
/* these in_addr's could probably be sockaddr_in's */
struct in_addr client_addr;
+ in_port_t client_port;
struct in_addr my_addr;
unsigned short my_port;
@@ -2047,6 +2051,9 @@
}
flags;
+#if LINUX_NETFILTER
+ struct sockaddr_in src;
+#endif
};
#if USE_HTCP
signature.asc
Description: This is a digitally signed message part
