Skip to content

Commit

Permalink
Setting for Binding Stateless Operations (microsoft#1723)
Browse files Browse the repository at this point in the history
  • Loading branch information
nibanks authored Jun 16, 2021
1 parent 6f2e772 commit 65b6c92
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 120 deletions.
8 changes: 7 additions & 1 deletion docs/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The following settings are available via registry as well as via [QUIC_SETTINGS]
| Stream Receive Window | uint32_t | StreamRecvWindowDefault | 32,768 | Initial stream receive window size. |
| Stream Receive Buffer | uint32_t | StreamRecvBufferDefault | 4,096 | Stream initial buffer size. |
| Flow Control Window | uint32_t | ConnFlowControlWindow | 16,777,216 | Connection-wide flow control window. |
| Max Stateless Operations | uint32_t | MaxStatelessOperations | 16 | The maximum number of stateless operations that may be queued at any one time. |
| Max Stateless Operations | uint32_t | MaxStatelessOperations | 16 | The maximum number of stateless operations that may be queued on a worker at any one time. |
| Initial Window | uint32_t | InitialWindowPackets | 10 | The size (in packets) of the initial congestion window for a connection. |
| Send Idle Timeout | uint32_t | SendIdleTimeoutMs | 1,000 | Reset congestion control after being idle `SendIdleTimeoutMs` milliseconds. |
| Initial RTT | uint32_t | InitialRttMs | 333 | Initial RTT estimate. |
Expand All @@ -51,6 +51,12 @@ The following settings are available via registry as well as via [QUIC_SETTINGS]
| Datagram Receive Support | uint8_t | DatagramReceiveEnabled | 0 (FALSE) | Advertise support for QUIC datagram extension. |
| Server Resumption Level | uint8_t | ServerResumptionLevel | 0 (No resumption) | Server only. Controls resumption tickets and/or 0-RTT server support. |
| Version Negotiation Extension | uint8_t | VersionNegotiationExtEnabled| 0 (FALSE) | Controls QUIC Version Negotiation Extension support. |
| Minimum MTU | uint16_t | MinimumMtu | TODO | TODO |
| Maximum MTU | uint16_t | MaximumMtu | TODO | TODO |
| MTU Discovery Search Timeout | uint64_t | MtuDiscoverySearchCompleteTimeoutUs | TODO | TODO |
| MTU Discovery Missing Probe Count | uint8_t | MtuDiscoveryMissingProbeCount | TODO | TODO |
| Max Binding Stateless Operations | uint16_t | MaxBindingStatelessOperations | 100 | The maximum number of stateless operations that may be queued on a binding at any one time. |
| Stateless Operation Expiration | uint16_t | StatelessOperationExpirationMs | 100 | The time limit between operations for the same endpoint, in milliseconds. |

The types map to registry types as follows:
- `uint64_t` is a `REG_QWORD`.
Expand Down
114 changes: 81 additions & 33 deletions docs/api/QUIC_SETTINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,41 @@ typedef struct QUIC_SETTINGS {
union {
uint64_t IsSetFlags;
struct {
uint64_t MaxBytesPerKey : 1;
uint64_t HandshakeIdleTimeoutMs : 1;
uint64_t IdleTimeoutMs : 1;
uint64_t TlsClientMaxSendBuffer : 1;
uint64_t TlsServerMaxSendBuffer : 1;
uint64_t StreamRecvWindowDefault : 1;
uint64_t StreamRecvBufferDefault : 1;
uint64_t ConnFlowControlWindow : 1;
uint64_t MaxWorkerQueueDelayUs : 1;
uint64_t MaxStatelessOperations : 1;
uint64_t InitialWindowPackets : 1;
uint64_t SendIdleTimeoutMs : 1;
uint64_t InitialRttMs : 1;
uint64_t MaxAckDelayMs : 1;
uint64_t DisconnectTimeoutMs : 1;
uint64_t KeepAliveIntervalMs : 1;
uint64_t PeerBidiStreamCount : 1;
uint64_t PeerUnidiStreamCount : 1;
uint64_t RetryMemoryLimit : 1;
uint64_t LoadBalancingMode : 1;
uint64_t MaxOperationsPerDrain : 1;
uint64_t SendBufferingEnabled : 1;
uint64_t PacingEnabled : 1;
uint64_t MigrationEnabled : 1;
uint64_t DatagramReceiveEnabled : 1;
uint64_t ServerResumptionLevel : 1;
uint64_t DesiredVersionsList : 1;
uint64_t VersionNegotiationExtEnabled : 1;
uint64_t RESERVED : 36;
uint64_t MaxBytesPerKey : 1;
uint64_t HandshakeIdleTimeoutMs : 1;
uint64_t IdleTimeoutMs : 1;
uint64_t TlsClientMaxSendBuffer : 1;
uint64_t TlsServerMaxSendBuffer : 1;
uint64_t StreamRecvWindowDefault : 1;
uint64_t StreamRecvBufferDefault : 1;
uint64_t ConnFlowControlWindow : 1;
uint64_t MaxWorkerQueueDelayUs : 1;
uint64_t MaxStatelessOperations : 1;
uint64_t InitialWindowPackets : 1;
uint64_t SendIdleTimeoutMs : 1;
uint64_t InitialRttMs : 1;
uint64_t MaxAckDelayMs : 1;
uint64_t DisconnectTimeoutMs : 1;
uint64_t KeepAliveIntervalMs : 1;
uint64_t PeerBidiStreamCount : 1;
uint64_t PeerUnidiStreamCount : 1;
uint64_t RetryMemoryLimit : 1;
uint64_t LoadBalancingMode : 1;
uint64_t MaxOperationsPerDrain : 1;
uint64_t SendBufferingEnabled : 1;
uint64_t PacingEnabled : 1;
uint64_t MigrationEnabled : 1;
uint64_t DatagramReceiveEnabled : 1;
uint64_t ServerResumptionLevel : 1;
uint64_t DesiredVersionsList : 1;
uint64_t VersionNegotiationExtEnabled : 1;
uint64_t MinimumMtu : 1;
uint64_t MaximumMtu : 1;
uint64_t MtuDiscoverySearchCompleteTimeoutUs : 1;
uint64_t MtuDiscoveryMissingProbeCount : 1;
uint64_t MaxBindingStatelessOperations : 1;
uint64_t StatelessOperationExpirationMs : 1;
uint64_t RESERVED : 30;
} IsSet;
};

Expand All @@ -61,18 +67,24 @@ typedef struct QUIC_SETTINGS {
uint32_t KeepAliveIntervalMs;
uint16_t PeerBidiStreamCount;
uint16_t PeerUnidiStreamCount;
uint16_t RetryMemoryLimit;
uint16_t LoadBalancingMode;
uint16_t RetryMemoryLimit; // Global only
uint16_t LoadBalancingMode; // Global only
uint8_t MaxOperationsPerDrain;
uint8_t SendBufferingEnabled : 1;
uint8_t PacingEnabled : 1;
uint8_t MigrationEnabled : 1;
uint8_t DatagramReceiveEnabled : 1;
uint8_t ServerResumptionLevel : 2;
uint8_t ServerResumptionLevel : 2; // QUIC_SERVER_RESUMPTION_LEVEL
uint8_t VersionNegotiationExtEnabled : 1;
uint8_t RESERVED : 1;
const uint32_t* DesiredVersionsList;
uint32_t DesiredVersionsListLength;
uint16_t MinimumMtu;
uint16_t MaximumMtu;
uint64_t MtuDiscoverySearchCompleteTimeoutUs;
uint8_t MtuDiscoveryMissingProbeCount;
uint16_t MaxBindingStatelessOperations;
uint16_t StatelessOperationExpirationMs;

} QUIC_SETTINGS;
```
Expand Down Expand Up @@ -139,7 +151,7 @@ The maximum queue delay (in microseconds) allowed for a worker thread. This affe

`MaxStatelessOperations`

The maximum number of stateless operations that may be queued at any one time.
The maximum number of stateless operations that may be queued on a worker at any one time.

**Default value:** 16

Expand Down Expand Up @@ -257,6 +269,42 @@ Number of QUIC protocol versions in the DesiredVersionsList. Must be set to 0 un

**Default value:** 0

`MinimumMtu`

TODO

**Default value:** TODO

`MaximumMtu`

TODO

**Default value:** TODO

`MtuDiscoverySearchCompleteTimeoutUs`

TODO

**Default value:** TODO

`MtuDiscoveryMissingProbeCount`

TODO

**Default value:** TODO

`MaxBindingStatelessOperations`

The maximum number of stateless operations that may be queued on a binding at any one time.

**Default value:** 100

`StatelessOperationExpirationMs`

The time limit between operations for the same endpoint, in milliseconds.

**Default value:** 100

# Remarks

When setting new values for the settings, the app must set the corresponding `.IsSet.*` parameter for each actual parameter that is being set or updated. For example:
Expand Down
4 changes: 2 additions & 2 deletions src/core/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ QuicBindingCreateStatelessOperation(
ListEntry);

if (CxPlatTimeDiff32(OldStatelessCtx->CreationTimeMs, TimeMs) <
QUIC_STATELESS_OPERATION_EXPIRATION_MS) {
(uint32_t)MsQuicLib.Settings.StatelessOperationExpirationMs) {
break;
}

Expand All @@ -672,7 +672,7 @@ QuicBindingCreateStatelessOperation(
}
}

if (Binding->StatelessOperCount >= QUIC_MAX_BINDING_STATELESS_OPERATIONS) {
if (Binding->StatelessOperCount >= (uint32_t)MsQuicLib.Settings.MaxBindingStatelessOperations) {
QuicPacketLogDrop(Binding, CxPlatDataPathRecvDataToRecvPacket(Datagram),
"Max binding operations reached");
goto Exit;
Expand Down
2 changes: 2 additions & 0 deletions src/core/quicdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ CXPLAT_STATIC_ASSERT(
#define QUIC_SETTING_LOAD_BALANCING_MODE "LoadBalancingMode"
#define QUIC_SETTING_MAX_WORKER_QUEUE_DELAY "MaxWorkerQueueDelayMs"
#define QUIC_SETTING_MAX_STATELESS_OPERATIONS "MaxStatelessOperations"
#define QUIC_SETTING_MAX_BINDING_STATELESS_OPERATIONS "MaxBindingStatelessOperations"
#define QUIC_SETTING_STATELESS_OPERATION_EXPIRATION "StatelessOperationExpirationMs"
#define QUIC_SETTING_MAX_OPERATIONS_PER_DRAIN "MaxOperationsPerDrain"

#define QUIC_SETTING_SEND_BUFFERING_DEFAULT "SendBufferingDefault"
Expand Down
81 changes: 71 additions & 10 deletions src/core/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ QuicSettingsSetDefault(
if (!Settings->IsSet.MtuDiscoverySearchCompleteTimeoutUs) {
Settings->MtuDiscoverySearchCompleteTimeoutUs = QUIC_DPLPMTUD_RAISE_TIMER_TIMEOUT;
}
if (!Settings->IsSet.MaxBindingStatelessOperations) {
Settings->MaxBindingStatelessOperations = QUIC_MAX_BINDING_STATELESS_OPERATIONS;
}
if (!Settings->IsSet.StatelessOperationExpirationMs) {
Settings->StatelessOperationExpirationMs = QUIC_STATELESS_OPERATION_EXPIRATION_MS;
}
}

_IRQL_requires_max_(PASSIVE_LEVEL)
Expand Down Expand Up @@ -215,6 +221,12 @@ QuicSettingsCopy(
if (!Destination->IsSet.MtuDiscoverySearchCompleteTimeoutUs) {
Destination->MtuDiscoverySearchCompleteTimeoutUs = Source->MtuDiscoverySearchCompleteTimeoutUs;
}
if (!Destination->IsSet.MaxBindingStatelessOperations) {
Destination->MaxBindingStatelessOperations = Source->MaxBindingStatelessOperations;
}
if (!Destination->IsSet.StatelessOperationExpirationMs) {
Destination->StatelessOperationExpirationMs = Source->StatelessOperationExpirationMs;
}
}

#define SETTING_HAS_FIELD(Size, Field) \
Expand Down Expand Up @@ -466,6 +478,18 @@ QuicSettingApply(
Destination->IsSet.MtuDiscoveryMissingProbeCount = TRUE;
}
}

if (SETTING_HAS_FIELD(NewSettingsSize, StatelessOperationExpirationMs)) {
if (Source->IsSet.MaxBindingStatelessOperations && (!Destination->IsSet.MaxBindingStatelessOperations || OverWrite)) {
Destination->MaxBindingStatelessOperations = Source->MaxBindingStatelessOperations;
Destination->IsSet.MaxBindingStatelessOperations = TRUE;
}
if (Source->IsSet.StatelessOperationExpirationMs && (!Destination->IsSet.StatelessOperationExpirationMs || OverWrite)) {
Destination->StatelessOperationExpirationMs = Source->StatelessOperationExpirationMs;
Destination->IsSet.StatelessOperationExpirationMs = TRUE;
}
}

return TRUE;
}

Expand Down Expand Up @@ -835,6 +859,30 @@ QuicSettingsLoad(
(uint8_t*)&Settings->MtuDiscoverySearchCompleteTimeoutUs,
&ValueLen);
}
if (!Settings->IsSet.MaxBindingStatelessOperations) {
Value = QUIC_MAX_BINDING_STATELESS_OPERATIONS;
ValueLen = sizeof(Value);
CxPlatStorageReadValue(
Storage,
QUIC_SETTING_MAX_BINDING_STATELESS_OPERATIONS,
(uint8_t*)&Value,
&ValueLen);
if (Value < UINT16_MAX) {
Settings->MaxBindingStatelessOperations = (uint16_t)Value;
}
}
if (!Settings->IsSet.StatelessOperationExpirationMs) {
Value = QUIC_STATELESS_OPERATION_EXPIRATION_MS;
ValueLen = sizeof(Value);
CxPlatStorageReadValue(
Storage,
QUIC_SETTING_STATELESS_OPERATION_EXPIRATION,
(uint8_t*)&Value,
&ValueLen);
if (Value < UINT16_MAX) {
Settings->StatelessOperationExpirationMs = (uint16_t)Value;
}
}
}

_IRQL_requires_max_(PASSIVE_LEVEL)
Expand Down Expand Up @@ -869,10 +917,17 @@ QuicSettingsDump(
QuicTraceLogVerbose(SettingDumpConnFlowControlWindow, "[sett] ConnFlowControlWindow = %u", Settings->ConnFlowControlWindow);
QuicTraceLogVerbose(SettingDumpMaxBytesPerKey, "[sett] MaxBytesPerKey = %llu", Settings->MaxBytesPerKey);
QuicTraceLogVerbose(SettingDumpServerResumptionLevel, "[sett] ServerResumptionLevel = %hhu", Settings->ServerResumptionLevel);
QuicTraceLogVerbose(SettingMinimumMtu, "[sett] Minimum Mtu = %hu", Settings->MinimumMtu);
QuicTraceLogVerbose(SettingMaximumMtu, "[sett] Maximum Mtu = %hu", Settings->MaximumMtu);
QuicTraceLogVerbose(SettingMtuCompleteTimeout, "[sett] Mtu complete timeout = %llu", Settings->MtuDiscoverySearchCompleteTimeoutUs);
QuicTraceLogVerbose(SettingMtuMissingProbeCount, "[sett] Mtu probe count = %hhu", Settings->MtuDiscoveryMissingProbeCount);
QuicTraceLogVerbose(SettingDumpDesiredVersionsListLength,"[sett] Desired Version length = %u", Settings->DesiredVersionsListLength);
if (Settings->DesiredVersionsListLength > 0) {
QuicTraceLogVerbose(SettingDumpDesiredVersionsList, "[sett] Desired Version[0] = 0x%x", Settings->DesiredVersionsList[0]);
}
QuicTraceLogVerbose(SettingDumpVersionNegoExtEnabled, "[sett] Version Negotiation Ext Enabled = %hhu", Settings->VersionNegotiationExtEnabled);
QuicTraceLogVerbose(SettingDumpMinimumMtu, "[sett] MinimumMtu = %hu", Settings->MinimumMtu);
QuicTraceLogVerbose(SettingDumpMaximumMtu, "[sett] MaximumMtu = %hu", Settings->MaximumMtu);
QuicTraceLogVerbose(SettingDumpMtuCompleteTimeout, "[sett] MtuCompleteTimeout = %llu", Settings->MtuDiscoverySearchCompleteTimeoutUs);
QuicTraceLogVerbose(SettingDumpMtuMissingProbeCount, "[sett] MtuMissingProbeCount = %hhu", Settings->MtuDiscoveryMissingProbeCount);
QuicTraceLogVerbose(SettingDumpMaxBindingStatelessOper, "[sett] MaxBindingStatelessOper= %hu", Settings->MaxBindingStatelessOperations);
QuicTraceLogVerbose(SettingDumpStatelessOperExpirMs, "[sett] StatelessOperExpirMs = %hu", Settings->StatelessOperationExpirationMs);
}

_IRQL_requires_max_(PASSIVE_LEVEL)
Expand All @@ -884,8 +939,6 @@ QuicSettingsDumpNew(
const QUIC_SETTINGS* Settings
)
{
UNREFERENCED_PARAMETER(SettingsSize); // TODO - Use when reading settings

if (Settings->IsSet.SendBufferingEnabled) {
QuicTraceLogVerbose(SettingDumpSendBufferingEnabled, "[sett] SendBufferingEnabled = %hhu", Settings->SendBufferingEnabled);
}
Expand Down Expand Up @@ -982,16 +1035,24 @@ QuicSettingsDumpNew(
}
if (SETTING_HAS_FIELD(SettingsSize, MtuDiscoveryMissingProbeCount)) {
if (Settings->IsSet.MinimumMtu) {
QuicTraceLogVerbose(SettingDumpMinimumMtu, "[sett] Minimum Mtu = %hu", Settings->MinimumMtu);
QuicTraceLogVerbose(SettingDumpMinimumMtu, "[sett] MinimumMtu = %hu", Settings->MinimumMtu);
}
if (Settings->IsSet.MaximumMtu) {
QuicTraceLogVerbose(SettingDumpMaximumMtu, "[sett] Maximum Mtu = %hu", Settings->MaximumMtu);
QuicTraceLogVerbose(SettingDumpMaximumMtu, "[sett] MaximumMtu = %hu", Settings->MaximumMtu);
}
if (Settings->IsSet.MtuDiscoverySearchCompleteTimeoutUs) {
QuicTraceLogVerbose(SettingDumpMtuCompleteTimeout, "[sett] Mtu complete timeout = %llu", Settings->MtuDiscoverySearchCompleteTimeoutUs);
QuicTraceLogVerbose(SettingDumpMtuCompleteTimeout, "[sett] MtuCompleteTimeout = %llu", Settings->MtuDiscoverySearchCompleteTimeoutUs);
}
if (Settings->IsSet.MtuDiscoveryMissingProbeCount) {
QuicTraceLogVerbose(SettingDumpMtuMissingProbeCount, "[sett] Mtu probe count = %hhu", Settings->MtuDiscoveryMissingProbeCount);
QuicTraceLogVerbose(SettingDumpMtuMissingProbeCount, "[sett] MtuMissingProbeCount = %hhu", Settings->MtuDiscoveryMissingProbeCount);
}
}
if (SETTING_HAS_FIELD(SettingsSize, StatelessOperationExpirationMs)) {
if (Settings->IsSet.MaxBindingStatelessOperations) {
QuicTraceLogVerbose(SettingDumpMaxBindingStatelessOper, "[sett] MaxBindingStatelessOper= %hu", Settings->MaxBindingStatelessOperations);
}
if (Settings->IsSet.StatelessOperationExpirationMs) {
QuicTraceLogVerbose(SettingDumpStatelessOperExpirMs, "[sett] StatelessOperExpirMs = %hu", Settings->StatelessOperationExpirationMs);
}
}
}
7 changes: 5 additions & 2 deletions src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,9 @@ typedef struct QUIC_SETTINGS {
uint64_t MaximumMtu : 1;
uint64_t MtuDiscoverySearchCompleteTimeoutUs : 1;
uint64_t MtuDiscoveryMissingProbeCount : 1;
uint64_t RESERVED : 32;
uint64_t MaxBindingStatelessOperations : 1;
uint64_t StatelessOperationExpirationMs : 1;
uint64_t RESERVED : 30;
} IsSet;
};

Expand Down Expand Up @@ -537,7 +539,8 @@ typedef struct QUIC_SETTINGS {
uint16_t MaximumMtu;
uint64_t MtuDiscoverySearchCompleteTimeoutUs;
uint8_t MtuDiscoveryMissingProbeCount;

uint16_t MaxBindingStatelessOperations;
uint16_t StatelessOperationExpirationMs;

} QUIC_SETTINGS;

Expand Down
Loading

0 comments on commit 65b6c92

Please sign in to comment.