Cygwin: tcp: Support TCP_QUICKACK
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
		@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user