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

Reply via email to