#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> */
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;
}
/* 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()
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);
}
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)
/* 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) {
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;
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) {
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;
}
* 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)) {