Hi Willy,
Could you please let me know what your findings are about the proposed
patch?
Does it need some more work, is it implemented wrongly, or would it help
if i send my current haproxy.cfg file?
If i need to change something please let me know, thanks.
Thanks for your time,
PiBa-NL
Op 3-5-2013 18:03, Willy Tarreau schreef:
Hi,
sorry, I missed it.
I'll give it a look and merge it if it's OK.
Thanks, Willy
Op 27-4-2013 18:08, PiBa-NL schreef:
Hi Willy,
I generated 2 patch files:
-"FreeBSD IP_BINDANY git diff.patch" generated with a git diff
(against a hopefully relatively recent source tree)(i couldnt get it
to fetch http://git.1wt.eu/git/haproxy.git ..)
-"FreeBSD IP_BINDANY diff -urN.patch" generated with diff -urN
(against the 'port source')
I hope one of them can be used by you.
Please take a look and comment if something is amiss.
Greetings
PiBa-NL
diff -urN workoriginal/haproxy-1.5-dev18/include/common/compat.h
work/haproxy-1.5-dev18/include/common/compat.h
--- workoriginal/haproxy-1.5-dev18/include/common/compat.h 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/include/common/compat.h 2013-04-27
14:56:27.000000000 +0000
@@ -93,6 +93,15 @@
#endif /* !IPV6_TRANSPARENT */
#endif /* CONFIG_HAP_LINUX_TPROXY */
+#if (defined(SOL_IP) && defined(IP_TRANSPARENT)) \
+ || (defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)) \
+ || (defined(SOL_IP) && defined(IP_FREEBIND)) \
+ || (defined(IPPROTO_IP) && defined(IP_BINDANY)) \
+ || (defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)) \
+ || (defined(SOL_SOCKET) && defined(SO_BINDANY))
+ #define HAP_TRANSPARENT
+#endif
+
/* We'll try to enable SO_REUSEPORT on Linux 2.4 and 2.6 if not defined.
* There are two families of values depending on the architecture. Those
* are at least valid on Linux 2.4 and 2.6, reason why we'll rely on the
diff -urN workoriginal/haproxy-1.5-dev18/include/types/connection.h
work/haproxy-1.5-dev18/include/types/connection.h
--- workoriginal/haproxy-1.5-dev18/include/types/connection.h 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/include/types/connection.h 2013-04-27
14:56:30.000000000 +0000
@@ -219,7 +219,7 @@
char *iface_name; /* bind interface name or NULL */
struct port_range *sport_range; /* optional per-server TCP source
ports */
struct sockaddr_storage source_addr; /* the address to which we want to
bind for connect() */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
struct sockaddr_storage tproxy_addr; /* non-local address we want to
bind to for connect() */
char *bind_hdr_name; /* bind to this header name if
defined */
int bind_hdr_len; /* length of the name of the
header above */
diff -urN workoriginal/haproxy-1.5-dev18/src/backend.c
work/haproxy-1.5-dev18/src/backend.c
--- workoriginal/haproxy-1.5-dev18/src/backend.c 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/src/backend.c 2013-04-27 14:56:32.000000000
+0000
@@ -884,7 +884,7 @@
*/
static void assign_tproxy_address(struct session *s)
{
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
struct server *srv = objt_server(s->target);
struct conn_src *src;
diff -urN workoriginal/haproxy-1.5-dev18/src/cfgparse.c
work/haproxy-1.5-dev18/src/cfgparse.c
--- workoriginal/haproxy-1.5-dev18/src/cfgparse.c 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/src/cfgparse.c 2013-04-27 14:56:33.000000000
+0000
@@ -4535,8 +4535,8 @@
cur_arg += 2;
while (*(args[cur_arg])) {
if (!strcmp(args[cur_arg], "usesrc")) {
/* address to use outside */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
+#if !defined(HAP_TRANSPARENT)
if
(!is_addr(&newsrv->conn_src.source_addr)) {
Alert("parsing [%s:%d]
: '%s' requires an explicit '%s' address.\n",
file, linenum,
"usesrc", "source");
@@ -4625,7 +4625,7 @@
newsrv->conn_src.opts
|= CO_SRC_TPROXY_ADDR;
}
global.last_checks |=
LSTCHK_NETADM;
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if !defined(HAP_TRANSPARENT)
global.last_checks |=
LSTCHK_CTTPROXY;
#endif
cur_arg += 2;
@@ -4635,7 +4635,7 @@
file, linenum, "usesrc");
err_code |= ERR_ALERT |
ERR_FATAL;
goto out;
-#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY) */
+#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT) */
} /* "usesrc" */
if (!strcmp(args[cur_arg],
"interface")) { /* specifically bind to this interface */
@@ -5035,8 +5035,8 @@
cur_arg = 2;
while (*(args[cur_arg])) {
if (!strcmp(args[cur_arg], "usesrc")) { /* address to
use outside */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
+#if !defined(HAP_TRANSPARENT)
if (!is_addr(&curproxy->conn_src.source_addr)) {
Alert("parsing [%s:%d] : '%s' requires
an explicit 'source' address.\n",
file, linenum, "usesrc");
@@ -5125,7 +5125,7 @@
curproxy->conn_src.opts |=
CO_SRC_TPROXY_ADDR;
}
global.last_checks |= LSTCHK_NETADM;
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if !defined(HAP_TRANSPARENT)
global.last_checks |= LSTCHK_CTTPROXY;
#endif
#else /* no TPROXY support */
@@ -6802,7 +6802,7 @@
}
}
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
if (curproxy->conn_src.bind_hdr_occ) {
curproxy->conn_src.bind_hdr_occ = 0;
Warning("config : %s '%s' : ignoring use of
header %s as source IP in non-HTTP mode.\n",
@@ -6829,7 +6829,7 @@
err_code |= ERR_WARN;
}
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
if (curproxy->mode != PR_MODE_HTTP &&
newsrv->conn_src.bind_hdr_occ) {
newsrv->conn_src.bind_hdr_occ = 0;
Warning("config : %s '%s' : server %s cannot
use header %s as source IP in non-HTTP mode.\n",
diff -urN workoriginal/haproxy-1.5-dev18/src/haproxy.c
work/haproxy-1.5-dev18/src/haproxy.c
--- workoriginal/haproxy-1.5-dev18/src/haproxy.c 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/src/haproxy.c 2013-04-27 14:56:33.000000000
+0000
@@ -289,6 +289,29 @@
#else /* USE_OPENSSL */
printf("Built without OpenSSL support (USE_OPENSSL not set)\n");
#endif
+
+#ifdef HAP_TRANSPARENT
+ printf("Built with 'transparent proxy' support using:"
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ " IP_TRANSPARENT"
+ #endif
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ " IPV6_TRANSPARENT"
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ " IP_FREEBIND"
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ " IP_BINDANY"
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ " IPV6_BINDANY"
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ " SO_BINDANY"
+ #endif
+ "\n");
+#endif
putchar('\n');
list_pollers(stdout);
diff -urN workoriginal/haproxy-1.5-dev18/src/proto_tcp.c
work/haproxy-1.5-dev18/src/proto_tcp.c
--- workoriginal/haproxy-1.5-dev18/src/proto_tcp.c 2013-04-26
19:36:15.000000000 +0000
+++ work/haproxy-1.5-dev18/src/proto_tcp.c 2013-04-27 14:56:34.000000000
+0000
@@ -123,14 +123,26 @@
int foreign_ok = 0;
int ret;
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
static int ip_transp_working = 1;
static int ip6_transp_working = 1;
switch (local->ss_family) {
case AF_INET:
if (flags && ip_transp_working) {
- if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == 0
- || setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0)
+ int ret = 0;
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ ret |= setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ ret |= setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ ret |= setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ ret |= setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ if (ret)
foreign_ok = 1;
else
ip_transp_working = 0;
@@ -138,7 +150,14 @@
break;
case AF_INET6:
if (flags && ip6_transp_working) {
- if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == 0)
+ int ret = 0;
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ ret |= setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ ret |= setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ if (ret)
foreign_ok = 1;
else
ip6_transp_working = 0;
@@ -621,18 +640,36 @@
if (!ext)
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
if (!ext && (listener->options & LI_O_FOREIGN)) {
+ int ret = 0;
switch (listener->addr.ss_family) {
case AF_INET:
- if ((setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == -1)
- && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == -1)) {
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ ret = ret || setsockopt(fd, SOL_IP, IP_TRANSPARENT,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ ret = ret || setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ ret = ret || setsockopt(fd, IPPROTO_IP, IP_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ ret = ret || setsockopt(fd, SOL_SOCKET, SO_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ if (!ret){
msg = "cannot make listening socket
transparent";
err |= ERR_ALERT;
}
- break;
+ break;
case AF_INET6:
- if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == -1) {
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ ret = ret || setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ ret = ret || setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ if (!ret) {
msg = "cannot make listening socket
transparent";
err |= ERR_ALERT;
}
@@ -1546,7 +1583,7 @@
}
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
/* parse the "transparent" bind keyword */
static int bind_parse_transparent(char **args, int cur_arg, struct proxy *px,
struct bind_conf *conf, char **err)
{
@@ -1695,7 +1732,7 @@
#ifdef TCP_FASTOPEN
{ "tfo", bind_parse_tfo, 0 }, /* enable TCP_FASTOPEN
of listening socket */
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
{ "transparent", bind_parse_transparent, 0 }, /* transparently bind
to the specified addresses */
#endif
#ifdef IPV6_V6ONLY
include/common/compat.h | 9 +++++++
include/types/connection.h | 2 +-
src/backend.c | 2 +-
src/cfgparse.c | 18 +++++++-------
src/haproxy.c | 23 ++++++++++++++++++
src/proto_tcp.c | 59 +++++++++++++++++++++++++++++++++++++---------
6 files changed, 91 insertions(+), 22 deletions(-)
diff --git a/include/common/compat.h b/include/common/compat.h
index bb2d010..31fb9d9 100644
--- a/include/common/compat.h
+++ b/include/common/compat.h
@@ -93,6 +93,15 @@
#endif /* !IPV6_TRANSPARENT */
#endif /* CONFIG_HAP_LINUX_TPROXY */
+#if (defined(SOL_IP) && defined(IP_TRANSPARENT)) \
+ || (defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)) \
+ || (defined(SOL_IP) && defined(IP_FREEBIND)) \
+ || (defined(IPPROTO_IP) && defined(IP_BINDANY)) \
+ || (defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)) \
+ || (defined(SOL_SOCKET) && defined(SO_BINDANY))
+ #define HAP_TRANSPARENT
+#endif
+
/* We'll try to enable SO_REUSEPORT on Linux 2.4 and 2.6 if not defined.
* There are two families of values depending on the architecture. Those
* are at least valid on Linux 2.4 and 2.6, reason why we'll rely on the
diff --git a/include/types/connection.h b/include/types/connection.h
index 255811c..34fa7b0 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -219,7 +219,7 @@ struct conn_src {
char *iface_name; /* bind interface name or NULL */
struct port_range *sport_range; /* optional per-server TCP source
ports */
struct sockaddr_storage source_addr; /* the address to which we want to
bind for connect() */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
struct sockaddr_storage tproxy_addr; /* non-local address we want to
bind to for connect() */
char *bind_hdr_name; /* bind to this header name if
defined */
int bind_hdr_len; /* length of the name of the
header above */
diff --git a/src/backend.c b/src/backend.c
index 9f4e635..dc3c3c5 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -884,7 +884,7 @@ int assign_server_and_queue(struct session *s)
*/
static void assign_tproxy_address(struct session *s)
{
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
struct server *srv = objt_server(s->target);
struct conn_src *src;
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 49a91c0..39dd1fc 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4535,8 +4535,8 @@ stats_error_parsing:
cur_arg += 2;
while (*(args[cur_arg])) {
if (!strcmp(args[cur_arg], "usesrc")) {
/* address to use outside */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
+#if !defined(HAP_TRANSPARENT)
if
(!is_addr(&newsrv->conn_src.source_addr)) {
Alert("parsing [%s:%d]
: '%s' requires an explicit '%s' address.\n",
file, linenum,
"usesrc", "source");
@@ -4625,7 +4625,7 @@ stats_error_parsing:
newsrv->conn_src.opts
|= CO_SRC_TPROXY_ADDR;
}
global.last_checks |=
LSTCHK_NETADM;
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if !defined(HAP_TRANSPARENT)
global.last_checks |=
LSTCHK_CTTPROXY;
#endif
cur_arg += 2;
@@ -4635,7 +4635,7 @@ stats_error_parsing:
file, linenum, "usesrc");
err_code |= ERR_ALERT |
ERR_FATAL;
goto out;
-#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY) */
+#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT) */
} /* "usesrc" */
if (!strcmp(args[cur_arg],
"interface")) { /* specifically bind to this interface */
@@ -5035,8 +5035,8 @@ stats_error_parsing:
cur_arg = 2;
while (*(args[cur_arg])) {
if (!strcmp(args[cur_arg], "usesrc")) { /* address to
use outside */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
+#if !defined(HAP_TRANSPARENT)
if (!is_addr(&curproxy->conn_src.source_addr)) {
Alert("parsing [%s:%d] : '%s' requires
an explicit 'source' address.\n",
file, linenum, "usesrc");
@@ -5125,7 +5125,7 @@ stats_error_parsing:
curproxy->conn_src.opts |=
CO_SRC_TPROXY_ADDR;
}
global.last_checks |= LSTCHK_NETADM;
-#if !defined(CONFIG_HAP_LINUX_TPROXY)
+#if !defined(HAP_TRANSPARENT)
global.last_checks |= LSTCHK_CTTPROXY;
#endif
#else /* no TPROXY support */
@@ -6802,7 +6802,7 @@ out_uri_auth_compat:
}
}
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
if (curproxy->conn_src.bind_hdr_occ) {
curproxy->conn_src.bind_hdr_occ = 0;
Warning("config : %s '%s' : ignoring use of
header %s as source IP in non-HTTP mode.\n",
@@ -6829,7 +6829,7 @@ out_uri_auth_compat:
err_code |= ERR_WARN;
}
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+#if defined(CONFIG_HAP_CTTPROXY) || defined(HAP_TRANSPARENT)
if (curproxy->mode != PR_MODE_HTTP &&
newsrv->conn_src.bind_hdr_occ) {
newsrv->conn_src.bind_hdr_occ = 0;
Warning("config : %s '%s' : server %s cannot
use header %s as source IP in non-HTTP mode.\n",
diff --git a/src/haproxy.c b/src/haproxy.c
index dd1adcd..01e43b1 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -289,6 +289,29 @@ void display_build_opts()
#else /* USE_OPENSSL */
printf("Built without OpenSSL support (USE_OPENSSL not set)\n");
#endif
+
+#ifdef HAP_TRANSPARENT
+ printf("Built with 'transparent proxy' support using:"
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ " IP_TRANSPARENT"
+ #endif
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ " IPV6_TRANSPARENT"
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ " IP_FREEBIND"
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ " IP_BINDANY"
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ " IPV6_BINDANY"
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ " SO_BINDANY"
+ #endif
+ "\n");
+#endif
putchar('\n');
list_pollers(stdout);
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 781b24a..14a0184 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -123,14 +123,26 @@ int tcp_bind_socket(int fd, int flags, struct
sockaddr_storage *local, struct so
int foreign_ok = 0;
int ret;
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
static int ip_transp_working = 1;
static int ip6_transp_working = 1;
switch (local->ss_family) {
case AF_INET:
if (flags && ip_transp_working) {
- if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == 0
- || setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0)
+ int ret = 0;
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ ret |= setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ ret |= setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ ret |= setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ ret |= setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ if (ret)
foreign_ok = 1;
else
ip_transp_working = 0;
@@ -138,7 +150,14 @@ int tcp_bind_socket(int fd, int flags, struct
sockaddr_storage *local, struct so
break;
case AF_INET6:
if (flags && ip6_transp_working) {
- if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == 0)
+ int ret = 0;
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ ret |= setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ ret |= setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one,
sizeof(one)) == 0;
+ #endif
+ if (ret)
foreign_ok = 1;
else
ip6_transp_working = 0;
@@ -621,18 +640,36 @@ int tcp_bind_listener(struct listener *listener, char
*errmsg, int errlen)
if (!ext)
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
if (!ext && (listener->options & LI_O_FOREIGN)) {
+ int ret = 0;
switch (listener->addr.ss_family) {
case AF_INET:
- if ((setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one,
sizeof(one)) == -1)
- && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == -1)) {
+ #if defined(SOL_IP) && defined(IP_TRANSPARENT)
+ ret = ret || setsockopt(fd, SOL_IP, IP_TRANSPARENT,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_IP) && defined(IP_FREEBIND)
+ ret = ret || setsockopt(fd, SOL_IP, IP_FREEBIND, &one,
sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IP) && defined(IP_BINDANY)
+ ret = ret || setsockopt(fd, IPPROTO_IP, IP_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(SOL_SOCKET) && defined(SO_BINDANY)
+ ret = ret || setsockopt(fd, SOL_SOCKET, SO_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ if (!ret){
msg = "cannot make listening socket
transparent";
err |= ERR_ALERT;
}
- break;
+ break;
case AF_INET6:
- if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one,
sizeof(one)) == -1) {
+ #if defined(SOL_IPV6) && defined(IPV6_TRANSPARENT)
+ ret = ret || setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT,
&one, sizeof(one)) == 0;
+ #endif
+ #if defined(IPPROTO_IPV6) && defined(IPV6_BINDANY)
+ ret = ret || setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY,
&one, sizeof(one)) == 0;
+ #endif
+ if (!ret) {
msg = "cannot make listening socket
transparent";
err |= ERR_ALERT;
}
@@ -1546,7 +1583,7 @@ static int bind_parse_v6only(char **args, int cur_arg,
struct proxy *px, struct
}
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
/* parse the "transparent" bind keyword */
static int bind_parse_transparent(char **args, int cur_arg, struct proxy *px,
struct bind_conf *conf, char **err)
{
@@ -1695,7 +1732,7 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
#ifdef TCP_FASTOPEN
{ "tfo", bind_parse_tfo, 0 }, /* enable TCP_FASTOPEN
of listening socket */
#endif
-#ifdef CONFIG_HAP_LINUX_TPROXY
+#ifdef HAP_TRANSPARENT
{ "transparent", bind_parse_transparent, 0 }, /* transparently bind
to the specified addresses */
#endif
#ifdef IPV6_V6ONLY