-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
AB#1117049
System.Net.Sockets.Socket
currently implements cross platform support for a large number of manually configurable socket options. We allow many TCP specific options, but do not support the standard TCP_QUICKACK
option that is supported in both Windows and Unix.
Rationale and Usage
Nagles algorithm and TCP delayed ack are both used to solve similar problems around network congestion. Both are often enabled by default, but the interactions between them can cause extreme and unnecessary latency. For more information see this blog on MSDN, or this SD comment by John Nagle.
By enabling support for TCP_QUICKACK
, we allow performance oriented developers to choose how to balance network congestion and latency.
The new option would be set via the standard SetSocketOption API. As the option is already supported natively on all supported platforms, the changes required would be very minimal.
Proposed API
namespace System.Net.Sockets
{
// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.
public enum SocketOptionName
{
#region SocketOptionLevel.Tcp
TcpQuickAck = 12,
#endregion
}
}
[[API proposal added above by @rmkerr. Original issue below]]
Original Proposal
I'm not sure if Windows support this at socket level as Linux does. But delayed ack does not works well when the remote endpoint is using Nagle Algorithm (TCP_NODELAY = false).
Activity
karelz commentedon May 25, 2018
I couldn't find existing option on Windows sockets APIs either.
@davidsh should we ping Windows folks to confirm?
cc @geoffkizer
davidsh commentedon May 25, 2018
Yes @rmkerr could follow up with the usual TCP team that he already has worked with.
rmkerr commentedon May 25, 2018
I'll reach out to the TCP team to confirm. In the meantime, I recommend checking out the documentation here on managing some of the issues with the Nagle algorithm and delayed ack.
felipepessoto commentedon May 25, 2018
@rmkerr, I read that article, one of the issues I intend to prevent is the problem with Nagle algorithm
rmkerr commentedon May 29, 2018
It looks like WinSock does support this! We can either set
TCP_QUICKACK
viasetsocketopt
orSIO_TCP_SET_ACK_FREQUENCY
viaWSAIoctl
. In the interest of cross platform consistency we should probably useTCP_QUICKACK
.I think that this is definitely worth taking through API review, as it is a very useful tool for reducing latency when the Nagle algorithm is enabled.
rmkerr commentedon May 29, 2018
System.Net.Sockets.Socket
currently implements cross platform support for a large number of manually configurable socket options. We allow many TCP specific options, but do not support the standardTCP_QUICKACK
option that is supported in both Windows and Unix.Rationale and Usage
Nagles algorithm and TCP delayed ack are both used to solve similar problems around network congestion. Both are often enabled by default, but the interactions between them can cause extreme and unnecessary latency. For more information see this blog on MSDN, or this SD comment by John Nagle.
By enabling support for
TCP_QUICKACK
, we allow performance oriented developers to choose how to balance network congestion and latency.The new option would be set via the standard SetSocketOption API. As the option is already supported natively on all supported platforms, the changes required would be very minimal.
Proposed API
karelz commentedon May 29, 2018
Should be fairly straightforward - model it by other options
We need to make sure the TCP_QUICKACK is part of public Windows headers (or we need to wait for public MSDN docs). The number (12) should match the value in them (on Windows).
felipepessoto commentedon May 31, 2018
@rmkerr, These TCP constant options are the same in all SO? http://www.cse.scu.edu/~dclark/am_256_graph_theory/linux_2_6_stack/linux_2tcp_8h-source.html.
How did you find the constant 12 in Windows?
rmkerr commentedon May 31, 2018
This issue actually needs to be updated -- the API is slightly different than expected on Windows. Rather than using the standard
setsocketopt
interface, Windows allows for more granular control over ack frequency via theWSAIoctl
control codeSIO_TCP_SET_ACK_FREQUENCY
. That means that we can add the ability to disable delayed ack on all platforms, but the implementation may need to be platform specific. I think the implementation details need more discussion. Depending on the results of that discussion we may need to go through API review again.alfredmyers commentedon Jun 2, 2018
While researching on the topic, I found an issue over on the Kestrel repo.
The folks over there had an issue about it but it was closed aspnet/KestrelHttpServer#480
juliusfriedman commentedon Jun 6, 2018
I have some methods related to this however by other names, e.g
I believe the name "CongestionAlgorithm" is appropriate and the api allows a broader range of options:
Also for Retransmission:
And for others (most already with baked in checked for OS) see(https://github.com/juliusfriedman/net7mma/blob/master/Common/Extensions/SocketExtensions.cs):
NoSynRetries, Timestamp, OffloadPreference, DelayFinAck, GetMaximumTransmittableUnit, Urgency and last but not least MaximumSegmentSize.
stephentoub commentedon Nov 23, 2018
Removing api-approved until this is resolved.
24 remaining items
karelz commentedon Jul 17, 2020
Moving to Future based on above analysis by @antonfirsov: #798 (comment)
ericsampson commentedon Nov 1, 2020
This would be great to see in some form in .NET 6
antonfirsov commentedon Nov 1, 2020
It's possible to configure this on .NET 5 on Linux and Windows:
Linux (per call):
Windows (once):
I can't see a good cross-platform abstraction for the option though. @ericsampson if you have a real-life use-case for this, is there any problem with the platform-specific solutions I'm suggesting?
Additionally to disabling the Nagle algorithm, disable delayed ACKs.
The SIO_TCP_SET_ACK_FREQUENCY flag seems to be supported only on Wind…
Update dependencies from https://github.com/dotnet/arcade build 20211…
wfurt commentedon Nov 30, 2022
triage: workaround exist through platform specific. Since there is no consistent cross-platform it seems like bad fit for general Socket API. We can revisit this in the future.