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