Add QUIC_BUG_IF to QuicUtils::GetCryptoStreamId
In QUIC versions that use CRYPTO frames (instead of stream 1 frames) for
the crypto handshake, the concept of a "crypto stream ID" makes no
sense, so QuicUtils::GetCryptoStreamId should hit a QUIC_BUG_IF to
prevent its misuse.
gfe-relnote: Add QUIC_BUG_IF protected behind QuicVersionUsesCryptoFrames
PiperOrigin-RevId: 248463613
Change-Id: If6768658e9ffc058778b53a91f95839826602fbf
diff --git a/quic/core/chlo_extractor.cc b/quic/core/chlo_extractor.cc
index 2398693..ec3a899 100644
--- a/quic/core/chlo_extractor.cc
+++ b/quic/core/chlo_extractor.cc
@@ -151,8 +151,8 @@
return false;
}
QuicStringPiece data(frame.data_buffer, frame.data_length);
- if (frame.stream_id ==
- QuicUtils::GetCryptoStreamId(framer_->transport_version()) &&
+ if (QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+ frame.stream_id) &&
frame.offset == 0 && QuicTextUtils::StartsWith(data, "CHLO")) {
return OnHandshakeData(data);
}
diff --git a/quic/core/chlo_extractor_test.cc b/quic/core/chlo_extractor_test.cc
index e5e084c..258e141 100644
--- a/quic/core/chlo_extractor_test.cc
+++ b/quic/core/chlo_extractor_test.cc
@@ -141,11 +141,15 @@
}
TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
+ ParsedQuicVersion version = AllSupportedVersions()[0];
+ if (QuicVersionUsesCryptoFrames(version.transport_version)) {
+ return;
+ }
CryptoHandshakeMessage client_hello;
client_hello.set_tag(kCHLO);
std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
- MakePacket(AllSupportedVersions()[0], client_hello_str,
+ MakePacket(version, client_hello_str,
/*munge_offset*/ false, /*munge_stream_id*/ true);
EXPECT_FALSE(ChloExtractor::Extract(*packet_, AllSupportedVersions(), {},
&delegate_,
@@ -165,7 +169,11 @@
}
TEST_F(ChloExtractorTest, DoesNotFindInvalidChlo) {
- MakePacket(AllSupportedVersions()[0], "foo", /*munge_offset*/ false,
+ ParsedQuicVersion version = AllSupportedVersions()[0];
+ if (QuicVersionUsesCryptoFrames(version.transport_version)) {
+ return;
+ }
+ MakePacket(version, "foo", /*munge_offset*/ false,
/*munge_stream_id*/ true);
EXPECT_FALSE(ChloExtractor::Extract(*packet_, AllSupportedVersions(), {},
&delegate_,
diff --git a/quic/core/congestion_control/uber_loss_algorithm_test.cc b/quic/core/congestion_control/uber_loss_algorithm_test.cc
index 33b9393..1fe3465 100644
--- a/quic/core/congestion_control/uber_loss_algorithm_test.cc
+++ b/quic/core/congestion_control/uber_loss_algorithm_test.cc
@@ -31,12 +31,17 @@
void SendPacket(uint64_t packet_number, EncryptionLevel encryption_level) {
QuicStreamFrame frame;
- frame.stream_id =
- encryption_level == ENCRYPTION_INITIAL
- ? QuicUtils::GetCryptoStreamId(
- CurrentSupportedVersions()[0].transport_version)
- : QuicUtils::GetHeadersStreamId(
- CurrentSupportedVersions()[0].transport_version);
+ QuicTransportVersion version =
+ CurrentSupportedVersions()[0].transport_version;
+ frame.stream_id = QuicUtils::GetHeadersStreamId(version);
+ if (encryption_level == ENCRYPTION_INITIAL) {
+ if (QuicVersionUsesCryptoFrames(version)) {
+ frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ version, Perspective::IS_CLIENT);
+ } else {
+ frame.stream_id = QuicUtils::GetCryptoStreamId(version);
+ }
+ }
SerializedPacket packet(QuicPacketNumber(packet_number),
PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
false, false);
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 599f939..77d105c 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -207,10 +207,8 @@
EXPECT_TRUE(session_->IsEncryptionEstablished());
QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
ASSERT_TRUE(stream != nullptr);
- if (!QuicVersionUsesCryptoFrames(GetParam().transport_version)) {
- EXPECT_NE(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- stream->id());
- }
+ EXPECT_FALSE(QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ stream->id()));
// Process an "inchoate" REJ from the server which will cause
// an inchoate CHLO to be sent and will leave the encryption level
@@ -300,11 +298,8 @@
// frame; pretend we got one.
// Note that this is to be the second stream created, hence
- // the stream count is 4 (the two streams created as a part of
- // the test plus the crypto and header stream, internally created).
- // TODO(nharper): Change 4 to 3 & update comment accordingly when the crypto
- // stuff is no longer in a regular stream.
- // TODO(fkastenholz): do above if nharper doesn't :-)
+ // the stream count is 3 (the two streams created as a part of
+ // the test plus the header stream, internally created).
QuicMaxStreamsFrame frame(
0,
QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_)
@@ -316,11 +311,9 @@
stream = session_->CreateOutgoingBidirectionalStream();
EXPECT_NE(nullptr, stream);
if (GetParam().transport_version == QUIC_VERSION_99) {
- // Ensure that we have/have had four open streams, crypto, header, and the
- // two test streams. Primary purpose of this is to fail when crypto
- // no longer uses a normal stream. Some above constants will then need
- // to be changed.
- EXPECT_EQ(4u,
+ // Ensure that we have/have had three open streams: two test streams and the
+ // header stream.
+ EXPECT_EQ(3u,
QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_)
->outgoing_stream_count());
}
@@ -384,11 +377,8 @@
EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
if (GetParam().transport_version == QUIC_VERSION_99) {
// Note that this is to be the second stream created, hence
- // the stream count is 4 (the two streams created as a part of
- // the test plus the crypto and header stream, internally created).
- // TODO(nharper): Change 4 to 3 & update comment accordingly when the crypto
- // stuff is no longer in a regular stream.
- // TODO(fkastenholz): do above if nharper doesn't :-)
+ // the stream count is 3 (the two streams created as a part of
+ // the test plus the header stream, internally created).
QuicMaxStreamsFrame frame(
0,
QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_)
@@ -401,11 +391,9 @@
stream = session_->CreateOutgoingBidirectionalStream();
EXPECT_NE(nullptr, stream);
if (GetParam().transport_version == QUIC_VERSION_99) {
- // Ensure that we have/have had four open streams, crypto, header, and the
- // two test streams. Primary purpose of this is to fail when crypto
- // no longer uses a normal stream. Some above constants will then need
- // to be changed.
- EXPECT_EQ(4u,
+ // Ensure that we have/have had three open streams: two test streams and the
+ // header stream.
+ EXPECT_EQ(3u,
QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_)
->outgoing_stream_count());
}
@@ -448,7 +436,7 @@
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
session_->OnStreamHeaderList(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+ QuicUtils::GetHeadersStreamId(connection_->transport_version()),
/*fin=*/false, 0, trailers);
}
@@ -464,7 +452,7 @@
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
session_->OnPromiseHeaderList(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+ QuicUtils::GetHeadersStreamId(connection_->transport_version()),
promised_stream_id_, 0, trailers);
}
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index c7ce057..e0e417a 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -94,7 +94,7 @@
MOCK_METHOD0(OnCanWrite, void());
- bool HasPendingCryptoRetransmission() override { return false; }
+ bool HasPendingCryptoRetransmission() const override { return false; }
MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
@@ -241,9 +241,8 @@
QuicConsumedData SendStreamData(QuicStream* stream) {
struct iovec iov;
- if ((QuicVersionUsesCryptoFrames(connection()->transport_version()) ||
- stream->id() !=
- QuicUtils::GetCryptoStreamId(connection()->transport_version())) &&
+ if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+ stream->id()) &&
connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
}
@@ -396,6 +395,12 @@
if (perspective == Perspective::IS_SERVER) {
id |= 0x1;
}
+ if (bidirectional && perspective == Perspective::IS_CLIENT &&
+ QuicVersionUsesCryptoFrames(transport_version())) {
+ // Once stream ID 0 is used as a normal client initiated bidirectional
+ // stream, this shouldn't be needed any more.
+ id += 4;
+ }
return id;
}
@@ -1072,7 +1077,7 @@
TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
// Send two bytes of payload.
QuicStreamFrame data1(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), true, 0,
+ QuicUtils::GetHeadersStreamId(connection_->transport_version()), true, 0,
QuicStringPiece("HT"));
EXPECT_CALL(*connection_,
CloseConnection(
@@ -1085,7 +1090,7 @@
// Send two bytes of payload.
QuicRstStreamFrame rst1(
kInvalidControlFrameId,
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+ QuicUtils::GetHeadersStreamId(connection_->transport_version()),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(*connection_,
CloseConnection(
@@ -1559,7 +1564,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 28 would exceed stream count limit 7", _));
+ "Stream id 28 would exceed stream count limit 6", _));
}
// Create one more data streams to exceed limit of open stream.
QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index bcea7e5..d04efc5 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -146,9 +146,8 @@
http_decoder_visitor_(new HttpDecoderVisitor(this)),
body_buffer_(sequencer()),
ack_listener_(nullptr) {
- DCHECK_NE(QuicUtils::GetCryptoStreamId(
- spdy_session->connection()->transport_version()),
- id);
+ DCHECK(!QuicUtils::IsCryptoStreamId(
+ spdy_session->connection()->transport_version(), id));
// Don't receive any callbacks from the sequencer until headers
// are complete.
sequencer()->SetBlockedUntilFlush();
@@ -172,9 +171,8 @@
http_decoder_visitor_(new HttpDecoderVisitor(this)),
body_buffer_(sequencer()),
ack_listener_(nullptr) {
- DCHECK_NE(QuicUtils::GetCryptoStreamId(
- spdy_session->connection()->transport_version()),
- id());
+ DCHECK(!QuicUtils::IsCryptoStreamId(
+ spdy_session->connection()->transport_version(), id()));
// Don't receive any callbacks from the sequencer until headers
// are complete.
sequencer()->SetBlockedUntilFlush();
diff --git a/quic/core/legacy_quic_stream_id_manager.cc b/quic/core/legacy_quic_stream_id_manager.cc
index 6fb662a..447f16d 100644
--- a/quic/core/legacy_quic_stream_id_manager.cc
+++ b/quic/core/legacy_quic_stream_id_manager.cc
@@ -19,14 +19,18 @@
: session_(session),
max_open_outgoing_streams_(max_open_outgoing_streams),
max_open_incoming_streams_(max_open_incoming_streams),
- next_outgoing_stream_id_(
- QuicUtils::GetCryptoStreamId(
- session->connection()->transport_version()) +
- (session->perspective() == Perspective::IS_SERVER ? 1 : 2)),
+ next_outgoing_stream_id_(QuicUtils::GetFirstBidirectionalStreamId(
+ session->connection()->transport_version(),
+ session->perspective())),
largest_peer_created_stream_id_(
session->perspective() == Perspective::IS_SERVER
- ? QuicUtils::GetCryptoStreamId(
- session->connection()->transport_version())
+ ? (QuicVersionUsesCryptoFrames(
+ session->connection()->transport_version())
+ ? QuicUtils::GetFirstBidirectionalStreamId(
+ session->connection()->transport_version(),
+ Perspective::IS_CLIENT)
+ : QuicUtils::GetCryptoStreamId(
+ session->connection()->transport_version()))
: QuicUtils::GetInvalidStreamId(
session->connection()->transport_version())) {}
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index af388a9..c1d1d76 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1027,7 +1027,7 @@
if (debug_visitor_ != nullptr) {
debug_visitor_->OnStreamFrame(frame);
}
- if (frame.stream_id != QuicUtils::GetCryptoStreamId(transport_version()) &&
+ if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
if (MaybeConsiderAsMemoryCorruption(frame)) {
CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
@@ -3744,7 +3744,7 @@
bool QuicConnection::MaybeConsiderAsMemoryCorruption(
const QuicStreamFrame& frame) {
- if (frame.stream_id == QuicUtils::GetCryptoStreamId(transport_version()) ||
+ if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
return false;
}
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index d80b55f..4ecb780 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -660,7 +660,7 @@
QuicStreamOffset offset,
StreamSendingState state) {
ScopedPacketFlusher flusher(this, NO_ACK);
- if (id != QuicUtils::GetCryptoStreamId(transport_version()) &&
+ if (!QuicUtils::IsCryptoStreamId(transport_version(), id) &&
this->encryption_level() == ENCRYPTION_INITIAL) {
this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
}
@@ -709,6 +709,11 @@
QuicConsumedData SendCryptoStreamData() {
QuicStreamOffset offset = 0;
QuicStringPiece data("chlo");
+ return SendCryptoDataWithString(data, offset);
+ }
+
+ QuicConsumedData SendCryptoDataWithString(QuicStringPiece data,
+ QuicStreamOffset offset) {
if (!QuicVersionUsesCryptoFrames(transport_version())) {
return SendStreamDataWithString(
QuicUtils::GetCryptoStreamId(transport_version()), data, offset,
@@ -815,6 +820,8 @@
next_effective_peer_addr_ = QuicMakeUnique<QuicSocketAddress>(addr);
}
+ SimpleDataProducer* producer() { return &producer_; }
+
using QuicConnection::active_effective_peer_migration_type;
using QuicConnection::IsCurrentPacketConnectivityProbing;
using QuicConnection::SelectMutualVersion;
@@ -917,14 +924,9 @@
creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
generator_(QuicConnectionPeer::GetPacketGenerator(&connection_)),
manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
- frame1_(QuicUtils::GetCryptoStreamId(version().transport_version),
- false,
- 0,
- QuicStringPiece(data1)),
- frame2_(QuicUtils::GetCryptoStreamId(version().transport_version),
- false,
- 3,
- QuicStringPiece(data2)),
+ frame1_(0, false, 0, QuicStringPiece(data1)),
+ frame2_(0, false, 3, QuicStringPiece(data2)),
+ crypto_frame_(ENCRYPTION_INITIAL, 0, QuicStringPiece(data1)),
packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
connection_id_included_(CONNECTION_ID_PRESENT),
notifier_(&connection_) {
@@ -944,6 +946,15 @@
QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
GetParam().no_stop_waiting);
}
+ QuicStreamId stream_id;
+ if (QuicVersionUsesCryptoFrames(version().transport_version)) {
+ stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ version().transport_version, Perspective::IS_CLIENT);
+ } else {
+ stream_id = QuicUtils::GetCryptoStreamId(version().transport_version);
+ }
+ frame1_.stream_id = stream_id;
+ frame2_.stream_id = stream_id;
connection_.set_visitor(&visitor_);
if (connection_.session_decides_what_to_write()) {
connection_.SetSessionNotifier(¬ifier_);
@@ -1180,6 +1191,29 @@
level);
}
+ size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
+ QuicPacketHeader header = ConstructPacketHeader(1000, ENCRYPTION_INITIAL);
+ QuicFrames frames;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frames.push_back(QuicFrame(&crypto_frame_));
+ } else {
+ frames.push_back(QuicFrame(frame1_));
+ }
+ std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+ char buffer[kMaxOutgoingPacketSize];
+ peer_creator_.set_encryption_level(ENCRYPTION_INITIAL);
+ size_t encrypted_length =
+ peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1000),
+ *packet, buffer, kMaxOutgoingPacketSize);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+ if (connection_.GetSendAlarm()->IsSet()) {
+ connection_.GetSendAlarm()->Fire();
+ }
+ return encrypted_length;
+ }
+
size_t ProcessDataPacketAtLevel(uint64_t number,
bool has_stop_waiting,
EncryptionLevel level) {
@@ -1302,9 +1336,8 @@
return packet;
}
- std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
- bool has_stop_waiting,
- EncryptionLevel level) {
+ QuicPacketHeader ConstructPacketHeader(uint64_t number,
+ EncryptionLevel level) {
QuicPacketHeader header;
if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
level < ENCRYPTION_FORWARD_SECURE) {
@@ -1344,7 +1377,13 @@
}
header.packet_number_length = packet_number_length_;
header.packet_number = QuicPacketNumber(number);
+ return header;
+ }
+ std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
+ bool has_stop_waiting,
+ EncryptionLevel level) {
+ QuicPacketHeader header = ConstructPacketHeader(number, level);
QuicFrames frames;
frames.push_back(QuicFrame(frame1_));
if (has_stop_waiting) {
@@ -1514,6 +1553,7 @@
QuicStreamFrame frame1_;
QuicStreamFrame frame2_;
+ QuicCryptoFrame crypto_frame_;
QuicAckFrame ack_;
QuicStopWaitingFrame stop_waiting_;
QuicPacketNumberLength packet_number_length_;
@@ -1533,19 +1573,27 @@
EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
EXPECT_TRUE(connection_.connected());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_));
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_));
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
// Cause change in self_address.
QuicIpAddress host;
host.FromString("1.1.1.1");
QuicSocketAddress self_address(host, 123);
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), self_address,
- kPeerAddress);
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_));
+ } else {
+ EXPECT_CALL(visitor_, OnStreamFrame(_));
+ }
+ ProcessFramePacketWithAddresses(frame, self_address, kPeerAddress);
EXPECT_TRUE(connection_.connected());
}
@@ -1558,20 +1606,24 @@
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
EXPECT_TRUE(connection_.connected());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_));
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_));
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_));
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
// Cause change in self_address.
QuicIpAddress host;
host.FromString("1.1.1.1");
QuicSocketAddress self_address(host, 123);
EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_ERROR_MIGRATING_ADDRESS, _, _));
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), self_address,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, self_address, kPeerAddress);
EXPECT_FALSE(connection_.connected());
}
@@ -1584,26 +1636,29 @@
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
EXPECT_TRUE(connection_.connected());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+ }
QuicIpAddress host;
host.FromString("1.1.1.1");
QuicSocketAddress self_address1(host, 443);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), self_address1,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, self_address1, kPeerAddress);
// Cause self_address change to mapped Ipv4 address.
QuicIpAddress host2;
host2.FromString(
QuicStrCat("::ffff:", connection_.self_address().host().ToString()));
QuicSocketAddress self_address2(host2, connection_.self_address().port());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), self_address2,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, self_address2, kPeerAddress);
EXPECT_TRUE(connection_.connected());
// self_address change back to Ipv4 address.
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), self_address1,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, self_address1, kPeerAddress);
EXPECT_TRUE(connection_.connected());
}
@@ -1619,16 +1674,21 @@
QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
QuicSocketAddress());
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
const QuicSocketAddress kNewPeerAddress =
QuicSocketAddress(QuicIpAddress::Loopback6(),
/*port=*/23456);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kNewPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
@@ -1636,8 +1696,7 @@
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
// This is an old packet, do not migrate.
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
}
@@ -1656,12 +1715,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -1670,8 +1734,7 @@
const QuicSocketAddress kNewPeerAddress =
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kNewPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
}
@@ -1692,12 +1755,17 @@
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
@@ -1707,8 +1775,7 @@
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
@@ -1737,8 +1804,7 @@
connection_.ReturnEffectivePeerAddressForNextPacket(
kNewerEffectivePeerAddress);
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kFinalPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kFinalPeerAddress);
EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address());
EXPECT_EQ(PORT_CHANGE, connection_.active_effective_peer_migration_type());
@@ -1752,8 +1818,7 @@
kNewestEffectivePeerAddress);
EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kFinalPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kFinalPeerAddress);
EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address());
EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
@@ -1774,12 +1839,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -1881,12 +1951,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -1916,8 +1991,7 @@
// Process another packet with the old peer address on server side will not
// start peer migration.
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
}
@@ -1936,13 +2010,18 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -1988,12 +2067,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -2018,8 +2102,7 @@
// side will start peer migration.
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kNewPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
}
@@ -2037,12 +2120,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -2079,12 +2167,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -2124,12 +2217,17 @@
QuicSocketAddress());
EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
@@ -2138,8 +2236,7 @@
const QuicSocketAddress kNewPeerAddress =
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kNewPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
}
@@ -2177,7 +2274,11 @@
QuicFrames frames;
QuicPaddingFrame padding;
- frames.push_back(QuicFrame(frame1_));
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frames.push_back(QuicFrame(&crypto_frame_));
+ } else {
+ frames.push_back(QuicFrame(frame1_));
+ }
frames.push_back(QuicFrame(padding));
std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxOutgoingPacketSize];
@@ -2187,7 +2288,11 @@
EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
framer_.set_version(version());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+ } else {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ }
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
@@ -2218,7 +2323,11 @@
QuicFrames frames;
QuicPaddingFrame padding;
- frames.push_back(QuicFrame(frame1_));
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frames.push_back(QuicFrame(&crypto_frame_));
+ } else {
+ frames.push_back(QuicFrame(frame1_));
+ }
frames.push_back(QuicFrame(padding));
std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxOutgoingPacketSize];
@@ -2228,7 +2337,11 @@
EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
framer_.set_version(version());
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+ } else {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ }
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
@@ -2587,7 +2700,8 @@
}
// Send a packet containing stream frame.
SendStreamDataToPeer(
- QuicUtils::GetCryptoStreamId(connection_.version().transport_version),
+ QuicUtils::GetFirstBidirectionalStreamId(
+ connection_.version().transport_version, Perspective::IS_CLIENT),
"bar", 0, NO_FIN, nullptr);
// Session will not be informed until receiving another 20 packets.
@@ -2917,9 +3031,13 @@
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacket(1);
QuicPacketNumber last_packet;
- SendStreamDataToPeer(
- QuicUtils::GetCryptoStreamId(connection_.version().transport_version),
- "foo", 0, NO_FIN, &last_packet);
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ connection_.SendCryptoDataWithString("foo", 0);
+ } else {
+ SendStreamDataToPeer(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
+ NO_FIN, &last_packet);
+ }
// Verify ack is bundled with outging packet.
EXPECT_FALSE(writer_->ack_frames().empty());
@@ -2960,6 +3078,7 @@
}
TEST_P(QuicConnectionTest, FramePackingSendv) {
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
// Send data in 1 packet by writing multiple blocks in a single iovector
// using writev.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
@@ -2970,25 +3089,25 @@
iov[0].iov_len = 4;
iov[1].iov_base = data + 4;
iov[1].iov_len = 2;
- connection_.SaveAndSendStreamData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), iov, 2, 6,
- 0, NO_FIN);
+ QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ connection_.transport_version(), Perspective::IS_CLIENT);
+ connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
// Parse the last packet and ensure multiple iovector blocks have
// been packed into a single stream frame from one stream.
- EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
+ EXPECT_EQ(0u, writer_->padding_frames().size());
QuicStreamFrame* frame = writer_->stream_frames()[0].get();
- EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
- frame->stream_id);
+ EXPECT_EQ(stream_id, frame->stream_id);
EXPECT_EQ("ABCDEF", QuicStringPiece(frame->data_buffer, frame->data_length));
}
TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
// Try to send two stream frames in 1 packet by using writev.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
@@ -2999,9 +3118,9 @@
iov[0].iov_len = 4;
iov[1].iov_base = data + 4;
iov[1].iov_len = 2;
- connection_.SaveAndSendStreamData(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), iov, 2, 6,
- 0, NO_FIN);
+ QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ connection_.transport_version(), Perspective::IS_CLIENT);
+ connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN);
EXPECT_EQ(1u, connection_.NumQueuedPackets());
EXPECT_TRUE(connection_.HasQueuedData());
@@ -3012,20 +3131,19 @@
EXPECT_EQ(0u, connection_.NumQueuedPackets());
// Parse the last packet and ensure it's one stream frame from one stream.
- EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->padding_frames().size());
- EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
+ EXPECT_EQ(0u, writer_->padding_frames().size());
+ EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
}
TEST_P(QuicConnectionTest, SendingZeroBytes) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
// Send a zero byte write with a fin using writev.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SaveAndSendStreamData(
- QuicUtils::GetHeadersStreamId(connection_.transport_version()), nullptr,
- 0, 0, 0, FIN);
+ QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ connection_.transport_version(), Perspective::IS_CLIENT);
+ connection_.SaveAndSendStreamData(stream_id, nullptr, 0, 0, 0, FIN);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
@@ -3040,8 +3158,7 @@
EXPECT_EQ(1u + extra_padding_frames, writer_->frame_count());
EXPECT_EQ(extra_padding_frames, writer_->padding_frames().size());
ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_.transport_version()),
- writer_->stream_frames()[0]->stream_id);
+ EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
EXPECT_TRUE(writer_->stream_frames()[0]->fin);
}
@@ -3563,7 +3680,7 @@
const bool has_stop_waiting = false;
const EncryptionLevel level = ENCRYPTION_INITIAL;
std::unique_ptr<QuicPacket> packet(ConstructDataPacket(
- received_packet_num, has_stop_waiting, ENCRYPTION_INITIAL));
+ received_packet_num, has_stop_waiting, ENCRYPTION_FORWARD_SECURE));
char buffer[kMaxOutgoingPacketSize];
size_t encrypted_length =
peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
@@ -3953,9 +4070,11 @@
// the end of the packet. We can test this to check which encrypter was used.
connection_.SetEncrypter(ENCRYPTION_INITIAL,
QuicMakeUnique<TaggingEncrypter>(0x01));
- SendStreamDataToPeer(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN, nullptr);
+ QuicByteCount packet_size;
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(SaveArg<3>(&packet_size));
+ connection_.SendCryptoDataWithString("foo", 0);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
@@ -3992,9 +4111,7 @@
// Attempt to send a handshake message and have the socket block.
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
BlockOnNextWrite();
- connection_.SendStreamDataWithString(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN);
+ connection_.SendCryptoDataWithString("foo", 0);
// The packet should be serialized, but not queued.
EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -4046,9 +4163,7 @@
QuicMakeUnique<TaggingEncrypter>(0x01));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- SendStreamDataToPeer(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN, nullptr);
+ connection_.SendCryptoDataWithString("foo", 0);
connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(0x02));
@@ -6235,9 +6350,7 @@
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessPacket(1);
- connection_.SendStreamDataWithString(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN);
+ connection_.SendCryptoDataWithString("foo", 0);
// Check that ack is bundled with outgoing crypto data.
if (GetParam().no_stop_waiting) {
EXPECT_EQ(3u, writer_->frame_count());
@@ -6254,14 +6367,10 @@
ProcessPacket(1);
BlockOnNextWrite();
writer_->set_is_write_blocked_data_buffered(true);
- connection_.SendStreamDataWithString(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
- NO_FIN);
+ connection_.SendCryptoDataWithString("foo", 0);
EXPECT_TRUE(writer_->IsWriteBlocked());
EXPECT_FALSE(connection_.HasQueuedData());
- connection_.SendStreamDataWithString(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), "bar", 3,
- NO_FIN);
+ connection_.SendCryptoDataWithString("bar", 3);
EXPECT_TRUE(writer_->IsWriteBlocked());
EXPECT_TRUE(connection_.HasQueuedData());
}
@@ -8209,13 +8318,18 @@
return;
}
set_perspective(Perspective::IS_SERVER);
- QuicStreamFrame stream_frame(
- QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 0u,
- QuicStringPiece());
+ QuicFrame frame;
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ frame = QuicFrame(&crypto_frame_);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+ } else {
+ frame = QuicFrame(QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+ 0u, QuicStringPiece()));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ }
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessFramePacketWithAddresses(QuicFrame(stream_frame), kSelfAddress,
- kPeerAddress);
+ ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress);
// Let connection process a Google QUIC packet.
peer_framer_.set_version_for_tests(
@@ -8334,10 +8448,13 @@
return;
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ }
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
use_tagging_decrypter();
// Receives packet 1000 in initial data.
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_INITIAL);
+ ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(0x02));
@@ -8382,10 +8499,13 @@
return;
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ }
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
use_tagging_decrypter();
// Receives packet 1000 in initial data.
- ProcessDataPacketAtLevel(1000, false, ENCRYPTION_INITIAL);
+ ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(0x02));
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc
index 2263546..f394b3d 100644
--- a/quic/core/quic_crypto_stream.cc
+++ b/quic/core/quic_crypto_stream.cc
@@ -24,8 +24,12 @@
" ")
QuicCryptoStream::QuicCryptoStream(QuicSession* session)
- : QuicStream(QuicUtils::GetCryptoStreamId(
- session->connection()->transport_version()),
+ : QuicStream(QuicVersionUsesCryptoFrames(
+ session->connection()->transport_version())
+ ? QuicUtils::GetInvalidStreamId(
+ session->connection()->transport_version())
+ : QuicUtils::GetCryptoStreamId(
+ session->connection()->transport_version()),
session,
/*is_static=*/true,
QuicVersionUsesCryptoFrames(
@@ -159,6 +163,9 @@
size_t bytes_consumed =
session()->connection()->SendCryptoData(level, data.length(), offset);
session()->connection()->SetDefaultEncryptionLevel(current_level);
+ // Since CRYPTO frames aren't flow controlled, SendCryptoData should have sent
+ // all data we asked it to send.
+ DCHECK_EQ(bytes_consumed, data.length());
send_buffer->OnStreamDataConsumed(bytes_consumed);
}
@@ -213,7 +220,7 @@
QuicStream::OnStreamDataConsumed(bytes_consumed);
}
-bool QuicCryptoStream::HasPendingCryptoRetransmission() {
+bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
if (!QuicVersionUsesCryptoFrames(
session()->connection()->transport_version())) {
return false;
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h
index 0c6d08a..1b641b1 100644
--- a/quic/core/quic_crypto_stream.h
+++ b/quic/core/quic_crypto_stream.h
@@ -92,7 +92,7 @@
// Returns whether there are any bytes pending retransmission in CRYPTO
// frames.
- virtual bool HasPendingCryptoRetransmission();
+ virtual bool HasPendingCryptoRetransmission() const;
// Writes any pending CRYPTO frame retransmissions.
void WritePendingCryptoRetransmission();
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 831aac5..9af5f84 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -186,7 +186,8 @@
}
offset += frame.crypto_frame->data_length;
}
- if (offset < reject.length()) {
+ if (offset < reject.length() &&
+ !QuicVersionUsesCryptoFrames(framer_.transport_version())) {
DCHECK(!creator_.HasRoomForStreamFrame(
QuicUtils::GetCryptoStreamId(framer_.transport_version()), offset,
frame.stream_frame.data_length));
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 347df84..bf87ace 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -10012,7 +10012,7 @@
static QuicStreamId kTestQuicStreamId = 1;
static bool ExpectedStreamFrame(const QuicStreamFrame& frame) {
return (frame.stream_id == kTestQuicStreamId ||
- frame.stream_id == QuicUtils::GetCryptoStreamId(QUIC_VERSION_99)) &&
+ QuicUtils::IsCryptoStreamId(QUIC_VERSION_99, frame.stream_id)) &&
!frame.fin && frame.offset == 0 &&
std::string(frame.data_buffer, frame.data_length) == kTestString;
// FIN is hard-coded false in ConstructEncryptedPacket.
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index 0ffcc37..c013ce8 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -887,8 +887,8 @@
QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
<< transmission_type << ": " << frame;
if (frame.type == STREAM_FRAME &&
- frame.stream_frame.stream_id !=
- QuicUtils::GetCryptoStreamId(framer_->transport_version()) &&
+ !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+ frame.stream_frame.stream_id) &&
(packet_.encryption_level == ENCRYPTION_INITIAL ||
packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
const std::string error_details = QuicStrCat(
@@ -1011,8 +1011,8 @@
bool QuicPacketCreator::StreamFrameIsClientHello(
const QuicStreamFrame& frame) const {
if (framer_->perspective() == Perspective::IS_SERVER ||
- frame.stream_id !=
- QuicUtils::GetCryptoStreamId(framer_->transport_version())) {
+ !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+ frame.stream_id)) {
return false;
}
// The ClientHello is always sent with INITIAL encryption.
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index f87715b..655d587 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -1285,8 +1285,14 @@
const size_t max_plaintext_size =
client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version())));
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+ QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+ client_framer_.transport_version(), Perspective::IS_CLIENT);
+ if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+ stream_id =
+ QuicUtils::GetCryptoStreamId(client_framer_.transport_version());
+ }
+ EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
EXPECT_EQ(max_plaintext_size -
GetPacketHeaderSize(
client_framer_.transport_version(),
@@ -1307,20 +1313,17 @@
EXPECT_TRUE(
creator_.AddSavedFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version())));
+ EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
QuicFrame frame;
MakeIOVector("test", &iov_);
EXPECT_CALL(debug, OnFrameAddedToPacket(_));
- ASSERT_TRUE(creator_.ConsumeData(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_,
- 1u, iov_.iov_len, 0u, 0u, false, false, NOT_RETRANSMISSION, &frame));
+ ASSERT_TRUE(creator_.ConsumeData(stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u,
+ false, false, NOT_RETRANSMISSION, &frame));
size_t consumed = frame.stream_frame.data_length;
EXPECT_EQ(4u, consumed);
EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version())));
+ EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id));
QuicPaddingFrame padding_frame;
EXPECT_CALL(debug, OnFrameAddedToPacket(_));
@@ -1346,8 +1349,7 @@
DeleteSerializedPacket();
EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(
- QuicUtils::GetCryptoStreamId(client_framer_.transport_version())));
+ EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
EXPECT_EQ(max_plaintext_size -
GetPacketHeaderSize(
client_framer_.transport_version(),
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc
index ee15df0..d811f9d 100644
--- a/quic/core/quic_packet_generator.cc
+++ b/quic/core/quic_packet_generator.cc
@@ -138,7 +138,7 @@
QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
"generator tries to write stream data.";
bool has_handshake =
- (id == QuicUtils::GetCryptoStreamId(packet_creator_.transport_version()));
+ QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id);
if (deprecate_ack_bundling_mode_) {
MaybeBundleAckOpportunistically();
}
@@ -228,8 +228,7 @@
QuicStreamOffset offset,
bool fin,
size_t total_bytes_consumed) {
- DCHECK_NE(id,
- QuicUtils::GetCryptoStreamId(packet_creator_.transport_version()));
+ DCHECK(!QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id));
while (total_bytes_consumed < write_length &&
delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 705142a..676d6e7 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -587,16 +587,29 @@
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- MakeIOVector("foo bar", &iov_);
- QuicConsumedData consumed = generator_.ConsumeData(
- QuicUtils::GetCryptoStreamId(framer_.transport_version()), &iov_, 1u,
- iov_.iov_len, 0, NO_FIN);
- EXPECT_EQ(7u, consumed.bytes_consumed);
+ std::string data = "foo bar";
+ MakeIOVector(data, &iov_);
+ size_t consumed_bytes = 0;
+ if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+ consumed_bytes = generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+ } else {
+ consumed_bytes =
+ generator_
+ .ConsumeData(
+ QuicUtils::GetCryptoStreamId(framer_.transport_version()),
+ &iov_, 1u, iov_.iov_len, 0, NO_FIN)
+ .bytes_consumed;
+ }
+ EXPECT_EQ(7u, consumed_bytes);
EXPECT_FALSE(generator_.HasQueuedFrames());
EXPECT_FALSE(generator_.HasRetransmittableFrames());
PacketContents contents;
- contents.num_stream_frames = 1;
+ if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+ contents.num_crypto_frames = 1;
+ } else {
+ contents.num_stream_frames = 1;
+ }
contents.num_padding_frames = 1;
CheckPacketContains(contents, 0);
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index d56689f..96f98ad 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -102,6 +102,10 @@
connection_->SetDataProducer(this);
connection_->SetFromConfig(config_);
+ if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ return;
+ }
+
DCHECK_EQ(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
GetMutableCryptoStream()->id());
if (!eliminate_static_stream_map_) {
@@ -250,8 +254,8 @@
// make exceptions for them with respect to processing things like
// STOP_SENDING.
if (QuicContainsKey(static_stream_map_, stream_id) ||
- stream_id ==
- QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ stream_id)) {
QUIC_DVLOG(1) << ENDPOINT
<< "Received STOP_SENDING for a static stream, id: "
<< stream_id << " Closing connection";
@@ -658,6 +662,11 @@
}
bool QuicSession::HasPendingHandshake() const {
+ if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ // Writing CRYPTO frames is not subject to flow control, so there can't be
+ // pending data to write, only pending retransmissions.
+ return GetCryptoStream()->HasPendingCryptoRetransmission();
+ }
return QuicContainsKey(
streams_with_pending_retransmission_,
QuicUtils::GetCryptoStreamId(connection_->transport_version())) ||
@@ -687,7 +696,7 @@
// it might end up resulting in unencrypted stream data being sent.
// While this is impossible to avoid given sufficient corruption, this
// seems like a reasonable mitigation.
- if (id == QuicUtils::GetCryptoStreamId(connection_->transport_version()) &&
+ if (QuicUtils::IsCryptoStreamId(connection_->transport_version(), id) &&
stream != GetMutableCryptoStream()) {
QUIC_BUG << "Stream id mismatch";
connection_->CloseConnection(
@@ -697,7 +706,7 @@
return QuicConsumedData(0, false);
}
if (!IsEncryptionEstablished() &&
- id != QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ !QuicUtils::IsCryptoStreamId(connection_->transport_version(), id)) {
// Do not let streams write without encryption. The calling stream will end
// up write blocked until OnCanWrite is next called.
return QuicConsumedData(0, false);
@@ -1265,8 +1274,8 @@
QuicSession::StreamHandler QuicSession::GetOrCreateStreamImpl(
QuicStreamId stream_id) {
if (eliminate_static_stream_map_ &&
- stream_id ==
- QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ stream_id)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_eliminate_static_stream_map_2, 13, 17);
return StreamHandler(GetMutableCryptoStream());
}
@@ -1407,7 +1416,7 @@
if (QuicContainsKey(static_stream_map_, id) ||
QuicContainsKey(dynamic_stream_map_, id) ||
QuicContainsKey(pending_stream_map_, id) ||
- id == QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ QuicUtils::IsCryptoStreamId(connection_->transport_version(), id)) {
// Stream is active
return true;
}
@@ -1562,7 +1571,7 @@
}
if (eliminate_static_stream_map_ &&
- id == QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ QuicUtils::IsCryptoStreamId(connection_->transport_version(), id)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_eliminate_static_stream_map_2, 15, 17);
return const_cast<QuicCryptoStream*>(GetCryptoStream());
}
@@ -1803,7 +1812,8 @@
if (connection_->session_decides_what_to_write()) {
QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
crypto_stream->NeuterUnencryptedStreamData();
- if (!crypto_stream->HasPendingRetransmission()) {
+ if (!crypto_stream->HasPendingRetransmission() &&
+ !QuicVersionUsesCryptoFrames(connection_->transport_version())) {
streams_with_pending_retransmission_.erase(
QuicUtils::GetCryptoStreamId(connection_->transport_version()));
}
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 95bb6d4..deb6643 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -94,7 +94,7 @@
}
MOCK_METHOD0(OnCanWrite, void());
- bool HasPendingCryptoRetransmission() override { return false; }
+ bool HasPendingCryptoRetransmission() const override { return false; }
MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
@@ -109,7 +109,13 @@
class TestStream : public QuicStream {
public:
TestStream(QuicStreamId id, QuicSession* session, StreamType type)
- : QuicStream(id, session, /*is_static=*/false, type) {}
+ : TestStream(id, session, /*is_static=*/false, type) {}
+
+ TestStream(QuicStreamId id,
+ QuicSession* session,
+ bool is_static,
+ StreamType type)
+ : QuicStream(id, session, is_static, type) {}
TestStream(PendingStream pending, StreamType type)
: QuicStream(std::move(pending), type, /*is_static=*/false) {}
@@ -260,8 +266,8 @@
QuicConsumedData SendStreamData(QuicStream* stream) {
struct iovec iov;
- if (stream->id() !=
- QuicUtils::GetCryptoStreamId(connection()->transport_version()) &&
+ if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+ stream->id()) &&
this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
}
@@ -417,6 +423,10 @@
if (perspective == Perspective::IS_SERVER) {
id |= 0x1;
}
+ if (QuicVersionUsesCryptoFrames(connection_->transport_version()) &&
+ bidirectional && perspective == Perspective::IS_CLIENT) {
+ id += 4;
+ }
return id;
}
@@ -780,7 +790,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 800 would exceed stream count limit 51",
+ "Stream id 800 would exceed stream count limit 50",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET
))
@@ -1255,10 +1265,19 @@
}
TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
+ QuicStreamId headers_stream_id =
+ QuicUtils::GetHeadersStreamId(connection_->transport_version());
+ std::unique_ptr<TestStream> fake_headers_stream = QuicMakeUnique<TestStream>(
+ headers_stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
+ if (GetQuicReloadableFlag(quic_eliminate_static_stream_map_2)) {
+ QuicSessionPeer::RegisterStaticStreamNew(&session_,
+ std::move(fake_headers_stream));
+ } else {
+ QuicSessionPeer::RegisterStaticStream(&session_, headers_stream_id,
+ fake_headers_stream.get());
+ }
// Send two bytes of payload.
- QuicStreamFrame data1(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), true, 0,
- QuicStringPiece("HT"));
+ QuicStreamFrame data1(headers_stream_id, true, 0, QuicStringPiece("HT"));
EXPECT_CALL(*connection_,
CloseConnection(
QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
@@ -1267,11 +1286,20 @@
}
TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) {
+ QuicStreamId headers_stream_id =
+ QuicUtils::GetHeadersStreamId(connection_->transport_version());
+ std::unique_ptr<TestStream> fake_headers_stream = QuicMakeUnique<TestStream>(
+ headers_stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
+ if (GetQuicReloadableFlag(quic_eliminate_static_stream_map_2)) {
+ QuicSessionPeer::RegisterStaticStreamNew(&session_,
+ std::move(fake_headers_stream));
+ } else {
+ QuicSessionPeer::RegisterStaticStream(&session_, headers_stream_id,
+ fake_headers_stream.get());
+ }
// Send two bytes of payload.
- QuicRstStreamFrame rst1(
- kInvalidControlFrameId,
- QuicUtils::GetCryptoStreamId(connection_->transport_version()),
- QUIC_ERROR_PROCESSING_STREAM, 0);
+ QuicRstStreamFrame rst1(kInvalidControlFrameId, headers_stream_id,
+ QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(*connection_,
CloseConnection(
QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream",
@@ -1620,7 +1648,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 24 would exceed stream count limit 6", _));
+ "Stream id 24 would exceed stream count limit 5", _));
} else {
EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
EXPECT_CALL(*connection_,
@@ -1916,9 +1944,12 @@
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
- QuicStreamFrame frame1(
- QuicUtils::GetCryptoStreamId(connection_->transport_version()), false, 0,
- 1300);
+ QuicStreamFrame frame1;
+ if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ frame1 = QuicStreamFrame(
+ QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
+ 0, 1300);
+ }
QuicStreamFrame frame2(stream2->id(), false, 0, 9);
QuicStreamFrame frame3(stream4->id(), false, 0, 9);
@@ -2354,7 +2385,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID,
- "Stream id 404 would exceed stream count limit 101", _));
+ "Stream id 404 would exceed stream count limit 100", _));
session_.OnStreamFrame(bidirectional_stream_frame);
QuicStreamId unidirectional_stream_id = StreamCountToId(
@@ -2395,9 +2426,19 @@
// Applicable only to V99
return;
}
+ QuicStreamId stream_id = 0;
+ std::unique_ptr<TestStream> fake_static_stream = QuicMakeUnique<TestStream>(
+ stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
+ if (GetQuicReloadableFlag(quic_eliminate_static_stream_map_2)) {
+ QuicSessionPeer::RegisterStaticStreamNew(&session_,
+ std::move(fake_static_stream));
+ } else {
+ QuicSessionPeer::RegisterStaticStream(&session_, stream_id,
+ fake_static_stream.get());
+ }
// Check that a stream id in the static stream map is ignored.
// Note that the notion of a static stream is Google-specific.
- QuicStopSendingFrame frame(1, 0, 123);
+ QuicStopSendingFrame frame(1, stream_id, 123);
EXPECT_CALL(*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID,
"Received STOP_SENDING for a static stream", _));
diff --git a/quic/core/quic_stream_id_manager.cc b/quic/core/quic_stream_id_manager.cc
index 94a8487..7fac723 100644
--- a/quic/core/quic_stream_id_manager.cc
+++ b/quic/core/quic_stream_id_manager.cc
@@ -283,24 +283,6 @@
return false;
}
- // This is a stream id for a stream that is started by this node
- if (perspective() == Perspective::IS_CLIENT &&
- stream_id == QuicUtils::GetCryptoStreamId(transport_version())) {
- // TODO(fkastenholz): When crypto is moved into the CRYPTO_STREAM
- // and streamID 0 is no longer special, this needs to be removed.
- // Stream-id-0 seems not be allocated via get-next-stream-id,
- // which would increment outgoing_stream_count_, so increment
- // the count here to account for it.
- // Do not need to update next_outgoing_stream_id_ because it is
- // initiated to 4 (that is, it skips the crypto stream ID).
- if (outgoing_stream_count_ >=
- QuicUtils::GetMaxStreamCount(unidirectional_, perspective())) {
- // Already at the implementation limit, return false...
- return false;
- }
- outgoing_stream_count_++;
- }
-
// Increase the outgoing_max_streams_ limit to reflect the semantic that
// outgoing_max_streams_ was inialized to a "maximum request/response" count
// and only becomes a maximum stream count when we receive the first
diff --git a/quic/core/quic_stream_id_manager_test.cc b/quic/core/quic_stream_id_manager_test.cc
index 164e911..79c4845 100644
--- a/quic/core/quic_stream_id_manager_test.cc
+++ b/quic/core/quic_stream_id_manager_test.cc
@@ -202,10 +202,14 @@
// If bidi, Crypto stream default created at start up, it is one
// more stream to account for since initialization is "number of
// request/responses" & crypto is added in to that, not streams.
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + (GetParam() ? 1u : 0u),
+ size_t extra_stream_count = 0;
+ if (GetParam() && !QuicVersionUsesCryptoFrames(transport_version())) {
+ extra_stream_count = 1;
+ }
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection + extra_stream_count,
stream_id_manager_->outgoing_max_streams());
// Test is predicated on having 1 static stream going if bidi, 0 if not...)
- EXPECT_EQ((GetParam() ? 1u : 0u),
+ EXPECT_EQ(extra_stream_count,
stream_id_manager_->outgoing_static_stream_count());
EXPECT_EQ(kDefaultMaxStreamsPerConnection,
@@ -243,7 +247,11 @@
// If bidi, Crypto stream default created at start up, it is one
// more stream to account for since initialization is "number of
// request/responses" & crypto is added in to that, not streams.
- EXPECT_EQ(implementation_max - 1u + (GetParam() ? 1u : 0u),
+ size_t extra_stream_count = 0;
+ if (GetParam() && !QuicVersionUsesCryptoFrames(transport_version())) {
+ extra_stream_count = 1;
+ }
+ EXPECT_EQ(implementation_max - 1u + extra_stream_count,
stream_id_manager_->outgoing_max_streams());
stream_id_manager_->AdjustMaxOpenOutgoingStreams(implementation_max);
@@ -496,7 +504,11 @@
// If bidi, Crypto stream default created at start up, it is one
// more stream to account for since initialization is "number of
// request/responses" & crypto is added in to that, not streams.
- EXPECT_EQ(number_of_streams + (IsBidi() ? 1u : 0u),
+ size_t extra_stream_count = 0;
+ if (IsBidi() && !QuicVersionUsesCryptoFrames(transport_version())) {
+ extra_stream_count = 1;
+ }
+ EXPECT_EQ(number_of_streams + extra_stream_count,
stream_id_manager_->outgoing_max_streams());
while (number_of_streams) {
EXPECT_TRUE(stream_id_manager_->CanOpenNextOutgoingStream());
@@ -515,7 +527,7 @@
// If bidi, Crypto stream default created at start up, it is one
// more stream to account for since initialization is "number of
// request/responses" & crypto is added in to that, not streams.
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + (IsBidi() ? 1u : 0u),
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection + extra_stream_count,
session_->save_frame().max_streams_frame.stream_count);
// If we try to get the next id (above the limit), it should cause a quic-bug.
EXPECT_QUIC_BUG(
@@ -783,7 +795,11 @@
// more stream to account for since initialization is "number of
// request/responses" & crypto is added in to that, not streams.
// Since this is the server, the stream is incoming.
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + (IsBidi() ? 1u : 0u),
+ size_t extra_stream_count = 0;
+ if (IsBidi() && !QuicVersionUsesCryptoFrames(transport_version())) {
+ extra_stream_count = 1;
+ }
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection + extra_stream_count,
stream_id_manager_->incoming_actual_max_streams());
EXPECT_EQ(kDefaultMaxStreamsPerConnection,
stream_id_manager_->outgoing_max_streams());
@@ -814,9 +830,17 @@
stream_id_manager_->incoming_actual_max_streams() + 20,
Perspective::IS_CLIENT); // This node is a server, incoming stream
// ids must be client-originated.
- std::string error_details =
- IsBidi() ? "Stream id 480 would exceed stream count limit 101"
- : "Stream id 478 would exceed stream count limit 100";
+ std::string error_details;
+ if (IsBidi()) {
+ if (QuicVersionUsesCryptoFrames(transport_version())) {
+ error_details = "Stream id 476 would exceed stream count limit 100";
+ } else {
+ error_details = "Stream id 480 would exceed stream count limit 101";
+ }
+ } else {
+ error_details = "Stream id 478 would exceed stream count limit 100";
+ }
+
EXPECT_CALL(*connection_,
CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
EXPECT_FALSE(
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc
index 85ce4f2..dc40122 100644
--- a/quic/core/quic_utils.cc
+++ b/quic/core/quic_utils.cc
@@ -383,9 +383,18 @@
// static
QuicStreamId QuicUtils::GetCryptoStreamId(QuicTransportVersion version) {
- // TODO(nharper): Change this to return GetInvalidStreamId for version 47 or
- // greater. Currently, too many things break with that change.
- return version == QUIC_VERSION_99 ? 0 : 1;
+ QUIC_BUG_IF(QuicVersionUsesCryptoFrames(version))
+ << "CRYPTO data aren't in stream frames; they have no stream ID.";
+ return QuicVersionUsesCryptoFrames(version) ? GetInvalidStreamId(version) : 1;
+}
+
+// static
+bool QuicUtils::IsCryptoStreamId(QuicTransportVersion version,
+ QuicStreamId stream_id) {
+ if (QuicVersionUsesCryptoFrames(version)) {
+ return false;
+ }
+ return stream_id == GetCryptoStreamId(version);
}
// static
@@ -453,6 +462,7 @@
QuicTransportVersion version,
Perspective perspective) {
if (perspective == Perspective::IS_CLIENT) {
+ // TODO(nharper): Return 0 instead of 4 when CRYPTO frames are used.
return version == QUIC_VERSION_99 ? 4 : 3;
}
return version == QUIC_VERSION_99 ? 1 : 2;
diff --git a/quic/core/quic_utils.h b/quic/core/quic_utils.h
index befeee7..bac025e 100644
--- a/quic/core/quic_utils.h
+++ b/quic/core/quic_utils.h
@@ -116,6 +116,11 @@
// Returns crypto stream ID of |version|.
static QuicStreamId GetCryptoStreamId(QuicTransportVersion version);
+ // Returns whether |id| is the stream ID for the crypto stream. If |version|
+ // is a version where crypto data doesn't go over stream frames, this function
+ // will always return false.
+ static bool IsCryptoStreamId(QuicTransportVersion version, QuicStreamId id);
+
// Returns headers stream ID of |version|.
static QuicStreamId GetHeadersStreamId(QuicTransportVersion version);
diff --git a/quic/test_tools/quic_server_session_base_peer.h b/quic/test_tools/quic_server_session_base_peer.h
index 30c9b22..d2a21a6 100644
--- a/quic/test_tools/quic_server_session_base_peer.h
+++ b/quic/test_tools/quic_server_session_base_peer.h
@@ -21,9 +21,11 @@
static void SetCryptoStream(QuicServerSessionBase* s,
QuicCryptoServerStream* crypto_stream) {
s->crypto_stream_.reset(crypto_stream);
- s->RegisterStaticStream(
- QuicUtils::GetCryptoStreamId(s->connection()->transport_version()),
- crypto_stream);
+ if (!QuicVersionUsesCryptoFrames(s->connection()->transport_version())) {
+ s->RegisterStaticStream(
+ QuicUtils::GetCryptoStreamId(s->connection()->transport_version()),
+ crypto_stream);
+ }
}
static bool IsBandwidthResumptionEnabled(QuicServerSessionBase* s) {
return s->bandwidth_resumption_enabled_;
diff --git a/quic/test_tools/quic_session_peer.cc b/quic/test_tools/quic_session_peer.cc
index 0683fd7..ed7043d 100644
--- a/quic/test_tools/quic_session_peer.cc
+++ b/quic/test_tools/quic_session_peer.cc
@@ -166,6 +166,20 @@
}
// static
+void QuicSessionPeer::RegisterStaticStream(QuicSession* session,
+ QuicStreamId id,
+ QuicStream* stream) {
+ return session->RegisterStaticStream(id, stream);
+}
+
+// static
+void QuicSessionPeer::RegisterStaticStreamNew(
+ QuicSession* session,
+ std::unique_ptr<QuicStream> stream) {
+ return session->RegisterStaticStreamNew(std::move(stream));
+}
+
+// static
bool QuicSessionPeer::IsStreamClosed(QuicSession* session, QuicStreamId id) {
DCHECK_NE(0u, id);
return session->IsClosedStream(id);
diff --git a/quic/test_tools/quic_session_peer.h b/quic/test_tools/quic_session_peer.h
index 994a36c..3828981 100644
--- a/quic/test_tools/quic_session_peer.h
+++ b/quic/test_tools/quic_session_peer.h
@@ -64,6 +64,11 @@
QuicSession* session);
static void ActivateStream(QuicSession* session,
std::unique_ptr<QuicStream> stream);
+ static void RegisterStaticStream(QuicSession* session,
+ QuicStreamId stream_id,
+ QuicStream* stream);
+ static void RegisterStaticStreamNew(QuicSession* session,
+ std::unique_ptr<QuicStream> stream);
// Discern the state of a stream. Exactly one of these should be true at a
// time for any stream id > 0 (other than the special streams 1 and 3).
diff --git a/quic/test_tools/simple_session_notifier.cc b/quic/test_tools/simple_session_notifier.cc
index 9ae4d22..e72e0e1 100644
--- a/quic/test_tools/simple_session_notifier.cc
+++ b/quic/test_tools/simple_session_notifier.cc
@@ -72,7 +72,7 @@
QuicByteCount data_length,
bool fin) {
StreamState& state = stream_map_.find(id)->second;
- if (id == QuicUtils::GetCryptoStreamId(connection_->transport_version()) &&
+ if (QuicUtils::IsCryptoStreamId(connection_->transport_version(), id) &&
data_length > 0) {
crypto_bytes_transferred_[connection_->encryption_level()].Add(
offset, offset + data_length);
@@ -127,8 +127,11 @@
}
void SimpleSessionNotifier::NeuterUnencryptedData() {
+ // TODO(nharper): Handle CRYPTO frame case.
+ if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ return;
+ }
for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
- // TODO(nharper): Handle CRYPTO frame case.
QuicStreamFrame stream_frame(
QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
interval.min(), interval.max() - interval.min());
@@ -146,7 +149,6 @@
return;
}
// Write new data.
- // TODO(nharper): Write CRYPTO frames.
for (const auto& pair : stream_map_) {
const auto& state = pair.second;
if (!StreamHasBufferedData(pair.first)) {
@@ -320,8 +322,8 @@
EncryptionLevel retransmission_encryption_level =
connection_->encryption_level();
EncryptionLevel current_encryption_level = connection_->encryption_level();
- if (frame.stream_frame.stream_id ==
- QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ frame.stream_frame.stream_id)) {
for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
retransmission_encryption_level = static_cast<EncryptionLevel>(i);
@@ -339,8 +341,8 @@
const bool can_bundle_fin =
retransmit_fin &&
(retransmission_offset + retransmission_length == state.bytes_sent);
- if (frame.stream_frame.stream_id ==
- QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ frame.stream_frame.stream_id)) {
// Set appropriate encryption level for crypto stream.
connection_->SetDefaultEncryptionLevel(retransmission_encryption_level);
}
@@ -356,8 +358,8 @@
if (can_bundle_fin) {
retransmit_fin = !consumed.fin_consumed;
}
- if (frame.stream_frame.stream_id ==
- QuicUtils::GetCryptoStreamId(connection_->transport_version())) {
+ if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+ frame.stream_frame.stream_id)) {
// Restore encryption level.
connection_->SetDefaultEncryptionLevel(current_encryption_level);
}
@@ -497,7 +499,36 @@
}
bool SimpleSessionNotifier::RetransmitLostCryptoData() {
- // TODO(nharper): Handle CRYPTO frame case.
+ if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ for (EncryptionLevel level :
+ {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+ ENCRYPTION_FORWARD_SECURE}) {
+ auto& state = crypto_state_[level];
+ while (!state.pending_retransmissions.Empty()) {
+ connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
+ EncryptionLevel current_encryption_level =
+ connection_->encryption_level();
+ connection_->SetDefaultEncryptionLevel(level);
+ QuicIntervalSet<QuicStreamOffset> retransmission(
+ state.pending_retransmissions.begin()->min(),
+ state.pending_retransmissions.begin()->max());
+ retransmission.Intersection(crypto_bytes_transferred_[level]);
+ QuicStreamOffset retransmission_offset = retransmission.begin()->min();
+ QuicByteCount retransmission_length =
+ retransmission.begin()->max() - retransmission.begin()->min();
+ size_t bytes_consumed = connection_->SendCryptoData(
+ level, retransmission_length, retransmission_offset);
+ // Restore encryption level.
+ connection_->SetDefaultEncryptionLevel(current_encryption_level);
+ state.pending_retransmissions.Difference(
+ retransmission_offset, retransmission_offset + bytes_consumed);
+ if (bytes_consumed < retransmission_length) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
if (!QuicContainsKey(stream_map_, QuicUtils::GetCryptoStreamId(
connection_->transport_version()))) {
return true;
diff --git a/quic/test_tools/simple_session_notifier_test.cc b/quic/test_tools/simple_session_notifier_test.cc
index 53712fd..e5298eb 100644
--- a/quic/test_tools/simple_session_notifier_test.cc
+++ b/quic/test_tools/simple_session_notifier_test.cc
@@ -4,10 +4,12 @@
#include "net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h"
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.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"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
using testing::_;
using testing::InSequence;
@@ -126,6 +128,9 @@
}
TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ return;
+ }
InSequence s;
// Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
@@ -159,6 +164,9 @@
}
TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ return;
+ }
InSequence s;
// Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
@@ -221,6 +229,71 @@
EXPECT_FALSE(notifier_.WillingToWrite());
}
+TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
+ if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ return;
+ }
+ SimpleDataProducer producer;
+ connection_.SetDataProducer(&producer);
+ InSequence s;
+ // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
+ .WillOnce(Invoke(&connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, std::string(1024, 'a'));
+ producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, std::string(524, 'a'));
+ notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
+ // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+ connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<NullEncrypter>(
+ Perspective::IS_CLIENT));
+ EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
+ .WillOnce(Invoke(&connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, std::string(1024, 'a'));
+ notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
+ // Send stream 3 [0, 1024) and connection is blocked.
+ EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
+ .WillOnce(Return(QuicConsumedData(512, false)));
+ notifier_.WriteOrBufferData(3, 1024, FIN);
+ // Send stream 5 [0, 1024).
+ EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
+ notifier_.WriteOrBufferData(5, 1024, NO_FIN);
+ // Reset stream 5 with error.
+ EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
+ notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
+
+ // Lost crypto data [500, 1500) and stream 3 [0, 512).
+ QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
+ QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
+ QuicStreamFrame stream3_frame(3, false, 0, 512);
+ notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
+ notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
+ notifier_.OnFrameLost(QuicFrame(stream3_frame));
+
+ // Connection becomes writable.
+ // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
+ // they are in different encryption levels.
+ EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
+ .WillOnce(Invoke(&connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
+ .WillOnce(Invoke(&connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ // Lost stream 3 data gets retransmitted.
+ EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
+ .WillOnce(Return(QuicConsumedData(512, false)));
+ // Buffered control frames get sent.
+ EXPECT_CALL(connection_, SendControlFrame(_))
+ .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+ // Buffered stream 3 data [512, 1024) gets sent.
+ EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
+ .WillOnce(Return(QuicConsumedData(512, true)));
+ notifier_.OnCanWrite();
+ EXPECT_FALSE(notifier_.WillingToWrite());
+}
+
TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
InSequence s;
// Send stream 3 data [0, 10) and fin.
diff --git a/quic/tools/quic_simple_server_session_test.cc b/quic/tools/quic_simple_server_session_test.cc
index 7429732..aa9104a 100644
--- a/quic/tools/quic_simple_server_session_test.cc
+++ b/quic/tools/quic_simple_server_session_test.cc
@@ -54,9 +54,11 @@
static void SetCryptoStream(QuicSimpleServerSession* s,
QuicCryptoServerStream* crypto_stream) {
s->crypto_stream_.reset(crypto_stream);
- s->RegisterStaticStream(
- QuicUtils::GetCryptoStreamId(s->connection()->transport_version()),
- crypto_stream);
+ if (!QuicVersionUsesCryptoFrames(s->connection()->transport_version())) {
+ s->RegisterStaticStream(
+ QuicUtils::GetCryptoStreamId(s->connection()->transport_version()),
+ crypto_stream);
+ }
}
static QuicSpdyStream* CreateIncomingStream(QuicSimpleServerSession* s,