Implement QUICv2 in QUICHE.
This CL reflects draft-ietf-quic-v2-01, except for the version negotiation bits -- therefore, the enable flag is blocked by the VN bug.
There are a bunch of changes to line breaks, particularly in quic_framer, that I believe came from the recently updated code checkers. I'm ignoring some new code checks that suggest changes to existing code constructs -- perhaps we should address the defensive coding stuff in another CL.
Protected by FLAGS_quic_reloadable_flag_quic_enable_version_rfcv2.
PiperOrigin-RevId: 424961568
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc
index 50bbfef..05bbdfe 100644
--- a/quic/core/crypto/crypto_utils.cc
+++ b/quic/core/crypto/crypto_utils.cc
@@ -57,8 +57,7 @@
// |out_len|, respectively. The resulting expanded secret is returned.
std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
const std::vector<uint8_t>& secret,
- const std::string& label,
- size_t out_len) {
+ const std::string& label, size_t out_len) {
bssl::ScopedCBB quic_hkdf_label;
CBB inner_label;
const char label_prefix[] = "tls13 ";
@@ -91,13 +90,23 @@
} // namespace
+const std::string getLabelForVersion(const ParsedQuicVersion& version,
+ const absl::string_view& predicate) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync with HKDF labels");
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ return absl::StrCat("quicv2 ", predicate);
+ } else {
+ return absl::StrCat("quic ", predicate);
+ }
+}
+
void CryptoUtils::InitializeCrypterSecrets(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- QuicCrypter* crypter) {
- SetKeyAndIV(prf, pp_secret, crypter);
- std::vector<uint8_t> header_protection_key =
- GenerateHeaderProtectionKey(prf, pp_secret, crypter->GetKeySize());
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, QuicCrypter* crypter) {
+ SetKeyAndIV(prf, pp_secret, version, crypter);
+ std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
+ prf, pp_secret, version, crypter->GetKeySize());
crypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -105,11 +114,13 @@
void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter) {
std::vector<uint8_t> key =
- HkdfExpandLabel(prf, pp_secret, "quic key", crypter->GetKeySize());
- std::vector<uint8_t> iv =
- HkdfExpandLabel(prf, pp_secret, "quic iv", crypter->GetIVSize());
+ HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
+ crypter->GetKeySize());
+ std::vector<uint8_t> iv = HkdfExpandLabel(
+ prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
crypter->SetKey(
absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
crypter->SetIV(
@@ -117,16 +128,17 @@
}
std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- size_t out_len) {
- return HkdfExpandLabel(prf, pp_secret, "quic hp", out_len);
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, size_t out_len) {
+ return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
+ out_len);
}
std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
- const EVP_MD* prf,
+ const EVP_MD* prf, const ParsedQuicVersion& version,
const std::vector<uint8_t>& current_secret) {
- return HkdfExpandLabel(prf, current_secret, "quic ku", current_secret.size());
+ return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
+ current_secret.size());
}
namespace {
@@ -138,6 +150,9 @@
const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
+const uint8_t kV2Draft01InitialSalt[] = {
+ 0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
+ 0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
// Salts used by deployed versions of QUIC. When introducing a new version,
// generate a new salt by running `openssl rand -hex 20`.
@@ -154,9 +169,12 @@
const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
size_t* out_len) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync with initial encryption salts");
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
+ return kV2Draft01InitialSalt;
+ } else if (version == ParsedQuicVersion::RFCv1()) {
*out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
return kRFCv1InitialSalt;
} else if (version == ParsedQuicVersion::Draft29()) {
@@ -191,6 +209,11 @@
0xe3, 0x68, 0xc8, 0x4e};
const uint8_t kRFCv1RetryIntegrityNonce[] = {
0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
+const uint8_t kV2Draft01RetryIntegrityKey[] = {
+ 0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
+ 0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
+const uint8_t kV2Draft01RetryIntegrityNonce[] = {
+ 0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
@@ -204,13 +227,21 @@
bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
absl::string_view* key,
absl::string_view* nonce) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync with retry integrity keys");
if (!version.UsesTls()) {
QUIC_BUG(quic_bug_10699_2)
<< "Attempted to get retry integrity keys for invalid version "
<< version;
return false;
+ } else if (version == ParsedQuicVersion::V2Draft01()) {
+ *key = absl::string_view(
+ reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
+ ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
+ *nonce = absl::string_view(
+ reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
+ ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
+ return true;
} else if (version == ParsedQuicVersion::RFCv1()) {
*key = absl::string_view(
reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
@@ -291,20 +322,20 @@
std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
hash, handshake_secret, encryption_label, EVP_MD_size(hash));
crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
- InitializeCrypterSecrets(hash, encryption_secret, crypters->encrypter.get());
+ InitializeCrypterSecrets(hash, encryption_secret, version,
+ crypters->encrypter.get());
std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
hash, handshake_secret, decryption_label, EVP_MD_size(hash));
crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
- InitializeCrypterSecrets(hash, decryption_secret, crypters->decrypter.get());
+ InitializeCrypterSecrets(hash, decryption_secret, version,
+ crypters->decrypter.get());
}
// static
bool CryptoUtils::ValidateRetryIntegrityTag(
- ParsedQuicVersion version,
- QuicConnectionId original_connection_id,
- absl::string_view retry_without_tag,
- absl::string_view integrity_tag) {
+ ParsedQuicVersion version, QuicConnectionId original_connection_id,
+ absl::string_view retry_without_tag, absl::string_view integrity_tag) {
unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
QUIC_BUG(quic_bug_10699_4)
@@ -348,10 +379,8 @@
}
// static
-void CryptoUtils::GenerateNonce(QuicWallTime now,
- QuicRandom* random_generator,
- absl::string_view orbit,
- std::string* nonce) {
+void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+ absl::string_view orbit, std::string* nonce) {
// a 4-byte timestamp + 28 random bytes.
nonce->reserve(kNonceSize);
nonce->resize(kNonceSize);
@@ -375,17 +404,13 @@
}
// static
-bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version,
- absl::string_view premaster_secret,
- QuicTag aead,
- absl::string_view client_nonce,
- absl::string_view server_nonce,
- absl::string_view pre_shared_key,
- const std::string& hkdf_input,
- Perspective perspective,
- Diversification diversification,
- CrypterPair* crypters,
- std::string* subkey_secret) {
+bool CryptoUtils::DeriveKeys(
+ const ParsedQuicVersion& version, absl::string_view premaster_secret,
+ QuicTag aead, absl::string_view client_nonce,
+ absl::string_view server_nonce, absl::string_view pre_shared_key,
+ const std::string& hkdf_input, Perspective perspective,
+ Diversification diversification, CrypterPair* crypters,
+ std::string* subkey_secret) {
// If the connection is using PSK, concatenate it with the pre-master secret.
std::unique_ptr<char[]> psk_premaster_secret;
if (!pre_shared_key.empty()) {
@@ -573,8 +598,7 @@
}
QuicErrorCode CryptoUtils::ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- ParsedQuicVersion version,
+ const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) {
if (client_hello.tag() != kCHLO) {
@@ -597,8 +621,7 @@
}
QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
- QuicVersionLabel client_version,
- ParsedQuicVersion connection_version,
+ QuicVersionLabel client_version, ParsedQuicVersion connection_version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) {
if (client_version != CreateQuicVersionLabel(connection_version)) {
@@ -736,8 +759,7 @@
// static
std::string CryptoUtils::HashHandshakeMessage(
- const CryptoHandshakeMessage& message,
- Perspective /*perspective*/) {
+ const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
std::string output;
const QuicData& serialized = message.GetSerialized();
uint8_t digest[SHA256_DIGEST_LENGTH];
diff --git a/quic/core/crypto/crypto_utils.h b/quic/core/crypto/crypto_utils.h
index 8884f6f..fce6201 100644
--- a/quic/core/crypto/crypto_utils.h
+++ b/quic/core/crypto/crypto_utils.h
@@ -79,9 +79,11 @@
// on the given QuicCrypter |*crypter|.
// This follows the derivation described in section 7.3 of RFC 8446, except
// with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
- // as described in draft-ietf-quic-tls-14, section 5.1.
+ // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
+ // described in draft-ietf-quic-v2-01.
static void InitializeCrypterSecrets(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter);
// Derives the key and IV from the packet protection secret and sets those
@@ -90,17 +92,17 @@
// called before using |crypter|.
static void SetKeyAndIV(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter);
// Derives the header protection key from the packet protection secret.
static std::vector<uint8_t> GenerateHeaderProtectionKey(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- size_t out_len);
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, size_t out_len);
// Given a secret for key phase n, return the secret for phase n+1.
static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
- const EVP_MD* prf,
+ const EVP_MD* prf, const ParsedQuicVersion& version,
const std::vector<uint8_t>& current_secret);
// IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
@@ -130,10 +132,8 @@
// <4 bytes> current time
// <8 bytes> |orbit| (or random if |orbit| is empty)
// <20 bytes> random
- static void GenerateNonce(QuicWallTime now,
- QuicRandom* random_generator,
- absl::string_view orbit,
- std::string* nonce);
+ static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+ absl::string_view orbit, std::string* nonce);
// DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
// |subkey_secret| (optional -- may be null) given the contents of
@@ -155,15 +155,12 @@
// |SetDiversificationNonce| with a diversification nonce will be needed to
// complete keying.
static bool DeriveKeys(const ParsedQuicVersion& version,
- absl::string_view premaster_secret,
- QuicTag aead,
+ absl::string_view premaster_secret, QuicTag aead,
absl::string_view client_nonce,
absl::string_view server_nonce,
absl::string_view pre_shared_key,
- const std::string& hkdf_input,
- Perspective perspective,
- Diversification diversification,
- CrypterPair* crypters,
+ const std::string& hkdf_input, Perspective perspective,
+ Diversification diversification, CrypterPair* crypters,
std::string* subkey_secret);
// Computes the FNV-1a hash of the provided DER-encoded cert for use in the
@@ -199,8 +196,7 @@
// Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
// code and sets |error_details|.
static QuicErrorCode ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- ParsedQuicVersion version,
+ const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details);
@@ -212,8 +208,7 @@
// Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
// code and sets |error_details|.
static QuicErrorCode ValidateClientHelloVersion(
- QuicVersionLabel client_version,
- ParsedQuicVersion connection_version,
+ QuicVersionLabel client_version, ParsedQuicVersion connection_version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details);
diff --git a/quic/core/crypto/crypto_utils_test.cc b/quic/core/crypto/crypto_utils_test.cc
index 251f136..df1546a 100644
--- a/quic/core/crypto/crypto_utils_test.cc
+++ b/quic/core/crypto/crypto_utils_test.cc
@@ -8,6 +8,7 @@
#include "absl/base/macros.h"
#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/quic_test_utils.h"
@@ -165,6 +166,48 @@
EXPECT_FALSE(error_details.empty());
}
+// Test that the library is using the correct labels for each version, and
+// therefore generating correct obfuscators, using the test vectors in appendix
+// A of each RFC or internet-draft.
+TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
+ // if the number of HTTP/3 QUIC versions has changed, we need to change the
+ // expected_keys hardcoded into this test. Regrettably, this is not a
+ // compile-time constant.
+ EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
+ const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
+ 0x14, 0x9d, 0x0b, 0x16, 0x62, 0xab, 0x87, 0x1f,
+ 0xbe, 0x63, 0xc4, 0x9b, 0x5e, 0x65, 0x5a, 0x5d};
+ const char v1_key[] = {// test vector from RFC 9001, A.1
+ 0xcf, 0x3a, 0x53, 0x31, 0x65, 0x3c, 0x36, 0x4c,
+ 0x88, 0xf0, 0xf3, 0x79, 0xb6, 0x06, 0x7e, 0x37};
+ const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
+ 0x15, 0xd5, 0xb4, 0xd9, 0xa2, 0xb8, 0x91, 0x6a,
+ 0xa3, 0x9b, 0x1b, 0xfe, 0x57, 0x4d, 0x2a, 0xad};
+ const char connection_id[] = // test vector from both docs
+ {0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08};
+ const QuicConnectionId cid(connection_id, sizeof(connection_id));
+ const char* key_str;
+ size_t key_size;
+ for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+ if (version == ParsedQuicVersion::Draft29()) {
+ key_str = draft_29_key;
+ key_size = sizeof(draft_29_key);
+ } else if (version == ParsedQuicVersion::RFCv1()) {
+ key_str = v1_key;
+ key_size = sizeof(v1_key);
+ } else { // draft-ietf-quic-v2-01
+ key_str = v2_01_key;
+ key_size = sizeof(v2_01_key);
+ }
+ const absl::string_view expected_key{key_str, key_size};
+
+ CrypterPair crypters;
+ CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
+ &crypters);
+ EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
+ }
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/core/handshaker_delegate_interface.h b/quic/core/handshaker_delegate_interface.h
index 1e47d16..7fbc5ae 100644
--- a/quic/core/handshaker_delegate_interface.h
+++ b/quic/core/handshaker_delegate_interface.h
@@ -7,6 +7,7 @@
#include "quic/core/crypto/transport_parameters.h"
#include "quic/core/quic_types.h"
+#include "quic/core/quic_versions.h"
namespace quic {
@@ -21,15 +22,12 @@
// Called when new decryption key of |level| is available. Returns true if
// decrypter is set successfully, otherwise, returns false.
virtual bool OnNewDecryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool set_alternative_decrypter,
- bool latch_once_used) = 0;
+ EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+ bool set_alternative_decrypter, bool latch_once_used) = 0;
// Called when new encryption key of |level| is available.
virtual void OnNewEncryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) = 0;
+ EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
// Called to set default encryption level to |level|. Only used in QUIC
// crypto.
@@ -68,8 +66,7 @@
// On failure, returns a QuicErrorCode and saves a detailed error in
// |error_details|.
virtual QuicErrorCode ProcessTransportParameters(
- const TransportParameters& params,
- bool is_resumption,
+ const TransportParameters& params, bool is_resumption,
std::string* error_details) = 0;
// Called at the end of an handshake operation callback.
@@ -77,6 +74,10 @@
// Whether a packet flusher is currently attached.
virtual bool PacketFlusherAttached() const = 0;
+
+ // Get the QUIC version currently in use. tls_handshaker needs this to pass
+ // to crypto_utils to apply version-dependent HKDF labels.
+ virtual ParsedQuicVersion parsed_version() const = 0;
};
} // namespace quic
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index aa1ef09..cf84969 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -485,8 +485,7 @@
}
}
- void AddToCache(absl::string_view path,
- int response_code,
+ void AddToCache(absl::string_view path, int response_code,
absl::string_view body) {
memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
response_code, body);
@@ -657,16 +656,14 @@
}
bool SendSynchronousRequestAndCheckResponse(
- QuicTestClient* client,
- const std::string& request,
+ QuicTestClient* client, const std::string& request,
const std::string& expected_response) {
std::string received_response = client->SendSynchronousRequest(request);
return CheckResponse(client, received_response, expected_response);
}
bool SendSynchronousRequestAndCheckResponse(
- const std::string& request,
- const std::string& expected_response) {
+ const std::string& request, const std::string& expected_response) {
return SendSynchronousRequestAndCheckResponse(client_.get(), request,
expected_response);
}
@@ -844,8 +841,7 @@
};
// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(EndToEndTests,
- EndToEndTest,
+INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
::testing::ValuesIn(GetTestParams()),
::testing::PrintToStringParamName());
@@ -3210,8 +3206,7 @@
class DuplicatePacketWithSpoofedSelfAddressWriter
: public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -4385,13 +4380,10 @@
class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
public:
ServerStreamWithErrorResponseBody(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend,
std::string response_body)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
response_body_(std::move(response_body)) {}
@@ -4420,8 +4412,7 @@
~StreamWithErrorFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamWithErrorResponseBody(
id, session, quic_simple_server_backend, response_body_);
@@ -4434,12 +4425,9 @@
// A test server stream that drops all received body.
class ServerStreamThatDropsBody : public QuicSimpleServerStream {
public:
- ServerStreamThatDropsBody(QuicStreamId id,
- QuicSpdySession* session,
+ ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend) {}
~ServerStreamThatDropsBody() override = default;
@@ -4481,8 +4469,7 @@
~ServerStreamThatDropsBodyFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatDropsBody(id, session,
quic_simple_server_backend);
@@ -4493,13 +4480,9 @@
class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
public:
ServerStreamThatSendsHugeResponse(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend,
- int64_t body_bytes)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ QuicStreamId id, QuicSpdySession* session,
+ QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
body_bytes_(body_bytes) {}
@@ -4529,8 +4512,7 @@
~ServerStreamThatSendsHugeResponseFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatSendsHugeResponse(
id, session, quic_simple_server_backend, body_bytes_);
@@ -5255,8 +5237,7 @@
// called.
class PacketHoldingWriter : public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -5710,8 +5691,7 @@
: error_returned_(false), version_(version) {}
~BadShloPacketWriter() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
@@ -5728,6 +5708,9 @@
}
bool TypeByteIsServerHello(uint8_t type_byte) {
+ if (version_.UsesV2PacketTypes()) {
+ return ((type_byte & 0x30) >> 4) == 3;
+ }
if (version_.UsesQuicCrypto()) {
// ENCRYPTION_ZERO_RTT packet.
return ((type_byte & 0x30) >> 4) == 1;
@@ -5784,21 +5767,23 @@
class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
public:
- BadShloPacketWriter2() : error_returned_(false) {}
+ BadShloPacketWriter2(ParsedQuicVersion version)
+ : error_returned_(false), version_(version) {}
~BadShloPacketWriter2() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
const uint8_t type_byte = buffer[0];
- if ((type_byte & FLAGS_LONG_HEADER) &&
- (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
- QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
+
+ if (type_byte & FLAGS_LONG_HEADER) {
+ if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
+ ((type_byte & 0x7F) == 0x7C)) {
+ QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+ return WriteResult(WRITE_STATUS_OK, buf_len);
+ }
+ } else if (!error_returned_) {
QUIC_DVLOG(1) << "Return write error for short header packet";
error_returned_ = true;
return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
@@ -5809,6 +5794,7 @@
private:
bool error_returned_;
+ ParsedQuicVersion version_;
};
TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
@@ -5839,7 +5825,7 @@
dispatcher,
// This causes the all server sent ZERO_RTT_PROTECTED packets to be
// dropped, and first short header packet causes write error.
- new BadShloPacketWriter2());
+ new BadShloPacketWriter2(version_));
server_thread_->Resume();
client_.reset(CreateQuicClient(client_writer_));
EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
@@ -6028,8 +6014,7 @@
public:
explicit CopyingPacketWriter(int num_packets_to_copy)
: num_packets_to_copy_(num_packets_to_copy) {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 393bfd8..053849f 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -184,19 +184,12 @@
TestConnection(QuicConnectionId connection_id,
QuicSocketAddress initial_self_address,
QuicSocketAddress initial_peer_address,
- TestConnectionHelper* helper,
- TestAlarmFactory* alarm_factory,
- TestPacketWriter* writer,
- Perspective perspective,
+ TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
+ TestPacketWriter* writer, Perspective perspective,
ParsedQuicVersion version)
- : QuicConnection(connection_id,
- initial_self_address,
- initial_peer_address,
- helper,
- alarm_factory,
- writer,
- /* owns_writer= */ false,
- perspective,
+ : QuicConnection(connection_id, initial_self_address,
+ initial_peer_address, helper, alarm_factory, writer,
+ /* owns_writer= */ false, perspective,
SupportedVersions(version)),
notifier_(nullptr) {
writer->set_perspective(perspective);
@@ -215,11 +208,9 @@
QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
}
- void SendPacket(EncryptionLevel /*level*/,
- uint64_t packet_number,
+ void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
std::unique_ptr<QuicPacket> packet,
- HasRetransmittableData retransmittable,
- bool has_ack,
+ HasRetransmittableData retransmittable, bool has_ack,
bool has_pending_frames) {
ScopedPacketFlusher flusher(this);
char buffer[kMaxOutgoingPacketSize];
@@ -239,8 +230,7 @@
}
QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
+ const struct iovec* iov, int iov_count,
size_t total_length,
QuicStreamOffset offset,
StreamSendingState state) {
@@ -555,8 +545,7 @@
// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
struct TestParams {
- TestParams(ParsedQuicVersion version,
- AckResponse ack_response,
+ TestParams(ParsedQuicVersion version, AckResponse ack_response,
bool no_stop_waiting)
: version(version),
ack_response(ack_response),
@@ -609,30 +598,20 @@
protected:
QuicConnectionTest()
: connection_id_(TestConnectionId()),
- framer_(SupportedVersions(version()),
- QuicTime::Zero(),
- Perspective::IS_CLIENT,
- connection_id_.length()),
+ framer_(SupportedVersions(version()), QuicTime::Zero(),
+ Perspective::IS_CLIENT, connection_id_.length()),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
alarm_factory_(new TestAlarmFactory()),
- peer_framer_(SupportedVersions(version()),
- QuicTime::Zero(),
- Perspective::IS_SERVER,
- connection_id_.length()),
- peer_creator_(connection_id_,
- &peer_framer_,
+ peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
+ Perspective::IS_SERVER, connection_id_.length()),
+ peer_creator_(connection_id_, &peer_framer_,
/*delegate=*/nullptr),
writer_(
new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
- connection_(connection_id_,
- kSelfAddress,
- kPeerAddress,
- helper_.get(),
- alarm_factory_.get(),
- writer_.get(),
- Perspective::IS_CLIENT,
+ connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
+ alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
version()),
creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
@@ -872,16 +851,14 @@
QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
}
- size_t ProcessFramePacketAtLevel(uint64_t number,
- QuicFrame frame,
+ size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
EncryptionLevel level) {
QuicFrames frames;
frames.push_back(frame);
return ProcessFramesPacketAtLevel(number, frames, level);
}
- size_t ProcessFramesPacketAtLevel(uint64_t number,
- const QuicFrames& frames,
+ size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
EncryptionLevel level) {
QuicPacketHeader header = ConstructPacketHeader(number, level);
// Set the correct encryption level and encrypter on peer_creator and
@@ -1025,8 +1002,7 @@
return encrypted_length;
}
- size_t ProcessDataPacketAtLevel(uint64_t number,
- bool has_stop_waiting,
+ size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
EncryptionLevel level) {
std::unique_ptr<QuicPacket> packet(
ConstructDataPacket(number, has_stop_waiting, level));
@@ -1055,8 +1031,7 @@
QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
}
- QuicByteCount SendStreamDataToPeer(QuicStreamId id,
- absl::string_view data,
+ QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
QuicStreamOffset offset,
StreamSendingState state,
QuicPacketNumber* last_packet) {
@@ -1084,8 +1059,7 @@
.Times(AnyNumber());
}
- void SendRstStream(QuicStreamId id,
- QuicRstStreamErrorCode error,
+ void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written) {
notifier_.WriteOrBufferRstStream(id, error, bytes_written);
connection_.OnStreamReset(id, error);
@@ -10499,7 +10473,12 @@
return;
}
- // These values come from draft-ietf-quic-tls Appendix A.4.
+ // These values come from draft-ietf-quic-v2 Appendix A.4.
+ uint8_t retry_packet_rfcv2[] = {
+ 0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+ 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
+ 0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
+ // These values come from RFC9001 Appendix A.4.
uint8_t retry_packet_rfcv1[] = {
0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
@@ -10511,7 +10490,10 @@
uint8_t* retry_packet;
size_t retry_packet_length;
- if (version() == ParsedQuicVersion::RFCv1()) {
+ if (version() == ParsedQuicVersion::V2Draft01()) {
+ retry_packet = retry_packet_rfcv2;
+ retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
+ } else if (version() == ParsedQuicVersion::RFCv1()) {
retry_packet = retry_packet_rfcv1;
retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
} else if (version() == ParsedQuicVersion::Draft29()) {
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index ca4ae48..add5164 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -1521,7 +1521,7 @@
dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
}
-static_assert(quic::SupportedVersions().size() == 5u,
+static_assert(quic::SupportedVersions().size() == 6u,
"Please add new RejectDeprecatedVersion tests above this assert "
"when deprecating versions");
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 7482050..90e3fbd 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -135,6 +135,8 @@
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pacing_sender_bursts, false)
// When true, set the initial congestion control window from connection options in QuicSentPacketManager rather than TcpCubicSenderBytes.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, true)
+// When true, support draft-ietf-quic-v2-01
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_version_2_draft_01, false)
// When true, the B203 connection option causes the Bbr2Sender to ignore inflight_hi during PROBE_UP and increase it when the bytes delivered without loss are higher.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_ignore_inflight_hi_in_probe_up, true)
// When true, the B205 connection option enables extra acked in STARTUP, and B204 adds new logic to decrease it whenever max bandwidth increases.
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 79ace5a..6d2d9c7 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -170,8 +170,7 @@
}
}
-QuicPacketNumberLength ReadAckPacketNumberLength(
- uint8_t flags) {
+QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
case PACKET_FLAGS_8BYTE_PACKET:
return PACKET_6BYTE_PACKET_NUMBER;
@@ -197,16 +196,17 @@
return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
}
-uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type) {
+uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
+ const ParsedQuicVersion& version) {
switch (type) {
case INITIAL:
- return 0;
+ return version.UsesV2PacketTypes() ? (1 << 4) : 0;
case ZERO_RTT_PROTECTED:
- return 1 << 4;
+ return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
case HANDSHAKE:
- return 2 << 4;
+ return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
case RETRY:
- return 3 << 4;
+ return version.UsesV2PacketTypes() ? 0 : (3 << 4);
case VERSION_NEGOTIATION:
return 0xF0; // Value does not matter
default:
@@ -215,20 +215,23 @@
}
}
-bool GetLongHeaderType(uint8_t type, QuicLongHeaderType* long_header_type) {
+bool GetLongHeaderType(uint8_t type, const ParsedQuicVersion& version,
+ QuicLongHeaderType* long_header_type) {
QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
switch ((type & 0x30) >> 4) {
case 0:
- *long_header_type = INITIAL;
+ *long_header_type = version.UsesV2PacketTypes() ? RETRY : INITIAL;
break;
case 1:
- *long_header_type = ZERO_RTT_PROTECTED;
+ *long_header_type =
+ version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
break;
case 2:
- *long_header_type = HANDSHAKE;
+ *long_header_type =
+ version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
break;
case 3:
- *long_header_type = RETRY;
+ *long_header_type = version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
break;
default:
QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
@@ -331,8 +334,7 @@
return full_packet_number > 0 || version.HasIetfQuicFrames();
}
-bool AppendIetfConnectionIds(bool version_flag,
- bool use_length_prefix,
+bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
QuicConnectionId destination_connection_id,
QuicConnectionId source_connection_id,
QuicDataWriter* writer) {
@@ -533,8 +535,7 @@
// static
size_t QuicFramer::GetConnectionCloseFrameSize(
- QuicTransportVersion version,
- const QuicConnectionCloseFrame& frame) {
+ QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
// Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
return kQuicFrameTypeSize + kQuicErrorCodeSize +
@@ -569,8 +570,7 @@
// static
size_t QuicFramer::GetWindowUpdateFrameSize(
- QuicTransportVersion version,
- const QuicWindowUpdateFrame& frame) {
+ QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
}
@@ -599,8 +599,7 @@
// static
size_t QuicFramer::GetStreamsBlockedFrameSize(
- QuicTransportVersion version,
- const QuicStreamsBlockedFrame& frame) {
+ QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
QUIC_BUG(quic_bug_10850_10)
<< "In version " << version
@@ -658,8 +657,7 @@
// static
size_t QuicFramer::GetRetransmittableControlFrameSize(
- QuicTransportVersion version,
- const QuicFrame& frame) {
+ QuicTransportVersion version, const QuicFrame& frame) {
switch (frame.type) {
case PING_FRAME:
// Ping has no payload.
@@ -793,11 +791,8 @@
}
size_t QuicFramer::GetSerializedFrameLength(
- const QuicFrame& frame,
- size_t free_bytes,
- bool first_frame,
- bool last_frame,
- QuicPacketNumberLength packet_number_length) {
+ const QuicFrame& frame, size_t free_bytes, bool first_frame,
+ bool last_frame, QuicPacketNumberLength packet_number_length) {
// Prevent a rare crash reported in b/19458523.
if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
QUIC_BUG(quic_bug_10850_13)
@@ -887,8 +882,7 @@
}
size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- char* buffer,
+ const QuicFrames& frames, char* buffer,
size_t packet_length,
EncryptionLevel level) {
QUIC_BUG_IF(quic_bug_12975_2,
@@ -1345,10 +1339,8 @@
// static
std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool use_length_prefix,
- const ParsedQuicVersionVector& versions) {
+ QuicConnectionId client_connection_id, bool ietf_quic,
+ bool use_length_prefix, const ParsedQuicVersionVector& versions) {
QUIC_CODE_COUNT(quic_build_version_negotiation);
if (use_length_prefix) {
QUICHE_DCHECK(ietf_quic);
@@ -1420,8 +1412,7 @@
// static
std::unique_ptr<QuicEncryptedPacket>
QuicFramer::BuildIetfVersionNegotiationPacket(
- bool use_length_prefix,
- QuicConnectionId server_connection_id,
+ bool use_length_prefix, QuicConnectionId server_connection_id,
QuicConnectionId client_connection_id,
const ParsedQuicVersionVector& versions) {
QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
@@ -1566,8 +1557,7 @@
}
bool QuicFramer::ProcessVersionNegotiationPacket(
- QuicDataReader* reader,
- const QuicPacketHeader& header) {
+ QuicDataReader* reader, const QuicPacketHeader& header) {
QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
QuicVersionNegotiationPacket packet(
@@ -1667,8 +1657,7 @@
// If the IETF length field only spans part of the outer packet,
// then there is a coalesced packet after this one.
void QuicFramer::MaybeProcessCoalescedPacket(
- const QuicDataReader& encrypted_reader,
- uint64_t remaining_bytes_length,
+ const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
const QuicPacketHeader& header) {
if (header.remaining_packet_length >= remaining_bytes_length) {
// There is no coalesced packet.
@@ -2221,7 +2210,7 @@
if (header.version_flag) {
type = static_cast<uint8_t>(
FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
- LongHeaderTypeToOnWireValue(header.long_packet_type) |
+ LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
PacketNumberLengthToOnWireValue(header.packet_number_length));
} else {
type = static_cast<uint8_t>(
@@ -2357,8 +2346,7 @@
uint64_t QuicFramer::CalculatePacketNumberFromWire(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t packet_number) const {
+ QuicPacketNumber base_packet_number, uint64_t packet_number) const {
// The new packet number might have wrapped to the next epoch, or
// it might have reverse wrapped to the previous epoch, or it might
// remain in the same epoch. Select the packet number closest to the
@@ -2632,7 +2620,8 @@
set_detailed_error("Fixed bit is 0 in long header.");
return false;
}
- if (!GetLongHeaderType(type, &header->long_packet_type)) {
+ if (!GetLongHeaderType(type, header->version,
+ &header->long_packet_type)) {
set_detailed_error("Illegal long header type value.");
return false;
}
@@ -2690,14 +2679,11 @@
// static
bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader,
- ParsedQuicVersion version,
- Perspective perspective,
+ QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
bool should_update_expected_server_connection_id_length,
uint8_t* expected_server_connection_id_length,
uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length,
- std::string* detailed_error) {
+ uint8_t* source_connection_id_length, std::string* detailed_error) {
uint8_t connection_id_lengths_byte;
if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
*detailed_error = "Unable to read ConnectionId length.";
@@ -2880,10 +2866,8 @@
}
bool QuicFramer::ProcessAndCalculatePacketNumber(
- QuicDataReader* reader,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t* packet_number) {
+ QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
+ QuicPacketNumber base_packet_number, uint64_t* packet_number) {
uint64_t wire_packet_number;
if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
return false;
@@ -3131,8 +3115,7 @@
// static
bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
- uint64_t frame_type,
- EncryptionLevel level) {
+ uint64_t frame_type, EncryptionLevel level) {
switch (level) {
case ENCRYPTION_INITIAL:
case ENCRYPTION_HANDSHAKE:
@@ -3560,8 +3543,7 @@
}
} // namespace
-bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader,
- uint8_t frame_type,
+bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
QuicStreamFrame* frame) {
uint8_t stream_flags = frame_type;
@@ -3748,12 +3730,12 @@
// Determine the two lengths from the frame type: largest acked length,
// ack block length.
- const QuicPacketNumberLength ack_block_length = ReadAckPacketNumberLength(
- ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
- kActBlockLengthOffset));
- const QuicPacketNumberLength largest_acked_length = ReadAckPacketNumberLength(
- ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
- kLargestAckedOffset));
+ const QuicPacketNumberLength ack_block_length =
+ ReadAckPacketNumberLength(ExtractBits(
+ frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
+ const QuicPacketNumberLength largest_acked_length =
+ ReadAckPacketNumberLength(ExtractBits(
+ frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
uint64_t largest_acked;
if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
@@ -4364,11 +4346,9 @@
// static
absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
- QuicTransportVersion version,
- const QuicEncryptedPacket& encrypted,
+ QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool includes_version,
+ QuicConnectionIdLength source_connection_id_length, bool includes_version,
bool includes_diversification_nonce,
QuicPacketNumberLength packet_number_length,
QuicVariableLengthIntegerLength retry_token_length_length,
@@ -4397,8 +4377,7 @@
}
void QuicFramer::SetAlternativeDecrypter(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
+ EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used) {
QUICHE_DCHECK_NE(level, decrypter_level_);
QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
@@ -4523,10 +4502,8 @@
}
size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
- QuicPacketNumber packet_number,
- size_t ad_len,
- size_t total_len,
- size_t buffer_len,
+ QuicPacketNumber packet_number, size_t ad_len,
+ size_t total_len, size_t buffer_len,
char* buffer) {
QUICHE_DCHECK(packet_number.IsInitialized());
if (encrypter_[level] == nullptr) {
@@ -4568,10 +4545,8 @@
} // namespace
-bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level,
- char* buffer,
- size_t buffer_len,
- size_t ad_len) {
+bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
+ size_t buffer_len, size_t ad_len) {
QuicDataReader buffer_reader(buffer, buffer_len);
QuicDataWriter buffer_writer(buffer_len, buffer);
// The sample starts 4 bytes after the start of the packet number.
@@ -4615,7 +4590,7 @@
QuicLongHeaderType header_type;
if (IsLongHeader(type_byte)) {
bitmask = 0x0f;
- if (!GetLongHeaderType(type_byte, &header_type)) {
+ if (!GetLongHeaderType(type_byte, version_, &header_type)) {
return false;
}
}
@@ -4781,8 +4756,7 @@
size_t QuicFramer::EncryptPayload(EncryptionLevel level,
QuicPacketNumber packet_number,
- const QuicPacket& packet,
- char* buffer,
+ const QuicPacket& packet, char* buffer,
size_t buffer_len) {
QUICHE_DCHECK(packet_number.IsInitialized());
if (encrypter_[level] == nullptr) {
@@ -4867,8 +4841,7 @@
absl::string_view encrypted,
absl::string_view associated_data,
const QuicPacketHeader& header,
- char* decrypted_buffer,
- size_t buffer_length,
+ char* decrypted_buffer, size_t buffer_length,
size_t* decrypted_length,
EncryptionLevel* decrypted_level) {
if (!EncryptionLevelIsValid(decrypter_level_)) {
@@ -5100,8 +5073,7 @@
}
size_t QuicFramer::GetAckFrameSize(
- const QuicAckFrame& ack,
- QuicPacketNumberLength /*packet_number_length*/) {
+ const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
QUICHE_DCHECK(!ack.packets.Empty());
size_t ack_size = 0;
@@ -5141,8 +5113,7 @@
}
size_t QuicFramer::ComputeFrameLength(
- const QuicFrame& frame,
- bool last_frame_in_packet,
+ const QuicFrame& frame, bool last_frame_in_packet,
QuicPacketNumberLength packet_number_length) {
switch (frame.type) {
case STREAM_FRAME:
@@ -5370,8 +5341,7 @@
}
// static
-bool QuicFramer::AppendStreamId(size_t stream_id_length,
- QuicStreamId stream_id,
+bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
QuicDataWriter* writer) {
if (stream_id_length == 0 || stream_id_length > 4) {
QUIC_BUG(quic_bug_10850_77)
@@ -5397,8 +5367,7 @@
// static
bool QuicFramer::AppendAckBlock(uint8_t gap,
QuicPacketNumberLength length_length,
- uint64_t length,
- QuicDataWriter* writer) {
+ uint64_t length, QuicDataWriter* writer) {
if (length == 0) {
if (!IsValidPacketNumberLength(length_length)) {
QUIC_BUG(quic_bug_10850_79)
@@ -5976,8 +5945,7 @@
}
bool QuicFramer::AppendConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer) {
+ const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
if (VersionHasIetfQuicFrames(version_.transport_version)) {
return AppendIetfConnectionCloseFrame(frame, writer);
}
@@ -6084,8 +6052,7 @@
}
bool QuicFramer::IsVersionNegotiation(
- const QuicPacketHeader& header,
- bool packet_has_ietf_packet_header) const {
+ const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
if (!packet_has_ietf_packet_header &&
perspective_ == Perspective::IS_CLIENT) {
return header.version_flag;
@@ -6097,8 +6064,7 @@
}
bool QuicFramer::AppendIetfConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer) {
+ const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
QUIC_BUG(quic_bug_10850_90)
@@ -6135,8 +6101,7 @@
}
bool QuicFramer::ProcessIetfConnectionCloseFrame(
- QuicDataReader* reader,
- QuicConnectionCloseType type,
+ QuicDataReader* reader, QuicConnectionCloseType type,
QuicConnectionCloseFrame* frame) {
frame->close_type = type;
@@ -6263,8 +6228,7 @@
}
bool QuicFramer::ProcessStopSendingFrame(
- QuicDataReader* reader,
- QuicStopSendingFrame* stop_sending_frame) {
+ QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
&stop_sending_frame->stream_id)) {
return false;
@@ -6281,8 +6245,7 @@
}
bool QuicFramer::AppendStopSendingFrame(
- const QuicStopSendingFrame& stop_sending_frame,
- QuicDataWriter* writer) {
+ const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
set_detailed_error("Can not write stop sending stream id");
return false;
@@ -6438,8 +6401,7 @@
}
bool QuicFramer::AppendNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& frame,
- QuicDataWriter* writer) {
+ const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(frame.sequence_number)) {
set_detailed_error("Can not write New Connection ID sequence number");
return false;
@@ -6500,8 +6462,7 @@
}
bool QuicFramer::AppendRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame,
- QuicDataWriter* writer) {
+ const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(frame.sequence_number)) {
set_detailed_error("Can not write Retire Connection ID sequence number");
return false;
@@ -6510,8 +6471,7 @@
}
bool QuicFramer::ProcessRetireConnectionIdFrame(
- QuicDataReader* reader,
- QuicRetireConnectionIdFrame* frame) {
+ QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
if (!reader->ReadVarInt62(&frame->sequence_number)) {
set_detailed_error(
"Unable to read retire connection ID frame sequence number.");
@@ -6567,8 +6527,7 @@
}
uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
- const QuicStreamFrame& frame,
- bool last_frame_in_packet) const {
+ const QuicStreamFrame& frame, bool last_frame_in_packet) const {
QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
uint8_t type_byte = IETF_STREAM;
if (!last_frame_in_packet) {
@@ -6662,14 +6621,10 @@
// static
QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
- QuicDataReader* reader,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- QuicVersionLabel* version_label,
+ QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
+ bool* version_present, QuicVersionLabel* version_label,
ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- std::string* detailed_error) {
+ QuicConnectionId* destination_connection_id, std::string* detailed_error) {
*format = GOOGLE_QUIC_PACKET;
*version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
uint8_t destination_connection_id_length = 0;
@@ -6696,10 +6651,8 @@
const QuicVersionLabel kProxVersionLabel = 0x50524F58; // "PROX"
inline bool PacketHasLengthPrefixedConnectionIds(
- const QuicDataReader& reader,
- ParsedQuicVersion parsed_version,
- QuicVersionLabel version_label,
- uint8_t first_byte) {
+ const QuicDataReader& reader, ParsedQuicVersion parsed_version,
+ QuicVersionLabel version_label, uint8_t first_byte) {
if (parsed_version.IsKnown()) {
return parsed_version.HasLengthPrefixedConnectionIds();
}
@@ -6733,12 +6686,9 @@
}
inline bool ParseLongHeaderConnectionIds(
- QuicDataReader* reader,
- bool has_length_prefix,
- QuicVersionLabel version_label,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- std::string* detailed_error) {
+ QuicDataReader* reader, bool has_length_prefix,
+ QuicVersionLabel version_label, QuicConnectionId* destination_connection_id,
+ QuicConnectionId* source_connection_id, std::string* detailed_error) {
if (has_length_prefix) {
if (!reader->ReadLengthPrefixedConnectionId(destination_connection_id)) {
*detailed_error = "Unable to read destination connection ID.";
@@ -6795,21 +6745,15 @@
// static
QuicErrorCode QuicFramer::ParsePublicHeader(
- QuicDataReader* reader,
- uint8_t expected_destination_connection_id_length,
- bool ietf_format,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- bool* has_length_prefix,
- QuicVersionLabel* version_label,
- ParsedQuicVersion* parsed_version,
+ QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
+ bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
+ bool* version_present, bool* has_length_prefix,
+ QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
QuicConnectionId* destination_connection_id,
QuicConnectionId* source_connection_id,
QuicLongHeaderType* long_packet_type,
QuicVariableLengthIntegerLength* retry_token_length_length,
- absl::string_view* retry_token,
- std::string* detailed_error) {
+ absl::string_view* retry_token, std::string* detailed_error) {
*version_present = false;
*has_length_prefix = false;
*version_label = 0;
@@ -6875,7 +6819,7 @@
}
// Parse long packet type.
- if (!GetLongHeaderType(*first_byte, long_packet_type)) {
+ if (!GetLongHeaderType(*first_byte, *parsed_version, long_packet_type)) {
*detailed_error = "Unable to parse long packet type.";
return QUIC_INVALID_PACKET_HEADER;
}
@@ -6903,8 +6847,7 @@
// static
bool QuicFramer::WriteClientVersionNegotiationProbePacket(
- char* packet_bytes,
- QuicByteCount packet_length,
+ char* packet_bytes, QuicByteCount packet_length,
const char* destination_connection_id_bytes,
uint8_t destination_connection_id_length) {
if (packet_bytes == nullptr) {
@@ -6981,10 +6924,8 @@
// static
bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
- const char* packet_bytes,
- QuicByteCount packet_length,
- char* source_connection_id_bytes,
- uint8_t* source_connection_id_length_out,
+ const char* packet_bytes, QuicByteCount packet_length,
+ char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
std::string* detailed_error) {
if (detailed_error == nullptr) {
QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 28b7c20..207329c 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -105,10 +105,8 @@
bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
return true;
}
- bool EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
+ bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
+ absl::string_view plaintext, char* output,
size_t* output_length,
size_t /*max_output_length*/) override {
packet_number_ = QuicPacketNumber(packet_number);
@@ -162,10 +160,8 @@
bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
return true;
}
- bool DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
+ bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
+ absl::string_view ciphertext, char* output,
size_t* output_length,
size_t /*max_output_length*/) override {
packet_number_ = QuicPacketNumber(packet_number);
@@ -197,9 +193,7 @@
};
std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
- const QuicPacket& packet,
- uint8_t tag,
- bool phase) {
+ const QuicPacket& packet, uint8_t tag, bool phase) {
std::string packet_data = std::string(packet.AsStringPiece());
if (phase) {
packet_data[0] |= FLAGS_KEY_PHASE_BIT;
@@ -692,9 +686,7 @@
decrypter_(new test::TestDecrypter()),
version_(GetParam()),
start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
- framer_(AllSupportedVersions(),
- start_,
- Perspective::IS_SERVER,
+ framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
kQuicDefaultConnectionIdLength) {
framer_.set_version(version_);
if (framer_.version().KnowsWhichDecrypterToUse()) {
@@ -726,6 +718,19 @@
return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
}
+ // Helper functions to take a v1 long header packet and make it v2. These are
+ // not needed for short header packets, but if sent, this function will exit
+ // cleanly. It needs to be called twice for coalesced packets (see references
+ // to length_of_first_coalesced_packet below for examples of how to do this).
+ inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
+ if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
+ packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
+ }
+ }
+ inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
+ ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
+ }
+
bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
if (packet_number != encrypter_->packet_number_) {
QUIC_LOG(ERROR) << "Encrypted incorrect packet number. expected "
@@ -762,8 +767,7 @@
}
bool CheckDecryption(
- const QuicEncryptedPacket& encrypted,
- bool includes_version,
+ const QuicEncryptedPacket& encrypted, bool includes_version,
bool includes_diversification_nonce,
QuicConnectionIdLength destination_connection_id_length,
QuicConnectionIdLength source_connection_id_length,
@@ -838,15 +842,13 @@
}
}
- if (expected_error.empty())
- continue;
+ if (expected_error.empty()) continue;
CheckProcessingFails(*packet, i, expected_error, error_code);
}
}
- void CheckProcessingFails(const QuicEncryptedPacket& packet,
- size_t len,
+ void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
std::string expected_error,
QuicErrorCode error_code) {
QuicEncryptedPacket encrypted(packet.data(), len, false);
@@ -855,8 +857,7 @@
EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
}
- void CheckProcessingFails(unsigned char* packet,
- size_t len,
+ void CheckProcessingFails(unsigned char* packet, size_t len,
std::string expected_error,
QuicErrorCode error_code) {
QuicEncryptedPacket encrypted(AsChars(packet), len, false);
@@ -894,8 +895,7 @@
// N starts at 1.
QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
- Perspective perspective,
- bool bidirectional,
+ Perspective perspective, bool bidirectional,
int n) {
if (bidirectional) {
return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
@@ -931,8 +931,7 @@
GetQuicVersionByte(3)
// Run all framer tests with all supported versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicFramerTests,
- QuicFramerTest,
+INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
::testing::ValuesIn(AllSupportedVersions()),
::testing::PrintToStringParamName());
@@ -1273,6 +1272,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -1379,6 +1379,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -1669,6 +1670,7 @@
};
// clang-format on
+ ReviseFirstByteByVersion(packet49);
PacketFragments& fragments =
framer_.version().HasLongHeaderLengths()
? packet49
@@ -2970,6 +2972,7 @@
? VARIABLE_LENGTH_INTEGER_LENGTH_1
: VARIABLE_LENGTH_INTEGER_LENGTH_0;
+ ReviseFirstByteByVersion(packet_ietf);
PacketFragments& fragments =
VersionHasIetfQuicFrames(framer_.transport_version())
? packet_ietf
@@ -6420,6 +6423,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().UsesTls()) {
+ ReviseFirstByteByVersion(packet_with_tag);
p = packet_with_tag;
p_length = ABSL_ARRAYSIZE(packet_with_tag);
} else if (framer_.version().HasLongHeaderLengths()) {
@@ -7115,6 +7119,7 @@
unsigned char* p = packet;
size_t p_size = ABSL_ARRAYSIZE(packet);
if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+ ReviseFirstByteByVersion(packet_ietf);
p = packet_ietf;
p_size = ABSL_ARRAYSIZE(packet_ietf);
} else if (framer_.version().HasLongHeaderLengths()) {
@@ -13034,10 +13039,16 @@
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t first_packet_ietf_size = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13157,6 +13168,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13304,10 +13316,16 @@
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t first_packet_ietf_size = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13415,6 +13433,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -13517,6 +13536,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -13677,10 +13697,15 @@
};
// clang-format on
const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13844,10 +13869,16 @@
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13949,10 +13980,16 @@
// version would be here but we cut off the invalid coalesced header.
};
// clang-format on
+ const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -14180,6 +14217,7 @@
QuicEncryptedPacket(AsChars(long_header_packet),
ABSL_ARRAYSIZE(long_header_packet), false)));
} else {
+ ReviseFirstByteByVersion(long_header_packet_ietf);
EXPECT_TRUE(framer_.ProcessPacket(
QuicEncryptedPacket(AsChars(long_header_packet_ietf),
ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
@@ -14708,9 +14746,11 @@
0x00,
};
// clang-format on
+
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -14776,6 +14816,7 @@
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -15615,6 +15656,7 @@
};
// clang-format on
+ ReviseFirstByteByVersion(packet);
QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index d06e1fe..88ae992 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -312,6 +312,7 @@
std::string* error_details) override;
void OnHandshakeCallbackDone() override;
bool PacketFlusherAttached() const override;
+ ParsedQuicVersion parsed_version() const override { return version(); }
// Implement StreamDelegateInterface.
void OnStreamError(QuicErrorCode error_code,
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
index 13e590d..4a84797 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -36,9 +36,11 @@
}
void QuicVersionManager::MaybeRefilterSupportedVersions() {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
- if (disable_version_rfcv1_ !=
+ if (enable_version_2_draft_01_ !=
+ GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
+ disable_version_rfcv1_ !=
GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
disable_version_draft_29_ !=
GetQuicReloadableFlag(quic_disable_version_draft_29) ||
@@ -48,6 +50,8 @@
GetQuicReloadableFlag(quic_disable_version_q046) ||
disable_version_q043_ !=
GetQuicReloadableFlag(quic_disable_version_q043)) {
+ enable_version_2_draft_01_ =
+ GetQuicReloadableFlag(quic_enable_version_2_draft_01);
disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
disable_version_draft_29_ =
GetQuicReloadableFlag(quic_disable_version_draft_29);
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index af44d34..44e134a 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -55,6 +55,8 @@
private:
// Cached value of reloadable flags.
+ // quic_enable_version_2_draft_01 flag
+ bool enable_version_2_draft_01_ = false;
// quic_disable_version_rfcv1 flag
bool disable_version_rfcv1_ = true;
// quic_disable_version_draft_29 flag
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index 403009a..aa4581e 100644
--- a/quic/core/quic_version_manager_test.cc
+++ b/quic/core/quic_version_manager_test.cc
@@ -18,11 +18,12 @@
class QuicVersionManagerTest : public QuicTest {};
TEST_F(QuicVersionManagerTest, QuicVersionManager) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicEnableVersion(version);
}
+ QuicDisableVersion(ParsedQuicVersion::V2Draft01());
QuicDisableVersion(ParsedQuicVersion::RFCv1());
QuicDisableVersion(ParsedQuicVersion::Draft29());
QuicVersionManager manager(AllSupportedVersions());
@@ -65,6 +66,20 @@
manager.GetSupportedVersionsWithOnlyHttp3());
EXPECT_THAT(manager.GetSupportedAlpns(),
ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+ offset++;
+ QuicEnableVersion(ParsedQuicVersion::V2Draft01());
+ expected_parsed_versions.insert(expected_parsed_versions.begin(),
+ ParsedQuicVersion::V2Draft01());
+ EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+ EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+ manager.GetSupportedVersions());
+ EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+ EXPECT_EQ(CurrentSupportedHttp3Versions(),
+ manager.GetSupportedVersionsWithOnlyHttp3());
+ EXPECT_THAT(
+ manager.GetSupportedAlpns(),
+ ElementsAre("h3", "h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
}
} // namespace
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 4c9e661..63d21a1 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -42,11 +42,13 @@
}
void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
const bool enable = should_enable;
const bool disable = !should_enable;
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
+ } else if (version == ParsedQuicVersion::RFCv1()) {
SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
} else if (version == ParsedQuicVersion::Draft29()) {
SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
@@ -182,6 +184,11 @@
return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
}
+bool ParsedQuicVersion::UsesV2PacketTypes() const {
+ QUICHE_DCHECK(IsKnown());
+ return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
bool VersionHasLengthPrefixedConnectionIds(
QuicTransportVersion transport_version) {
QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
@@ -213,9 +220,11 @@
}
QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
- if (parsed_version == ParsedQuicVersion::RFCv1()) {
+ if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+ return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
+ } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
} else if (parsed_version == ParsedQuicVersion::Draft29()) {
return MakeVersionLabel(0xff, 0x00, 0x00, 29);
@@ -411,10 +420,16 @@
ParsedQuicVersionVector FilterSupportedVersions(
ParsedQuicVersionVector versions) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
ParsedQuicVersionVector filtered_versions;
filtered_versions.reserve(versions.size());
for (const ParsedQuicVersion& version : versions) {
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
+ filtered_versions.push_back(version);
+ }
+ } else if (version == ParsedQuicVersion::RFCv1()) {
if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
filtered_versions.push_back(version);
}
@@ -444,8 +459,7 @@
}
ParsedQuicVersionVector ParsedVersionOfIndex(
- const ParsedQuicVersionVector& versions,
- int index) {
+ const ParsedQuicVersionVector& versions, int index) {
ParsedQuicVersionVector version;
int version_count = versions.size();
if (index >= 0 && index < version_count) {
@@ -461,8 +475,7 @@
}
std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels,
- const std::string& separator,
+ const QuicVersionLabelVector& version_labels, const std::string& separator,
size_t skip_after_nth_version) {
std::string result;
for (size_t i = 0; i < version_labels.size(); ++i) {
@@ -490,6 +503,7 @@
RETURN_STRING_LITERAL(QUIC_VERSION_50);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
+ RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
}
@@ -508,10 +522,13 @@
}
std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
if (version == UnsupportedQuicVersion()) {
return "0";
+ } else if (version == ParsedQuicVersion::V2Draft01()) {
+ QUICHE_DCHECK(version.UsesHttp3());
+ return "v2draft01";
} else if (version == ParsedQuicVersion::RFCv1()) {
QUICHE_DCHECK(version.UsesHttp3());
return "RFCv1";
@@ -536,8 +553,7 @@
}
std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions,
- const std::string& separator,
+ const ParsedQuicVersionVector& versions, const std::string& separator,
size_t skip_after_nth_version) {
std::string result;
for (size_t i = 0; i < versions.size(); ++i) {
@@ -604,7 +620,9 @@
}
std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
- if (parsed_version == ParsedQuicVersion::RFCv1()) {
+ if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+ return "h3";
+ } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
return "h3";
} else if (parsed_version == ParsedQuicVersion::Draft29()) {
return "h3-29";
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 331a99c..6c2144a 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -122,8 +122,9 @@
// Number 70 used to represent draft-ietf-quic-transport-25.
// Number 71 used to represent draft-ietf-quic-transport-27.
// Number 72 used to represent draft-ietf-quic-transport-28.
- QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
- QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
+ QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
+ QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
+ QUIC_VERSION_IETF_2_DRAFT_01 = 81, // draft-ietf-quic-v2-01.
// Version 99 was a dumping ground for IETF QUIC changes which were not yet
// ready for production between 2018-02 and 2020-02.
@@ -171,6 +172,7 @@
QuicTransportVersion transport_version) {
bool transport_version_is_valid = false;
constexpr QuicTransportVersion valid_transport_versions[] = {
+ QUIC_VERSION_IETF_2_DRAFT_01,
QUIC_VERSION_IETF_RFC_V1,
QUIC_VERSION_IETF_DRAFT_29,
QUIC_VERSION_50,
@@ -195,7 +197,8 @@
return transport_version != QUIC_VERSION_UNSUPPORTED &&
transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
- transport_version != QUIC_VERSION_IETF_RFC_V1;
+ transport_version != QUIC_VERSION_IETF_RFC_V1 &&
+ transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
case PROTOCOL_TLS1_3:
return transport_version != QUIC_VERSION_UNSUPPORTED &&
transport_version != QUIC_VERSION_50 &&
@@ -245,6 +248,10 @@
transport_version != other.transport_version;
}
+ static constexpr ParsedQuicVersion V2Draft01() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
+ }
+
static constexpr ParsedQuicVersion RFCv1() {
return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
}
@@ -361,6 +368,9 @@
// Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
bool UsesQuicCrypto() const;
+
+ // Returns whether this version uses the QUICv2 Long Header Packet Types.
+ bool UsesV2PacketTypes() const;
};
QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
@@ -377,8 +387,7 @@
using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const ParsedQuicVersionVector& versions);
+ std::ostream& os, const ParsedQuicVersionVector& versions);
// Representation of the on-the-wire QUIC version number. Will be written/read
// to the wire in network-byte-order.
@@ -386,27 +395,25 @@
using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicVersionLabelVector& version_labels);
+ std::ostream& os, const QuicVersionLabelVector& version_labels);
// This vector contains all crypto handshake protocols that are supported.
constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
}
-constexpr std::array<ParsedQuicVersion, 5> SupportedVersions() {
+constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
return {
- ParsedQuicVersion::RFCv1(), ParsedQuicVersion::Draft29(),
- ParsedQuicVersion::Q050(), ParsedQuicVersion::Q046(),
- ParsedQuicVersion::Q043(),
+ ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
+ ParsedQuicVersion::Draft29(), ParsedQuicVersion::Q050(),
+ ParsedQuicVersion::Q046(), ParsedQuicVersion::Q043(),
};
}
using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicTransportVersionVector& transport_versions);
+ std::ostream& os, const QuicTransportVersionVector& transport_versions);
// Returns a vector of supported QUIC versions.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
@@ -494,8 +501,7 @@
// QuicVersionLabel values in the supplied |version_labels| vector. The values
// after the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels,
- const std::string& separator,
+ const QuicVersionLabelVector& version_labels, const std::string& separator,
size_t skip_after_nth_version);
// Returns comma separated list of string representations of QuicVersionLabel
@@ -529,8 +535,7 @@
// ParsedQuicVersion values in the supplied |versions| vector. The values after
// the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions,
- const std::string& separator,
+ const ParsedQuicVersionVector& versions, const std::string& separator,
size_t skip_after_nth_version);
// Returns comma separated list of string representations of ParsedQuicVersion
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index d60bd4d..6f384dd 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -120,9 +120,13 @@
ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
EXPECT_EQ(ParsedQuicVersion::RFCv1(),
ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
- EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::RFCv1(),
+ EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+ ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
+ EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
+ ParsedQuicVersion::RFCv1(),
ParsedQuicVersion::Draft29()}),
ParseQuicVersionLabelVector(QuicVersionLabelVector{
+ MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
@@ -217,6 +221,8 @@
CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
EXPECT_EQ(MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
+ CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
// Make sure the negotiation reserved version is in the IETF reserved space.
EXPECT_EQ(
@@ -291,6 +297,8 @@
EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ("v2draft01",
+ ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
@@ -357,23 +365,25 @@
// yet a typo was made in doing the #defines and it was caught
// only in some test far removed from here... Better safe than sorry.
TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
EXPECT_EQ(QUIC_VERSION_43, 43);
EXPECT_EQ(QUIC_VERSION_46, 46);
EXPECT_EQ(QUIC_VERSION_50, 50);
EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
+ EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
}
TEST_F(QuicVersionsTest, AlpnForVersion) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
}
TEST_F(QuicVersionsTest, QuicVersionEnabling) {
@@ -423,8 +433,12 @@
EXPECT_NE(CreateQuicVersionLabel(version1),
CreateQuicVersionLabel(version2))
<< version1 << " " << version2;
- EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
- << version1 << " " << version2;
+ // The one pair where ALPNs are the same.
+ if ((version1 != ParsedQuicVersion::V2Draft01()) &&
+ (version2 != ParsedQuicVersion::RFCv1())) {
+ EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
+ << version1 << " " << version2;
+ }
}
}
}
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
index ad7dafb..2eee1cc 100644
--- a/quic/core/tls_handshaker.cc
+++ b/quic/core/tls_handshaker.cc
@@ -25,8 +25,7 @@
TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
void TlsHandshaker::ProofVerifierCallbackImpl::Run(
- bool ok,
- const std::string& /*error_details*/,
+ bool ok, const std::string& /*error_details*/,
std::unique_ptr<ProofVerifyDetails>* details) {
if (parent_ == nullptr) {
return;
@@ -42,9 +41,7 @@
parent_->AdvanceHandshake();
}
-void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() {
- parent_ = nullptr;
-}
+void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
: stream_(stream), handshaker_delegate_(session) {}
@@ -243,10 +240,13 @@
std::unique_ptr<QuicEncrypter> encrypter =
QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, write_secret, encrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, write_secret,
+ handshaker_delegate_->parsed_version(),
+ encrypter.get());
std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(prf, write_secret,
- encrypter->GetKeySize());
+ CryptoUtils::GenerateHeaderProtectionKey(
+ prf, write_secret, handshaker_delegate_->parsed_version(),
+ encrypter->GetKeySize());
encrypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -266,10 +266,13 @@
std::unique_ptr<QuicDecrypter> decrypter =
QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, read_secret, decrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, read_secret,
+ handshaker_delegate_->parsed_version(),
+ decrypter.get());
std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(prf, read_secret,
- decrypter->GetKeySize());
+ CryptoUtils::GenerateHeaderProtectionKey(
+ prf, read_secret, handshaker_delegate_->parsed_version(),
+ decrypter->GetKeySize());
decrypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -296,14 +299,16 @@
}
const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
const EVP_MD* prf = Prf(cipher);
- latest_read_secret_ =
- CryptoUtils::GenerateNextKeyPhaseSecret(prf, latest_read_secret_);
- latest_write_secret_ =
- CryptoUtils::GenerateNextKeyPhaseSecret(prf, latest_write_secret_);
+ latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+ prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
+ latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+ prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
std::unique_ptr<QuicDecrypter> decrypter =
QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(prf, latest_read_secret_, decrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
+ handshaker_delegate_->parsed_version(),
+ decrypter.get());
decrypter->SetHeaderProtectionKey(absl::string_view(
reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
one_rtt_read_header_protection_key_.size()));
@@ -322,7 +327,9 @@
const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
std::unique_ptr<QuicEncrypter> encrypter =
QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_, encrypter.get());
+ CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
+ handshaker_delegate_->parsed_version(),
+ encrypter.get());
encrypter->SetHeaderProtectionKey(absl::string_view(
reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
one_rtt_write_header_protection_key_.size()));