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

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: Adding NET_EXPORT_PRIVATE to DelegateInterface. Created 5 years 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)
174 ->UpdateBytesForStream(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,
452 stream2->id(), 6000))),
453 Invoke(&stream2_blocker,
454 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
455 EXPECT_CALL(*stream2, OnCanWrite())
456 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
457 &session_, &TestSession::SendLargeFakeData,
458 stream2->id(), 6000))),
459 Invoke(&stream2_blocker,
460 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
461 session_.OnCanWrite();
462
463 // We should get one more call for stream2, at which point it has used its
464 // write quota and we move over to stream 4.
465 EXPECT_CALL(*stream2, OnCanWrite())
466 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
467 &session_, &TestSession::SendLargeFakeData,
468 stream2->id(), 6000))),
469 Invoke(&stream2_blocker,
470 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
471 EXPECT_CALL(*stream4, OnCanWrite())
472 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
473 &session_, &TestSession::SendLargeFakeData,
474 stream4->id(), 6000))),
475 Invoke(&stream4_blocker,
476 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
477 session_.OnCanWrite();
478
479 // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
480 // priority stream 6. 4 should be preempted. 6 will write but *not* block so
481 // will cede back to 4.
482 stream6->set_priority(kHighestPriority);
483 EXPECT_CALL(*stream4, OnCanWrite())
484 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
485 &session_, &TestSession::SendLargeFakeData,
486 stream4->id(), 6000))),
487 Invoke(&stream4_blocker,
488 &StreamBlocker::MarkConnectionLevelWriteBlocked),
489 Invoke(&stream6_blocker,
490 &StreamBlocker::MarkHighPriorityWriteBlocked)));
491 EXPECT_CALL(*stream6, OnCanWrite())
492 .WillOnce(testing::IgnoreResult(Invoke(CreateFunctor(
493 &session_, &TestSession::SendLargeFakeData, stream4->id(), 6000))));
494 session_.OnCanWrite();
495
496 // Stream4 alread did 6k worth of writes, so after doing another 12k it should
497 // cede and 2 should resume.
498 EXPECT_CALL(*stream4, OnCanWrite())
499 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
500 &session_, &TestSession::SendLargeFakeData,
501 stream4->id(), 12000))),
502 Invoke(&stream4_blocker,
503 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
504 EXPECT_CALL(*stream2, OnCanWrite())
505 .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
506 &session_, &TestSession::SendLargeFakeData,
507 stream2->id(), 6000))),
508 Invoke(&stream2_blocker,
509 &StreamBlocker::MarkConnectionLevelWriteBlocked)));
510 session_.OnCanWrite();
511 }
512
403 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { 513 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
404 // Drive congestion control manually. 514 // Drive congestion control manually.
405 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; 515 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
406 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); 516 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
407 517
408 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); 518 TestStream* stream2 = session_.CreateOutgoingDynamicStream();
409 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); 519 TestStream* stream4 = session_.CreateOutgoingDynamicStream();
410 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); 520 TestStream* stream6 = session_.CreateOutgoingDynamicStream();
411 521
412 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority); 522 session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 InSequence s; 619 InSequence s;
510 // Force most streams to re-register, which is common scenario when we block 620 // 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. 621 // the Crypto stream, and only the crypto stream can "really" write.
512 622
513 // Due to prioritization, we *should* be asked to write the crypto stream 623 // Due to prioritization, we *should* be asked to write the crypto stream
514 // first. 624 // first.
515 // Don't re-register the crypto stream (which signals complete writing). 625 // Don't re-register the crypto stream (which signals complete writing).
516 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); 626 TestCryptoStream* crypto_stream = session_.GetCryptoStream();
517 EXPECT_CALL(*crypto_stream, OnCanWrite()); 627 EXPECT_CALL(*crypto_stream, OnCanWrite());
518 628
519 // Re-register all other streams, to show they weren't able to proceed. 629 EXPECT_CALL(*stream2, OnCanWrite());
520 EXPECT_CALL(*stream2, OnCanWrite()) 630 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()) 631 EXPECT_CALL(*stream4, OnCanWrite())
527 .WillOnce(Invoke(&stream4_blocker, 632 .WillOnce(Invoke(&stream4_blocker,
528 &StreamBlocker::MarkConnectionLevelWriteBlocked)); 633 &StreamBlocker::MarkConnectionLevelWriteBlocked));
529 634
530 session_.OnCanWrite(); 635 session_.OnCanWrite();
531 EXPECT_TRUE(session_.WillingAndAbleToWrite()); 636 EXPECT_TRUE(session_.WillingAndAbleToWrite());
532 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. 637 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
533 } 638 }
534 639
535 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) { 640 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 1067
963 // Unblock the headers stream by supplying a WINDOW_UPDATE. 1068 // Unblock the headers stream by supplying a WINDOW_UPDATE.
964 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), 1069 QuicWindowUpdateFrame window_update_frame(headers_stream->id(),
965 2 * kMinimumFlowControlSendWindow); 1070 2 * kMinimumFlowControlSendWindow);
966 session_.OnWindowUpdateFrame(window_update_frame); 1071 session_.OnWindowUpdateFrame(window_update_frame);
967 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); 1072 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
968 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); 1073 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
969 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); 1074 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
970 } 1075 }
971 1076
972 TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseConnectionClose) {
973 FLAGS_quic_count_unfinished_as_open_streams = false;
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) { 1077 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 1078 // 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 1079 // with a FIN or RST then we send a connection close or an RST to
1004 // refuse streams. 1080 // refuse streams.
1005 const QuicStreamId kMaxStreams = 5; 1081 const QuicStreamId kMaxStreams = 5;
1006 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); 1082 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
1007 const QuicStreamId kFirstStreamId = kClientDataStreamId1; 1083 const QuicStreamId kFirstStreamId = kClientDataStreamId1;
1008 const QuicStreamId kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams; 1084 const QuicStreamId kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams;
1009 1085
1010 // Create kMaxStreams data streams, and close them all without receiving a 1086 // Create kMaxStreams data streams, and close them all without receiving a
1011 // FIN or a RST_STREAM from the client. 1087 // FIN or a RST_STREAM from the client.
(...skipping 19 matching lines...) Expand all
1031 1107
1032 // Called after any new data is received by the session, and triggers the 1108 // Called after any new data is received by the session, and triggers the
1033 // call to close the connection. 1109 // call to close the connection.
1034 session_.PostProcessAfterData(); 1110 session_.PostProcessAfterData();
1035 } 1111 }
1036 1112
1037 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) { 1113 TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
1038 // Verify that a draining stream (which has received a FIN but not consumed 1114 // 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 1115 // it) does not count against the open quota (because it is closed from the
1040 // protocol point of view). 1116 // protocol point of view).
1041 if (FLAGS_quic_count_unfinished_as_open_streams) { 1117 if (GetParam() <= QUIC_VERSION_27) {
1042 if (GetParam() <= QUIC_VERSION_27) { 1118 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS))
1043 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)) 1119 .Times(0);
1044 .Times(0);
1045 } else {
1046 EXPECT_CALL(*connection_, SendRstStream(_, QUIC_REFUSED_STREAM, _))
1047 .Times(0);
1048 }
1049 } else { 1120 } else {
1050 EXPECT_CALL(*connection_, 1121 EXPECT_CALL(*connection_, SendRstStream(_, QUIC_REFUSED_STREAM, _))
1051 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS))
1052 .Times(0); 1122 .Times(0);
1053 } 1123 }
1054
1055 const QuicStreamId kMaxStreams = 5; 1124 const QuicStreamId kMaxStreams = 5;
1056 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); 1125 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
1057 1126
1058 // Create kMaxStreams + 1 data streams, and mark them draining. 1127 // Create kMaxStreams + 1 data streams, and mark them draining.
1059 const QuicStreamId kFirstStreamId = kClientDataStreamId1; 1128 const QuicStreamId kFirstStreamId = kClientDataStreamId1;
1060 const QuicStreamId kFinalStreamId = 1129 const QuicStreamId kFinalStreamId =
1061 kClientDataStreamId1 + 2 * kMaxStreams + 1; 1130 kClientDataStreamId1 + 2 * kMaxStreams + 1;
1062 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) { 1131 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
1063 QuicStreamFrame data1(i, true, 0, StringPiece("HT")); 1132 QuicStreamFrame data1(i, true, 0, StringPiece("HT"));
1064 session_.OnStreamFrame(data1); 1133 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 1192 // Verify that there is no entry for the stream in
1124 // locally_closed_streams_highest_offset_. 1193 // locally_closed_streams_highest_offset_.
1125 EXPECT_EQ( 1194 EXPECT_EQ(
1126 FLAGS_quic_fix_fin_accounting ? 0u : 1u, 1195 FLAGS_quic_fix_fin_accounting ? 0u : 1u,
1127 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size()); 1196 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
1128 } 1197 }
1129 1198
1130 } // namespace 1199 } // namespace
1131 } // namespace test 1200 } // namespace test
1132 } // namespace net 1201 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698