]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] backend: support servers on 0.0.0.0
authorWilly Tarreau <w@1wt.eu>
Tue, 13 Jul 2010 12:49:50 +0000 (14:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 13 Jul 2010 12:57:52 +0000 (14:57 +0200)
Till now when a server was configured with address 0.0.0.0, the
connection was forwarded to this address which generally is intercepted
by the system as a local address, so this was completely useless.

One sometimes useful feature for outgoing transparent proxies is to
be able to forward the connection to the same address the client
requested. This patch fixes the meaning of 0.0.0.0 precisely to
ensure that the connection will be forwarded to the initial client's
destination address.

doc/configuration.txt
src/backend.c

index 11c7a1ae2a38040c7d9c91a0b9840bf216156f0d..d1fa1fa1fca1c6f3e611d2a096c13a572286b68d 100644 (file)
@@ -4296,7 +4296,14 @@ server <name> <address>[:port] [param*]
 
     <address> is the IPv4 address of the server. Alternatively, a resolvable
               hostname is supported, but this name will be resolved during
-              start-up.
+              start-up. Address "0.0.0.0" or "*" has a special meaning. It
+              indicates that the connection will be forwarded to the same IP
+              address as the one from the client connection. This is useful in
+              transparent proxy architectures where the client's connection is
+              intercepted and haproxy must forward to the original destination
+              address. This is more or less what the "transparent" keyword does
+              except that with a server it's possible to limit concurrency and
+              to report statistics.
 
     <ports>   is an optional port specification. If set, all connections will
               be sent to this port. If unset, the same port the client
index 1fc6b2aaadda0e0ed8e3048eaaea04a2a2f9a5f7..33a81ab91efd0790d9a2307a28fa660a63fc83ec 100644 (file)
@@ -661,6 +661,17 @@ int assign_server_address(struct session *s)
 
                s->srv_addr = s->srv->addr;
 
+               if (!s->srv_addr.sin_addr.s_addr) {
+                       /* if the server has no address, we use the same address
+                        * the client asked, which is handy for remapping ports
+                        * locally on multiple addresses at once.
+                        */
+                       if (!(s->be->options & PR_O_TRANSP) && !(s->flags & SN_FRT_ADDR_SET))
+                               get_frt_addr(s);
+
+                       s->srv_addr.sin_addr = ((struct sockaddr_in *)&s->frt_addr)->sin_addr;
+               }
+
                /* if this server remaps proxied ports, we'll use
                 * the port the client connected to with an offset. */
                if (s->srv->state & SRV_MAPPORTS) {