On Thursday 13 January 2005 18:15, Henrik Nordstrom wrote:
> 
> On Thu, 13 Jan 2005, Denis Vlasenko wrote:
> 
> > 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(
> 
> According to my notes this was fixed quite some time ago:
> 
> http://www.squid-cache.org/Versions/v2/2.5/bugs/#squid-2.5.STABLE7-httpd_accel_vport

Your patch is about "httpd_accel_port 0 did not work unless httpd_accel_host 
virtual
was also specified" but I do have that specified!

My patch is for slightly different bug. I will try to explain.

Your patch:

Index: squid/src/client_side.c
diff -c squid/src/client_side.c:1.561.2.64 squid/src/client_side.c:1.561.2.65
*** squid/src/client_side.c:1.561.2.64  Tue Dec  7 16:57:25 2004
--- squid/src/client_side.c     Tue Dec  7 17:44:01 2004
***************
*** 2872,2877 ****
--- 2872,2886 ----
                vport, url);
  #endif
            debug(33, 5) ("VHOST REWRITE: '%s'\n", http->uri);
+       } else if (vport_mode) {
+           int vport;
+           const char *protocol_name = "http";
+           vport = (int) ntohs(http->conn->me.sin_port);
+           url_sz = strlen(url) + 32 + Config.appendDomainLen +
+               strlen(Config.Accel.host);
+           http->uri = xcalloc(url_sz, 1);
+           snprintf(http->uri, url_sz, "%s://%s:%d%s",
+               protocol_name, Config.Accel.host, vport, url);
        } else {
            url_sz = strlen(Config2.Accel.prefix) + strlen(url) +
                Config.appendDomainLen + 1;


it is to be applied to this place:

#else
#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));
            if (vport_mode)
                vport = (int) ntohs(http->conn->me.sin_port);
#endif
            snprintf(http->uri, url_sz, "http://%s:%d%s";,
                inet_ntoa(http->conn->me.sin_addr),
                vport, url);
#endif
            debug(33, 5) ("VHOST REWRITE: '%s'\n", http->uri);
        } else {
            url_sz = strlen(Config2.Accel.prefix) + strlen(url) +
                Config.appendDomainLen + 1;
            http->uri = xcalloc(url_sz, 1);
            snprintf(http->uri, url_sz, "%s%s", Config2.Accel.prefix, url);
        }
        http->flags.accel = 1;

So, vport = (int) ntohs(http->conn->me.sin_port); line in your patch
is outside of #if LINUX_NETFILTER and thus have no chance in hell to extract
correct dst port in my case when squid listens on NATed port:

this is my xparent proxy box:

-----------> :8080 \
-----------> :3128 -> NATed to port 9080 --> squid -----> internet
-----------> :80   /

HTTP requests which go to port 8080 get NATed to 9080, accepted by
squid, and if there is "Host:" header which does not have :8080 spec -
guess what? squid sends request to origin server's port 9080 (!)
because it believes user's request was to port 9080.

squid should ask NAT machinery about "original", untranslated dst
port and send request to it instead. My patch does exactly that.

Please apply.
--
vda

Reply via email to