From 240e491356dcec18f18761e26175fd431de2eb59 Mon Sep 17 00:00:00 2001
From: Anthony Rossi <41394064+anrossi@users.noreply.github.com>
Date: Mon, 4 Nov 2024 18:08:25 -0800
Subject: [PATCH 1/2] Improve version deployment documentation
---
docs/Deployment.md | 5 +++++
docs/Settings.md | 12 +++++++-----
docs/Versions.md | 29 +++++++++++++++++++++++++----
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/docs/Deployment.md b/docs/Deployment.md
index 4d8caed2fb..c8142daa57 100644
--- a/docs/Deployment.md
+++ b/docs/Deployment.md
@@ -137,6 +137,11 @@ MsQuic uses worker threads internally to execute the QUIC protocol logic. For ea
The queue delay threshold can be configured via the `MaxWorkerQueueDelayMs` setting.
+## Version Negotiation
+
+MsQuic supports QUIC protocol versions 1 and 2, and the version negotiation extension. By default, version negotiation is off, but can be enabled at runtime.
+Instructions for configuring and deploying QUIC versions are at [Versions](Versions.md).
+
# Diagnostics
For details on how to diagnose any issues with your deployment at the MsQuic layer see [Diagnostics](Diagnostics.md).
diff --git a/docs/Settings.md b/docs/Settings.md
index f6fc75038a..4d421575ce 100644
--- a/docs/Settings.md
+++ b/docs/Settings.md
@@ -74,11 +74,12 @@ While `REG_DWORD` can hold values larger than `uint16_t`, the administrator shou
The following settings are available via registry as well as via [QUIC_VERSION_SETTINGS](./Versions.md):
-| Setting | Type | Registry Name | Default | Description |
-|-----------------------------------|------------|--------------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------|
-| Acceptable Versions List | uint32_t[] | AcceptableVersions | Unset | Sets the list of versions that a given server instance will use if a client sends a first flight using them. |
-| Offered Versions List | uint32_t[] | OfferedVersions | Unset | Sets the list of versions that a given server instance will send in a Version Negotiation packet if it receives a first flight from an unknown version. This list will most often be equal to the Acceptable Versions list. |
-| Fully-Deployed Versions List | uint32_t[] | FullyDeployedVersions | Unset | Sets the list of QUIC versions that is supported and negotiated by every single QUIC server instance in this deployment. Used to generate the AvailableVersions list in the Version Negotiation Extension Transport Parameter. |
+| Setting | Type | Registry Name | Default | Description |
+|-----------------------------------|------------|------------------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------|
+| Acceptable Versions List | uint32_t[] | AcceptableVersions | Unset | Sets the list of versions that a given server instance will use if a client sends a first flight using them. |
+| Offered Versions List | uint32_t[] | OfferedVersions | Unset | Sets the list of versions that a given server instance will send in a Version Negotiation packet if it receives a first flight from an unknown version. This list will most often be equal to the Acceptable Versions list. |
+| Fully-Deployed Versions List | uint32_t[] | FullyDeployedVersions | Unset | Sets the list of QUIC versions that is supported and negotiated by every single QUIC server instance in this deployment. Used to generate the AvailableVersions list in the Version Negotiation Extension Transport Parameter. |
+| Version Negotiation Ext. Enabled | uint32_t | VersionNegotiationExtEnabled | 0 (FALSE) | Enables the Version Negotiation Extension |
The `uint32_t[]` type is a `REG_BINARY` blob of the versions list, with each version in little-endian format.
@@ -132,6 +133,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
| `QUIC_PARAM_CONFIGURATION_TICKET_KEYS`
1 | QUIC_TICKET_KEY_CONFIG[] | Set-only | Resumption ticket encryption keys. Server-side only. |
| `QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS`
2 | QUIC_VERSIONS_SETTINGS | Both | Change version settings for all connections on the configuration. |
| `QUIC_PARAM_CONFIGURATION_SCHANNEL_CREDENTIAL_ATTRIBUTE_W`
3 | QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W | Set-only | Calls `SetCredentialsAttributesW` with the supplied attribute and buffer on the credential handle. Schannel-only. Only valid once the credential has been loaded. |
+| `QUIC_PARAM_CONFIGURATION_VERSION_NEG_ENABLED`
(preview) | BOOLEAN | Both | Enables the version negotiation extension for all client connections on the configuration. |
## Listener Parameters
diff --git a/docs/Versions.md b/docs/Versions.md
index b7f694f2a0..241df7e648 100644
--- a/docs/Versions.md
+++ b/docs/Versions.md
@@ -57,7 +57,7 @@ Configuring the QUIC versions on a MsQuic server is similar to configuring them
If a server is not in a fleet, or the operator/application does not ever need to change QUIC versions, then all three lists in `QUIC_VERSION_SETTINGS` **MUST** be the same.
-If a server is deployed in a fleet, and the server operator wishes to change the supported QUIC versions, the Version Negotiation specification details how that should be done, quoted here:
+If a server is deployed in a fleet, and the server operator wishes to change the supported QUIC versions, the [Version Negotiation specification](https://www.rfc-editor.org/rfc/rfc9368.html#section-5) details how that should be done, quoted here:
> When adding support for a new version:
> * The first step is to progressively add support for the new version to all server instances. This step updates the Acceptable Versions but not the Offered Versions nor the Fully-Deployed Versions. Once all server instances have been updated, operators wait for at least one MSL to allow any in-flight Version Negotiation packets to arrive.
> * Then, the second step is to progressively add the new version to Offered Versions on all server instances. Once complete, operators wait for at least another MSL.
@@ -70,7 +70,7 @@ If a server is deployed in a fleet, and the server operator wishes to change the
**Note that this opens connections to version downgrades (but only for partially-deployed versions) during the update window, since those could be due to clients communicating with both updated and non-updated server instances.**
-
+### Configuring Versions via code
This snippet should execute before the server's `QUIC_CONFIGURATION` is created:
```c
QUIC_VERSION_SETTINGS Settings = { 0 };
@@ -92,9 +92,30 @@ MsQuic->SetParam(
&Settings);
```
+### Configuring Versions via Windows Registry
+MsQuic supports setting the Acceptable Versions, Offered Versions, and Fully-Deployed Versions lists via the Windows registry. These settings are global for all servers and clients on the machine.
+The registry settings are overridden by settings specified in the code.
+The registry values must be created under the HKLM\System\CurrentControlSet\Services\MsQuic\Parameters key.
+Each list is stored in the registry as a `REG_BINARY` type, with the version numbers in little-endian (host) order.
+The registry value for Acceptable Versions must be named "AcceptableVersions".
+The registry value for Offered Versions must be named "OfferedVersions".
+The registry value for Fully-Deployed Versions must be named "FullyDeployedVersions".
+
+Here's a sample .reg file that creates all three lists with QUIC version 2 first and QUIC version 1 after, in little endian order, and enables version negotiation:
+```reg
+Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MsQuic\Parameters]
+"AcceptableVersions"=hex:cf,43,33,6b,01,00,00,00
+"OfferedVersions"=hex:cf,43,33,6b,01,00,00,00
+"FullyDeployedVersions"=hex:cf,43,33,6b,01,00,00,00
+"VersionNegotiationExtEnabled"=dword:00000001
+```
+
# QUIC Version Negotiation Extension
-The Version Negotiation Extension is on by default in our officially-released binaries. Since the standard is not yet complete, incompatible changes may be made preventing different drafts from working with each other. An application using MsQuic should be cautious about enabling the Version Negotiation Extension in production scenarios until the standard is complete.
+The Version Negotiation Extension is off by default in our officially-released binaries, but can be enabled via registry or [Settings](./Settings.md).
+The Version Negotiated Extension has been standardized and is present in MsQuic since version 2.3.
## Enabling Version Negotiation Extension on MsQuic Client
@@ -103,4 +124,4 @@ This setting **MUST** be set before [`ConnectionStart`](api/ConnectionStart.md)
## Enabling Version Negotiation Extension on MsQuic Server
-Enabling the Version Negotiation Extension on server follows the same restrictions as setting the QUIC version on server, i.e. it **MUST** be set globally, using [`SetParam`](api/SetParam.md) before the `QUIC_CONFIGURATION` is opened for the server. It is set automatically when `QUIC_VERSION_SETTINGS` are set.
+Enabling the Version Negotiation Extension on server follows the same restrictions as setting the QUIC version on server, i.e. it **MUST** be set globally, using [`SetParam`](api/SetParam.md) before the `QUIC_CONFIGURATION` is opened for the server. It is set automatically when `QUIC_VERSION_SETTINGS` are set, except via registry.
From 3b4df79a2f8126248c94f1eee87cfb34ed7e3098 Mon Sep 17 00:00:00 2001
From: Anthony Rossi <41394064+anrossi@users.noreply.github.com>
Date: Tue, 5 Nov 2024 18:55:04 -0800
Subject: [PATCH 2/2] Address comments.
---
docs/Settings.md | 5 +++--
docs/Versions.md | 8 ++++----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/docs/Settings.md b/docs/Settings.md
index 4d421575ce..9df659b894 100644
--- a/docs/Settings.md
+++ b/docs/Settings.md
@@ -79,7 +79,7 @@ The following settings are available via registry as well as via [QUIC_VERSION_S
| Acceptable Versions List | uint32_t[] | AcceptableVersions | Unset | Sets the list of versions that a given server instance will use if a client sends a first flight using them. |
| Offered Versions List | uint32_t[] | OfferedVersions | Unset | Sets the list of versions that a given server instance will send in a Version Negotiation packet if it receives a first flight from an unknown version. This list will most often be equal to the Acceptable Versions list. |
| Fully-Deployed Versions List | uint32_t[] | FullyDeployedVersions | Unset | Sets the list of QUIC versions that is supported and negotiated by every single QUIC server instance in this deployment. Used to generate the AvailableVersions list in the Version Negotiation Extension Transport Parameter. |
-| Version Negotiation Ext. Enabled | uint32_t | VersionNegotiationExtEnabled | 0 (FALSE) | Enables the Version Negotiation Extension |
+| Version Negotiation Ext. Enabled | uint32_t | VersionNegotiationExtEnabled | 0 (FALSE) | Enables the Version Negotiation Extension. |
The `uint32_t[]` type is a `REG_BINARY` blob of the versions list, with each version in little-endian format.
@@ -115,6 +115,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
| `QUIC_PARAM_GLOBAL_EXECUTION_CONFIG`
9 | QUIC_EXECUTION_CONFIG | Both | Globally configure the execution model used for QUIC. Must be set before opening registration. |
| `QUIC_PARAM_GLOBAL_TLS_PROVIDER`
10 | QUIC_TLS_PROVIDER | Get-Only | The TLS provider being used by MsQuic for the TLS handshake. |
| `QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY`
11 | uint8_t[] | Set-Only | Globally change the stateless reset key for all subsequent connections. |
+| `QUIC_PARAM_GLOBAL_VERSION_NEGOTIATION_ENABLED`
(preview) | uint8_t (BOOLEAN) | Both | Globally enable the version negotiation extension for all client and server connections. |
## Registration Parameters
@@ -133,7 +134,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
| `QUIC_PARAM_CONFIGURATION_TICKET_KEYS`
1 | QUIC_TICKET_KEY_CONFIG[] | Set-only | Resumption ticket encryption keys. Server-side only. |
| `QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS`
2 | QUIC_VERSIONS_SETTINGS | Both | Change version settings for all connections on the configuration. |
| `QUIC_PARAM_CONFIGURATION_SCHANNEL_CREDENTIAL_ATTRIBUTE_W`
3 | QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W | Set-only | Calls `SetCredentialsAttributesW` with the supplied attribute and buffer on the credential handle. Schannel-only. Only valid once the credential has been loaded. |
-| `QUIC_PARAM_CONFIGURATION_VERSION_NEG_ENABLED`
(preview) | BOOLEAN | Both | Enables the version negotiation extension for all client connections on the configuration. |
+| `QUIC_PARAM_CONFIGURATION_VERSION_NEG_ENABLED`
(preview) | uint8_t (BOOLEAN) | Both | Enables the version negotiation extension for all client connections on the configuration. |
## Listener Parameters
diff --git a/docs/Versions.md b/docs/Versions.md
index 241df7e648..eb67cea9e3 100644
--- a/docs/Versions.md
+++ b/docs/Versions.md
@@ -95,11 +95,11 @@ MsQuic->SetParam(
### Configuring Versions via Windows Registry
MsQuic supports setting the Acceptable Versions, Offered Versions, and Fully-Deployed Versions lists via the Windows registry. These settings are global for all servers and clients on the machine.
The registry settings are overridden by settings specified in the code.
-The registry values must be created under the HKLM\System\CurrentControlSet\Services\MsQuic\Parameters key.
+The registry values must be created under the `HKLM\System\CurrentControlSet\Services\MsQuic\Parameters` key.
Each list is stored in the registry as a `REG_BINARY` type, with the version numbers in little-endian (host) order.
-The registry value for Acceptable Versions must be named "AcceptableVersions".
-The registry value for Offered Versions must be named "OfferedVersions".
-The registry value for Fully-Deployed Versions must be named "FullyDeployedVersions".
+The registry value for Acceptable Versions must be named `AcceptableVersions`.
+The registry value for Offered Versions must be named `OfferedVersions`.
+The registry value for Fully-Deployed Versions must be named `FullyDeployedVersions`.
Here's a sample .reg file that creates all three lists with QUIC version 2 first and QUIC version 1 after, in little endian order, and enables version negotiation:
```reg