Do not send control frames (by session) until encryption gets established.
Protected by FLAGS_quic_reloadable_flag_quic_encrypted_control_frames.
PiperOrigin-RevId: 339672390
Change-Id: I7bcab9157f05d92cbd74b4488957cabc0e7ea6fa
diff --git a/quic/core/http/quic_client_promised_info_test.cc b/quic/core/http/quic_client_promised_info_test.cc
index 1a1ec69..9e21f41 100644
--- a/quic/core/http/quic_client_promised_info_test.cc
+++ b/quic/core/http/quic_client_promised_info_test.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
@@ -52,6 +53,11 @@
void set_authorized(bool authorized) { authorized_ = authorized; }
+ MOCK_METHOD(bool,
+ WriteControlFrame,
+ (const QuicFrame& frame, TransmissionType type),
+ (override));
+
private:
QuicCryptoClientConfig crypto_config_;
@@ -73,6 +79,9 @@
promise_id_(
QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_.Initialize();
headers_[":status"] = "200";
@@ -142,7 +151,7 @@
ASSERT_NE(promised, nullptr);
// Fire the alarm that will cancel the promised stream.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
@@ -156,7 +165,7 @@
// Promise with an unsafe method
push_promise_[":method"] = "PUT";
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
ReceivePromise(promise_id_);
@@ -170,7 +179,7 @@
// Promise with a missing method
push_promise_.erase(":method");
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
ReceivePromise(promise_id_);
@@ -184,7 +193,7 @@
// Remove required header field to make URL invalid
push_promise_.erase(":authority");
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
ReceivePromise(promise_id_);
@@ -197,7 +206,7 @@
TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
session_.set_authorized(false);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
@@ -222,7 +231,7 @@
headers);
TestPushPromiseDelegate delegate(/*match=*/false);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
@@ -300,7 +309,7 @@
session_.GetOrCreateStream(promise_id_);
// Cancel the promised stream.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
promised->Cancel();
@@ -323,7 +332,7 @@
promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
headers);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY);
diff --git a/quic/core/http/quic_server_session_base_test.cc b/quic/core/http/quic_server_session_base_test.cc
index 8cfa01b..4abde42 100644
--- a/quic/core/http/quic_server_session_base_test.cc
+++ b/quic/core/http/quic_server_session_base_test.cc
@@ -71,6 +71,11 @@
~TestServerSession() override { DeleteConnection(); }
+ MOCK_METHOD(bool,
+ WriteControlFrame,
+ (const QuicFrame& frame, TransmissionType type),
+ (override));
+
protected:
QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
if (!ShouldCreateIncomingStream(id)) {
@@ -147,6 +152,9 @@
connection_ = new StrictMock<MockQuicConnection>(
&helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_ = std::make_unique<TestServerSession>(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &memory_cache_backend_);
@@ -193,7 +201,7 @@
EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
// Expect the RESET_STREAM that is generated in response to receiving a
// STOP_SENDING.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
session_->OnStopSendingFrame(stop_sending);
@@ -249,7 +257,7 @@
if (!VersionHasIetfQuicFrames(transport_version())) {
// For non-version 99, the RESET_STREAM will do the full close.
// Set up expects accordingly.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
QUIC_RST_ACKNOWLEDGEMENT));
@@ -278,7 +286,7 @@
if (!VersionHasIetfQuicFrames(transport_version())) {
// For non-version 99, the RESET_STREAM will do the full close.
// Set up expects accordingly.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
QUIC_RST_ACKNOWLEDGEMENT));
@@ -318,7 +326,7 @@
if (!VersionHasIetfQuicFrames(transport_version())) {
// For non-version 99, the RESET_STREAM will do the full close.
// Set up expects accordingly.
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
QUIC_RST_ACKNOWLEDGEMENT));
@@ -348,9 +356,6 @@
// streams. For versions other than version 99, the server accepts slightly
// more than the negotiated stream limit to deal with rare cases where a
// client FIN/RST is lost.
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
if (!VersionHasIetfQuicFrames(transport_version())) {
@@ -387,7 +392,7 @@
// For non-version 99, QUIC responds to an attempt to exceed the stream
// limit by resetting the stream.
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
} else {
// In version 99 QUIC responds to an attempt to exceed the stream limit by
@@ -403,9 +408,6 @@
// Test that the server closes the connection if a client makes too many data
// streams available. The server accepts slightly more than the negotiated
// stream limit to deal with rare cases where a client FIN/RST is lost.
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
const size_t kAvailableStreamLimit =
@@ -512,9 +514,6 @@
QuicTagVector copt;
copt.push_back(kBWRE);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_TRUE(
@@ -706,9 +705,6 @@
QuicTagVector copt;
copt.push_back(kBWMX);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_TRUE(
@@ -718,9 +714,6 @@
TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
EXPECT_FALSE(
QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_FALSE(
@@ -736,9 +729,6 @@
QuicTagVector copt;
copt.push_back(kQNSP);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
- connection_->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(session_->perspective()));
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_FALSE(session_->server_push_enabled());
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 18e8712..c8bae78 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -766,6 +766,7 @@
}
TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
+ CompleteCryptoHandshake();
for (size_t i = 0u; i < session_->get_max_promises(); i++) {
push_promise_[":path"] = quiche::QuicheStringPrintf("/bar%zu", i);
diff --git a/quic/core/http/quic_spdy_client_stream_test.cc b/quic/core/http/quic_spdy_client_stream_test.cc
index c8653ed..90d4ee1 100644
--- a/quic/core/http/quic_spdy_client_stream_test.cc
+++ b/quic/core/http/quic_spdy_client_stream_test.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
@@ -46,6 +47,11 @@
delete;
~MockQuicSpdyClientSession() override = default;
+ MOCK_METHOD(bool,
+ WriteControlFrame,
+ (const QuicFrame& frame, TransmissionType type),
+ (override));
+
using QuicSession::ActivateStream;
private:
@@ -68,7 +74,9 @@
body_("hello world") {
session_.Initialize();
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
headers_[":status"] = "200";
headers_["content-length"] = "11";
@@ -109,7 +117,7 @@
TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
headers_[":status"] = "200 ok";
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
auto headers = AsHeaderList(headers_);
@@ -200,7 +208,7 @@
// 101 "Switching Protocols" is forbidden in HTTP/3 as per the
// "HTTP Upgrade" section of draft-ietf-quic-http.
headers_[":status"] = "101";
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
auto headers = AsHeaderList(headers_);
@@ -246,7 +254,7 @@
std::string data = VersionUsesHttp3(connection_->transport_version())
? header + large_body
: large_body;
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(session_, WriteControlFrame(_, _));
EXPECT_CALL(*connection_,
OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 36ebf87..714c21d 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -85,6 +85,13 @@
params_->cipher_suite = 1;
}
+ void EstablishZeroRttEncryption() {
+ encryption_established_ = true;
+ session()->connection()->SetEncrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::make_unique<NullEncrypter>(session()->perspective()));
+ }
+
void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
encryption_established_ = true;
one_rtt_keys_available_ = true;
@@ -573,6 +580,7 @@
}
TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
@@ -586,6 +594,7 @@
}
TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
+ CompleteHandshake();
QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
session_.GetOrCreateStream(stream_id1);
@@ -988,6 +997,7 @@
}
TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
+ CompleteHandshake();
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
@@ -1065,6 +1075,7 @@
}
TEST_P(QuicSpdySessionTestServer, SendGoAway) {
+ CompleteHandshake();
if (VersionHasIetfQuicFrames(transport_version())) {
// HTTP/3 GOAWAY has different semantic and thus has its own test.
return;
@@ -1188,6 +1199,7 @@
}
TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
+ CompleteHandshake();
if (VersionHasIetfQuicFrames(transport_version())) {
// HTTP/3 GOAWAY doesn't have such restriction.
return;
@@ -1400,6 +1412,7 @@
// Ensure that Writev consumes all the data it is given (simulate no socket
// blocking).
+ session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
session_.set_writev_consumes_all_data(true);
// Create a stream, and send enough data to make it flow control blocked.
@@ -1426,9 +1439,12 @@
TEST_P(QuicSpdySessionTestServer,
HandshakeUnblocksFlowControlBlockedCryptoStream) {
- if (QuicVersionUsesCryptoFrames(transport_version())) {
+ if (QuicVersionUsesCryptoFrames(transport_version()) ||
+ connection_->encrypted_control_frames()) {
// QUIC version 47 onwards uses CRYPTO frames for the handshake, so this
- // test doesn't make sense for those versions.
+ // test doesn't make sense for those versions. With
+ // use_encryption_level_context, control frames can only be sent when
+ // encryption gets established, do not send BLOCKED for crypto streams.
return;
}
// Test that if the crypto stream is flow control blocked, then if the SHLO
@@ -1498,6 +1514,7 @@
// Test that if the header stream is flow control blocked, then if the SHLO
// contains a larger send window offset, the stream becomes unblocked.
+ session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
session_.set_writev_consumes_all_data(true);
TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
@@ -1614,6 +1631,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
+ session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
@@ -1629,7 +1647,6 @@
QuicTagVector copt;
copt.push_back(kIFW7);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
-
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
@@ -1668,6 +1685,7 @@
// If a buggy/malicious peer creates too many streams that are not ended
// with a FIN or RST then we send an RST to refuse streams for versions other
// than version 99. In version 99 the connection gets closed.
+ CompleteHandshake();
const QuicStreamId kMaxStreams = 5;
if (VersionHasIetfQuicFrames(transport_version())) {
QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
@@ -1722,6 +1740,7 @@
// Verify that a draining stream (which has received a FIN but not consumed
// it) does not count against the open quota (because it is closed from the
// protocol point of view).
+ CompleteHandshake();
if (VersionHasIetfQuicFrames(transport_version())) {
// Simulate receiving a config. so that MAX_STREAMS/etc frames may
// be transmitted
@@ -1907,6 +1926,7 @@
// Verify that an incoming FIN is recorded in a stream object even if the read
// side has been closed. This prevents an entry from being made in
// locally_closed_streams_highest_offset_ (which will never be deleted).
+ CompleteHandshake();
TestStream* stream = session_.CreateOutgoingBidirectionalStream();
QuicStreamId stream_id = stream->id();
@@ -2111,6 +2131,7 @@
TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
// Resetting a stream will send a QPACK Stream Cancellation instruction on the
// decoder stream. For simplicity, ignore writes on this stream.
+ CompleteHandshake();
NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
if (VersionUsesHttp3(transport_version())) {
session_.qpack_decoder()->set_qpack_stream_sender_delegate(
@@ -2156,6 +2177,7 @@
}
TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
+ CompleteHandshake();
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
InSequence s;
@@ -2274,7 +2296,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
-
+ CompleteHandshake();
char input[] = {0x04, // type
'a', 'b', 'c'}; // data
absl::string_view payload(input, ABSL_ARRAYSIZE(input));
@@ -2326,7 +2348,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
-
+ CompleteHandshake();
char input[] = {0x04, // type
'a', 'b', 'c'}; // data
absl::string_view payload(input, ABSL_ARRAYSIZE(input));
@@ -2367,7 +2389,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
-
+ CompleteHandshake();
char input[] = {0x41, 0x00, // type (256)
'a', 'b', 'c'}; // data
absl::string_view payload(input, ABSL_ARRAYSIZE(input));
@@ -2479,7 +2501,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
-
+ CompleteHandshake();
session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
@@ -2546,6 +2568,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
+ CompleteHandshake();
ASSERT_TRUE(session_.UsesPendingStreams());
const QuicStreamId stream_id =
@@ -2592,6 +2615,7 @@
if (!VersionUsesHttp3(transport_version())) {
return;
}
+ CompleteHandshake();
ASSERT_TRUE(session_.UsesPendingStreams());
const QuicStreamId stream_id =
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index f493598..db6facf 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -349,7 +349,10 @@
clock_->ApproximateNow(),
&arena_,
alarm_factory_),
- support_handshake_done_(version().HasHandshakeDone()) {
+ support_handshake_done_(version().HasHandshakeDone()),
+ encrypted_control_frames_(
+ GetQuicReloadableFlag(quic_encrypted_control_frames) &&
+ packet_creator_.let_connection_handle_pings()) {
QUIC_BUG_IF(!start_peer_migration_earlier_ && send_path_response_);
if (GetQuicReloadableFlag(quic_connection_set_initial_self_address)) {
DCHECK(perspective_ == Perspective::IS_CLIENT ||
@@ -1840,8 +1843,8 @@
if (!should_last_packet_instigate_acks_) {
uber_received_packet_manager_.MaybeUpdateAckTimeout(
should_last_packet_instigate_acks_, last_decrypted_packet_level_,
- last_header_.packet_number,
- clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+ last_header_.packet_number, clock_->ApproximateNow(),
+ sent_packet_manager_.GetRttStats());
}
ClearLastFrames();
@@ -5342,8 +5345,8 @@
should_last_packet_instigate_acks_ = true;
uber_received_packet_manager_.MaybeUpdateAckTimeout(
/*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
- last_header_.packet_number,
- clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+ last_header_.packet_number, clock_->ApproximateNow(),
+ sent_packet_manager_.GetRttStats());
}
QuicTime QuicConnection::GetPathDegradingDeadline() const {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 45eb1cb..681a64a 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1127,6 +1127,8 @@
bool is_processing_packet() const { return framer_.is_processing_packet(); }
+ bool encrypted_control_frames() const { return encrypted_control_frames_; }
+
protected:
// Calls cancel() on all the alarms owned by this connection.
void CancelAllAlarms();
@@ -1926,6 +1928,8 @@
const bool check_keys_before_writing_ =
GetQuicReloadableFlag(quic_check_keys_before_writing);
+
+ bool encrypted_control_frames_;
};
} // namespace quic
diff --git a/quic/core/quic_control_frame_manager_test.cc b/quic/core/quic_control_frame_manager_test.cc
index cf90e90..68658bb 100644
--- a/quic/core/quic_control_frame_manager_test.cc
+++ b/quic/core/quic_control_frame_manager_test.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
@@ -37,7 +38,7 @@
class QuicControlFrameManagerTest : public QuicTest {
public:
- bool SaveControlFrame(const QuicFrame& frame) {
+ bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) {
frame_ = frame;
return true;
}
@@ -54,13 +55,16 @@
void Initialize() {
connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
Perspective::IS_SERVER);
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
EXPECT_FALSE(manager_->HasPendingRetransmission());
EXPECT_FALSE(manager_->WillingToWrite());
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
"Going away.");
@@ -103,10 +107,10 @@
TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
Initialize();
InSequence s;
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
// Send control frames 1, 2, 3.
manager_->OnCanWrite();
EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
@@ -139,8 +143,8 @@
EXPECT_TRUE(manager_->WillingToWrite());
// Send control frames 4, 5.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
manager_->WritePing();
EXPECT_FALSE(manager_->WillingToWrite());
@@ -149,10 +153,10 @@
TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
Initialize();
InSequence s;
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
// Send control frames 1, 2, 3.
manager_->OnCanWrite();
@@ -166,17 +170,17 @@
manager_->OnControlFrameAcked(QuicFrame(&goaway_));
// Retransmit control frames 1, 3.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
EXPECT_FALSE(manager_->HasPendingRetransmission());
EXPECT_TRUE(manager_->WillingToWrite());
// Send control frames 4, 5, and 6.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(number_of_frames_ - 2u)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
manager_->WritePing();
EXPECT_FALSE(manager_->WillingToWrite());
@@ -186,26 +190,26 @@
Initialize();
InSequence s;
// Send control frames 1, 2, 3, 4.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(number_of_frames_)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
// Ack control frame 2.
manager_->OnControlFrameAcked(QuicFrame(&goaway_));
- // Do not retransmit an acked frame.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+ // Do not retransmit an acked frame
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0);
EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_),
PTO_RETRANSMISSION));
// Retransmit control frame 3.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
PTO_RETRANSMISSION));
// Retransmit control frame 4, and connection is write blocked.
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
PTO_RETRANSMISSION));
}
@@ -213,9 +217,9 @@
TEST_F(QuicControlFrameManagerTest, DonotSendPingWithBufferedFrames) {
Initialize();
InSequence s;
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
// Send control frame 1.
manager_->OnCanWrite();
EXPECT_FALSE(manager_->HasPendingRetransmission());
@@ -224,9 +228,9 @@
// Send PING when there is buffered frames.
manager_->WritePing();
// Verify only the buffered frames are sent.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(number_of_frames_ - 1)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
EXPECT_FALSE(manager_->HasPendingRetransmission());
EXPECT_FALSE(manager_->WillingToWrite());
@@ -236,10 +240,10 @@
Initialize();
InSequence s;
// Send Non-AckFrequency frame 1-5.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(5)
- .WillRepeatedly(Invoke(&ClearControlFrame));
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
manager_->OnCanWrite();
// Send AckFrequencyFrame as frame 6.
@@ -247,8 +251,8 @@
frame_to_send.packet_tolerance = 10;
frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24);
manager_->WriteOrBufferAckFrequency(frame_to_send);
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
// Ack AckFrequencyFrame.
@@ -270,8 +274,8 @@
300);
InSequence s;
// Flush all buffered control frames.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
// Mark all 3 window updates as lost.
@@ -282,7 +286,7 @@
EXPECT_TRUE(manager_->WillingToWrite());
// Verify only the latest window update gets retransmitted.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
manager_->OnCanWrite();
EXPECT_EQ(number_of_frames_ + 2u,
@@ -302,8 +306,8 @@
QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
InSequence s;
// Flush all buffered control frames.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
// Mark all 3 window updates as lost.
@@ -314,9 +318,9 @@
EXPECT_TRUE(manager_->WillingToWrite());
// Verify all 3 window updates get retransmitted.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(3)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
manager_->OnCanWrite();
EXPECT_FALSE(manager_->HasPendingRetransmission());
EXPECT_FALSE(manager_->WillingToWrite());
@@ -324,13 +328,13 @@
TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
Initialize();
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(5)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
// Flush buffered frames.
manager_->OnCanWrite();
// Write 995 control frames.
- EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
for (size_t i = 0; i < 995; ++i) {
manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
}
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 0526112..e06a766 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -4,80 +4,81 @@
// This file is autogenerated by the QUICHE Copybara export script.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_settings, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_fast_huffman_encoder, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_frames, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_split_up_send_rst, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_stop_sending_uses_ietf_error_code, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_version_negotiation_for_short_connection_ids, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_record_received_min_ack_delay, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_start_peer_migration_earlier, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_process_undecryptable_packets_after_async_decrypt_callback, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_let_connection_handle_pings, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_granular_qpack_error_codes, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_key_update_supported, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_http3_new_default_urgency_value, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_out_of_order_sending2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_undecryptable_packets2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_missing_initial_keys2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_arm_pto_for_application_data, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_give_sent_packet_to_debug_visitor_after_sent, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_aead_limits, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pto_pending_timer_count, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_willing_and_able_to_write2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_http3_goaway_stream_id, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_clip_received_error_code, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_address_validation, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_27, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t050, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_initial_ack, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_copy_bbr_cwnd_to_bbr2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_deallocate_message_right_after_sent, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_2_rttvar, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_close_connection_in_on_can_write_with_blocked_writer, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_tcp_inflight_hi_headroom, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_check_keys_before_writing, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_support_max_bootstrap_cwnd, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_set_initial_self_address, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_clean_up_spdy_session_destructor, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_post_inflight_to_detect_queuing, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_exit_startup_on_loss_with_bw_growth, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_loss_exit_use_max_delivered, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_limit_inflight_hi, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ack_delay_alarm_granularity, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_close, true)
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false)
QUIC_FLAG(FLAGS_quic_restart_flag_quic_support_release_time_for_gso, false)
QUIC_FLAG(FLAGS_quic_restart_flag_quic_session_tickets_always_enabled, false)
QUIC_FLAG(FLAGS_quic_restart_flag_quic_enable_zero_rtt_for_tls_v2, true)
+QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false)
QUIC_FLAG(FLAGS_quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pto_pending_timer_count, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_out_of_order_sending2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_split_up_send_rst, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_missing_initial_keys2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_stop_sending_uses_ietf_error_code, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_fast_huffman_encoder, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_start_peer_migration_earlier, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_version_negotiation_for_short_connection_ids, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_frames, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_process_undecryptable_packets_after_async_decrypt_callback, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_record_received_min_ack_delay, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_settings, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_close, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_let_connection_handle_pings, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_key_update_supported, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_http3_new_default_urgency_value, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_willing_and_able_to_write2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_granular_qpack_error_codes, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_give_sent_packet_to_debug_visitor_after_sent, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_undecryptable_packets2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_http3_goaway_stream_id, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_arm_pto_for_application_data, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_address_validation, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_encrypted_control_frames, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_aead_limits, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_clip_received_error_code, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t050, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_27, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_initial_ack, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_2_rttvar, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_deallocate_message_right_after_sent, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_copy_bbr_cwnd_to_bbr2, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_set_initial_self_address, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_close_connection_in_on_can_write_with_blocked_writer, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_clean_up_spdy_session_destructor, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_check_keys_before_writing, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_tcp_inflight_hi_headroom, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_post_inflight_to_detect_queuing, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_support_max_bootstrap_cwnd, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_loss_exit_use_max_delivered, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_limit_inflight_hi, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_exit_startup_on_loss_with_bw_growth, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ack_delay_alarm_granularity, false)
diff --git a/quic/core/quic_flow_controller_test.cc b/quic/core/quic_flow_controller_test.cc
index 29a9ba3..5a27570 100644
--- a/quic/core/quic_flow_controller_test.cc
+++ b/quic/core/quic_flow_controller_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
@@ -39,6 +40,9 @@
void Initialize() {
connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
Perspective::IS_CLIENT);
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_ = std::make_unique<MockQuicSession>(connection_);
flow_controller_ = std::make_unique<QuicFlowController>(
session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
@@ -115,7 +119,7 @@
QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
// Consume enough bytes to send a WINDOW_UPDATE frame.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
@@ -185,7 +189,7 @@
should_auto_tune_receive_window_ = true;
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -237,9 +241,9 @@
TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -292,7 +296,7 @@
should_auto_tune_receive_window_ = true;
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -347,9 +351,9 @@
TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(2)
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 5079b46..5f1c5ef 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -804,6 +804,14 @@
TransmissionType type) {
DCHECK(connection()->connected())
<< ENDPOINT << "Try to write control frames when connection is closed.";
+ if (connection_->encrypted_control_frames()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_encrypted_control_frames);
+ if (!IsEncryptionEstablished()) {
+ QUIC_BUG << ENDPOINT << "Tried to send control frame " << frame
+ << " before encryption is established.";
+ return false;
+ }
+ }
SetTransmissionType(type);
return connection_->SendControlFrame(frame);
}
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 738ee0b..129c937 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -70,6 +70,13 @@
params_->cipher_suite = 1;
}
+ void EstablishZeroRttEncryption() {
+ encryption_established_ = true;
+ session()->connection()->SetEncrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::make_unique<NullEncrypter>(session()->perspective()));
+ }
+
void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
encryption_established_ = true;
one_rtt_keys_available_ = true;
@@ -715,6 +722,7 @@
}
TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
@@ -728,6 +736,7 @@
}
TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
@@ -741,6 +750,7 @@
}
TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
+ CompleteHandshake();
QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
session_.GetOrCreateStream(stream_id1);
@@ -761,6 +771,7 @@
}
TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
+ CompleteHandshake();
QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
session_.GetOrCreateStream(stream_id1);
@@ -923,6 +934,7 @@
}
TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
QuicStreamId closed_stream_id = stream2->id();
// Close the stream.
@@ -1278,6 +1290,7 @@
if (!VersionHasIetfQuicFrames(transport_version())) {
return;
}
+ CompleteHandshake();
for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
session_.GetNextOutgoingBidirectionalStreamId();
@@ -1363,6 +1376,7 @@
}
TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
+ CompleteHandshake();
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
@@ -1432,6 +1446,7 @@
// In IETF QUIC, GOAWAY lives up in the HTTP layer.
return;
}
+ CompleteHandshake();
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
@@ -1453,6 +1468,7 @@
}
TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
+ CompleteHandshake();
if (VersionHasIetfQuicFrames(transport_version())) {
// In IETF QUIC, GOAWAY lives up in the HTTP layer.
return;
@@ -1554,12 +1570,7 @@
TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
- if (connection_->version().HasHandshakeDone()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- }
- CryptoHandshakeMessage msg;
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ CompleteHandshake();
EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
}
@@ -1621,6 +1632,7 @@
// Ensure that Writev consumes all the data it is given (simulate no socket
// blocking).
session_.set_writev_consumes_all_data(true);
+ session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
// Create a stream, and send enough data to make it flow control blocked.
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -1636,8 +1648,7 @@
// Now complete the crypto handshake, resulting in an increased flow control
// send window.
- CryptoHandshakeMessage msg;
- session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ CompleteHandshake();
EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
// Stream is now unblocked.
EXPECT_FALSE(stream2->IsFlowControlBlocked());
@@ -1646,7 +1657,8 @@
}
TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
- if (QuicVersionUsesCryptoFrames(GetParam().transport_version)) {
+ if (QuicVersionUsesCryptoFrames(GetParam().transport_version) ||
+ connection_->encrypted_control_frames()) {
// QUIC version 47 onwards uses CRYPTO frames for the handshake, so this
// test doesn't make sense for those versions since CRYPTO frames aren't
// flow controlled.
@@ -1684,8 +1696,7 @@
// Now complete the crypto handshake, resulting in an increased flow control
// send window.
- CryptoHandshakeMessage msg;
- session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ CompleteHandshake();
EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
&session_,
QuicUtils::GetCryptoStreamId(connection_->transport_version())));
@@ -1696,6 +1707,7 @@
}
TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
+ CompleteHandshake();
// Test that when we receive an out of order stream RST we correctly adjust
// our connection level flow control receive window.
// On close, the stream should mark as consumed all bytes between the highest
@@ -1725,6 +1737,7 @@
}
TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
+ CompleteHandshake();
// Test the situation where we receive a FIN on a stream, and before we fully
// consume all the data from the sequencer buffer we locally RST the stream.
// The bytes between highest consumed byte, and the final byte offset that we
@@ -1751,6 +1764,7 @@
}
TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+ CompleteHandshake();
// Test that when we RST the stream (and tear down stream state), and then
// receive a FIN from the peer, we correctly adjust our connection level flow
// control receive window.
@@ -1790,6 +1804,7 @@
}
TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+ CompleteHandshake();
// Test that when we RST the stream (and tear down stream state), and then
// receive a RST from the peer, we correctly adjust our connection level flow
// control receive window.
@@ -1855,6 +1870,7 @@
}
TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
+ CompleteHandshake();
// Test that if we receive a stream RST with a highest byte offset that
// violates flow control, that we close the connection.
const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
@@ -1877,6 +1893,7 @@
}
TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
+ CompleteHandshake();
// If a buggy/malicious peer creates too many streams that are not ended
// with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
// connection is closed.
@@ -1919,6 +1936,7 @@
// Verify that a draining stream (which has received a FIN but not consumed
// it) does not count against the open quota (because it is closed from the
// protocol point of view).
+ CompleteHandshake();
TestStream* stream = session_.CreateOutgoingBidirectionalStream();
QuicStreamId stream_id = stream->id();
QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT"));
@@ -2030,6 +2048,7 @@
// Verify that a draining stream (which has received a FIN but not consumed
// it) does not count against the open quota (because it is closed from the
// protocol point of view).
+ CompleteHandshake();
if (VersionHasIetfQuicFrames(transport_version())) {
// On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
// not enough streams to create the next one.
@@ -2186,6 +2205,7 @@
}
TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
+ CompleteHandshake();
// Verify that an incoming FIN is recorded in a stream object even if the read
// side has been closed. This prevents an entry from being made in
// locally_closed_streams_highest_offset_ (which will never be deleted).
@@ -2291,6 +2311,7 @@
}
TEST_P(QuicSessionTestServer, ZombieStreams) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
QuicStreamPeer::SetStreamBytesWritten(3, stream2);
EXPECT_TRUE(stream2->IsWaitingForAcks());
@@ -2304,6 +2325,7 @@
}
TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
+ CompleteHandshake();
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
QuicStreamPeer::SetStreamBytesWritten(3, stream2);
EXPECT_TRUE(stream2->IsWaitingForAcks());
@@ -2323,6 +2345,7 @@
// Regression test of b/71548958.
TEST_P(QuicSessionTestServer, TestZombieStreams) {
+ CompleteHandshake();
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -2455,6 +2478,7 @@
}
TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+ CompleteHandshake();
InSequence s;
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -2494,6 +2518,7 @@
}
TEST_P(QuicSessionTestServer, RetransmitFrames) {
+ CompleteHandshake();
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
InSequence s;
@@ -2530,6 +2555,7 @@
// Regression test of b/110082001.
TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
+ CompleteHandshake();
// This test mimics the scenario when a dynamic stream retransmits lost data
// and causes connection close.
TestStream* stream = session_.CreateOutgoingBidirectionalStream();
@@ -2568,13 +2594,7 @@
MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
"", &storage)));
- // Finish handshake.
- if (connection_->version().HasHandshakeDone()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- }
- CryptoHandshakeMessage handshake_message;
- connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session_.GetMutableCryptoStream()->OnHandshakeMessage(handshake_message);
+ CompleteHandshake();
EXPECT_TRUE(session_.OneRttKeysAvailable());
absl::string_view message;
@@ -2615,6 +2635,7 @@
// Regression test of b/115323618.
TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
+ CompleteHandshake();
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
std::string body(100, '.');
@@ -2644,6 +2665,7 @@
}
TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
+ CompleteHandshake();
EXPECT_FALSE(
QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
@@ -2916,7 +2938,7 @@
if (!VersionHasIetfQuicFrames(transport_version())) {
return;
}
-
+ CompleteHandshake();
TestStream* stream = session_.CreateOutgoingBidirectionalStream();
QuicStreamId stream_id = stream->id();
CloseStream(stream_id);
@@ -2943,6 +2965,7 @@
// If a STOP_SENDING is received for a peer initiated stream, the new stream
// will be created.
TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
+ CompleteHandshake();
if (!VersionHasIetfQuicFrames(transport_version())) {
return;
}
@@ -2962,6 +2985,7 @@
// For a valid stream, ensure that all works
TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
+ CompleteHandshake();
if (!VersionHasIetfQuicFrames(transport_version())) {
// Applicable only to IETF QUIC
return;
@@ -3027,6 +3051,7 @@
}
TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
+ CompleteHandshake();
if (!VersionHasIetfQuicFrames(transport_version())) {
return;
}
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc
index d6ad3f8..563a7fd 100644
--- a/quic/core/quic_stream_test.cc
+++ b/quic/core/quic_stream_test.cc
@@ -621,9 +621,9 @@
EXPECT_CALL(*connection_,
CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
.Times(0);
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
std::string data(1000, 'x');
for (QuicStreamOffset offset = 0;
@@ -951,9 +951,9 @@
EXPECT_TRUE(session_->HasUnackedStreamData());
EXPECT_CALL(*connection_,
OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
- EXPECT_CALL(*connection_, SendControlFrame(_))
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
.Times(AtLeast(1))
- .WillRepeatedly(Invoke(&ClearControlFrame));
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
if (!session_->split_up_send_rst()) {
EXPECT_CALL(*session_,
SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 9, _))
@@ -1475,8 +1475,8 @@
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
std::string data(1024, '.');
stream->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
@@ -1509,8 +1509,8 @@
std::string data(100, '.');
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
stream->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc
index d6395d0..30ed4fd 100644
--- a/quic/test_tools/quic_connection_peer.cc
+++ b/quic/test_tools/quic_connection_peer.cc
@@ -394,5 +394,10 @@
connection->connected_ = false;
}
+// static
+void QuicConnectionPeer::SendPing(QuicConnection* connection) {
+ connection->SendPingAtLevel(connection->encryption_level());
+}
+
} // namespace test
} // namespace quic
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h
index ecc98c5..8859a58 100644
--- a/quic/test_tools/quic_connection_peer.h
+++ b/quic/test_tools/quic_connection_peer.h
@@ -162,6 +162,8 @@
pending_path_challenge_payloads(QuicConnection* connection);
static void SetConnectionClose(QuicConnection* connection);
+
+ static void SendPing(QuicConnection* connection);
};
} // namespace test
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index 0357ee2..8bf49d9 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -214,6 +214,11 @@
return true;
}
+bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
+ TransmissionType /*type*/) {
+ return ClearControlFrame(frame);
+}
+
uint64_t SimpleRandom::RandUint64() {
uint64_t result;
RandBytes(&result, sizeof(result));
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index 0224235..f05859d 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -254,6 +254,8 @@
// Delete |frame| and return true.
bool ClearControlFrame(const QuicFrame& frame);
+bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
+ TransmissionType type);
// Simple random number generator used to compute random numbers suitable
// for pseudo-randomly dropping packets in tests.
@@ -840,6 +842,10 @@
TransmissionType type,
absl::optional<EncryptionLevel> level),
(override));
+ MOCK_METHOD(bool,
+ WriteControlFrame,
+ (const QuicFrame& frame, TransmissionType type),
+ (override));
MOCK_METHOD(void,
SendRstStream,
diff --git a/quic/tools/quic_simple_server_session_test.cc b/quic/tools/quic_simple_server_session_test.cc
index 8cd89f4..28e8899 100644
--- a/quic/tools/quic_simple_server_session_test.cc
+++ b/quic/tools/quic_simple_server_session_test.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "absl/strings/string_view.h"
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
@@ -203,6 +204,10 @@
());
MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override));
+ MOCK_METHOD(bool,
+ WriteControlFrame,
+ (const QuicFrame& frame, TransmissionType type),
+ (override));
};
class QuicSimpleServerSessionTest
@@ -256,6 +261,9 @@
connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
&helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_ = std::make_unique<MockQuicSimpleServerSession>(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &memory_cache_backend_);
@@ -266,9 +274,8 @@
session_->Initialize();
if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(
- this, &QuicSimpleServerSessionTest::ClearMaxStreamsControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
}
session_->OnConfigNegotiated();
}
@@ -335,7 +342,8 @@
GetNthClientInitiatedBidirectionalId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
+
if (!VersionHasIetfQuicFrames(transport_version())) {
// For version 99, this is covered in InjectStopSending()
EXPECT_CALL(*connection_,
@@ -365,7 +373,7 @@
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
// For version 99, this is covered in InjectStopSending()
EXPECT_CALL(*connection_,
OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
@@ -406,7 +414,7 @@
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
if (!VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
// For version 99, this is covered in InjectStopSending()
EXPECT_CALL(*connection_,
OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
@@ -622,6 +630,9 @@
ParsedQuicVersionVector supported_versions = SupportedVersions(GetParam());
connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
&helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
+ connection_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(connection_->perspective()));
session_ = std::make_unique<MockQuicSimpleServerSession>(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &memory_cache_backend_);
@@ -629,9 +640,8 @@
// Needed to make new session flow control window and server push work.
if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(this, &QuicSimpleServerSessionServerPushTest::
- ClearMaxStreamsControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
}
session_->OnConfigNegotiated();
@@ -881,8 +891,8 @@
// V99 will send out a STREAMS_BLOCKED frame when it tries to exceed the
// limit. This will clear the frames so that they do not block the later
// rst-stream frame.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
}
QuicByteCount data_frame_header_length = PromisePushResources(num_resources);
@@ -898,8 +908,8 @@
QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
QUIC_STREAM_CANCELLED, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
EXPECT_CALL(*connection_,
OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
session_->OnRstStream(rst);
@@ -968,8 +978,8 @@
// V99 will send out a stream-id-blocked frame when the we desired to exceed
// the limit. This will clear the frames so that they do not block the later
// rst-stream frame.
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&ClearControlFrame));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _))
+ .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
}
QuicByteCount data_frame_header_length = PromisePushResources(num_resources);
QuicStreamId stream_to_open;
@@ -983,7 +993,7 @@
// Resetting an open stream will close the stream and give space for extra
// stream to be opened.
QuicStreamId stream_got_reset = GetNthServerInitiatedUnidirectionalId(3);
- EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*session_, WriteControlFrame(_, _));
if (!VersionHasIetfQuicFrames(transport_version())) {
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
// For version 99, this is covered in InjectStopSending()