From: Amaury Denoyelle Date: Mon, 2 Oct 2023 15:17:15 +0000 (+0200) Subject: MINOR: backend: refactor specific source address allocation X-Git-Tag: v2.9-dev7~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd001ff346da42e5f5c4019e4fa10b13d59f9526;p=thirdparty%2Fhaproxy.git MINOR: backend: refactor specific source address allocation Refactor alloc_bind_address() function which is used to allocate a sockaddr if a connection to a target server relies on a specific source address setting. The main objective of this change is to be able to use this function outside of backend module, namely for preconnections using a reverse server. As such, this function is now exported globally. For reverse connect, there is no stream instance. As such, the function parts which relied on it were reduced to the minimal. Now, stream is only used if a non-static address is configured which is useful for usesrc client|clientip|hdr_ip. These options have no sense for reverse connect so it should be safe to use the same function. --- diff --git a/include/haproxy/backend.h b/include/haproxy/backend.h index 4bfdf07715..986852c2a8 100644 --- a/include/haproxy/backend.h +++ b/include/haproxy/backend.h @@ -33,6 +33,9 @@ int assign_server(struct stream *s); int assign_server_address(struct stream *s); int assign_server_and_queue(struct stream *s); +int alloc_bind_address(struct sockaddr_storage **ss, + struct server *srv, struct proxy *be, + struct stream *s); int srv_redispatch_connect(struct stream *t); void back_try_conn_req(struct stream *s); void back_handle_st_req(struct stream *s); diff --git a/src/backend.c b/src/backend.c index 2f9da87abc..7da5da873e 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1061,16 +1061,24 @@ int assign_server_and_queue(struct stream *s) } } -/* Allocate an address for source binding on the specified server or backend. - * The allocation is only performed if the connection is intended to be used - * with transparent mode. +/* Allocate an address if an explicit source address must be used for a backend + * connection. * - * Returns SRV_STATUS_OK if no transparent mode or the address was successfully - * allocated. Otherwise returns SRV_STATUS_INTERNAL. Does nothing if the - * address was already allocated. + * Two parameters are taken into account to check if specific source address is + * configured. The first one is which is the server instance to connect + * to. It may be NULL when dispatching is used. The second one is the + * backend instance which contains the target server or dispatch. + * + * A stream instance can be used to set the stream owner of the backend + * connection. It is a required parameter if the source address is a dynamic + * parameter. + * + * Returns SRV_STATUS_OK if either no specific source address specified or its + * allocation is done correctly. On error returns SRV_STATUS_INTERNAL. */ -static int alloc_bind_address(struct sockaddr_storage **ss, - struct server *srv, struct stream *s) +int alloc_bind_address(struct sockaddr_storage **ss, + struct server *srv, struct proxy *be, + struct stream *s) { #if defined(CONFIG_HAP_TRANSPARENT) const struct sockaddr_storage *addr; @@ -1080,14 +1088,14 @@ static int alloc_bind_address(struct sockaddr_storage **ss, size_t vlen; #endif - if (*ss) - return SRV_STATUS_OK; + /* Ensure the function will not overwrite an allocated address. */ + BUG_ON(*ss); #if defined(CONFIG_HAP_TRANSPARENT) if (srv && srv->conn_src.opts & CO_SRC_BIND) src = &srv->conn_src; - else if (s->be->conn_src.opts & CO_SRC_BIND) - src = &s->be->conn_src; + else if (be->conn_src.opts & CO_SRC_BIND) + src = &be->conn_src; /* no transparent mode, no need to allocate an address, returns OK */ if (!src) @@ -1103,6 +1111,8 @@ static int alloc_bind_address(struct sockaddr_storage **ss, case CO_SRC_TPROXY_CLI: case CO_SRC_TPROXY_CIP: + BUG_ON(!s); /* Dynamic source setting requires a stream instance. */ + /* FIXME: what can we do if the client connects in IPv6 or unix socket ? */ addr = sc_src(s->scf); if (!addr) @@ -1115,6 +1125,8 @@ static int alloc_bind_address(struct sockaddr_storage **ss, break; case CO_SRC_TPROXY_DYN: + BUG_ON(!s); /* Dynamic source setting requires a stream instance. */ + if (!src->bind_hdr_occ || !IS_HTX_STRM(s)) return SRV_STATUS_INTERNAL; @@ -1350,7 +1362,7 @@ static int connect_server(struct stream *s) if (err != SRV_STATUS_OK) return SF_ERR_INTERNAL; - err = alloc_bind_address(&bind_addr, srv, s); + err = alloc_bind_address(&bind_addr, srv, s->be, s); if (err != SRV_STATUS_OK) return SF_ERR_INTERNAL;