Reliable Reset Stream Support - Phase 1 - Feature Negotiation (#3778)

This commit is contained in:
Jack He (Github) 2023-08-11 04:36:06 -07:00 коммит произвёл GitHub
Родитель d1a82364e8
Коммит 09eff16e01
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
28 изменённых файлов: 775 добавлений и 18 удалений

Просмотреть файл

@ -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;
}