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/quic/quic_session.h" 6 7 #include <set> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/containers/hash_tables.h" 12 #include "base/rand_util.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "net/quic/crypto/crypto_protocol.h" 15 #include "net/quic/quic_crypto_stream.h" 16 #include "net/quic/quic_flags.h" 17 #include "net/quic/quic_protocol.h" 18 #include "net/quic/quic_utils.h" 19 #include "net/quic/reliable_quic_stream.h" 20 #include "net/quic/test_tools/quic_config_peer.h" 21 #include "net/quic/test_tools/quic_connection_peer.h" 22 #include "net/quic/test_tools/quic_data_stream_peer.h" 23 #include "net/quic/test_tools/quic_flow_controller_peer.h" 24 #include "net/quic/test_tools/quic_session_peer.h" 25 #include "net/quic/test_tools/quic_test_utils.h" 26 #include "net/quic/test_tools/reliable_quic_stream_peer.h" 27 #include "net/spdy/spdy_framer.h" 28 #include "net/test/gtest_util.h" 29 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gmock_mutant.h" 31 #include "testing/gtest/include/gtest/gtest.h" 32 33 using base::hash_map; 34 using std::set; 35 using std::vector; 36 using testing::CreateFunctor; 37 using testing::InSequence; 38 using testing::Invoke; 39 using testing::Return; 40 using testing::StrictMock; 41 using testing::_; 42 43 namespace net { 44 namespace test { 45 namespace { 46 47 const QuicPriority kHighestPriority = 0; 48 const QuicPriority kSomeMiddlePriority = 3; 49 50 class TestCryptoStream : public QuicCryptoStream { 51 public: 52 explicit TestCryptoStream(QuicSession* session) 53 : QuicCryptoStream(session) { 54 } 55 56 virtual void OnHandshakeMessage( 57 const CryptoHandshakeMessage& message) OVERRIDE { 58 encryption_established_ = true; 59 handshake_confirmed_ = true; 60 CryptoHandshakeMessage msg; 61 string error_details; 62 session()->config()->SetInitialFlowControlWindowToSend( 63 kInitialSessionFlowControlWindowForTest); 64 session()->config()->SetInitialStreamFlowControlWindowToSend( 65 kInitialStreamFlowControlWindowForTest); 66 session()->config()->SetInitialSessionFlowControlWindowToSend( 67 kInitialSessionFlowControlWindowForTest); 68 session()->config()->ToHandshakeMessage(&msg); 69 const QuicErrorCode error = session()->config()->ProcessPeerHello( 70 msg, CLIENT, &error_details); 71 EXPECT_EQ(QUIC_NO_ERROR, error); 72 session()->OnConfigNegotiated(); 73 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 74 } 75 76 MOCK_METHOD0(OnCanWrite, void()); 77 }; 78 79 class TestHeadersStream : public QuicHeadersStream { 80 public: 81 explicit TestHeadersStream(QuicSession* session) 82 : QuicHeadersStream(session) { 83 } 84 85 MOCK_METHOD0(OnCanWrite, void()); 86 }; 87 88 class TestStream : public QuicDataStream { 89 public: 90 TestStream(QuicStreamId id, QuicSession* session) 91 : QuicDataStream(id, session) { 92 } 93 94 using ReliableQuicStream::CloseWriteSide; 95 96 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { 97 return data_len; 98 } 99 100 void SendBody(const string& data, bool fin) { 101 WriteOrBufferData(data, fin, NULL); 102 } 103 104 MOCK_METHOD0(OnCanWrite, void()); 105 }; 106 107 // Poor man's functor for use as callback in a mock. 108 class StreamBlocker { 109 public: 110 StreamBlocker(QuicSession* session, QuicStreamId stream_id) 111 : session_(session), 112 stream_id_(stream_id) { 113 } 114 115 void MarkWriteBlocked() { 116 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority); 117 } 118 119 private: 120 QuicSession* const session_; 121 const QuicStreamId stream_id_; 122 }; 123 124 class TestSession : public QuicSession { 125 public: 126 explicit TestSession(QuicConnection* connection) 127 : QuicSession(connection, 128 DefaultQuicConfig()), 129 crypto_stream_(this), 130 writev_consumes_all_data_(false) { 131 InitializeSession(); 132 } 133 134 virtual TestCryptoStream* GetCryptoStream() OVERRIDE { 135 return &crypto_stream_; 136 } 137 138 virtual TestStream* CreateOutgoingDataStream() OVERRIDE { 139 TestStream* stream = new TestStream(GetNextStreamId(), this); 140 ActivateStream(stream); 141 return stream; 142 } 143 144 virtual TestStream* CreateIncomingDataStream(QuicStreamId id) OVERRIDE { 145 return new TestStream(id, this); 146 } 147 148 bool IsClosedStream(QuicStreamId id) { 149 return QuicSession::IsClosedStream(id); 150 } 151 152 QuicDataStream* GetIncomingDataStream(QuicStreamId stream_id) { 153 return QuicSession::GetIncomingDataStream(stream_id); 154 } 155 156 virtual QuicConsumedData WritevData( 157 QuicStreamId id, 158 const IOVector& data, 159 QuicStreamOffset offset, 160 bool fin, 161 FecProtection fec_protection, 162 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) OVERRIDE { 163 // Always consumes everything. 164 if (writev_consumes_all_data_) { 165 return QuicConsumedData(data.TotalBufferSize(), fin); 166 } else { 167 return QuicSession::WritevData(id, data, offset, fin, fec_protection, 168 ack_notifier_delegate); 169 } 170 } 171 172 void set_writev_consumes_all_data(bool val) { 173 writev_consumes_all_data_ = val; 174 } 175 176 QuicConsumedData SendStreamData(QuicStreamId id) { 177 return WritevData(id, IOVector(), 0, true, MAY_FEC_PROTECT, NULL); 178 } 179 180 using QuicSession::PostProcessAfterData; 181 182 private: 183 StrictMock<TestCryptoStream> crypto_stream_; 184 185 bool writev_consumes_all_data_; 186 }; 187 188 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { 189 protected: 190 QuicSessionTest() 191 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), 192 session_(connection_) { 193 session_.config()->SetInitialFlowControlWindowToSend( 194 kInitialSessionFlowControlWindowForTest); 195 session_.config()->SetInitialStreamFlowControlWindowToSend( 196 kInitialStreamFlowControlWindowForTest); 197 session_.config()->SetInitialSessionFlowControlWindowToSend( 198 kInitialSessionFlowControlWindowForTest); 199 headers_[":host"] = "www.google.com"; 200 headers_[":path"] = "/index.hml"; 201 headers_[":scheme"] = "http"; 202 headers_["cookie"] = 203 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " 204 "__utmc=160408618; " 205 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" 206 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" 207 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" 208 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" 209 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh" 210 "1zFMi5vzcns38-8_Sns; " 211 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-" 212 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339" 213 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c" 214 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%" 215 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4" 216 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1" 217 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP" 218 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6" 219 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b" 220 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" 221 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" 222 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" 223 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" 224 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" 225 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; 226 } 227 228 void CheckClosedStreams() { 229 for (int i = kCryptoStreamId; i < 100; i++) { 230 if (closed_streams_.count(i) == 0) { 231 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; 232 } else { 233 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; 234 } 235 } 236 } 237 238 void CloseStream(QuicStreamId id) { 239 session_.CloseStream(id); 240 closed_streams_.insert(id); 241 } 242 243 QuicVersion version() const { return connection_->version(); } 244 245 MockConnection* connection_; 246 TestSession session_; 247 set<QuicStreamId> closed_streams_; 248 SpdyHeaderBlock headers_; 249 }; 250 251 INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTest, 252 ::testing::ValuesIn(QuicSupportedVersions())); 253 254 TEST_P(QuicSessionTest, PeerAddress) { 255 EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address()); 256 } 257 258 TEST_P(QuicSessionTest, IsCryptoHandshakeConfirmed) { 259 EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed()); 260 CryptoHandshakeMessage message; 261 session_.GetCryptoStream()->OnHandshakeMessage(message); 262 EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed()); 263 } 264 265 TEST_P(QuicSessionTest, IsClosedStreamDefault) { 266 // Ensure that no streams are initially closed. 267 for (int i = kCryptoStreamId; i < 100; i++) { 268 EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i; 269 } 270 } 271 272 TEST_P(QuicSessionTest, ImplicitlyCreatedStreams) { 273 ASSERT_TRUE(session_.GetIncomingDataStream(7) != NULL); 274 // Both 3 and 5 should be implicitly created. 275 EXPECT_FALSE(session_.IsClosedStream(3)); 276 EXPECT_FALSE(session_.IsClosedStream(5)); 277 ASSERT_TRUE(session_.GetIncomingDataStream(5) != NULL); 278 ASSERT_TRUE(session_.GetIncomingDataStream(3) != NULL); 279 } 280 281 TEST_P(QuicSessionTest, IsClosedStreamLocallyCreated) { 282 TestStream* stream2 = session_.CreateOutgoingDataStream(); 283 EXPECT_EQ(2u, stream2->id()); 284 TestStream* stream4 = session_.CreateOutgoingDataStream(); 285 EXPECT_EQ(4u, stream4->id()); 286 287 CheckClosedStreams(); 288 CloseStream(4); 289 CheckClosedStreams(); 290 CloseStream(2); 291 CheckClosedStreams(); 292 } 293 294 TEST_P(QuicSessionTest, IsClosedStreamPeerCreated) { 295 QuicStreamId stream_id1 = kClientDataStreamId1; 296 QuicStreamId stream_id2 = kClientDataStreamId2; 297 QuicDataStream* stream1 = session_.GetIncomingDataStream(stream_id1); 298 QuicDataStreamPeer::SetHeadersDecompressed(stream1, true); 299 QuicDataStream* stream2 = session_.GetIncomingDataStream(stream_id2); 300 QuicDataStreamPeer::SetHeadersDecompressed(stream2, true); 301 302 CheckClosedStreams(); 303 CloseStream(stream_id1); 304 CheckClosedStreams(); 305 CloseStream(stream_id2); 306 // Create a stream explicitly, and another implicitly. 307 QuicDataStream* stream3 = session_.GetIncomingDataStream(stream_id2 + 4); 308 QuicDataStreamPeer::SetHeadersDecompressed(stream3, true); 309 CheckClosedStreams(); 310 // Close one, but make sure the other is still not closed 311 CloseStream(stream3->id()); 312 CheckClosedStreams(); 313 } 314 315 TEST_P(QuicSessionTest, StreamIdTooLarge) { 316 QuicStreamId stream_id = kClientDataStreamId1; 317 session_.GetIncomingDataStream(stream_id); 318 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); 319 session_.GetIncomingDataStream(stream_id + kMaxStreamIdDelta + 2); 320 } 321 322 TEST_P(QuicSessionTest, DecompressionError) { 323 QuicHeadersStream* stream = QuicSessionPeer::GetHeadersStream(&session_); 324 const unsigned char data[] = { 325 0x80, 0x03, 0x00, 0x01, // SPDY/3 SYN_STREAM frame 326 0x00, 0x00, 0x00, 0x25, // flags/length 327 0x00, 0x00, 0x00, 0x05, // stream id 328 0x00, 0x00, 0x00, 0x00, // associated stream id 329 0x00, 0x00, 330 'a', 'b', 'c', 'd' // invalid compressed data 331 }; 332 EXPECT_CALL(*connection_, 333 SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 334 "SPDY framing error.")); 335 stream->ProcessRawData(reinterpret_cast<const char*>(data), 336 arraysize(data)); 337 } 338 339 TEST_P(QuicSessionTest, DebugDFatalIfMarkingClosedStreamWriteBlocked) { 340 TestStream* stream2 = session_.CreateOutgoingDataStream(); 341 // Close the stream. 342 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD); 343 // TODO(rtenneti): enable when chromium supports EXPECT_DEBUG_DFATAL. 344 /* 345 QuicStreamId kClosedStreamId = stream2->id(); 346 EXPECT_DEBUG_DFATAL( 347 session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority), 348 "Marking unknown stream 2 blocked."); 349 */ 350 } 351 352 TEST_P(QuicSessionTest, DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { 353 const QuicPriority kDifferentPriority = 0; 354 355 TestStream* stream2 = session_.CreateOutgoingDataStream(); 356 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); 357 // TODO(rtenneti): enable when chromium supports EXPECT_DEBUG_DFATAL. 358 /* 359 EXPECT_DEBUG_DFATAL( 360 session_.MarkWriteBlocked(stream2->id(), kDifferentPriority), 361 "Priorities do not match. Got: 0 Expected: 3"); 362 */ 363 } 364 365 TEST_P(QuicSessionTest, OnCanWrite) { 366 TestStream* stream2 = session_.CreateOutgoingDataStream(); 367 TestStream* stream4 = session_.CreateOutgoingDataStream(); 368 TestStream* stream6 = session_.CreateOutgoingDataStream(); 369 370 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); 371 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); 372 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); 373 374 InSequence s; 375 StreamBlocker stream2_blocker(&session_, stream2->id()); 376 // Reregister, to test the loop limit. 377 EXPECT_CALL(*stream2, OnCanWrite()) 378 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); 379 EXPECT_CALL(*stream6, OnCanWrite()); 380 EXPECT_CALL(*stream4, OnCanWrite()); 381 session_.OnCanWrite(); 382 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 383 } 384 385 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { 386 // Drive congestion control manually. 387 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; 388 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); 389 390 TestStream* stream2 = session_.CreateOutgoingDataStream(); 391 TestStream* stream4 = session_.CreateOutgoingDataStream(); 392 TestStream* stream6 = session_.CreateOutgoingDataStream(); 393 394 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); 395 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); 396 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); 397 398 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly( 399 Return(QuicTime::Delta::Zero())); 400 EXPECT_CALL(*send_algorithm, GetCongestionWindow()) 401 .WillOnce(Return(kMaxPacketSize * 10)); 402 EXPECT_CALL(*stream2, OnCanWrite()) 403 .WillOnce(IgnoreResult(Invoke(CreateFunctor( 404 &session_, &TestSession::SendStreamData, stream2->id())))); 405 EXPECT_CALL(*stream4, OnCanWrite()) 406 .WillOnce(IgnoreResult(Invoke(CreateFunctor( 407 &session_, &TestSession::SendStreamData, stream4->id())))); 408 EXPECT_CALL(*stream6, OnCanWrite()) 409 .WillOnce(IgnoreResult(Invoke(CreateFunctor( 410 &session_, &TestSession::SendStreamData, stream6->id())))); 411 412 // Expect that we only send one packet, the writes from different streams 413 // should be bundled together. 414 MockPacketWriter* writer = 415 static_cast<MockPacketWriter*>( 416 QuicConnectionPeer::GetWriter(session_.connection())); 417 EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( 418 Return(WriteResult(WRITE_STATUS_OK, 0))); 419 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)).Times(1); 420 session_.OnCanWrite(); 421 EXPECT_FALSE(session_.WillingAndAbleToWrite()); 422 } 423 424 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) { 425 InSequence s; 426 427 // Drive congestion control manually. 428 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; 429 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); 430 431 TestStream* stream2 = session_.CreateOutgoingDataStream(); 432 TestStream* stream4 = session_.CreateOutgoingDataStream(); 433 TestStream* stream6 = session_.CreateOutgoingDataStream(); 434 435 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); 436 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); 437 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); 438 439 StreamBlocker stream2_blocker(&session_, stream2->id()); 440 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( 441 QuicTime::Delta::Zero())); 442 EXPECT_CALL(*stream2, OnCanWrite()); 443 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( 444 QuicTime::Delta::Zero())); 445 EXPECT_CALL(*stream6, OnCanWrite()); 446 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( 447 QuicTime::Delta::Infinite())); 448 // stream4->OnCanWrite is not called. 449 450 session_.OnCanWrite(); 451 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 452 453 // Still congestion-control blocked. 454 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( 455 QuicTime::Delta::Infinite())); 456 session_.OnCanWrite(); 457 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 458 459 // stream4->OnCanWrite is called once the connection stops being 460 // congestion-control blocked. 461 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( 462 QuicTime::Delta::Zero())); 463 EXPECT_CALL(*stream4, OnCanWrite()); 464 session_.OnCanWrite(); 465 EXPECT_FALSE(session_.WillingAndAbleToWrite()); 466 } 467 468 TEST_P(QuicSessionTest, BufferedHandshake) { 469 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. 470 471 // Test that blocking other streams does not change our status. 472 TestStream* stream2 = session_.CreateOutgoingDataStream(); 473 StreamBlocker stream2_blocker(&session_, stream2->id()); 474 stream2_blocker.MarkWriteBlocked(); 475 EXPECT_FALSE(session_.HasPendingHandshake()); 476 477 TestStream* stream3 = session_.CreateOutgoingDataStream(); 478 StreamBlocker stream3_blocker(&session_, stream3->id()); 479 stream3_blocker.MarkWriteBlocked(); 480 EXPECT_FALSE(session_.HasPendingHandshake()); 481 482 // Blocking (due to buffering of) the Crypto stream is detected. 483 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); 484 EXPECT_TRUE(session_.HasPendingHandshake()); 485 486 TestStream* stream4 = session_.CreateOutgoingDataStream(); 487 StreamBlocker stream4_blocker(&session_, stream4->id()); 488 stream4_blocker.MarkWriteBlocked(); 489 EXPECT_TRUE(session_.HasPendingHandshake()); 490 491 InSequence s; 492 // Force most streams to re-register, which is common scenario when we block 493 // the Crypto stream, and only the crypto stream can "really" write. 494 495 // Due to prioritization, we *should* be asked to write the crypto stream 496 // first. 497 // Don't re-register the crypto stream (which signals complete writing). 498 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 499 EXPECT_CALL(*crypto_stream, OnCanWrite()); 500 501 // Re-register all other streams, to show they weren't able to proceed. 502 EXPECT_CALL(*stream2, OnCanWrite()) 503 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); 504 EXPECT_CALL(*stream3, OnCanWrite()) 505 .WillOnce(Invoke(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); 506 EXPECT_CALL(*stream4, OnCanWrite()) 507 .WillOnce(Invoke(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); 508 509 session_.OnCanWrite(); 510 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 511 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. 512 } 513 514 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { 515 TestStream* stream2 = session_.CreateOutgoingDataStream(); 516 TestStream* stream4 = session_.CreateOutgoingDataStream(); 517 TestStream* stream6 = session_.CreateOutgoingDataStream(); 518 519 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); 520 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); 521 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); 522 CloseStream(stream6->id()); 523 524 InSequence s; 525 EXPECT_CALL(*stream2, OnCanWrite()); 526 EXPECT_CALL(*stream4, OnCanWrite()); 527 session_.OnCanWrite(); 528 EXPECT_FALSE(session_.WillingAndAbleToWrite()); 529 } 530 531 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { 532 if (version() < QUIC_VERSION_19) { 533 return; 534 } 535 536 // Ensure connection level flow control blockage. 537 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); 538 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); 539 540 // Mark the crypto and headers streams as write blocked, we expect them to be 541 // allowed to write later. 542 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); 543 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); 544 545 // Create a data stream, and although it is write blocked we never expect it 546 // to be allowed to write as we are connection level flow control blocked. 547 TestStream* stream = session_.CreateOutgoingDataStream(); 548 session_.MarkWriteBlocked(stream->id(), kSomeMiddlePriority); 549 EXPECT_CALL(*stream, OnCanWrite()).Times(0); 550 551 // The crypto and headers streams should be called even though we are 552 // connection flow control blocked. 553 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 554 EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1); 555 TestHeadersStream* headers_stream = new TestHeadersStream(&session_); 556 QuicSessionPeer::SetHeadersStream(&session_, headers_stream); 557 EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1); 558 559 session_.OnCanWrite(); 560 EXPECT_FALSE(session_.WillingAndAbleToWrite()); 561 } 562 563 TEST_P(QuicSessionTest, SendGoAway) { 564 EXPECT_CALL(*connection_, 565 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); 566 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); 567 EXPECT_TRUE(session_.goaway_sent()); 568 569 EXPECT_CALL(*connection_, 570 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); 571 EXPECT_TRUE(session_.GetIncomingDataStream(3u)); 572 } 573 574 TEST_P(QuicSessionTest, DoNotSendGoAwayTwice) { 575 EXPECT_CALL(*connection_, 576 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")).Times(1); 577 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); 578 EXPECT_TRUE(session_.goaway_sent()); 579 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); 580 } 581 582 TEST_P(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { 583 // Add 1 to the connection timeout on the server side. 584 EXPECT_EQ(kDefaultInitialTimeoutSecs + 1, 585 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); 586 CryptoHandshakeMessage msg; 587 session_.GetCryptoStream()->OnHandshakeMessage(msg); 588 EXPECT_EQ(kMaximumIdleTimeoutSecs + 1, 589 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); 590 } 591 592 TEST_P(QuicSessionTest, RstStreamBeforeHeadersDecompressed) { 593 // Send two bytes of payload. 594 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); 595 vector<QuicStreamFrame> frames; 596 frames.push_back(data1); 597 session_.OnStreamFrames(frames); 598 EXPECT_EQ(1u, session_.GetNumOpenStreams()); 599 600 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); 601 session_.OnRstStream(rst1); 602 EXPECT_EQ(0u, session_.GetNumOpenStreams()); 603 // Connection should remain alive. 604 EXPECT_TRUE(connection_->connected()); 605 } 606 607 TEST_P(QuicSessionTest, MultipleRstStreamsCauseSingleConnectionClose) { 608 // If multiple invalid reset stream frames arrive in a single packet, this 609 // should trigger a connection close. However there is no need to send 610 // multiple connection close frames. 611 612 // Create valid stream. 613 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); 614 vector<QuicStreamFrame> frames; 615 frames.push_back(data1); 616 session_.OnStreamFrames(frames); 617 EXPECT_EQ(1u, session_.GetNumOpenStreams()); 618 619 // Process first invalid stream reset, resulting in the connection being 620 // closed. 621 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)) 622 .Times(1); 623 QuicStreamId kLargeInvalidStreamId = 99999999; 624 QuicRstStreamFrame rst1(kLargeInvalidStreamId, QUIC_STREAM_NO_ERROR, 0); 625 session_.OnRstStream(rst1); 626 QuicConnectionPeer::CloseConnection(connection_); 627 628 // Processing of second invalid stream reset should not result in the 629 // connection being closed for a second time. 630 QuicRstStreamFrame rst2(kLargeInvalidStreamId, QUIC_STREAM_NO_ERROR, 0); 631 session_.OnRstStream(rst2); 632 } 633 634 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedStream) { 635 // Test that if a stream is flow control blocked, then on receipt of the SHLO 636 // containing a suitable send window offset, the stream becomes unblocked. 637 if (version() <= QUIC_VERSION_16) { 638 return; 639 } 640 641 // Ensure that Writev consumes all the data it is given (simulate no socket 642 // blocking). 643 session_.set_writev_consumes_all_data(true); 644 645 // Create a stream, and send enough data to make it flow control blocked. 646 TestStream* stream2 = session_.CreateOutgoingDataStream(); 647 string body(kDefaultFlowControlSendWindow, '.'); 648 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); 649 stream2->SendBody(body, false); 650 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); 651 652 // The handshake message will call OnCanWrite, so the stream can resume 653 // writing. 654 EXPECT_CALL(*stream2, OnCanWrite()); 655 // Now complete the crypto handshake, resulting in an increased flow control 656 // send window. 657 CryptoHandshakeMessage msg; 658 session_.GetCryptoStream()->OnHandshakeMessage(msg); 659 660 // Stream is now unblocked. 661 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); 662 } 663 664 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedCryptoStream) { 665 if (version() <= QUIC_VERSION_19) { 666 return; 667 } 668 // Test that if the crypto stream is flow control blocked, then if the SHLO 669 // contains a larger send window offset, the stream becomes unblocked. 670 session_.set_writev_consumes_all_data(true); 671 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 672 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); 673 QuicHeadersStream* headers_stream = 674 QuicSessionPeer::GetHeadersStream(&session_); 675 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 676 // Write until the crypto stream is flow control blocked. 677 int i = 0; 678 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { 679 QuicConfig config; 680 CryptoHandshakeMessage crypto_message; 681 config.ToHandshakeMessage(&crypto_message); 682 crypto_stream->SendHandshakeMessage(crypto_message); 683 ++i; 684 } 685 EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked()); 686 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 687 EXPECT_FALSE(session_.HasDataToWrite()); 688 EXPECT_TRUE(crypto_stream->HasBufferedData()); 689 690 // The handshake message will call OnCanWrite, so the stream can 691 // resume writing. 692 EXPECT_CALL(*crypto_stream, OnCanWrite()); 693 // Now complete the crypto handshake, resulting in an increased flow control 694 // send window. 695 CryptoHandshakeMessage msg; 696 session_.GetCryptoStream()->OnHandshakeMessage(msg); 697 698 // Stream is now unblocked and will no longer have buffered data. 699 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); 700 } 701 702 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedHeadersStream) { 703 if (version() <= QUIC_VERSION_19) { 704 return; 705 } 706 // Test that if the header stream is flow control blocked, then if the SHLO 707 // contains a larger send window offset, the stream becomes unblocked. 708 session_.set_writev_consumes_all_data(true); 709 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 710 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); 711 QuicHeadersStream* headers_stream = 712 QuicSessionPeer::GetHeadersStream(&session_); 713 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 714 QuicStreamId stream_id = 5; 715 // Write until the header stream is flow control blocked. 716 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { 717 SpdyHeaderBlock headers; 718 headers["header"] = base::Uint64ToString(base::RandUint64()) + 719 base::Uint64ToString(base::RandUint64()) + 720 base::Uint64ToString(base::RandUint64()); 721 headers_stream->WriteHeaders(stream_id, headers, true, nullptr); 722 stream_id += 2; 723 } 724 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); 725 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); 726 EXPECT_FALSE(session_.HasDataToWrite()); 727 EXPECT_TRUE(headers_stream->HasBufferedData()); 728 729 // Now complete the crypto handshake, resulting in an increased flow control 730 // send window. 731 CryptoHandshakeMessage msg; 732 session_.GetCryptoStream()->OnHandshakeMessage(msg); 733 734 // Stream is now unblocked and will no longer have buffered data. 735 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 736 EXPECT_FALSE(headers_stream->HasBufferedData()); 737 } 738 739 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { 740 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. 741 // Test that receipt of an invalid (< default) flow control window from 742 // the peer results in the connection being torn down. 743 if (version() <= QUIC_VERSION_16 || version() > QUIC_VERSION_19) { 744 return; 745 } 746 747 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; 748 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), 749 kInvalidWindow); 750 751 EXPECT_CALL(*connection_, 752 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); 753 session_.OnConfigNegotiated(); 754 } 755 756 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { 757 // Test that receipt of an invalid (< default) stream flow control window from 758 // the peer results in the connection being torn down. 759 if (version() <= QUIC_VERSION_19) { 760 return; 761 } 762 763 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; 764 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), 765 kInvalidWindow); 766 767 EXPECT_CALL(*connection_, 768 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); 769 session_.OnConfigNegotiated(); 770 } 771 772 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { 773 // Test that receipt of an invalid (< default) session flow control window 774 // from the peer results in the connection being torn down. 775 if (version() <= QUIC_VERSION_19) { 776 return; 777 } 778 779 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; 780 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), 781 kInvalidWindow); 782 783 EXPECT_CALL(*connection_, 784 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); 785 session_.OnConfigNegotiated(); 786 } 787 788 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { 789 if (version() < QUIC_VERSION_19) { 790 return; 791 } 792 793 // Test that when we receive an out of order stream RST we correctly adjust 794 // our connection level flow control receive window. 795 // On close, the stream should mark as consumed all bytes between the highest 796 // byte consumed so far and the final byte offset from the RST frame. 797 TestStream* stream = session_.CreateOutgoingDataStream(); 798 799 const QuicStreamOffset kByteOffset = 800 1 + kInitialSessionFlowControlWindowForTest / 2; 801 802 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. 803 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); 804 // We do expect a connection level WINDOW_UPDATE when the stream is reset. 805 EXPECT_CALL(*connection_, 806 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + 807 kByteOffset)).Times(1); 808 809 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, 810 kByteOffset); 811 session_.OnRstStream(rst_frame); 812 session_.PostProcessAfterData(); 813 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); 814 } 815 816 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { 817 if (version() < QUIC_VERSION_19) { 818 return; 819 } 820 821 // Test the situation where we receive a FIN on a stream, and before we fully 822 // consume all the data from the sequencer buffer we locally RST the stream. 823 // The bytes between highest consumed byte, and the final byte offset that we 824 // determined when the FIN arrived, should be marked as consumed at the 825 // connection level flow controller when the stream is reset. 826 TestStream* stream = session_.CreateOutgoingDataStream(); 827 828 const QuicStreamOffset kByteOffset = 829 1 + kInitialSessionFlowControlWindowForTest / 2; 830 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); 831 vector<QuicStreamFrame> frames; 832 frames.push_back(frame); 833 session_.OnStreamFrames(frames); 834 session_.PostProcessAfterData(); 835 836 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); 837 EXPECT_EQ(kByteOffset, 838 stream->flow_controller()->highest_received_byte_offset()); 839 840 // We only expect to see a connection WINDOW_UPDATE when talking 841 // QUIC_VERSION_19, as in this case both stream and session flow control 842 // windows are the same size. In later versions we will not see a connection 843 // level WINDOW_UPDATE when exhausting a stream, as the stream flow control 844 // limit is much lower than the connection flow control limit. 845 if (version() == QUIC_VERSION_19) { 846 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. 847 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); 848 // We do expect a connection level WINDOW_UPDATE when the stream is reset. 849 EXPECT_CALL(*connection_, 850 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + 851 kByteOffset)).Times(1); 852 } 853 854 // Reset stream locally. 855 stream->Reset(QUIC_STREAM_CANCELLED); 856 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); 857 } 858 859 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { 860 // Test that when we RST the stream (and tear down stream state), and then 861 // receive a FIN from the peer, we correctly adjust our connection level flow 862 // control receive window. 863 if (version() < QUIC_VERSION_19) { 864 return; 865 } 866 867 // Connection starts with some non-zero highest received byte offset, 868 // due to other active streams. 869 const uint64 kInitialConnectionBytesConsumed = 567; 870 const uint64 kInitialConnectionHighestReceivedOffset = 1234; 871 EXPECT_LT(kInitialConnectionBytesConsumed, 872 kInitialConnectionHighestReceivedOffset); 873 session_.flow_controller()->UpdateHighestReceivedOffset( 874 kInitialConnectionHighestReceivedOffset); 875 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); 876 877 // Reset our stream: this results in the stream being closed locally. 878 TestStream* stream = session_.CreateOutgoingDataStream(); 879 stream->Reset(QUIC_STREAM_CANCELLED); 880 881 // Now receive a response from the peer with a FIN. We should handle this by 882 // adjusting the connection level flow control receive window to take into 883 // account the total number of bytes sent by the peer. 884 const QuicStreamOffset kByteOffset = 5678; 885 string body = "hello"; 886 IOVector data = MakeIOVector(body); 887 QuicStreamFrame frame(stream->id(), true, kByteOffset, data); 888 vector<QuicStreamFrame> frames; 889 frames.push_back(frame); 890 session_.OnStreamFrames(frames); 891 892 QuicStreamOffset total_stream_bytes_sent_by_peer = 893 kByteOffset + body.length(); 894 EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer, 895 session_.flow_controller()->bytes_consumed()); 896 EXPECT_EQ( 897 kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer, 898 session_.flow_controller()->highest_received_byte_offset()); 899 } 900 901 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) { 902 // Test that when we RST the stream (and tear down stream state), and then 903 // receive a RST from the peer, we correctly adjust our connection level flow 904 // control receive window. 905 if (version() < QUIC_VERSION_19) { 906 return; 907 } 908 909 // Connection starts with some non-zero highest received byte offset, 910 // due to other active streams. 911 const uint64 kInitialConnectionBytesConsumed = 567; 912 const uint64 kInitialConnectionHighestReceivedOffset = 1234; 913 EXPECT_LT(kInitialConnectionBytesConsumed, 914 kInitialConnectionHighestReceivedOffset); 915 session_.flow_controller()->UpdateHighestReceivedOffset( 916 kInitialConnectionHighestReceivedOffset); 917 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); 918 919 // Reset our stream: this results in the stream being closed locally. 920 TestStream* stream = session_.CreateOutgoingDataStream(); 921 stream->Reset(QUIC_STREAM_CANCELLED); 922 923 // Now receive a RST from the peer. We should handle this by adjusting the 924 // connection level flow control receive window to take into account the total 925 // number of bytes sent by the peer. 926 const QuicStreamOffset kByteOffset = 5678; 927 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, 928 kByteOffset); 929 session_.OnRstStream(rst_frame); 930 931 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, 932 session_.flow_controller()->bytes_consumed()); 933 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, 934 session_.flow_controller()->highest_received_byte_offset()); 935 } 936 937 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { 938 // Test that if we receive a stream RST with a highest byte offset that 939 // violates flow control, that we close the connection. 940 if (version() <= QUIC_VERSION_16) { 941 return; 942 } 943 944 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; 945 EXPECT_CALL(*connection_, 946 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) 947 .Times(2); 948 949 // Check that stream frame + FIN results in connection close. 950 TestStream* stream = session_.CreateOutgoingDataStream(); 951 stream->Reset(QUIC_STREAM_CANCELLED); 952 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); 953 vector<QuicStreamFrame> frames; 954 frames.push_back(frame); 955 session_.OnStreamFrames(frames); 956 957 // Check that RST results in connection close. 958 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, 959 kLargeOffset); 960 session_.OnRstStream(rst_frame); 961 } 962 963 TEST_P(QuicSessionTest, VersionNegotiationDisablesFlowControl) { 964 if (version() < QUIC_VERSION_19) { 965 return; 966 } 967 968 // Test that after successful version negotiation, flow control is disabled 969 // appropriately at both the connection and stream level. 970 971 // Initially both stream and connection flow control are enabled. 972 TestStream* stream = session_.CreateOutgoingDataStream(); 973 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); 974 EXPECT_TRUE(session_.flow_controller()->IsEnabled()); 975 976 // Version 18 implies that stream flow control is enabled, but connection 977 // level is disabled. 978 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_18); 979 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); 980 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); 981 982 // Version 16 means all flow control is disabled. 983 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16); 984 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); 985 EXPECT_FALSE(stream->flow_controller()->IsEnabled()); 986 } 987 988 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) { 989 // Test that a flow control blocked headers stream gets unblocked on recipt of 990 // a WINDOW_UPDATE frame. Regression test for b/17413860. 991 if (version() < QUIC_VERSION_21) { 992 return; 993 } 994 995 // Set the headers stream to be flow control blocked. 996 QuicHeadersStream* headers_stream = 997 QuicSessionPeer::GetHeadersStream(&session_); 998 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), 999 0); 1000 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); 1001 1002 // Unblock the headers stream by supplying a WINDOW_UPDATE. 1003 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), 1004 2 * kDefaultFlowControlSendWindow); 1005 vector<QuicWindowUpdateFrame> frames; 1006 frames.push_back(window_update_frame); 1007 session_.OnWindowUpdateFrames(frames); 1008 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 1009 } 1010 1011 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { 1012 if (version() < QUIC_VERSION_18) { 1013 return; 1014 } 1015 // If a buggy/malicious peer creates too many streams that are not ended with 1016 // a FIN or RST then we send a connection close. 1017 ValueRestore<bool> old_flag(&FLAGS_close_quic_connection_unfinished_streams_2, 1018 true); 1019 1020 EXPECT_CALL(*connection_, 1021 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1); 1022 1023 const int kMaxStreams = 5; 1024 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); 1025 1026 // Create kMaxStreams + 1 data streams, and close them all without receiving a 1027 // FIN or a RST from the client. 1028 const int kFirstStreamId = kClientDataStreamId1; 1029 const int kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams + 1; 1030 for (int i = kFirstStreamId; i < kFinalStreamId; i += 2) { 1031 QuicStreamFrame data1(i, false, 0, MakeIOVector("HT")); 1032 vector<QuicStreamFrame> frames; 1033 frames.push_back(data1); 1034 session_.OnStreamFrames(frames); 1035 EXPECT_EQ(1u, session_.GetNumOpenStreams()); 1036 session_.CloseStream(i); 1037 } 1038 1039 // Called after any new data is received by the session, and triggers the call 1040 // to close the connection. 1041 session_.PostProcessAfterData(); 1042 } 1043 1044 } // namespace 1045 } // namespace test 1046 } // namespace net 1047