Cygwin: tcp: Support TCP_QUICKACK

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2020-07-01 21:26:59 +02:00 committed by Ken Brown
parent 48656e7834
commit fd4b5bd9b2
3 changed files with 49 additions and 0 deletions

View File

@ -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 */

View File

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

View File

@ -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 */