Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: net/quic/quic_session_test.cc

Issue 1470713003: Landing Recent QUIC changes until and including Mon Nov 16 14:15:48 2015 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review feedback fixes in quic_connection.cc, quic_connection_test.cc and quic_server_bin.cc. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_session.h" 5 #include "net/quic/quic_session.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 18 matching lines...) Expand all
29 #include "net/test/gtest_util.h" 29 #include "net/test/gtest_util.h"
30 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gmock_mutant.h" 31 #include "testing/gmock_mutant.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 33
34 using base::hash_map; 34 using base::hash_map;
35 using std::set; 35 using std::set;
36 using std::string; 36 using std::string;
37 using std::vector; 37 using std::vector;
38 using testing::CreateFunctor; 38 using testing::CreateFunctor;
39 using net::SpdyPriority;
39 using testing::InSequence; 40 using testing::InSequence;
40 using testing::Invoke; 41 using testing::Invoke;
41 using testing::Return; 42 using testing::Return;
42 using testing::StrictMock; 43 using testing::StrictMock;
43 using testing::_; 44 using testing::_;
44 45
45 namespace net { 46 namespace net {
46 namespace test { 47 namespace test {
47 namespace { 48 namespace {
48 49
49 const QuicPriority kHighestPriority = 0; 50 const SpdyPriority kHighestPriority = 0;
50 const QuicPriority kSomeMiddlePriority = 3; 51 const SpdyPriority kSomeMiddlePriority = 3;
51 52
52 class TestCryptoStream : public QuicCryptoStream { 53 class TestCryptoStream : public QuicCryptoStream {
53 public: 54 public:
54 explicit TestCryptoStream(QuicSession* session) 55 explicit TestCryptoStream(QuicSession* session)
55 : QuicCryptoStream(session) { 56 : QuicCryptoStream(session) {
56 } 57 }
57 58
58 void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override { 59 void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
59 encryption_established_ = true; 60 encryption_established_ = true;
60 handshake_confirmed_ = true; 61 handshake_confirmed_ = true;
(...skipping 28 matching lines...) Expand all
89 : QuicSpdyStream(id, session) {} 90 : QuicSpdyStream(id, session) {}
90 91
91 using ReliableQuicStream::CloseWriteSide; 92 using ReliableQuicStream::CloseWriteSide;
92 93
93 void OnDataAvailable() override {} 94 void OnDataAvailable() override {}
94 95
95 void SendBody(const string& data, bool fin) { 96 void SendBody(const string& data, bool fin) {
96 WriteOrBufferData(data, fin, nullptr); 97 WriteOrBufferData(data, fin, nullptr);
97 } 98 }
98 99
100 using QuicSpdyStream::set_priority;
101
99 MOCK_METHOD0(OnCanWrite, void()); 102 MOCK_METHOD0(OnCanWrite, void());
100 }; 103 };
101 104
102 // Poor man's functor for use as callback in a mock. 105 // Poor man's functor for use as callback in a mock.
103 class StreamBlocker { 106 class StreamBlocker {
104 public: 107 public:
105 StreamBlocker(QuicSession* session, QuicStreamId stream_id) 108 StreamBlocker(QuicSession* session, QuicStreamId stream_id)
106 : session_(session), 109 : session_(session),
107 stream_id_(stream_id) { 110 stream_id_(stream_id) {
108 } 111 }
109 112
110 void MarkConnectionLevelWriteBlocked() { 113 void MarkConnectionLevelWriteBlocked() {
111 session_->MarkConnectionLevelWriteBlocked(stream_id_, kSomeMiddlePriority); 114 session_->MarkConnectionLevelWriteBlocked(stream_id_, kSomeMiddlePriority);
112 } 115 }
113 116
117 void MarkHighPriorityWriteBlocked() {
118 session_->MarkConnectionLevelWriteBlocked(stream_id_, kHighestPriority);
119 }
120
114 private: 121 private:
115 QuicSession* const session_; 122 QuicSession* const session_;
116 const QuicStreamId stream_id_; 123 const QuicStreamId stream_id_;
117 }; 124 };
118 125
119 class TestSession : public QuicSpdySession { 126 class TestSession : public QuicSpdySession {
120 public: 127 public:
121 explicit TestSession(QuicConnection* connection) 128 explicit TestSession(QuicConnection* connection)
122 : QuicSpdySession(connection, DefaultQuicConfig()), 129 : QuicSpdySession(connection, DefaultQuicConfig()),
123 crypto_stream_(this), 130 crypto_stream_(this),
(...skipping 27 matching lines...) Expand all
151 return QuicSpdySession::GetOrCreateDynamicStream(stream_id); 158 return QuicSpdySession::GetOrCreateDynamicStream(stream_id);
152 } 159 }
153 160
154 QuicConsumedData WritevData( 161 QuicConsumedData WritevData(
155 QuicStreamId id, 162 QuicStreamId id,
156 QuicIOVector data, 163 QuicIOVector data,
157 QuicStreamOffset offset, 164 QuicStreamOffset offset,
158 bool fin, 165 bool fin,
159 FecProtection fec_protection, 166 FecProtection fec_protection,
160 QuicAckListenerInterface* ack_notifier_delegate) override { 167 QuicAckListenerInterface* ack_notifier_delegate) override {
161 // Always consumes everything. 168 QuicConsumedData consumed(data.total_length, fin);
162 if (writev_consumes_all_data_) { 169 if (!writev_consumes_all_data_) {
163 return QuicConsumedData(data.total_length, fin); 170 consumed = QuicSession::WritevData(id, data, offset, fin, fec_protection,
164 } else { 171 ack_notifier_delegate);
165 return QuicSession::WritevData(id, data, offset, fin, fec_protection,
166 ack_notifier_delegate);
167 } 172 }
173 QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
174 id, consumed.bytes_consumed);
175 return consumed;
168 } 176 }
169 177
170 void set_writev_consumes_all_data(bool val) { 178 void set_writev_consumes_all_data(bool val) {
171 writev_consumes_all_data_ = val; 179 writev_consumes_all_data_ = val;
172 } 180 }
173 181
174 QuicConsumedData SendStreamData(QuicStreamId id) { 182 QuicConsumedData SendStreamData(QuicStreamId id) {
175 struct iovec iov; 183 struct iovec iov;
176 return WritevData(id, MakeIOVector("not empty", &iov), 0, true, 184 return WritevData(id, MakeIOVector("not empty", &iov), 0, true,
177 MAY_FEC_PROTECT, nullptr); 185 MAY_FEC_PROTECT, nullptr);
178 } 186 }
179 187
188 QuicConsumedData SendLargeFakeData(QuicStreamId id, int bytes) {
189 DCHECK(writev_consumes_all_data_);
190 struct iovec iov;
191 iov.iov_base = nullptr; // should not be read.
192 iov.iov_len = static_cast<size_t>(bytes);
193 return WritevData(id, QuicIOVector(&iov, 1, bytes), 0, true,
194 MAY_FEC_PROTECT, nullptr);
195 }
196
180 using QuicSession::PostProcessAfterData; 197 using QuicSession::PostProcessAfterData;
181 198
182 private: 199 private:
183 StrictMock<TestCryptoStream> crypto_stream_; 200 StrictMock<TestCryptoStream> crypto_stream_;
184 201
185 bool writev_consumes_all_data_; 202 bool writev_consumes_all_data_;
186 }; 203 };
187 204
188 class QuicSessionTestBase : public ::testing::TestWithParam<QuicVersion> { 205 class QuicSessionTestBase : public ::testing::TestWithParam<QuicVersion> {
189 protected: 206 protected:
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // Close the stream. 380 // Close the stream.
364 EXPECT_CALL(*connection_, SendRstStream(closed_stream_id, _, _)); 381 EXPECT_CALL(*connection_, SendRstStream(closed_stream_id, _, _));
365 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD); 382 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
366 EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked( 383 EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked(
367 closed_stream_id, kSomeMiddlePriority), 384 closed_stream_id, kSomeMiddlePriority),
368 "Marking unknown stream 2 blocked."); 385 "Marking unknown stream 2 blocked.");
369 } 386 }
370 387
371 TEST_P(QuicSessionTestServer, 388 TEST_P(QuicSessionTestServer,
372 DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { 389 DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) {
373 const QuicPriority kDifferentPriority = 0; 390 const SpdyPriority kDifferentPriority = 0;
374 391
375 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); 392 TestStream* stream2 = session_.CreateOutgoingDynamicStream();
376 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); 393 EXPECT_NE(kDifferentPriority, stream2->Priority());
377 EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked( 394 EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked(
378 stream2->id(), kDifferentPriority), 395 stream2->id(), kDifferentPriority),
379 "Priorities do not match. Got: 0 Expected: 3"); 396 "Priorities do not match. Got: 0 Expected: 3");
380 } 397 }
381 398
382 TEST_P(QuicSessionTestServer, OnCanWrite) { 399 TEST_P(QuicSessionTestServer, OnCanWrite) {
383 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); 400 TestStream* stream2 = session_.CreateOutgoingDynamicStream();
384 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); 401 TestStream* stream4 = session_.CreateOutgoingDynamicStream();
385 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); 402 TestStream* stream6 = session_.CreateOutgoingDynamicStream();
386 403
387 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority); 404 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
388 session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority); 405 session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority);
389 session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority); 406 session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
390 407
391 InSequence s; 408 InSequence s;
392 StreamBlocker stream2_blocker(&session_, stream2->id()); 409 StreamBlocker stream2_blocker(&session_, stream2->id());
393 // Reregister, to test the loop limit. 410
394 EXPECT_CALL(*stream2, OnCanWrite()) 411 if (FLAGS_quic_batch_writes) {
395 .WillOnce(Invoke(&stream2_blocker, 412 // Reregister, to test the loop limit.
396 &StreamBlocker::MarkConnectionLevelWriteBlocked)); 413 EXPECT_CALL(*stream2, OnCanWrite())
397 EXPECT_CALL(*stream6, OnCanWrite()); 414 .WillOnce(Invoke(&stream2_blocker,
398 EXPECT_CALL(*stream4, OnCanWrite()); 415 &StreamBlocker::MarkConnectionLevelWriteBlocked));
416 // 2 will get called a second time as it didn't finish its block
417 EXPECT_CALL(*stream2, OnCanWrite());
418 EXPECT_CALL(*stream6, OnCanWrite());
419 // 4 will not get called, as we exceeded the loop limit.
420 } else {
421 // Reregister, to test the loop limit.
422 EXPECT_CALL(*stream2, OnCanWrite())
423 .WillOnce(Invoke(&stream2_blocker,
424 &StreamBlocker::MarkConnectionLevelWriteBlocked));
425 EXPECT_CALL(*stream6, OnCanWrite());
426 EXPECT_CALL(*stream4, OnCanWrite());
427 }
399 session_.OnCanWrite(); 428 session_.OnCanWrite();
400 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 429 EXPECT_TRUE(session_.WillingAndAbleToWrite());
401 } 430 }
402 431
432 TEST_P(QuicSessionTestServer, TestBatchedWrites) {
433 FLAGS_quic_batch_writes = true;
434 TestStream* stream2 = session_.CreateOutgoingDynamicStream();
435 TestStream* stream4 = session_.CreateOutgoingDynamicStream();
436 TestStream* stream6 = session_.CreateOutgoingDynamicStream();
437
438 session_.set_writev_consumes_all_data(true);
439 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
440 session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
441
442 StreamBlocker stream2_blocker(&session_, stream2->id());
443 StreamBlocker stream4_blocker(&session_, stream4->id());
444 StreamBlocker stream6_blocker(&session_, stream6->id());
445 // With two sessions blocked, we should get two write calls. They should both
446 // go to the first stream as it will only write 6k and mark itself blocked
447 // again.
448 InSequence s;
449 EXPECT_CALL(*stream2, OnCanWrite())
450 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
451 &session_, &TestSession::SendLargeFakeData, stream2->id(), 6000))),
452 Invoke(&stream2_blocker,
453 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
454 EXPECT_CALL(*stream2, OnCanWrite())
455 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
456 &session_, &TestSession::SendLargeFakeData, stream2->id(), 6000))),
457 Invoke(&stream2_blocker,
458 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
459 session_.OnCanWrite();
460
461 // We should get one more call for stream2, at which point it has used its
462 // write quota and we move over to stream 4.
463 EXPECT_CALL(*stream2, OnCanWrite())
464 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
465 &session_, &TestSession::SendLargeFakeData, stream2->id(), 6000))),
466 Invoke(&stream2_blocker,
467 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
468 EXPECT_CALL(*stream4, OnCanWrite())
469 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
470 &session_, &TestSession::SendLargeFakeData, stream4->id(), 6000))),
471 Invoke(&stream4_blocker,
472 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
473 session_.OnCanWrite();
474
475 // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
476 // priority stream 6. 4 should be preempted. 6 will write but *not* block so
477 // will cede back to 4.
478 stream6->set_priority(kHighestPriority);
479 EXPECT_CALL(*stream4, OnCanWrite())
480 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
481 &session_, &TestSession::SendLargeFakeData, stream4->id(), 6000))),
482 Invoke(&stream4_blocker,
483 &StreamBlocker::MarkConnectionLevelWriteBlocked),
484 Invoke(&stream6_blocker,
485 &StreamBlocker::MarkHighPriorityWriteBlocked)));
486 EXPECT_CALL(*stream6, OnCanWrite())
487 .WillOnce(testing::IgnoreResult(Invoke(CreateFunctor(
488 &session_, &TestSession::SendLargeFakeData, stream4->id(), 6000))));
489 session_.OnCanWrite();
490
491 // Stream4 alread did 6k worth of writes, so after doing another 12k it should
492 // cede and 2 should resume.
493 EXPECT_CALL(*stream4, OnCanWrite())
494 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
495 &session_, &TestSession::SendLargeFakeData, stream4->id(), 12000))),
496 Invoke(&stream4_blocker,
497 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
498 EXPECT_CALL(*stream2, OnCanWrite())
499 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
500 &session_, &TestSession::SendLargeFakeData, stream2->id(), 6000))),
501 Invoke(&stream2_blocker,
502 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
503 session_.OnCanWrite();
504 }
505
403 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { 506 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
404 // Drive congestion control manually. 507 // Drive congestion control manually.
405 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; 508 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
406 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); 509 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
407 510
408 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); 511 TestStream* stream2 = session_.CreateOutgoingDynamicStream();
409 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); 512 TestStream* stream4 = session_.CreateOutgoingDynamicStream();
410 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); 513 TestStream* stream6 = session_.CreateOutgoingDynamicStream();
411 514
412 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority); 515 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 InSequence s; 612 InSequence s;
510 // Force most streams to re-register, which is common scenario when we block 613 // Force most streams to re-register, which is common scenario when we block
511 // the Crypto stream, and only the crypto stream can "really" write. 614 // the Crypto stream, and only the crypto stream can "really" write.
512 615
513 // Due to prioritization, we *should* be asked to write the crypto stream 616 // Due to prioritization, we *should* be asked to write the crypto stream
514 // first. 617 // first.
515 // Don't re-register the crypto stream (which signals complete writing). 618 // Don't re-register the crypto stream (which signals complete writing).
516 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 619 TestCryptoStream* crypto_stream = session_.GetCryptoStream();
517 EXPECT_CALL(*crypto_stream, OnCanWrite()); 620 EXPECT_CALL(*crypto_stream, OnCanWrite());
518 621
519 // Re-register all other streams, to show they weren't able to proceed. 622 EXPECT_CALL(*stream2, OnCanWrite());
520 EXPECT_CALL(*stream2, OnCanWrite()) 623 EXPECT_CALL(*stream3, OnCanWrite());
521 .WillOnce(Invoke(&stream2_blocker,
522 &StreamBlocker::MarkConnectionLevelWriteBlocked));
523 EXPECT_CALL(*stream3, OnCanWrite())
524 .WillOnce(Invoke(&stream3_blocker,
525 &StreamBlocker::MarkConnectionLevelWriteBlocked));
526 EXPECT_CALL(*stream4, OnCanWrite()) 624 EXPECT_CALL(*stream4, OnCanWrite())
527 .WillOnce(Invoke(&stream4_blocker, 625 .WillOnce(Invoke(&stream4_blocker,
528 &StreamBlocker::MarkConnectionLevelWriteBlocked)); 626 &StreamBlocker::MarkConnectionLevelWriteBlocked));
529 627
530 session_.OnCanWrite(); 628 session_.OnCanWrite();
531 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 629 EXPECT_TRUE(session_.WillingAndAbleToWrite());
532 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. 630 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
533 } 631 }
534 632
535 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) { 633 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 1060
963 // Unblock the headers stream by supplying a WINDOW_UPDATE. 1061 // Unblock the headers stream by supplying a WINDOW_UPDATE.
964 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), 1062 QuicWindowUpdateFrame window_update_frame(headers_stream->id(),
965 2 * kMinimumFlowControlSendWindow); 1063 2 * kMinimumFlowControlSendWindow);
966 session_.OnWindowUpdateFrame(window_update_frame); 1064 session_.OnWindowUpdateFrame(window_update_frame);
967 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 1065 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
968 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); 1066 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
969 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); 1067 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
970 } 1068 }
971 1069
972 TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseConnectionClose) { 1070 TEST_P(QuicSessionTestServer,
973 FLAGS_quic_count_unfinished_as_open_streams = false; 1071 TooManyUnfinishedStreamsCauseServerRejectStream) {
974 // If a buggy/malicious peer creates too many streams that are not ended
975 // with a FIN or RST then we send a connection close.
976 EXPECT_CALL(*connection_,
977 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS));
978
979 const QuicStreamId kMaxStreams = 5;
980 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
981
982 // Create kMaxStreams + 1 data streams, and close them all without receiving
983 // a FIN or a RST_STREAM from the client.
984 const QuicStreamId kFirstStreamId = kClientDataStreamId1;
985 const QuicStreamId kFinalStreamId =
986 kClientDataStreamId1 + 2 * kMaxStreams + 1;
987 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
988 QuicStreamFrame data1(i, false, 0, StringPiece("HT"));
989 session_.OnStreamFrame(data1);
990 EXPECT_EQ(1u, session_.GetNumOpenStreams());
991 EXPECT_CALL(*connection_, SendRstStream(i, _, _));
992 session_.CloseStream(i);
993 }
994
995 // Called after any new data is received by the session, and triggers the
996 // call to close the connection.
997 session_.PostProcessAfterData();
998 }
999
1000 TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
1001 FLAGS_quic_count_unfinished_as_open_streams = true;
1002 // If a buggy/malicious peer creates too many streams that are not ended 1072 // If a buggy/malicious peer creates too many streams that are not ended
1003 // with a FIN or RST then we send a connection close or an RST to 1073 // with a FIN or RST then we send a connection close or an RST to
1004 // refuse streams. 1074 // refuse streams.
1005 const QuicStreamId kMaxStreams = 5; 1075 const QuicStreamId kMaxStreams = 5;
1006 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); 1076 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
1007 const QuicStreamId kFirstStreamId = kClientDataStreamId1; 1077 const QuicStreamId kFirstStreamId = kClientDataStreamId1;
1008 const QuicStreamId kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams; 1078 const QuicStreamId kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams;
1009 1079
1010 // Create kMaxStreams data streams, and close them all without receiving a 1080 // Create kMaxStreams data streams, and close them all without receiving a
1011 // FIN or a RST_STREAM from the client. 1081 // FIN or a RST_STREAM from the client.
(...skipping 19 matching lines...) Expand all
1031 1101
1032 // Called after any new data is received by the session, and triggers the 1102 // Called after any new data is received by the session, and triggers the
1033 // call to close the connection. 1103 // call to close the connection.
1034 session_.PostProcessAfterData(); 1104 session_.PostProcessAfterData();
1035 } 1105 }
1036 1106
1037 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) { 1107 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
1038 // Verify that a draining stream (which has received a FIN but not consumed 1108 // Verify that a draining stream (which has received a FIN but not consumed
1039 // it) does not count against the open quota (because it is closed from the 1109 // it) does not count against the open quota (because it is closed from the
1040 // protocol point of view). 1110 // protocol point of view).
1041 if (FLAGS_quic_count_unfinished_as_open_streams) { 1111 if (GetParam() <= QUIC_VERSION_27) {
1042 if (GetParam() <= QUIC_VERSION_27) { 1112 EXPECT_CALL(*connection_,
1043 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)) 1113 SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)).Times(0);
1044 .Times(0);
1045 } else {
1046 EXPECT_CALL(*connection_, SendRstStream(_, QUIC_REFUSED_STREAM, _))
1047 .Times(0);
1048 }
1049 } else { 1114 } else {
1050 EXPECT_CALL(*connection_, 1115 EXPECT_CALL(*connection_,
1051 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)) 1116 SendRstStream(_, QUIC_REFUSED_STREAM, _)).Times(0);
1052 .Times(0);
1053 } 1117 }
1054
1055 const QuicStreamId kMaxStreams = 5; 1118 const QuicStreamId kMaxStreams = 5;
1056 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); 1119 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
1057 1120
1058 // Create kMaxStreams + 1 data streams, and mark them draining. 1121 // Create kMaxStreams + 1 data streams, and mark them draining.
1059 const QuicStreamId kFirstStreamId = kClientDataStreamId1; 1122 const QuicStreamId kFirstStreamId = kClientDataStreamId1;
1060 const QuicStreamId kFinalStreamId = 1123 const QuicStreamId kFinalStreamId =
1061 kClientDataStreamId1 + 2 * kMaxStreams + 1; 1124 kClientDataStreamId1 + 2 * kMaxStreams + 1;
1062 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) { 1125 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
1063 QuicStreamFrame data1(i, true, 0, StringPiece("HT")); 1126 QuicStreamFrame data1(i, true, 0, StringPiece("HT"));
1064 session_.OnStreamFrame(data1); 1127 session_.OnStreamFrame(data1);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 // Verify that there is no entry for the stream in 1186 // Verify that there is no entry for the stream in
1124 // locally_closed_streams_highest_offset_. 1187 // locally_closed_streams_highest_offset_.
1125 EXPECT_EQ( 1188 EXPECT_EQ(
1126 FLAGS_quic_fix_fin_accounting ? 0u : 1u, 1189 FLAGS_quic_fix_fin_accounting ? 0u : 1u,
1127 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size()); 1190 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
1128 } 1191 }
1129 1192
1130 } // namespace 1193 } // namespace
1131 } // namespace test 1194 } // namespace test
1132 } // namespace net 1195 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698