From aac570cd0384f7fb942e7eb1eeb8c7d0605f50e2 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 21 Feb 2025 07:53:21 +0100 Subject: [PATCH] BUG/MEDIUM: uxst: fix outgoing abns address family in connect() 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 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/proto_uxst.c b/src/proto_uxst.c index f8b6958091..8122ad384f 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -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; } -- 2.39.5