[squid-users] Re: [PATCH] fix transparent caching when squid listens on non-80 port

From: Denis Vlasenko <vda@dont-contact.us>
Date: Thu, 13 Jan 2005 21:39:28 +0200

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
Received on Thu Jan 13 2005 - 12:39:38 MST

This archive was generated by hypermail pre-2.1.9 : Mon Mar 07 2005 - 12:59:35 MST