зеркало из https://github.com/microsoft/msquic.git
Reliable Reset Stream Support - Phase 1 - Feature Negotiation (#3778)
This commit is contained in:
Родитель
d1a82364e8
Коммит
09eff16e01
|
@ -2409,6 +2409,10 @@ QuicConnGenerateLocalTransportParameters(
|
|||
LocalTP->Flags |= QUIC_TP_FLAG_GREASE_QUIC_BIT;
|
||||
}
|
||||
|
||||
if (Connection->Settings.ReliableResetEnabled) {
|
||||
LocalTP->Flags |= QUIC_TP_FLAG_RELIABLE_RESET_ENABLED;
|
||||
}
|
||||
|
||||
if (QuicConnIsServer(Connection)) {
|
||||
|
||||
if (Connection->Streams.Types[STREAM_ID_FLAG_IS_CLIENT | STREAM_ID_FLAG_IS_BI_DIR].MaxTotalStreamCount) {
|
||||
|
@ -3042,6 +3046,32 @@ QuicConnProcessPeerTransportParameters(
|
|||
Connection->Stats.GreaseBitNegotiated = TRUE;
|
||||
}
|
||||
|
||||
if (Connection->Settings.ReliableResetEnabled &&
|
||||
(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_RELIABLE_RESET_ENABLED) > 0) {
|
||||
//
|
||||
// Reliable Reset is enabled on both sides.
|
||||
//
|
||||
|
||||
Connection->State.ReliableResetStreamNegotiated = TRUE;
|
||||
}
|
||||
|
||||
if (Connection->Settings.ReliableResetEnabled) {
|
||||
//
|
||||
// Send event to app to indicate result of negotiation if app cares.
|
||||
//
|
||||
|
||||
QUIC_CONNECTION_EVENT Event;
|
||||
Event.Type = QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED;
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated = Connection->State.ReliableResetStreamNegotiated;
|
||||
|
||||
QuicTraceLogConnVerbose(
|
||||
IndicateReliableResetNegotiated,
|
||||
Connection,
|
||||
"Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]",
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated);
|
||||
QuicConnIndicateEvent(Connection, &Event);
|
||||
}
|
||||
|
||||
//
|
||||
// Fully validate all exchanged connection IDs.
|
||||
//
|
||||
|
@ -5259,6 +5289,8 @@ QuicConnRecvFrames(
|
|||
AckImmediately = TRUE;
|
||||
break;
|
||||
|
||||
case QUIC_FRAME_RELIABLE_RESET_STREAM:
|
||||
// TODO - Implement this frame.
|
||||
default:
|
||||
//
|
||||
// No default case necessary, as we have already validated the frame
|
||||
|
@ -6454,10 +6486,10 @@ QuicConnParamSet(
|
|||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Must be set before the client connection is started.
|
||||
//
|
||||
|
||||
if (QuicConnIsServer(Connection) ||
|
||||
QUIC_CONN_BAD_START_STATE(Connection)) {
|
||||
Status = QUIC_STATUS_INVALID_STATE;
|
||||
|
@ -7267,6 +7299,29 @@ QuicConnApplyNewSettings(
|
|||
Connection->Stats.GreaseBitNegotiated = TRUE;
|
||||
}
|
||||
|
||||
if (QuicConnIsServer(Connection) &&
|
||||
Connection->Settings.ReliableResetEnabled &&
|
||||
(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_RELIABLE_RESET_ENABLED) > 0) {
|
||||
Connection->State.ReliableResetStreamNegotiated = TRUE;
|
||||
}
|
||||
|
||||
if (QuicConnIsServer(Connection) && Connection->Settings.ReliableResetEnabled) {
|
||||
//
|
||||
// Send event to app to indicate result of negotiation if app cares.
|
||||
//
|
||||
|
||||
QUIC_CONNECTION_EVENT Event;
|
||||
Event.Type = QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED;
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated = Connection->State.ReliableResetStreamNegotiated;
|
||||
|
||||
QuicTraceLogConnVerbose(
|
||||
IndicateReliableResetNegotiated,
|
||||
Connection,
|
||||
"Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]",
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated);
|
||||
QuicConnIndicateEvent(Connection, &Event);
|
||||
}
|
||||
|
||||
if (Connection->Settings.EcnEnabled) {
|
||||
QUIC_PATH* Path = &Connection->Paths[0];
|
||||
Path->EcnValidationState = ECN_VALIDATION_TESTING;
|
||||
|
|
|
@ -180,6 +180,11 @@ typedef union QUIC_CONNECTION_STATE {
|
|||
//
|
||||
BOOLEAN FixedBit : 1;
|
||||
|
||||
//
|
||||
// Indicates that the peer accepts RELIABLE_RESET kind of frames, in addition to RESET_STREAM frames.
|
||||
//
|
||||
BOOLEAN ReliableResetStreamNegotiated : 1;
|
||||
|
||||
#ifdef CxPlatVerifierEnabledByAddr
|
||||
//
|
||||
// The calling app is being verified (app or driver verifier).
|
||||
|
|
|
@ -66,6 +66,7 @@ typedef enum eSniNameType {
|
|||
#define QUIC_TP_ID_MIN_ACK_DELAY 0xFF03DE1AULL // varint
|
||||
#define QUIC_TP_ID_CIBIR_ENCODING 0x1000 // {varint, varint}
|
||||
#define QUIC_TP_ID_GREASE_QUIC_BIT 0x2AB2 // N/A
|
||||
#define QUIC_TP_ID_RELIABLE_RESET_ENABLED 0x17f7586d2cb570 // varint
|
||||
|
||||
BOOLEAN
|
||||
QuicTpIdIsReserved(
|
||||
|
@ -850,6 +851,12 @@ QuicCryptoTlsEncodeTransportParameters(
|
|||
QUIC_TP_ID_GREASE_QUIC_BIT,
|
||||
0);
|
||||
}
|
||||
if (TransportParams->Flags & QUIC_TP_FLAG_RELIABLE_RESET_ENABLED) {
|
||||
RequiredTPLen +=
|
||||
TlsTransportParamLength(
|
||||
QUIC_TP_ID_RELIABLE_RESET_ENABLED,
|
||||
0);
|
||||
}
|
||||
if (TestParam != NULL) {
|
||||
RequiredTPLen +=
|
||||
TlsTransportParamLength(
|
||||
|
@ -1164,6 +1171,18 @@ QuicCryptoTlsEncodeTransportParameters(
|
|||
Connection,
|
||||
"TP: Grease Quic Bit");
|
||||
}
|
||||
if (TransportParams->Flags & QUIC_TP_FLAG_RELIABLE_RESET_ENABLED) {
|
||||
TPBuf =
|
||||
TlsWriteTransportParam(
|
||||
QUIC_TP_ID_RELIABLE_RESET_ENABLED,
|
||||
0,
|
||||
NULL,
|
||||
TPBuf);
|
||||
QuicTraceLogConnVerbose(
|
||||
EncodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Encode Reliable Reset");
|
||||
}
|
||||
if (TestParam != NULL) {
|
||||
TPBuf =
|
||||
TlsWriteTransportParam(
|
||||
|
@ -1822,6 +1841,23 @@ QuicCryptoTlsDecodeTransportParameters( // NOLINT(readability-function-size, goo
|
|||
"TP: Grease QUIC Bit");
|
||||
break;
|
||||
|
||||
case QUIC_TP_ID_RELIABLE_RESET_ENABLED:
|
||||
if (Length != 0) {
|
||||
QuicTraceEvent(
|
||||
ConnErrorStatus,
|
||||
"[conn][%p] ERROR, %u, %s.",
|
||||
Connection,
|
||||
Length,
|
||||
"Invalid length of QUIC_TP_ID_RELIABLE_RESET_ENABLED");
|
||||
goto Exit;
|
||||
}
|
||||
TransportParams->Flags |= QUIC_TP_FLAG_RELIABLE_RESET_ENABLED;
|
||||
QuicTraceLogConnVerbose(
|
||||
DecodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Decode Reliable Reset");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (QuicTpIdIsReserved(Id)) {
|
||||
QuicTraceLogConnWarning(
|
||||
|
|
|
@ -408,6 +408,56 @@ QuicResetStreamFrameDecode(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOLEAN
|
||||
QuicReliableResetFrameEncode(
|
||||
_In_ const QUIC_RELIABLE_RESET_STREAM_EX * const Frame,
|
||||
_Inout_ uint16_t* Offset,
|
||||
_In_ uint16_t BufferLength,
|
||||
_Out_writes_to_(BufferLength, *Offset) uint8_t* Buffer
|
||||
)
|
||||
{
|
||||
uint16_t RequiredLength =
|
||||
sizeof(uint8_t) + // Type
|
||||
QuicVarIntSize(Frame->ErrorCode) +
|
||||
QuicVarIntSize(Frame->StreamID) +
|
||||
QuicVarIntSize(Frame->FinalSize) +
|
||||
QuicVarIntSize(Frame->ReliableSize);
|
||||
|
||||
if (BufferLength < *Offset + RequiredLength) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Buffer = Buffer + *Offset;
|
||||
Buffer = QuicUint8Encode(QUIC_FRAME_RELIABLE_RESET_STREAM, Buffer);
|
||||
Buffer = QuicVarIntEncode(Frame->StreamID, Buffer);
|
||||
Buffer = QuicVarIntEncode(Frame->ErrorCode, Buffer);
|
||||
Buffer = QuicVarIntEncode(Frame->FinalSize, Buffer);
|
||||
QuicVarIntEncode(Frame->ReliableSize, Buffer);
|
||||
*Offset += RequiredLength;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOLEAN
|
||||
QuicReliableResetFrameDecode(
|
||||
_In_ uint16_t BufferLength,
|
||||
_In_reads_bytes_(BufferLength)
|
||||
const uint8_t * const Buffer,
|
||||
_Inout_ uint16_t* Offset,
|
||||
_Out_ QUIC_RELIABLE_RESET_STREAM_EX* Frame
|
||||
)
|
||||
{
|
||||
if (!QuicVarIntDecode(BufferLength, Buffer, Offset, &Frame->StreamID) ||
|
||||
!QuicVarIntDecode(BufferLength, Buffer, Offset, &Frame->ErrorCode) ||
|
||||
!QuicVarIntDecode(BufferLength, Buffer, Offset, &Frame->FinalSize) ||
|
||||
!QuicVarIntDecode(BufferLength, Buffer, Offset, &Frame->ReliableSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOLEAN
|
||||
QuicStopSendingFrameEncode(
|
||||
|
|
|
@ -145,7 +145,9 @@ typedef enum QUIC_FRAME_TYPE {
|
|||
QUIC_FRAME_CONNECTION_CLOSE = 0x1cULL, // to 0x1d
|
||||
QUIC_FRAME_CONNECTION_CLOSE_1 = 0x1dULL,
|
||||
QUIC_FRAME_HANDSHAKE_DONE = 0x1eULL,
|
||||
/* 0x1f to 0x2f are unused currently */
|
||||
/* 0x1f to 0x20 are unused currently */
|
||||
QUIC_FRAME_RELIABLE_RESET_STREAM = 0x21ULL, // intentionally ignore type 0x20 of QUIC_RESET_STREAM cause it's likely to be removed from RFC.
|
||||
/* 0x22 to 0x2f are unused currently */
|
||||
QUIC_FRAME_DATAGRAM = 0x30ULL, // to 0x31
|
||||
QUIC_FRAME_DATAGRAM_1 = 0x31ULL,
|
||||
/* 0x32 to 0xad are unused currently */
|
||||
|
@ -163,7 +165,8 @@ CXPLAT_STATIC_ASSERT(
|
|||
#define QUIC_FRAME_IS_KNOWN(X) \
|
||||
(X <= QUIC_FRAME_HANDSHAKE_DONE || \
|
||||
(X >= QUIC_FRAME_DATAGRAM && X <= QUIC_FRAME_DATAGRAM_1) || \
|
||||
X == QUIC_FRAME_ACK_FREQUENCY || X == QUIC_FRAME_IMMEDIATE_ACK \
|
||||
X == QUIC_FRAME_ACK_FREQUENCY || X == QUIC_FRAME_IMMEDIATE_ACK || \
|
||||
X == QUIC_FRAME_RELIABLE_RESET_STREAM \
|
||||
)
|
||||
|
||||
//
|
||||
|
@ -253,6 +256,38 @@ QuicResetStreamFrameDecode(
|
|||
_Out_ QUIC_RESET_STREAM_EX* Frame
|
||||
);
|
||||
|
||||
//
|
||||
// QUIC_FRAME_RELIABLE_RESET_STREAM Encoding/Decoding
|
||||
//
|
||||
typedef struct QUIC_RELIABLE_RESET_STREAM_EX {
|
||||
|
||||
QUIC_VAR_INT StreamID;
|
||||
QUIC_VAR_INT ErrorCode;
|
||||
QUIC_VAR_INT FinalSize;
|
||||
QUIC_VAR_INT ReliableSize;
|
||||
|
||||
} QUIC_RELIABLE_RESET_STREAM_EX;
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOLEAN
|
||||
QuicReliableResetFrameEncode(
|
||||
_In_ const QUIC_RELIABLE_RESET_STREAM_EX * const Frame,
|
||||
_Inout_ uint16_t* Offset,
|
||||
_In_ uint16_t BufferLength,
|
||||
_Out_writes_to_(BufferLength, *Offset)
|
||||
uint8_t* Buffer
|
||||
);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOLEAN
|
||||
QuicReliableResetFrameDecode(
|
||||
_In_ uint16_t BufferLength,
|
||||
_In_reads_bytes_(BufferLength)
|
||||
const uint8_t * const Buffer,
|
||||
_Inout_ uint16_t* Offset,
|
||||
_Out_ QUIC_RELIABLE_RESET_STREAM_EX* Frame
|
||||
);
|
||||
|
||||
//
|
||||
// QUIC_FRAME_STOP_SENDING Encoding/Decoding
|
||||
//
|
||||
|
|
|
@ -521,6 +521,11 @@ CXPLAT_STATIC_ASSERT(
|
|||
//
|
||||
#define QUIC_DEFAULT_ENCRYPTION_OFFLOAD_ALLOWED FALSE
|
||||
|
||||
//
|
||||
// The default settings for allowing Reliable Reset support.
|
||||
//
|
||||
#define QUIC_DEFAULT_RELIABLE_RESET_ENABLED FALSE
|
||||
|
||||
//
|
||||
// The number of rounds in Cubic Slow Start to sample RTT.
|
||||
//
|
||||
|
@ -574,6 +579,7 @@ CXPLAT_STATIC_ASSERT(
|
|||
#define QUIC_TP_FLAG_MIN_ACK_DELAY 0x00100000
|
||||
#define QUIC_TP_FLAG_CIBIR_ENCODING 0x00200000
|
||||
#define QUIC_TP_FLAG_GREASE_QUIC_BIT 0x00400000
|
||||
#define QUIC_TP_FLAG_RELIABLE_RESET_ENABLED 0x00800000
|
||||
|
||||
#define QUIC_TP_MAX_PACKET_SIZE_DEFAULT 65527
|
||||
#define QUIC_TP_MAX_UDP_PAYLOAD_SIZE_MIN 1200
|
||||
|
@ -620,6 +626,7 @@ CXPLAT_STATIC_ASSERT(
|
|||
#define QUIC_SETTING_ECN_ENABLED "EcnEnabled"
|
||||
#define QUIC_SETTING_HYSTART_ENABLED "HyStartEnabled"
|
||||
#define QUIC_SETTING_ENCRYPTION_OFFLOAD_ALLOWED "EncryptionOffloadAllowed"
|
||||
#define QUIC_SETTING_RELIABLE_RESET_ENABLED "ReliableResetEnabled"
|
||||
|
||||
#define QUIC_SETTING_INITIAL_WINDOW_PACKETS "InitialWindowPackets"
|
||||
#define QUIC_SETTING_SEND_IDLE_TIMEOUT_MS "SendIdleTimeoutMs"
|
||||
|
|
|
@ -147,6 +147,9 @@ QuicSettingsSetDefault(
|
|||
if (!Settings->IsSet.EncryptionOffloadAllowed) {
|
||||
Settings->EncryptionOffloadAllowed = QUIC_DEFAULT_ENCRYPTION_OFFLOAD_ALLOWED;
|
||||
}
|
||||
if (!Settings->IsSet.ReliableResetEnabled) {
|
||||
Settings->ReliableResetEnabled = QUIC_DEFAULT_RELIABLE_RESET_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
|
@ -294,6 +297,9 @@ QuicSettingsCopy(
|
|||
if (!Destination->IsSet.EncryptionOffloadAllowed) {
|
||||
Destination->EncryptionOffloadAllowed = Source->EncryptionOffloadAllowed;
|
||||
}
|
||||
if (!Destination->IsSet.ReliableResetEnabled) {
|
||||
Destination->ReliableResetEnabled = Source->ReliableResetEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
|
@ -616,6 +622,11 @@ QuicSettingApply(
|
|||
Destination->IsSet.EncryptionOffloadAllowed = TRUE;
|
||||
}
|
||||
|
||||
if (Source->IsSet.ReliableResetEnabled && (!Destination->IsSet.ReliableResetEnabled || OverWrite)) {
|
||||
Destination->ReliableResetEnabled = Source->ReliableResetEnabled;
|
||||
Destination->IsSet.ReliableResetEnabled = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1217,6 +1228,16 @@ VersionSettingsFail:
|
|||
&ValueLen);
|
||||
Settings->EncryptionOffloadAllowed = !!Value;
|
||||
}
|
||||
if (!Settings->IsSet.ReliableResetEnabled) {
|
||||
Value = QUIC_DEFAULT_RELIABLE_RESET_ENABLED;
|
||||
ValueLen = sizeof(Value);
|
||||
CxPlatStorageReadValue(
|
||||
Storage,
|
||||
QUIC_SETTING_RELIABLE_RESET_ENABLED,
|
||||
(uint8_t*)&Value,
|
||||
&ValueLen);
|
||||
Settings->ReliableResetEnabled = !!Value;
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
|
@ -1280,6 +1301,7 @@ QuicSettingsDump(
|
|||
QuicTraceLogVerbose(SettingEcnEnabled, "[sett] EcnEnabled = %hhu", Settings->EcnEnabled);
|
||||
QuicTraceLogVerbose(SettingHyStartEnabled, "[sett] HyStartEnabled = %hhu", Settings->HyStartEnabled);
|
||||
QuicTraceLogVerbose(SettingEncryptionOffloadAllowed, "[sett] EncryptionOffloadAllowed = %hhu", Settings->EncryptionOffloadAllowed);
|
||||
QuicTraceLogVerbose(SettingReliableResetEnabled, "[sett] ReliableResetEnabled = %hhu", Settings->ReliableResetEnabled);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
|
@ -1423,6 +1445,9 @@ QuicSettingsDumpNew(
|
|||
if (Settings->IsSet.EncryptionOffloadAllowed) {
|
||||
QuicTraceLogVerbose(SettingEncryptionOffloadAllowed, "[sett] EncryptionOffloadAllowed = %hhu", Settings->EncryptionOffloadAllowed);
|
||||
}
|
||||
if (Settings->IsSet.ReliableResetEnabled) {
|
||||
QuicTraceLogVerbose(SettingReliableResetEnabled, "[sett] ReliableResetEnabled = %hhu", Settings->ReliableResetEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
#define SETTINGS_SIZE_THRU_FIELD(SettingsType, Field) \
|
||||
|
@ -1634,6 +1659,14 @@ QuicSettingsSettingsToInternal(
|
|||
SettingsSize,
|
||||
InternalSettings);
|
||||
|
||||
SETTING_COPY_FLAG_TO_INTERNAL_SIZED(
|
||||
Flags,
|
||||
ReliableResetEnabled,
|
||||
QUIC_SETTINGS,
|
||||
Settings,
|
||||
SettingsSize,
|
||||
InternalSettings);
|
||||
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1750,6 +1783,14 @@ QuicSettingsGetSettings(
|
|||
*SettingsLength,
|
||||
InternalSettings);
|
||||
|
||||
SETTING_COPY_FLAG_FROM_INTERNAL_SIZED(
|
||||
Flags,
|
||||
ReliableResetEnabled,
|
||||
QUIC_SETTINGS,
|
||||
Settings,
|
||||
*SettingsLength,
|
||||
InternalSettings);
|
||||
|
||||
*SettingsLength = CXPLAT_MIN(*SettingsLength, sizeof(QUIC_SETTINGS));
|
||||
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
|
|
|
@ -55,7 +55,8 @@ typedef struct QUIC_SETTINGS_INTERNAL {
|
|||
uint64_t EcnEnabled : 1;
|
||||
uint64_t HyStartEnabled : 1;
|
||||
uint64_t EncryptionOffloadAllowed : 1;
|
||||
uint64_t RESERVED : 23;
|
||||
uint64_t ReliableResetEnabled : 1;
|
||||
uint64_t RESERVED : 22;
|
||||
} IsSet;
|
||||
};
|
||||
|
||||
|
@ -99,6 +100,7 @@ typedef struct QUIC_SETTINGS_INTERNAL {
|
|||
uint8_t EcnEnabled : 1;
|
||||
uint8_t HyStartEnabled : 1;
|
||||
uint8_t EncryptionOffloadAllowed : 1;
|
||||
uint8_t ReliableResetEnabled : 1;
|
||||
uint8_t MtuDiscoveryMissingProbeCount;
|
||||
|
||||
} QUIC_SETTINGS_INTERNAL;
|
||||
|
|
|
@ -224,6 +224,25 @@ TEST(FrameTest, ResetStreamFrameEncodeDecode)
|
|||
ASSERT_EQ(Frame.FinalSize, DecodedFrame.FinalSize);
|
||||
}
|
||||
|
||||
TEST(FrameTest, ReliableResetStreamFrameEncodeDecode)
|
||||
{
|
||||
QUIC_RELIABLE_RESET_STREAM_EX Frame = {127, 4294967297, 65536, 35000};
|
||||
QUIC_RELIABLE_RESET_STREAM_EX DecodedFrame = {0, 0, 0, 0};
|
||||
uint8_t Buffer[20];
|
||||
uint16_t BufferLength = (uint16_t) sizeof(Buffer);
|
||||
uint16_t Offset = 0;
|
||||
|
||||
CxPlatZeroMemory(Buffer, sizeof(Buffer));
|
||||
ASSERT_TRUE(QuicReliableResetFrameEncode(&Frame, &Offset, BufferLength, Buffer));
|
||||
Offset = 1;
|
||||
ASSERT_TRUE(QuicReliableResetFrameDecode(BufferLength, Buffer, &Offset, &DecodedFrame));
|
||||
|
||||
ASSERT_EQ(Frame.StreamID, DecodedFrame.StreamID);
|
||||
ASSERT_EQ(Frame.ErrorCode, DecodedFrame.ErrorCode);
|
||||
ASSERT_EQ(Frame.FinalSize, DecodedFrame.FinalSize);
|
||||
ASSERT_EQ(Frame.ReliableSize, DecodedFrame.ReliableSize);
|
||||
}
|
||||
|
||||
struct ResetStreamFrameParams {
|
||||
uint8_t Buffer[4];
|
||||
uint16_t BufferLength = 4;
|
||||
|
|
|
@ -118,6 +118,7 @@ TEST(SettingsTest, TestAllSettingsFieldsSet)
|
|||
SETTINGS_FEATURE_SET_TEST(EcnEnabled, QuicSettingsSettingsToInternal);
|
||||
SETTINGS_FEATURE_SET_TEST(HyStartEnabled, QuicSettingsSettingsToInternal);
|
||||
SETTINGS_FEATURE_SET_TEST(EncryptionOffloadAllowed, QuicSettingsSettingsToInternal);
|
||||
SETTINGS_FEATURE_SET_TEST(ReliableResetEnabled, QuicSettingsSettingsToInternal);
|
||||
|
||||
Settings.IsSetFlags = 0;
|
||||
Settings.IsSet.RESERVED = ~Settings.IsSet.RESERVED;
|
||||
|
@ -197,6 +198,7 @@ TEST(SettingsTest, TestAllSettingsFieldsGet)
|
|||
SETTINGS_FEATURE_GET_TEST(EcnEnabled, QuicSettingsGetSettings);
|
||||
SETTINGS_FEATURE_GET_TEST(HyStartEnabled, QuicSettingsGetSettings);
|
||||
SETTINGS_FEATURE_GET_TEST(EncryptionOffloadAllowed, QuicSettingsGetSettings);
|
||||
SETTINGS_FEATURE_GET_TEST(ReliableResetEnabled, QuicSettingsGetSettings);
|
||||
|
||||
Settings.IsSetFlags = 0;
|
||||
Settings.IsSet.RESERVED = ~Settings.IsSet.RESERVED;
|
||||
|
|
|
@ -33,6 +33,7 @@ union QuicV1Frames {
|
|||
QUIC_CONNECTION_CLOSE_EX ConnectionCloseFrame;
|
||||
QUIC_DATAGRAM_EX DatagramFrame;
|
||||
QUIC_ACK_FREQUENCY_EX AckFrequencyFrame;
|
||||
QUIC_RELIABLE_RESET_STREAM_EX ReliableResetStreamFrame;
|
||||
};
|
||||
|
||||
TEST(SpinFrame, SpinFrame1000000)
|
||||
|
@ -225,6 +226,13 @@ TEST(SpinFrame, SpinFrame1000000)
|
|||
FailedDecodes++;
|
||||
}
|
||||
break;
|
||||
case QUIC_FRAME_RELIABLE_RESET_STREAM:
|
||||
if (QuicReliableResetFrameDecode(BufferLength, Buffer, &Offset, &DecodedFrame.ReliableResetStreamFrame)) {
|
||||
SuccessfulDecodes++;
|
||||
} else {
|
||||
FailedDecodes++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT_TRUE(FALSE) << "You have a test bug. FrameType: " << (QUIC_FRAME_TYPE) FrameType << " doesn't have a matching case.";
|
||||
break;
|
||||
|
|
|
@ -212,3 +212,12 @@ TEST(TransportParamTest, GreaseQuicBit)
|
|||
EncodeDecodeAndCompare(&OriginalTP);
|
||||
EncodeDecodeAndCompare(&OriginalTP, true);
|
||||
}
|
||||
|
||||
TEST(TransportParamTest, ReliableResetEnabled)
|
||||
{
|
||||
QUIC_TRANSPORT_PARAMETERS OriginalTP;
|
||||
CxPlatZeroMemory(&OriginalTP, sizeof(OriginalTP));
|
||||
OriginalTP.Flags = QUIC_TP_FLAG_RELIABLE_RESET_ENABLED;
|
||||
EncodeDecodeAndCompare(&OriginalTP);
|
||||
EncodeDecodeAndCompare(&OriginalTP, true);
|
||||
}
|
||||
|
|
|
@ -1296,6 +1296,19 @@ namespace Microsoft.Quic
|
|||
}
|
||||
}
|
||||
|
||||
internal ulong ReliableResetEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return Anonymous2.Anonymous.ReliableResetEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Anonymous2.Anonymous.ReliableResetEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong ReservedFlags
|
||||
{
|
||||
get
|
||||
|
@ -1828,17 +1841,31 @@ namespace Microsoft.Quic
|
|||
}
|
||||
}
|
||||
|
||||
[NativeTypeName("uint64_t : 28")]
|
||||
internal ulong RESERVED
|
||||
[NativeTypeName("uint64_t : 1")]
|
||||
internal ulong ReliableResetEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_bitfield >> 36) & 0xFFFFFFFUL;
|
||||
return (_bitfield >> 36) & 0x1UL;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_bitfield = (_bitfield & ~(0xFFFFFFFUL << 36)) | ((value & 0xFFFFFFFUL) << 36);
|
||||
_bitfield = (_bitfield & ~(0x1UL << 36)) | ((value & 0x1UL) << 36);
|
||||
}
|
||||
}
|
||||
|
||||
[NativeTypeName("uint64_t : 27")]
|
||||
internal ulong RESERVED
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_bitfield >> 37) & 0x7FFFFFFUL;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_bitfield = (_bitfield & ~(0x7FFFFFFUL << 37)) | ((value & 0x7FFFFFFUL) << 37);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1887,17 +1914,31 @@ namespace Microsoft.Quic
|
|||
}
|
||||
}
|
||||
|
||||
[NativeTypeName("uint64_t : 62")]
|
||||
internal ulong ReservedFlags
|
||||
[NativeTypeName("uint64_t : 1")]
|
||||
internal ulong ReliableResetEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_bitfield >> 2) & 0x3FFFFFFFUL;
|
||||
return (_bitfield >> 2) & 0x1UL;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_bitfield = (_bitfield & ~(0x3FFFFFFFUL << 2)) | ((value & 0x3FFFFFFFUL) << 2);
|
||||
_bitfield = (_bitfield & ~(0x1UL << 2)) | ((value & 0x1UL) << 2);
|
||||
}
|
||||
}
|
||||
|
||||
[NativeTypeName("uint64_t : 61")]
|
||||
internal ulong ReservedFlags
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_bitfield >> 3) & 0x1FFFFFFFUL;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_bitfield = (_bitfield & ~(0x1FFFFFFFUL << 3)) | ((value & 0x1FFFFFFFUL) << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2179,6 +2220,7 @@ namespace Microsoft.Quic
|
|||
RESUMED = 13,
|
||||
RESUMPTION_TICKET_RECEIVED = 14,
|
||||
PEER_CERTIFICATE_RECEIVED = 15,
|
||||
RELIABLE_RESET_NEGOTIATED = 16,
|
||||
}
|
||||
|
||||
internal partial struct QUIC_CONNECTION_EVENT
|
||||
|
@ -2316,6 +2358,14 @@ namespace Microsoft.Quic
|
|||
}
|
||||
}
|
||||
|
||||
internal ref _Anonymous_e__Union._RELIABLE_RESET_NEGOTIATED_e__Struct RELIABLE_RESET_NEGOTIATED
|
||||
{
|
||||
get
|
||||
{
|
||||
return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.RELIABLE_RESET_NEGOTIATED, 1));
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal partial struct _Anonymous_e__Union
|
||||
{
|
||||
|
@ -2383,6 +2433,10 @@ namespace Microsoft.Quic
|
|||
[NativeTypeName("struct (anonymous struct)")]
|
||||
internal _PEER_CERTIFICATE_RECEIVED_e__Struct PEER_CERTIFICATE_RECEIVED;
|
||||
|
||||
[FieldOffset(0)]
|
||||
[NativeTypeName("struct (anonymous struct)")]
|
||||
internal _RELIABLE_RESET_NEGOTIATED_e__Struct RELIABLE_RESET_NEGOTIATED;
|
||||
|
||||
internal unsafe partial struct _CONNECTED_e__Struct
|
||||
{
|
||||
[NativeTypeName("BOOLEAN")]
|
||||
|
@ -2554,6 +2608,12 @@ namespace Microsoft.Quic
|
|||
[NativeTypeName("QUIC_CERTIFICATE_CHAIN *")]
|
||||
internal void* Chain;
|
||||
}
|
||||
|
||||
internal partial struct _RELIABLE_RESET_NEGOTIATED_e__Struct
|
||||
{
|
||||
[NativeTypeName("BOOLEAN")]
|
||||
internal byte IsNegotiated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1072,6 +1072,26 @@ tracepoint(CLOG_CONNECTION_C, CompatibleVersionUpgradeComplete , arg1, arg3, arg
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for IndicateReliableResetNegotiated
|
||||
// [conn][%p] Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]
|
||||
// QuicTraceLogConnVerbose(
|
||||
IndicateReliableResetNegotiated,
|
||||
Connection,
|
||||
"Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]",
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated);
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
// arg3 = arg3 = Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_IndicateReliableResetNegotiated
|
||||
#define _clog_4_ARGS_TRACE_IndicateReliableResetNegotiated(uniqueId, arg1, encoded_arg_string, arg3)\
|
||||
tracepoint(CLOG_CONNECTION_C, IndicateReliableResetNegotiated , arg1, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for IndicatePeerCertificateReceived
|
||||
// [conn][%p] Indicating QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED (0x%x, 0x%x)
|
||||
|
|
|
@ -1165,6 +1165,29 @@ TRACEPOINT_EVENT(CLOG_CONNECTION_C, CompatibleVersionUpgradeComplete,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for IndicateReliableResetNegotiated
|
||||
// [conn][%p] Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]
|
||||
// QuicTraceLogConnVerbose(
|
||||
IndicateReliableResetNegotiated,
|
||||
Connection,
|
||||
"Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]",
|
||||
Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated);
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
// arg3 = arg3 = Event.RELIABLE_RESET_NEGOTIATED.IsNegotiated = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_CONNECTION_C, IndicateReliableResetNegotiated,
|
||||
TP_ARGS(
|
||||
const void *, arg1,
|
||||
unsigned char, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg1, arg1)
|
||||
ctf_integer(unsigned char, arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for IndicatePeerCertificateReceived
|
||||
// [conn][%p] Indicating QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED (0x%x, 0x%x)
|
||||
|
|
|
@ -581,6 +581,24 @@ tracepoint(CLOG_CRYPTO_TLS_C, EncodeTPGreaseQuicBit , arg1);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for EncodeTPReliableReset
|
||||
// [conn][%p] TP: Encode Reliable Reset
|
||||
// QuicTraceLogConnVerbose(
|
||||
EncodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Encode Reliable Reset");
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_3_ARGS_TRACE_EncodeTPReliableReset
|
||||
#define _clog_3_ARGS_TRACE_EncodeTPReliableReset(uniqueId, arg1, encoded_arg_string)\
|
||||
tracepoint(CLOG_CRYPTO_TLS_C, EncodeTPReliableReset , arg1);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for EncodeTPTest
|
||||
// [conn][%p] TP: TEST TP (Type %hu, Length %hu)
|
||||
|
@ -1115,6 +1133,24 @@ tracepoint(CLOG_CRYPTO_TLS_C, DecodeTPGreaseQuicBit , arg1);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DecodeTPReliableReset
|
||||
// [conn][%p] TP: Decode Reliable Reset
|
||||
// QuicTraceLogConnVerbose(
|
||||
DecodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Decode Reliable Reset");
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_3_ARGS_TRACE_DecodeTPReliableReset
|
||||
#define _clog_3_ARGS_TRACE_DecodeTPReliableReset(uniqueId, arg1, encoded_arg_string)\
|
||||
tracepoint(CLOG_CRYPTO_TLS_C, DecodeTPReliableReset , arg1);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for ConnError
|
||||
// [conn][%p] ERROR, %s.
|
||||
|
|
|
@ -630,6 +630,25 @@ TRACEPOINT_EVENT(CLOG_CRYPTO_TLS_C, EncodeTPGreaseQuicBit,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for EncodeTPReliableReset
|
||||
// [conn][%p] TP: Encode Reliable Reset
|
||||
// QuicTraceLogConnVerbose(
|
||||
EncodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Encode Reliable Reset");
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_CRYPTO_TLS_C, EncodeTPReliableReset,
|
||||
TP_ARGS(
|
||||
const void *, arg1),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg1, arg1)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for EncodeTPTest
|
||||
// [conn][%p] TP: TEST TP (Type %hu, Length %hu)
|
||||
|
@ -1240,6 +1259,25 @@ TRACEPOINT_EVENT(CLOG_CRYPTO_TLS_C, DecodeTPGreaseQuicBit,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DecodeTPReliableReset
|
||||
// [conn][%p] TP: Decode Reliable Reset
|
||||
// QuicTraceLogConnVerbose(
|
||||
DecodeTPReliableReset,
|
||||
Connection,
|
||||
"TP: Decode Reliable Reset");
|
||||
// arg1 = arg1 = Connection = arg1
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_CRYPTO_TLS_C, DecodeTPReliableReset,
|
||||
TP_ARGS(
|
||||
const void *, arg1),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg1, arg1)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for ConnError
|
||||
// [conn][%p] ERROR, %s.
|
||||
|
|
|
@ -707,6 +707,21 @@ tracepoint(CLOG_SETTINGS_C, SettingEncryptionOffloadAllowed , arg2);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for SettingReliableResetEnabled
|
||||
// [sett] ReliableResetEnabled = %hhu
|
||||
// QuicTraceLogVerbose(SettingReliableResetEnabled, "[sett] ReliableResetEnabled = %hhu", Settings->ReliableResetEnabled);
|
||||
// arg2 = arg2 = Settings->ReliableResetEnabled = arg2
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_3_ARGS_TRACE_SettingReliableResetEnabled
|
||||
#define _clog_3_ARGS_TRACE_SettingReliableResetEnabled(uniqueId, encoded_arg_string, arg2)\
|
||||
tracepoint(CLOG_SETTINGS_C, SettingReliableResetEnabled , arg2);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for SettingDumpLFixedServerID
|
||||
// [sett] FixedServerID = %u
|
||||
|
|
|
@ -730,6 +730,22 @@ TRACEPOINT_EVENT(CLOG_SETTINGS_C, SettingEncryptionOffloadAllowed,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for SettingReliableResetEnabled
|
||||
// [sett] ReliableResetEnabled = %hhu
|
||||
// QuicTraceLogVerbose(SettingReliableResetEnabled, "[sett] ReliableResetEnabled = %hhu", Settings->ReliableResetEnabled);
|
||||
// arg2 = arg2 = Settings->ReliableResetEnabled = arg2
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_SETTINGS_C, SettingReliableResetEnabled,
|
||||
TP_ARGS(
|
||||
unsigned char, arg2),
|
||||
TP_FIELDS(
|
||||
ctf_integer(unsigned char, arg2, arg2)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for SettingDumpLFixedServerID
|
||||
// [sett] FixedServerID = %u
|
||||
|
|
|
@ -669,7 +669,8 @@ typedef struct QUIC_SETTINGS {
|
|||
uint64_t HyStartEnabled : 1;
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
uint64_t EncryptionOffloadAllowed : 1;
|
||||
uint64_t RESERVED : 28;
|
||||
uint64_t ReliableResetEnabled : 1;
|
||||
uint64_t RESERVED : 27;
|
||||
#else
|
||||
uint64_t RESERVED : 29;
|
||||
#endif
|
||||
|
@ -716,7 +717,8 @@ typedef struct QUIC_SETTINGS {
|
|||
uint64_t HyStartEnabled : 1;
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
uint64_t EncryptionOffloadAllowed : 1;
|
||||
uint64_t ReservedFlags : 62;
|
||||
uint64_t ReliableResetEnabled : 1;
|
||||
uint64_t ReservedFlags : 61;
|
||||
#else
|
||||
uint64_t ReservedFlags : 63;
|
||||
#endif
|
||||
|
@ -1140,6 +1142,9 @@ typedef enum QUIC_CONNECTION_EVENT_TYPE {
|
|||
QUIC_CONNECTION_EVENT_RESUMED = 13, // Server-only; provides resumption data, if any.
|
||||
QUIC_CONNECTION_EVENT_RESUMPTION_TICKET_RECEIVED = 14, // Client-only; provides ticket to persist, if any.
|
||||
QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED = 15, // Only with QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED set
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED = 16, // Only indicated if QUIC_SETTINGS.ReliableResetEnabled is TRUE.
|
||||
#endif
|
||||
} QUIC_CONNECTION_EVENT_TYPE;
|
||||
|
||||
typedef struct QUIC_CONNECTION_EVENT {
|
||||
|
@ -1212,6 +1217,11 @@ typedef struct QUIC_CONNECTION_EVENT {
|
|||
QUIC_STATUS DeferredStatus; // Most severe error status (only valid with QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION)
|
||||
QUIC_CERTIFICATE_CHAIN* Chain; // Peer certificate chain (platform specific). Valid only during QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED callback.
|
||||
} PEER_CERTIFICATE_RECEIVED;
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
struct {
|
||||
BOOLEAN IsNegotiated;
|
||||
} RELIABLE_RESET_NEGOTIATED;
|
||||
#endif
|
||||
};
|
||||
} QUIC_CONNECTION_EVENT;
|
||||
|
||||
|
|
|
@ -472,6 +472,7 @@ public:
|
|||
MsQuicSettings& SetEcnEnabled(bool Value) { EcnEnabled = Value; IsSet.EcnEnabled = TRUE; return *this; }
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
MsQuicSettings& SetEncryptionOffloadAllowed(bool Value) { EncryptionOffloadAllowed = Value; IsSet.EncryptionOffloadAllowed = TRUE; return *this; }
|
||||
MsQuicSettings& SetReliableResetEnabled(bool value) { ReliableResetEnabled = value; IsSet.ReliableResetEnabled = TRUE; return *this; }
|
||||
#endif
|
||||
|
||||
QUIC_STATUS
|
||||
|
|
|
@ -3507,6 +3507,18 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"DecodeTPReliableReset": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] TP: Decode Reliable Reset",
|
||||
"UniqueId": "DecodeTPReliableReset",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg1"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"DecodeTPReserved": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] TP: Reserved ID %llu, length %hu",
|
||||
|
@ -4055,6 +4067,18 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"EncodeTPReliableReset": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] TP: Encode Reliable Reset",
|
||||
"UniqueId": "EncodeTPReliableReset",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg1"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"EncodeTPRetrySourceCID": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] TP: Retry Source Connection ID (%s)",
|
||||
|
@ -5823,6 +5847,22 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"IndicateReliableResetNegotiated": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]",
|
||||
"UniqueId": "IndicateReliableResetNegotiated",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg1"
|
||||
},
|
||||
{
|
||||
"DefinationEncoding": "hhu",
|
||||
"MacroVariableName": "arg3"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"IndicateResumed": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] Indicating QUIC_CONNECTION_EVENT_RESUMED",
|
||||
|
@ -9078,6 +9118,38 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogInfo"
|
||||
},
|
||||
"ReliableResetEnabledUpdated": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] Updated reliable reset frame enabled to %hhu",
|
||||
"UniqueId": "ReliableResetEnabledUpdated",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg1"
|
||||
},
|
||||
{
|
||||
"DefinationEncoding": "hhu",
|
||||
"MacroVariableName": "arg3"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogConnVerbose"
|
||||
},
|
||||
"ReliableResetFrameReceived": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[conn][%p] Received a reliable reset frame. Local reliable reset extension preferences: %hhu",
|
||||
"UniqueId": "ReliableResetFrameReceived",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg1"
|
||||
},
|
||||
{
|
||||
"DefinationEncoding": "hhu",
|
||||
"MacroVariableName": "arg3"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogConnInfo"
|
||||
},
|
||||
"RemoteBlocked": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[strm][%p] Remote FC blocked (%llu)",
|
||||
|
@ -10503,6 +10575,18 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogVerbose"
|
||||
},
|
||||
"SettingReliableResetEnabled": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[sett] ReliableResetEnabled = %hhu",
|
||||
"UniqueId": "SettingReliableResetEnabled",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "hhu",
|
||||
"MacroVariableName": "arg2"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogVerbose"
|
||||
},
|
||||
"SettingsInvalidAcceptableVersion": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "Invalid AcceptableVersion supplied to settings! 0x%x at position %d",
|
||||
|
@ -13636,6 +13720,11 @@
|
|||
"TraceID": "DecodeTPPreferredAddress",
|
||||
"EncodingString": "[conn][%p] TP: Preferred Address"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "eabf7a25-2986-5193-5044-318b4711544e",
|
||||
"TraceID": "DecodeTPReliableReset",
|
||||
"EncodingString": "[conn][%p] TP: Decode Reliable Reset"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "95f4176f-e0b5-1420-53d9-44e244c44ea5",
|
||||
"TraceID": "DecodeTPReserved",
|
||||
|
@ -13811,6 +13900,11 @@
|
|||
"TraceID": "EncodeTPPreferredAddress",
|
||||
"EncodingString": "[conn][%p] TP: Preferred Address"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "75ce2146-e447-c891-d263-df4892bddda9",
|
||||
"TraceID": "EncodeTPReliableReset",
|
||||
"EncodingString": "[conn][%p] TP: Encode Reliable Reset"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "214be45a-42ba-44e1-05c2-f82f3200e671",
|
||||
"TraceID": "EncodeTPRetrySourceCID",
|
||||
|
@ -14251,6 +14345,11 @@
|
|||
"TraceID": "IndicatePeerStreamStarted",
|
||||
"EncodingString": "[conn][%p] Indicating QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED [%p, 0x%x]"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "cb6ed5bc-5216-e56f-9e29-117ba277fde6",
|
||||
"TraceID": "IndicateReliableResetNegotiated",
|
||||
"EncodingString": "[conn][%p] Indicating QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED [IsNegotiated=%hhu]"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "8c1a717b-f814-d6d9-3f2e-f1987be847d6",
|
||||
"TraceID": "IndicateResumed",
|
||||
|
@ -15326,6 +15425,16 @@
|
|||
"TraceID": "RegistrationVerifierEnabled",
|
||||
"EncodingString": "[ reg][%p] Verifing enabled!"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "7c8196a9-c4d5-9b85-26ae-ee4492bfe6c8",
|
||||
"TraceID": "ReliableResetEnabledUpdated",
|
||||
"EncodingString": "[conn][%p] Updated reliable reset frame enabled to %hhu"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "3ea0dcfb-b981-88e5-b801-74fb2684acaa",
|
||||
"TraceID": "ReliableResetFrameReceived",
|
||||
"EncodingString": "[conn][%p] Received a reliable reset frame. Local reliable reset extension preferences: %hhu"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "90a48bef-0658-1e75-8afa-d4fff8d929bf",
|
||||
"TraceID": "RemoteBlocked",
|
||||
|
@ -15806,6 +15915,11 @@
|
|||
"TraceID": "SettingHyStartEnabled",
|
||||
"EncodingString": "[sett] HyStartEnabled = %hhu"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "f5c7d703-ecd1-8dd0-c16d-11857945bfcf",
|
||||
"TraceID": "SettingReliableResetEnabled",
|
||||
"EncodingString": "[sett] ReliableResetEnabled = %hhu"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "e7d29156-fb54-8f96-f3e2-1aa999886c12",
|
||||
"TraceID": "SettingsInvalidAcceptableVersion",
|
||||
|
|
|
@ -186,6 +186,13 @@ void
|
|||
QuicTestFailedVersionNegotiation(
|
||||
_In_ int Family
|
||||
);
|
||||
|
||||
void
|
||||
QuicTestReliableResetNegotiation(
|
||||
_In_ int Family,
|
||||
_In_ bool ServerSupport,
|
||||
_In_ bool ClientSupport
|
||||
);
|
||||
#endif // QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
|
||||
void
|
||||
|
@ -914,6 +921,12 @@ typedef struct {
|
|||
BOOLEAN AsyncValidation;
|
||||
} QUIC_RUN_CUSTOM_CERT_VALIDATION;
|
||||
|
||||
typedef struct {
|
||||
int Family;
|
||||
BOOLEAN ServerSupport;
|
||||
BOOLEAN ClientSupport;
|
||||
} QUIC_RUN_RELIABLE_RESET_NEGOTIATION;
|
||||
|
||||
#define IOCTL_QUIC_RUN_CUSTOM_SERVER_CERT_VALIDATION \
|
||||
QUIC_CTL_CODE(47, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// QUIC_RUN_CUSTOM_CERT_VALIDATION
|
||||
|
@ -1176,4 +1189,8 @@ typedef struct {
|
|||
QUIC_CTL_CODE(110, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// QUIC_RUN_CUSTOM_CERT_VALIDATION
|
||||
|
||||
#define QUIC_MAX_IOCTL_FUNC_CODE 110
|
||||
#define IOCTL_QUIC_RELIABLE_RESET_NEGOTIATION \
|
||||
QUIC_CTL_CODE(111, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// QUIC_RUN_RELIABLE_RESET_NEGOTIATION
|
||||
|
||||
#define QUIC_MAX_IOCTL_FUNC_CODE 111
|
||||
|
|
|
@ -995,6 +995,21 @@ TEST_P(WithFamilyArgs, FailedVersionNegotiation) {
|
|||
QuicTestFailedVersionNegotiation(GetParam().Family);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(WithReliableResetArgs, ReliableResetNegotiation) {
|
||||
TestLoggerT<ParamType> Logger("ReliableResetNegotiation", GetParam());
|
||||
if (TestingKernelMode) {
|
||||
QUIC_RUN_RELIABLE_RESET_NEGOTIATION Params = {
|
||||
GetParam().Family,
|
||||
GetParam().ServerSupport,
|
||||
GetParam().ClientSupport
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RELIABLE_RESET_NEGOTIATION, Params));
|
||||
} else {
|
||||
QuicTestReliableResetNegotiation(GetParam().Family, GetParam().ServerSupport, GetParam().ClientSupport);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
|
||||
TEST_P(WithHandshakeArgs5, CustomServerCertificateValidation) {
|
||||
|
@ -2249,6 +2264,11 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
Handshake,
|
||||
WithHandshakeArgs7,
|
||||
testing::ValuesIn(HandshakeArgs7::Generate()));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Handshake,
|
||||
WithReliableResetArgs,
|
||||
testing::ValuesIn(ReliableResetArgs::Generate()));
|
||||
#endif
|
||||
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
|
|
|
@ -299,6 +299,31 @@ class WithHandshakeArgs9 : public testing::Test,
|
|||
public testing::WithParamInterface<bool> {
|
||||
};
|
||||
|
||||
struct ReliableResetArgs {
|
||||
int Family;
|
||||
bool ServerSupport;
|
||||
bool ClientSupport;
|
||||
static ::std::vector<ReliableResetArgs> Generate() {
|
||||
::std::vector<ReliableResetArgs> list;
|
||||
for (int Family : { 4, 6 })
|
||||
for (bool ServerSupport : { false, true })
|
||||
for (bool ClientSupport : { false, true })
|
||||
list.push_back({ Family, ServerSupport, ClientSupport });
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream& o, const ReliableResetArgs& args) {
|
||||
return o <<
|
||||
(args.Family == 4 ? "v4" : "v6") << "/" <<
|
||||
(args.ServerSupport ? "Server Yes" : "Server No") << "/" <<
|
||||
(args.ClientSupport ? "Client Yes" : "Client No");
|
||||
}
|
||||
|
||||
class WithReliableResetArgs : public testing::Test,
|
||||
public testing::WithParamInterface<ReliableResetArgs> {
|
||||
};
|
||||
|
||||
struct SendArgs1 {
|
||||
int Family;
|
||||
uint64_t Length;
|
||||
|
|
|
@ -482,6 +482,7 @@ size_t QUIC_IOCTL_BUFFER_SIZES[] =
|
|||
sizeof(INT32),
|
||||
sizeof(INT32),
|
||||
sizeof(QUIC_RUN_CUSTOM_CERT_VALIDATION),
|
||||
sizeof(QUIC_RUN_RELIABLE_RESET_NEGOTIATION)
|
||||
};
|
||||
|
||||
CXPLAT_STATIC_ASSERT(
|
||||
|
@ -517,7 +518,7 @@ typedef union {
|
|||
QUIC_RUN_VN_TP_ODD_SIZE_PARAMS OddSizeVnTpParams;
|
||||
UINT8 TestServerVNTP;
|
||||
BOOLEAN Bidirectional;
|
||||
|
||||
QUIC_RUN_RELIABLE_RESET_NEGOTIATION ReliableResetNegotiationParams;
|
||||
} QUIC_IOCTL_PARAMS;
|
||||
|
||||
#define QuicTestCtlRun(X) \
|
||||
|
@ -1338,7 +1339,16 @@ QuicTestCtlEvtIoDeviceControl(
|
|||
Params->CustomCertValidationParams.AcceptCert,
|
||||
Params->CustomCertValidationParams.AsyncValidation));
|
||||
break;
|
||||
|
||||
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
case IOCTL_QUIC_RELIABLE_RESET_NEGOTIATION:
|
||||
CXPLAT_FRE_ASSERT(Params != nullptr);
|
||||
QuicTestCtlRun(
|
||||
QuicTestReliableResetNegotiation(
|
||||
Params->ReliableResetNegotiationParams.Family,
|
||||
Params->ReliableResetNegotiationParams.ServerSupport,
|
||||
Params->ReliableResetNegotiationParams.ClientSupport));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
|
|
@ -1880,6 +1880,85 @@ QuicTestFailedVersionNegotiation(
|
|||
QUIC_VERSION_1_H,
|
||||
Family);
|
||||
}
|
||||
|
||||
void
|
||||
QuicTestReliableResetNegotiation(
|
||||
_In_ int Family,
|
||||
_In_ bool ServerSupport,
|
||||
_In_ bool ClientSupport
|
||||
)
|
||||
{
|
||||
struct Context {
|
||||
bool Negotiated {false};
|
||||
bool CallbackReceived {false};
|
||||
QUIC_STATUS ConnectionCallback(_Inout_ QUIC_CONNECTION_EVENT* Event)
|
||||
{
|
||||
if (Event->Type == QUIC_CONNECTION_EVENT_RELIABLE_RESET_NEGOTIATED) {
|
||||
CallbackReceived = true;
|
||||
Negotiated = Event->RELIABLE_RESET_NEGOTIATED.IsNegotiated;
|
||||
}
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
static QUIC_STATUS s_ConnectionCallback(
|
||||
_In_ MsQuicConnection* /* Connection */,
|
||||
_In_opt_ void* context,
|
||||
_Inout_ QUIC_CONNECTION_EVENT* Event
|
||||
) {
|
||||
return ((Context*)context)->ConnectionCallback(Event);
|
||||
}
|
||||
};
|
||||
|
||||
Context ClientContext, ServerContext;
|
||||
|
||||
MsQuicRegistration Registration(true);
|
||||
TEST_TRUE(Registration.IsValid());
|
||||
|
||||
MsQuicSettings ServerSettings;
|
||||
MsQuicSettings ClientSettings;
|
||||
ServerSettings.SetReliableResetEnabled(ServerSupport);
|
||||
ClientSettings.SetReliableResetEnabled(ClientSupport);
|
||||
|
||||
MsQuicConfiguration ServerConfiguration(Registration, "MsQuicTest", ServerSettings, ServerSelfSignedCredConfig);
|
||||
TEST_QUIC_SUCCEEDED(ServerConfiguration.GetInitStatus());
|
||||
|
||||
MsQuicConfiguration ClientConfiguration(Registration, "MsQuicTest", ClientSettings, MsQuicCredentialConfig());
|
||||
TEST_QUIC_SUCCEEDED(ClientConfiguration.GetInitStatus());
|
||||
|
||||
QUIC_ADDRESS_FAMILY QuicAddrFamily = (Family == 4) ? QUIC_ADDRESS_FAMILY_INET : QUIC_ADDRESS_FAMILY_INET6;
|
||||
QuicAddr ServerLocalAddr(QuicAddrFamily);
|
||||
MsQuicAutoAcceptListener Listener(Registration, ServerConfiguration, Context::s_ConnectionCallback, &ServerContext);
|
||||
|
||||
TEST_QUIC_SUCCEEDED(Listener.Start("MsQuicTest", &ServerLocalAddr.SockAddr));
|
||||
TEST_QUIC_SUCCEEDED(Listener.GetInitStatus());
|
||||
TEST_QUIC_SUCCEEDED(Listener.GetLocalAddr(ServerLocalAddr));
|
||||
|
||||
MsQuicConnection Connection(Registration, CleanUpManual, Context::s_ConnectionCallback, &ClientContext);
|
||||
TEST_QUIC_SUCCEEDED(Connection.GetInitStatus());
|
||||
TEST_QUIC_SUCCEEDED(Connection.Start(ClientConfiguration, ServerLocalAddr.GetFamily(), QUIC_TEST_LOOPBACK_FOR_AF(ServerLocalAddr.GetFamily()), ServerLocalAddr.GetPort()));
|
||||
|
||||
TEST_TRUE(Connection.HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout));
|
||||
TEST_TRUE(Connection.HandshakeComplete);
|
||||
TEST_TRUE(Listener.LastConnection->HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout));
|
||||
TEST_TRUE(Listener.LastConnection->HandshakeComplete);
|
||||
|
||||
MsQuicSettings ListenerServerSettings2;
|
||||
TEST_QUIC_SUCCEEDED(Listener.LastConnection->GetSettings(&ListenerServerSettings2));
|
||||
TEST_EQUAL(ListenerServerSettings2.ReliableResetEnabled, (int) ServerSupport);
|
||||
|
||||
if (ClientSupport) {
|
||||
TEST_TRUE(ClientContext.CallbackReceived);
|
||||
TEST_TRUE(ClientContext.Negotiated == ServerSupport);
|
||||
} else {
|
||||
TEST_FALSE(ClientContext.CallbackReceived);
|
||||
}
|
||||
if (ServerSupport) {
|
||||
TEST_TRUE(ServerContext.CallbackReceived);
|
||||
TEST_TRUE(ServerContext.Negotiated == ClientSupport);
|
||||
} else {
|
||||
TEST_FALSE(ServerContext.CallbackReceived);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QUIC_API_ENABLE_PREVIEW_FEATURES
|
||||
|
||||
void
|
||||
|
|
|
@ -535,7 +535,7 @@ struct SetParamHelper {
|
|||
|
||||
void SpinQuicRandomizeSettings(QUIC_SETTINGS& Settings, uint16_t ThreadID)
|
||||
{
|
||||
switch (GetRandom(36)) {
|
||||
switch (GetRandom(37)) {
|
||||
case 0:
|
||||
//Settings.MaxBytesPerKey = GetRandom(UINT64_MAX);
|
||||
//Settings.IsSet.MaxBytesPerKey = TRUE;
|
||||
|
@ -680,6 +680,10 @@ void SpinQuicRandomizeSettings(QUIC_SETTINGS& Settings, uint16_t ThreadID)
|
|||
Settings.EncryptionOffloadAllowed = GetRandom((uint8_t)1);
|
||||
Settings.IsSet.EncryptionOffloadAllowed = TRUE;
|
||||
break;
|
||||
case 36:
|
||||
Settings.ReliableResetEnabled = GetRandom((uint8_t)1);
|
||||
Settings.IsSet.ReliableResetEnabled = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче