TCP Fast Open implementation? #1476

Description

@icylogic

Proposal: TCP Fast Open

TCP 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

>netsh int tcp show global
Querying active state...
TCP Global Parameters
----------------------------------------------
...
TCP Fast Open : enabled

but dotnet has not implemented this for System.Net yet.

Rational and Usage

This 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.

And 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:

vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

Please check the "Original Proposal" for details.

Proposed API

namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
#region SocketOptionLevel.Tcp
// ...FastOpen=15
#endregion
}}

This enum value is 15 for Windows according to ws2ipdef.h.

Problems & Extra works

  • Implementation
    In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
    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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

  • Compatibility
    According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

  • Other System.Net API
    For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

Original Proposal

TCP Fast Open on Windows

Windows 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)

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.

Native API for TCP Fast Open

This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

dotnet API relating to TCP Fast Open

According 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:

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.

The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

//TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

dotnet implementation

The 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.

It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

More about TCP Fast Open:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
      Skip to content

      TCP Fast Open implementation? #1476

      Description

      @icylogic

      Proposal: TCP Fast Open

      TCP 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

      >netsh int tcp show global
      Querying active state...
      TCP Global Parameters
      ----------------------------------------------
      ...
      TCP Fast Open : enabled
      

      but dotnet has not implemented this for System.Net yet.

      Rational and Usage

      This 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.

      And 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:

      vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

      Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

      A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

      Please check the "Original Proposal" for details.

      Proposed API

      namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
      #region SocketOptionLevel.Tcp
      // ...FastOpen=15
      #endregion
      }}

      This enum value is 15 for Windows according to ws2ipdef.h.

      Problems & Extra works

      • Implementation
        In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
        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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

      • Compatibility
        According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

      • Other System.Net API
        For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

      Original Proposal

      TCP Fast Open on Windows

      Windows 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)

      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.

      Native API for TCP Fast Open

      This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

      dotnet API relating to TCP Fast Open

      According 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:

      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.

      The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

      //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

      dotnet implementation

      The 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.

      It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

      PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

      More about TCP Fast Open:

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Assignees

      No one assigned

        Type

        No type

        Projects

        No projects

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
          Skip to content

          TCP Fast Open implementation? #1476

          Description

          @icylogic

          Proposal: TCP Fast Open

          TCP 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

          >netsh int tcp show global
          Querying active state...
          TCP Global Parameters
          ----------------------------------------------
          ...
          TCP Fast Open : enabled
          

          but dotnet has not implemented this for System.Net yet.

          Rational and Usage

          This 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.

          And 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:

          vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

          Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

          A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

          Please check the "Original Proposal" for details.

          Proposed API

          namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
          #region SocketOptionLevel.Tcp
          // ...FastOpen=15
          #endregion
          }}

          This enum value is 15 for Windows according to ws2ipdef.h.

          Problems & Extra works

          • Implementation
            In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
            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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

          • Compatibility
            According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

          • Other System.Net API
            For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

          Original Proposal

          TCP Fast Open on Windows

          Windows 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)

          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.

          Native API for TCP Fast Open

          This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

          dotnet API relating to TCP Fast Open

          According 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:

          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.

          The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

          //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

          dotnet implementation

          The 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.

          It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

          PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

          More about TCP Fast Open:

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Assignees

          No one assigned

            Type

            No type

            Projects

            No projects

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              TCP Fast Open implementation? #1476

              Description

              @icylogic

              Proposal: TCP Fast Open

              TCP 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

              >netsh int tcp show global
              Querying active state...
              TCP Global Parameters
              ----------------------------------------------
              ...
              TCP Fast Open : enabled
              

              but dotnet has not implemented this for System.Net yet.

              Rational and Usage

              This 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.

              And 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:

              vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

              Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

              A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

              Please check the "Original Proposal" for details.

              Proposed API

              namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
              #region SocketOptionLevel.Tcp
              // ...FastOpen=15
              #endregion
              }}

              This enum value is 15 for Windows according to ws2ipdef.h.

              Problems & Extra works

              • Implementation
                In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
                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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

              • Compatibility
                According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

              • Other System.Net API
                For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

              Original Proposal

              TCP Fast Open on Windows

              Windows 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)

              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.

              Native API for TCP Fast Open

              This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

              dotnet API relating to TCP Fast Open

              According 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:

              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.

              The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

              //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

              dotnet implementation

              The 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.

              It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

              PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

              More about TCP Fast Open:

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Assignees

              No one assigned

                Type

                No type

                Projects

                No projects

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
                  Skip to content

                  TCP Fast Open implementation? #1476

                  Description

                  @icylogic

                  Proposal: TCP Fast Open

                  TCP 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

                  >netsh int tcp show global
                  Querying active state...
                  TCP Global Parameters
                  ----------------------------------------------
                  ...
                  TCP Fast Open : enabled
                  

                  but dotnet has not implemented this for System.Net yet.

                  Rational and Usage

                  This 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.

                  And 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:

                  vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

                  Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

                  A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

                  Please check the "Original Proposal" for details.

                  Proposed API

                  namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
                  #region SocketOptionLevel.Tcp
                  // ...FastOpen=15
                  #endregion
                  }}

                  This enum value is 15 for Windows according to ws2ipdef.h.

                  Problems & Extra works

                  • Implementation
                    In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
                    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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

                  • Compatibility
                    According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

                  • Other System.Net API
                    For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

                  Original Proposal

                  TCP Fast Open on Windows

                  Windows 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)

                  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.

                  Native API for TCP Fast Open

                  This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

                  dotnet API relating to TCP Fast Open

                  According 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:

                  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.

                  The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

                  //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

                  dotnet implementation

                  The 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.

                  It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

                  PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

                  More about TCP Fast Open:

                  Activity

                  Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Type

                    No type

                    Projects

                    No projects

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                      Skip to content

                      TCP Fast Open implementation? #1476

                      Description

                      @icylogic

                      Proposal: TCP Fast Open

                      TCP 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

                      >netsh int tcp show global
                      Querying active state...
                      TCP Global Parameters
                      ----------------------------------------------
                      ...
                      TCP Fast Open : enabled
                      

                      but dotnet has not implemented this for System.Net yet.

                      Rational and Usage

                      This 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.

                      And 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:

                      vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

                      Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

                      A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

                      Please check the "Original Proposal" for details.

                      Proposed API

                      namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
                      #region SocketOptionLevel.Tcp
                      // ...FastOpen=15
                      #endregion
                      }}

                      This enum value is 15 for Windows according to ws2ipdef.h.

                      Problems & Extra works

                      • Implementation
                        In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
                        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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

                      • Compatibility
                        According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

                      • Other System.Net API
                        For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

                      Original Proposal

                      TCP Fast Open on Windows

                      Windows 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)

                      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.

                      Native API for TCP Fast Open

                      This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

                      dotnet API relating to TCP Fast Open

                      According 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:

                      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.

                      The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

                      //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

                      dotnet implementation

                      The 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.

                      It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

                      PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

                      More about TCP Fast Open:

                      Activity

                      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Type

                        No type

                        Projects

                        No projects

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                          Skip to content

                          TCP Fast Open implementation? #1476

                          Description

                          @icylogic

                          Proposal: TCP Fast Open

                          TCP 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

                          >netsh int tcp show global
                          Querying active state...
                          TCP Global Parameters
                          ----------------------------------------------
                          ...
                          TCP Fast Open : enabled
                          

                          but dotnet has not implemented this for System.Net yet.

                          Rational and Usage

                          This 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.

                          And 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:

                          vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

                          Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

                          A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

                          Please check the "Original Proposal" for details.

                          Proposed API

                          namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
                          #region SocketOptionLevel.Tcp
                          // ...FastOpen=15
                          #endregion
                          }}

                          This enum value is 15 for Windows according to ws2ipdef.h.

                          Problems & Extra works

                          • Implementation
                            In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
                            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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

                          • Compatibility
                            According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

                          • Other System.Net API
                            For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

                          Original Proposal

                          TCP Fast Open on Windows

                          Windows 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)

                          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.

                          Native API for TCP Fast Open

                          This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

                          dotnet API relating to TCP Fast Open

                          According 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:

                          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.

                          The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

                          //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

                          dotnet implementation

                          The 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.

                          It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

                          PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

                          More about TCP Fast Open:

                          Activity

                          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Type

                            No type

                            Projects

                            No projects

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                              Skip to content

                              TCP Fast Open implementation? #1476

                              Description

                              @icylogic

                              Proposal: TCP Fast Open

                              TCP 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

                              >netsh int tcp show global
                              Querying active state...
                              TCP Global Parameters
                              ----------------------------------------------
                              ...
                              TCP Fast Open : enabled
                              

                              but dotnet has not implemented this for System.Net yet.

                              Rational and Usage

                              This 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.

                              And 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:

                              vars=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);vare=newSocketAsyncEventArgs();s.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.FastOpen,true);e.SetBuffer(buffer,offset,length);s.ConnectAsync(e);

                              Note that buffer[offset] ~ buffer[offset+length-1] might be (partially) sent together with SYN. It's up to the OS how to send.

                              A typical usage is the TLS handshake. In successive connections, the client could send a SYN with TLS Client Hello.

                              Please check the "Original Proposal" for details.

                              Proposed API

                              namespaceSystem.Net.Sockets{// Defines socket option names for the <see cref='System.Net.Sockets.Socket'/> class.publicenumSocketOptionName{// ...
                              #region SocketOptionLevel.Tcp
                              // ...FastOpen=15
                              #endregion
                              }}

                              This enum value is 15 for Windows according to ws2ipdef.h.

                              Problems & Extra works

                              • Implementation
                                In fact, adding just one line like the code above in SocketOptionName.cs would work for Windows.
                                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 dotnet/corefx#14237 . To make this work for Unix we may need to modify this part

                              • Compatibility
                                According to MSDN, this option is available since Windows 10, 1607. Maybe we should generate a warning if this option is set on the older Windows platform

                              • Other System.Net API
                                For API using sockets in its code such as WebClient or HttpClient, it could take advantage of this feature, especially for "https://" scheme.

                              Original Proposal

                              TCP Fast Open on Windows

                              Windows 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)

                              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.

                              Native API for TCP Fast Open

                              This feature could be turned on using native Windows Socket 2 API: IPPROTO_TCP Socket Options. But it has not been implemented in dotnet (SocketOptionName.cs).

                              dotnet API relating to TCP Fast Open

                              According 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:

                              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.

                              The native method ConnectEx is called by DoOperationConnect which is called by socket.ConnectAsync on Windows. And the buffer could be set as a property of SocketAsyncEventArgs.

                              //TFO is defined as 15 in ws2ipdef.hsocket.SetSocketOption(SocketOptionLevel.Tcp,(SocketOptionName)15,true);e.SetBuffer(buffer,start,length);//e is a SocketAsyncEventArgssocket.ConnectAsync(e);

                              dotnet implementation

                              The 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.

                              It would be nice if the Public API contained all of the possible socket options across Windows, Linux, and Darwin.

                              PS. TCP Fast Open is natively supported on Linux and OSX. Here's how to use it on Linux: TCP Fast Open: expediting web services

                              More about TCP Fast Open:

                              Activity

                              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Type

                                No type

                                Projects

                                No projects

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions