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.
This commit is contained in:
Aurelien DARRAGON 2024-10-28 15:02:19 +01:00
parent d879bf6600
commit 43861e3234
2 changed files with 59 additions and 17 deletions

View File

@ -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 */

View File

@ -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,12 +85,58 @@ 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_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;
if (a->ss_family != b->ss_family)
return -1;
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 -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)
{
@ -98,19 +144,13 @@ int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_st
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_UNIX)
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));
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;