diff --git a/doc/configuration.txt b/doc/configuration.txt index 11c7a1ae2..d1fa1fa1f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4296,7 +4296,14 @@ server
[:port] [param*]
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. is an optional port specification. If set, all connections will be sent to this port. If unset, the same port the client diff --git a/src/backend.c b/src/backend.c index 1fc6b2aaa..33a81ab91 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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) {