Squid uses destination port of incoming request
in order to determine dst port for it's own request
if vport is used. This is handled correctly for
case where there is no "Host:" header in user
request. However, if there *IS* a "Host:" header
without explicit :port spec, squid does not check
whether port was translated by NAT before reaching
squid.
This will work if your squid listens on port 80, but
in my case, it was on 9080, causing all requests to go
to port 9080 too on origin servers 8(
Patch fixes this. Fix for LINUX_NETFILTER only, sorry.
Patch also fixes missing "\n" in debug print and
optimizes "http->conn" into "conn" because they
are equal throughout affected function.
Patch developed and tested on STABLE1, rediffed
to STABLE7.
--
vda
--- squid-2.5.STABLE7/src/client_side.c.orig Wed Oct 6 01:34:42 2004
+++ squid-2.5.STABLE7/src/client_side.c Thu Jan 13 16:04:41 2005
@@ -2717,8 +2717,13 @@
int vport;
char *q;
const char *protocol_name = "http";
- if (vport_mode)
- vport = (int) ntohs(http->conn->me.sin_port);
+ if (vport_mode) {
+#if LINUX_NETFILTER
+ /* If the call fails the address structure will be unchanged */
+ getsockopt(conn->fd, SOL_IP, SO_ORIGINAL_DST, &conn->me, &sock_sz);
+#endif
+ vport = (int) ntohs(conn->me.sin_port);
+ }
else
vport = (int) Config.Accel.port;
/* If a Host: header was specified, use it to build the URL
@@ -2741,9 +2746,9 @@
http->uri = xcalloc(url_sz, 1);
#if SSL_FORWARDING_NOT_YET_DONE
- if (Config.Sockaddr.https->s.sin_port == http->conn->me.sin_port) {
+ if (Config.Sockaddr.https->s.sin_port == conn->me.sin_port) {
protocol_name = "https";
- vport = ntohs(http->conn->me.sin_port);
+ vport = ntohs(conn->me.sin_port);
}
#endif
snprintf(http->uri, url_sz, "%s://%s:%d%s",
@@ -2754,14 +2759,14 @@
url_sz = strlen(url) + 32 + Config.appendDomainLen;
http->uri = xcalloc(url_sz, 1);
if (vport_mode)
- vport = (int) ntohs(http->conn->me.sin_port);
+ vport = (int) ntohs(conn->me.sin_port);
else
vport = (int) Config.Accel.port;
#if IPF_TRANSPARENT
- natLookup.nl_inport = http->conn->me.sin_port;
- natLookup.nl_outport = http->conn->peer.sin_port;
- natLookup.nl_inip = http->conn->me.sin_addr;
- natLookup.nl_outip = http->conn->peer.sin_addr;
+ natLookup.nl_inport = conn->me.sin_port;
+ natLookup.nl_outport = conn->peer.sin_port;
+ natLookup.nl_inip = conn->me.sin_addr;
+ natLookup.nl_outip = conn->peer.sin_addr;
natLookup.nl_flags = IPN_TCP;
if (natfd < 0) {
int save_errno;
@@ -2805,7 +2810,7 @@
return parseHttpRequestAbort(conn, "error:nat-lookup-failed");
} else
snprintf(http->uri, url_sz, "http://%s:%d%s",
- inet_ntoa(http->conn->me.sin_addr),
+ inet_ntoa(conn->me.sin_addr),
vport, url);
} else {
if (vport_mode)
@@ -2823,10 +2828,10 @@
return parseHttpRequestAbort(conn, "error:pf-open-failed");
}
memset(&nl, 0, sizeof(struct pfioc_natlook));
- nl.saddr.v4.s_addr = http->conn->peer.sin_addr.s_addr;
- nl.sport = http->conn->peer.sin_port;
- nl.daddr.v4.s_addr = http->conn->me.sin_addr.s_addr;
- nl.dport = http->conn->me.sin_port;
+ nl.saddr.v4.s_addr = conn->peer.sin_addr.s_addr;
+ nl.sport = conn->peer.sin_port;
+ nl.daddr.v4.s_addr = conn->me.sin_addr.s_addr;
+ nl.dport = conn->me.sin_port;
nl.af = AF_INET;
nl.proto = IPPROTO_TCP;
nl.direction = PF_OUT;
@@ -2838,7 +2843,7 @@
return parseHttpRequestAbort(conn, "error:pf-lookup-failed");
} else
snprintf(http->uri, url_sz, "http://%s:%d%s",
- inet_ntoa(http->conn->me.sin_addr),
+ inet_ntoa(conn->me.sin_addr),
vport, url);
} else
snprintf(http->uri, url_sz, "http://%s:%d%s",
@@ -2848,12 +2853,12 @@
#if LINUX_NETFILTER
/* If the call fails the address structure will be unchanged */
getsockopt(conn->fd, SOL_IP, SO_ORIGINAL_DST, &conn->me, &sock_sz);
- debug(33, 5) ("parseHttpRequest: addr = %s", inet_ntoa(conn->me.sin_addr));
+ debug(33, 5) ("parseHttpRequest: addr = %s\n", inet_ntoa(conn->me.sin_addr));
if (vport_mode)
- vport = (int) ntohs(http->conn->me.sin_port);
+ vport = (int) ntohs(conn->me.sin_port);
#endif
snprintf(http->uri, url_sz, "http://%s:%d%s",
- inet_ntoa(http->conn->me.sin_addr),
+ inet_ntoa(conn->me.sin_addr),
vport, url);
#endif
debug(33, 5) ("VHOST REWRITE: '%s'\n", http->uri);