]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: uxst: fix outgoing abns address family in connect()
authorWilly Tarreau <w@1wt.eu>
Fri, 21 Feb 2025 06:53:21 +0000 (07:53 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 21 Feb 2025 06:59:08 +0000 (07:59 +0100)
Since we reworked the unix socket families in order to support custom
addresses for different addressing schemes, we've been using extra
values for the ss_family field in sockaddr_storage. These ones have
to be adjusted before calling bind() or connect(). It turns out that
after the abns/abnsz updates in 3.1, the connect() code was not adjusted
to take care of the change, resulting in AF_CUST_ABNS or AF_CUST_ABNSZ
to be placed in the address that was passed to connect().

The right approach is to locally copy the address, get its length,
fixup the family and use the fixed value and length for connect().

This must be backported to 3.1. Many thanks for @Mewp for reporting
this issue in github issue #2875.

src/proto_uxst.c

index f8b6958091b28fc126a7f0064e990106c5994efb..8122ad384f66538a7c8468a89be8473ff9e61bce 100644 (file)
@@ -307,6 +307,8 @@ static int uxst_suspend_receiver(struct receiver *rx)
  */
 static int uxst_connect_server(struct connection *conn, int flags)
 {
+       struct sockaddr_storage addr;
+       socklen_t addr_len;
        int fd, stream_err;
        struct server *srv;
        struct proxy *be;
@@ -339,7 +341,14 @@ static int uxst_connect_server(struct connection *conn, int flags)
        if (global.tune.server_rcvbuf)
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
-       if (connect(fd, (struct sockaddr *)conn->dst, get_addr_len(conn->dst)) == -1) {
+       /* address may contain a custom family that is used to adjust the
+        * length (abns vs abnsz).
+        */
+       addr = *conn->dst;
+       addr_len = get_addr_len(&addr);
+       addr.ss_family = AF_UNIX;
+
+       if (connect(fd, (struct sockaddr *)&addr, addr_len) == -1) {
                if (errno == EINPROGRESS || errno == EALREADY) {
                        conn->flags |= CO_FL_WAIT_L4_CONN;
                }