MINOR: sock: restore effective UNIX family in sock_get_old_sockets()

When getting sockets from older process in sock_get_old_sockets(), we
leverage getsockname() to fill sockaddr struct from known fd.

However, the kernel doesn't know about our custom UNIX families such
as CUST_ABNS and CUST_ABNSZ which are both based on AF_UNIX real family.

Since haproxy socket API relies on effective family (and not real family)
to recognize the socket type instead of having to guess it by analyzing
the path content, let's restore it right after getsockname() since we
have all the infos needed to deduce the right family.

If the path starts with a NULL byte, we know that it is an abstract sock.
Then we simply check <addrlen> value from getsockname() to know if the
addr makes uses of the whole path space (normal ABNS) or partial path
space (zero ABNS / aka ABNZ) terminated by 0.
This commit is contained in:
Aurelien DARRAGON 2024-10-28 15:17:10 +01:00
parent d24768ab44
commit ae64444303
1 changed files with 17 additions and 0 deletions

View File

@ -600,6 +600,23 @@ int sock_get_old_sockets(const char *unixsocket)
ha_free(&xfer_sock);
continue;
}
if (xfer_sock->addr.ss_family == AF_UNIX) {
const struct sockaddr_un *un = (const struct sockaddr_un *)&xfer_sock->addr;
/* restore effective family if needed, because getsockname()
* only knows about real families:
*/
if (un->sun_path[0]); // regular UNIX socket, not a custom family
else if (socklen == sizeof(*un))
xfer_sock->addr.ss_family = AF_CUST_ABNS;
else {
/* not all struct sockaddr_un space is used..
* (sun_path is partially filled)
*/
xfer_sock->addr.ss_family = AF_CUST_ABNSZ;
}
}
if (curoff >= maxoff) {
ha_warning("Inconsistency while transferring sockets\n");