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/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.