public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin] Cygwin: tcp: Support TCP_USER_TIMEOUT
@ 2020-07-01 18:32 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2020-07-01 18:32 UTC (permalink / raw)
  To: cygwin-cvs

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=ffb07b41bcc6763a6026366343ee2d467683e984

commit ffb07b41bcc6763a6026366343ee2d467683e984
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Jul 1 20:30:22 2020 +0200

    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>

Diff:
---
 winsup/cygwin/fhandler_socket_inet.cc | 36 +++++++++++++++++++++++++++++++++++
 winsup/cygwin/include/netinet/tcp.h   |  2 ++
 winsup/cygwin/wincap.cc               | 11 +++++++++++
 winsup/cygwin/wincap.h                |  2 ++
 4 files changed, 51 insertions(+)

diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc
index 9bdaece5a..6b6b63d83 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 9c2e90eaa..8ccb0dfaa 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 323c5a368..b18e732cd 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 26c4c01ef..2f4191aa1 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 ()
   {


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-07-01 18:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-01 18:32 [newlib-cygwin] Cygwin: tcp: Support TCP_USER_TIMEOUT Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).