diff --git a/Makefile b/Makefile index d17f17e94..1f6adc46f 100644 --- a/Makefile +++ b/Makefile @@ -947,7 +947,8 @@ OBJS += src/mux_h2.o src/mux_fcgi.o src/mux_h1.o src/tcpcheck.o \ src/base64.o src/auth.o src/uri_auth.o src/time.o src/ebistree.o \ src/dynbuf.o src/wdt.o src/pipe.o src/init.o src/http_acl.o \ src/hpack-huff.o src/hpack-enc.o src/dict.o src/freq_ctr.o \ - src/ebtree.o src/hash.o src/dgram.o src/version.o + src/ebtree.o src/hash.o src/dgram.o src/version.o \ + src/proto_reverse_connect.o ifneq ($(TRACE),) OBJS += src/calltrace.o diff --git a/include/haproxy/proto_reverse_connect.h b/include/haproxy/proto_reverse_connect.h new file mode 100644 index 000000000..31edbb794 --- /dev/null +++ b/include/haproxy/proto_reverse_connect.h @@ -0,0 +1,13 @@ +#ifndef _HAPROXY_PROTO_REVERSE_CONNECT_H +#define _HAPROXY_PROTO_REVERSE_CONNECT_H + +#include +#include + +int rev_bind_receiver(struct receiver *rx, char **errmsg); + +int rev_bind_listener(struct listener *listener, char *errmsg, int errlen); + +int rev_accepting_conn(const struct receiver *rx); + +#endif /* _HAPROXY_PROTO_REVERSE_CONNECT_H */ diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 47df36641..7846fd5b8 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -39,7 +39,8 @@ struct connection; */ #define AF_CUST_EXISTING_FD (AF_MAX + 1) #define AF_CUST_SOCKPAIR (AF_MAX + 2) -#define AF_CUST_MAX (AF_MAX + 3) +#define AF_CUST_REV_SRV (AF_MAX + 3) +#define AF_CUST_MAX (AF_MAX + 4) /* * Test in case AF_CUST_MAX overflows the sa_family_t (unsigned int) diff --git a/src/proto_reverse_connect.c b/src/proto_reverse_connect.c new file mode 100644 index 000000000..621f32871 --- /dev/null +++ b/src/proto_reverse_connect.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +#include + +struct proto_fam proto_fam_reverse_connect = { + .name = "reverse_connect", + .sock_domain = AF_CUST_REV_SRV, + .sock_family = AF_INET, + .bind = rev_bind_receiver, +}; + +struct protocol proto_reverse_connect = { + .name = "rev", + + /* connection layer */ + .listen = rev_bind_listener, + .add = default_add_listener, + + /* address family */ + .fam = &proto_fam_reverse_connect, + + /* socket layer */ + .proto_type = PROTO_TYPE_STREAM, + .sock_type = SOCK_STREAM, + .sock_prot = IPPROTO_TCP, + .rx_listening = rev_accepting_conn, + .receivers = LIST_HEAD_INIT(proto_reverse_connect.receivers), +}; + +int rev_bind_receiver(struct receiver *rx, char **errmsg) +{ + return ERR_NONE; +} + +int rev_bind_listener(struct listener *listener, char *errmsg, int errlen) +{ + return ERR_NONE; +} + +int rev_accepting_conn(const struct receiver *rx) +{ + return 1; +} + +INITCALL1(STG_REGISTER, protocol_register, &proto_reverse_connect); diff --git a/src/tools.c b/src/tools.c index 7e75e74a8..a9a114bca 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1101,6 +1101,10 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int str2 += 9; ss.ss_family = AF_CUST_SOCKPAIR; } + else if (strncmp(str2, "rev@", 3) == 0) { + str2 += 4; + ss.ss_family = AF_CUST_REV_SRV; + } else if (*str2 == '/') { ss.ss_family = AF_UNIX; } @@ -1188,6 +1192,9 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int memcpy(un->sun_path, pfx, prefix_path_len); memcpy(un->sun_path + prefix_path_len + abstract, str2, adr_len + 1 - abstract); } + else if (ss.ss_family == AF_CUST_REV_SRV) { + /* Nothing to do here. */ + } else { /* IPv4 and IPv6 */ char *end = str2 + strlen(str2); char *chr;