]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: socket: replace SOL_IP/IPV6/TCP with IPPROTO_IP/IPV6/TCP
authorWilly Tarreau <w@1wt.eu>
Wed, 31 Mar 2021 06:45:47 +0000 (08:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 31 Mar 2021 06:59:34 +0000 (08:59 +0200)
Historically we've used SOL_IP/SOL_IPV6/SOL_TCP everywhere as the socket
level value in getsockopt() and setsockopt() but as we've seen over time
it regularly broke the build and required to have them defined to their
IPPROTO_* equivalent. The Linux ip(7) man page says:

   Using the SOL_IP socket options level isn't portable; BSD-based
   stacks use the IPPROTO_IP level.

And it indeed looks like a pure linuxism inherited from old examples and
documentation. strace also reports SOL_* instead of IPPROTO_*, which does
not help... A check to linux/in.h shows they have the same values. Only
SOL_SOCKET and other non-IP values make sense since there is no IPPROTO
equivalent.

Let's get rid of this annoying confusion by removing all redefinitions of
SOL_IP/IPV6/TCP and using IPPROTO_* instead, just like any other operating
system. This also removes duplicated tests for the same value.

Note that this should not result in exposing syscalls to other OSes
as the only ones that were still conditionned to SOL_IPV6 were for
IPV6_UNICAST_HOPS which already had an IPPROTO_IPV6 equivalent, and
IPV6_TRANSPARENT which is Linux-specific.

contrib/tcploop/tcploop.c
include/haproxy/compat.h
src/proto_quic.c
src/proto_tcp.c
src/sock_inet.c
src/tcp_act.c
src/tcp_sample.c

index 7786494caf22065e70e54ac77c626be5537d2fcd..0571a6dfd7048d93f396b6c78aab93b16b26acc4 100644 (file)
 #include <time.h>
 #include <unistd.h>
 
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-
 #ifndef MSG_MORE
 #define MSG_MORE 0
 #endif
@@ -316,7 +312,7 @@ int wait_on_fd(int fd, int events)
 
 int tcp_set_nodelay(int sock, const char *arg)
 {
-       return setsockopt(sock, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
+       return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
 }
 
 int tcp_set_nolinger(int sock, const char *arg)
@@ -328,7 +324,7 @@ int tcp_set_noquickack(int sock, const char *arg)
 {
 #ifdef TCP_QUICKACK
        /* warning: do not use during connect if nothing is to be sent! */
-       return setsockopt(sock, SOL_TCP, TCP_QUICKACK, &zero, sizeof(zero));
+       return setsockopt(sock, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
 #else
        return 0;
 #endif
index 0c1d9c9be4408f47530d71943c6c09a4c28b177c..39d46c2be0e3ef3afdf34b016fb6b439bddc904d 100644 (file)
@@ -215,16 +215,6 @@ typedef struct { } empty_t;
 #endif
 #endif
 
-/* FreeBSD doesn't define SOL_IP and prefers IPPROTO_IP */
-#ifndef SOL_IP
-#define SOL_IP IPPROTO_IP
-#endif
-
-/* same for SOL_TCP */
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-
 /* If IPv6 is supported, define IN6_IS_ADDR_V4MAPPED() if missing. */
 #if defined(IPV6_TCLASS) && !defined(IN6_IS_ADDR_V4MAPPED)
 #define IN6_IS_ADDR_V4MAPPED(a) \
index c52d7927d58c1c9b6dcf1b7ab40081058b565465..dac7c2389a2f624ec534e954156f410dd4a91c65 100644 (file)
@@ -406,7 +406,7 @@ int quic_connect_server(struct connection *conn, int flags)
                else {
 #ifdef IP_BIND_ADDRESS_NO_PORT
                        static THREAD_LOCAL int bind_address_no_port = 1;
-                       setsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, (const void *) &bind_address_no_port, sizeof(int));
+                       setsockopt(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, (const void *) &bind_address_no_port, sizeof(int));
 #endif
                        ret = quic_bind_socket(fd, flags, &src->source_addr, conn->src);
                        if (ret != 0)
index cef2ff890cf0186c2814667946999d049a25fab5..1317d31377e5ba40ae847436b1d4e7ee33b112c1 100644 (file)
@@ -443,7 +443,7 @@ int tcp_connect_server(struct connection *conn, int flags)
                else {
 #ifdef IP_BIND_ADDRESS_NO_PORT
                        static THREAD_LOCAL int bind_address_no_port = 1;
-                       setsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, (const void *) &bind_address_no_port, sizeof(int));
+                       setsockopt(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, (const void *) &bind_address_no_port, sizeof(int));
 #endif
                        ret = tcp_bind_socket(fd, flags, &src->source_addr, conn->src);
                        if (ret != 0)
index 6adaf184ebd295dbb320479f85506c46b8dedad7..ab881d86969a02ffe64039e9e21cf89167dc5d2d 100644 (file)
@@ -154,7 +154,7 @@ int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
                 * other families because v6-mapped IPv4 addresses are still
                 * reported as v4.
                 */
-               if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, sa, &salen) == 0)
+               if (getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST, sa, &salen) == 0)
                        return 0;
 #endif
                return ret;
@@ -174,12 +174,12 @@ int sock_inet_is_foreign(int fd, sa_family_t family)
        case AF_INET:
 #if defined(IP_TRANSPARENT)
                val = 0; len = sizeof(val);
-               if (getsockopt(fd, SOL_IP, IP_TRANSPARENT, &val, &len) == 0 && val)
+               if (getsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &val, &len) == 0 && val)
                        return 1;
 #endif
 #if defined(IP_FREEBIND)
                val = 0; len = sizeof(val);
-               if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val)
+               if (getsockopt(fd, IPPROTO_IP, IP_FREEBIND, &val, &len) == 0 && val)
                        return 1;
 #endif
 #if defined(IP_BINDANY)
@@ -195,14 +195,14 @@ int sock_inet_is_foreign(int fd, sa_family_t family)
                break;
 
        case AF_INET6:
-#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
+#if defined(IPV6_TRANSPARENT)
                val = 0; len = sizeof(val);
-               if (getsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &val, &len) == 0 && val)
+               if (getsockopt(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, &val, &len) == 0 && val)
                        return 1;
 #endif
 #if defined(IP_FREEBIND)
                val = 0; len = sizeof(val);
-               if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val)
+               if (getsockopt(fd, IPPROTO_IP, IP_FREEBIND, &val, &len) == 0 && val)
                        return 1;
 #endif
 #if defined(IPV6_BINDANY)
@@ -229,10 +229,10 @@ int sock_inet4_make_foreign(int fd)
 {
        return
 #if defined(IP_TRANSPARENT)
-               setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 ||
+               setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 ||
 #endif
 #if defined(IP_FREEBIND)
-               setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
+               setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
 #endif
 #if defined(IP_BINDANY)
                setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == 0 ||
@@ -251,11 +251,11 @@ int sock_inet4_make_foreign(int fd)
 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 ||
+#if defined(IPV6_TRANSPARENT)
+               setsockopt(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0 ||
 #endif
 #if defined(IP_FREEBIND)
-               setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
+               setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
 #endif
 #if defined(IPV6_BINDANY)
                setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0 ||
index fa0a9898b54a0c4fe6e7967d217354ea7f5c4f50..46157c1026afe3364ce2b75e5502cdb986276b64 100644 (file)
@@ -182,7 +182,7 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct
        /* re-enable quickack if it was disabled to ack all data and avoid
         * retransmits from the client that might trigger a real reset.
         */
-       setsockopt(conn->handle.fd, SOL_TCP, TCP_QUICKACK, &one, sizeof(one));
+       setsockopt(conn->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
 #endif
        /* lingering must absolutely be disabled so that we don't send a
         * shutdown(), this is critical to the TCP_REPAIR trick. When no stream
@@ -197,7 +197,7 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct
        fdtab[conn->handle.fd].linger_risk = 1;
 
 #ifdef TCP_REPAIR
-       if (setsockopt(conn->handle.fd, SOL_TCP, TCP_REPAIR, &one, sizeof(one)) == 0) {
+       if (setsockopt(conn->handle.fd, IPPROTO_TCP, TCP_REPAIR, &one, sizeof(one)) == 0) {
                /* socket will be quiet now */
                goto out;
        }
@@ -208,16 +208,11 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct
         */
 #ifdef IP_TTL
        if (conn->src && conn->src->ss_family == AF_INET)
-               setsockopt(conn->handle.fd, SOL_IP, IP_TTL, &one, sizeof(one));
+               setsockopt(conn->handle.fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
 #endif
 #ifdef IPV6_UNICAST_HOPS
-#if defined(SOL_IPV6)
-       if (conn->src && conn->src->ss_family == AF_INET6)
-               setsockopt(conn->handle.fd, SOL_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
-#elif defined(IPPROTO_IPV6)
        if (conn->src && conn->src->ss_family == AF_INET6)
                setsockopt(conn->handle.fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
-#endif
 #endif
  out:
        /* kill the stream if any */
index 91a5fb306693c377c9885e0fc8da578853aec796..06ad6c635596d01e752ce54fcbe96d0c19b6adaa 100644 (file)
@@ -260,7 +260,7 @@ static inline int get_tcp_info(const struct arg *args, struct sample *smp,
        /* The fd may not be available for the tcp_info struct, and the
          syscal can fail. */
        optlen = sizeof(info);
-       if (getsockopt(conn->handle.fd, SOL_TCP, TCP_INFO, &info, &optlen) == -1)
+       if (getsockopt(conn->handle.fd, IPPROTO_TCP, TCP_INFO, &info, &optlen) == -1)
                return 0;
 
        /* extract the value. */