Skip to content

quic: implement multiple c++ side improvements#62620

Closed
jasnell wants to merge 5 commits intonodejs:mainfrom
jasnell:jasnell/quic-tlscontext-improvements
Closed

quic: implement multiple c++ side improvements#62620
jasnell wants to merge 5 commits intonodejs:mainfrom
jasnell:jasnell/quic-tlscontext-improvements

Conversation

@jasnell
Copy link
Copy Markdown
Member

@jasnell jasnell commented Apr 6, 2026

Further QUIC c++ side improvements supporting proper SNI handling, multi-ALPN negotiation on the server-side, hash performance/strength improvements, and some bug fixes.

Signed-off-by: James M Snell jasnell@gmail.com
Assisted-by: Opencode:Opus 4.6

jasnell added 4 commits April 6, 2026 13:55
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
@jasnell jasnell requested review from Qard and mcollina April 6, 2026 21:20
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/gyp
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Apr 6, 2026
@jasnell jasnell changed the title quic: implement rapidhash for hashing improvements quic: implement multiple c++ side improvements Apr 6, 2026
@nodejs-github-bot

This comment was marked as outdated.

@codecov

This comment was marked as outdated.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

nodejs-github-bot commented Apr 6, 2026

@jasnell jasnell added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 8, 2026
Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not deeply familiar with the QUIC code (or rapidhash) yet but it makes sense overall, details look reasonable to me - just two questions about the public API surface.

The ALPN (Application-Layer Protocol Negotiation) identifier(s).

For **client** sessions, this is a single string specifying the protocol
the client wants to use (e.g. `'h3'`).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we only support one ALPN value for clients? AFAICT there's no such restriction in QUIC itself, so we will want to support multiple values for clients fairly rapidly. It seems simpler to set the signature as string[] for everybody right from the start, and it looks like it'd make the implementation simpler and more consistent across the two sides.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is largely about use case... specifically, what use case will there be here the client doesn't know what protocol it wants to speak? Restricting to a single ALPN here simplifies the implementation flow and covers the majority case. But the overall api here is far from done... if there are use cases we need to cover, let's identify them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specifically, what use case will there be here the client doesn't know what protocol it wants to speak?

There's a few examples of this in production use today:

  • DNS works over QUIC natively (DoQ) or over HTTP/3 (DoH3).
  • Media streaming has native protocols for QUIC (MoQT) and for WebTransport-over-QUIC
  • MQTT works over QUIC natively, and over websockets.

That's before we get into people versioning QUIC protocols (e.g. moqt has used moqt-NN for the each draft N of the protocol). Again, none of this is a first-launch issues, but we'll run into this eventually, just want to avoid hassle later when we have to change the public API.

For this case, it does simplify the API surface long-term if we just support this from day 1, and simplifies some of the implementation here too (granted, not all of it - but we can drop the separate client/server logic from processTlsOptions at least).

endpoint.setSNIContexts({
'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
}, { replace: true });
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a good argument for the sni object form in the options, for performance & simplicity in the common case. I'm not so sure about the dynamic update method though?

We are eventually going to need a callback here (for dynamic cert generation, wildcard certificates, on-demand cert loading, etc). I would expect most setSNIContexts use cases would be subsumed by a SNICallback option, which means this method is largely redundant, and a callback would be more consistent with all our other TLS configuration anyway. Is there a use case I'm missing where this is API is preferable?

Not really opposed if you'd prefer to do this now and punt callbacks to later anyway, just want to make sure we're not aiming to implement this to replace SNI callbacks entirely, because I don't think it'll be sufficient.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, comes down to use cases. The current design keeps the implementation simple and easier to optimize. It's not immediately apparent if callbacks will definitely be needed later

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not immediately apparent if callbacks will definitely be needed later

It's a hard requirement for anywhere you need to generate certs on demand (where you don't know the cert subject until you read the SNI). That means localhost HTTPS setups for dev servers etc, mitm proxies (full disclosure - I make one of these), self-hosting homelabs, etc. If you don't know the hostnames involved before the connection arrives, you can't use the current API. Not a day 1 use case, but it'd be good to support this eventually.

Not strictly required but very useful for plenty of other cases, like wildcard certs (SNI is x.example.com, match that to a wildcard cert for *.example.com) or platforms with very large numbers of hosts available, or dynamic ACME setups where you need to read the cert from some store on demand.

Happy to avoid it for now if that helps, there's no long-term downside to this if it helps for now, but we will need a callback as well eventually.

@avivkeller avivkeller added the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 9, 2026
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels Apr 9, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Commit Queue failed
- Loading data for nodejs/node/pull/62620
✔  Done loading data for nodejs/node/pull/62620
----------------------------------- PR info ------------------------------------
Title      quic: implement multiple c++ side improvements (#62620)
Author     James M Snell <jasnell@gmail.com> (@jasnell)
Branch     jasnell:jasnell/quic-tlscontext-improvements -> nodejs:main
Labels     lib / src, author ready, needs-ci
Commits    5
 - quic: implement rapidhash for hashing improvements
 - quic: apply multiple TLS context improvements and SNI support
 - quic: support multiple ALPN negotiation
 - quic: fixup token verification to handle zero expiration
 - quic: fixup cpp linting after updates
Committers 1
 - James M Snell <jasnell@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Mon, 06 Apr 2026 21:20:29 GMT
   ✔  Approvals: 1
   ✔  - Robert Nagy (@ronag) (TSC): https://github.com/nodejs/node/pull/62620#pullrequestreview-4070035275
   ✘  This PR needs to wait 117 more hours to land (or 0 minutes if there is one more approval)
   ✔  Last GitHub CI successful
   ℹ  Last Full PR CI on 2026-04-06T23:54:10Z: https://ci.nodejs.org/job/node-test-pull-request/72526/
- Querying data for job/node-test-pull-request/72526/
✔  Build data downloaded
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/24166549552

Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to go with the SNI approach, fair enough.

If we can, I'd still rather just support string[] for both ends of ALPN but if you feel strongly or it's a massive pain let's just leave it for now.

@jasnell
Copy link
Copy Markdown
Member Author

jasnell commented Apr 9, 2026

There's still a long way to go and lots of api decisions still need to be worked through...

jasnell added a commit that referenced this pull request Apr 9, 2026
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: #62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
jasnell added a commit that referenced this pull request Apr 9, 2026
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: #62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
jasnell added a commit that referenced this pull request Apr 9, 2026
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: #62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
jasnell added a commit that referenced this pull request Apr 9, 2026
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: #62620
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
@jasnell
Copy link
Copy Markdown
Member Author

jasnell commented Apr 9, 2026

Landed in e6ef477...79671cf

@jasnell jasnell closed this Apr 9, 2026
@jasnell
Copy link
Copy Markdown
Member Author

jasnell commented Apr 9, 2026

Landed in e6ef477...79671cf

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

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-failed An error occurred while landing this pull request using GitHub Actions. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants