WIP: make abns a custom unix socket address family
Now it looks better and seems to work fine. Both stream and dgram were converted, and regtests still pass. Some tests must be performed on the CLI with show sess and show fd to be sure.
This commit is contained in:
parent
e5e49d9cf2
commit
7f2b85773f
|
@ -40,7 +40,8 @@ struct connection;
|
|||
#define AF_CUST_EXISTING_FD (AF_MAX + 1)
|
||||
#define AF_CUST_SOCKPAIR (AF_MAX + 2)
|
||||
#define AF_CUST_RHTTP_SRV (AF_MAX + 3)
|
||||
#define AF_CUST_MAX (AF_MAX + 4)
|
||||
#define AF_CUST_ABNS (AF_MAX + 4)
|
||||
#define AF_CUST_MAX (AF_MAX + 5)
|
||||
|
||||
/*
|
||||
* Test in case AF_CUST_MAX overflows the sa_family_t (unsigned int)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <haproxy/receiver-t.h>
|
||||
|
||||
extern struct proto_fam proto_fam_unix;
|
||||
extern struct proto_fam proto_fam_abns;
|
||||
|
||||
int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
|
||||
int sock_unix_bind_receiver(struct receiver *rx, char **errmsg);
|
||||
|
|
|
@ -710,7 +710,10 @@ static inline int is_inet_addr(const struct sockaddr_storage *addr)
|
|||
*/
|
||||
static inline int is_addr(const struct sockaddr_storage *addr)
|
||||
{
|
||||
if (addr->ss_family == AF_UNIX || addr->ss_family == AF_CUST_SOCKPAIR)
|
||||
/* WT: ideally we should use real_family(addr->ss_family) here, but we
|
||||
* have so few custom addresses that it's simple enough to test them all.
|
||||
*/
|
||||
if (addr->ss_family == AF_UNIX || addr->ss_family == AF_CUST_ABNS || addr->ss_family == AF_CUST_SOCKPAIR)
|
||||
return 1;
|
||||
else
|
||||
return is_inet_addr(addr);
|
||||
|
@ -749,6 +752,7 @@ static inline int get_addr_len(const struct sockaddr_storage *addr)
|
|||
case AF_INET6:
|
||||
return sizeof(struct sockaddr_in6);
|
||||
case AF_UNIX:
|
||||
case AF_CUST_ABNS:
|
||||
return sizeof(struct sockaddr_un);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -651,7 +651,7 @@ int listeners_setenv(struct proxy *frontend, const char *varname)
|
|||
if (trash->data)
|
||||
chunk_appendf(trash, ";");
|
||||
|
||||
if (l->rx.addr.ss_family == AF_UNIX) {
|
||||
if (l->rx.addr.ss_family == AF_UNIX || l->rx.addr.ss_family == AF_CUST_ABNS) {
|
||||
const struct sockaddr_un *un;
|
||||
|
||||
un = (struct sockaddr_un *)&l->rx.addr;
|
||||
|
@ -1579,7 +1579,7 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx)
|
|||
char addr[46];
|
||||
char port[6];
|
||||
|
||||
if (l->rx.addr.ss_family == AF_UNIX) {
|
||||
if (l->rx.addr.ss_family == AF_UNIX || l->rx.addr.ss_family == AF_CUST_ABNS) {
|
||||
const struct sockaddr_un *un;
|
||||
|
||||
un = (struct sockaddr_un *)&l->rx.addr;
|
||||
|
|
|
@ -67,7 +67,39 @@ struct protocol proto_uxdg = {
|
|||
.nb_receivers = 0,
|
||||
};
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
struct protocol proto_abns_dgram = {
|
||||
.name = "abns_dgram",
|
||||
|
||||
/* connection layer */
|
||||
.xprt_type = PROTO_TYPE_DGRAM,
|
||||
.listen = uxdg_bind_listener,
|
||||
.enable = uxdg_enable_listener,
|
||||
.disable = uxdg_disable_listener,
|
||||
.add = default_add_listener,
|
||||
.unbind = default_unbind_listener,
|
||||
.suspend = default_suspend_listener,
|
||||
.resume = default_resume_listener,
|
||||
|
||||
/* binding layer */
|
||||
.rx_suspend = uxdg_suspend_receiver,
|
||||
|
||||
/* address family */
|
||||
.fam = &proto_fam_abns,
|
||||
|
||||
/* socket layer */
|
||||
.proto_type = PROTO_TYPE_DGRAM,
|
||||
.sock_type = SOCK_DGRAM,
|
||||
.sock_prot = 0,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.receivers = LIST_HEAD_INIT(proto_abns_dgram.receivers),
|
||||
.nb_receivers = 0,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, protocol_register, &proto_uxdg);
|
||||
INITCALL1(STG_REGISTER, protocol_register, &proto_abns_dgram);
|
||||
|
||||
/* This function tries to bind dgram unix socket listener. It may return a warning or
|
||||
* an error message in <errmsg> if the message is at most <errlen> bytes long
|
||||
|
|
|
@ -85,7 +85,48 @@ struct protocol proto_uxst = {
|
|||
.nb_receivers = 0,
|
||||
};
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
struct protocol proto_abns_stream = {
|
||||
.name = "abns_stream",
|
||||
|
||||
/* connection layer */
|
||||
.xprt_type = PROTO_TYPE_STREAM,
|
||||
.listen = uxst_bind_listener,
|
||||
.enable = uxst_enable_listener,
|
||||
.disable = uxst_disable_listener,
|
||||
.add = default_add_listener,
|
||||
.unbind = default_unbind_listener,
|
||||
.suspend = default_suspend_listener,
|
||||
.resume = default_resume_listener,
|
||||
.accept_conn = sock_accept_conn,
|
||||
.ctrl_init = sock_conn_ctrl_init,
|
||||
.ctrl_close = sock_conn_ctrl_close,
|
||||
.connect = uxst_connect_server,
|
||||
.drain = sock_drain,
|
||||
.check_events = sock_check_events,
|
||||
.ignore_events = sock_ignore_events,
|
||||
|
||||
/* binding layer */
|
||||
.rx_suspend = uxst_suspend_receiver,
|
||||
|
||||
/* address family */
|
||||
.fam = &proto_fam_abns,
|
||||
|
||||
/* socket layer */
|
||||
.proto_type = PROTO_TYPE_STREAM,
|
||||
.sock_type = SOCK_STREAM,
|
||||
.sock_prot = 0,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_listening = sock_accepting_conn,
|
||||
.default_iocb = sock_accept_iocb,
|
||||
.receivers = LIST_HEAD_INIT(proto_abns_stream.receivers),
|
||||
.nb_receivers = 0,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, protocol_register, &proto_uxst);
|
||||
INITCALL1(STG_REGISTER, protocol_register, &proto_abns_stream);
|
||||
|
||||
/********************************
|
||||
* 1) low-level socket functions
|
||||
|
|
|
@ -29,8 +29,9 @@
|
|||
#include <haproxy/fd.h>
|
||||
#include <haproxy/global.h>
|
||||
#include <haproxy/listener.h>
|
||||
#include <haproxy/receiver-t.h>
|
||||
#include <haproxy/namespace.h>
|
||||
#include <haproxy/protocol.h>
|
||||
#include <haproxy/receiver-t.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/sock_unix.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
@ -49,6 +50,19 @@ struct proto_fam proto_fam_unix = {
|
|||
.get_dst = sock_get_dst,
|
||||
};
|
||||
|
||||
struct proto_fam proto_fam_abns = {
|
||||
.name = "abns",
|
||||
.sock_domain = AF_UNIX,
|
||||
.sock_family = AF_CUST_ABNS,
|
||||
.real_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
|
||||
|
@ -71,10 +85,10 @@ int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_st
|
|||
const struct sockaddr_un *bu = (const struct sockaddr_un *)b;
|
||||
int idx, dot, idx2;
|
||||
|
||||
if (a->ss_family != b->ss_family)
|
||||
if (real_family(a->ss_family) != real_family(b->ss_family))
|
||||
return -1;
|
||||
|
||||
if (a->ss_family != AF_UNIX)
|
||||
if (real_family(a->ss_family) != AF_UNIX)
|
||||
return -1;
|
||||
|
||||
if (au->sun_path[0] != bu->sun_path[0])
|
||||
|
|
|
@ -1043,7 +1043,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
|||
else if (strncmp(str2, "abns@", 5) == 0) {
|
||||
str2 += 5;
|
||||
abstract = 1;
|
||||
ss.ss_family = AF_UNIX;
|
||||
ss.ss_family = AF_CUST_ABNS;
|
||||
}
|
||||
else if (strncmp(str2, "ip@", 3) == 0) {
|
||||
str2 += 3;
|
||||
|
@ -1186,7 +1186,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
else if (ss.ss_family == AF_UNIX) {
|
||||
else if (ss.ss_family == AF_UNIX || ss.ss_family == AF_CUST_ABNS) {
|
||||
struct sockaddr_un *un = (struct sockaddr_un *)&ss;
|
||||
int prefix_path_len;
|
||||
int max_path_len;
|
||||
|
@ -1435,6 +1435,7 @@ char * sa2str(const struct sockaddr_storage *addr, int port, int map_ports)
|
|||
ptr = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
||||
break;
|
||||
case AF_UNIX:
|
||||
case AF_CUST_ABNS:
|
||||
path = ((struct sockaddr_un *)addr)->sun_path;
|
||||
if (path[0] == '\0') {
|
||||
const int max_length = sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path) - 1;
|
||||
|
@ -1882,6 +1883,7 @@ int addr_to_str(const struct sockaddr_storage *addr, char *str, int size)
|
|||
ptr = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
||||
break;
|
||||
case AF_UNIX:
|
||||
case AF_CUST_ABNS:
|
||||
memcpy(str, "unix", 5);
|
||||
return addr->ss_family;
|
||||
default:
|
||||
|
@ -1919,6 +1921,7 @@ int port_to_str(const struct sockaddr_storage *addr, char *str, int size)
|
|||
port = ((struct sockaddr_in6 *)addr)->sin6_port;
|
||||
break;
|
||||
case AF_UNIX:
|
||||
case AF_CUST_ABNS:
|
||||
memcpy(str, "unix", 5);
|
||||
return addr->ss_family;
|
||||
default:
|
||||
|
@ -6352,6 +6355,7 @@ const char *hash_ipanon(uint32_t scramble, char *ipstring, int hasport)
|
|||
break;
|
||||
|
||||
case AF_UNIX:
|
||||
case AF_CUST_ABNS:
|
||||
return HA_ANON_STR(scramble, ipstring);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue