Skip to content

Commit d4219b5

Browse files
authored
Official Version 1 Support (#1099) (#1114)
1 parent e8fb2e2 commit d4219b5

22 files changed

+200
-422
lines changed

.azure/templates/build-config-user.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626

2727
- task: Cache@2
2828
inputs:
29-
key: '"${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.extraName }}_4" | .gitmodules'
29+
key: '"${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.extraName }}_5" | .gitmodules'
3030
path: build/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.tls }}/openssl
3131
displayName: Cache OpenSSL
3232
condition: eq('${{ parameters.tls }}', 'openssl')

src/core/binding.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -1427,12 +1427,8 @@ QuicBindingDeliverDatagrams(
14271427
// Only Initial (version specific) packets are processed from here on.
14281428
//
14291429
switch (Packet->Invariant->LONG_HDR.Version) {
1430-
case QUIC_VERSION_DRAFT_27:
1431-
case QUIC_VERSION_DRAFT_28:
1430+
case QUIC_VERSION_1:
14321431
case QUIC_VERSION_DRAFT_29:
1433-
case QUIC_VERSION_DRAFT_30:
1434-
case QUIC_VERSION_DRAFT_31:
1435-
case QUIC_VERSION_DRAFT_32:
14361432
case QUIC_VERSION_MS_1:
14371433
if (Packet->LH->Type != QUIC_INITIAL) {
14381434
QuicPacketLogDrop(Binding, Packet, "Non-initial packet not matched with a connection");

src/core/connection.c

+51-97
Original file line numberDiff line numberDiff line change
@@ -1694,12 +1694,8 @@ QuicConnOnQuicVersionSet(
16941694
Connection->Stats.QuicVersion);
16951695

16961696
switch (Connection->Stats.QuicVersion) {
1697-
case QUIC_VERSION_DRAFT_27:
1698-
case QUIC_VERSION_DRAFT_28:
1697+
case QUIC_VERSION_1:
16991698
case QUIC_VERSION_DRAFT_29:
1700-
case QUIC_VERSION_DRAFT_30:
1701-
case QUIC_VERSION_DRAFT_31:
1702-
case QUIC_VERSION_DRAFT_32:
17031699
case QUIC_VERSION_MS_1:
17041700
default:
17051701
Connection->State.HeaderProtectionEnabled = TRUE;
@@ -1888,6 +1884,13 @@ QuicConnStart(
18881884
return Status;
18891885
}
18901886

1887+
_IRQL_requires_max_(PASSIVE_LEVEL)
1888+
QUIC_STATUS
1889+
QuicConnGenerateLocalTransportParameters(
1890+
_In_ QUIC_CONNECTION* Connection,
1891+
_Out_ QUIC_TRANSPORT_PARAMETERS* LocalTP
1892+
);
1893+
18911894
_IRQL_requires_max_(PASSIVE_LEVEL)
18921895
void
18931896
QuicConnRestart(
@@ -1921,8 +1924,30 @@ QuicConnRestart(
19211924
QuicCongestionControlReset(&Connection->CongestionControl);
19221925
QuicSendReset(&Connection->Send);
19231926
QuicLossDetectionReset(&Connection->LossDetection);
1924-
QuicCryptoReset(&Connection->Crypto, CompleteReset);
1927+
1928+
if (CompleteReset) {
1929+
QUIC_DBG_ASSERT(Connection->Configuration != NULL);
1930+
1931+
QUIC_TRANSPORT_PARAMETERS LocalTP = { 0 };
1932+
QUIC_STATUS Status =
1933+
QuicConnGenerateLocalTransportParameters(Connection, &LocalTP);
1934+
QUIC_FRE_ASSERT(QUIC_SUCCEEDED(Status)); // Can't fail since it passed already.
1935+
UNREFERENCED_PARAMETER(Status);
1936+
1937+
Status =
1938+
QuicCryptoInitializeTls(
1939+
&Connection->Crypto,
1940+
Connection->Configuration->SecurityConfig,
1941+
&LocalTP);
1942+
if (QUIC_FAILED(Status)) {
1943+
QuicConnFatalError(Connection, Status, NULL);
1944+
}
1945+
1946+
} else {
1947+
QuicCryptoReset(&Connection->Crypto);
1948+
}
19251949
}
1950+
19261951
_IRQL_requires_max_(PASSIVE_LEVEL)
19271952
QUIC_STATUS
19281953
QuicConnSendResumptionTicket(
@@ -2164,14 +2189,12 @@ QuicConnGenerateLocalTransportParameters(
21642189
LocalTP->AckDelayExponent = Connection->AckDelayExponent;
21652190
}
21662191

2167-
if (Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27) {
2168-
LocalTP->Flags |= QUIC_TP_FLAG_INITIAL_SOURCE_CONNECTION_ID;
2169-
LocalTP->InitialSourceConnectionIDLength = SourceCid->CID.Length;
2170-
QuicCopyMemory(
2171-
LocalTP->InitialSourceConnectionID,
2172-
SourceCid->CID.Data,
2173-
SourceCid->CID.Length);
2174-
}
2192+
LocalTP->Flags |= QUIC_TP_FLAG_INITIAL_SOURCE_CONNECTION_ID;
2193+
LocalTP->InitialSourceConnectionIDLength = SourceCid->CID.Length;
2194+
QuicCopyMemory(
2195+
LocalTP->InitialSourceConnectionID,
2196+
SourceCid->CID.Data,
2197+
SourceCid->CID.Length);
21752198

21762199
if (Connection->Settings.DatagramReceiveEnabled) {
21772200
LocalTP->Flags |= QUIC_TP_FLAG_MAX_DATAGRAM_FRAME_SIZE;
@@ -2227,8 +2250,7 @@ QuicConnGenerateLocalTransportParameters(
22272250
QUIC_FREE(Connection->OrigDestCID, QUIC_POOL_CID);
22282251
Connection->OrigDestCID = NULL;
22292252

2230-
if (Connection->State.HandshakeUsedRetryPacket &&
2231-
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27) {
2253+
if (Connection->State.HandshakeUsedRetryPacket) {
22322254
QUIC_DBG_ASSERT(SourceCid->Link.Next != NULL);
22332255
const QUIC_CID_HASH_ENTRY* PrevSourceCid =
22342256
QUIC_CONTAINING_RECORD(
@@ -2369,68 +2391,6 @@ QuicConnSetConfiguration(
23692391
return Status;
23702392
}
23712393

2372-
BOOLEAN
2373-
QuicConnValidateTransportParameterDraft27CIDs(
2374-
_In_ QUIC_CONNECTION* Connection
2375-
)
2376-
{
2377-
if (Connection->State.HandshakeUsedRetryPacket) {
2378-
QUIC_DBG_ASSERT(!QuicConnIsServer(Connection));
2379-
QUIC_DBG_ASSERT(Connection->OrigDestCID != NULL);
2380-
//
2381-
// If we received a Retry packet during the handshake, we (the client)
2382-
// must validate that the server knew the original connection ID we sent,
2383-
// so that we can be sure that no middle box injected the Retry packet.
2384-
//
2385-
if (!(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_ORIGINAL_DESTINATION_CONNECTION_ID)) {
2386-
QuicTraceEvent(
2387-
ConnError,
2388-
"[conn][%p] ERROR, %s.",
2389-
Connection,
2390-
"Peer didn't provide the original destination CID in TP");
2391-
return FALSE;
2392-
} else if (Connection->PeerTransportParams.OriginalDestinationConnectionIDLength != Connection->OrigDestCID->Length) {
2393-
QuicTraceEvent(
2394-
ConnError,
2395-
"[conn][%p] ERROR, %s.",
2396-
Connection,
2397-
"Peer provided incorrect length of original destination CID in TP");
2398-
return FALSE;
2399-
} else if (
2400-
memcmp(
2401-
Connection->PeerTransportParams.OriginalDestinationConnectionID,
2402-
Connection->OrigDestCID->Data,
2403-
Connection->OrigDestCID->Length) != 0) {
2404-
QuicTraceEvent(
2405-
ConnError,
2406-
"[conn][%p] ERROR, %s.",
2407-
Connection,
2408-
"Peer provided incorrect original destination CID in TP");
2409-
return FALSE;
2410-
} else {
2411-
QUIC_FREE(Connection->OrigDestCID, QUIC_POOL_CID);
2412-
Connection->OrigDestCID = NULL;
2413-
}
2414-
2415-
} else if (!QuicConnIsServer(Connection)) {
2416-
//
2417-
// Per spec, the client must validate no original destination CID TP
2418-
// was sent if no Retry occurred. No need to validate cached values, as
2419-
// they don't apply to the current connection attempt.
2420-
//
2421-
if (!!(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_ORIGINAL_DESTINATION_CONNECTION_ID)) {
2422-
QuicTraceEvent(
2423-
ConnError,
2424-
"[conn][%p] ERROR, %s.",
2425-
Connection,
2426-
"Peer provided the original destination CID in TP when no Retry occurred");
2427-
return FALSE;
2428-
}
2429-
}
2430-
2431-
return TRUE;
2432-
}
2433-
24342394
BOOLEAN
24352395
QuicConnValidateTransportParameterCIDs(
24362396
_In_ QUIC_CONNECTION* Connection
@@ -2556,17 +2516,10 @@ QuicConnProcessPeerTransportParameters(
25562516
}
25572517

25582518
//
2559-
// Version draft-28 and later fully validate all exchanged connection IDs.
2560-
// Version draft-27 only validates in the Retry scenario.
2519+
// Fully validate all exchanged connection IDs.
25612520
//
2562-
if (Connection->Stats.QuicVersion == QUIC_VERSION_DRAFT_27) {
2563-
if (!QuicConnValidateTransportParameterDraft27CIDs(Connection)) {
2564-
goto Error;
2565-
}
2566-
} else {
2567-
if (!QuicConnValidateTransportParameterCIDs(Connection)) {
2568-
goto Error;
2569-
}
2521+
if (!QuicConnValidateTransportParameterCIDs(Connection)) {
2522+
goto Error;
25702523
}
25712524
}
25722525

@@ -2809,16 +2762,20 @@ QuicConnRecvVerNeg(
28092762
"Received Version Negotation:");
28102763
for (uint16_t i = 0; i < ServerVersionListLength; i++) {
28112764

2765+
uint32_t ServerVersion;
2766+
QuicCopyMemory(&ServerVersion, &ServerVersionList[i], sizeof(ServerVersion));
2767+
28122768
QuicTraceLogConnVerbose(
28132769
VerNegItem,
28142770
Connection,
2815-
" Ver[%d]: 0x%x", i,
2816-
QuicByteSwapUint32(ServerVersionList[i]));
2771+
" Ver[%d]: 0x%x",
2772+
i,
2773+
QuicByteSwapUint32(ServerVersion));
28172774

28182775
//
28192776
// Check to see if this is the current version.
28202777
//
2821-
if (ServerVersionList[i] == Connection->Stats.QuicVersion) {
2778+
if (ServerVersion == Connection->Stats.QuicVersion) {
28222779
QuicPacketLogDrop(Connection, Packet, "Version Negotation that includes the current version");
28232780
return;
28242781
}
@@ -2827,9 +2784,8 @@ QuicConnRecvVerNeg(
28272784
// Check to see if this is supported, if we haven't already found a
28282785
// supported version.
28292786
//
2830-
if (SupportedVersion == 0 &&
2831-
QuicIsVersionSupported(ServerVersionList[i])) {
2832-
SupportedVersion = ServerVersionList[i];
2787+
if (SupportedVersion == 0 && QuicIsVersionSupported(ServerVersion)) {
2788+
SupportedVersion = ServerVersion;
28332789
}
28342790
}
28352791

@@ -3203,9 +3159,7 @@ QuicConnRecvHeader(
32033159

32043160
QuicPathSetValid(Connection, Path, QUIC_PATH_VALID_INITIAL_TOKEN);
32053161

3206-
} else if (
3207-
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27 &&
3208-
Connection->OrigDestCID == NULL) {
3162+
} else if (Connection->OrigDestCID == NULL) {
32093163

32103164
Connection->OrigDestCID =
32113165
QUIC_ALLOC_NONPAGED(

src/core/crypto.c

+23-15
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ QuicCryptoInitializeTls(
270270
QUIC_DBG_ASSERT(SecConfig != NULL);
271271
QUIC_DBG_ASSERT(Connection->Configuration != NULL);
272272

273+
Crypto->MaxSentLength = 0;
274+
Crypto->UnAckedOffset = 0;
275+
Crypto->NextSendOffset = 0;
276+
Crypto->RecoveryNextOffset = 0;
277+
Crypto->RecoveryEndOffset = 0;
278+
Crypto->InRecovery = FALSE;
279+
280+
Crypto->TlsState.BufferLength = 0;
281+
Crypto->TlsState.BufferTotalLength = 0;
282+
273283
TlsConfig.IsServer = IsServer;
274284
if (IsServer) {
275285
TlsConfig.AlpnBuffer = Crypto->TlsState.NegotiatedAlpn;
@@ -289,6 +299,10 @@ QuicCryptoInitializeTls(
289299
TlsConfig.ServerName = Connection->RemoteServerName;
290300
}
291301

302+
TlsConfig.TPType =
303+
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_29 ?
304+
TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS :
305+
TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS_DRAFT;
292306
TlsConfig.LocalTPBuffer =
293307
QuicCryptoTlsEncodeTransportParameters(
294308
Connection,
@@ -302,6 +316,11 @@ QuicCryptoInitializeTls(
302316
goto Error;
303317
}
304318

319+
if (Crypto->TLS != NULL) {
320+
QuicTlsUninitialize(Crypto->TLS);
321+
Crypto->TLS = NULL;
322+
}
323+
305324
Status = QuicTlsInitialize(&TlsConfig, &Crypto->TlsState, &Crypto->TLS);
306325
if (QUIC_FAILED(Status)) {
307326
QuicTraceEvent(
@@ -326,8 +345,7 @@ QuicCryptoInitializeTls(
326345
_IRQL_requires_max_(PASSIVE_LEVEL)
327346
void
328347
QuicCryptoReset(
329-
_In_ QUIC_CRYPTO* Crypto,
330-
_In_ BOOLEAN ResetTls
348+
_In_ QUIC_CRYPTO* Crypto
331349
)
332350
{
333351
QUIC_DBG_ASSERT(!QuicConnIsServer(QuicCryptoGetConnection(Crypto)));
@@ -342,19 +360,9 @@ QuicCryptoReset(
342360
Crypto->RecoveryEndOffset = 0;
343361
Crypto->InRecovery = FALSE;
344362

345-
UNREFERENCED_PARAMETER(ResetTls);
346-
/*if (ResetTls) {
347-
Crypto->TlsState.BufferLength = 0;
348-
Crypto->TlsState.BufferTotalLength = 0;
349-
350-
QuicTlsReset(Crypto->TLS);
351-
QuicCryptoProcessData(Crypto, TRUE);
352-
353-
} else*/ {
354-
QuicSendSetSendFlag(
355-
&QuicCryptoGetConnection(Crypto)->Send,
356-
QUIC_CONN_SEND_FLAG_CRYPTO);
357-
}
363+
QuicSendSetSendFlag(
364+
&QuicCryptoGetConnection(Crypto)->Send,
365+
QUIC_CONN_SEND_FLAG_CRYPTO);
358366

359367
QuicCryptoValidate(Crypto);
360368
}

src/core/crypto.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ QuicCryptoInitializeTls(
142142
_IRQL_requires_max_(PASSIVE_LEVEL)
143143
void
144144
QuicCryptoReset(
145-
_In_ QUIC_CRYPTO* Crypto,
146-
_In_ BOOLEAN ResetTls
145+
_In_ QUIC_CRYPTO* Crypto
147146
);
148147

149148
//

src/core/crypto_tls.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ typedef enum eTlsExtensions {
3030
TlsExt_ServerName = 0x00,
3131
TlsExt_AppProtocolNegotiation = 0x10,
3232
TlsExt_SessionTicket = 0x23,
33-
TlsExt_QuicTransportParameters = 0xffa5
3433
} eTlsExtensions;
3534

3635
typedef enum eSniNameType {
@@ -386,7 +385,21 @@ QuicCryptoTlsReadExtensions(
386385
return Status;
387386
}
388387

389-
} else if (ExtType == TlsExt_QuicTransportParameters) {
388+
} else if (
389+
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_29 &&
390+
ExtType == TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS) {
391+
if (!QuicCryptoTlsDecodeTransportParameters(
392+
Connection,
393+
FALSE,
394+
Buffer,
395+
ExtLen,
396+
&Connection->PeerTransportParams)) {
397+
return QUIC_STATUS_INVALID_PARAMETER;
398+
}
399+
FoundTransportParameters = TRUE;
400+
} else if (
401+
Connection->Stats.QuicVersion == QUIC_VERSION_DRAFT_29 &&
402+
ExtType == TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS_DRAFT) {
390403
if (!QuicCryptoTlsDecodeTransportParameters(
391404
Connection,
392405
FALSE,

0 commit comments

Comments
 (0)