]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: sock_inet: move default_tcp_maxseg from proto_tcp.c
authorWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 16:03:10 +0000 (18:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 16:51:36 +0000 (18:51 +0200)
Let's determine it at boot time instead of doing it on first use. It
also saves us from having to keep it thread local. It's been moved to
the new sock_inet_prepare() function, and the variables were renamed
to sock_inet_tcp_maxseg_default and sock_inet6_tcp_maxseg_default.

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

index 6e3718a2d76ba7a3a0389f75eea592907a9aa5bb..d90b41953e69e7c68b9f61f5e5913f364fe857ec 100644 (file)
@@ -28,6 +28,8 @@
 #include <haproxy/api.h>
 
 extern int sock_inet6_v6only_default;
+extern int sock_inet_tcp_maxseg_default;
+extern int sock_inet6_tcp_maxseg_default;
 
 int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
 int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
index 144f4bcfaba2c5f700f16dc426e672d3e786e3b9..44b11e44a010e77e9341cb1fce2ede6c3cdbd758 100644 (file)
@@ -101,12 +101,6 @@ static struct protocol proto_tcpv6 = {
 
 INITCALL1(STG_REGISTER, protocol_register, &proto_tcpv6);
 
-/* Default TCP parameters, got by opening a temporary TCP socket. */
-#ifdef TCP_MAXSEG
-static THREAD_LOCAL int default_tcp_maxseg = -1;
-static THREAD_LOCAL int default_tcp6_maxseg = -1;
-#endif
-
 /* Binds ipv4/ipv6 address <local> to socket <fd>, unless <flags> is set, in which
  * case we try to bind <remote>. <flags> is a 2-bit field consisting of :
  *  - 0 : ignore remote address (may even be a NULL pointer)
@@ -655,36 +649,6 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
        int ext, ready;
        socklen_t ready_len;
        const char *msg = NULL;
-#ifdef TCP_MAXSEG
-
-       /* Create a temporary TCP socket to get default parameters we can't
-        * guess.
-        * */
-       ready_len = sizeof(default_tcp_maxseg);
-       if (default_tcp_maxseg == -1) {
-               default_tcp_maxseg = -2;
-               fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-               if (fd < 0)
-                       ha_warning("Failed to create a temporary socket!\n");
-               else {
-                       if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &default_tcp_maxseg,
-                           &ready_len) == -1)
-                               ha_warning("Failed to get the default value of TCP_MAXSEG\n");
-                       close(fd);
-               }
-       }
-       if (default_tcp6_maxseg == -1) {
-               default_tcp6_maxseg = -2;
-               fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
-               if (fd >= 0) {
-                       if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &default_tcp6_maxseg,
-                           &ready_len) == -1)
-                               ha_warning("Failed ot get the default value of TCP_MAXSEG for IPv6\n");
-                       close(fd);
-               }
-       }
-#endif
-
 
        /* ensure we never return garbage */
        if (errlen)
@@ -822,9 +786,9 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
                socklen_t len = sizeof(tmpmaxseg);
 
                if (listener->addr.ss_family == AF_INET)
-                       defaultmss = default_tcp_maxseg;
+                       defaultmss = sock_inet_tcp_maxseg_default;
                else
-                       defaultmss = default_tcp6_maxseg;
+                       defaultmss = sock_inet6_tcp_maxseg_default;
 
                getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &tmpmaxseg, &len);
                if (defaultmss > 0 &&
index c5b80da1c710c81c835b7c03f032555da5f26a90..29666801bea8d31a737b163b50a1fe4c450c1b25 100644 (file)
  */
 int sock_inet6_v6only_default = 0;
 
+/* Default TCPv4/TCPv6 MSS settings. -1=unknown. */
+int sock_inet_tcp_maxseg_default = -1;
+int sock_inet6_tcp_maxseg_default = -1;
+
 /* Compares two AF_INET sockaddr addresses. Returns 0 if they match or non-zero
  * if they do not match.
  */
@@ -175,6 +179,17 @@ static void sock_inet_prepare()
        int fd, val;
        socklen_t len;
 
+       fd = socket(AF_INET, SOCK_STREAM, 0);
+       if (fd >= 0) {
+#ifdef TCP_MAXSEG
+               /* retrieve the OS' default mss for TCPv4 */
+               len = sizeof(val);
+               if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &val, &len) == 0)
+                       sock_inet_tcp_maxseg_default = val;
+#endif
+               close(fd);
+       }
+
        fd = socket(AF_INET6, SOCK_STREAM, 0);
        if (fd >= 0) {
 #if defined(IPV6_V6ONLY)
@@ -183,6 +198,13 @@ static void sock_inet_prepare()
                if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, &len) == 0 && val > 0)
                        sock_inet6_v6only_default = 1;
 #endif
+
+#ifdef TCP_MAXSEG
+               /* retrieve the OS' default mss for TCPv6 */
+               len = sizeof(val);
+               if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &val, &len) == 0)
+                       sock_inet6_tcp_maxseg_default = val;
+#endif
                close(fd);
        }
 }