{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/16375","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/16375/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/16375/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/16375/events","html_url":"https://github.com/dotnet/corefx/issues/16375","id":209374577,"number":16375,"title":"TCP Fast Open implementation?","user":{"login":"icylogic","id":2814357,"avatar_url":"https://avatars2.githubusercontent.com/u/2814357?v=3","gravatar_id":"","url":"https://api.github.com/users/icylogic","html_url":"https://github.com/icylogic","followers_url":"https://api.github.com/users/icylogic/followers","following_url":"https://api.github.com/users/icylogic/following{/other_user}","gists_url":"https://api.github.com/users/icylogic/gists{/gist_id}","starred_url":"https://api.github.com/users/icylogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/icylogic/subscriptions","organizations_url":"https://api.github.com/users/icylogic/orgs","repos_url":"https://api.github.com/users/icylogic/repos","events_url":"https://api.github.com/users/icylogic/events{/privacy}","received_events_url":"https://api.github.com/users/icylogic/received_events","type":"User","site_admin":false},"labels":[{"id":153714228,"url":"https://api.github.com/repos/dotnet/corefx/labels/api-needs-work","name":"api-needs-work","color":"207de5","default":false},{"id":497898539,"url":"https://api.github.com/repos/dotnet/corefx/labels/area-System.Net.Sockets","name":"area-System.Net.Sockets","color":"d4c5f9","default":false},{"id":311091887,"url":"https://api.github.com/repos/dotnet/corefx/labels/os-windows","name":"os-windows","color":"fef2c0","default":false},{"id":145399958,"url":"https://api.github.com/repos/dotnet/corefx/labels/up%20for%20grabs","name":"up for grabs","color":"159818","default":false}],"state":"open","locked":false,"assignee":{"login":"icylogic","id":2814357,"avatar_url":"https://avatars2.githubusercontent.com/u/2814357?v=3","gravatar_id":"","url":"https://api.github.com/users/icylogic","html_url":"https://github.com/icylogic","followers_url":"https://api.github.com/users/icylogic/followers","following_url":"https://api.github.com/users/icylogic/following{/other_user}","gists_url":"https://api.github.com/users/icylogic/gists{/gist_id}","starred_url":"https://api.github.com/users/icylogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/icylogic/subscriptions","organizations_url":"https://api.github.com/users/icylogic/orgs","repos_url":"https://api.github.com/users/icylogic/repos","events_url":"https://api.github.com/users/icylogic/events{/privacy}","received_events_url":"https://api.github.com/users/icylogic/received_events","type":"User","site_admin":false},"assignees":[{"login":"icylogic","id":2814357,"avatar_url":"https://avatars2.githubusercontent.com/u/2814357?v=3","gravatar_id":"","url":"https://api.github.com/users/icylogic","html_url":"https://github.com/icylogic","followers_url":"https://api.github.com/users/icylogic/followers","following_url":"https://api.github.com/users/icylogic/following{/other_user}","gists_url":"https://api.github.com/users/icylogic/gists{/gist_id}","starred_url":"https://api.github.com/users/icylogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/icylogic/subscriptions","organizations_url":"https://api.github.com/users/icylogic/orgs","repos_url":"https://api.github.com/users/icylogic/repos","events_url":"https://api.github.com/users/icylogic/events{/privacy}","received_events_url":"https://api.github.com/users/icylogic/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/dotnet/corefx/milestones/5","html_url":"https://github.com/dotnet/corefx/milestone/5","labels_url":"https://api.github.com/repos/dotnet/corefx/milestones/5/labels","id":1328080,"number":5,"title":"Future","description":"Milestone tracking the issues triaged for an unspecified future release","creator":{"login":"joshfree","id":1302850,"avatar_url":"https://avatars2.githubusercontent.com/u/1302850?v=3","gravatar_id":"","url":"https://api.github.com/users/joshfree","html_url":"https://github.com/joshfree","followers_url":"https://api.github.com/users/joshfree/followers","following_url":"https://api.github.com/users/joshfree/following{/other_user}","gists_url":"https://api.github.com/users/joshfree/gists{/gist_id}","starred_url":"https://api.github.com/users/joshfree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshfree/subscriptions","organizations_url":"https://api.github.com/users/joshfree/orgs","repos_url":"https://api.github.com/users/joshfree/repos","events_url":"https://api.github.com/users/joshfree/events{/privacy}","received_events_url":"https://api.github.com/users/joshfree/received_events","type":"User","site_admin":false},"open_issues":803,"closed_issues":128,"state":"open","created_at":"2015-09-29T00:25:45Z","updated_at":"2017-03-06T23:48:17Z","due_on":null,"closed_at":null},"comments":16,"created_at":"2017-02-22T07:35:54Z","updated_at":"2017-03-07T00:38:53Z","closed_at":null,"body":"## Proposal: TCP Fast Open\r\n\r\nTCP Fast Open is an extension for TCP to speed up the handshaking process in successive TCP connections. This feature has been available for OSX and Linux for years and was implemented on Windows by Anniversary Update. Users could check by `netsh`\r\n```\r\n>netsh int tcp show global\r\nQuerying active state...\r\n\r\nTCP Global Parameters\r\n----------------------------------------------\r\n...\r\nTCP Fast Open                       : enabled\r\n```\r\nbut dotnet has not implemented this for System.Net yet.\r\n\r\n### Rational and Usage\r\n\r\nThis new API is important and powerful because when it is used with TLS False Start, we are down to 1-RTT from original 3-RTT for a successive TCP+TLS (HTTPS) connection, and furthermore, 0-RTT could be achieved by combining TFO and TLS 1.3.\r\n\r\nAnd it's easy to use: programmers only need to add a few lines to set an socket option and provide a buffer filled with data to send. Here's the usage:\r\n\r\n``` C#\r\nvar s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\r\nvar e = new SocketAsyncEventArgs();\r\ns.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.FastOpen, true);\r\ne.SetBuffer(buffer, offset, length); \r\ns.ConnectAsync(e);\r\n```\r\n\r\nNote that  `buffer[offset]` ~ `buffer[offset+length-1]` might be (partially) sent together with SYN. It's up to the OS how to send.\r\n\r\nA typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.\r\n\r\nPlease check the \"Original Proposal\" for details.\r\n\r\n### Proposed API\r\n\r\n``` C#\r\nnamespace System.Net.Sockets\r\n{\r\n    // Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.\r\n    public enum SocketOptionName\r\n    {\r\n        // ...\r\n\r\n        #region SocketOptionLevel.Tcp\r\n        // ...\r\n        FastOpen = 15\r\n        #endregion\r\n\r\n    }\r\n}\r\n```\r\n\r\nThis enum value is 15 for Windows according to `ws2ipdef.h`.\r\n\r\n### Problems & Extra works\r\n\r\n- Implementation\r\n  In fact, adding just one line like the code above in [SocketOptionName.cs](https://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/System.Net.Sockets/src/System/Net/Sockets/SocketOptionName.cs) would work for Windows.\r\n  However, it might not work for Unix. Since dotnet simply pass the socket option to native API on Windows while the Unix Pal would check the value. For more information about the difference please check the relevant issue #14237 . To make this work for Unix we may need to modify [this part](https://github.com/dotnet/corefx/blob/master/src/Native/Unix/System.Native/pal_networking.cpp#L2103-L2113)\r\n\r\n- Compatibility\r\n  According to [MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596(v=vs.85).aspx), this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform\r\n\r\n- Other System.Net API\r\n  For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for \"https://\" scheme.\r\n\r\n### Original Proposal\r\n\r\n#### TCP Fast Open on Windows\r\nWindows has introduced TCP Fast Open in the Anniversary Update serveral months ago. ([Announcing: New Transport Advancements in the Anniversary Update for Windows 10 and Windows Server 2016](https://blogs.technet.microsoft.com/networking/2016/07/18/announcing-new-transport-advancements-in-the-anniversary-update-for-windows-10-and-windows-server-2016/))\r\n> TFO is one full Round Trip Time (RTT) faster than the standard TCP setup which requires a three way-handshake. This leads to latency savings and is very relevant to short web transfers over the Internet where the average latency is on the order of 40 msec.\r\n\r\n#### Native API for TCP Fast Open \r\nThis feature could be turned on using native Windows Socket 2 API: [IPPROTO_TCP Socket Options](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596(v=vs.85).aspx). But it has not been implemented in dotnet ([SocketOptionName.cs](https://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/System.Net.Sockets/src/System/Net/Sockets/SocketOptionName.cs)). \r\n\r\n#### dotnet API relating to TCP Fast Open\r\nAccording to the Native API Documentation, in addition to passing a new enum value to  the method `setSocketOption` which then calls the native `setsockopt`, we need to set up the buffer including the data to send during the initial connection:\r\n>Note that to make use of fast opens, you should use ConnectEx to make the initial connection, and specify data in that function's lpSendBuffer parameter to be transferred during the handshake process. Some of the data in lpSendBuffer will be transferred under the Fast Open protocol.\r\n\r\nThe native method `ConnectEx` is called by  [`DoOperationConnect`](https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs#L235) which is called by [`socket.ConnectAsync`](https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs#L235) on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.\r\n\r\n```C#\r\n//TFO is defined as 15 in ws2ipdef.h\r\nsocket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)15, true);  \r\ne.SetBuffer(buffer, start, length);  //e is a SocketAsyncEventArgs\r\nsocket.ConnectAsync(e);\r\n```\r\n\r\n#### dotnet implementation\r\nThe most straightforward way to implement this feature is to add a new value to the SocketOptionName enum. But it enables this feature only on Windows. In this issue https://github.com/dotnet/corefx/issues/14237, it seems that members are interested in introducing a new cross-platform API for TCP options.\r\n>It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.\r\n\r\nPS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: [TCP Fast Open: expediting web services](https://lwn.net/Articles/508865/)\r\n\r\nMore about TCP Fast Open:\r\n- [RFC7413](https://tools.ietf.org/html/rfc7413)\r\n- [Windows blog: Building a faster and more secure web with TCP Fast Open, TLS False Start, and TLS 1.3](https://blogs.windows.com/msedgedev/2016/06/15/building-a-faster-and-more-secure-web-with-tcp-fast-open-tls-false-start-and-tls-1-3/#0ODjLsVbVq2W3FyD.97)"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/284582520","html_url":"https://github.com/dotnet/corefx/issues/16375#issuecomment-284582520","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/16375","id":284582520,"user":{"login":"geoffkizer","id":12518809,"avatar_url":"https://avatars1.githubusercontent.com/u/12518809?v=3","gravatar_id":"","url":"https://api.github.com/users/geoffkizer","html_url":"https://github.com/geoffkizer","followers_url":"https://api.github.com/users/geoffkizer/followers","following_url":"https://api.github.com/users/geoffkizer/following{/other_user}","gists_url":"https://api.github.com/users/geoffkizer/gists{/gist_id}","starred_url":"https://api.github.com/users/geoffkizer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geoffkizer/subscriptions","organizations_url":"https://api.github.com/users/geoffkizer/orgs","repos_url":"https://api.github.com/users/geoffkizer/repos","events_url":"https://api.github.com/users/geoffkizer/events{/privacy}","received_events_url":"https://api.github.com/users/geoffkizer/received_events","type":"User","site_admin":false},"created_at":"2017-03-07T00:38:53Z","updated_at":"2017-03-07T00:38:53Z","body":"> At the very least, it might alleviate potential confusion around exactly what SetSocketOption does.\r\n\r\nParticularly if we're adding something like \"SetRawSocketOption\" for platform-specific socket option acces.\r\n\r\nIt would be nice to say:\r\n(a) Platform-agnostic settings are exposed via easy to discover properties; they often map to socket options, but due to differences between platforms, we map these as appropriate\r\n(b) Platform-specific socket options are accessible through a new API(s); use at your own risk\r\n(c) SetSocketOptions is deprecated; use the properties from (a) instead\r\n\r\nThoughts?"}}
{"actor":{"display_login":"geoffkizer"}}