[MEDIUM] backend: support servers on 0.0.0.0

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.
This commit is contained in:
Willy Tarreau 2010-07-13 14:49:50 +02:00
parent 35da19ca70
commit d669a4f72b
2 changed files with 19 additions and 1 deletions

View 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

View 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) {