From: Aurelien DARRAGON Date: Mon, 28 Oct 2024 14:02:19 +0000 (+0100) Subject: MEDIUM: sock_unix: use per-family addrcmp function X-Git-Tag: v3.1-dev11~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43861e32341a95ddf75f4b2134bc5c7da02891a9;p=thirdparty%2Fhaproxy.git MEDIUM: sock_unix: use per-family addrcmp function Thanks to previous commit, we may now use dedicated addrcmp functions for each UNIX address family. This allows to simplify sock_unix_addrcmp() function and avoid useless checks in order to try to guess the socket type. In this patch we implement sock_abns_addrcmp() and sock_abnsz_addrcmp() functions, which are respectively used for ABNS and ABNSZ custom families sock_unix_addrcmp() now only holds regular UNIX socket comparing logic. --- diff --git a/include/haproxy/sock_unix.h b/include/haproxy/sock_unix.h index 39583e9f9b..9431094f30 100644 --- a/include/haproxy/sock_unix.h +++ b/include/haproxy/sock_unix.h @@ -33,6 +33,8 @@ extern struct proto_fam proto_fam_abns; extern struct proto_fam proto_fam_abnsz; int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); +int sock_abns_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); +int sock_abnsz_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); int sock_unix_bind_receiver(struct receiver *rx, char **errmsg); #endif /* _HAPROXY_SOCK_UNIX_H */ diff --git a/src/sock_unix.c b/src/sock_unix.c index 8785845b31..22ab862f5e 100644 --- a/src/sock_unix.c +++ b/src/sock_unix.c @@ -57,7 +57,7 @@ struct proto_fam proto_fam_abns = { .real_family = AF_UNIX, .sock_addrlen = sizeof(struct sockaddr_un), .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path), - .addrcmp = sock_unix_addrcmp, + .addrcmp = sock_abns_addrcmp, .bind = sock_unix_bind_receiver, .get_src = sock_get_src, .get_dst = sock_get_dst, @@ -70,7 +70,7 @@ struct proto_fam proto_fam_abnsz = { .real_family = AF_UNIX, .sock_addrlen = sizeof(struct sockaddr_un), .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path), - .addrcmp = sock_unix_addrcmp, + .addrcmp = sock_abnsz_addrcmp, .bind = sock_unix_bind_receiver, .get_src = sock_get_src, .get_dst = sock_get_dst, @@ -85,32 +85,72 @@ struct proto_fam proto_fam_abnsz = { */ -/* Compares two AF_UNIX sockaddr addresses. Returns 0 if they match or non-zero - * if they do not match. It also supports ABNS socket addresses (those starting - * with \0). For regular UNIX sockets however, this does explicitly support - * matching names ending exactly with .XXXXX.tmp which are newly bound sockets - * about to be replaced; this suffix is then ignored. Note that our UNIX socket - * paths are always zero-terminated. +/* Compares two AF_CUST_ABNS sockaddr addresses (ABNS UNIX sockets). Returns 0 if + * they match or non-zero. */ -int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b) +int sock_abns_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b) { const struct sockaddr_un *au = (const struct sockaddr_un *)a; const struct sockaddr_un *bu = (const struct sockaddr_un *)b; - int idx, dot, idx2; - if (real_family(a->ss_family) != real_family(b->ss_family)) + if (a->ss_family != b->ss_family) return -1; - if (real_family(a->ss_family) != AF_UNIX) + if (a->ss_family != AF_CUST_ABNS) return -1; if (au->sun_path[0] != bu->sun_path[0]) return -1; - if (au->sun_path[0] == 0) - return memcmp(au->sun_path, bu->sun_path, sizeof(au->sun_path)); + if (au->sun_path[0] != '\0') + return -1; + + return memcmp(au->sun_path, bu->sun_path, sizeof(au->sun_path)); +} + + +/* Compares two AF_CUST_ABNSZ sockaddr addresses (ABNSZ UNIX sockets). Returns 0 if + * they match or non-zero. + */ +int sock_abnsz_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b) +{ + const struct sockaddr_un *au = (const struct sockaddr_un *)a; + const struct sockaddr_un *bu = (const struct sockaddr_un *)b; + + if (a->ss_family != b->ss_family) + return -1; + + if (a->ss_family != AF_CUST_ABNSZ) + return -1; + + if (au->sun_path[0] != bu->sun_path[0]) + return -1; + + if (au->sun_path[0] != '\0') + return -1; + + return strncmp(au->sun_path + 1, bu->sun_path + 1, sizeof(au->sun_path) - 1); +} + +/* Compares two AF_UNIX sockaddr addresses (regular UNIX sockets). Returns 0 if + * they match or non-zero. Tis does explicitly support matching names ending + * exactly with .XXXXX.tmp which are newly bound sockets about to be replaced; + * this suffix is then ignored. Note that our UNIX socket paths are always + * zero-terminated. + */ +int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b) +{ + const struct sockaddr_un *au = (const struct sockaddr_un *)a; + const struct sockaddr_un *bu = (const struct sockaddr_un *)b; + int idx, dot, idx2; + + if (a->ss_family != b->ss_family) + return -1; + + if (a->ss_family != AF_UNIX) + return -1; - idx = 1; dot = 0; + idx = 0; dot = 0; while (au->sun_path[idx] == bu->sun_path[idx]) { if (au->sun_path[idx] == 0) return 0;