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);

Reply via email to