MINOR: protocol: perform a live check for SO_REUSEPORT support
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.
diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h
index eec65fe..47df366 100644
--- a/include/haproxy/protocol-t.h
+++ b/include/haproxy/protocol-t.h
@@ -66,6 +66,7 @@
/* 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.
diff --git a/src/protocol.c b/src/protocol.c
index c190a36..c4b57c5 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -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 @@
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;
+ /* 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);
+
- /* OK it looks like it is supported */
- return 1;
+ _HA_ATOMIC_OR(&proto->flags, PROTO_F_REUSEPORT_TESTED);
+ return ret;
}
return 0;
}