Enable TLS in BufferedPacketStoreTest gfe-relnote: n/a, test-only PiperOrigin-RevId: 308347324 Change-Id: Ie025a58810bd047e55a45ef0240338e457020744
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc index 62e1e7b..fde97c9 100644 --- a/quic/core/quic_dispatcher_test.cc +++ b/quic/core/quic_dispatcher_test.cc
@@ -203,7 +203,7 @@ connection_id_(1) {} void SetUp() override { - dispatcher_->InitializeWithWriter(new MockPacketWriter()); + dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>()); // Set the counter to some value to start with. QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop( dispatcher_.get(), kMaxNumSessionsToCreate); @@ -305,7 +305,7 @@ const QuicSocketAddress& peer_address, const ParsedQuicVersion& version, const QuicConnectionId& server_connection_id) { - if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO && + if (version.UsesQuicCrypto() && ChloExtractor::Extract(*received_packet, version, {}, nullptr, server_connection_id.length())) { // Add CHLO packet to the beginning to be verified first, because it is @@ -368,6 +368,25 @@ return std::string(client_hello.GetSerialized().AsStringPiece()); } + void ProcessUndecryptableEarlyPacket( + const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + ProcessUndecryptableEarlyPacket(version_, peer_address, + server_connection_id); + } + + void ProcessUndecryptableEarlyPacket( + const ParsedQuicVersion& version, + const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + std::unique_ptr<QuicEncryptedPacket> encrypted_packet = + GetUndecryptableEarlyPacket(version, server_connection_id); + std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket( + *encrypted_packet, mock_helper_.GetClock()->Now())); + ProcessReceivedPacket(std::move(received_packet), peer_address, version, + server_connection_id); + } + void ProcessFirstFlight(const QuicSocketAddress& peer_address, const QuicConnectionId& server_connection_id) { ProcessFirstFlight(version_, peer_address, server_connection_id); @@ -464,7 +483,7 @@ ::testing::PrintToStringParamName()); TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) { - if (version_.handshake_protocol != PROTOCOL_TLS1_3) { + if (version_.UsesQuicCrypto()) { return; } QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); @@ -490,7 +509,7 @@ void QuicDispatcherTestBase::TestTlsMultiPacketClientHello( bool add_reordering) { - if (version_.handshake_protocol != PROTOCOL_TLS1_3) { + if (!version_.UsesTls()) { return; } QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); @@ -975,7 +994,7 @@ } TEST_P(QuicDispatcherTestAllVersions, OKSeqNoPacketProcessed) { - if (version_.handshake_protocol == PROTOCOL_TLS1_3) { + if (version_.UsesTls()) { // QUIC+TLS allows clients to start with any packet number. return; } @@ -1813,69 +1832,100 @@ public: BufferedPacketStoreTest() : QuicDispatcherTestBase(), - server_addr_(QuicSocketAddress(QuicIpAddress::Any4(), 5)), - client_addr_(QuicIpAddress::Loopback4(), 1234), - signed_config_(new QuicSignedServerConfig) {} + client_addr_(QuicIpAddress::Loopback4(), 1234) {} - void SetUp() override { - QuicDispatcherTestBase::SetUp(); - clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock(); - - ASSERT_EQ(PROTOCOL_QUIC_CRYPTO, version_.handshake_protocol); - ASSERT_NE(QUIC_VERSION_UNSUPPORTED, version_.transport_version); - - CryptoHandshakeMessage chlo = - crypto_test_utils::GenerateDefaultInchoateCHLO( - clock_, version_.transport_version, &crypto_config_); - // Pass an inchoate CHLO. - crypto_test_utils::GenerateFullCHLO( - chlo, &crypto_config_, server_addr_, client_addr_, - version_.transport_version, clock_, signed_config_, - QuicDispatcherPeer::GetCache(dispatcher_.get()), &full_chlo_); + void ProcessFirstFlight(const ParsedQuicVersion& version, + const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address, + server_connection_id); } - std::string SerializeFullCHLO() { - return std::string(full_chlo_.GetSerialized().AsStringPiece()); + void ProcessFirstFlight(const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + ProcessFirstFlight(version_, peer_address, server_connection_id); + } + + void ProcessFirstFlight(const QuicConnectionId& server_connection_id) { + ProcessFirstFlight(client_addr_, server_connection_id); + } + + void ProcessFirstFlight(const ParsedQuicVersion& version, + const QuicConnectionId& server_connection_id) { + ProcessFirstFlight(version, client_addr_, server_connection_id); + } + + void ProcessUndecryptableEarlyPacket( + const ParsedQuicVersion& version, + const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket( + version, peer_address, server_connection_id); + } + + void ProcessUndecryptableEarlyPacket( + const QuicSocketAddress& peer_address, + const QuicConnectionId& server_connection_id) { + ProcessUndecryptableEarlyPacket(version_, peer_address, + server_connection_id); + } + + void ProcessUndecryptableEarlyPacket( + const QuicConnectionId& server_connection_id) { + ProcessUndecryptableEarlyPacket(version_, client_addr_, + server_connection_id); } protected: - QuicSocketAddress server_addr_; QuicSocketAddress client_addr_; - QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_; - const QuicClock* clock_; - CryptoHandshakeMessage full_chlo_; }; -ParsedQuicVersionVector BufferedPacketStoreTestParams() { - ParsedQuicVersionVector versions; - for (const ParsedQuicVersion& version : CurrentSupportedVersions()) { - if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) { - // TODO(b/149597791) Remove this once we can parse ALPN with TLS. - break; - } - versions.push_back(version); - } - return versions; -} - INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest, - ::testing::ValuesIn(BufferedPacketStoreTestParams()), + ::testing::ValuesIn(CurrentSupportedVersions()), ::testing::PrintToStringParamName()); +TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) { + InSequence s; + QuicConnectionId conn_id = TestConnectionId(1); + // Non-CHLO should be buffered upon arrival, and should trigger + // ShouldCreateOrBufferPacketForConnection(). + EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection( + ReceivedPacketInfoConnectionIdEquals(conn_id))); + // Process non-CHLO packet. + ProcessUndecryptableEarlyPacket(conn_id); + EXPECT_EQ(0u, dispatcher_->session_map().size()) + << "No session should be created before CHLO arrives."; + + // When CHLO arrives, a new session should be created, and all packets + // buffered should be delivered to the session. + EXPECT_CALL(*dispatcher_, + CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _)) + .WillOnce(Return(ByMove(CreateSession( + dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, + &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .Times(2) // non-CHLO + CHLO. + .WillRepeatedly( + WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) { + if (version_.UsesQuicCrypto()) { + ValidatePacket(conn_id, packet); + } + }))); + ProcessFirstFlight(conn_id); +} + TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { InSequence s; - QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); QuicConnectionId conn_id = TestConnectionId(1); // A bunch of non-CHLO should be buffered upon arrival, and the first one // should trigger ShouldCreateOrBufferPacketForConnection(). EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection( ReceivedPacketInfoConnectionIdEquals(conn_id))); for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { - ProcessPacket(client_address, conn_id, true, - quiche::QuicheStrCat("data packet ", i + 1), - CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, - /*packet_number=*/i + 1); + ProcessUndecryptableEarlyPacket(conn_id); } EXPECT_EQ(0u, dispatcher_->session_map().size()) << "No session should be created before CHLO arrives."; @@ -1884,10 +1934,10 @@ data_connection_map_[conn_id].pop_back(); // When CHLO arrives, a new session should be created, and all packets // buffered should be delivered to the session. - EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address, - quiche::QuicheStringPiece(), _)) + EXPECT_CALL(*dispatcher_, + CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( - dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)))); @@ -1898,9 +1948,11 @@ .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO. .WillRepeatedly( WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(conn_id, packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(conn_id, packet); + } }))); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); + ProcessFirstFlight(conn_id); } TEST_P(BufferedPacketStoreTest, @@ -1914,10 +1966,7 @@ EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection( ReceivedPacketInfoConnectionIdEquals(conn_id))); - ProcessPacket(client_address, conn_id, true, - quiche::QuicheStrCat("data packet on connection ", i), - CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, - /*packet_number=*/2); + ProcessUndecryptableEarlyPacket(client_address, conn_id); } // Pop out the packet on last connection as it shouldn't be enqueued in store @@ -1938,7 +1987,7 @@ ReceivedPacketInfoConnectionIdEquals(conn_id))); } EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, @@ -1951,48 +2000,45 @@ .Times(num_packet_to_process) .WillRepeatedly(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(conn_id, packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(conn_id, packet); + } }))); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); + ProcessFirstFlight(client_address, conn_id); } } // Tests that store delivers empty packet list if CHLO arrives firstly. TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { QuicConnectionId conn_id = TestConnectionId(1); - QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection( ReceivedPacketInfoConnectionIdEquals(conn_id))); - EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address, - quiche::QuicheStringPiece(), _)) + EXPECT_CALL(*dispatcher_, + CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( - dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)))); EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), - ProcessUdpPacket(_, client_address, _)); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); + ProcessUdpPacket(_, client_addr_, _)); + ProcessFirstFlight(conn_id); } // Tests that a retransmitted CHLO arrives after a connection for the // CHLO has been created. TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { InSequence s; - QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); QuicConnectionId conn_id = TestConnectionId(1); - ProcessPacket(client_address, conn_id, true, - quiche::QuicheStrCat("data packet ", 2), CONNECTION_ID_PRESENT, - PACKET_4BYTE_PACKET_NUMBER, - /*packet_number=*/2); + ProcessUndecryptableEarlyPacket(conn_id); // When CHLO arrives, a new session should be created, and all packets // buffered should be delivered to the session. - EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address, - quiche::QuicheStringPiece(), _)) + EXPECT_CALL(*dispatcher_, + CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _)) .Times(1) // Only triggered by 1st CHLO. .WillOnce(Return(ByMove(CreateSession( - dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)))); EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), @@ -2000,11 +2046,18 @@ .Times(3) // Triggered by 1 data packet and 2 CHLOs. .WillRepeatedly( WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(conn_id, packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(conn_id, packet); + } }))); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); + std::vector<std::unique_ptr<QuicReceivedPacket>> packets = + GetFirstFlightOfPackets(version_, conn_id); + ASSERT_EQ(packets.size(), 1u); + // Receive the CHLO once. + ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id); + // Receive the CHLO a second time to simulate retransmission. + ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id); } // Tests that expiration of a connection add connection id to time wait list. @@ -2015,9 +2068,8 @@ QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); - QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); QuicConnectionId conn_id = TestConnectionId(1); - ProcessPacket(client_address, conn_id, true, + ProcessPacket(client_addr_, conn_id, true, quiche::QuicheStrCat("data packet ", 2), CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/2); @@ -2032,7 +2084,7 @@ // list. ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); - ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); + ProcessFirstFlight(conn_id); } TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) { @@ -2053,7 +2105,7 @@ if (conn_id <= kMaxNumSessionsToCreate) { EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, @@ -2064,11 +2116,12 @@ ProcessUdpPacket(_, _, _)) .WillOnce(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, - SerializeFullCHLO()); + ProcessFirstFlight(TestConnectionId(conn_id)); if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore && conn_id > kMaxNumSessionsToCreate) { EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id))); @@ -2087,7 +2140,7 @@ ++conn_id) { EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, @@ -2096,12 +2149,14 @@ ProcessUdpPacket(_, _, _)) .WillOnce(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .Times(0); while (store->HasChlosBuffered()) { @@ -2121,7 +2176,7 @@ if (conn_id <= kMaxNumSessionsToCreate) { EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, @@ -2132,22 +2187,23 @@ ProcessUdpPacket(_, _, _)) .WillOnce(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, - SerializeFullCHLO()); + ProcessFirstFlight(TestConnectionId(conn_id)); } // Retransmit CHLO on last connection should be dropped. QuicConnectionId last_connection = TestConnectionId(kMaxNumSessionsToCreate + 1); - ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO()); + ProcessFirstFlight(last_connection); size_t packets_buffered = 2; // Reset counter and process buffered CHLO. EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, last_connection, client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, @@ -2158,7 +2214,9 @@ .Times(packets_buffered) .WillRepeatedly(WithArg<2>( Invoke([this, last_connection](const QuicEncryptedPacket& packet) { - ValidatePacket(last_connection, packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(last_connection, packet); + } }))); dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate); } @@ -2171,7 +2229,7 @@ if (conn_id <= kMaxNumSessionsToCreate) { EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, @@ -2182,11 +2240,12 @@ ProcessUdpPacket(_, _, _)) .WillRepeatedly(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, - SerializeFullCHLO()); + ProcessFirstFlight(TestConnectionId(conn_id)); } // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The @@ -2198,7 +2257,7 @@ // Reset counter and process buffered CHLO. EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, last_connection_id, client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, @@ -2210,7 +2269,9 @@ .Times(kDefaultMaxUndecryptablePackets + 1) .WillRepeatedly(WithArg<2>( Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) { - ValidatePacket(last_connection_id, packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(last_connection_id, packet); + } }))); dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate); } @@ -2222,9 +2283,7 @@ QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); uint64_t conn_id = 1; - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, "data packet", - CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, - /*packet_number=*/1); + ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id)); // Fill packet buffer to full with CHLOs on other connections. Need to feed // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create // session directly. @@ -2234,7 +2293,7 @@ if (conn_id <= kMaxNumSessionsToCreate + 1) { EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), _)) + Eq(ExpectedAlpn()), _)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, @@ -2245,18 +2304,18 @@ ProcessUdpPacket(_, _, _)) .WillOnce(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, - SerializeFullCHLO()); + ProcessFirstFlight(TestConnectionId(conn_id)); } EXPECT_FALSE(store->HasChloForConnection( /*connection_id=*/TestConnectionId(1))); // CHLO on connection 1 should still be buffered. - ProcessPacket(client_addr_, /*server_connection_id=*/TestConnectionId(1), - true, SerializeFullCHLO()); + ProcessFirstFlight(TestConnectionId(1)); EXPECT_TRUE(store->HasChloForConnection( /*connection_id=*/TestConnectionId(1))); } @@ -2272,9 +2331,10 @@ ParsedQuicVersion version = supported_versions[(conn_id - 1) % supported_versions.size()]; if (conn_id <= kMaxNumSessionsToCreate) { - EXPECT_CALL(*dispatcher_, - CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), version)) + EXPECT_CALL( + *dispatcher_, + CreateQuicSession(TestConnectionId(conn_id), client_addr_, + Eq(ExpectedAlpnForVersion(version)), version)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, @@ -2285,12 +2345,12 @@ ProcessUdpPacket(_, _, _)) .WillRepeatedly(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } - ProcessPacket(client_addr_, TestConnectionId(conn_id), true, version, - SerializeFullCHLO(), true, CONNECTION_ID_PRESENT, - PACKET_4BYTE_PACKET_NUMBER, 1); + ProcessFirstFlight(version, TestConnectionId(conn_id)); } // Process buffered CHLOs. Verify the version is correct. @@ -2300,7 +2360,7 @@ supported_versions[(conn_id - 1) % supported_versions.size()]; EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), client_addr_, - quiche::QuicheStringPiece(), version)) + Eq(ExpectedAlpnForVersion(version)), version)) .WillOnce(Return(ByMove(CreateSession( dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_, &mock_helper_, &mock_alarm_factory_, &crypto_config_, @@ -2309,7 +2369,9 @@ ProcessUdpPacket(_, _, _)) .WillRepeatedly(WithArg<2>( Invoke([this, conn_id](const QuicEncryptedPacket& packet) { - ValidatePacket(TestConnectionId(conn_id), packet); + if (version_.UsesQuicCrypto()) { + ValidatePacket(TestConnectionId(conn_id), packet); + } }))); } dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc index 9fab452..93611e3 100644 --- a/quic/test_tools/quic_test_utils.cc +++ b/quic/test_tools/quic_test_utils.cc
@@ -793,6 +793,7 @@ .WillByDefault(testing::Return(nullptr)); ON_CALL(*this, Flush()) .WillByDefault(testing::Return(WriteResult(WRITE_STATUS_OK, 0))); + ON_CALL(*this, SupportsReleaseTime()).WillByDefault(testing::Return(false)); } MockPacketWriter::~MockPacketWriter() {} @@ -981,6 +982,49 @@ return new QuicEncryptedPacket(buffer, encrypted_length, true); } +std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket( + const ParsedQuicVersion& version, + const QuicConnectionId& server_connection_id) { + QuicPacketHeader header; + header.destination_connection_id = server_connection_id; + header.destination_connection_id_included = CONNECTION_ID_PRESENT; + header.source_connection_id = EmptyQuicConnectionId(); + header.source_connection_id_included = CONNECTION_ID_PRESENT; + if (!version.SupportsClientConnectionIds()) { + header.source_connection_id_included = CONNECTION_ID_ABSENT; + } + header.version_flag = true; + header.reset_flag = false; + header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER; + header.packet_number = QuicPacketNumber(33); + header.long_packet_type = ZERO_RTT_PROTECTED; + if (version.HasLongHeaderLengths()) { + header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1; + header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2; + } + + QuicFrames frames; + frames.push_back(QuicFrame(QuicPingFrame())); + frames.push_back(QuicFrame(QuicPaddingFrame(100))); + QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_CLIENT, + kQuicDefaultConnectionIdLength); + framer.SetInitialObfuscators(server_connection_id); + + framer.SetEncrypter(ENCRYPTION_ZERO_RTT, + std::make_unique<NullEncrypter>(Perspective::IS_CLIENT)); + std::unique_ptr<QuicPacket> packet( + BuildUnsizedDataPacket(&framer, header, frames)); + EXPECT_TRUE(packet != nullptr); + char* buffer = new char[kMaxOutgoingPacketSize]; + size_t encrypted_length = + framer.EncryptPayload(ENCRYPTION_ZERO_RTT, header.packet_number, *packet, + buffer, kMaxOutgoingPacketSize); + EXPECT_NE(0u, encrypted_length); + DeleteFrames(&frames); + return std::make_unique<QuicEncryptedPacket>(buffer, encrypted_length, + /*owns_buffer=*/true); +} + QuicReceivedPacket* ConstructReceivedPacket( const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time) {
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h index d70cbef..92c13f3 100644 --- a/quic/test_tools/quic_test_utils.h +++ b/quic/test_tools/quic_test_utils.h
@@ -148,8 +148,13 @@ uint64_t packet_number, const std::string& data); -// Constructs a received packet for testing. The caller must take ownership of -// the returned pointer. +// Creates a client-to-server ZERO-RTT packet that will fail to decrypt. +std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket( + const ParsedQuicVersion& version, + const QuicConnectionId& server_connection_id); + +// Constructs a received packet for testing. The caller must take ownership +// of the returned pointer. QuicReceivedPacket* ConstructReceivedPacket( const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time);