Repository navigation
Update on QUIC #57281
Description
Activity
Next steps: My next step is to dig further into the new OpenSSL APIs to determine if they can be used together with ngtcp2. I will update here once I know more.
Update: It looks like OpenSSL 3.5 is not expected to be released until sometime in April, which means we're not likely to be able to make any real progress until at least then.
Reacted by Antoine du Hamel, Trivikram Kamat, Sebastian Beltran, Yagiz Nizipli, Tim Fish, Richard Lau, Jason Zhang, merojosa, Gregory Daynes, Will Slattum and 32 moreUpdate: It looks like OpenSSL 3.5 is not expected to be released until sometime in April, which means we're not likely to be able to make any real progress until at least then.
FWIW the roadmap from OpenSSL for 3.5:
- Alpha release date: March 11, 2025
- Beta release date: March 25, 2025
- Release date: April 8, 2025So we'll hopefully get an alpha next week. I can look at adding an on-demand CI to test dynamically linking Node.js against the alpha/beta.
Reacted by Michael Dawson, James M Snell, Rafael Gonzaga, Will Slattum, Szymon Marczak, Sean Blonien, Isaiah Ballah and oriel haimCan we expect OpenSSL 3.5 to land on Node.js 24?
- It's the next LTS.
- It is releasing on April 8, 2025, which is before Node.js v24.0.0 release on April 22, 2025.
Based on https://github.com/nodejs/collaborators/discussions/202 we will end up with OpenSSL 3.5 on 22.x as well as 24.x. This does not however mean it'll happen with the first 24.x release. It'll happen eventually
Reacted by Trivikram Kamat, Kevin Stefanelli, Yann Brelière, teddybee, Jurj Andrei George, Sean Blonien, Isaiah Ballah and oriel haimReacted by Szymon Marczak, Jurj Andrei George and Isaiah Ballah- addedquicIssues and PRs related to the QUIC transport implementation.Issues and PRs related to the QUIC transport implementation.
on Mar 4, 2025 Ok, unfortunately it looks like the new quic-related APIs that openssl is insisting on are not going to work with the ngtcp2 dependency. The reason is fairly straightforward... the original APIs that Openssl refused to land are based on a pull-model, where ngtcp2 pulls the necessary stuff from openssl as needed while the new apis that openssl has landed are push based. This difference means that the basic abstraction api that ngtcp2 has implemented (and that works with numerous other TLS implementations) just won't work. The author of ngtcp2 has no plans to try to make it work. Thus far, openssl has chosen to implement a model that is just fundamentally incompatible with the way the other tls implementations work.
So what does all this mean? It means that QUIC in Node.js is likely dead at this point unless one of the following occur:
- We pivot away from using ngtcp2 and nghttp3 to using an as-yet-unspecified alternative implementation that is capable of using the new openssl APIs (this would mean rewriting a massive portion of the code I have ... again).
- Someone is somehow able to implement a wrapper around the new openssl apis that makes it work with ngtcp2
- Openssl has a change of heart and decides to provide useful APIs that the ecosystem can use.
- We're able to switch to Boringssl and drop openssl entirely.
At this point I'm not confident that any of these will happen. Therefore, I'm just about ready to call it quits and just abandon the effort entirely. I will be exploring a couple of other options over the next few days but unless anyone has any helpful concrete suggestions, if I'm not able to identify a path forward within the next few days I will be opening a PR that just removes anything relating to quic back from the repo and giving up the effort entirely.
Reacted by Trivikram Kamat, João Filipe Silva de Almeida, Emanuel Lindström and Alberto EspositoReacted by Trivikram Kamat, João Filipe Silva de Almeida, EVA (Entity Value Attribute), Valentin Semirulnik, Yann Brelière, Jesse Pence, Shawn Mealey, Fabian Scherer and oriel haimReacted by Gus, Sebastian Beltran, Will Slattum, Tim Perry, Gürgün Dayıoğlu, Mathew Heard, Tyson Clugg, Niels Kersic, EVA (Entity Value Attribute), Valentin Semirulnik and 8 moreReacted by Sebastian Beltran, Toni Villena, Szymon Marczak, Arthur Moore and YohanSI'm just a JS dev that really likes Node, so I know I'm not qualified to comment here. But, I will anyway. :)
It really seems like the best long-term solution at this point is to abandon OpenSSL in favor of another implementation. Even beyond the issues with QUIC there are also the regular vulnerabilities that pop up. I understand that OpenSSL is pretty deeply integrated with Node, so switching would be a huge task, but that's my $0.02.
I know you've poured a ton of work/time into getting QUIC into Node, and I wanted to say thank you for that effort.
Reacted by Omar Assadi and RichlvReacted by Gürgün Dayıoğlu, Yagiz Nizipli, Sebastian Beltran, Will Slattum, jimin_park, Matteo Collina, James M Snell, thermarthae, ignoramous, Clint Harrison and 22 moreI've been digging into some options over the past few days and will be having a call soon with the folks in openssl who are working on the quic stuff they do have. Hopefully that will bear some fruit that will allow us to move forward.
I've also been chatting a bit with the author of ngtcp2 and he thinks that there might be a workaround with the openssl APIs that involves quite a bit more bookkeeping complexity but still might be possible.
There's another library called picotls that ngtcp2 can work with that also layers on top of openssl that could be an option but it has no API stability or LTS guarantees so that would likely be a last resort kind of option.
Once I have the call with the openssl folks I'll come back and update here on possible next steps.
Reacted by Matteo Collina, Alex Potsides, Igor Savin, Trivikram Kamat, Toni Villena, Tim Perry, Sebastian Beltran, Dominic, Will Slattum, thermarthae and 27 moreEven beyond the issues with QUIC there are also the regular vulnerabilities that pop up.
openssl has probably more eyes who find vulnerabilities than other less reviewed implementations.
Reacted by Paola (Alma) Captanovska, Jurj Andrei George and RichlvA... Quic... Update here... ;-)
Happy days! There is work underway by the lead maintainer of ngtcp2 (@tatsuhiro-t) with assistance from a couple openssl folks to implement the necessary abstraction bits to get ngtcp2 working with openssl 3.5. This means that we're back on track to having quic in node.js but there's obviously going to be more of a delay as it is not clear when that work will be ready to go. I'm monitoring closely and will update as I know more.
Reacted by Jordan Harband, João Filipe Silva de Almeida, Nils K, Gürgün Dayıoğlu, Ethan Arrowood, Jurj Andrei George and Pramit SharmaReacted by Yann Brelière, Paola (Alma) Captanovska, Ajay Jadhav, TyIsI, Matt W, Jurj Andrei George and JannisReacted by Tim Perry, Filip Skokan, Igor Savin, Sebastian Beltran, Trivikram Kamat, Alex Potsides, Anatoly Voevodin, Dominic, Will Slattum, thermarthae and 29 morengtcp2/ngtcp2#1582 is merged into main.
Reacted by Richard Lau, v1rtl, Tim Perry, Anatoly Voevodin, Will Slattum, Trivikram Kamat, Sebastian Beltran, thermarthae, Matt Ickstadt, James M Snell and 23 moreNow, once Node.js is updated to OpenSSL 3.5 (which @richardlau and @targos are looking at I believe) I will be able to pick this up and continue this work. Woo!
Unfortunately all of this does mean that we will be unable to backport any of the QUIC stuff to any prior Node.js version that does not have OpenSSL 3.5... but I'll just be happy when the darn thing is done.
Reacted by ignoramousReacted by Gus, Eric McDaniel, Dan Gee, Chengzhong Wu, Anton Sapyanov, Yeonju Hwang, TyIsI, Jurj Andrei George, Isaiah Ballah, oriel haim and 1 moreReacted by Alex Potsides, Dominic, Sebastian Beltran, Matteo Collina, thermarthae, Trivikram Kamat, Will Slattum, prostreyd, Jannis, Anatoly Voevodin and 19 more👍 on moving to BoringSSL.
One workaround for the lack of long term support is to always build with a bundled BoringSSL that is statically linked and has its symbols stripped from the public API. Distributions would need to rebuild Node.js whenever there is a BoringSSL vulnerability.
Reacted by Brian, John Hurliman and Ivan GoncharovReacted by Nils K, Adam Jędrzejowski and Yeonju HwangAt this time we won't be moving to BoringSSL. I'm currently on hold waiting for Openssl 3.5 to be able to land. Once that is available I will be able to continue this work.
Reacted by Nils K, Sebastian Beltran, Trivikram Kamat, Mrgaton, Momen, Reece Carolan, Gürgün Dayıoğlu, Niels Kersic, Ryan Glover, Arthur Moore and 5 moreThank you for the work and the explanation of why a deadlock in development occurred.
When I started my Node.js WebTransport plugin for http/3 as an intermediate solution, I thought I could abandon it after a year and switch to the native implementation.I plan to eventually create a wrapper around the native node implementation (I have working software that I would need to reimplement otherwise, and a working node native http/2 implementation).
This would also mean that my tests can run against Node.js (including tests against browsers, quiche implementation), which may help find bugs (and I may also supply patches, at least for Firefox and Chromium, it happened like this).
Please tell me if and when this would be helpful for you.
(Only the obstacle I see is that the body is only aArrayBuffer | ArrayBufferView | Blob, which would break many streaming applications and is currently incompatible, but the underlyingDataQueueC++ class should also support a stream?)Reacted by Niels Kersic, Ryan Glover and Mathew Heard19 remaining items
Hi everyone,
I’ve been experimenting with a Node.js implementation of QUIC as part of an independent project. It’s still a work in progress (not production-ready yet), but it already includes a self-contained TLS 1.3 implementation (no OpenSSL dependency), packet parsing, and stream management.Here’s the repo if anyone is interested in following or providing feedback:
https://github.com/colocohen/quicoI thought it might be relevant to share here, since it shows that QUIC support in pure Node.js is feasible, and can evolve with community interest. Any thoughts or feedback are very welcome.
Reacted by ignoramousReacted by Mathew Heard, Uditha Atukorala, Daniel Norman, Ryan McCartney, stfn, gurgunday-spendesk, Gürgün Dayıoğlu, Isaiah Ballah, Michael Giraldo, Jannis and 6 more@colocohen I was not expecting TLS1.3 in ~2000 lines of JS!
Hey jasnell / trivikr, was QUIC released as part of the Nodejs 25 release?
Hi @Arka-98, QUIC is available with option
--experimental-quicin Node.js 25.x
Example code for handshake can be viewed in https://github.com/nodejs/node/blob/main/test/parallel/test-quic-handshake.mjsSome features are yet to be implemented. And it's going to take more time for QUIC to be tested by the community before it can get stable.
Node.js is volunteer driven project. Lead developer James and others are working on their free time.
If the support for QUIC in Node.js important for you, do help us get it to completion!An easiest way to help is to use QUIC with option
--experimental-quicin Node.js 25.x+ and either submit or upvote feature requests!
An example of a feature request from last week is to support for streaming posted at https://www.github.com/nodejs/node/issues/60234You can also dive deep into the implementation, and post PRs yourself to add support!
For example, @martenrichter who submitted the above feature request to support streaming has opened a PR at https://www.github.com/nodejs/node/pull/60237Other ways to contribute:
- Add unit tests where they're lacking. You can refer my conference talk for an example where I post a PR live from stage.
- Write documentation for folks who want to use QUIC in experimental mode.
Reacted by ignoramousReacted by David van der Sluijs, Arkadipta Das, Matteo Collina, David Arteaga, Jannis, Valentin Semirulnik, Morgan Touverey Quilling, rohan, Dan Gee, oriel haim and 7 moreReacted by Shawn Mealey, Oskar Larsson Högfeldt, Roger Padilla and Gussure thanks trivikr
Reacted by Trivikram KamatHow to test this without a proper http/3 server?
@khteh the committed code can host a server and function as a client. Its transport layer.
I'll be running the same test suite on it that we previously built to experiment with the previous QUIC implementation once clienthello and streams (PR https://www.github.com/nodejs/node/issues/60234) merge.
I've been looking into committing clienthello (inc dynamic key/certificate) support, havent figured out the specifics of doing it yet though. Seems not particularly beginner friendly so I might focus elsewhere for now.
Just asking out loud:
As far as the NodeJS implementation goes, is there a feature/implementation matrix of which spec features have been implemented and what hasn't, and what needs tests or testing?
Or is there a reference implementation test suite?
Reacted by Cisco Guillaume@almaceleste That doesn't include QUIC though?
Reacted by Cisco Guillaume and Pete Anøther@TyIsI, apparently, this is because this feature is not included in the EcmaScript.
@almaceleste that was my understanding as well.
That's why I figured I would ask if there is an implementation matrix specifically for QUIC.
I'll assume that there isn't one and see if I can get around to making one this week!
@jasnell & @martenrichter I'm not sure if it would be helpful, but I'd be happy to try and take a swing at some of those tests. Not sure if there is any in particular that might be helpful to grab.
Reacted by TyIsI@nbbeeken yes, thank you!
I'll get read up and redirect any questions I have to there.
Reacted by Neal Beeken
Just wanted to give an update on the situation with the QUIC implementation.
At this point I'm quite glad that I didn't move forward on the implementation that ... um... quickly.
Some history:
QUIC depends directly on TLS 1.3 as a core part of the protocol. Years ago BoringSSL defined and implemented a set of additional APIs that exposed the functionality runtimes need to correctly implement TLS 1.3 for QUIC. Engineers at Akamai and Microsoft ported those APIs -- again, years ago -- to OpenSSL and had a PR that sat there ready to go for years that the OpenSSL project refused to land. Because of the indecision, Akamai and Microsoft decided to lightly fork OpenSSL with the BoringSSL QUIC APIs which, because it was backwards compatible with OpenSSL and because they were able to keep it up to date with OpenSSL, we decided to adopt. So for a while now we have been shipping Node.js with this alternative OpenSSL+quic.
However, a while back the OpenSSL project decided, for reasons that are still completely mysterious to me, that they wanted to have their entirely own implementation of the full QUIC protocol. So instead of just landing the APIs that already existed and that folks were already using, they decided to come up with an entirely new implementation from scratch. Unfortunate, up to now this implementation has not exposed any of the APIs we would actually need to be able to implement QUIC ourselves.
What this decision by the OpenSSL OMC has done is forced Akamai and Microsoft to fully fork OpenSSL into a new project called quictls which is no longer tracking OpenSSL development. They will attempt to remain as API compatible as possible for most things but the QUIC stuff is completely separate. What's worse is that quictls is currently not able to commit to the kinds of Long Term Support guarantees that we need for Node.js.
This means that we are being forced off of quictls and will need to move back to the mainline OpenSSL.
Within the past few weeks, OpenSSL has added a handful of APIs to OpenSSL 3.5 that allow other implementations to make use of the TLS 1.3 implementation .... openssl/openssl#26683 ... The problem, of course, is that OpenSSL 3.5 has not yet been released and it is not actually clear if what APIs they have exposed will actually work with the ngtcp2 library that we use to handle most of the QUIC semantics. My next task will be to try to verify that ngtcp2 can use these new, different, as yet unreleased APIs.
This puts the entire QUIC-in-Node.js project at risk. If we cannot make these APIs work then I'm not quite sure where to go from here beyond adandoning all of the work that has already been done. I will be investigating further over the next few weeks and hopefully will be able to make something work but we shall see.
One additional downside of this approach taken by OpenSSL is that it will make it impossible to backport the QUIC implementation to any Node.js versions that does not have at least OpenSSL version 3.5.
Side note: I'd actually like us to consider the possibility of switching entirely to BoringSSL and away from OpenSSL. While BoringSSL does not carry the same Long Term Support guarantees that OpenSSL does, and has a much more constrained set of algorithms/options -- meaning it would absolutely be a breaking change -- the model they follow echoes that approach that v8 takes and we've been able to deal with that just fine.
/cc @nodejs/quic @nodejs/tsc @nodejs/net @nodejs/crypto