]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: perform a live check for SO_REUSEPORT support
authorWilly Tarreau <w@1wt.eu>
Sat, 22 Apr 2023 16:26:56 +0000 (18:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 23 Apr 2023 07:46:15 +0000 (09:46 +0200)
When testing if a protocol supports SO_REUSEPORT, we're now able to
verify if the OS does really support it. While it may be supported at
build time, it may possibly have been blocked in a container for
example so we'd rather know what it's like.

include/haproxy/protocol-t.h
src/protocol.c

index eec65fed4266e1519ce9f852bf782fab2597e528..47df36641c4a20bfac01eeb31bec441a8d9479e0 100644 (file)
@@ -66,6 +66,7 @@ enum proto_type {
 
 /* Flags for protocol->flags */
 #define PROTO_F_REUSEPORT_SUPPORTED             0x00000001 /* SO_REUSEPORT is supported */
+#define PROTO_F_REUSEPORT_TESTED                0x00000002 /* SO_REUSEPORT support was tested */
 
 /* protocol families define standard functions acting on a given address family
  * for a socket implementation, such as AF_INET/PF_INET for example.
index c190a3664223b53619c890504d1ef10b0d49fb14..c4b57c5efa1a4d0edaa9a1849d40b35f12525351 100644 (file)
@@ -21,6 +21,7 @@
 #include <haproxy/proto_quic.h>
 #include <haproxy/protocol.h>
 #include <haproxy/proxy.h>
+#include <haproxy/sock.h>
 #include <haproxy/tools.h>
 
 
@@ -92,12 +93,23 @@ void protocol_setf_all(uint flag)
 int protocol_supports_flag(struct protocol *proto, uint flag)
 {
        if (flag == PROTO_F_REUSEPORT_SUPPORTED) {
+               int ret = 0;
+
                /* check if the protocol supports SO_REUSEPORT */
                if (!(_HA_ATOMIC_LOAD(&proto->flags) & PROTO_F_REUSEPORT_SUPPORTED))
                        return 0;
 
-               /* OK it looks like it is supported */
-               return 1;
+               /* at least nobody said it was not supported */
+               if (_HA_ATOMIC_LOAD(&proto->flags) & PROTO_F_REUSEPORT_TESTED)
+                       return 1;
+
+               /* run a live check */
+               ret = _sock_supports_reuseport(proto->fam, proto->sock_type, proto->sock_prot);
+               if (!ret)
+                       _HA_ATOMIC_AND(&proto->flags, ~PROTO_F_REUSEPORT_SUPPORTED);
+
+               _HA_ATOMIC_OR(&proto->flags, PROTO_F_REUSEPORT_TESTED);
+               return ret;
        }
        return 0;
 }