REORG: sock_inet: move default_tcp_maxseg from proto_tcp.c

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.
This commit is contained in:
Willy Tarreau 2020-08-28 18:03:10 +02:00
parent d88e8c06ac
commit e5bdc51bb5
3 changed files with 26 additions and 38 deletions

View 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);

View 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 &&

View File

@ -40,6 +40,10 @@
*/
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);
}
}