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