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.
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");