MINOR: backend: rewrite alloc of stream target address

Change the API of the function used to allocate the stream target
address. This is done in order to be able to allocate the destination
address and use it to reuse a connection sharing with the same address.
In particular, the flag stream SF_ADDR_SET is now set outside of the
function.
This commit is contained in:
Amaury Denoyelle 2021-01-11 15:24:31 +01:00
parent e676239922
commit 68cf3959b3

View File

@ -827,36 +827,32 @@ out_ok:
return err;
}
/*
* This function assigns a server address to a stream, and sets SF_ADDR_SET.
/* Allocate an address for the destination endpoint
* The address is taken from the currently assigned server, or from the
* dispatch or transparent address.
*
* It may return :
* SRV_STATUS_OK if everything is OK.
* SRV_STATUS_INTERNAL for other unrecoverable errors.
*
* Upon successful return, the stream flag SF_ADDR_SET is set. This flag is
* not cleared, so it's to the caller to clear it if required.
* Returns SRV_STATUS_OK on success.
* On error, the allocated address is freed and SRV_STATUS_INTERNAL is returned.
*/
int assign_server_address(struct stream *s)
static int alloc_dst_address(struct sockaddr_storage **ss,
struct server *srv, struct stream *s)
{
struct connection *cli_conn = objt_conn(strm_orig(s));
DPRINTF(stderr,"assign_server_address : s=%p\n",s);
if (!sockaddr_alloc(&s->target_addr, NULL, 0))
return SRV_STATUS_INTERNAL;
*ss = NULL;
if ((s->flags & SF_DIRECT) || (s->be->lbprm.algo & BE_LB_KIND)) {
/* A server is necessarily known for this stream */
if (!(s->flags & SF_ASSIGNED))
return SRV_STATUS_INTERNAL;
*s->target_addr = __objt_server(s->target)->addr;
set_host_port(s->target_addr, __objt_server(s->target)->svc_port);
if (!sockaddr_alloc(ss, NULL, 0))
return SRV_STATUS_INTERNAL;
if (!is_addr(s->target_addr) && cli_conn) {
**ss = srv->addr;
set_host_port(*ss, srv->svc_port);
if (!is_addr(*ss) && cli_conn) {
/* 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. Nothing is done
@ -865,15 +861,17 @@ int assign_server_address(struct stream *s)
if (!conn_get_dst(cli_conn)) {
/* do nothing if we can't retrieve the address */
} else if (cli_conn->dst->ss_family == AF_INET) {
((struct sockaddr_in *)s->target_addr)->sin_addr = ((struct sockaddr_in *)cli_conn->dst)->sin_addr;
((struct sockaddr_in *)*ss)->sin_addr =
((struct sockaddr_in *)cli_conn->dst)->sin_addr;
} else if (cli_conn->dst->ss_family == AF_INET6) {
((struct sockaddr_in6 *)s->target_addr)->sin6_addr = ((struct sockaddr_in6 *)cli_conn->dst)->sin6_addr;
((struct sockaddr_in6 *)*ss)->sin6_addr =
((struct sockaddr_in6 *)cli_conn->dst)->sin6_addr;
}
}
/* if this server remaps proxied ports, we'll use
* the port the client connected to with an offset. */
if ((__objt_server(s->target)->flags & SRV_F_MAPPORTS) && cli_conn) {
if ((srv->flags & SRV_F_MAPPORTS) && cli_conn) {
int base_port;
if (conn_get_dst(cli_conn)) {
@ -881,20 +879,26 @@ int assign_server_address(struct stream *s)
base_port = get_host_port(cli_conn->dst);
/* Second, assign the outgoing connection's port */
base_port += get_host_port(s->target_addr);
set_host_port(s->target_addr, base_port);
base_port += get_host_port(*ss);
set_host_port(*ss, base_port);
}
}
}
else if (s->be->options & PR_O_DISPATCH) {
if (!sockaddr_alloc(ss, NULL, 0))
return SRV_STATUS_INTERNAL;
/* connect to the defined dispatch addr */
*s->target_addr = s->be->dispatch_addr;
**ss = s->be->dispatch_addr;
}
else if ((s->be->options & PR_O_TRANSP) && cli_conn) {
if (!sockaddr_alloc(ss, NULL, 0))
return SRV_STATUS_INTERNAL;
/* in transparent mode, use the original dest addr if no dispatch specified */
if (conn_get_dst(cli_conn) &&
(cli_conn->dst->ss_family == AF_INET || cli_conn->dst->ss_family == AF_INET6))
*s->target_addr = *cli_conn->dst;
**ss = *cli_conn->dst;
}
else if (s->be->options & PR_O_HTTP_PROXY) {
/* If HTTP PROXY option is set, then server is already assigned
@ -905,7 +909,6 @@ int assign_server_address(struct stream *s)
return SRV_STATUS_INTERNAL;
}
s->flags |= SF_ADDR_SET;
return SRV_STATUS_OK;
}
@ -1467,11 +1470,13 @@ skip_reuse:
}
if (!(s->flags & SF_ADDR_SET)) {
err = assign_server_address(s);
err = alloc_dst_address(&s->target_addr, srv, s);
if (err != SRV_STATUS_OK) {
conn_free(srv_conn);
return SF_ERR_INTERNAL;
}
s->flags |= SF_ADDR_SET;
}
/* copy the target address into the connection */