From e3b45184143a1561167ae2fd7ad41d4b0a845b58 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 27 Oct 2021 17:28:55 +0200 Subject: [PATCH] MINOR: protocols: make use of the protocol type to select the protocol Instead of using sock_type and ctrl_type to select a protocol, let's make use of the new protocol type. For now they always match so there is no change. This is applied to address parsing and to socket retrieval from older processes. --- include/haproxy/protocol.h | 12 ++++----- src/cfgparse.c | 2 +- src/protocol.c | 5 ++-- src/sock.c | 2 +- src/tools.c | 52 ++++++++++++++++++++++++-------------- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/include/haproxy/protocol.h b/include/haproxy/protocol.h index eba28e5ad..0c52bf705 100644 --- a/include/haproxy/protocol.h +++ b/include/haproxy/protocol.h @@ -27,7 +27,7 @@ #include /* [AF][sock_dgram][ctrl_dgram] */ -extern struct protocol *__protocol_by_family[AF_CUST_MAX][2][2]; +extern struct protocol *__protocol_by_family[AF_CUST_MAX][PROTO_NUM_TYPES][2]; __decl_thread(extern HA_SPINLOCK_T proto_lock); /* Registers the protocol */ @@ -86,14 +86,14 @@ static inline struct protocol *protocol_by_family(int family) return NULL; } -/* returns the protocol associated to family with sock_type and - * ctrl_type of either SOCK_STREAM or SOCK_DGRAM depending on the requested - * values, or NULL if not found. +/* returns the protocol associated to family with proto_type among the + * supported protocol types, and ctrl_type of either SOCK_STREAM or SOCK_DGRAM + * depending on the requested values, or NULL if not found. */ -static inline struct protocol *protocol_lookup(int family, int sock_dgram, int ctrl_dgram) +static inline struct protocol *protocol_lookup(int family, enum proto_type proto_type, int ctrl_dgram) { if (family >= 0 && family < AF_CUST_MAX) - return __protocol_by_family[family][!!sock_dgram][!!ctrl_dgram]; + return __protocol_by_family[family][proto_type][!!ctrl_dgram]; return NULL; } diff --git a/src/cfgparse.c b/src/cfgparse.c index 892170284..ed5efda6d 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -161,7 +161,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, * is selected, regardless of bind_conf settings. We then need * to initialize QUIC params. */ - if (proto->sock_type == SOCK_DGRAM && proto->ctrl_type == SOCK_STREAM) { + if (proto->proto_type == PROTO_TYPE_DGRAM && proto->ctrl_type == SOCK_STREAM) { bind_conf->xprt = xprt_get(XPRT_QUIC); quic_transport_params_init(&bind_conf->quic_params, 1); } diff --git a/src/protocol.c b/src/protocol.c index dc0e41d74..3d908a133 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -24,7 +24,7 @@ /* List head of all registered protocols */ static struct list protocols = LIST_HEAD_INIT(protocols); -struct protocol *__protocol_by_family[AF_CUST_MAX][2][2] __read_mostly = { }; +struct protocol *__protocol_by_family[AF_CUST_MAX][PROTO_NUM_TYPES][2] __read_mostly = { }; /* This is the global spinlock we may need to register/unregister listeners or * protocols. Its main purpose is in fact to serialize the rare stop/deinit() @@ -38,11 +38,12 @@ void protocol_register(struct protocol *proto) int sock_domain = proto->fam->sock_domain; BUG_ON(sock_domain < 0 || sock_domain >= AF_CUST_MAX); + BUG_ON(proto->proto_type >= PROTO_NUM_TYPES); HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); LIST_APPEND(&protocols, &proto->list); __protocol_by_family[sock_domain] - [proto->sock_type == SOCK_DGRAM] + [proto->proto_type] [proto->ctrl_type == SOCK_DGRAM] = proto; HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock); } diff --git a/src/sock.c b/src/sock.c index e546d8f4a..e3d4a6e4c 100644 --- a/src/sock.c +++ b/src/sock.c @@ -545,7 +545,7 @@ int sock_find_compatible_fd(const struct receiver *rx) if (!rx->proto->fam->addrcmp) return -1; - if (rx->proto->sock_type == SOCK_DGRAM) + if (rx->proto->proto_type == PROTO_TYPE_DGRAM) options |= SOCK_XFER_OPT_DGRAM; if (rx->settings->options & RX_O_FOREIGN) diff --git a/src/tools.c b/src/tools.c index 144ef7eaf..8fc67163a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -946,7 +946,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int int portl, porth, porta; int abstract = 0; int new_fd = -1; - int sock_type, ctrl_type; + enum proto_type proto_type; + int ctrl_type; portl = porth = porta = 0; if (fqdn) @@ -967,18 +968,23 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int /* prepare the default socket types */ if ((opts & (PA_O_STREAM|PA_O_DGRAM)) == PA_O_DGRAM || - ((opts & (PA_O_STREAM|PA_O_DGRAM)) == (PA_O_DGRAM|PA_O_STREAM) && (opts & PA_O_DEFAULT_DGRAM))) - sock_type = ctrl_type = SOCK_DGRAM; - else - sock_type = ctrl_type = SOCK_STREAM; + ((opts & (PA_O_STREAM|PA_O_DGRAM)) == (PA_O_DGRAM|PA_O_STREAM) && (opts & PA_O_DEFAULT_DGRAM))) { + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; + } else { + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; + } if (strncmp(str2, "stream+", 7) == 0) { str2 += 7; - sock_type = ctrl_type = SOCK_STREAM; + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "dgram+", 6) == 0) { str2 += 6; - sock_type = ctrl_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; } if (strncmp(str2, "unix@", 5) == 0) { @@ -990,13 +996,15 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int str2 += 5; abstract = 0; ss.ss_family = AF_UNIX; - sock_type = ctrl_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; } else if (strncmp(str2, "uxst@", 5) == 0) { str2 += 5; abstract = 0; ss.ss_family = AF_UNIX; - sock_type = ctrl_type = SOCK_STREAM; + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "abns@", 5) == 0) { str2 += 5; @@ -1018,43 +1026,49 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int else if (strncmp(str2, "tcp4@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET; - sock_type = ctrl_type = SOCK_STREAM; + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "udp4@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET; - sock_type = ctrl_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; } else if (strncmp(str2, "tcp6@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET6; - sock_type = ctrl_type = SOCK_STREAM; + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "udp6@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET6; - sock_type = ctrl_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; } else if (strncmp(str2, "tcp@", 4) == 0) { str2 += 4; ss.ss_family = AF_UNSPEC; - sock_type = ctrl_type = SOCK_STREAM; + proto_type = PROTO_TYPE_STREAM; + ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "udp@", 4) == 0) { str2 += 4; ss.ss_family = AF_UNSPEC; - sock_type = ctrl_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; + ctrl_type = SOCK_DGRAM; } else if (strncmp(str2, "quic4@", 6) == 0) { str2 += 6; ss.ss_family = AF_INET; - sock_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "quic6@", 6) == 0) { str2 += 6; ss.ss_family = AF_INET6; - sock_type = SOCK_DGRAM; + proto_type = PROTO_TYPE_DGRAM; ctrl_type = SOCK_STREAM; } else if (strncmp(str2, "fd@", 3) == 0) { @@ -1113,7 +1127,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int addr_len = sizeof(type); if (getsockopt(new_fd, SOL_SOCKET, SO_TYPE, &type, &addr_len) != 0 || - (type == SOCK_STREAM) != (sock_type == SOCK_STREAM)) { + (type == SOCK_STREAM) != (proto_type == PROTO_TYPE_STREAM)) { memprintf(err, "socket on file descriptor '%d' is of the wrong type.\n", new_fd); goto out; } @@ -1280,7 +1294,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int * for servers actually). */ new_proto = protocol_lookup(ss.ss_family, - sock_type == SOCK_DGRAM, + proto_type, ctrl_type == SOCK_DGRAM); if (!new_proto && (!fqdn || !*fqdn) && (ss.ss_family != AF_CUST_EXISTING_FD)) {