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

commit ee2292413792f0360d357bc200c5e947eae516e6
Author: Corinna Vinschen <[email protected]>
Date:   Wed Jul 1 21:26:59 2020 +0200

    Cygwin: tcp: Support TCP_QUICKACK
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/fhandler.h              |  1 +
 winsup/cygwin/fhandler_socket_inet.cc | 45 +++++++++++++++++++++++++++++++++++
 winsup/cygwin/include/netinet/tcp.h   |  3 +++
 3 files changed, 49 insertions(+)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 24184dacc..7a28adc16 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -719,6 +719,7 @@ class fhandler_socket_inet: public fhandler_socket_wsock
 {
  private:
   bool oobinline;      /* True if option SO_OOBINLINE is set */
+  bool tcp_quickack;   /* True if quickack is enabled */
   bool tcp_fastopen;   /* True if TCP_FASTOPEN is set on older systems */
   int  tcp_keepidle;   /* TCP_KEEPIDLE value in secs on older systems */
   int  tcp_keepcnt;    /* TCP_KEEPCNT value on older systems */
diff --git a/winsup/cygwin/fhandler_socket_inet.cc 
b/winsup/cygwin/fhandler_socket_inet.cc
index 6b6b63d83..74c415d60 100644
--- a/winsup/cygwin/fhandler_socket_inet.cc
+++ b/winsup/cygwin/fhandler_socket_inet.cc
@@ -693,6 +693,7 @@ fhandler_socket_wsock::set_socket_handle (SOCKET sock, int 
af, int type,
 fhandler_socket_inet::fhandler_socket_inet () :
   fhandler_socket_wsock (),
   oobinline (false),
+  tcp_quickack (false),
   tcp_fastopen (false),
   tcp_keepidle (7200), /* WinSock default */
   tcp_keepcnt (10),    /* WinSock default */
@@ -1579,6 +1580,10 @@ fhandler_socket_wsock::writev (const struct iovec *const 
iov, const int iovcnt,
 #define TCP_MAXRT            5 /* Older systems don't support TCP_MAXRTMS
                                   TCP_MAXRT takes secs, not msecs. */
 
+#ifndef SIO_TCP_SET_ACK_FREQUENCY
+#define SIO_TCP_SET_ACK_FREQUENCY      _WSAIOW(IOC_VENDOR,23)
+#endif
+
 #define MAX_TCP_KEEPIDLE  32767
 #define MAX_TCP_KEEPCNT     255
 #define MAX_TCP_KEEPINTVL 32767
@@ -1767,6 +1772,41 @@ fhandler_socket_inet::setsockopt (int level, int 
optname, const void *optval,
          ignore = true;
          break;
 
+       case TCP_QUICKACK:
+         /* Various sources on the net claim that TCP_QUICKACK is supported
+            by Windows, even using the same optname value of 12.  However,
+            the ws2ipdef.h header calls this option TCP_CONGESTION_ALGORITHM
+            and there's no official statement, nor official documentation
+            confirming or denying this option is equivalent to Linux'
+            TCP_QUICKACK.  Also, weirdly, this option takes values from 0..7.
+
+            There is another undocumented option to WSAIoctl called
+            SIO_TCP_SET_ACK_FREQUENCY which is already used by some
+            projects, so we're going to use it here, too, for now.
+
+            There's an open issue in the dotnet github,
+            https://github.com/dotnet/runtime/issues/798
+            Hopefully this clarifies the situation in the not too distant
+            future... */
+         {
+           DWORD dummy;
+           /* 
https://stackoverflow.com/questions/55034112/c-disable-delayed-ack-on-windows
+              claims that valid values for SIO_TCP_SET_ACK_FREQUENCY are
+              1..255.  In contrast to that, my own testing shows that
+              valid values are 0 and 1 exclusively. */
+           int freq = !!*(int *) optval;
+           if (WSAIoctl (get_socket (), SIO_TCP_SET_ACK_FREQUENCY, &freq,
+                         sizeof freq, NULL, 0, &dummy, NULL, NULL)
+               == SOCKET_ERROR)
+             {
+               set_winsock_errno ();
+               return -1;
+             }
+           ignore = true;
+           tcp_quickack = freq ? true : false;
+         }
+         break;
+
        case TCP_MAXRT:
          /* Don't let this option slip through from user space. */
          set_errno (EOPNOTSUPP);
@@ -1983,6 +2023,11 @@ fhandler_socket_inet::getsockopt (int level, int 
optname, const void *optval,
 
       switch (optname)
        {
+       case TCP_QUICKACK:
+         *(int *) optval = tcp_quickack ? 1 : 0;
+         *optlen = sizeof (int);
+         return 0;
+
        case TCP_MAXRT:
          /* Don't let this option slip through from user space. */
          set_errno (EOPNOTSUPP);
diff --git a/winsup/cygwin/include/netinet/tcp.h 
b/winsup/cygwin/include/netinet/tcp.h
index 8ccb0dfaa..7e4f5bbd6 100644
--- a/winsup/cygwin/include/netinet/tcp.h
+++ b/winsup/cygwin/include/netinet/tcp.h
@@ -126,6 +126,9 @@ 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_QUICKACK     0x0c   /* block/reenable quick acks
+                                  (TCP_CONGESTION_ALGORITHM in ws2ipdef.h,
+                                   valid vals 0 - 7, unclear if equivalent) */
 #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 */

Reply via email to