Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 106 additions & 15 deletions doc/api/quic.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,34 @@ added: v23.8.0

True if `endpoint.destroy()` has been called. Read only.

### `endpoint.setSNIContexts(entries[, options])`

<!-- YAML
added: REPLACEME
-->

* `entries` {object} An object mapping host names to TLS identity options.
Each entry must include `keys` and `certs`.
* `options` {object}
* `replace` {boolean} If `true`, replaces the entire SNI map. If `false`
(the default), merges the entries into the existing map.

Replaces or updates the SNI TLS contexts for this endpoint. This allows
changing the TLS identity (key/certificate) used for specific host names
without restarting the endpoint. Existing sessions are unaffected — only
new sessions will use the updated contexts.

```mjs
endpoint.setSNIContexts({
'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
});

// Replace the entire SNI map
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.


### `endpoint.stats`

<!-- YAML
Expand Down Expand Up @@ -1113,22 +1141,37 @@ added: v23.8.0
#### `sessionOptions.alpn`

<!-- YAML
added: v23.8.0
added: REPLACEME
-->

* Type: {string}
* Type: {string} (client) | {string\[]} (server)

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.


For **server** sessions, this is an array of protocol names in preference
order that the server supports (e.g. `['h3', 'h3-29']`). During the TLS
handshake, the server selects the first protocol from its list that the
client also supports.

The ALPN protocol identifier.
The negotiated ALPN determines which Application implementation is used
for the session. `'h3'` and `'h3-*'` variants select the HTTP/3
application; all other values select the default application.

#### `sessionOptions.ca`
Default: `'h3'`

#### `sessionOptions.ca` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The CA certificates to use for sessions.
The CA certificates to use for client sessions. For server sessions, CA
certificates are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.cc`

Expand All @@ -1143,15 +1186,16 @@ Specifies the congestion control algorithm that will be used

This is an advanced option that users typically won't have need to specify.

#### `sessionOptions.certs`
#### `sessionOptions.certs` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The TLS certificates to use for sessions.
The TLS certificates to use for client sessions. For server sessions,
certificates are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.ciphers`

Expand All @@ -1163,15 +1207,16 @@ added: v23.8.0

The list of supported TLS 1.3 cipher algorithms.

#### `sessionOptions.crl`
#### `sessionOptions.crl` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The CRL to use for sessions.
The CRL to use for client sessions. For server sessions, CRLs are specified
per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.groups`

Expand All @@ -1193,7 +1238,7 @@ added: v23.8.0

True to enable TLS keylogging output.

#### `sessionOptions.keys`
#### `sessionOptions.keys` (client only)

<!-- YAML
added: v23.8.0
Expand All @@ -1205,7 +1250,8 @@ changes:

* Type: {KeyObject|KeyObject\[]}

The TLS crypto keys to use for sessions.
The TLS crypto keys to use for client sessions. For server sessions,
keys are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.maxPayloadSize`

Expand Down Expand Up @@ -1288,15 +1334,56 @@ added: v23.8.0
Specifies the maximum number of milliseconds a TLS handshake is permitted to take
to complete before timing out.

#### `sessionOptions.sni`
#### `sessionOptions.servername` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {string}

The peer server name to target.
The peer server name to target (SNI). Defaults to `'localhost'`.

#### `sessionOptions.sni` (server only)

<!-- YAML
added: REPLACEME
-->

* Type: {Object}

An object mapping host names to TLS identity options for Server Name
Indication (SNI) support. This is required for server sessions. The
special key `'*'` specifies the default/fallback identity used when
no other host name matches. Each entry may contain:

* `keys` {KeyObject|KeyObject\[]} The TLS private keys. **Required.**
* `certs` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
The TLS certificates. **Required.**
* `ca` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
Optional CA certificate overrides.
* `crl` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
Optional certificate revocation lists.
* `verifyPrivateKey` {boolean} Verify the private key. Default: `false`.

```mjs
const endpoint = await listen(callback, {
sni: {
'*': { keys: [defaultKey], certs: [defaultCert] },
'api.example.com': { keys: [apiKey], certs: [apiCert] },
'www.example.com': { keys: [wwwKey], certs: [wwwCert], ca: [customCA] },
},
});
```

Shared TLS options (such as `ciphers`, `groups`, `keylog`, and `verifyClient`)
are specified at the top level of the session options and apply to all
identities. Each SNI entry overrides only the per-identity certificate
fields.

The SNI map can be replaced at runtime using `endpoint.setSNIContexts()`,
which atomically swaps the map for new sessions while existing sessions
continue to use their original identity.

#### `sessionOptions.tlsTrace`

Expand Down Expand Up @@ -1338,15 +1425,17 @@ added: v23.8.0

True to require verification of TLS client certificate.

#### `sessionOptions.verifyPrivateKey`
#### `sessionOptions.verifyPrivateKey` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {boolean}

True to require private key verification.
True to require private key verification for client sessions. For server
sessions, this option is specified per-identity in the
[`sessionOptions.sni`][] map.

#### `sessionOptions.version`

Expand Down Expand Up @@ -1715,3 +1804,5 @@ added: v23.8.0
<!-- YAML
added: v23.8.0
-->

[`sessionOptions.sni`]: #sessionoptionssni-server-only
Loading
Loading