1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/third_party/quiche/src/quic/core/quic_session.h"
6
7 #include <cstdint>
8 #include <set>
9 #include <string>
10 #include <utility>
11
12 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
13 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
14 #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
15 #include "net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h"
16 #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
17 #include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
18 #include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
19 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
20 #include "net/third_party/quiche/src/quic/core/quic_stream.h"
21 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
22 #include "net/third_party/quiche/src/quic/core/quic_versions.h"
23 #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
24 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
25 #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
26 #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h"
27 #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
28 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
29 #include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
30 #include "net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h"
31 #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
32 #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
33 #include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
34 #include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
35 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
36 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
37 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h"
38 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
39 #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
40 #include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
41 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
42 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
43
44 using spdy::kV3HighestPriority;
45 using spdy::SpdyPriority;
46 using testing::_;
47 using testing::AtLeast;
48 using testing::InSequence;
49 using testing::Invoke;
50 using testing::NiceMock;
51 using testing::Return;
52 using testing::StrictMock;
53 using testing::WithArg;
54
55 namespace quic {
56 namespace test {
57 namespace {
58
59 class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
60 public:
TestCryptoStream(QuicSession * session)61 explicit TestCryptoStream(QuicSession* session)
62 : QuicCryptoStream(session),
63 QuicCryptoHandshaker(this, session),
64 encryption_established_(false),
65 one_rtt_keys_available_(false),
66 params_(new QuicCryptoNegotiatedParameters) {
67 // Simulate a negotiated cipher_suite with a fake value.
68 params_->cipher_suite = 1;
69 }
70
OnHandshakeMessage(const CryptoHandshakeMessage &)71 void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
72 encryption_established_ = true;
73 one_rtt_keys_available_ = true;
74 QuicErrorCode error;
75 std::string error_details;
76 session()->config()->SetInitialStreamFlowControlWindowToSend(
77 kInitialStreamFlowControlWindowForTest);
78 session()->config()->SetInitialSessionFlowControlWindowToSend(
79 kInitialSessionFlowControlWindowForTest);
80 if (session()->connection()->version().handshake_protocol ==
81 PROTOCOL_TLS1_3) {
82 TransportParameters transport_parameters;
83 EXPECT_TRUE(
84 session()->config()->FillTransportParameters(&transport_parameters));
85 error = session()->config()->ProcessTransportParameters(
86 transport_parameters, CLIENT, &error_details);
87 } else {
88 CryptoHandshakeMessage msg;
89 session()->config()->ToHandshakeMessage(&msg, transport_version());
90 error =
91 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
92 }
93 EXPECT_THAT(error, IsQuicNoError());
94 session()->OnConfigNegotiated();
95 if (session()->connection()->version().handshake_protocol ==
96 PROTOCOL_TLS1_3) {
97 session()->OnOneRttKeysAvailable();
98 } else {
99 session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
100 }
101 session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
102 }
103
104 // QuicCryptoStream implementation
encryption_established() const105 bool encryption_established() const override {
106 return encryption_established_;
107 }
one_rtt_keys_available() const108 bool one_rtt_keys_available() const override {
109 return one_rtt_keys_available_;
110 }
crypto_negotiated_params() const111 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
112 const override {
113 return *params_;
114 }
crypto_message_parser()115 CryptoMessageParser* crypto_message_parser() override {
116 return QuicCryptoHandshaker::crypto_message_parser();
117 }
OnPacketDecrypted(EncryptionLevel)118 void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
OnOneRttPacketAcknowledged()119 void OnOneRttPacketAcknowledged() override {}
OnHandshakeDoneReceived()120 void OnHandshakeDoneReceived() override {}
GetHandshakeState() const121 HandshakeState GetHandshakeState() const override {
122 return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
123 }
124
125 MOCK_METHOD0(OnCanWrite, void());
HasPendingCryptoRetransmission() const126 bool HasPendingCryptoRetransmission() const override { return false; }
127
128 MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
129
130 private:
131 using QuicCryptoStream::session;
132
133 bool encryption_established_;
134 bool one_rtt_keys_available_;
135 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
136 };
137
138 class TestStream : public QuicStream {
139 public:
TestStream(QuicStreamId id,QuicSession * session,StreamType type)140 TestStream(QuicStreamId id, QuicSession* session, StreamType type)
141 : TestStream(id, session, /*is_static=*/false, type) {}
142
TestStream(QuicStreamId id,QuicSession * session,bool is_static,StreamType type)143 TestStream(QuicStreamId id,
144 QuicSession* session,
145 bool is_static,
146 StreamType type)
147 : QuicStream(id, session, is_static, type) {}
148
TestStream(PendingStream * pending,StreamType type)149 TestStream(PendingStream* pending, StreamType type)
150 : QuicStream(pending, type, /*is_static=*/false) {}
151
152 using QuicStream::CloseReadSide;
153 using QuicStream::CloseWriteSide;
154 using QuicStream::WriteMemSlices;
155
OnDataAvailable()156 void OnDataAvailable() override {}
157
158 MOCK_METHOD0(OnCanWrite, void());
159 MOCK_METHOD4(RetransmitStreamData,
160 bool(QuicStreamOffset, QuicByteCount, bool, TransmissionType));
161
162 MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
163 };
164
165 class TestSession : public QuicSession {
166 public:
TestSession(QuicConnection * connection,MockQuicSessionVisitor * session_visitor)167 explicit TestSession(QuicConnection* connection,
168 MockQuicSessionVisitor* session_visitor)
169 : QuicSession(connection,
170 session_visitor,
171 DefaultQuicConfig(),
172 CurrentSupportedVersions(),
173 /*num_expected_unidirectional_static_streams = */ 0),
174 crypto_stream_(this),
175 writev_consumes_all_data_(false),
176 uses_pending_streams_(false),
177 num_incoming_streams_created_(0) {
178 Initialize();
179 this->connection()->SetEncrypter(
180 ENCRYPTION_FORWARD_SECURE,
181 std::make_unique<NullEncrypter>(connection->perspective()));
182 }
183
~TestSession()184 ~TestSession() override { DeleteConnection(); }
185
GetMutableCryptoStream()186 TestCryptoStream* GetMutableCryptoStream() override {
187 return &crypto_stream_;
188 }
189
GetCryptoStream() const190 const TestCryptoStream* GetCryptoStream() const override {
191 return &crypto_stream_;
192 }
193
CreateOutgoingBidirectionalStream()194 TestStream* CreateOutgoingBidirectionalStream() {
195 QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
196 if (id ==
197 QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
198 return nullptr;
199 }
200 TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
201 ActivateStream(QuicWrapUnique(stream));
202 return stream;
203 }
204
CreateOutgoingUnidirectionalStream()205 TestStream* CreateOutgoingUnidirectionalStream() {
206 TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
207 this, WRITE_UNIDIRECTIONAL);
208 ActivateStream(QuicWrapUnique(stream));
209 return stream;
210 }
211
CreateIncomingStream(QuicStreamId id)212 TestStream* CreateIncomingStream(QuicStreamId id) override {
213 // Enforce the limit on the number of open streams.
214 if (GetNumOpenIncomingStreams() + 1 >
215 max_open_incoming_bidirectional_streams() &&
216 !VersionHasIetfQuicFrames(connection()->transport_version())) {
217 // No need to do this test for version 99; it's done by
218 // QuicSession::GetOrCreateStream.
219 connection()->CloseConnection(
220 QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
221 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
222 return nullptr;
223 }
224
225 TestStream* stream =
226 new TestStream(id, this,
227 DetermineStreamType(
228 id, connection()->transport_version(), perspective(),
229 /*is_incoming=*/true, BIDIRECTIONAL));
230 ActivateStream(QuicWrapUnique(stream));
231 ++num_incoming_streams_created_;
232 return stream;
233 }
234
CreateIncomingStream(PendingStream * pending)235 TestStream* CreateIncomingStream(PendingStream* pending) override {
236 QuicStreamId id = pending->id();
237 TestStream* stream = new TestStream(
238 pending, DetermineStreamType(id, connection()->transport_version(),
239 perspective(),
240 /*is_incoming=*/true, BIDIRECTIONAL));
241 ActivateStream(QuicWrapUnique(stream));
242 ++num_incoming_streams_created_;
243 return stream;
244 }
245
246 // QuicSession doesn't do anything in this method. So it's overridden here to
247 // test that the session handles pending streams correctly in terms of
248 // receiving stream frames.
ProcessPendingStream(PendingStream * pending)249 bool ProcessPendingStream(PendingStream* pending) override {
250 struct iovec iov;
251 if (pending->sequencer()->GetReadableRegion(&iov)) {
252 // Create TestStream once the first byte is received.
253 CreateIncomingStream(pending);
254 return true;
255 }
256 return false;
257 }
258
IsClosedStream(QuicStreamId id)259 bool IsClosedStream(QuicStreamId id) {
260 return QuicSession::IsClosedStream(id);
261 }
262
GetOrCreateStream(QuicStreamId stream_id)263 QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
264 return QuicSession::GetOrCreateStream(stream_id);
265 }
266
ShouldKeepConnectionAlive() const267 bool ShouldKeepConnectionAlive() const override {
268 return GetNumActiveStreams() > 0;
269 }
270
WritevData(QuicStreamId id,size_t write_length,QuicStreamOffset offset,StreamSendingState state,TransmissionType type,quiche::QuicheOptional<EncryptionLevel> level)271 QuicConsumedData WritevData(
272 QuicStreamId id,
273 size_t write_length,
274 QuicStreamOffset offset,
275 StreamSendingState state,
276 TransmissionType type,
277 quiche::QuicheOptional<EncryptionLevel> level) override {
278 bool fin = state != NO_FIN;
279 QuicConsumedData consumed(write_length, fin);
280 if (!writev_consumes_all_data_) {
281 consumed =
282 QuicSession::WritevData(id, write_length, offset, state, type, level);
283 }
284 QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
285 id, consumed.bytes_consumed);
286 return consumed;
287 }
288
289 MOCK_METHOD1(OnCanCreateNewOutgoingStream, void(bool unidirectional));
290
set_writev_consumes_all_data(bool val)291 void set_writev_consumes_all_data(bool val) {
292 writev_consumes_all_data_ = val;
293 }
294
SendStreamData(QuicStream * stream)295 QuicConsumedData SendStreamData(QuicStream* stream) {
296 struct iovec iov;
297 if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
298 stream->id()) &&
299 this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
300 this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
301 }
302 MakeIOVector("not empty", &iov);
303 QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
304 QuicConsumedData consumed =
305 WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, QuicheNullOpt);
306 QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
307 consumed.bytes_consumed);
308 return consumed;
309 }
310
save_frame()311 const QuicFrame& save_frame() { return save_frame_; }
312
SaveFrame(const QuicFrame & frame)313 bool SaveFrame(const QuicFrame& frame) {
314 save_frame_ = frame;
315 DeleteFrame(&const_cast<QuicFrame&>(frame));
316 return true;
317 }
318
SendLargeFakeData(QuicStream * stream,int bytes)319 QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
320 DCHECK(writev_consumes_all_data_);
321 return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
322 QuicheNullOpt);
323 }
324
UsesPendingStreams() const325 bool UsesPendingStreams() const override { return uses_pending_streams_; }
326
set_uses_pending_streams(bool uses_pending_streams)327 void set_uses_pending_streams(bool uses_pending_streams) {
328 uses_pending_streams_ = uses_pending_streams;
329 }
330
num_incoming_streams_created() const331 int num_incoming_streams_created() const {
332 return num_incoming_streams_created_;
333 }
334
335 using QuicSession::ActivateStream;
336 using QuicSession::CanOpenNextOutgoingBidirectionalStream;
337 using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
338 using QuicSession::closed_streams;
339 using QuicSession::GetNextOutgoingBidirectionalStreamId;
340 using QuicSession::GetNextOutgoingUnidirectionalStreamId;
341 using QuicSession::zombie_streams;
342
343 private:
344 StrictMock<TestCryptoStream> crypto_stream_;
345
346 bool writev_consumes_all_data_;
347 bool uses_pending_streams_;
348 QuicFrame save_frame_;
349 int num_incoming_streams_created_;
350 };
351
352 class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
353 protected:
QuicSessionTestBase(Perspective perspective,bool configure_session)354 QuicSessionTestBase(Perspective perspective, bool configure_session)
355 : connection_(
356 new StrictMock<MockQuicConnection>(&helper_,
357 &alarm_factory_,
358 perspective,
359 SupportedVersions(GetParam()))),
360 session_(connection_, &session_visitor_),
361 configure_session_(configure_session) {
362 session_.config()->SetInitialStreamFlowControlWindowToSend(
363 kInitialStreamFlowControlWindowForTest);
364 session_.config()->SetInitialSessionFlowControlWindowToSend(
365 kInitialSessionFlowControlWindowForTest);
366
367 if (configure_session) {
368 if (VersionHasIetfQuicFrames(transport_version())) {
369 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
370 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(true)).Times(1);
371 }
372 QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
373 session_.config(), kDefaultMaxStreamsPerConnection);
374 QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
375 session_.config(), kDefaultMaxStreamsPerConnection);
376 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
377 session_.config(), kMinimumFlowControlSendWindow);
378 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
379 session_.config(), kMinimumFlowControlSendWindow);
380 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
381 session_.config(), kMinimumFlowControlSendWindow);
382 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
383 session_.config(), kMinimumFlowControlSendWindow);
384 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
385 session_.OnConfigNegotiated();
386 }
387 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
388 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
389 .Times(testing::AnyNumber());
390 testing::Mock::VerifyAndClearExpectations(&session_);
391 }
392
~QuicSessionTestBase()393 ~QuicSessionTestBase() {
394 if (configure_session_) {
395 EXPECT_TRUE(session_.is_configured());
396 }
397 }
398
CheckClosedStreams()399 void CheckClosedStreams() {
400 QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
401 connection_->transport_version(), Perspective::IS_CLIENT);
402 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
403 first_stream_id =
404 QuicUtils::GetCryptoStreamId(connection_->transport_version());
405 }
406 for (QuicStreamId i = first_stream_id; i < 100; i++) {
407 if (!QuicContainsKey(closed_streams_, i)) {
408 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
409 } else {
410 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
411 }
412 }
413 }
414
CloseStream(QuicStreamId id)415 void CloseStream(QuicStreamId id) {
416 if (VersionHasIetfQuicFrames(transport_version())) {
417 if (QuicUtils::GetStreamType(id, session_.perspective(),
418 session_.IsIncomingStream(id)) ==
419 READ_UNIDIRECTIONAL) {
420 // Verify reset is not sent for READ_UNIDIRECTIONAL streams.
421 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
422 EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(0);
423 } else if (QuicUtils::GetStreamType(id, session_.perspective(),
424 session_.IsIncomingStream(id)) ==
425 WRITE_UNIDIRECTIONAL) {
426 // Verify RESET_STREAM but not STOP_SENDING is sent for write-only
427 // stream.
428 EXPECT_CALL(*connection_, SendControlFrame(_))
429 .Times(1)
430 .WillOnce(Invoke(&ClearControlFrame));
431 EXPECT_CALL(*connection_, OnStreamReset(id, _));
432 } else {
433 // Verify RESET_STREAM and STOP_SENDING are sent for BIDIRECTIONAL
434 // streams.
435 EXPECT_CALL(*connection_, SendControlFrame(_))
436 .Times(2)
437 .WillRepeatedly(Invoke(&ClearControlFrame));
438 EXPECT_CALL(*connection_, OnStreamReset(id, _));
439 }
440 } else {
441 EXPECT_CALL(*connection_, SendControlFrame(_))
442 .WillOnce(Invoke(&ClearControlFrame));
443 EXPECT_CALL(*connection_, OnStreamReset(id, _));
444 }
445 session_.CloseStream(id);
446 closed_streams_.insert(id);
447 }
448
transport_version() const449 QuicTransportVersion transport_version() const {
450 return connection_->transport_version();
451 }
452
GetNthClientInitiatedBidirectionalId(int n)453 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
454 return QuicUtils::GetFirstBidirectionalStreamId(
455 connection_->transport_version(), Perspective::IS_CLIENT) +
456 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
457 }
458
GetNthClientInitiatedUnidirectionalId(int n)459 QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
460 return QuicUtils::GetFirstUnidirectionalStreamId(
461 connection_->transport_version(), Perspective::IS_CLIENT) +
462 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
463 }
464
GetNthServerInitiatedBidirectionalId(int n)465 QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
466 return QuicUtils::GetFirstBidirectionalStreamId(
467 connection_->transport_version(), Perspective::IS_SERVER) +
468 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
469 }
470
GetNthServerInitiatedUnidirectionalId(int n)471 QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
472 return QuicUtils::GetFirstUnidirectionalStreamId(
473 connection_->transport_version(), Perspective::IS_SERVER) +
474 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
475 }
476
StreamCountToId(QuicStreamCount stream_count,Perspective perspective,bool bidirectional)477 QuicStreamId StreamCountToId(QuicStreamCount stream_count,
478 Perspective perspective,
479 bool bidirectional) {
480 // Calculate and build up stream ID rather than use
481 // GetFirst... because tests that rely on this method
482 // needs to do the stream count where #1 is 0/1/2/3, and not
483 // take into account that stream 0 is special.
484 QuicStreamId id =
485 ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
486 if (!bidirectional) {
487 id |= 0x2;
488 }
489 if (perspective == Perspective::IS_SERVER) {
490 id |= 0x1;
491 }
492 return id;
493 }
494
495 MockQuicConnectionHelper helper_;
496 MockAlarmFactory alarm_factory_;
497 NiceMock<MockQuicSessionVisitor> session_visitor_;
498 StrictMock<MockQuicConnection>* connection_;
499 TestSession session_;
500 std::set<QuicStreamId> closed_streams_;
501 bool configure_session_;
502 };
503
504 class QuicSessionTestServer : public QuicSessionTestBase {
505 public:
506 // CheckMultiPathResponse validates that a written packet
507 // contains both expected path responses.
CheckMultiPathResponse(const char * buffer,size_t buf_len,const QuicIpAddress &,const QuicSocketAddress &,PerPacketOptions *)508 WriteResult CheckMultiPathResponse(const char* buffer,
509 size_t buf_len,
510 const QuicIpAddress& /*self_address*/,
511 const QuicSocketAddress& /*peer_address*/,
512 PerPacketOptions* /*options*/) {
513 QuicEncryptedPacket packet(buffer, buf_len);
514 {
515 InSequence s;
516 EXPECT_CALL(framer_visitor_, OnPacket());
517 EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
518 EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
519 EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
520 EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
521 EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
522 .WillOnce(
523 WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
524 EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
525 return true;
526 })));
527 EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
528 .WillOnce(
529 WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
530 EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
531 return true;
532 })));
533 EXPECT_CALL(framer_visitor_, OnPacketComplete());
534 }
535 client_framer_.ProcessPacket(packet);
536 return WriteResult(WRITE_STATUS_OK, 0);
537 }
538
539 protected:
QuicSessionTestServer()540 QuicSessionTestServer()
541 : QuicSessionTestBase(Perspective::IS_SERVER, /*configure_session=*/true),
542 path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
543 path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
544 client_framer_(SupportedVersions(GetParam()),
545 QuicTime::Zero(),
546 Perspective::IS_CLIENT,
547 kQuicDefaultConnectionIdLength) {
548 client_framer_.set_visitor(&framer_visitor_);
549 client_framer_.SetInitialObfuscators(TestConnectionId());
550 }
551
552 QuicPathFrameBuffer path_frame_buffer1_;
553 QuicPathFrameBuffer path_frame_buffer2_;
554 StrictMock<MockFramerVisitor> framer_visitor_;
555 // Framer used to process packets sent by server.
556 QuicFramer client_framer_;
557 };
558
559 INSTANTIATE_TEST_SUITE_P(Tests,
560 QuicSessionTestServer,
561 ::testing::ValuesIn(AllSupportedVersions()),
562 ::testing::PrintToStringParamName());
563
TEST_P(QuicSessionTestServer,PeerAddress)564 TEST_P(QuicSessionTestServer, PeerAddress) {
565 EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
566 session_.peer_address());
567 }
568
TEST_P(QuicSessionTestServer,SelfAddress)569 TEST_P(QuicSessionTestServer, SelfAddress) {
570 EXPECT_TRUE(session_.self_address().IsInitialized());
571 }
572
TEST_P(QuicSessionTestServer,DontCallOnWriteBlockedForDisconnectedConnection)573 TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
574 EXPECT_CALL(*connection_, CloseConnection(_, _, _))
575 .WillOnce(
576 Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
577 connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
578 ConnectionCloseBehavior::SILENT_CLOSE);
579 ASSERT_FALSE(connection_->connected());
580
581 EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
582 session_.OnWriteBlocked();
583 }
584
TEST_P(QuicSessionTestServer,OneRttKeysAvailable)585 TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
586 EXPECT_FALSE(session_.OneRttKeysAvailable());
587 CryptoHandshakeMessage message;
588 if (connection_->version().HasHandshakeDone()) {
589 EXPECT_CALL(*connection_, SendControlFrame(_));
590 }
591 session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
592 EXPECT_TRUE(session_.OneRttKeysAvailable());
593 }
594
TEST_P(QuicSessionTestServer,IsClosedStreamDefault)595 TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
596 // Ensure that no streams are initially closed.
597 QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
598 connection_->transport_version(), Perspective::IS_CLIENT);
599 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
600 first_stream_id =
601 QuicUtils::GetCryptoStreamId(connection_->transport_version());
602 }
603 for (QuicStreamId i = first_stream_id; i < 100; i++) {
604 EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
605 }
606 }
607
TEST_P(QuicSessionTestServer,AvailableBidirectionalStreams)608 TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
609 ASSERT_TRUE(session_.GetOrCreateStream(
610 GetNthClientInitiatedBidirectionalId(3)) != nullptr);
611 // Smaller bidirectional streams should be available.
612 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
613 &session_, GetNthClientInitiatedBidirectionalId(1)));
614 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
615 &session_, GetNthClientInitiatedBidirectionalId(2)));
616 ASSERT_TRUE(session_.GetOrCreateStream(
617 GetNthClientInitiatedBidirectionalId(2)) != nullptr);
618 ASSERT_TRUE(session_.GetOrCreateStream(
619 GetNthClientInitiatedBidirectionalId(1)) != nullptr);
620 }
621
TEST_P(QuicSessionTestServer,AvailableUnidirectionalStreams)622 TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
623 ASSERT_TRUE(session_.GetOrCreateStream(
624 GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
625 // Smaller unidirectional streams should be available.
626 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
627 &session_, GetNthClientInitiatedUnidirectionalId(1)));
628 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
629 &session_, GetNthClientInitiatedUnidirectionalId(2)));
630 ASSERT_TRUE(session_.GetOrCreateStream(
631 GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
632 ASSERT_TRUE(session_.GetOrCreateStream(
633 GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
634 }
635
TEST_P(QuicSessionTestServer,MaxAvailableBidirectionalStreams)636 TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
637 if (VersionHasIetfQuicFrames(transport_version())) {
638 EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
639 session_.MaxAvailableBidirectionalStreams());
640 } else {
641 // The protocol specification requires that there can be at least 10 times
642 // as many available streams as the connection's maximum open streams.
643 EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
644 kMaxAvailableStreamsMultiplier,
645 session_.MaxAvailableBidirectionalStreams());
646 }
647 }
648
TEST_P(QuicSessionTestServer,MaxAvailableUnidirectionalStreams)649 TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
650 if (VersionHasIetfQuicFrames(transport_version())) {
651 EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
652 session_.MaxAvailableUnidirectionalStreams());
653 } else {
654 // The protocol specification requires that there can be at least 10 times
655 // as many available streams as the connection's maximum open streams.
656 EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
657 kMaxAvailableStreamsMultiplier,
658 session_.MaxAvailableUnidirectionalStreams());
659 }
660 }
661
TEST_P(QuicSessionTestServer,IsClosedBidirectionalStreamLocallyCreated)662 TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
663 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
664 EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
665 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
666 EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
667
668 CheckClosedStreams();
669 CloseStream(GetNthServerInitiatedBidirectionalId(0));
670 CheckClosedStreams();
671 CloseStream(GetNthServerInitiatedBidirectionalId(1));
672 CheckClosedStreams();
673 }
674
TEST_P(QuicSessionTestServer,IsClosedUnidirectionalStreamLocallyCreated)675 TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
676 TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
677 EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
678 TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
679 EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
680
681 CheckClosedStreams();
682 CloseStream(GetNthServerInitiatedUnidirectionalId(0));
683 CheckClosedStreams();
684 CloseStream(GetNthServerInitiatedUnidirectionalId(1));
685 CheckClosedStreams();
686 }
687
TEST_P(QuicSessionTestServer,IsClosedBidirectionalStreamPeerCreated)688 TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
689 QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
690 QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
691 session_.GetOrCreateStream(stream_id1);
692 session_.GetOrCreateStream(stream_id2);
693
694 CheckClosedStreams();
695 CloseStream(stream_id1);
696 CheckClosedStreams();
697 CloseStream(stream_id2);
698 // Create a stream, and make another available.
699 QuicStream* stream3 = session_.GetOrCreateStream(
700 stream_id2 +
701 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
702 CheckClosedStreams();
703 // Close one, but make sure the other is still not closed
704 CloseStream(stream3->id());
705 CheckClosedStreams();
706 }
707
TEST_P(QuicSessionTestServer,IsClosedUnidirectionalStreamPeerCreated)708 TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
709 QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
710 QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
711 session_.GetOrCreateStream(stream_id1);
712 session_.GetOrCreateStream(stream_id2);
713
714 CheckClosedStreams();
715 CloseStream(stream_id1);
716 CheckClosedStreams();
717 CloseStream(stream_id2);
718 // Create a stream, and make another available.
719 QuicStream* stream3 = session_.GetOrCreateStream(
720 stream_id2 +
721 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
722 CheckClosedStreams();
723 // Close one, but make sure the other is still not closed
724 CloseStream(stream3->id());
725 CheckClosedStreams();
726 }
727
TEST_P(QuicSessionTestServer,MaximumAvailableOpenedBidirectionalStreams)728 TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
729 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
730 session_.GetOrCreateStream(stream_id);
731 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
732 EXPECT_NE(nullptr,
733 session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(
734 session_.max_open_incoming_bidirectional_streams() - 1)));
735 }
736
TEST_P(QuicSessionTestServer,MaximumAvailableOpenedUnidirectionalStreams)737 TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
738 QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
739 session_.GetOrCreateStream(stream_id);
740 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
741 EXPECT_NE(nullptr,
742 session_.GetOrCreateStream(GetNthClientInitiatedUnidirectionalId(
743 session_.max_open_incoming_unidirectional_streams() - 1)));
744 }
745
TEST_P(QuicSessionTestServer,TooManyAvailableBidirectionalStreams)746 TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
747 QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
748 QuicStreamId stream_id2;
749 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
750 // A stream ID which is too large to create.
751 stream_id2 = GetNthClientInitiatedBidirectionalId(
752 session_.MaxAvailableBidirectionalStreams() + 2);
753 if (VersionHasIetfQuicFrames(transport_version())) {
754 // IETF QUIC terminates the connection with invalid stream id
755 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
756 } else {
757 // other versions terminate the connection with
758 // QUIC_TOO_MANY_AVAILABLE_STREAMS.
759 EXPECT_CALL(*connection_,
760 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
761 }
762 EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
763 }
764
TEST_P(QuicSessionTestServer,TooManyAvailableUnidirectionalStreams)765 TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
766 QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
767 QuicStreamId stream_id2;
768 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
769 // A stream ID which is too large to create.
770 stream_id2 = GetNthClientInitiatedUnidirectionalId(
771 session_.MaxAvailableUnidirectionalStreams() + 2);
772 if (VersionHasIetfQuicFrames(transport_version())) {
773 // IETF QUIC terminates the connection with invalid stream id
774 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
775 } else {
776 // other versions terminate the connection with
777 // QUIC_TOO_MANY_AVAILABLE_STREAMS.
778 EXPECT_CALL(*connection_,
779 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
780 }
781 EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
782 }
783
TEST_P(QuicSessionTestServer,ManyAvailableBidirectionalStreams)784 TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
785 // When max_open_streams_ is 200, should be able to create 200 streams
786 // out-of-order, that is, creating the one with the largest stream ID first.
787 if (VersionHasIetfQuicFrames(transport_version())) {
788 QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
789 // Smaller limit on unidirectional streams to help detect crossed wires.
790 QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 50);
791 } else {
792 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
793 }
794 // Create a stream at the start of the range.
795 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
796 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
797
798 // Create the largest stream ID of a threatened total of 200 streams.
799 // GetNth... starts at 0, so for 200 streams, get the 199th.
800 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
801 EXPECT_NE(nullptr, session_.GetOrCreateStream(
802 GetNthClientInitiatedBidirectionalId(199)));
803
804 if (VersionHasIetfQuicFrames(transport_version())) {
805 // If IETF QUIC, check to make sure that creating bidirectional
806 // streams does not mess up the unidirectional streams.
807 stream_id = GetNthClientInitiatedUnidirectionalId(0);
808 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
809 // Now try to get the last possible unidirectional stream.
810 EXPECT_NE(nullptr, session_.GetOrCreateStream(
811 GetNthClientInitiatedUnidirectionalId(49)));
812 // and this should fail because it exceeds the unidirectional limit
813 // (but not the bi-)
814 EXPECT_CALL(
815 *connection_,
816 CloseConnection(QUIC_INVALID_STREAM_ID,
817 "Stream id 798 would exceed stream count limit 50",
818 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
819 .Times(1);
820 EXPECT_EQ(nullptr, session_.GetOrCreateStream(
821 GetNthClientInitiatedUnidirectionalId(199)));
822 }
823 }
824
TEST_P(QuicSessionTestServer,ManyAvailableUnidirectionalStreams)825 TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
826 // When max_open_streams_ is 200, should be able to create 200 streams
827 // out-of-order, that is, creating the one with the largest stream ID first.
828 if (VersionHasIetfQuicFrames(transport_version())) {
829 QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 200);
830 // Smaller limit on unidirectional streams to help detect crossed wires.
831 QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 50);
832 } else {
833 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
834 }
835 // Create one stream.
836 QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
837 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
838
839 // Create the largest stream ID of a threatened total of 200 streams.
840 // GetNth... starts at 0, so for 200 streams, get the 199th.
841 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
842 EXPECT_NE(nullptr, session_.GetOrCreateStream(
843 GetNthClientInitiatedUnidirectionalId(199)));
844 if (VersionHasIetfQuicFrames(transport_version())) {
845 // If IETF QUIC, check to make sure that creating unidirectional
846 // streams does not mess up the bidirectional streams.
847 stream_id = GetNthClientInitiatedBidirectionalId(0);
848 EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
849 // Now try to get the last possible bidirectional stream.
850 EXPECT_NE(nullptr, session_.GetOrCreateStream(
851 GetNthClientInitiatedBidirectionalId(49)));
852 // and this should fail because it exceeds the bnidirectional limit
853 // (but not the uni-)
854 std::string error_detail;
855 if (QuicVersionUsesCryptoFrames(transport_version())) {
856 error_detail = "Stream id 796 would exceed stream count limit 50";
857 } else {
858 error_detail = "Stream id 800 would exceed stream count limit 50";
859 }
860 EXPECT_CALL(
861 *connection_,
862 CloseConnection(QUIC_INVALID_STREAM_ID, error_detail,
863 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
864 .Times(1);
865 EXPECT_EQ(nullptr, session_.GetOrCreateStream(
866 GetNthClientInitiatedBidirectionalId(199)));
867 }
868 }
869
TEST_P(QuicSessionTestServer,DebugDFatalIfMarkingClosedStreamWriteBlocked)870 TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
871 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
872 QuicStreamId closed_stream_id = stream2->id();
873 // Close the stream.
874 EXPECT_CALL(*connection_, SendControlFrame(_));
875 EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
876 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
877 std::string msg = quiche::QuicheStrCat("Marking unknown stream ",
878 closed_stream_id, " blocked.");
879 EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
880 msg);
881 }
882
TEST_P(QuicSessionTestServer,OnCanWrite)883 TEST_P(QuicSessionTestServer, OnCanWrite) {
884 session_.set_writev_consumes_all_data(true);
885 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
886 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
887 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
888
889 session_.MarkConnectionLevelWriteBlocked(stream2->id());
890 session_.MarkConnectionLevelWriteBlocked(stream6->id());
891 session_.MarkConnectionLevelWriteBlocked(stream4->id());
892
893 InSequence s;
894
895 // Reregister, to test the loop limit.
896 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
897 session_.SendStreamData(stream2);
898 session_.MarkConnectionLevelWriteBlocked(stream2->id());
899 }));
900 // 2 will get called a second time as it didn't finish its block
901 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
902 session_.SendStreamData(stream2);
903 }));
904 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
905 session_.SendStreamData(stream6);
906 }));
907 // 4 will not get called, as we exceeded the loop limit.
908 session_.OnCanWrite();
909 EXPECT_TRUE(session_.WillingAndAbleToWrite());
910 }
911
TEST_P(QuicSessionTestServer,TestBatchedWrites)912 TEST_P(QuicSessionTestServer, TestBatchedWrites) {
913 session_.set_writev_consumes_all_data(true);
914 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
915 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
916 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
917
918 session_.set_writev_consumes_all_data(true);
919 session_.MarkConnectionLevelWriteBlocked(stream2->id());
920 session_.MarkConnectionLevelWriteBlocked(stream4->id());
921
922 // With two sessions blocked, we should get two write calls. They should both
923 // go to the first stream as it will only write 6k and mark itself blocked
924 // again.
925 InSequence s;
926 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
927 session_.SendLargeFakeData(stream2, 6000);
928 session_.MarkConnectionLevelWriteBlocked(stream2->id());
929 }));
930 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
931 session_.SendLargeFakeData(stream2, 6000);
932 session_.MarkConnectionLevelWriteBlocked(stream2->id());
933 }));
934 session_.OnCanWrite();
935
936 // We should get one more call for stream2, at which point it has used its
937 // write quota and we move over to stream 4.
938 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
939 session_.SendLargeFakeData(stream2, 6000);
940 session_.MarkConnectionLevelWriteBlocked(stream2->id());
941 }));
942 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
943 session_.SendLargeFakeData(stream4, 6000);
944 session_.MarkConnectionLevelWriteBlocked(stream4->id());
945 }));
946 session_.OnCanWrite();
947
948 // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
949 // priority stream 6. 4 should be preempted. 6 will write but *not* block so
950 // will cede back to 4.
951 stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
952 EXPECT_CALL(*stream4, OnCanWrite())
953 .WillOnce(Invoke([this, stream4, stream6]() {
954 session_.SendLargeFakeData(stream4, 6000);
955 session_.MarkConnectionLevelWriteBlocked(stream4->id());
956 session_.MarkConnectionLevelWriteBlocked(stream6->id());
957 }));
958 EXPECT_CALL(*stream6, OnCanWrite())
959 .WillOnce(Invoke([this, stream4, stream6]() {
960 session_.SendStreamData(stream6);
961 session_.SendLargeFakeData(stream4, 6000);
962 }));
963 session_.OnCanWrite();
964
965 // Stream4 alread did 6k worth of writes, so after doing another 12k it should
966 // cede and 2 should resume.
967 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
968 session_.SendLargeFakeData(stream4, 12000);
969 session_.MarkConnectionLevelWriteBlocked(stream4->id());
970 }));
971 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
972 session_.SendLargeFakeData(stream2, 6000);
973 session_.MarkConnectionLevelWriteBlocked(stream2->id());
974 }));
975 session_.OnCanWrite();
976 }
977
TEST_P(QuicSessionTestServer,Http2Priority)978 TEST_P(QuicSessionTestServer, Http2Priority) {
979 if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
980 // The test is using HTTP/2 priority which is not supported in IETF QUIC.
981 return;
982 }
983 QuicTagVector copt;
984 copt.push_back(kH2PR);
985 QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
986 session_.OnConfigNegotiated();
987 ASSERT_TRUE(session_.use_http2_priority_write_scheduler());
988
989 session_.set_writev_consumes_all_data(true);
990 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
991 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
992 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
993
994 session_.set_writev_consumes_all_data(true);
995 /*
996 0
997 /|\
998 2 4 6
999 */
1000 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1001 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1002 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1003
1004 // Verify streams are scheduled round robin.
1005 InSequence s;
1006 EXPECT_CALL(*stream2, OnCanWrite());
1007 EXPECT_CALL(*stream4, OnCanWrite());
1008 EXPECT_CALL(*stream6, OnCanWrite());
1009 session_.OnCanWrite();
1010
1011 /*
1012 0
1013 |
1014 4
1015 / \
1016 2 6
1017 */
1018 // Update stream 4's priority.
1019 stream4->SetPriority(
1020 spdy::SpdyStreamPrecedence(0, spdy::kHttp2DefaultStreamWeight, true));
1021 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1022 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1023 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1024
1025 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1026 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1027 }));
1028 EXPECT_CALL(*stream4, OnCanWrite());
1029 EXPECT_CALL(*stream2, OnCanWrite());
1030 session_.OnCanWrite();
1031 EXPECT_CALL(*stream6, OnCanWrite());
1032 session_.OnCanWrite();
1033
1034 /*
1035 0
1036 |
1037 6
1038 |
1039 4
1040 |
1041 2
1042 */
1043 // Update stream 6's priority.
1044 stream6->SetPriority(
1045 spdy::SpdyStreamPrecedence(0, spdy::kHttp2DefaultStreamWeight, true));
1046 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1047 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1048 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1049
1050 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
1051 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1052 }));
1053 EXPECT_CALL(*stream6, OnCanWrite());
1054 EXPECT_CALL(*stream4, OnCanWrite());
1055 session_.OnCanWrite();
1056 EXPECT_CALL(*stream2, OnCanWrite());
1057 session_.OnCanWrite();
1058 }
1059
TEST_P(QuicSessionTestServer,RoundRobinScheduling)1060 TEST_P(QuicSessionTestServer, RoundRobinScheduling) {
1061 if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
1062 // IETF QUIC currently doesn't support PRIORITY.
1063 return;
1064 }
1065 QuicTagVector copt;
1066 copt.push_back(kRRWS);
1067 QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
1068 session_.OnConfigNegotiated();
1069
1070 session_.set_writev_consumes_all_data(true);
1071 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1072 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1073 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1074
1075 session_.set_writev_consumes_all_data(true);
1076 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1077 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1078 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1079
1080 // Verify streams are scheduled round robin.
1081 InSequence s;
1082 EXPECT_CALL(*stream2, OnCanWrite());
1083 EXPECT_CALL(*stream4, OnCanWrite());
1084 EXPECT_CALL(*stream6, OnCanWrite());
1085 session_.OnCanWrite();
1086
1087 /* 2, 4, 6, 8 */
1088 TestStream* stream8 = session_.CreateOutgoingBidirectionalStream();
1089
1090 // Verify updated priority is ignored.
1091 stream4->SetPriority(spdy::SpdyStreamPrecedence(spdy::kV3HighestPriority));
1092 session_.MarkConnectionLevelWriteBlocked(stream8->id());
1093 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1094 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1095 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1096
1097 EXPECT_CALL(*stream8, OnCanWrite());
1098 EXPECT_CALL(*stream4, OnCanWrite());
1099 EXPECT_CALL(*stream2, OnCanWrite());
1100 EXPECT_CALL(*stream6, OnCanWrite());
1101 session_.OnCanWrite();
1102 }
1103
TEST_P(QuicSessionTestServer,OnCanWriteBundlesStreams)1104 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
1105 // Encryption needs to be established before data can be sent.
1106 if (connection_->version().HasHandshakeDone()) {
1107 EXPECT_CALL(*connection_, SendControlFrame(_))
1108 .WillRepeatedly(Invoke(&ClearControlFrame));
1109 }
1110 CryptoHandshakeMessage msg;
1111 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1112 QuicConnectionPeer::GetWriter(session_.connection()));
1113 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1114
1115 // Drive congestion control manually.
1116 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1117 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1118
1119 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1120 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1121 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1122
1123 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1124 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1125 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1126
1127 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
1128 EXPECT_CALL(*send_algorithm, GetCongestionWindow())
1129 .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
1130 EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
1131 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1132 session_.SendStreamData(stream2);
1133 }));
1134 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1135 session_.SendStreamData(stream4);
1136 }));
1137 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
1138 session_.SendStreamData(stream6);
1139 }));
1140
1141 // Expect that we only send one packet, the writes from different streams
1142 // should be bundled together.
1143 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
1144 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1145 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
1146 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1147 session_.OnCanWrite();
1148 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1149 }
1150
TEST_P(QuicSessionTestServer,OnCanWriteCongestionControlBlocks)1151 TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
1152 session_.set_writev_consumes_all_data(true);
1153 InSequence s;
1154
1155 // Drive congestion control manually.
1156 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1157 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1158
1159 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1160 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1161 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1162
1163 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1164 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1165 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1166
1167 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1168 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1169 session_.SendStreamData(stream2);
1170 }));
1171 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1172 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
1173 session_.SendStreamData(stream6);
1174 }));
1175 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
1176 // stream4->OnCanWrite is not called.
1177
1178 session_.OnCanWrite();
1179 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1180
1181 // Still congestion-control blocked.
1182 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
1183 session_.OnCanWrite();
1184 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1185
1186 // stream4->OnCanWrite is called once the connection stops being
1187 // congestion-control blocked.
1188 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1189 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1190 session_.SendStreamData(stream4);
1191 }));
1192 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1193 session_.OnCanWrite();
1194 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1195 }
1196
TEST_P(QuicSessionTestServer,OnCanWriteWriterBlocks)1197 TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
1198 // Drive congestion control manually in order to ensure that
1199 // application-limited signaling is handled correctly.
1200 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1201 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1202 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
1203
1204 // Drive packet writer manually.
1205 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1206 QuicConnectionPeer::GetWriter(session_.connection()));
1207 EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
1208 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
1209
1210 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1211
1212 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1213
1214 EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
1215 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
1216
1217 session_.OnCanWrite();
1218 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1219 }
1220
TEST_P(QuicSessionTestServer,SendStreamsBlocked)1221 TEST_P(QuicSessionTestServer, SendStreamsBlocked) {
1222 if (!VersionHasIetfQuicFrames(transport_version())) {
1223 return;
1224 }
1225 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
1226 ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
1227 session_.GetNextOutgoingBidirectionalStreamId();
1228 }
1229 // Next checking causes STREAMS_BLOCKED to be sent.
1230 EXPECT_CALL(*connection_, SendControlFrame(_))
1231 .WillOnce(Invoke([](const QuicFrame& frame) {
1232 EXPECT_FALSE(frame.streams_blocked_frame.unidirectional);
1233 EXPECT_EQ(kDefaultMaxStreamsPerConnection,
1234 frame.streams_blocked_frame.stream_count);
1235 ClearControlFrame(frame);
1236 return true;
1237 }));
1238 EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
1239
1240 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
1241 ASSERT_TRUE(session_.CanOpenNextOutgoingUnidirectionalStream());
1242 session_.GetNextOutgoingUnidirectionalStreamId();
1243 }
1244 // Next checking causes STREAM_BLOCKED to be sent.
1245 EXPECT_CALL(*connection_, SendControlFrame(_))
1246 .WillOnce(Invoke([](const QuicFrame& frame) {
1247 EXPECT_TRUE(frame.streams_blocked_frame.unidirectional);
1248 EXPECT_EQ(kDefaultMaxStreamsPerConnection,
1249 frame.streams_blocked_frame.stream_count);
1250 ClearControlFrame(frame);
1251 return true;
1252 }));
1253 EXPECT_FALSE(session_.CanOpenNextOutgoingUnidirectionalStream());
1254 }
1255
TEST_P(QuicSessionTestServer,BufferedHandshake)1256 TEST_P(QuicSessionTestServer, BufferedHandshake) {
1257 // This test is testing behavior of crypto stream flow control, but when
1258 // CRYPTO frames are used, there is no flow control for the crypto handshake.
1259 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
1260 return;
1261 }
1262 session_.set_writev_consumes_all_data(true);
1263 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
1264
1265 // Test that blocking other streams does not change our status.
1266 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1267 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1268 EXPECT_FALSE(session_.HasPendingHandshake());
1269
1270 TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
1271 session_.MarkConnectionLevelWriteBlocked(stream3->id());
1272 EXPECT_FALSE(session_.HasPendingHandshake());
1273
1274 // Blocking (due to buffering of) the Crypto stream is detected.
1275 session_.MarkConnectionLevelWriteBlocked(
1276 QuicUtils::GetCryptoStreamId(connection_->transport_version()));
1277 EXPECT_TRUE(session_.HasPendingHandshake());
1278
1279 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1280 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1281 EXPECT_TRUE(session_.HasPendingHandshake());
1282
1283 InSequence s;
1284 // Force most streams to re-register, which is common scenario when we block
1285 // the Crypto stream, and only the crypto stream can "really" write.
1286
1287 // Due to prioritization, we *should* be asked to write the crypto stream
1288 // first.
1289 // Don't re-register the crypto stream (which signals complete writing).
1290 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1291 EXPECT_CALL(*crypto_stream, OnCanWrite());
1292
1293 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1294 session_.SendStreamData(stream2);
1295 }));
1296 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
1297 session_.SendStreamData(stream3);
1298 }));
1299 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1300 session_.SendStreamData(stream4);
1301 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1302 }));
1303
1304 session_.OnCanWrite();
1305 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1306 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
1307 }
1308
TEST_P(QuicSessionTestServer,OnCanWriteWithClosedStream)1309 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
1310 session_.set_writev_consumes_all_data(true);
1311 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1312 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1313 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1314
1315 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1316 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1317 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1318 CloseStream(stream6->id());
1319
1320 InSequence s;
1321 EXPECT_CALL(*connection_, SendControlFrame(_))
1322 .WillRepeatedly(Invoke(&ClearControlFrame));
1323 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1324 session_.SendStreamData(stream2);
1325 }));
1326 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1327 session_.SendStreamData(stream4);
1328 }));
1329 session_.OnCanWrite();
1330 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1331 }
1332
TEST_P(QuicSessionTestServer,OnCanWriteLimitsNumWritesIfFlowControlBlocked)1333 TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
1334 // Drive congestion control manually in order to ensure that
1335 // application-limited signaling is handled correctly.
1336 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1337 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1338 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
1339
1340 // Ensure connection level flow control blockage.
1341 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
1342 EXPECT_TRUE(session_.flow_controller()->IsBlocked());
1343 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
1344 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1345
1346 // Mark the crypto and headers streams as write blocked, we expect them to be
1347 // allowed to write later.
1348 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
1349 session_.MarkConnectionLevelWriteBlocked(
1350 QuicUtils::GetCryptoStreamId(connection_->transport_version()));
1351 }
1352
1353 // Create a data stream, and although it is write blocked we never expect it
1354 // to be allowed to write as we are connection level flow control blocked.
1355 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1356 session_.MarkConnectionLevelWriteBlocked(stream->id());
1357 EXPECT_CALL(*stream, OnCanWrite()).Times(0);
1358
1359 // The crypto and headers streams should be called even though we are
1360 // connection flow control blocked.
1361 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
1362 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1363 EXPECT_CALL(*crypto_stream, OnCanWrite());
1364 }
1365
1366 // After the crypto and header streams perform a write, the connection will be
1367 // blocked by the flow control, hence it should become application-limited.
1368 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1369
1370 session_.OnCanWrite();
1371 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1372 }
1373
TEST_P(QuicSessionTestServer,SendGoAway)1374 TEST_P(QuicSessionTestServer, SendGoAway) {
1375 if (VersionHasIetfQuicFrames(transport_version())) {
1376 // In IETF QUIC, GOAWAY lives up in the HTTP layer.
1377 return;
1378 }
1379 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1380 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1381 QuicConnectionPeer::GetWriter(session_.connection()));
1382 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
1383 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1384
1385 EXPECT_CALL(*connection_, SendControlFrame(_))
1386 .WillOnce(
1387 Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
1388 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1389 EXPECT_TRUE(session_.goaway_sent());
1390
1391 const QuicStreamId kTestStreamId = 5u;
1392 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1393 EXPECT_CALL(*connection_,
1394 OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
1395 .Times(0);
1396 EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
1397 }
1398
TEST_P(QuicSessionTestServer,DoNotSendGoAwayTwice)1399 TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
1400 if (VersionHasIetfQuicFrames(transport_version())) {
1401 // In IETF QUIC, GOAWAY lives up in the HTTP layer.
1402 return;
1403 }
1404 EXPECT_CALL(*connection_, SendControlFrame(_))
1405 .WillOnce(Invoke(&ClearControlFrame));
1406 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1407 EXPECT_TRUE(session_.goaway_sent());
1408 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1409 }
1410
TEST_P(QuicSessionTestServer,InvalidGoAway)1411 TEST_P(QuicSessionTestServer, InvalidGoAway) {
1412 if (VersionHasIetfQuicFrames(transport_version())) {
1413 // In IETF QUIC, GOAWAY lives up in the HTTP layer.
1414 return;
1415 }
1416 QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
1417 session_.next_outgoing_bidirectional_stream_id(), "");
1418 session_.OnGoAway(go_away);
1419 }
1420
1421 // Test that server session will send a connectivity probe in response to a
1422 // connectivity probe on the same path.
TEST_P(QuicSessionTestServer,ServerReplyToConnectivityProbe)1423 TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
1424 QuicSocketAddress old_peer_address =
1425 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
1426 EXPECT_EQ(old_peer_address, session_.peer_address());
1427
1428 QuicSocketAddress new_peer_address =
1429 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
1430
1431 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1432 QuicConnectionPeer::GetWriter(session_.connection()));
1433 EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
1434 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1435 EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
1436 .WillOnce(Invoke(
1437 connection_,
1438 &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
1439 if (VersionHasIetfQuicFrames(transport_version())) {
1440 // Need to explicitly do this to emulate the reception of a PathChallenge,
1441 // which stores its payload for use in generating the response.
1442 connection_->OnPathChallengeFrame(
1443 QuicPathChallengeFrame(0, path_frame_buffer1_));
1444 }
1445 session_.OnPacketReceived(session_.self_address(), new_peer_address,
1446 /*is_connectivity_probe=*/true);
1447 EXPECT_EQ(old_peer_address, session_.peer_address());
1448 }
1449
1450 // Same as above, but check that if there are two PATH_CHALLENGE frames in the
1451 // packet, the response has both of them AND we do not do migration. This for
1452 // IETF QUIC only.
TEST_P(QuicSessionTestServer,ServerReplyToConnectivityProbes)1453 TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbes) {
1454 if (!VersionHasIetfQuicFrames(transport_version())) {
1455 return;
1456 }
1457 QuicSocketAddress old_peer_address =
1458 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
1459 EXPECT_EQ(old_peer_address, session_.peer_address());
1460
1461 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1462 QuicConnectionPeer::GetWriter(session_.connection()));
1463 // CheckMultiPathResponse validates that the written packet
1464 // contains both path responses.
1465 EXPECT_CALL(*writer, WritePacket(_, _, _, old_peer_address, _))
1466 .WillOnce(Invoke(this, &QuicSessionTestServer::CheckMultiPathResponse));
1467
1468 EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
1469 .WillOnce(Invoke(
1470 connection_,
1471 &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
1472 QuicConnectionPeer::SetLastHeaderFormat(connection_,
1473 IETF_QUIC_SHORT_HEADER_PACKET);
1474 // Need to explicitly do this to emulate the reception of a PathChallenge,
1475 // which stores its payload for use in generating the response.
1476 connection_->OnPathChallengeFrame(
1477 QuicPathChallengeFrame(0, path_frame_buffer1_));
1478 connection_->OnPathChallengeFrame(
1479 QuicPathChallengeFrame(0, path_frame_buffer2_));
1480 session_.OnPacketReceived(session_.self_address(), old_peer_address,
1481 /*is_connectivity_probe=*/true);
1482 }
1483
TEST_P(QuicSessionTestServer,IncreasedTimeoutAfterCryptoHandshake)1484 TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
1485 EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
1486 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1487 if (connection_->version().HasHandshakeDone()) {
1488 EXPECT_CALL(*connection_, SendControlFrame(_));
1489 }
1490 CryptoHandshakeMessage msg;
1491 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1492 EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
1493 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1494 }
1495
TEST_P(QuicSessionTestServer,OnStreamFrameFinStaticStreamId)1496 TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
1497 if (VersionUsesHttp3(connection_->transport_version())) {
1498 // The test relies on headers stream, which no longer exists in IETF QUIC.
1499 return;
1500 }
1501 QuicStreamId headers_stream_id =
1502 QuicUtils::GetHeadersStreamId(connection_->transport_version());
1503 std::unique_ptr<TestStream> fake_headers_stream =
1504 std::make_unique<TestStream>(headers_stream_id, &session_,
1505 /*is_static*/ true, BIDIRECTIONAL);
1506 QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream));
1507 // Send two bytes of payload.
1508 QuicStreamFrame data1(headers_stream_id, true, 0,
1509 quiche::QuicheStringPiece("HT"));
1510 EXPECT_CALL(*connection_,
1511 CloseConnection(
1512 QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
1513 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1514 session_.OnStreamFrame(data1);
1515 }
1516
TEST_P(QuicSessionTestServer,OnStreamFrameInvalidStreamId)1517 TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
1518 // Send two bytes of payload.
1519 QuicStreamFrame data1(
1520 QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
1521 quiche::QuicheStringPiece("HT"));
1522 EXPECT_CALL(*connection_,
1523 CloseConnection(
1524 QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
1525 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1526 session_.OnStreamFrame(data1);
1527 }
1528
TEST_P(QuicSessionTestServer,OnRstStreamInvalidStreamId)1529 TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
1530 // Send two bytes of payload.
1531 QuicRstStreamFrame rst1(
1532 kInvalidControlFrameId,
1533 QuicUtils::GetInvalidStreamId(connection_->transport_version()),
1534 QUIC_ERROR_PROCESSING_STREAM, 0);
1535 EXPECT_CALL(*connection_,
1536 CloseConnection(
1537 QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
1538 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1539 session_.OnRstStream(rst1);
1540 }
1541
TEST_P(QuicSessionTestServer,HandshakeUnblocksFlowControlBlockedStream)1542 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
1543 if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
1544 // This test requires Google QUIC crypto because it assumes streams start
1545 // off unblocked.
1546 return;
1547 }
1548 // Test that if a stream is flow control blocked, then on receipt of the SHLO
1549 // containing a suitable send window offset, the stream becomes unblocked.
1550
1551 // Ensure that Writev consumes all the data it is given (simulate no socket
1552 // blocking).
1553 session_.set_writev_consumes_all_data(true);
1554
1555 // Create a stream, and send enough data to make it flow control blocked.
1556 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1557 std::string body(kMinimumFlowControlSendWindow, '.');
1558 EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
1559 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1560 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1561 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
1562 stream2->WriteOrBufferData(body, false, nullptr);
1563 EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
1564 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
1565 EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
1566
1567 // Now complete the crypto handshake, resulting in an increased flow control
1568 // send window.
1569 CryptoHandshakeMessage msg;
1570 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1571 EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
1572 // Stream is now unblocked.
1573 EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
1574 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1575 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1576 }
1577
TEST_P(QuicSessionTestServer,HandshakeUnblocksFlowControlBlockedCryptoStream)1578 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
1579 if (QuicVersionUsesCryptoFrames(GetParam().transport_version)) {
1580 // QUIC version 47 onwards uses CRYPTO frames for the handshake, so this
1581 // test doesn't make sense for those versions since CRYPTO frames aren't
1582 // flow controlled.
1583 return;
1584 }
1585 // Test that if the crypto stream is flow control blocked, then if the SHLO
1586 // contains a larger send window offset, the stream becomes unblocked.
1587 session_.set_writev_consumes_all_data(true);
1588 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1589 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
1590 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1591 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1592 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1593 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1594 EXPECT_CALL(*connection_, SendControlFrame(_))
1595 .WillOnce(Invoke(&ClearControlFrame));
1596 for (QuicStreamId i = 0;
1597 !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) {
1598 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1599 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1600 QuicStreamOffset offset = crypto_stream->stream_bytes_written();
1601 QuicConfig config;
1602 CryptoHandshakeMessage crypto_message;
1603 config.ToHandshakeMessage(&crypto_message, transport_version());
1604 crypto_stream->SendHandshakeMessage(crypto_message);
1605 char buf[1000];
1606 QuicDataWriter writer(1000, buf, quiche::NETWORK_BYTE_ORDER);
1607 crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer);
1608 }
1609 EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked());
1610 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1611 EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
1612 EXPECT_FALSE(session_.HasDataToWrite());
1613 EXPECT_TRUE(crypto_stream->HasBufferedData());
1614
1615 // Now complete the crypto handshake, resulting in an increased flow control
1616 // send window.
1617 CryptoHandshakeMessage msg;
1618 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1619 EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
1620 &session_,
1621 QuicUtils::GetCryptoStreamId(connection_->transport_version())));
1622 // Stream is now unblocked and will no longer have buffered data.
1623 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
1624 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1625 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1626 }
1627
TEST_P(QuicSessionTestServer,ConnectionFlowControlAccountingRstOutOfOrder)1628 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
1629 // Test that when we receive an out of order stream RST we correctly adjust
1630 // our connection level flow control receive window.
1631 // On close, the stream should mark as consumed all bytes between the highest
1632 // byte consumed so far and the final byte offset from the RST frame.
1633 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1634
1635 const QuicStreamOffset kByteOffset =
1636 1 + kInitialSessionFlowControlWindowForTest / 2;
1637
1638 EXPECT_CALL(*connection_, SendControlFrame(_))
1639 .Times(2)
1640 .WillRepeatedly(Invoke(&ClearControlFrame));
1641 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1642
1643 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1644 QUIC_STREAM_CANCELLED, kByteOffset);
1645 session_.OnRstStream(rst_frame);
1646 if (VersionHasIetfQuicFrames(transport_version())) {
1647 // The test requires the stream to be fully closed in both directions. For
1648 // IETF QUIC, the RST_STREAM only closes one side.
1649 QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
1650 QUIC_STREAM_CANCELLED);
1651 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
1652 session_.OnStopSendingFrame(frame);
1653 }
1654 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
1655 }
1656
TEST_P(QuicSessionTestServer,ConnectionFlowControlAccountingFinAndLocalReset)1657 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
1658 // Test the situation where we receive a FIN on a stream, and before we fully
1659 // consume all the data from the sequencer buffer we locally RST the stream.
1660 // The bytes between highest consumed byte, and the final byte offset that we
1661 // determined when the FIN arrived, should be marked as consumed at the
1662 // connection level flow controller when the stream is reset.
1663 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1664
1665 const QuicStreamOffset kByteOffset =
1666 kInitialSessionFlowControlWindowForTest / 2 - 1;
1667 QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
1668 session_.OnStreamFrame(frame);
1669 EXPECT_TRUE(connection_->connected());
1670
1671 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed());
1672 EXPECT_EQ(kByteOffset + frame.data_length,
1673 stream->flow_controller()->highest_received_byte_offset());
1674
1675 // Reset stream locally.
1676 EXPECT_CALL(*connection_, SendControlFrame(_));
1677 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1678 stream->Reset(QUIC_STREAM_CANCELLED);
1679 EXPECT_EQ(kByteOffset + frame.data_length,
1680 session_.flow_controller()->bytes_consumed());
1681 }
1682
TEST_P(QuicSessionTestServer,ConnectionFlowControlAccountingFinAfterRst)1683 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
1684 // Test that when we RST the stream (and tear down stream state), and then
1685 // receive a FIN from the peer, we correctly adjust our connection level flow
1686 // control receive window.
1687
1688 // Connection starts with some non-zero highest received byte offset,
1689 // due to other active streams.
1690 const uint64_t kInitialConnectionBytesConsumed = 567;
1691 const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
1692 EXPECT_LT(kInitialConnectionBytesConsumed,
1693 kInitialConnectionHighestReceivedOffset);
1694 session_.flow_controller()->UpdateHighestReceivedOffset(
1695 kInitialConnectionHighestReceivedOffset);
1696 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
1697
1698 // Reset our stream: this results in the stream being closed locally.
1699 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1700 EXPECT_CALL(*connection_, SendControlFrame(_));
1701 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1702 stream->Reset(QUIC_STREAM_CANCELLED);
1703
1704 // Now receive a response from the peer with a FIN. We should handle this by
1705 // adjusting the connection level flow control receive window to take into
1706 // account the total number of bytes sent by the peer.
1707 const QuicStreamOffset kByteOffset = 5678;
1708 std::string body = "hello";
1709 QuicStreamFrame frame(stream->id(), true, kByteOffset,
1710 quiche::QuicheStringPiece(body));
1711 session_.OnStreamFrame(frame);
1712
1713 QuicStreamOffset total_stream_bytes_sent_by_peer =
1714 kByteOffset + body.length();
1715 EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
1716 session_.flow_controller()->bytes_consumed());
1717 EXPECT_EQ(
1718 kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
1719 session_.flow_controller()->highest_received_byte_offset());
1720 }
1721
TEST_P(QuicSessionTestServer,ConnectionFlowControlAccountingRstAfterRst)1722 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
1723 // Test that when we RST the stream (and tear down stream state), and then
1724 // receive a RST from the peer, we correctly adjust our connection level flow
1725 // control receive window.
1726
1727 // Connection starts with some non-zero highest received byte offset,
1728 // due to other active streams.
1729 const uint64_t kInitialConnectionBytesConsumed = 567;
1730 const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
1731 EXPECT_LT(kInitialConnectionBytesConsumed,
1732 kInitialConnectionHighestReceivedOffset);
1733 session_.flow_controller()->UpdateHighestReceivedOffset(
1734 kInitialConnectionHighestReceivedOffset);
1735 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
1736
1737 // Reset our stream: this results in the stream being closed locally.
1738 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1739 EXPECT_CALL(*connection_, SendControlFrame(_));
1740 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1741 stream->Reset(QUIC_STREAM_CANCELLED);
1742 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
1743
1744 // Now receive a RST from the peer. We should handle this by adjusting the
1745 // connection level flow control receive window to take into account the total
1746 // number of bytes sent by the peer.
1747 const QuicStreamOffset kByteOffset = 5678;
1748 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1749 QUIC_STREAM_CANCELLED, kByteOffset);
1750 session_.OnRstStream(rst_frame);
1751
1752 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
1753 session_.flow_controller()->bytes_consumed());
1754 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
1755 session_.flow_controller()->highest_received_byte_offset());
1756 }
1757
TEST_P(QuicSessionTestServer,InvalidStreamFlowControlWindowInHandshake)1758 TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
1759 // Test that receipt of an invalid (< default) stream flow control window from
1760 // the peer results in the connection being torn down.
1761 const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
1762 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
1763 kInvalidWindow);
1764
1765 if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
1766 EXPECT_CALL(*connection_,
1767 CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
1768 } else {
1769 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
1770 }
1771 session_.OnConfigNegotiated();
1772 }
1773
TEST_P(QuicSessionTestServer,InvalidSessionFlowControlWindowInHandshake)1774 TEST_P(QuicSessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
1775 // Test that receipt of an invalid (< default) session flow control window
1776 // from the peer results in the connection being torn down.
1777 const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
1778 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
1779 kInvalidWindow);
1780 if (!connection_->version().AllowsLowFlowControlLimits()) {
1781 EXPECT_CALL(*connection_,
1782 CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
1783 } else {
1784 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
1785 }
1786 session_.OnConfigNegotiated();
1787 }
1788
1789 // Test negotiation of custom server initial flow control window.
TEST_P(QuicSessionTestServer,CustomFlowControlWindow)1790 TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
1791 QuicTagVector copt;
1792 copt.push_back(kIFW7);
1793 QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
1794
1795 session_.OnConfigNegotiated();
1796 EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
1797 session_.flow_controller()));
1798 }
1799
TEST_P(QuicSessionTestServer,FlowControlWithInvalidFinalOffset)1800 TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
1801 // Test that if we receive a stream RST with a highest byte offset that
1802 // violates flow control, that we close the connection.
1803 const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
1804 EXPECT_CALL(*connection_,
1805 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
1806 .Times(2);
1807
1808 // Check that stream frame + FIN results in connection close.
1809 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1810 EXPECT_CALL(*connection_, SendControlFrame(_));
1811 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1812 stream->Reset(QUIC_STREAM_CANCELLED);
1813 QuicStreamFrame frame(stream->id(), true, kLargeOffset,
1814 quiche::QuicheStringPiece());
1815 session_.OnStreamFrame(frame);
1816
1817 // Check that RST results in connection close.
1818 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1819 QUIC_STREAM_CANCELLED, kLargeOffset);
1820 session_.OnRstStream(rst_frame);
1821 }
1822
TEST_P(QuicSessionTestServer,TooManyUnfinishedStreamsCauseServerRejectStream)1823 TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
1824 // If a buggy/malicious peer creates too many streams that are not ended
1825 // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
1826 // connection is closed.
1827 const QuicStreamId kMaxStreams = 5;
1828 if (VersionHasIetfQuicFrames(transport_version())) {
1829 QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
1830 kMaxStreams);
1831 } else {
1832 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
1833 }
1834 const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
1835 const QuicStreamId kFinalStreamId =
1836 GetNthClientInitiatedBidirectionalId(kMaxStreams);
1837 // Create kMaxStreams data streams, and close them all without receiving a
1838 // FIN or a RST_STREAM from the client.
1839 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
1840 i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
1841 QuicStreamFrame data1(i, false, 0, quiche::QuicheStringPiece("HT"));
1842 session_.OnStreamFrame(data1);
1843 // EXPECT_EQ(1u, session_.GetNumOpenStreams());
1844 if (VersionHasIetfQuicFrames(transport_version())) {
1845 // Expect two control frames, RST STREAM and STOP SENDING
1846 EXPECT_CALL(*connection_, SendControlFrame(_))
1847 .Times(2)
1848 .WillRepeatedly(Invoke(&ClearControlFrame));
1849 } else {
1850 // Expect one control frame, just RST STREAM
1851 EXPECT_CALL(*connection_, SendControlFrame(_))
1852 .WillOnce(Invoke(&ClearControlFrame));
1853 }
1854 // Close stream. Should not make new streams available since
1855 // the stream is not finished.
1856 EXPECT_CALL(*connection_, OnStreamReset(i, _));
1857 session_.CloseStream(i);
1858 }
1859
1860 if (VersionHasIetfQuicFrames(transport_version())) {
1861 EXPECT_CALL(
1862 *connection_,
1863 CloseConnection(QUIC_INVALID_STREAM_ID,
1864 "Stream id 20 would exceed stream count limit 5", _));
1865 } else {
1866 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1867 EXPECT_CALL(*connection_,
1868 OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
1869 .Times(1);
1870 }
1871 // Create one more data streams to exceed limit of open stream.
1872 QuicStreamFrame data1(kFinalStreamId, false, 0,
1873 quiche::QuicheStringPiece("HT"));
1874 session_.OnStreamFrame(data1);
1875 }
1876
TEST_P(QuicSessionTestServer,DrainingStreamsDoNotCountAsOpenedOutgoing)1877 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
1878 // Verify that a draining stream (which has received a FIN but not consumed
1879 // it) does not count against the open quota (because it is closed from the
1880 // protocol point of view).
1881 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1882 QuicStreamId stream_id = stream->id();
1883 QuicStreamFrame data1(stream_id, true, 0, quiche::QuicheStringPiece("HT"));
1884 session_.OnStreamFrame(data1);
1885 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
1886 session_.StreamDraining(stream_id);
1887 }
1888
TEST_P(QuicSessionTestServer,NoPendingStreams)1889 TEST_P(QuicSessionTestServer, NoPendingStreams) {
1890 session_.set_uses_pending_streams(false);
1891
1892 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1893 transport_version(), Perspective::IS_CLIENT);
1894 QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT"));
1895 session_.OnStreamFrame(data1);
1896 EXPECT_EQ(1, session_.num_incoming_streams_created());
1897
1898 QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT"));
1899 session_.OnStreamFrame(data2);
1900 EXPECT_EQ(1, session_.num_incoming_streams_created());
1901 }
1902
TEST_P(QuicSessionTestServer,PendingStreams)1903 TEST_P(QuicSessionTestServer, PendingStreams) {
1904 if (!VersionUsesHttp3(transport_version())) {
1905 return;
1906 }
1907 session_.set_uses_pending_streams(true);
1908
1909 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1910 transport_version(), Perspective::IS_CLIENT);
1911 QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT"));
1912 session_.OnStreamFrame(data1);
1913 EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1914 EXPECT_EQ(0, session_.num_incoming_streams_created());
1915
1916 QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT"));
1917 session_.OnStreamFrame(data2);
1918 EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1919 EXPECT_EQ(1, session_.num_incoming_streams_created());
1920 }
1921
TEST_P(QuicSessionTestServer,RstPendingStreams)1922 TEST_P(QuicSessionTestServer, RstPendingStreams) {
1923 if (!VersionUsesHttp3(transport_version())) {
1924 return;
1925 }
1926 session_.set_uses_pending_streams(true);
1927
1928 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1929 transport_version(), Perspective::IS_CLIENT);
1930 QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT"));
1931 session_.OnStreamFrame(data1);
1932 EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1933 EXPECT_EQ(0, session_.num_incoming_streams_created());
1934 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
1935
1936 QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
1937 QUIC_ERROR_PROCESSING_STREAM, 12);
1938 session_.OnRstStream(rst1);
1939 EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1940 EXPECT_EQ(0, session_.num_incoming_streams_created());
1941 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
1942
1943 QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT"));
1944 session_.OnStreamFrame(data2);
1945 EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1946 EXPECT_EQ(0, session_.num_incoming_streams_created());
1947 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
1948 }
1949
TEST_P(QuicSessionTestServer,OnFinPendingStreams)1950 TEST_P(QuicSessionTestServer, OnFinPendingStreams) {
1951 if (!VersionUsesHttp3(transport_version())) {
1952 return;
1953 }
1954 session_.set_uses_pending_streams(true);
1955
1956 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1957 transport_version(), Perspective::IS_CLIENT);
1958 QuicStreamFrame data(stream_id, true, 0, "");
1959 session_.OnStreamFrame(data);
1960
1961 EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1962 EXPECT_EQ(0, session_.num_incoming_streams_created());
1963 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
1964 }
1965
TEST_P(QuicSessionTestServer,PendingStreamOnWindowUpdate)1966 TEST_P(QuicSessionTestServer, PendingStreamOnWindowUpdate) {
1967 if (!VersionUsesHttp3(transport_version())) {
1968 return;
1969 }
1970
1971 session_.set_uses_pending_streams(true);
1972 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1973 transport_version(), Perspective::IS_CLIENT);
1974 QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT"));
1975 session_.OnStreamFrame(data1);
1976 EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
1977 EXPECT_EQ(0, session_.num_incoming_streams_created());
1978 QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
1979 0);
1980 EXPECT_CALL(
1981 *connection_,
1982 CloseConnection(
1983 QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
1984 "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
1985 session_.OnWindowUpdateFrame(window_update_frame);
1986 }
1987
TEST_P(QuicSessionTestServer,DrainingStreamsDoNotCountAsOpened)1988 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
1989 // Verify that a draining stream (which has received a FIN but not consumed
1990 // it) does not count against the open quota (because it is closed from the
1991 // protocol point of view).
1992 if (VersionHasIetfQuicFrames(transport_version())) {
1993 // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
1994 // not enough streams to create the next one.
1995 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1996 } else {
1997 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1998 }
1999 EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
2000 const QuicStreamId kMaxStreams = 5;
2001 if (VersionHasIetfQuicFrames(transport_version())) {
2002 QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
2003 kMaxStreams);
2004 } else {
2005 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
2006 }
2007
2008 // Create kMaxStreams + 1 data streams, and mark them draining.
2009 const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
2010 const QuicStreamId kFinalStreamId =
2011 GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
2012 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
2013 i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
2014 QuicStreamFrame data1(i, true, 0, quiche::QuicheStringPiece("HT"));
2015 session_.OnStreamFrame(data1);
2016 EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
2017 session_.StreamDraining(i);
2018 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
2019 }
2020 }
2021
2022 class QuicSessionTestClient : public QuicSessionTestBase {
2023 protected:
QuicSessionTestClient()2024 QuicSessionTestClient()
2025 : QuicSessionTestBase(Perspective::IS_CLIENT,
2026 /*configure_session=*/true) {}
2027 };
2028
2029 INSTANTIATE_TEST_SUITE_P(Tests,
2030 QuicSessionTestClient,
2031 ::testing::ValuesIn(AllSupportedVersions()),
2032 ::testing::PrintToStringParamName());
2033
TEST_P(QuicSessionTestClient,AvailableBidirectionalStreamsClient)2034 TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
2035 ASSERT_TRUE(session_.GetOrCreateStream(
2036 GetNthServerInitiatedBidirectionalId(2)) != nullptr);
2037 // Smaller bidirectional streams should be available.
2038 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
2039 &session_, GetNthServerInitiatedBidirectionalId(0)));
2040 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
2041 &session_, GetNthServerInitiatedBidirectionalId(1)));
2042 ASSERT_TRUE(session_.GetOrCreateStream(
2043 GetNthServerInitiatedBidirectionalId(0)) != nullptr);
2044 ASSERT_TRUE(session_.GetOrCreateStream(
2045 GetNthServerInitiatedBidirectionalId(1)) != nullptr);
2046 // And 5 should be not available.
2047 EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
2048 &session_, GetNthClientInitiatedBidirectionalId(1)));
2049 }
2050
TEST_P(QuicSessionTestClient,OnMaxStreamFrame)2051 TEST_P(QuicSessionTestClient, OnMaxStreamFrame) {
2052 if (!VersionUsesHttp3(transport_version())) {
2053 return;
2054 }
2055 QuicMaxStreamsFrame frame;
2056 frame.unidirectional = false;
2057 frame.stream_count = 120;
2058 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
2059 session_.OnMaxStreamsFrame(frame);
2060
2061 QuicMaxStreamsFrame frame2;
2062 frame2.unidirectional = false;
2063 frame2.stream_count = 110;
2064 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
2065 session_.OnMaxStreamsFrame(frame2);
2066 }
2067
TEST_P(QuicSessionTestClient,AvailableUnidirectionalStreamsClient)2068 TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
2069 ASSERT_TRUE(session_.GetOrCreateStream(
2070 GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
2071 // Smaller unidirectional streams should be available.
2072 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
2073 &session_, GetNthServerInitiatedUnidirectionalId(0)));
2074 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
2075 &session_, GetNthServerInitiatedUnidirectionalId(1)));
2076 ASSERT_TRUE(session_.GetOrCreateStream(
2077 GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
2078 ASSERT_TRUE(session_.GetOrCreateStream(
2079 GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
2080 // And 5 should be not available.
2081 EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
2082 &session_, GetNthClientInitiatedUnidirectionalId(1)));
2083 }
2084
TEST_P(QuicSessionTestClient,RecordFinAfterReadSideClosed)2085 TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
2086 // Verify that an incoming FIN is recorded in a stream object even if the read
2087 // side has been closed. This prevents an entry from being made in
2088 // locally_closed_streams_highest_offset_ (which will never be deleted).
2089 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2090 QuicStreamId stream_id = stream->id();
2091
2092 // Close the read side manually.
2093 QuicStreamPeer::CloseReadSide(stream);
2094
2095 // Receive a stream data frame with FIN.
2096 QuicStreamFrame frame(stream_id, true, 0, quiche::QuicheStringPiece());
2097 session_.OnStreamFrame(frame);
2098 EXPECT_TRUE(stream->fin_received());
2099
2100 // Reset stream locally.
2101 EXPECT_CALL(*connection_, SendControlFrame(_));
2102 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
2103 stream->Reset(QUIC_STREAM_CANCELLED);
2104 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
2105
2106 EXPECT_TRUE(connection_->connected());
2107 EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
2108 EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
2109
2110 // The stream is not waiting for the arrival of the peer's final offset as it
2111 // was received with the FIN earlier.
2112 EXPECT_EQ(
2113 0u,
2114 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
2115 }
2116
TEST_P(QuicSessionTestClient,IncomingStreamWithClientInitiatedStreamId)2117 TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) {
2118 const QuicErrorCode expected_error =
2119 VersionHasIetfQuicFrames(transport_version())
2120 ? QUIC_HTTP_STREAM_WRONG_DIRECTION
2121 : QUIC_INVALID_STREAM_ID;
2122 EXPECT_CALL(
2123 *connection_,
2124 CloseConnection(expected_error, "Data for nonexistent stream",
2125 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
2126
2127 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1),
2128 /* fin = */ false, /* offset = */ 0,
2129 quiche::QuicheStringPiece("foo"));
2130 session_.OnStreamFrame(frame);
2131 }
2132
TEST_P(QuicSessionTestServer,ZombieStreams)2133 TEST_P(QuicSessionTestServer, ZombieStreams) {
2134 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2135 QuicStreamPeer::SetStreamBytesWritten(3, stream2);
2136 EXPECT_TRUE(stream2->IsWaitingForAcks());
2137
2138 EXPECT_CALL(*connection_, SendControlFrame(_));
2139 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2140 session_.CloseStream(stream2->id());
2141 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2142 ASSERT_EQ(1u, session_.closed_streams()->size());
2143 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
2144 session_.OnStreamDoneWaitingForAcks(stream2->id());
2145 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2146 EXPECT_EQ(1u, session_.closed_streams()->size());
2147 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
2148 }
2149
TEST_P(QuicSessionTestServer,RstStreamReceivedAfterRstStreamSent)2150 TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
2151 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2152 QuicStreamPeer::SetStreamBytesWritten(3, stream2);
2153 EXPECT_TRUE(stream2->IsWaitingForAcks());
2154
2155 EXPECT_CALL(*connection_, SendControlFrame(_));
2156 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2157 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
2158 stream2->Reset(quic::QUIC_STREAM_CANCELLED);
2159
2160 QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
2161 QUIC_ERROR_PROCESSING_STREAM, 0);
2162 if (!VersionHasIetfQuicFrames(transport_version())) {
2163 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
2164 }
2165 session_.OnRstStream(rst1);
2166 }
2167
2168 // Regression test of b/71548958.
TEST_P(QuicSessionTestServer,TestZombieStreams)2169 TEST_P(QuicSessionTestServer, TestZombieStreams) {
2170 session_.set_writev_consumes_all_data(true);
2171
2172 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2173 std::string body(100, '.');
2174 stream2->WriteOrBufferData(body, false, nullptr);
2175 EXPECT_TRUE(stream2->IsWaitingForAcks());
2176 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
2177
2178 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
2179 QUIC_STREAM_CANCELLED, 1234);
2180 // Just for the RST_STREAM
2181 EXPECT_CALL(*connection_, SendControlFrame(_))
2182 .WillOnce(Invoke(&ClearControlFrame));
2183 if (VersionHasIetfQuicFrames(transport_version())) {
2184 EXPECT_CALL(*connection_,
2185 OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
2186 } else {
2187 EXPECT_CALL(*connection_,
2188 OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
2189 }
2190 stream2->OnStreamReset(rst_frame);
2191
2192 if (VersionHasIetfQuicFrames(transport_version())) {
2193 // The test requires the stream to be fully closed in both directions. For
2194 // IETF QUIC, the RST_STREAM only closes one side.
2195 QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
2196 QUIC_STREAM_CANCELLED);
2197 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2198 session_.OnStopSendingFrame(frame);
2199 }
2200 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2201 ASSERT_EQ(1u, session_.closed_streams()->size());
2202 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
2203
2204 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
2205 if (VersionHasIetfQuicFrames(transport_version())) {
2206 // Once for the RST_STREAM, once for the STOP_SENDING
2207 EXPECT_CALL(*connection_, SendControlFrame(_))
2208 .Times(2)
2209 .WillRepeatedly(Invoke(&ClearControlFrame));
2210 } else {
2211 // Just for the RST_STREAM
2212 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
2213 }
2214 EXPECT_CALL(*connection_,
2215 OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
2216 stream4->WriteOrBufferData(body, false, nullptr);
2217 // Note well: Reset() actually closes the stream in both directions. For
2218 // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
2219 // QUIC it sends both a RST_STREAM and a STOP_SENDING (each of which
2220 // closes in only one direction).
2221 stream4->Reset(QUIC_STREAM_CANCELLED);
2222 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
2223 EXPECT_EQ(2u, session_.closed_streams()->size());
2224 }
2225
TEST_P(QuicSessionTestServer,OnStreamFrameLost)2226 TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
2227 InSequence s;
2228
2229 // Drive congestion control manually.
2230 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
2231 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
2232
2233 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
2234 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2235 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
2236
2237 QuicStreamFrame frame1;
2238 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
2239 frame1 = QuicStreamFrame(
2240 QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
2241 0, 1300);
2242 }
2243 QuicStreamFrame frame2(stream2->id(), false, 0, 9);
2244 QuicStreamFrame frame3(stream4->id(), false, 0, 9);
2245
2246 // Lost data on cryption stream, streams 2 and 4.
2247 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
2248 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
2249 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
2250 .WillOnce(Return(true));
2251 }
2252 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
2253 session_.OnFrameLost(QuicFrame(frame3));
2254 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
2255 session_.OnFrameLost(QuicFrame(frame1));
2256 } else {
2257 QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
2258 session_.OnFrameLost(QuicFrame(&crypto_frame));
2259 }
2260 session_.OnFrameLost(QuicFrame(frame2));
2261 EXPECT_TRUE(session_.WillingAndAbleToWrite());
2262
2263 // Mark streams 2 and 4 write blocked.
2264 session_.MarkConnectionLevelWriteBlocked(stream2->id());
2265 session_.MarkConnectionLevelWriteBlocked(stream4->id());
2266
2267 // Lost data is retransmitted before new data, and retransmissions for crypto
2268 // stream go first.
2269 // Do not check congestion window when crypto stream has lost data.
2270 EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
2271 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
2272 EXPECT_CALL(*crypto_stream, OnCanWrite());
2273 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
2274 .WillOnce(Return(false));
2275 }
2276 // Check congestion window for non crypto streams.
2277 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2278 EXPECT_CALL(*stream4, OnCanWrite());
2279 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
2280 // Connection is blocked.
2281 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
2282
2283 session_.OnCanWrite();
2284 EXPECT_TRUE(session_.WillingAndAbleToWrite());
2285
2286 // Unblock connection.
2287 // Stream 2 retransmits lost data.
2288 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2289 EXPECT_CALL(*stream2, OnCanWrite());
2290 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
2291 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2292 // Stream 2 sends new data.
2293 EXPECT_CALL(*stream2, OnCanWrite());
2294 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2295 EXPECT_CALL(*stream4, OnCanWrite());
2296 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
2297
2298 session_.OnCanWrite();
2299 EXPECT_FALSE(session_.WillingAndAbleToWrite());
2300 }
2301
TEST_P(QuicSessionTestServer,DonotRetransmitDataOfClosedStreams)2302 TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
2303 InSequence s;
2304
2305 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2306 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
2307 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
2308
2309 QuicStreamFrame frame1(stream2->id(), false, 0, 9);
2310 QuicStreamFrame frame2(stream4->id(), false, 0, 9);
2311 QuicStreamFrame frame3(stream6->id(), false, 0, 9);
2312
2313 EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
2314 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
2315 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
2316 session_.OnFrameLost(QuicFrame(frame3));
2317 session_.OnFrameLost(QuicFrame(frame2));
2318 session_.OnFrameLost(QuicFrame(frame1));
2319
2320 session_.MarkConnectionLevelWriteBlocked(stream2->id());
2321 session_.MarkConnectionLevelWriteBlocked(stream4->id());
2322 session_.MarkConnectionLevelWriteBlocked(stream6->id());
2323
2324 // Reset stream 4 locally.
2325 EXPECT_CALL(*connection_, SendControlFrame(_));
2326 EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
2327 stream4->Reset(QUIC_STREAM_CANCELLED);
2328
2329 // Verify stream 4 is removed from streams with lost data list.
2330 EXPECT_CALL(*stream6, OnCanWrite());
2331 EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
2332 EXPECT_CALL(*stream2, OnCanWrite());
2333 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
2334 EXPECT_CALL(*connection_, SendControlFrame(_))
2335 .WillRepeatedly(Invoke(&ClearControlFrame));
2336 EXPECT_CALL(*stream2, OnCanWrite());
2337 EXPECT_CALL(*stream6, OnCanWrite());
2338 session_.OnCanWrite();
2339 }
2340
TEST_P(QuicSessionTestServer,RetransmitFrames)2341 TEST_P(QuicSessionTestServer, RetransmitFrames) {
2342 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
2343 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
2344 InSequence s;
2345
2346 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2347 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
2348 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
2349 EXPECT_CALL(*connection_, SendControlFrame(_))
2350 .WillOnce(Invoke(&ClearControlFrame));
2351 session_.SendWindowUpdate(stream2->id(), 9);
2352
2353 QuicStreamFrame frame1(stream2->id(), false, 0, 9);
2354 QuicStreamFrame frame2(stream4->id(), false, 0, 9);
2355 QuicStreamFrame frame3(stream6->id(), false, 0, 9);
2356 QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
2357 QuicFrames frames;
2358 frames.push_back(QuicFrame(frame1));
2359 frames.push_back(QuicFrame(&window_update));
2360 frames.push_back(QuicFrame(frame2));
2361 frames.push_back(QuicFrame(frame3));
2362 EXPECT_FALSE(session_.WillingAndAbleToWrite());
2363
2364 EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
2365 .WillOnce(Return(true));
2366 EXPECT_CALL(*connection_, SendControlFrame(_))
2367 .WillOnce(Invoke(&ClearControlFrame));
2368 EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
2369 .WillOnce(Return(true));
2370 EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
2371 .WillOnce(Return(true));
2372 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
2373 session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
2374 }
2375
2376 // Regression test of b/110082001.
TEST_P(QuicSessionTestServer,RetransmitLostDataCausesConnectionClose)2377 TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
2378 // This test mimics the scenario when a dynamic stream retransmits lost data
2379 // and causes connection close.
2380 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2381 QuicStreamFrame frame(stream->id(), false, 0, 9);
2382
2383 EXPECT_CALL(*stream, HasPendingRetransmission())
2384 .Times(2)
2385 .WillOnce(Return(true))
2386 .WillOnce(Return(false));
2387 session_.OnFrameLost(QuicFrame(frame));
2388 // Retransmit stream data causes connection close. Stream has not sent fin
2389 // yet, so an RST is sent.
2390 EXPECT_CALL(*stream, OnCanWrite())
2391 .WillOnce(Invoke(stream, &QuicStream::OnClose));
2392 if (VersionHasIetfQuicFrames(transport_version())) {
2393 // Once for the RST_STREAM, once for the STOP_SENDING
2394 EXPECT_CALL(*connection_, SendControlFrame(_))
2395 .Times(2)
2396 .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
2397 } else {
2398 // Just for the RST_STREAM
2399 EXPECT_CALL(*connection_, SendControlFrame(_))
2400 .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
2401 }
2402 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
2403 session_.OnCanWrite();
2404 }
2405
TEST_P(QuicSessionTestServer,SendMessage)2406 TEST_P(QuicSessionTestServer, SendMessage) {
2407 // Cannot send message when encryption is not established.
2408 EXPECT_FALSE(session_.OneRttKeysAvailable());
2409 quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
2410 EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
2411 session_.SendMessage(
2412 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2413 "", &storage)));
2414
2415 // Finish handshake.
2416 if (connection_->version().HasHandshakeDone()) {
2417 EXPECT_CALL(*connection_, SendControlFrame(_));
2418 }
2419 CryptoHandshakeMessage handshake_message;
2420 session_.GetMutableCryptoStream()->OnHandshakeMessage(handshake_message);
2421 EXPECT_TRUE(session_.OneRttKeysAvailable());
2422
2423 quiche::QuicheStringPiece message;
2424 EXPECT_CALL(*connection_, SendMessage(1, _, false))
2425 .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
2426 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
2427 session_.SendMessage(
2428 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2429 message, &storage)));
2430 // Verify message_id increases.
2431 EXPECT_CALL(*connection_, SendMessage(2, _, false))
2432 .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
2433 EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
2434 session_.SendMessage(
2435 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2436 message, &storage)));
2437 // Verify unsent message does not consume a message_id.
2438 EXPECT_CALL(*connection_, SendMessage(2, _, false))
2439 .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
2440 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
2441 session_.SendMessage(
2442 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2443 message, &storage)));
2444
2445 QuicMessageFrame frame(1);
2446 QuicMessageFrame frame2(2);
2447 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
2448 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
2449
2450 // Lost message 2.
2451 session_.OnMessageLost(2);
2452 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
2453
2454 // message 1 gets acked.
2455 session_.OnMessageAcked(1, QuicTime::Zero());
2456 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
2457 }
2458
2459 // Regression test of b/115323618.
TEST_P(QuicSessionTestServer,LocallyResetZombieStreams)2460 TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
2461 session_.set_writev_consumes_all_data(true);
2462 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2463 std::string body(100, '.');
2464 stream2->CloseReadSide();
2465 stream2->WriteOrBufferData(body, true, nullptr);
2466 EXPECT_TRUE(stream2->IsWaitingForAcks());
2467 // Verify stream2 is a zombie streams.
2468 EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2469
2470 QuicStreamFrame frame(stream2->id(), true, 0, 100);
2471 EXPECT_CALL(*stream2, HasPendingRetransmission())
2472 .WillRepeatedly(Return(true));
2473 session_.OnFrameLost(QuicFrame(frame));
2474
2475 // Reset stream2 locally.
2476 EXPECT_CALL(*connection_, SendControlFrame(_))
2477 .WillRepeatedly(Invoke(&ClearControlFrame));
2478 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2479 stream2->Reset(QUIC_STREAM_CANCELLED);
2480
2481 // Verify stream 2 gets closed.
2482 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2483 EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
2484 EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
2485 session_.OnCanWrite();
2486 }
2487
TEST_P(QuicSessionTestServer,CleanUpClosedStreamsAlarm)2488 TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
2489 EXPECT_FALSE(
2490 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
2491
2492 session_.set_writev_consumes_all_data(true);
2493 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2494 EXPECT_FALSE(stream2->IsWaitingForAcks());
2495
2496 EXPECT_CALL(*connection_, SendControlFrame(_));
2497 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2498 session_.CloseStream(stream2->id());
2499 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2500 EXPECT_EQ(1u, session_.closed_streams()->size());
2501 EXPECT_TRUE(
2502 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
2503
2504 alarm_factory_.FireAlarm(
2505 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
2506 EXPECT_TRUE(session_.closed_streams()->empty());
2507 }
2508
TEST_P(QuicSessionTestServer,WriteUnidirectionalStream)2509 TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
2510 session_.set_writev_consumes_all_data(true);
2511 TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
2512 &session_, WRITE_UNIDIRECTIONAL);
2513 session_.ActivateStream(QuicWrapUnique(stream4));
2514 std::string body(100, '.');
2515 stream4->WriteOrBufferData(body, false, nullptr);
2516 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
2517 stream4->WriteOrBufferData(body, true, nullptr);
2518 EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
2519 }
2520
TEST_P(QuicSessionTestServer,ReceivedDataOnWriteUnidirectionalStream)2521 TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
2522 TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
2523 &session_, WRITE_UNIDIRECTIONAL);
2524 session_.ActivateStream(QuicWrapUnique(stream4));
2525
2526 EXPECT_CALL(
2527 *connection_,
2528 CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
2529 .Times(1);
2530 QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
2531 0, 2);
2532 session_.OnStreamFrame(stream_frame);
2533 }
2534
TEST_P(QuicSessionTestServer,ReadUnidirectionalStream)2535 TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
2536 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2537 &session_, READ_UNIDIRECTIONAL);
2538 session_.ActivateStream(QuicWrapUnique(stream4));
2539 EXPECT_FALSE(stream4->IsWaitingForAcks());
2540 // Discard all incoming data.
2541 stream4->StopReading();
2542
2543 std::string data(100, '.');
2544 QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
2545 0, data);
2546 stream4->OnStreamFrame(stream_frame);
2547 EXPECT_TRUE(session_.closed_streams()->empty());
2548
2549 QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
2550 100, data);
2551 stream4->OnStreamFrame(stream_frame2);
2552 EXPECT_EQ(1u, session_.closed_streams()->size());
2553 }
2554
TEST_P(QuicSessionTestServer,WriteOrBufferDataOnReadUnidirectionalStream)2555 TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
2556 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2557 &session_, READ_UNIDIRECTIONAL);
2558 session_.ActivateStream(QuicWrapUnique(stream4));
2559
2560 EXPECT_CALL(*connection_,
2561 CloseConnection(
2562 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2563 .Times(1);
2564 std::string body(100, '.');
2565 stream4->WriteOrBufferData(body, false, nullptr);
2566 }
2567
TEST_P(QuicSessionTestServer,WritevDataOnReadUnidirectionalStream)2568 TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
2569 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2570 &session_, READ_UNIDIRECTIONAL);
2571 session_.ActivateStream(QuicWrapUnique(stream4));
2572
2573 EXPECT_CALL(*connection_,
2574 CloseConnection(
2575 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2576 .Times(1);
2577 std::string body(100, '.');
2578 struct iovec iov = {const_cast<char*>(body.data()), body.length()};
2579 QuicMemSliceStorage storage(
2580 &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
2581 1024);
2582 stream4->WriteMemSlices(storage.ToSpan(), false);
2583 }
2584
TEST_P(QuicSessionTestServer,WriteMemSlicesOnReadUnidirectionalStream)2585 TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
2586 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2587 &session_, READ_UNIDIRECTIONAL);
2588 session_.ActivateStream(QuicWrapUnique(stream4));
2589
2590 EXPECT_CALL(*connection_,
2591 CloseConnection(
2592 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2593 .Times(1);
2594 char data[1024];
2595 std::vector<std::pair<char*, size_t>> buffers;
2596 buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data)));
2597 buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data)));
2598 QuicTestMemSliceVector vector(buffers);
2599 stream4->WriteMemSlices(vector.span(), false);
2600 }
2601
2602 // Test code that tests that an incoming stream frame with a new (not previously
2603 // seen) stream id is acceptable. The ID must not be larger than has been
2604 // advertised. It may be equal to what has been advertised. These tests
2605 // invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
2606 // QuicSession::OnStreamFrame in order to check that all the steps are connected
2607 // properly and that nothing in the call path interferes with the check.
2608 // First test make sure that streams with ids below the limit are accepted.
TEST_P(QuicSessionTestServer,NewStreamIdBelowLimit)2609 TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
2610 if (!VersionHasIetfQuicFrames(transport_version())) {
2611 // Applicable only to IETF QUIC
2612 return;
2613 }
2614 QuicStreamId bidirectional_stream_id = StreamCountToId(
2615 QuicSessionPeer::v99_streamid_manager(&session_)
2616 ->advertised_max_incoming_bidirectional_streams() -
2617 1,
2618 Perspective::IS_CLIENT,
2619 /*bidirectional=*/true);
2620
2621 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2622 "Random String");
2623 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2624 session_.OnStreamFrame(bidirectional_stream_frame);
2625
2626 QuicStreamId unidirectional_stream_id = StreamCountToId(
2627 QuicSessionPeer::v99_streamid_manager(&session_)
2628 ->advertised_max_incoming_unidirectional_streams() -
2629 1,
2630 Perspective::IS_CLIENT,
2631 /*bidirectional=*/false);
2632 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2633 0, "Random String");
2634 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2635 session_.OnStreamFrame(unidirectional_stream_frame);
2636 }
2637
2638 // Accept a stream with an ID that equals the limit.
TEST_P(QuicSessionTestServer,NewStreamIdAtLimit)2639 TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
2640 if (!VersionHasIetfQuicFrames(transport_version())) {
2641 // Applicable only to IETF QUIC
2642 return;
2643 }
2644 QuicStreamId bidirectional_stream_id =
2645 StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_)
2646 ->advertised_max_incoming_bidirectional_streams(),
2647 Perspective::IS_CLIENT, /*bidirectional=*/true);
2648 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2649 "Random String");
2650 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2651 session_.OnStreamFrame(bidirectional_stream_frame);
2652
2653 QuicStreamId unidirectional_stream_id =
2654 StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_)
2655 ->advertised_max_incoming_unidirectional_streams(),
2656 Perspective::IS_CLIENT, /*bidirectional=*/false);
2657 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2658 0, "Random String");
2659 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2660 session_.OnStreamFrame(unidirectional_stream_frame);
2661 }
2662
2663 // Close the connection if the id exceeds the limit.
TEST_P(QuicSessionTestServer,NewStreamIdAboveLimit)2664 TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
2665 if (!VersionHasIetfQuicFrames(transport_version())) {
2666 // Applicable only to IETF QUIC
2667 return;
2668 }
2669
2670 QuicStreamId bidirectional_stream_id = StreamCountToId(
2671 QuicSessionPeer::v99_streamid_manager(&session_)
2672 ->advertised_max_incoming_bidirectional_streams() +
2673 1,
2674 Perspective::IS_CLIENT, /*bidirectional=*/true);
2675 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2676 "Random String");
2677 EXPECT_CALL(
2678 *connection_,
2679 CloseConnection(QUIC_INVALID_STREAM_ID,
2680 "Stream id 400 would exceed stream count limit 100", _));
2681 session_.OnStreamFrame(bidirectional_stream_frame);
2682
2683 QuicStreamId unidirectional_stream_id = StreamCountToId(
2684 QuicSessionPeer::v99_streamid_manager(&session_)
2685 ->advertised_max_incoming_unidirectional_streams() +
2686 1,
2687 Perspective::IS_CLIENT, /*bidirectional=*/false);
2688 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2689 0, "Random String");
2690 EXPECT_CALL(
2691 *connection_,
2692 CloseConnection(QUIC_INVALID_STREAM_ID,
2693 "Stream id 402 would exceed stream count limit 100", _));
2694 session_.OnStreamFrame(unidirectional_stream_frame);
2695 }
2696
2697 // Checks that invalid stream ids are handled.
TEST_P(QuicSessionTestServer,OnStopSendingInvalidStreamId)2698 TEST_P(QuicSessionTestServer, OnStopSendingInvalidStreamId) {
2699 if (!VersionHasIetfQuicFrames(transport_version())) {
2700 return;
2701 }
2702 // Check that "invalid" stream ids are rejected.
2703 QuicStopSendingFrame frame(1, -1, 123);
2704 EXPECT_CALL(
2705 *connection_,
2706 CloseConnection(QUIC_INVALID_STREAM_ID,
2707 "Received STOP_SENDING for an invalid stream", _));
2708 session_.OnStopSendingFrame(frame);
2709 }
2710
TEST_P(QuicSessionTestServer,OnStopSendingReadUnidirectional)2711 TEST_P(QuicSessionTestServer, OnStopSendingReadUnidirectional) {
2712 if (!VersionHasIetfQuicFrames(transport_version())) {
2713 return;
2714 }
2715 // It's illegal to send STOP_SENDING with a stream ID that is read-only.
2716 QuicStopSendingFrame frame(1, GetNthClientInitiatedUnidirectionalId(1), 123);
2717 EXPECT_CALL(
2718 *connection_,
2719 CloseConnection(QUIC_INVALID_STREAM_ID,
2720 "Received STOP_SENDING for a read-only stream", _));
2721 session_.OnStopSendingFrame(frame);
2722 }
2723
2724 // Static streams ignore STOP_SENDING.
TEST_P(QuicSessionTestServer,OnStopSendingStaticStreams)2725 TEST_P(QuicSessionTestServer, OnStopSendingStaticStreams) {
2726 if (!VersionHasIetfQuicFrames(transport_version())) {
2727 return;
2728 }
2729 QuicStreamId stream_id = 0;
2730 std::unique_ptr<TestStream> fake_static_stream = std::make_unique<TestStream>(
2731 stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
2732 QuicSessionPeer::ActivateStream(&session_, std::move(fake_static_stream));
2733 // Check that a stream id in the static stream map is ignored.
2734 QuicStopSendingFrame frame(1, stream_id, 123);
2735 EXPECT_CALL(*connection_,
2736 CloseConnection(QUIC_INVALID_STREAM_ID,
2737 "Received STOP_SENDING for a static stream", _));
2738 session_.OnStopSendingFrame(frame);
2739 }
2740
2741 // If stream is write closed, do not send a RESET_STREAM frame.
TEST_P(QuicSessionTestServer,OnStopSendingForWriteClosedStream)2742 TEST_P(QuicSessionTestServer, OnStopSendingForWriteClosedStream) {
2743 if (!VersionHasIetfQuicFrames(transport_version())) {
2744 return;
2745 }
2746
2747 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2748 QuicStreamId stream_id = stream->id();
2749 stream->CloseWriteSide();
2750 EXPECT_TRUE(stream->write_side_closed());
2751 QuicStopSendingFrame frame(1, stream_id, 123);
2752 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2753 session_.OnStopSendingFrame(frame);
2754 }
2755
2756 // If stream is closed, return true and do not close the connection.
TEST_P(QuicSessionTestServer,OnStopSendingClosedStream)2757 TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) {
2758 if (!VersionHasIetfQuicFrames(transport_version())) {
2759 return;
2760 }
2761
2762 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2763 QuicStreamId stream_id = stream->id();
2764 // Expect these as side effect of closing the stream.
2765 EXPECT_CALL(*connection_, SendControlFrame(_));
2766 EXPECT_CALL(*connection_, OnStreamReset(_, _));
2767 session_.CloseStream(stream_id);
2768 QuicStopSendingFrame frame(1, stream_id, 123);
2769 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2770 session_.OnStopSendingFrame(frame);
2771 }
2772
2773 // If stream id is a nonexistent local stream, return false and close the
2774 // connection.
TEST_P(QuicSessionTestServer,OnStopSendingInputNonExistentLocalStream)2775 TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) {
2776 if (!VersionHasIetfQuicFrames(transport_version())) {
2777 return;
2778 }
2779
2780 QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
2781 123);
2782 EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_STREAM_WRONG_DIRECTION,
2783 "Data for nonexistent stream", _))
2784 .Times(1);
2785 session_.OnStopSendingFrame(frame);
2786 }
2787
2788 // If a STOP_SENDING is received for a peer initiated stream, the new stream
2789 // will be created.
TEST_P(QuicSessionTestServer,OnStopSendingNewStream)2790 TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
2791 if (!VersionHasIetfQuicFrames(transport_version())) {
2792 return;
2793 }
2794 QuicStopSendingFrame frame(1, GetNthClientInitiatedBidirectionalId(1), 123);
2795
2796 // A Rst will be sent as a response for STOP_SENDING.
2797 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
2798 EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
2799 session_.OnStopSendingFrame(frame);
2800
2801 QuicStream* stream =
2802 session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(1));
2803 EXPECT_TRUE(stream);
2804 EXPECT_TRUE(stream->write_side_closed());
2805 }
2806
2807 // For a valid stream, ensure that all works
TEST_P(QuicSessionTestServer,OnStopSendingInputValidStream)2808 TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
2809 if (!VersionHasIetfQuicFrames(transport_version())) {
2810 // Applicable only to IETF QUIC
2811 return;
2812 }
2813
2814 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2815
2816 // Ensure that the stream starts out open in both directions.
2817 EXPECT_FALSE(stream->write_side_closed());
2818 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
2819
2820 QuicStreamId stream_id = stream->id();
2821 QuicStopSendingFrame frame(1, stream_id, 123);
2822 // Expect a reset to come back out.
2823 EXPECT_CALL(*connection_, SendControlFrame(_));
2824 EXPECT_CALL(
2825 *connection_,
2826 OnStreamReset(stream_id, static_cast<QuicRstStreamErrorCode>(123)));
2827 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2828 session_.OnStopSendingFrame(frame);
2829
2830 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
2831 EXPECT_TRUE(stream->write_side_closed());
2832 }
2833
TEST_P(QuicSessionTestServer,WriteBufferedCryptoFrames)2834 TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
2835 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
2836 return;
2837 }
2838 std::string data(1350, 'a');
2839 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
2840 // Only consumed 1000 bytes.
2841 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
2842 .WillOnce(Return(1000));
2843 crypto_stream->WriteCryptoData(ENCRYPTION_INITIAL, data);
2844 EXPECT_TRUE(session_.HasPendingHandshake());
2845 EXPECT_TRUE(session_.WillingAndAbleToWrite());
2846
2847 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
2848 crypto_stream->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
2849
2850 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
2851 .WillOnce(Return(350));
2852 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
2853 .WillOnce(Return(1350));
2854 session_.OnCanWrite();
2855 EXPECT_FALSE(session_.HasPendingHandshake());
2856 EXPECT_FALSE(session_.WillingAndAbleToWrite());
2857 }
2858
2859 // Regression test for
2860 // https://bugs.chromium.org/p/chromium/issues/detail?id=1002119
TEST_P(QuicSessionTestServer,StreamFrameReceivedAfterFin)2861 TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) {
2862 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2863 QuicStreamFrame frame(stream->id(), true, 0, ",");
2864 session_.OnStreamFrame(frame);
2865
2866 QuicStreamFrame frame1(stream->id(), false, 1, ",");
2867 EXPECT_CALL(*connection_,
2868 CloseConnection(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET, _, _));
2869 session_.OnStreamFrame(frame1);
2870 }
2871
TEST_P(QuicSessionTestServer,ResetForIETFStreamTypes)2872 TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
2873 if (!VersionHasIetfQuicFrames(transport_version())) {
2874 return;
2875 }
2876
2877 QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
2878
2879 EXPECT_CALL(*connection_, SendControlFrame(_))
2880 .Times(1)
2881 .WillOnce(Invoke(&ClearControlFrame));
2882 EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
2883 session_.SendRstStream(read_only, QUIC_STREAM_CANCELLED, 0);
2884
2885 QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
2886 EXPECT_CALL(*connection_, SendControlFrame(_))
2887 .Times(1)
2888 .WillOnce(Invoke(&ClearControlFrame));
2889 EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
2890 session_.SendRstStream(write_only, QUIC_STREAM_CANCELLED, 0);
2891
2892 QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
2893 EXPECT_CALL(*connection_, SendControlFrame(_))
2894 .Times(2)
2895 .WillRepeatedly(Invoke(&ClearControlFrame));
2896 EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
2897 session_.SendRstStream(bidirectional, QUIC_STREAM_CANCELLED, 0);
2898 }
2899
TEST_P(QuicSessionTestServer,DecryptionKeyAvailableBeforeEncryptionKey)2900 TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) {
2901 if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
2902 return;
2903 }
2904 ASSERT_FALSE(connection_->framer().HasEncrypterOfEncryptionLevel(
2905 ENCRYPTION_HANDSHAKE));
2906 EXPECT_FALSE(session_.OnNewDecryptionKeyAvailable(
2907 ENCRYPTION_HANDSHAKE, /*decrypter=*/nullptr,
2908 /*set_alternative_decrypter=*/false, /*latch_once_used=*/false));
2909 }
2910
TEST_P(QuicSessionTestServer,IncomingStreamWithServerInitiatedStreamId)2911 TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) {
2912 const QuicErrorCode expected_error =
2913 VersionHasIetfQuicFrames(transport_version())
2914 ? QUIC_HTTP_STREAM_WRONG_DIRECTION
2915 : QUIC_INVALID_STREAM_ID;
2916 EXPECT_CALL(
2917 *connection_,
2918 CloseConnection(expected_error, "Data for nonexistent stream",
2919 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
2920
2921 QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1),
2922 /* fin = */ false, /* offset = */ 0,
2923 quiche::QuicheStringPiece("foo"));
2924 session_.OnStreamFrame(frame);
2925 }
2926
2927 // A client test class that can be used when the automatic configuration is not
2928 // desired.
2929 class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {
2930 protected:
QuicSessionTestClientUnconfigured()2931 QuicSessionTestClientUnconfigured()
2932 : QuicSessionTestBase(Perspective::IS_CLIENT,
2933 /*configure_session=*/false) {}
2934 };
2935
2936 INSTANTIATE_TEST_SUITE_P(Tests,
2937 QuicSessionTestClientUnconfigured,
2938 ::testing::ValuesIn(AllSupportedVersions()),
2939 ::testing::PrintToStringParamName());
2940
TEST_P(QuicSessionTestClientUnconfigured,StreamInitiallyBlockedThenUnblocked)2941 TEST_P(QuicSessionTestClientUnconfigured, StreamInitiallyBlockedThenUnblocked) {
2942 if (!connection_->version().AllowsLowFlowControlLimits()) {
2943 return;
2944 }
2945 // Create a stream before negotiating the config and verify it starts off
2946 // blocked.
2947 QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10);
2948 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2949 EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
2950 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
2951 EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
2952
2953 // Negotiate the config with higher received limits.
2954 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
2955 session_.config(), kMinimumFlowControlSendWindow);
2956 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
2957 session_.config(), kMinimumFlowControlSendWindow);
2958 session_.OnConfigNegotiated();
2959
2960 // Stream is now unblocked.
2961 EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
2962 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
2963 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
2964 }
2965
2966 } // namespace
2967 } // namespace test
2968 } // namespace quic
2969