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.
This commit is contained in:
Willy Tarreau 2025-02-21 07:53:21 +01:00
parent 390df282c1
commit aac570cd03

View 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;
}