-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement TCP Keep-Alive for WinHttpHandler #44889
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/ncl Issue Details
|
CheckDisposedOrStarted(); | ||
_receiveDataTimeout = value; | ||
} | ||
} | ||
|
||
public bool TcpKeepAliveEnabled { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the set here call CheckDisposedOrStarted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default here is false? I'm just questioning that because the comment earlier says "The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second" which suggests the default here should actually be true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second
The same docs also state that :
The SO_KEEPALIVE option for a socket is disabled (set to FALSE) by default. [...] When this socket option is enabled, the TCP stack sends keep-alive packets when no data or acknowledgement packets have been received for the connection within an interval.
From this I concluded that if SO_KEEPALIVE
or SIO_KEEPALIVE_VALS
are left unchanged, no keepalive packets gonna be sent. We may want to double check with the winsock team since the wording is kinda contradictional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's double-check, and then either update the implementation or the comment :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The defaults is false. This discussion resulted in an update of the docs ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never see TCP keep-alive packets in HTTP network traces I get from customers, and that would be pretty obvious with the 1 second interval. I know we decided we're sticking with winsock defaults and violating RFC, but the RFC does say TCP keep-alives should default off in no uncertain terms:
Implementors MAY include "keep-alives" in their TCP
implementations, although this practice is not universally
accepted. If keep-alives are included, the application MUST
be able to turn them on or off for each TCP connection, and
they MUST default to off.
https://tools.ietf.org/html/rfc1122#page-101
I'm glad the winsock defaults at least align with the RFC on this part.
@@ -70,6 +70,8 @@ public static ProxyInfo RequestProxySettings | |||
|
|||
public static List<IntPtr> WinHttpOptionClientCertContext { get { return winHttpOptionClientCertContextList; } } | |||
|
|||
public static (uint KeepAliveTime, uint KeepAliveInterval)? TcpKeepaliveOptions { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the other properties here are named WinHttpOption*, should we do the same for this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple small issues above, otherwise LGTM
keepaliveinterval = (uint)_tcpKeepAliveInterval.TotalMilliseconds, | ||
keepalivetime = (uint)_tcpKeepAliveTime.TotalMilliseconds | ||
}; | ||
void* ptr = &tcpKeepalive; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this local seems unnecessary, and you can just use (IntPtr)&tcpKeepalive
below.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@geoffkizer I think all finding have been addressed, wondering if it's worth to wait for a few more approvals for this. |
LGTM |
@geoffkizer @stephentoub what about documentation? Should I add xmldoc right in the PR, or is it sufficient to have the |
Yup, thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to improve validation, otherwise lgtm.
src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
Show resolved
Hide resolved
I've added the docs, can someone double-check the them before we merge? |
LGTM |
This implements the API proposal from #44025 (comment) except the
[SupportedOSPlatform("windows10.0.2004")]
bits. I prefer to handle that separately in a follow-up PR, since it doesn't seem to be a a functional concern, but rather focuses on managing build targets.I decided to handle compatibility in a way consistent with other properties:
WinHttpException
will be thrown, if OS doesn't support the property.Contributes to #44025.
/cc @geoffkizer @wfurt @alnikola