Skip to content
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

QUIC support #23064

Open
rektide opened this issue Sep 24, 2018 · 35 comments

Comments

Projects
None yet
@rektide
Copy link

commented Sep 24, 2018

Is your feature request related to a problem? Please describe.
The web is gaining a new connection-less, enduring long term way of communicating, quic & it would be great to be able to use this new communication technology in node.

Describe the solution you'd like
It would be excellent to see a quic module supported in Node.

Describe alternatives you've considered
We could do this in userland, but like http and http2, I believe it is fundamental & integral enough to the web & Node's purposes that Node should officially support an implementation.

@mscdex

This comment has been minimized.

Copy link
Contributor

commented Sep 24, 2018

As far as I can see QUIC no longer has a current IETF draft, so I think it's a bit premature to be adding it to core at this time. Also, there are already some QUIC addons and pure js modules available on npm.

@Fishrock123

This comment has been minimized.

Copy link
Member

commented Sep 26, 2018

I have never heard of "QUIC". I think this should be indefinitely shelved until some potential future usage in applications or implementation as a web standard is at a very significant stage.

I suggest closing this as nothing may be actionable for years or perhaps ever.

@Fishrock123

This comment has been minimized.

Copy link
Member

commented Sep 28, 2018

Closing, at least for now.

@jasnell

This comment has been minimized.

Copy link
Member

commented Oct 2, 2018

I don't think closing this so quickly is necessary really. QUIC has a while to go before it is proven out but I think it's worthwhile keeping this open while we at least have the discussion. I'm not going to reopen it myself but I'm happy to keep discussing.

@rektide ... The quic module on npm today has only 18 downloads over the past week. I have not evaluated the quality of that module but that number suggests that the demand for this may not be very high. To help us have this discussion, it would be helpful to know:

  1. which browsers outside of Chrome are using QUIC
  2. the current state of any standardization efforts around QUIC
  3. the success or failure of any user land modules to provide an implementation of QUIC

Btw, given that QUIC conversations are almost always bundled with http2 discussions, pinging @nodejs/http2 for thoughts and opinions.

@jasnell jasnell added net http2 labels Oct 2, 2018

@LPardue

This comment has been minimized.

Copy link

commented Oct 2, 2018

The IETF are working to standardise QUIC. Their milestone plan is on this bottom of this page. The family of documents are due to be submitted to IESG in November 2018. The main documents of interest to this thread are the Transport and HTTP mapping documents.

HTTP over QUIC is similar to HTTP/2 but there are subtle (and not so subtle) differences.

A list of QUIC implementations are available on the working group wiki. There are no current browsers that support IETF HTTP over QUIC. However, Chrome has indicated it's intent to migrate their Google QUIC support towards an IETF (compatible) version.

The WG have held several interop sessions where the above implementations have been tested against each other. To date, the main application-level testing has been simple HTTP/1.1. The formal HTTP over QUIC mapping has not had much interop.

@jasnell

This comment has been minimized.

Copy link
Member

commented Oct 2, 2018

I hadn't realized that the IETF WG had made that much progress. That's definitely encouraging! I will say that it is going to be difficult gathering support to implement QUIC in Node.js so long as there are no major browsers supporting the IETF version of the protocol but that doesn't mean that we cannot explore it. One thing that would be good to know is: how difficult is it to implement the protocol in a performant way in pure userland code? Does it require native addon development?

@LPardue

This comment has been minimized.

Copy link

commented Oct 2, 2018

It's probably also worth highlighting that the IETF version of QUIC makes a much clearer separation of the transport layers and application layers than Google's version. This, in effect, means that QUIC becomes a secure, multiplexed transport for any application. This then becomes a natural substitute for other UDP-based protocols. There are several groups looking at other applications on top of QUIC. For instance, using QUIC as the transport for WebRTC.

I'm no Node.js expert, but I might suggest that providing a common core QUIC transport capability could allow innovation in the application space in userland.

@addaleax addaleax reopened this Oct 3, 2018

@mcollina

This comment has been minimized.

Copy link
Member

commented Oct 3, 2018

I think the bare minimum Node.js has to do is to add DTLS support. The major issue with that one has been finding a corporate sponsor to fund that work, as it looks like a sizable task that is bigger of a single individual.

@LPardue

This comment has been minimized.

Copy link

commented Oct 3, 2018

DTLS is not required for QUIC. It uses the TLS 1.3 handshake to establish a session key that is used to protect QUIC packets using AEAD.

@rmarx

This comment has been minimized.

Copy link

commented Oct 3, 2018

As a research project, we have been working on a NodeJS-based IETF QUIC client called Quicker (https://github.com/rmarx/quicker) (note: very unstable, very non-production ready). It's currently fully implemented in TypeScript (except for the OpenSSL stuff, which uses the NodeJS OpenSSL dependency + some C++ interfacing code). It's too early to do real performance testing and comparison to C/C++, but very early results do indicate a severe performance penalty for this type of setup.

It's my feeling that eventually NodeJS will want to use a C/C++ library for the main QUIC stuff (the creator of nghttp2, which Node now uses to provide HTTP/2, is also working on a C QUIC library called ngtcp2, which seems a likely candidate). One of the nice things about HTTP/2 was that it could be added with a simple NPM package (the "spdy" package was the one we used in our research), but this is currently more complex for QUIC because of the OpenSSL/TLS1.3 dependency which is still changing (the creator of ngtcp2 has his own OpenSSL fork for these changes, which we use as well). We currently have our own forked NodeJS with direct C++ changes, but are looking if we can't do this as a native plugin as well, which would be easier to redistribute (but still more of a PITA than an NPM package).

Long story short: I think it's currently too early to contemplate adding QUIC to NodeJS proper, but maybe looking into ways to speed up OpenSSL updates to the latest versions / integration with a (native) plugin would open up options for semi-easy to install external plugins while the libraries mature enough to be integrated later. If anyone from the Node project would be willing to help with that, please let me know :)

@jasnell

This comment has been minimized.

Copy link
Member

commented Oct 3, 2018

We do have an ongoing effort to update openssl. From the sounds of it, implementing in core sounds like it would be best from an ease of implementation perspective once we do have the necessary openssl updates and once there are more implementations of the ietf version available.

For those who want to see this: what are the top three compelling features of the protocol that make it essential?

@LPardue

This comment has been minimized.

Copy link

commented Oct 3, 2018

For those who want to see this: what are the top three compelling features of the protocol that make it essential?

In no order:

And more speculatively, opening the door to more advanced approaches to Path MTU Detection.

@rmarx

This comment has been minimized.

Copy link

commented Oct 4, 2018

Interesting to see your list Lucas :)
For me:

  • Much faster connection establishment (0-RTT best case, 1-RTT worst case). This can also be achieved with TCP fast open + TLS1.3, but this requires (much?) more effort during server setup
  • More resilience to packet loss (TCP head of line blocking problem is resolved, each individual stream (resource) has separate loss detection logic, (much) better for slow/cellular networks)
  • Custom congestion control algorithms per-connection (for example when using Chrome's NetInfo API, congestion control logic can be adapted early based on the connection, leading to faster transfers for (small) resources).

As Lucas has also said, QUIC is not just intended for use with HTTP, but could be seen as a new transport layer protocol (sometimes also called TCP2.0), so it's useful for more than just typical web servers.

@rektide

This comment has been minimized.

Copy link
Author

commented Oct 4, 2018

For those who want to see this: what are the top three compelling features of the protocol that make it essential?

  • Connectionless behavior. I can be on cellular, talking with a server, switch over to wifi, & the server will understand that it's still me talking to it. Also permits multipathing, allowing me to be talking to the server over both at once. More importantly to me, it means that my connection isn't going to get dropped by middleboxes & have to get set up again: I can stay "connected" via QUIC for potentially a very very very long time, which makes it extremely interesting for things like sending notifications to users & other long-running sparse connected systems. I am 100% here for this.
  • No head of line blocking!! HTTP2 has streams, but since it works over TCP, so if there's packet loss or slow down, the other un-related streams to the stream that just had packet loss have to slow down, even if there's a ton of other usable data still flowing nicely. In QUIC, out of order packets can be assembled in order in the appropriate stream right away since there's no TCP bottleneck. This is a huge upgrade over HTTP2, & makes the massive change to a binary protocol we toiled for so long to make happen actually worthwhile for the first time. Massive potential to speed up cellular users, give them far far more robust & predictable performance.
  • Forward error correction may, may not end up being included. Potentially interesting for lossy connections.
  • Fast connection set up time.
@sebdeckers

This comment has been minimized.

Copy link
Contributor

commented Oct 5, 2018

QUIC is the new TCP Socket. High-performance, stability, security are my QUIC wishlist.

Other protocol working groups at IETF like DNS-over-HTTPS or RTCWeb (aka WebRTC) seem to be moving in the direction of recommending or assuming QUIC to replace UDP or TCP.

HTTP over QUIC is a separate spec. It could be reasonable to expose a lower level pure QUIC API in a quic module, with a separate higher level http-over-quic module that mostly implements the http2 module's core (and compatibility) interfaces.

@mcollina

This comment has been minimized.

Copy link
Member

commented Oct 5, 2018

I'm in favor of adding this as soon as it gets adoption in the rest of the OSS ecosysten; it seems a bit premature to add this right now, as the protocol has not been standardized just yet.

@reklatsmasters

This comment has been minimized.

Copy link
Contributor

commented Oct 6, 2018

QUIC is much easier of DTLS + SCTP stack in WebRTC. I can't wait to use quic in NodeRTC. I hope that quic will be available in nodejs core as soon as possible. The specification is already exist. Anyway, there is not a problem to do pure js implementation.

@adrianhopebailie

This comment has been minimized.

Copy link

commented Oct 22, 2018

In Interledger.js we have been building a QUIC-inspired protocol called STREAM (https://github.com/interledgerjs/ilp-protocol-stream) and this has raised some interesting questions related to the standard Node modules/classes like net.Socket and DuplexStream.

I assume this issue is not the place to start designing but something worth noting is that a QUIC "socket" has multiple streams (as opposed to a TCP socket) so the current net.Socket abstraction (which extends DuplexStream) MAY not work as-is.

Is there a place that those working on implementing QUIC in Node.js are convening to discuss these (and possibly other) design issues?

@adrianhopebailie

This comment has been minimized.

Copy link

commented Oct 22, 2018

FYI: http2 and QUIC are a very compelling combination
https://tools.ietf.org/html/draft-ietf-quic-http-15

@trivikr

This comment has been minimized.

Copy link
Contributor

commented Oct 29, 2018

Proposal to call HTTP over QUIC as HTTP/3 https://mailarchive.ietf.org/arch/msg/quic/RLRs4nB1lwFCZ_7k0iuz0ZBa35s

EDIT: Updated that the link is a proposal as explained by @bazzadp in the following comment

@bazzadp

This comment has been minimized.

Copy link

commented Oct 29, 2018

Not quite. HTTP over QUIC is proposed to be called HTTP/3. QUIC will likely be used for transporting more than just HTTP. QUIC the transport layer will still be called QUIC. Part of the reason for this is to separate the two to avoid this confusion.

It’s also just a proposal at the moment and is to be discussed in next weeks IETF meet-up in Bangkok.

@jasnell

This comment has been minimized.

Copy link
Member

commented Oct 29, 2018

http/3 ... sigh. Ok, good to know.

@jasnell

This comment has been minimized.

Copy link
Member

commented Oct 29, 2018

FWIW, I've started to track the progress of the draft through IETF and I'm investigating implementation options. I'm currently focusing attention on the ngtcp2 implementation as that will most likely give us the best alignment with nghttp2 should we choose to move forward. What I would anticipate is the implementation moving in two phases:

  1. Implementation of the basic QUIC support. This would include both server and client, likely using a new internal module.. (e.g. const quic = require('quic')). The majority of the implementation would exist at the C/C++ level with a thin JavaScript binding on top.

  2. Phase 2 would be the HTTP/2 over QUIC integration. Because of the way the binding is defined such that HTTP/2 flow control, stream management, and headers are essentially taken over by QUIC, there would need to be a fairly sizable (but not unreasonable) refactoring in the HTTP/2 internals in node_http2.cc and node_http2.h. Changes at the JavaScript API layer should be minimal, fortunately.

My plan is to create a forked repository to begin implementation likely by around January, with an eye towards following the specification as it progresses. I will update this thread once that work begins and will include an invitation should anyone else want to help out ;-)

@bazzadp

This comment has been minimized.

Copy link

commented Oct 29, 2018

Btw not sure you saw this: https://www.ietf.org/blog/whats-happening-quic/. Says it will go into 2019 (not really a surprise to anyone thats been following this and Nov 2018 was a little too aggressive) but that it is getting close and is settling down.

They're not ready for Working Group Last Call yet, but the chairs, editors, and many implementers believe that we're exiting the design phase of the work so that we can focus on getting full implementation of the specifications to validate that design.

In other words, we think that the set of drafts is ready for broader implementation and review, even if we're not yet ready to say that they should become RFCs.

@rmarx

This comment has been minimized.

Copy link

commented Oct 29, 2018

Great to hear @jasnell! Definitely interested in contributing when you move forward.

I'm not sure at this moment if it's a good idea to refactor the current HTTP/2 API to support both HTTP/2 over TCP and HTTP over QUIC, since while they are similar, there are enough details that would make that difficult (e.g., QPACK). Especially looking toward future changes, it might be more flexible to keep them separate (afaik, some new things in HTTP/QUIC like prioritization placeholders will not be backported to HTTP/2 for example). However, that's still a ways of, so by the time the implementation starts, the proper route should be clearer. By then, ngtcp2 will probably also have its own HTTP/QUIC implementation to get inspiration from.

@LPardue

This comment has been minimized.

Copy link

commented Oct 29, 2018

Nice plan @jasnell.

This is probably of marginal interest but in case you were not aware, BBC R&D had a stab at implementing HTTP/QUIC on top of ngtcp2 - https://github.com/bbc/nghq. It doesn't support the conventional unicast mode of delivery, and it is a bit outdated now, but it should show an example of how to get ngtcp2 running

@trivikr

This comment has been minimized.

Copy link
Contributor

commented Nov 12, 2018

HTTP-over-QUIC will now officially be called HTTP/3
Details: https://daniel.haxx.se/blog/2018/11/11/http-3/

@sebdeckers

This comment has been minimized.

Copy link
Contributor

commented Nov 12, 2018

In light of the QUIC evaluation I re-ran some old benchmarks. Only have access to a little dual core Macbook at the moment; probably not ideal to run client & server together.

  • Response with static random data at various sizes: 512b from to 1Mb
  • HTTP/1.1 & HTTP/2
  • No TLS
  • No compression

Results:
https://benchmark.commons.host

Observations:

  • Worth looking into libh2o as an alternative to nghttp2. Performance is exceptional. See: https://powerdns.org/libh2o/
  • respondWithFile scores very low. Perhaps because it does additional fs.stat?
  • fs.createReadStream seems to be a bottleneck. Writing from a static buffer is faster.
@mcollina

This comment has been minimized.

Copy link
Member

commented Nov 13, 2018

Some of the samples have the same colors, making it really hard to understand at which one they refer to. Can you fix it? Maybe even split it in two diagrams.

@sebdeckers

This comment has been minimized.

Copy link
Contributor

commented Nov 13, 2018

@mcollina It's c3.js doing the UI. Try hovering/tapping on the labels. Zoom/pan on trackpad. Option+click shows only 1 graph.

Or use the raw data:
https://benchmark.commons.host/results.csv

@mcollina

This comment has been minimized.

Copy link
Member

commented Nov 13, 2018

Thanks, ok!

@ccinelli

This comment has been minimized.

Copy link

commented Mar 20, 2019

@jasnell

This comment has been minimized.

Copy link
Member

commented Mar 20, 2019

Progress is being made on this! In a separate repo. Pull request coming very soon

@sequoiar

This comment has been minimized.

Copy link

commented Mar 20, 2019

And, a similar try HTTP-over-UDT(udp transport) is there

https://github.com/InstantWebP2P/node-httpp

@ccinelli

This comment has been minimized.

Copy link

commented Mar 20, 2019

UDT seems a project stopped in the past. It seems built on the same ideas used in QUIC but what made all the difference in adoption is that Chrome already uses QUIC at scale. If you control the most used browser, pushing a new technology for the web is something you can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.