]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: backend: refactor specific source address allocation
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 2 Oct 2023 15:17:15 +0000 (17:17 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 3 Oct 2023 15:49:12 +0000 (17:49 +0200)
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.

include/haproxy/backend.h
src/backend.c

index 4bfdf077159e0eb10b715ab9eff01643f2cae7fc..986852c2a81f7e4adbe8925d0d57ca01bd6c47ad 100644 (file)
@@ -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);
index 2f9da87abca5b6afb229acf2471506b100fa5f29..7da5da873ef3f9bc3c23314bfa5d6aef4209a4f4 100644 (file)
@@ -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 <srv> which is the server instance to connect
+ * to. It may be NULL when dispatching is used. The second one <be> is the
+ * backend instance which contains the target server or dispatch.
+ *
+ * A stream instance <s> 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;