]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: add a new proto_fam structure for protocol families
authorWilly Tarreau <w@1wt.eu>
Fri, 4 Sep 2020 06:07:11 +0000 (08:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Sep 2020 20:08:07 +0000 (22:08 +0200)
We need to specially handle protocol families which regroup common
functions used for a given address family. These functions include
bind(), addrcmp(), get_src() and get_dst() for now. Some fields are
also added about the address family, socket domain (protocol family
passed to the socket() syscall), and address length.

These protocol families are referenced from the protocols but not yet
used.

include/haproxy/proto_sockpair.h
include/haproxy/protocol-t.h
include/haproxy/sock_inet.h
include/haproxy/sock_unix.h
src/proto_sockpair.c
src/proto_tcp.c
src/proto_udp.c
src/proto_uxst.c
src/sock_inet.c
src/sock_unix.c

index b04ebea38ee9648a3a723b557fcf1ac7d27a0d68..6807169a797af1e36f9fc8508e8a4956ef280f05 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef _HAPROXY_PROTO_SOCKPAIR_H
 #define _HAPROXY_PROTO_SOCKPAIR_H
 
+extern struct proto_fam proto_fam_sockpair;
+
 int recv_fd_uxst(int sock);
 int send_fd_uxst(int fd, int send_fd);
 int sockpair_bind_receiver(struct receiver *rx, void (*handler)(int fd), char **errmsg);
index f29c9443569c3dc2d0100f99a6850a36a2191e9c..fe0c9812ad389aeadd6bfb42cdf2ad8d1f871f58 100644 (file)
@@ -58,6 +58,21 @@ struct connection;
 #define CONNECT_DELACK_ALWAYS                   0x00000004 /* Use a delayed ACK */
 #define CONNECT_CAN_USE_TFO                     0x00000008 /* We can use TFO for this connection */
 
+/* protocol families define standard functions acting on a given address family
+ * for a socket implementation, such as AF_INET/PF_INET for example.
+ */
+struct proto_fam {
+       char name[PROTO_NAME_LEN];                      /* family name, zero-terminated */
+       int sock_domain;                                /* socket domain, as passed to socket()   */
+       sa_family_t sock_family;                        /* socket family, for sockaddr */
+       socklen_t sock_addrlen;                         /* socket address length, used by bind() */
+       int l3_addrlen;                                 /* layer3 address length, used by hashes */
+       int (*addrcmp)(const struct sockaddr_storage *, const struct sockaddr_storage *); /* compare addresses (like memcmp) */
+       int (*bind)(struct receiver *rx, void (*handler)(int fd), char **errmsg); /* bind a receiver */
+       int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
+       int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
+};
+
 /* This structure contains all information needed to easily handle a protocol.
  * Its primary goal is to ease listeners maintenance. Specifically, the
  * bind() primitive must be used before any fork(), and the enable_all()
@@ -65,6 +80,7 @@ struct connection;
  */
 struct protocol {
        char name[PROTO_NAME_LEN];                      /* protocol name, zero-terminated */
+       struct proto_fam *fam;                          /* protocol family */
        int sock_domain;                                /* socket domain, as passed to socket()   */
        int sock_type;                                  /* socket type, as passed to socket()     */
        int sock_prot;                                  /* socket protocol, as passed to socket() */
index 9f95679b2e48659401c83c22e58f100322325a04..7ecdc7b6079f8bcca27c2221a62a12cf2feba856 100644 (file)
@@ -31,6 +31,9 @@ extern int sock_inet6_v6only_default;
 extern int sock_inet_tcp_maxseg_default;
 extern int sock_inet6_tcp_maxseg_default;
 
+extern struct proto_fam proto_fam_inet4;
+extern struct proto_fam proto_fam_inet6;
+
 int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
 int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
 int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
index 38ededaa0055f1ea12d7ed9cb5f487896d72277a..3b46b484223609a93dad4b725faa44ff4144e326 100644 (file)
@@ -28,6 +28,8 @@
 #include <haproxy/api.h>
 #include <haproxy/receiver-t.h>
 
+extern struct proto_fam proto_fam_unix;
+
 int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
 int sock_unix_bind_receiver(struct receiver *rx, void (*handler)(int fd), char **errmsg);
 
index a920f4e61dd35ecd36af38601a471b19502368e0..a2a9607a822e9f34b3b838cd6e55fddb6dcb3a0c 100644 (file)
@@ -45,9 +45,22 @@ static void sockpair_add_listener(struct listener *listener, int port);
 static int sockpair_bind_listener(struct listener *listener, char *errmsg, int errlen);
 static int sockpair_connect_server(struct connection *conn, int flags);
 
+struct proto_fam proto_fam_sockpair = {
+       .name = "sockpair",
+       .sock_domain = AF_CUST_SOCKPAIR,
+       .sock_family = AF_UNIX,
+       .sock_addrlen = sizeof(struct sockaddr_un),
+       .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),
+       .addrcmp = NULL,
+       .bind = sockpair_bind_receiver,
+       .get_src = NULL,
+       .get_dst = NULL,
+};
+
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_sockpair = {
        .name = "sockpair",
+       .fam = &proto_fam_sockpair,
        .sock_domain = AF_CUST_SOCKPAIR,
        .sock_type = SOCK_STREAM,
        .sock_prot = 0,
index 4af22e557a2a313d8b04aff3a14b1939175d66b5..cb4dc32020bcf90011ee292d00c6ecbf16124dbc 100644 (file)
@@ -51,6 +51,7 @@ static void tcpv6_add_listener(struct listener *listener, int port);
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_tcpv4 = {
        .name = "tcpv4",
+       .fam = &proto_fam_inet4,
        .sock_domain = AF_INET,
        .sock_type = SOCK_STREAM,
        .sock_prot = IPPROTO_TCP,
@@ -76,6 +77,7 @@ INITCALL1(STG_REGISTER, protocol_register, &proto_tcpv4);
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_tcpv6 = {
        .name = "tcpv6",
+       .fam = &proto_fam_inet6,
        .sock_domain = AF_INET6,
        .sock_type = SOCK_STREAM,
        .sock_prot = IPPROTO_TCP,
index 43eff39c47e8a40aa2561774280c8bcf5e6e343d..d4d6b2afa5e0344c8bb4e1c7dbeb5e10679d5bcf 100644 (file)
@@ -47,6 +47,7 @@ static void udp6_add_listener(struct listener *listener, int port);
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_udp4 = {
        .name = "udp4",
+       .fam = &proto_fam_inet4,
        .sock_domain = AF_CUST_UDP4,
        .sock_type = SOCK_DGRAM,
        .sock_prot = IPPROTO_UDP,
@@ -72,6 +73,7 @@ INITCALL1(STG_REGISTER, protocol_register, &proto_udp4);
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_udp6 = {
        .name = "udp6",
+       .fam = &proto_fam_inet6,
        .sock_domain = AF_CUST_UDP6,
        .sock_type = SOCK_DGRAM,
        .sock_prot = IPPROTO_UDP,
index 5ceb18f13d20502dc1131785047d5abc34036fcc..0b8e1767d933a9d6306a0150c8b784219c05caf9 100644 (file)
@@ -48,6 +48,7 @@ static int uxst_pause_listener(struct listener *l);
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_unix = {
        .name = "unix_stream",
+       .fam = &proto_fam_unix,
        .sock_domain = PF_UNIX,
        .sock_type = SOCK_STREAM,
        .sock_prot = 0,
index 3bb4f34bfa0b9586616bff1307f45ef1dad59a36..09ff71e5ea2921137ab01ef4e1390a7cfc6e9b60 100644 (file)
 #include <haproxy/sock_inet.h>
 #include <haproxy/tools.h>
 
+struct proto_fam proto_fam_inet4 = {
+       .name = "inet4",
+       .sock_domain = PF_INET,
+       .sock_family = AF_INET,
+       .sock_addrlen = sizeof(struct sockaddr_in),
+       .l3_addrlen = 32/8,
+       .addrcmp = sock_inet4_addrcmp,
+       .bind = sock_inet_bind_receiver,
+       .get_src = sock_get_src,
+       .get_dst = sock_inet_get_dst,
+};
+
+struct proto_fam proto_fam_inet6 = {
+       .name = "inet6",
+       .sock_domain = PF_INET6,
+       .sock_family = AF_INET6,
+       .sock_addrlen = sizeof(struct sockaddr_in6),
+       .l3_addrlen = 128/8,
+       .addrcmp = sock_inet6_addrcmp,
+       .bind = sock_inet_bind_receiver,
+       .get_src = sock_get_src,
+       .get_dst = sock_get_dst,
+};
 
 /* PLEASE NOTE for function below:
  *   - sock_inet4_* is solely for AF_INET (IPv4)
index 04accb4be37647d0b259993769e8df3987a3d517..4620b74404b06e2a1e8e9624a2d03788520b0a51 100644 (file)
 #include <haproxy/tools.h>
 
 
+struct proto_fam proto_fam_unix = {
+       .name = "unix",
+       .sock_domain = PF_UNIX,
+       .sock_family = AF_UNIX,
+       .sock_addrlen = sizeof(struct sockaddr_un),
+       .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),
+       .addrcmp = sock_unix_addrcmp,
+       .bind = sock_unix_bind_receiver,
+       .get_src = sock_get_src,
+       .get_dst = sock_get_dst,
+};
+
 /* PLEASE NOTE for functions below:
  *
  * The address family SHOULD always be checked. In some cases a function will