]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: sock_inet: move the IPv4/v6 transparent mode code to sock_inet
authorWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 15:23:40 +0000 (17:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 16:51:36 +0000 (18:51 +0200)
This code was highly redundant, existing for TCP clients, TCP servers
and UDP servers. Let's move it to sock_inet where it belongs. The new
functions are sock_inet4_make_foreign() and sock_inet6_make_foreign().

include/haproxy/sock_inet.h
src/proto_tcp.c
src/proto_udp.c
src/sock_inet.c

index d90b41953e69e7c68b9f61f5e5913f364fe857ec..72b1204b2dd20baaff6901237f94bb21c59dd51d 100644 (file)
@@ -35,5 +35,7 @@ int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_s
 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);
 int sock_inet_is_foreign(int fd, sa_family_t family);
+int sock_inet4_make_foreign(int fd);
+int sock_inet6_make_foreign(int fd);
 
 #endif /* _HAPROXY_SOCK_INET_H */
index 4ae4a489f32ef882f62cdb421a35a97f832e0cd5..933eced34a276721ff5482f260cc1683f07086da 100644 (file)
@@ -129,20 +129,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
                         * multiple combinations of certain methods, so we try the
                         * supported ones until one succeeds.
                         */
-                       if (0
-#if defined(IP_TRANSPARENT)
-                           || (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0)
-#endif
-#if defined(IP_FREEBIND)
-                           || (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0)
-#endif
-#if defined(IP_BINDANY)
-                           || (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == 0)
-#endif
-#if defined(SO_BINDANY)
-                           || (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0)
-#endif
-                           )
+                       if (sock_inet4_make_foreign(fd))
                                foreign_ok = 1;
                        else
                                ip_transp_working = 0;
@@ -150,20 +137,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
                break;
        case AF_INET6:
                if (flags && ip6_transp_working) {
-                       if (0
-#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
-                           || (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0)
-#endif
-#if defined(IP_FREEBIND)
-                           || (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0)
-#endif
-#if defined(IPV6_BINDANY)
-                           || (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0)
-#endif
-#if defined(SO_BINDANY)
-                           || (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0)
-#endif
-                           )
+                       if (sock_inet6_make_foreign(fd))
                                foreign_ok = 1;
                        else
                                ip6_transp_working = 0;
@@ -664,39 +638,13 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
        if (!ext && (listener->options & LI_O_FOREIGN)) {
                switch (listener->addr.ss_family) {
                case AF_INET:
-                       if (1
-#if defined(IP_TRANSPARENT)
-                           && (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_FREEBIND)
-                           && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_BINDANY)
-                           && (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == -1)
-#endif
-#if defined(SO_BINDANY)
-                           && (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
-#endif
-                           ) {
+                       if (!sock_inet4_make_foreign(fd)) {
                                msg = "cannot make listening socket transparent";
                                err |= ERR_ALERT;
                        }
                break;
                case AF_INET6:
-                       if (1
-#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
-                           && (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_FREEBIND)
-                           && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
-#endif
-#if defined(IPV6_BINDANY)
-                           && (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == -1)
-#endif
-#if defined(SO_BINDANY)
-                           && (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
-#endif
-                           ) {
+                       if (!sock_inet6_make_foreign(fd)) {
                                msg = "cannot make listening socket transparent";
                                err |= ERR_ALERT;
                        }
@@ -920,27 +868,6 @@ int tcp_pause_listener(struct listener *l)
        return 1;
 }
 
-REGISTER_BUILD_OPTS("Built with transparent proxy support using:"
-#if defined(IP_TRANSPARENT)
-                   " IP_TRANSPARENT"
-#endif
-#if defined(IPV6_TRANSPARENT)
-                   " IPV6_TRANSPARENT"
-#endif
-#if defined(IP_FREEBIND)
-                   " IP_FREEBIND"
-#endif
-#if defined(IP_BINDANY)
-                   " IP_BINDANY"
-#endif
-#if defined(IPV6_BINDANY)
-                   " IPV6_BINDANY"
-#endif
-#if defined(SO_BINDANY)
-                   " SO_BINDANY"
-#endif
-                   "");
-
 
 /*
  * Local variables:
index 96b878a345528bfe2896d14ad28d180e6261c9e6..18e46ac917011e4f75452e12e72617b951d6e2b2 100644 (file)
@@ -241,39 +241,13 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen)
        if (listener->options & LI_O_FOREIGN) {
                switch (addr_inet.ss_family) {
                case AF_INET:
-                       if (1
-#if defined(IP_TRANSPARENT)
-                           && (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_FREEBIND)
-                           && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_BINDANY)
-                           && (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == -1)
-#endif
-#if defined(SO_BINDANY)
-                           && (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
-#endif
-                           ) {
+                       if (!sock_inet4_make_foreign(fd)) {
                                msg = "cannot make listening socket transparent";
                                err |= ERR_ALERT;
                        }
                break;
                case AF_INET6:
-                       if (1
-#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
-                           && (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
-#endif
-#if defined(IP_FREEBIND)
-                           && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
-#endif
-#if defined(IPV6_BINDANY)
-                           && (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == -1)
-#endif
-#if defined(SO_BINDANY)
-                           && (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
-#endif
-                           ) {
+                       if (!sock_inet6_make_foreign(fd)) {
                                msg = "cannot make listening socket transparent";
                                err |= ERR_ALERT;
                        }
index 29666801bea8d31a737b163b50a1fe4c450c1b25..3f4edcb1d42a248ecd5f4ddac87b255254772a70 100644 (file)
@@ -20,6 +20,7 @@
 #include <netinet/in.h>
 
 #include <haproxy/api.h>
+#include <haproxy/global.h>
 #include <haproxy/sock_inet.h>
 #include <haproxy/tools.h>
 
@@ -174,6 +175,52 @@ int sock_inet_is_foreign(int fd, sa_family_t family)
        return 0;
 }
 
+/* Attempt all known socket options to prepare an AF_INET4 socket to be bound
+ * to a foreign address. The socket must already exist and must not be bound.
+ * 1 is returned on success, 0 on failure. The caller must check the address
+ * family before calling this function.
+ */
+int sock_inet4_make_foreign(int fd)
+{
+       return
+#if defined(IP_TRANSPARENT)
+               setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(IP_FREEBIND)
+               setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(IP_BINDANY)
+               setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(SO_BINDANY)
+               setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0 ||
+#endif
+               0;
+}
+
+/* Attempt all known socket options to prepare an AF_INET6 socket to be bound
+ * to a foreign address. The socket must already exist and must not be bound.
+ * 1 is returned on success, 0 on failure. The caller must check the address
+ * family before calling this function.
+ */
+int sock_inet6_make_foreign(int fd)
+{
+       return
+#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
+               setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(IP_FREEBIND)
+               setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(IPV6_BINDANY)
+               setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0 ||
+#endif
+#if defined(SO_BINDANY)
+               setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0 ||
+#endif
+               0;
+}
+
 static void sock_inet_prepare()
 {
        int fd, val;
@@ -210,3 +257,25 @@ static void sock_inet_prepare()
 }
 
 INITCALL0(STG_PREPARE, sock_inet_prepare);
+
+
+REGISTER_BUILD_OPTS("Built with transparent proxy support using:"
+#if defined(IP_TRANSPARENT)
+                   " IP_TRANSPARENT"
+#endif
+#if defined(IPV6_TRANSPARENT)
+                   " IPV6_TRANSPARENT"
+#endif
+#if defined(IP_FREEBIND)
+                   " IP_FREEBIND"
+#endif
+#if defined(IP_BINDANY)
+                   " IP_BINDANY"
+#endif
+#if defined(IPV6_BINDANY)
+                   " IPV6_BINDANY"
+#endif
+#if defined(SO_BINDANY)
+                   " SO_BINDANY"
+#endif
+                   "");