nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.36k stars 29.48k forks source link

QUIC support #23064

Closed rektide closed 4 years ago

rektide commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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.

Edit: hah. Years later, this comment is laughable. Sorry folks.

Fishrock123 commented 6 years ago

Closing, at least for now.

jasnell commented 6 years ago

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.

LPardue commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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.

mcollina commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

Interesting to see your list Lucas :) For me:

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 commented 6 years ago

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

sebdeckers commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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

trivikr commented 5 years ago

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

tunetheweb commented 5 years ago

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 commented 5 years ago

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

jasnell commented 5 years ago

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

tunetheweb commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

sebdeckers commented 5 years ago

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.

Results: https://benchmark.commons.host

Observations:

mcollina commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

Thanks, ok!

ccinelli commented 5 years ago

https://github.com/ngtcp2/nghttp3

jasnell commented 5 years ago

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

sequoiar commented 5 years ago

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

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

ccinelli commented 5 years ago

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.

devsnek commented 5 years ago

https://github.com/nodejs/quic

vitaly-t commented 5 years ago

HTTP/3 support in Node.js became officially a big deal since Sept 26, 2019...

jasnell commented 5 years ago

Yep, work is definitely underway! I'm hoping we can get the first iteration into master by November. There's still quite a bit of work to do and I've been intentionally taking my time on it to make sure (a) the API is right and (b) allowing the spec and the underlying ngtcp2 implementation library to get a bit more stable. Now that the browsers and Cloudflare are officially rolling out support, it's time to really start cracking on getting things out.

tvvignesh commented 5 years ago

@jasnell First of all thanks a lot for the work that you guys are doing. Looked at the quic repository - really great to see that work is in progress. Was wondering one thing though - Since http/3 is nothing but http/2 over QUIC with mainly the transport layer changing, will it impact the libraries we use for http calls?

erwanriou commented 4 years ago

if i can suggest, we should try to make it as compatible as possible and not change too much the http.createServer(options, app).listen logic

In express, they still cannot handle http2 properly and don't have roadmap on doing it... and if you want to have it production ready, you cannot use heroku easy solution (they just don't handle it), you must rely on something like Caddy on its behalf... Or cloudflare... (but isn't it just the cache of the statics? )

jasnell commented 4 years ago

We can certainly try, however, the implementation will support both raw QUIC and HTTP/3 layered on top of quick and the basis on UDP rather than TCP sockets means that the set up logic and internal implementation are entirely different. It's not likely to be too seamless. Work on the implementation is happening in https://github.com/nodejs/quic

audstanley commented 4 years ago

I've been using the node-quic library, and it's not looking like it's implemented. Here are some benchmarks against KCP (aes-128). If this gets implemented, I will change the benchmark code. I haven't added TCP tests just yet. Here are some early results without official support: KCP verses gQUIC

jasnell commented 4 years ago

The initial QUIC support has started landing in core. It will take a while to stablize and graduate from experimental but we're making progress and we can close this issue now.

TomasHubelbauer commented 4 years ago

@jasnell How can one start with experiment with HTTP/3 in Node? Do I need a pre-release version (which version is the first to include HTTP/3?), do I need to build from source? Do I need to pass some flags to the Node CLI? What is the module name to use, http3?

jasnell commented 4 years ago

You'd need to check out the main repo and build from source. When building, you'll need to use the --experimental-quic configuration flag (e.g. ./configure --experimental-quic on linux, vcbuild experimental-quic on windows). See the quic.md for details on how to use once built.

rekire commented 3 years ago

If I understand this correctly then currently is there just an experimental raw QUIC support there. I was able to setup an endpoint but I cannot handle the request. Do I see it correctly that the request is QPACK encoded and needs to been interpreteded first to understand what the client is actually asking for?

If so is there already an implementation to use? It seems to be similar as what is required for http2.

rekire commented 3 years ago

Any updates here? QUIC has been approved as RFC-9000.

dead-claudia commented 2 years ago

@rekire Found #38233 after a bit of searching