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.
This commit is contained in:
Willy Tarreau 2021-10-27 17:28:55 +02:00
parent 337edfdbc5
commit e3b4518414
5 changed files with 44 additions and 29 deletions

View File

@ -27,7 +27,7 @@
#include <haproxy/thread.h>
/* [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 <proto> */
@ -86,14 +86,14 @@ static inline struct protocol *protocol_by_family(int family)
return NULL;
}
/* returns the protocol associated to family <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 <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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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)) {