diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2020-07-01 20:30:22 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2020-07-01 20:30:52 +0200 |
commit | ffb07b41bcc6763a6026366343ee2d467683e984 (patch) | |
tree | ff3ca9e8e6e7a6996e3b3ae527352b4ec3d7bbc9 | |
parent | 8ccffddc91942dcb4a6417c13b46c5ab5d81a5d9 (diff) | |
download | newlib-ffb07b41bcc6763a6026366343ee2d467683e984.zip newlib-ffb07b41bcc6763a6026366343ee2d467683e984.tar.gz newlib-ffb07b41bcc6763a6026366343ee2d467683e984.tar.bz2 |
Cygwin: tcp: Support TCP_USER_TIMEOUT
Use TCP_MAXRTMS on newer systems, TCP_MAXRT on older systems.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/fhandler_socket_inet.cc | 36 | ||||
-rw-r--r-- | winsup/cygwin/include/netinet/tcp.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/wincap.cc | 11 | ||||
-rw-r--r-- | winsup/cygwin/wincap.h | 2 |
4 files changed, 51 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc index 9bdaece..6b6b63d 100644 --- a/winsup/cygwin/fhandler_socket_inet.cc +++ b/winsup/cygwin/fhandler_socket_inet.cc @@ -1576,6 +1576,9 @@ fhandler_socket_wsock::writev (const struct iovec *const iov, const int iovcnt, return send_internal (&wsamsg, 0); } +#define TCP_MAXRT 5 /* Older systems don't support TCP_MAXRTMS + TCP_MAXRT takes secs, not msecs. */ + #define MAX_TCP_KEEPIDLE 32767 #define MAX_TCP_KEEPCNT 255 #define MAX_TCP_KEEPINTVL 32767 @@ -1639,6 +1642,7 @@ fhandler_socket_inet::setsockopt (int level, int optname, const void *optval, { bool ignore = false; int ret = -1; + unsigned int timeout; /* Preprocessing setsockopt. Set ignore to true if setsockopt call should get skipped entirely. */ @@ -1763,6 +1767,22 @@ fhandler_socket_inet::setsockopt (int level, int optname, const void *optval, ignore = true; break; + case TCP_MAXRT: + /* Don't let this option slip through from user space. */ + set_errno (EOPNOTSUPP); + return -1; + + case TCP_USER_TIMEOUT: + if (!wincap.has_tcp_maxrtms ()) + { + /* convert msecs to secs. Values < 1000 ms are converted to + 0 secs, just as in WinSock. */ + timeout = *(unsigned int *) optval / MSPERSEC; + optname = TCP_MAXRT; + optval = (const void *) &timeout; + } + break; + case TCP_FASTOPEN: /* Fake FastOpen on older systems. */ if (!wincap.has_tcp_fastopen ()) @@ -1963,6 +1983,17 @@ fhandler_socket_inet::getsockopt (int level, int optname, const void *optval, switch (optname) { + case TCP_MAXRT: + /* Don't let this option slip through from user space. */ + set_errno (EOPNOTSUPP); + return -1; + + case TCP_USER_TIMEOUT: + /* Older systems don't support TCP_MAXRTMS, just call TCP_MAXRT. */ + if (!wincap.has_tcp_maxrtms ()) + optname = TCP_MAXRT; + break; + case TCP_FASTOPEN: /* Fake FastOpen on older systems */ if (!wincap.has_tcp_fastopen ()) @@ -2052,6 +2083,11 @@ fhandler_socket_inet::getsockopt (int level, int optname, const void *optval, onebyte = true; break; + case TCP_MAXRT: /* After above conversion from TCP_USER_TIMEOUT */ + /* convert secs to msecs */ + *(unsigned int *) optval *= MSPERSEC; + break; + case TCP_FASTOPEN: onebyte = true; break; diff --git a/winsup/cygwin/include/netinet/tcp.h b/winsup/cygwin/include/netinet/tcp.h index 9c2e90e..8ccb0df 100644 --- a/winsup/cygwin/include/netinet/tcp.h +++ b/winsup/cygwin/include/netinet/tcp.h @@ -126,6 +126,8 @@ struct tcphdr { #define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ #define TCP_KEEPIDLE 0x03 /* start keepalives after this period */ #define TCP_MAXSEG 0x04 /* get maximum segment size (r/o on windows) */ +#define TCP_USER_TIMEOUT 0x0e /* how long for loss retry before timeout, + like WinSock TCP_MAXRTMS/TCP_MAXRT */ #define TCP_FASTOPEN 0x0f /* enable FastOpen on listeners */ #define TCP_KEEPCNT 0x10 /* number of keepalives before death */ #define TCP_KEEPINTVL 0x11 /* interval between keepalives */ diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 323c5a3..b18e732 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -48,6 +48,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_extended_mem_api:false, has_tcp_fastopen:false, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:false, }, }; @@ -81,6 +82,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_extended_mem_api:false, has_tcp_fastopen:false, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:false, }, }; @@ -114,6 +116,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_extended_mem_api:false, has_tcp_fastopen:false, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:false, }, }; @@ -147,6 +150,7 @@ wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { has_extended_mem_api:false, has_tcp_fastopen:false, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:false, }, }; @@ -180,6 +184,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_extended_mem_api:false, has_tcp_fastopen:false, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:false, }, }; @@ -213,6 +218,7 @@ wincaps wincap_10_1607 __attribute__((section (".cygwin_dll_common"), shared)) has_extended_mem_api:false, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:true, }, }; @@ -246,6 +252,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_extended_mem_api:false, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:false, + has_tcp_maxrtms:true, }, }; @@ -279,6 +286,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_extended_mem_api:false, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:true, + has_tcp_maxrtms:true, }, }; @@ -312,6 +320,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = has_extended_mem_api:true, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:true, + has_tcp_maxrtms:true, }, }; @@ -345,6 +354,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = has_extended_mem_api:true, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:true, + has_tcp_maxrtms:true, }, }; @@ -378,6 +388,7 @@ wincaps wincap_10_1903 __attribute__((section (".cygwin_dll_common"), shared)) = has_extended_mem_api:true, has_tcp_fastopen:true, has_linux_tcp_keepalive_sockopts:true, + has_tcp_maxrtms:true, }, }; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 26c4c01..2f4191a 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -42,6 +42,7 @@ struct wincaps unsigned has_extended_mem_api : 1; unsigned has_tcp_fastopen : 1; unsigned has_linux_tcp_keepalive_sockopts : 1; + unsigned has_tcp_maxrtms : 1; }; }; @@ -107,6 +108,7 @@ public: bool IMPLEMENT (has_extended_mem_api) bool IMPLEMENT (has_tcp_fastopen) bool IMPLEMENT (has_linux_tcp_keepalive_sockopts) + bool IMPLEMENT (has_tcp_maxrtms) void disable_case_sensitive_dirs () { |