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;
 }