blob: 8f418c01888a93bdc0b8ed30f11845909b41f645 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_session.h"
6
7#include <cstdint>
8#include <set>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include <utility>
11
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
13#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
14#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
15#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
16#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
17#include "net/third_party/quiche/src/quic/core/quic_packets.h"
18#include "net/third_party/quiche/src/quic/core/quic_stream.h"
19#include "net/third_party/quiche/src/quic/core/quic_utils.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
22#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h"
25#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
30#include "net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h"
31#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
32#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
33#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
34#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
35#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
36#include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h"
37#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
38
39using spdy::kV3HighestPriority;
40using spdy::SpdyPriority;
41using testing::_;
42using testing::AtLeast;
43using testing::InSequence;
44using testing::Invoke;
45using testing::NiceMock;
46using testing::Return;
47using testing::StrictMock;
48using testing::WithArg;
49
50namespace quic {
51namespace test {
52namespace {
53
54class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
55 public:
56 explicit TestCryptoStream(QuicSession* session)
57 : QuicCryptoStream(session),
58 QuicCryptoHandshaker(this, session),
59 encryption_established_(false),
60 handshake_confirmed_(false),
61 params_(new QuicCryptoNegotiatedParameters) {}
62
63 void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
64 encryption_established_ = true;
65 handshake_confirmed_ = true;
66 CryptoHandshakeMessage msg;
vasilvvc48c8712019-03-11 13:38:16 -070067 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -050068 session()->config()->SetInitialStreamFlowControlWindowToSend(
69 kInitialStreamFlowControlWindowForTest);
70 session()->config()->SetInitialSessionFlowControlWindowToSend(
71 kInitialSessionFlowControlWindowForTest);
72 session()->config()->ToHandshakeMessage(&msg);
73 const QuicErrorCode error =
74 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
75 EXPECT_EQ(QUIC_NO_ERROR, error);
76 session()->OnConfigNegotiated();
77 session()->connection()->SetDefaultEncryptionLevel(
78 ENCRYPTION_FORWARD_SECURE);
79 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
80 }
81
82 // QuicCryptoStream implementation
83 bool encryption_established() const override {
84 return encryption_established_;
85 }
86 bool handshake_confirmed() const override { return handshake_confirmed_; }
87 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
88 const override {
89 return *params_;
90 }
91 CryptoMessageParser* crypto_message_parser() override {
92 return QuicCryptoHandshaker::crypto_message_parser();
93 }
94
95 MOCK_METHOD0(OnCanWrite, void());
96 bool HasPendingCryptoRetransmission() override { return false; }
97
98 MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
99
100 private:
101 using QuicCryptoStream::session;
102
103 bool encryption_established_;
104 bool handshake_confirmed_;
105 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
106};
107
108class TestStream : public QuicStream {
109 public:
110 TestStream(QuicStreamId id, QuicSession* session, StreamType type)
111 : QuicStream(id, session, /*is_static=*/false, type) {}
112
113 TestStream(PendingStream pending, StreamType type)
renjietang35448992019-05-08 17:08:57 -0700114 : QuicStream(std::move(pending), type, /*is_static=*/false) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115
116 using QuicStream::CloseReadSide;
117 using QuicStream::CloseWriteSide;
118 using QuicStream::WriteMemSlices;
119 using QuicStream::WritevData;
120
121 void OnDataAvailable() override {}
122
123 MOCK_METHOD0(OnCanWrite, void());
124 MOCK_METHOD3(RetransmitStreamData,
125 bool(QuicStreamOffset, QuicByteCount, bool));
126
127 MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
128 MOCK_METHOD1(OnStopSending, void(uint16_t code));
129};
130
131class TestSession : public QuicSession {
132 public:
133 explicit TestSession(QuicConnection* connection,
134 MockQuicSessionVisitor* session_visitor)
135 : QuicSession(connection,
136 session_visitor,
137 DefaultQuicConfig(),
138 CurrentSupportedVersions()),
139 crypto_stream_(this),
140 writev_consumes_all_data_(false),
renjietange76b2da2019-05-13 14:50:23 -0700141 uses_pending_streams_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 num_incoming_streams_created_(0) {
143 Initialize();
144 this->connection()->SetEncrypter(
145 ENCRYPTION_FORWARD_SECURE,
146 QuicMakeUnique<NullEncrypter>(connection->perspective()));
147 }
148
149 ~TestSession() override { delete connection(); }
150
151 TestCryptoStream* GetMutableCryptoStream() override {
152 return &crypto_stream_;
153 }
154
155 const TestCryptoStream* GetCryptoStream() const override {
156 return &crypto_stream_;
157 }
158
159 TestStream* CreateOutgoingBidirectionalStream() {
160 QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
161 if (id ==
162 QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
163 return nullptr;
164 }
165 TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
166 ActivateStream(QuicWrapUnique(stream));
167 return stream;
168 }
169
170 TestStream* CreateOutgoingUnidirectionalStream() {
171 TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
172 this, WRITE_UNIDIRECTIONAL);
173 ActivateStream(QuicWrapUnique(stream));
174 return stream;
175 }
176
177 TestStream* CreateIncomingStream(QuicStreamId id) override {
178 // Enforce the limit on the number of open streams.
179 if (GetNumOpenIncomingStreams() + 1 >
180 max_open_incoming_bidirectional_streams() &&
181 connection()->transport_version() != QUIC_VERSION_99) {
182 // No need to do this test for version 99; it's done by
183 // QuicSession::GetOrCreateDynamicStream.
184 connection()->CloseConnection(
185 QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
186 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
187 return nullptr;
188 }
189
190 TestStream* stream =
191 new TestStream(id, this,
192 DetermineStreamType(
193 id, connection()->transport_version(), perspective(),
194 /*is_incoming=*/true, BIDIRECTIONAL));
195 ActivateStream(QuicWrapUnique(stream));
196 ++num_incoming_streams_created_;
197 return stream;
198 }
199
200 TestStream* CreateIncomingStream(PendingStream pending) override {
201 QuicStreamId id = pending.id();
202 TestStream* stream =
203 new TestStream(std::move(pending),
204 DetermineStreamType(
205 id, connection()->transport_version(), perspective(),
206 /*is_incoming=*/true, BIDIRECTIONAL));
207 ActivateStream(QuicWrapUnique(stream));
208 ++num_incoming_streams_created_;
209 return stream;
210 }
211
renjietange76b2da2019-05-13 14:50:23 -0700212 // QuicSession doesn't do anything in this method. So it's overridden here to
213 // test that the session handles pending streams correctly in terms of
214 // receiving stream frames.
215 void ProcessPendingStream(PendingStream* pending) override {
216 struct iovec iov;
217 if (pending->sequencer()->GetReadableRegion(&iov)) {
218 // Create TestStream once the first byte is received.
219 CreateIncomingStream(std::move(*pending));
220 }
221 }
222
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 bool IsClosedStream(QuicStreamId id) {
224 return QuicSession::IsClosedStream(id);
225 }
226
227 QuicStream* GetOrCreateDynamicStream(QuicStreamId stream_id) {
228 return QuicSession::GetOrCreateDynamicStream(stream_id);
229 }
230
231 bool ShouldKeepConnectionAlive() const override {
232 return GetNumOpenDynamicStreams() > 0;
233 }
234
235 QuicConsumedData WritevData(QuicStream* stream,
236 QuicStreamId id,
237 size_t write_length,
238 QuicStreamOffset offset,
239 StreamSendingState state) override {
240 bool fin = state != NO_FIN;
241 QuicConsumedData consumed(write_length, fin);
242 if (!writev_consumes_all_data_) {
243 consumed =
244 QuicSession::WritevData(stream, id, write_length, offset, state);
245 }
246 if (fin && consumed.fin_consumed) {
247 stream->set_fin_sent(true);
248 }
249 QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
250 id, consumed.bytes_consumed);
251 return consumed;
252 }
253
254 MOCK_METHOD0(OnCanCreateNewOutgoingStream, void());
255
256 void set_writev_consumes_all_data(bool val) {
257 writev_consumes_all_data_ = val;
258 }
259
260 QuicConsumedData SendStreamData(QuicStream* stream) {
261 struct iovec iov;
262 if (stream->id() !=
263 QuicUtils::GetCryptoStreamId(connection()->transport_version()) &&
264 this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
265 this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
266 }
267 MakeIOVector("not empty", &iov);
268 QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
269 QuicConsumedData consumed = WritevData(stream, stream->id(), 9, 0, FIN);
270 QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
271 consumed.bytes_consumed);
272 return consumed;
273 }
274
275 bool ClearControlFrame(const QuicFrame& frame) {
276 DeleteFrame(&const_cast<QuicFrame&>(frame));
277 return true;
278 }
279
280 bool SaveFrame(const QuicFrame& frame) {
281 save_frame_ = frame;
282 DeleteFrame(&const_cast<QuicFrame&>(frame));
283 return true;
284 }
285
286 const QuicFrame& save_frame() { return save_frame_; }
287
288 QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
289 DCHECK(writev_consumes_all_data_);
290 return WritevData(stream, stream->id(), bytes, 0, FIN);
291 }
292
renjietange76b2da2019-05-13 14:50:23 -0700293 bool UsesPendingStreams() const override { return uses_pending_streams_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500294
renjietange76b2da2019-05-13 14:50:23 -0700295 void set_uses_pending_streams(bool uses_pending_streams) {
296 uses_pending_streams_ = uses_pending_streams;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500297 }
298
299 int num_incoming_streams_created() const {
300 return num_incoming_streams_created_;
301 }
302
303 using QuicSession::ActivateStream;
304 using QuicSession::closed_streams;
305 using QuicSession::zombie_streams;
306
307 private:
308 StrictMock<TestCryptoStream> crypto_stream_;
309
310 bool writev_consumes_all_data_;
renjietange76b2da2019-05-13 14:50:23 -0700311 bool uses_pending_streams_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500312 QuicFrame save_frame_;
313 int num_incoming_streams_created_;
314};
315
316class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
317 protected:
318 explicit QuicSessionTestBase(Perspective perspective)
319 : connection_(
320 new StrictMock<MockQuicConnection>(&helper_,
321 &alarm_factory_,
322 perspective,
323 SupportedVersions(GetParam()))),
324 session_(connection_, &session_visitor_) {
325 session_.config()->SetInitialStreamFlowControlWindowToSend(
326 kInitialStreamFlowControlWindowForTest);
327 session_.config()->SetInitialSessionFlowControlWindowToSend(
328 kInitialSessionFlowControlWindowForTest);
329 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
330 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
331 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
332 .Times(testing::AnyNumber());
333 }
334
335 void CheckClosedStreams() {
QUICHE teamdc41bf12019-03-20 12:58:42 -0700336 QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
337 connection_->transport_version(), Perspective::IS_CLIENT);
338 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
339 first_stream_id =
340 QuicUtils::GetCryptoStreamId(connection_->transport_version());
341 }
342 for (QuicStreamId i = first_stream_id; i < 100; i++) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500343 if (!QuicContainsKey(closed_streams_, i)) {
344 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
345 } else {
346 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
347 }
348 }
349 }
350
351 void CloseStream(QuicStreamId id) {
352 if (session_.connection()->transport_version() == QUIC_VERSION_99 &&
353 QuicUtils::GetStreamType(id, session_.perspective(),
354 session_.IsIncomingStream(id)) ==
355 READ_UNIDIRECTIONAL) {
356 // Verify reset is not sent for READ_UNIDIRECTIONAL streams.
357 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
358 EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(0);
359 } else {
360 // Verify reset IS sent for BIDIRECTIONAL streams.
361 if (session_.connection()->transport_version() == QUIC_VERSION_99) {
362 // Once for the RST_STREAM, Once for the STOP_SENDING
363 EXPECT_CALL(*connection_, SendControlFrame(_))
364 .Times(2)
365 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
366 } else {
367 EXPECT_CALL(*connection_, SendControlFrame(_))
368 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
369 }
370 EXPECT_CALL(*connection_, OnStreamReset(id, _));
371 }
372 session_.CloseStream(id);
373 closed_streams_.insert(id);
374 }
375
376 QuicTransportVersion transport_version() const {
377 return connection_->transport_version();
378 }
379
380 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
381 return QuicUtils::GetFirstBidirectionalStreamId(
382 connection_->transport_version(), Perspective::IS_CLIENT) +
383 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
384 }
385
386 QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
387 return QuicUtils::GetFirstUnidirectionalStreamId(
388 connection_->transport_version(), Perspective::IS_CLIENT) +
389 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
390 }
391
392 QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
393 return QuicUtils::GetFirstBidirectionalStreamId(
394 connection_->transport_version(), Perspective::IS_SERVER) +
395 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
396 }
397
398 QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
399 return QuicUtils::GetFirstUnidirectionalStreamId(
400 connection_->transport_version(), Perspective::IS_SERVER) +
401 QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
402 }
403
fkastenholz3c4eabf2019-04-22 07:49:59 -0700404 QuicStreamId StreamCountToId(QuicStreamCount stream_count,
405 Perspective perspective,
406 bool bidirectional) {
407 // Calculate and build up stream ID rather than use
408 // GetFirst... because tests that rely on this method
409 // needs to do the stream count where #1 is 0/1/2/3, and not
410 // take into account that stream 0 is special.
411 QuicStreamId id =
412 ((stream_count - 1) * QuicUtils::StreamIdDelta(QUIC_VERSION_99));
413 if (!bidirectional) {
414 id |= 0x2;
415 }
416 if (perspective == Perspective::IS_SERVER) {
417 id |= 0x1;
418 }
419 return id;
420 }
421
QUICHE teama6ef0a62019-03-07 20:34:33 -0500422 MockQuicConnectionHelper helper_;
423 MockAlarmFactory alarm_factory_;
424 NiceMock<MockQuicSessionVisitor> session_visitor_;
425 StrictMock<MockQuicConnection>* connection_;
426 TestSession session_;
427 std::set<QuicStreamId> closed_streams_;
428};
429
430class QuicSessionTestServer : public QuicSessionTestBase {
431 public:
432 // CheckMultiPathResponse validates that a written packet
433 // contains both expected path responses.
434 WriteResult CheckMultiPathResponse(const char* buffer,
435 size_t buf_len,
436 const QuicIpAddress& self_address,
437 const QuicSocketAddress& peer_address,
438 PerPacketOptions* options) {
439 QuicEncryptedPacket packet(buffer, buf_len);
440 {
441 InSequence s;
442 EXPECT_CALL(framer_visitor_, OnPacket());
443 EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
444 EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
445 EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
446 EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
447 EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
448 .WillOnce(
449 WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
450 EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
451 return true;
452 })));
453 EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
454 .WillOnce(
455 WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
456 EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
457 return true;
458 })));
459 EXPECT_CALL(framer_visitor_, OnPacketComplete());
460 }
461 client_framer_.ProcessPacket(packet);
462 return WriteResult(WRITE_STATUS_OK, 0);
463 }
464
465 protected:
466 QuicSessionTestServer()
467 : QuicSessionTestBase(Perspective::IS_SERVER),
468 path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
469 path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
470 client_framer_(SupportedVersions(GetParam()),
471 QuicTime::Zero(),
472 Perspective::IS_CLIENT,
473 kQuicDefaultConnectionIdLength) {
474 client_framer_.set_visitor(&framer_visitor_);
475 }
476
477 QuicPathFrameBuffer path_frame_buffer1_;
478 QuicPathFrameBuffer path_frame_buffer2_;
479 StrictMock<MockFramerVisitor> framer_visitor_;
480 // Framer used to process packets sent by server.
481 QuicFramer client_framer_;
482};
483
484INSTANTIATE_TEST_SUITE_P(Tests,
485 QuicSessionTestServer,
486 ::testing::ValuesIn(AllSupportedVersions()));
487
488TEST_P(QuicSessionTestServer, PeerAddress) {
489 EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
490 session_.peer_address());
491}
492
493TEST_P(QuicSessionTestServer, SelfAddress) {
494 EXPECT_TRUE(session_.self_address().IsInitialized());
495}
496
497TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
498 EXPECT_CALL(*connection_, CloseConnection(_, _, _))
499 .WillOnce(
500 Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
501 connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
502 ConnectionCloseBehavior::SILENT_CLOSE);
503 ASSERT_FALSE(connection_->connected());
504
QUICHE teamaa1d6a82019-03-13 09:14:13 -0700505 EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 session_.OnWriteBlocked();
507}
508
509TEST_P(QuicSessionTestServer, IsCryptoHandshakeConfirmed) {
510 EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
511 CryptoHandshakeMessage message;
512 session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
513 EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
514}
515
516TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
517 // Ensure that no streams are initially closed.
QUICHE teamdc41bf12019-03-20 12:58:42 -0700518 QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
519 connection_->transport_version(), Perspective::IS_CLIENT);
520 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
521 first_stream_id =
522 QuicUtils::GetCryptoStreamId(connection_->transport_version());
523 }
524 for (QuicStreamId i = first_stream_id; i < 100; i++) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525 EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
526 }
527}
528
529TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
530 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
531 GetNthClientInitiatedBidirectionalId(3)) != nullptr);
532 // Smaller bidirectional streams should be available.
533 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
534 &session_, GetNthClientInitiatedBidirectionalId(1)));
535 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
536 &session_, GetNthClientInitiatedBidirectionalId(2)));
537 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
538 GetNthClientInitiatedBidirectionalId(2)) != nullptr);
539 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
540 GetNthClientInitiatedBidirectionalId(1)) != nullptr);
541}
542
543TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
544 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
545 GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
546 // Smaller unidirectional streams should be available.
547 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
548 &session_, GetNthClientInitiatedUnidirectionalId(1)));
549 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
550 &session_, GetNthClientInitiatedUnidirectionalId(2)));
551 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
552 GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
553 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
554 GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
555}
556
557TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
558 if (transport_version() == QUIC_VERSION_99) {
559 EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
560 session_.MaxAvailableBidirectionalStreams());
561 } else {
562 // The protocol specification requires that there can be at least 10 times
563 // as many available streams as the connection's maximum open streams.
564 EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
565 kMaxAvailableStreamsMultiplier,
566 session_.MaxAvailableBidirectionalStreams());
567 }
568}
569
570TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
571 if (transport_version() == QUIC_VERSION_99) {
572 EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
573 session_.MaxAvailableUnidirectionalStreams());
574 } else {
575 // The protocol specification requires that there can be at least 10 times
576 // as many available streams as the connection's maximum open streams.
577 EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
578 kMaxAvailableStreamsMultiplier,
579 session_.MaxAvailableUnidirectionalStreams());
580 }
581}
582
583TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
584 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
585 EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
586 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
587 EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
588
589 CheckClosedStreams();
590 CloseStream(GetNthServerInitiatedBidirectionalId(0));
591 CheckClosedStreams();
592 CloseStream(GetNthServerInitiatedBidirectionalId(1));
593 CheckClosedStreams();
594}
595
596TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
597 TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
598 EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
599 TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
600 EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
601
602 CheckClosedStreams();
603 CloseStream(GetNthServerInitiatedUnidirectionalId(0));
604 CheckClosedStreams();
605 CloseStream(GetNthServerInitiatedUnidirectionalId(1));
606 CheckClosedStreams();
607}
608
609TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
610 QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
611 QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
612 session_.GetOrCreateDynamicStream(stream_id1);
613 session_.GetOrCreateDynamicStream(stream_id2);
614
615 CheckClosedStreams();
616 CloseStream(stream_id1);
617 CheckClosedStreams();
618 CloseStream(stream_id2);
619 // Create a stream, and make another available.
620 QuicStream* stream3 = session_.GetOrCreateDynamicStream(
621 stream_id2 +
622 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
623 CheckClosedStreams();
624 // Close one, but make sure the other is still not closed
625 CloseStream(stream3->id());
626 CheckClosedStreams();
627}
628
629TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
630 QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
631 QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
632 session_.GetOrCreateDynamicStream(stream_id1);
633 session_.GetOrCreateDynamicStream(stream_id2);
634
635 CheckClosedStreams();
636 CloseStream(stream_id1);
637 CheckClosedStreams();
638 CloseStream(stream_id2);
639 // Create a stream, and make another available.
640 QuicStream* stream3 = session_.GetOrCreateDynamicStream(
641 stream_id2 +
642 2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
643 CheckClosedStreams();
644 // Close one, but make sure the other is still not closed
645 CloseStream(stream3->id());
646 CheckClosedStreams();
647}
648
649TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
650 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
651 session_.GetOrCreateDynamicStream(stream_id);
652 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
653 EXPECT_NE(
654 nullptr,
655 session_.GetOrCreateDynamicStream(GetNthClientInitiatedBidirectionalId(
656 session_.max_open_incoming_bidirectional_streams() - 1)));
657}
658
659TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
660 QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
661 session_.GetOrCreateDynamicStream(stream_id);
662 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
663 EXPECT_NE(
664 nullptr,
665 session_.GetOrCreateDynamicStream(GetNthClientInitiatedUnidirectionalId(
666 session_.max_open_incoming_unidirectional_streams() - 1)));
667}
668
669TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
670 QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
671 QuicStreamId stream_id2;
672 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
673 // A stream ID which is too large to create.
674 stream_id2 = GetNthClientInitiatedBidirectionalId(
675 session_.MaxAvailableBidirectionalStreams() + 2);
676 if (transport_version() == QUIC_VERSION_99) {
677 // V99 terminates the connection with invalid stream id
678 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
679 } else {
680 // other versions terminate the connection with
681 // QUIC_TOO_MANY_AVAILABLE_STREAMS.
682 EXPECT_CALL(*connection_,
683 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
684 }
685 EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
686}
687
688TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
689 QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
690 QuicStreamId stream_id2;
691 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
692 // A stream ID which is too large to create.
693 stream_id2 = GetNthClientInitiatedUnidirectionalId(
694 session_.MaxAvailableUnidirectionalStreams() + 2);
695 if (transport_version() == QUIC_VERSION_99) {
696 // V99 terminates the connection with invalid stream id
697 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
698 } else {
699 // other versions terminate the connection with
700 // QUIC_TOO_MANY_AVAILABLE_STREAMS.
701 EXPECT_CALL(*connection_,
702 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
703 }
704 EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
705}
706
707TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
708 // When max_open_streams_ is 200, should be able to create 200 streams
709 // out-of-order, that is, creating the one with the largest stream ID first.
710 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
711 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
712 // Create one stream.
713 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id));
714 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
715
716 // Create the largest stream ID of a threatened total of 200 streams.
717 // GetNth... starts at 0, so for 200 streams, get the 199th.
718 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(
719 GetNthClientInitiatedBidirectionalId(199)));
720}
721
722TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
723 // When max_open_streams_ is 200, should be able to create 200 streams
724 // out-of-order, that is, creating the one with the largest stream ID first.
725 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
726 QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
727 // Create one stream.
728 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id));
729 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
730
731 // Create the largest stream ID of a threatened total of 200 streams.
732 // GetNth... starts at 0, so for 200 streams, get the 199th.
733 EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(
734 GetNthClientInitiatedUnidirectionalId(199)));
735}
736
737TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
738 // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
739 if (GetParam() != AllSupportedVersions()[0]) {
740 return;
741 }
742
743 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
744 QuicStreamId closed_stream_id = stream2->id();
745 // Close the stream.
746 EXPECT_CALL(*connection_, SendControlFrame(_));
747 EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
748 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
vasilvvc48c8712019-03-11 13:38:16 -0700749 std::string msg =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500750 QuicStrCat("Marking unknown stream ", closed_stream_id, " blocked.");
751 EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
752 msg);
753}
754
755TEST_P(QuicSessionTestServer, OnCanWrite) {
756 session_.set_writev_consumes_all_data(true);
757 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
758 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
759 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
760
761 session_.MarkConnectionLevelWriteBlocked(stream2->id());
762 session_.MarkConnectionLevelWriteBlocked(stream6->id());
763 session_.MarkConnectionLevelWriteBlocked(stream4->id());
764
765 InSequence s;
766
767 // Reregister, to test the loop limit.
768 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
769 session_.SendStreamData(stream2);
770 session_.MarkConnectionLevelWriteBlocked(stream2->id());
771 }));
772 // 2 will get called a second time as it didn't finish its block
773 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
774 session_.SendStreamData(stream2);
775 }));
776 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
777 session_.SendStreamData(stream6);
778 }));
779 // 4 will not get called, as we exceeded the loop limit.
780 session_.OnCanWrite();
781 EXPECT_TRUE(session_.WillingAndAbleToWrite());
782}
783
784TEST_P(QuicSessionTestServer, TestBatchedWrites) {
785 session_.set_writev_consumes_all_data(true);
786 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
787 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
788 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
789
790 session_.set_writev_consumes_all_data(true);
791 session_.MarkConnectionLevelWriteBlocked(stream2->id());
792 session_.MarkConnectionLevelWriteBlocked(stream4->id());
793
794 // With two sessions blocked, we should get two write calls. They should both
795 // go to the first stream as it will only write 6k and mark itself blocked
796 // again.
797 InSequence s;
798 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
799 session_.SendLargeFakeData(stream2, 6000);
800 session_.MarkConnectionLevelWriteBlocked(stream2->id());
801 }));
802 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
803 session_.SendLargeFakeData(stream2, 6000);
804 session_.MarkConnectionLevelWriteBlocked(stream2->id());
805 }));
806 session_.OnCanWrite();
807
808 // We should get one more call for stream2, at which point it has used its
809 // write quota and we move over to stream 4.
810 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
811 session_.SendLargeFakeData(stream2, 6000);
812 session_.MarkConnectionLevelWriteBlocked(stream2->id());
813 }));
814 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
815 session_.SendLargeFakeData(stream4, 6000);
816 session_.MarkConnectionLevelWriteBlocked(stream4->id());
817 }));
818 session_.OnCanWrite();
819
820 // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
821 // priority stream 6. 4 should be preempted. 6 will write but *not* block so
822 // will cede back to 4.
823 stream6->SetPriority(kV3HighestPriority);
824 EXPECT_CALL(*stream4, OnCanWrite())
825 .WillOnce(Invoke([this, stream4, stream6]() {
826 session_.SendLargeFakeData(stream4, 6000);
827 session_.MarkConnectionLevelWriteBlocked(stream4->id());
828 session_.MarkConnectionLevelWriteBlocked(stream6->id());
829 }));
830 EXPECT_CALL(*stream6, OnCanWrite())
831 .WillOnce(Invoke([this, stream4, stream6]() {
832 session_.SendStreamData(stream6);
833 session_.SendLargeFakeData(stream4, 6000);
834 }));
835 session_.OnCanWrite();
836
837 // Stream4 alread did 6k worth of writes, so after doing another 12k it should
838 // cede and 2 should resume.
839 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
840 session_.SendLargeFakeData(stream4, 12000);
841 session_.MarkConnectionLevelWriteBlocked(stream4->id());
842 }));
843 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
844 session_.SendLargeFakeData(stream2, 6000);
845 session_.MarkConnectionLevelWriteBlocked(stream2->id());
846 }));
847 session_.OnCanWrite();
848}
849
850TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
851 // Encryption needs to be established before data can be sent.
852 CryptoHandshakeMessage msg;
853 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
854 QuicConnectionPeer::GetWriter(session_.connection()));
855 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
856
857 // Drive congestion control manually.
858 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
859 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
860
861 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
862 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
863 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
864
865 session_.MarkConnectionLevelWriteBlocked(stream2->id());
866 session_.MarkConnectionLevelWriteBlocked(stream6->id());
867 session_.MarkConnectionLevelWriteBlocked(stream4->id());
868
869 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
870 EXPECT_CALL(*send_algorithm, GetCongestionWindow())
dschinazi66dea072019-04-09 11:41:06 -0700871 .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500872 EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
873 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
874 session_.SendStreamData(stream2);
875 }));
876 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
877 session_.SendStreamData(stream4);
878 }));
879 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
880 session_.SendStreamData(stream6);
881 }));
882
883 // Expect that we only send one packet, the writes from different streams
884 // should be bundled together.
885 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
886 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
887 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
888 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
889 session_.OnCanWrite();
890 EXPECT_FALSE(session_.WillingAndAbleToWrite());
891}
892
893TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
894 session_.set_writev_consumes_all_data(true);
895 InSequence s;
896
897 // Drive congestion control manually.
898 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
899 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
900
901 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
902 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
903 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
904
905 session_.MarkConnectionLevelWriteBlocked(stream2->id());
906 session_.MarkConnectionLevelWriteBlocked(stream6->id());
907 session_.MarkConnectionLevelWriteBlocked(stream4->id());
908
909 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
910 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
911 session_.SendStreamData(stream2);
912 }));
913 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
914 EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
915 session_.SendStreamData(stream6);
916 }));
917 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
918 // stream4->OnCanWrite is not called.
919
920 session_.OnCanWrite();
921 EXPECT_TRUE(session_.WillingAndAbleToWrite());
922
923 // Still congestion-control blocked.
924 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
925 session_.OnCanWrite();
926 EXPECT_TRUE(session_.WillingAndAbleToWrite());
927
928 // stream4->OnCanWrite is called once the connection stops being
929 // congestion-control blocked.
930 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
931 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
932 session_.SendStreamData(stream4);
933 }));
934 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
935 session_.OnCanWrite();
936 EXPECT_FALSE(session_.WillingAndAbleToWrite());
937}
938
939TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
940 // Drive congestion control manually in order to ensure that
941 // application-limited signaling is handled correctly.
942 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
943 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
944 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
945
946 // Drive packet writer manually.
947 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
948 QuicConnectionPeer::GetWriter(session_.connection()));
949 EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
950 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
951
952 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
953
954 session_.MarkConnectionLevelWriteBlocked(stream2->id());
955
956 EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
957 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
958
959 session_.OnCanWrite();
960 EXPECT_TRUE(session_.WillingAndAbleToWrite());
961}
962
963TEST_P(QuicSessionTestServer, BufferedHandshake) {
nharperd5c4a932019-05-13 13:58:49 -0700964 // This test is testing behavior of crypto stream flow control, but when
965 // CRYPTO frames are used, there is no flow control for the crypto handshake.
966 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
967 return;
968 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500969 session_.set_writev_consumes_all_data(true);
970 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
971
972 // Test that blocking other streams does not change our status.
973 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
974 session_.MarkConnectionLevelWriteBlocked(stream2->id());
975 EXPECT_FALSE(session_.HasPendingHandshake());
976
977 TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
978 session_.MarkConnectionLevelWriteBlocked(stream3->id());
979 EXPECT_FALSE(session_.HasPendingHandshake());
980
981 // Blocking (due to buffering of) the Crypto stream is detected.
982 session_.MarkConnectionLevelWriteBlocked(
983 QuicUtils::GetCryptoStreamId(connection_->transport_version()));
984 EXPECT_TRUE(session_.HasPendingHandshake());
985
986 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
987 session_.MarkConnectionLevelWriteBlocked(stream4->id());
988 EXPECT_TRUE(session_.HasPendingHandshake());
989
990 InSequence s;
991 // Force most streams to re-register, which is common scenario when we block
992 // the Crypto stream, and only the crypto stream can "really" write.
993
994 // Due to prioritization, we *should* be asked to write the crypto stream
995 // first.
996 // Don't re-register the crypto stream (which signals complete writing).
997 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
998 EXPECT_CALL(*crypto_stream, OnCanWrite());
999
1000 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1001 session_.SendStreamData(stream2);
1002 }));
1003 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
1004 session_.SendStreamData(stream3);
1005 }));
1006 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1007 session_.SendStreamData(stream4);
1008 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1009 }));
1010
1011 session_.OnCanWrite();
1012 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1013 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
1014}
1015
1016TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
1017 session_.set_writev_consumes_all_data(true);
1018 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1019 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1020 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1021
1022 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1023 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1024 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1025 CloseStream(stream6->id());
1026
1027 InSequence s;
1028 EXPECT_CALL(*connection_, SendControlFrame(_))
1029 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
1030 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1031 session_.SendStreamData(stream2);
1032 }));
1033 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1034 session_.SendStreamData(stream4);
1035 }));
1036 session_.OnCanWrite();
1037 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1038}
1039
1040TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
1041 // Drive congestion control manually in order to ensure that
1042 // application-limited signaling is handled correctly.
1043 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1044 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1045 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
1046
1047 // Ensure connection level flow control blockage.
1048 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
1049 EXPECT_TRUE(session_.flow_controller()->IsBlocked());
1050 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
1051 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1052
1053 // Mark the crypto and headers streams as write blocked, we expect them to be
1054 // allowed to write later.
nharperd5c4a932019-05-13 13:58:49 -07001055 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
1056 session_.MarkConnectionLevelWriteBlocked(
1057 QuicUtils::GetCryptoStreamId(connection_->transport_version()));
1058 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001059
1060 // Create a data stream, and although it is write blocked we never expect it
1061 // to be allowed to write as we are connection level flow control blocked.
1062 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1063 session_.MarkConnectionLevelWriteBlocked(stream->id());
1064 EXPECT_CALL(*stream, OnCanWrite()).Times(0);
1065
1066 // The crypto and headers streams should be called even though we are
1067 // connection flow control blocked.
nharperd5c4a932019-05-13 13:58:49 -07001068 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
1069 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1070 EXPECT_CALL(*crypto_stream, OnCanWrite());
1071 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001072
1073 // After the crypto and header streams perform a write, the connection will be
1074 // blocked by the flow control, hence it should become application-limited.
1075 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1076
1077 session_.OnCanWrite();
1078 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1079}
1080
1081TEST_P(QuicSessionTestServer, SendGoAway) {
1082 if (transport_version() == QUIC_VERSION_99) {
1083 // GoAway frames are not in version 99
1084 return;
1085 }
1086 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1087 QuicConnectionPeer::GetWriter(session_.connection()));
1088 EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
1089 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1090
1091 EXPECT_CALL(*connection_, SendControlFrame(_))
1092 .WillOnce(
1093 Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
1094 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1095 EXPECT_TRUE(session_.goaway_sent());
1096
1097 const QuicStreamId kTestStreamId = 5u;
1098 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1099 EXPECT_CALL(*connection_,
1100 OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
1101 .Times(0);
1102 EXPECT_TRUE(session_.GetOrCreateDynamicStream(kTestStreamId));
1103}
1104
1105TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
1106 if (transport_version() == QUIC_VERSION_99) {
1107 // TODO(b/118808809): Enable this test for version 99 when GOAWAY is
1108 // supported.
1109 return;
1110 }
1111 EXPECT_CALL(*connection_, SendControlFrame(_))
1112 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1113 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1114 EXPECT_TRUE(session_.goaway_sent());
1115 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1116}
1117
1118TEST_P(QuicSessionTestServer, InvalidGoAway) {
1119 if (transport_version() == QUIC_VERSION_99) {
1120 // TODO(b/118808809): Enable this test for version 99 when GOAWAY is
1121 // supported.
1122 return;
1123 }
1124 QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
1125 session_.next_outgoing_bidirectional_stream_id(), "");
1126 session_.OnGoAway(go_away);
1127}
1128
1129// Test that server session will send a connectivity probe in response to a
1130// connectivity probe on the same path.
1131TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
1132 QuicSocketAddress old_peer_address =
1133 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
1134 EXPECT_EQ(old_peer_address, session_.peer_address());
1135
1136 QuicSocketAddress new_peer_address =
1137 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
1138
1139 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1140 QuicConnectionPeer::GetWriter(session_.connection()));
1141 EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
1142 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1143 EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
1144 .WillOnce(Invoke(
1145 connection_,
1146 &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
1147 if (transport_version() == QUIC_VERSION_99) {
1148 // Need to explicitly do this to emulate the reception of a PathChallenge,
1149 // which stores its payload for use in generating the response.
1150 connection_->OnPathChallengeFrame(
1151 QuicPathChallengeFrame(0, path_frame_buffer1_));
1152 }
1153 session_.OnConnectivityProbeReceived(session_.self_address(),
1154 new_peer_address);
1155 EXPECT_EQ(old_peer_address, session_.peer_address());
1156}
1157
1158// Same as above, but check that if there are two PATH_CHALLENGE frames in the
1159// packet, the response has both of them AND we do not do migration. This for
1160// V99 only.
1161TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbes) {
1162 if (transport_version() != QUIC_VERSION_99) {
1163 return;
1164 }
1165 QuicSocketAddress old_peer_address =
1166 QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
1167 EXPECT_EQ(old_peer_address, session_.peer_address());
1168
1169 MockPacketWriter* writer = static_cast<MockPacketWriter*>(
1170 QuicConnectionPeer::GetWriter(session_.connection()));
1171 // CheckMultiPathResponse validates that the written packet
1172 // contains both path responses.
1173 EXPECT_CALL(*writer, WritePacket(_, _, _, old_peer_address, _))
1174 .WillOnce(Invoke(this, &QuicSessionTestServer::CheckMultiPathResponse));
1175
1176 EXPECT_CALL(*connection_, SendConnectivityProbingResponsePacket(_))
1177 .WillOnce(Invoke(
1178 connection_,
1179 &MockQuicConnection::ReallySendConnectivityProbingResponsePacket));
QUICHE team8c1daa22019-03-13 08:33:41 -07001180 QuicConnectionPeer::SetLastHeaderFormat(connection_,
1181 IETF_QUIC_SHORT_HEADER_PACKET);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001182 // Need to explicitly do this to emulate the reception of a PathChallenge,
1183 // which stores its payload for use in generating the response.
1184 connection_->OnPathChallengeFrame(
1185 QuicPathChallengeFrame(0, path_frame_buffer1_));
1186 connection_->OnPathChallengeFrame(
1187 QuicPathChallengeFrame(0, path_frame_buffer2_));
1188 session_.OnConnectivityProbeReceived(session_.self_address(),
1189 old_peer_address);
1190}
1191
1192TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
1193 EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
1194 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1195 CryptoHandshakeMessage msg;
1196 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1197 EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
1198 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1199}
1200
1201TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
1202 // Send two bytes of payload.
1203 QuicStreamFrame data1(
1204 QuicUtils::GetCryptoStreamId(connection_->transport_version()), true, 0,
1205 QuicStringPiece("HT"));
1206 EXPECT_CALL(*connection_,
1207 CloseConnection(
1208 QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
1209 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1210 session_.OnStreamFrame(data1);
1211}
1212
1213TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) {
1214 // Send two bytes of payload.
1215 QuicRstStreamFrame rst1(
1216 kInvalidControlFrameId,
1217 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
1218 QUIC_ERROR_PROCESSING_STREAM, 0);
1219 EXPECT_CALL(*connection_,
1220 CloseConnection(
1221 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream",
1222 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1223 session_.OnRstStream(rst1);
1224}
1225
1226TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
1227 // Send two bytes of payload.
1228 QuicStreamFrame data1(
1229 QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
1230 QuicStringPiece("HT"));
1231 EXPECT_CALL(*connection_,
1232 CloseConnection(
bnce433f532019-04-16 13:05:27 -07001233 QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
QUICHE teama6ef0a62019-03-07 20:34:33 -05001234 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1235 session_.OnStreamFrame(data1);
1236}
1237
1238TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
1239 // Send two bytes of payload.
1240 QuicRstStreamFrame rst1(
1241 kInvalidControlFrameId,
1242 QuicUtils::GetInvalidStreamId(connection_->transport_version()),
1243 QUIC_ERROR_PROCESSING_STREAM, 0);
1244 EXPECT_CALL(*connection_,
1245 CloseConnection(
bnce433f532019-04-16 13:05:27 -07001246 QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
QUICHE teama6ef0a62019-03-07 20:34:33 -05001247 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1248 session_.OnRstStream(rst1);
1249}
1250
1251TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
1252 // Test that if a stream is flow control blocked, then on receipt of the SHLO
1253 // containing a suitable send window offset, the stream becomes unblocked.
1254
1255 // Ensure that Writev consumes all the data it is given (simulate no socket
1256 // blocking).
1257 session_.set_writev_consumes_all_data(true);
1258
1259 // Create a stream, and send enough data to make it flow control blocked.
1260 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
vasilvvc48c8712019-03-11 13:38:16 -07001261 std::string body(kMinimumFlowControlSendWindow, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001262 EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
1263 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1264 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1265 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
1266 stream2->WriteOrBufferData(body, false, nullptr);
1267 EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
1268 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
1269 EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
1270
1271 // Now complete the crypto handshake, resulting in an increased flow control
1272 // send window.
1273 CryptoHandshakeMessage msg;
1274 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1275 EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
1276 // Stream is now unblocked.
1277 EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
1278 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1279 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1280}
1281
1282TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
QUICHE teamea740082019-03-11 17:58:43 -07001283 if (QuicVersionUsesCryptoFrames(GetParam().transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001284 // QUIC version 47 onwards uses CRYPTO frames for the handshake, so this
1285 // test doesn't make sense for those versions since CRYPTO frames aren't
1286 // flow controlled.
1287 return;
1288 }
1289 // Test that if the crypto stream is flow control blocked, then if the SHLO
1290 // contains a larger send window offset, the stream becomes unblocked.
1291 session_.set_writev_consumes_all_data(true);
1292 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1293 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
1294 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1295 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1296 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1297 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1298 EXPECT_CALL(*connection_, SendControlFrame(_))
1299 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1300 for (QuicStreamId i = 0;
1301 !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) {
1302 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1303 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1304 QuicStreamOffset offset = crypto_stream->stream_bytes_written();
1305 QuicConfig config;
1306 CryptoHandshakeMessage crypto_message;
1307 config.ToHandshakeMessage(&crypto_message);
1308 crypto_stream->SendHandshakeMessage(crypto_message);
1309 char buf[1000];
1310 QuicDataWriter writer(1000, buf, NETWORK_BYTE_ORDER);
1311 crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer);
1312 }
1313 EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked());
1314 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1315 EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
1316 EXPECT_FALSE(session_.HasDataToWrite());
1317 EXPECT_TRUE(crypto_stream->HasBufferedData());
1318
1319 // Now complete the crypto handshake, resulting in an increased flow control
1320 // send window.
1321 CryptoHandshakeMessage msg;
1322 session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
1323 EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
1324 &session_,
1325 QuicUtils::GetCryptoStreamId(connection_->transport_version())));
1326 // Stream is now unblocked and will no longer have buffered data.
1327 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
1328 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
1329 EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
1330}
1331
1332TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
1333 // Test that when we receive an out of order stream RST we correctly adjust
1334 // our connection level flow control receive window.
1335 // On close, the stream should mark as consumed all bytes between the highest
1336 // byte consumed so far and the final byte offset from the RST frame.
1337 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1338
1339 const QuicStreamOffset kByteOffset =
1340 1 + kInitialSessionFlowControlWindowForTest / 2;
1341
1342 EXPECT_CALL(*connection_, SendControlFrame(_))
1343 .Times(2)
1344 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
1345 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1346
1347 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1348 QUIC_STREAM_CANCELLED, kByteOffset);
1349 session_.OnRstStream(rst_frame);
1350 if (transport_version() == QUIC_VERSION_99) {
1351 // The test is predicated on the stream being fully closed. For V99, the
1352 // RST_STREAM only does one side (the read side from the perspective of the
1353 // node receiving the RST_STREAM). This is needed to fully close the
1354 // stream and therefore fulfill all of the expects.
1355 QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
1356 QUIC_STREAM_CANCELLED);
1357 EXPECT_TRUE(session_.OnStopSendingFrame(frame));
1358 }
1359 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
1360}
1361
1362TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
1363 // Test the situation where we receive a FIN on a stream, and before we fully
1364 // consume all the data from the sequencer buffer we locally RST the stream.
1365 // The bytes between highest consumed byte, and the final byte offset that we
1366 // determined when the FIN arrived, should be marked as consumed at the
1367 // connection level flow controller when the stream is reset.
1368 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1369
1370 const QuicStreamOffset kByteOffset =
1371 kInitialSessionFlowControlWindowForTest / 2 - 1;
1372 QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
1373 session_.OnStreamFrame(frame);
1374 EXPECT_TRUE(connection_->connected());
1375
1376 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed());
1377 EXPECT_EQ(kByteOffset + frame.data_length,
1378 stream->flow_controller()->highest_received_byte_offset());
1379
1380 // Reset stream locally.
1381 EXPECT_CALL(*connection_, SendControlFrame(_));
1382 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1383 stream->Reset(QUIC_STREAM_CANCELLED);
1384 EXPECT_EQ(kByteOffset + frame.data_length,
1385 session_.flow_controller()->bytes_consumed());
1386}
1387
1388TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
1389 // Test that when we RST the stream (and tear down stream state), and then
1390 // receive a FIN from the peer, we correctly adjust our connection level flow
1391 // control receive window.
1392
1393 // Connection starts with some non-zero highest received byte offset,
1394 // due to other active streams.
1395 const uint64_t kInitialConnectionBytesConsumed = 567;
1396 const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
1397 EXPECT_LT(kInitialConnectionBytesConsumed,
1398 kInitialConnectionHighestReceivedOffset);
1399 session_.flow_controller()->UpdateHighestReceivedOffset(
1400 kInitialConnectionHighestReceivedOffset);
1401 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
1402
1403 // Reset our stream: this results in the stream being closed locally.
1404 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1405 EXPECT_CALL(*connection_, SendControlFrame(_));
1406 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1407 stream->Reset(QUIC_STREAM_CANCELLED);
1408
1409 // Now receive a response from the peer with a FIN. We should handle this by
1410 // adjusting the connection level flow control receive window to take into
1411 // account the total number of bytes sent by the peer.
1412 const QuicStreamOffset kByteOffset = 5678;
vasilvvc48c8712019-03-11 13:38:16 -07001413 std::string body = "hello";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001414 QuicStreamFrame frame(stream->id(), true, kByteOffset, QuicStringPiece(body));
1415 session_.OnStreamFrame(frame);
1416
1417 QuicStreamOffset total_stream_bytes_sent_by_peer =
1418 kByteOffset + body.length();
1419 EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
1420 session_.flow_controller()->bytes_consumed());
1421 EXPECT_EQ(
1422 kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
1423 session_.flow_controller()->highest_received_byte_offset());
1424}
1425
1426TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
1427 // Test that when we RST the stream (and tear down stream state), and then
1428 // receive a RST from the peer, we correctly adjust our connection level flow
1429 // control receive window.
1430
1431 // Connection starts with some non-zero highest received byte offset,
1432 // due to other active streams.
1433 const uint64_t kInitialConnectionBytesConsumed = 567;
1434 const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
1435 EXPECT_LT(kInitialConnectionBytesConsumed,
1436 kInitialConnectionHighestReceivedOffset);
1437 session_.flow_controller()->UpdateHighestReceivedOffset(
1438 kInitialConnectionHighestReceivedOffset);
1439 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
1440
1441 // Reset our stream: this results in the stream being closed locally.
1442 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1443 EXPECT_CALL(*connection_, SendControlFrame(_));
1444 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1445 stream->Reset(QUIC_STREAM_CANCELLED);
1446 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
1447
1448 // Now receive a RST from the peer. We should handle this by adjusting the
1449 // connection level flow control receive window to take into account the total
1450 // number of bytes sent by the peer.
1451 const QuicStreamOffset kByteOffset = 5678;
1452 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1453 QUIC_STREAM_CANCELLED, kByteOffset);
1454 session_.OnRstStream(rst_frame);
1455
1456 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
1457 session_.flow_controller()->bytes_consumed());
1458 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
1459 session_.flow_controller()->highest_received_byte_offset());
1460}
1461
1462TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
1463 // Test that receipt of an invalid (< default) stream flow control window from
1464 // the peer results in the connection being torn down.
1465 const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
1466 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
1467 kInvalidWindow);
1468
dschinazic7036122019-04-30 12:46:34 -07001469 if (!connection_->version().AllowsLowFlowControlLimits()) {
1470 EXPECT_CALL(*connection_,
1471 CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
1472 } else {
1473 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
1474 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001475 session_.OnConfigNegotiated();
1476}
1477
1478TEST_P(QuicSessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
1479 // Test that receipt of an invalid (< default) session flow control window
1480 // from the peer results in the connection being torn down.
1481 const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
1482 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
1483 kInvalidWindow);
dschinazic7036122019-04-30 12:46:34 -07001484 if (!connection_->version().AllowsLowFlowControlLimits()) {
1485 EXPECT_CALL(*connection_,
1486 CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
1487 } else {
1488 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
1489 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001490 session_.OnConfigNegotiated();
1491}
1492
1493// Test negotiation of custom server initial flow control window.
1494TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
1495 QuicTagVector copt;
1496 copt.push_back(kIFW7);
1497 QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
1498
1499 session_.OnConfigNegotiated();
1500 EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
1501 session_.flow_controller()));
1502}
1503
1504TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
1505 // Test that if we receive a stream RST with a highest byte offset that
1506 // violates flow control, that we close the connection.
1507 const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
1508 EXPECT_CALL(*connection_,
1509 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
1510 .Times(2);
1511
1512 // Check that stream frame + FIN results in connection close.
1513 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1514 EXPECT_CALL(*connection_, SendControlFrame(_));
1515 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1516 stream->Reset(QUIC_STREAM_CANCELLED);
1517 QuicStreamFrame frame(stream->id(), true, kLargeOffset, QuicStringPiece());
1518 session_.OnStreamFrame(frame);
1519
1520 // Check that RST results in connection close.
1521 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1522 QUIC_STREAM_CANCELLED, kLargeOffset);
1523 session_.OnRstStream(rst_frame);
1524}
1525
1526TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
1527 // If a buggy/malicious peer creates too many streams that are not ended
1528 // with a FIN or RST then we send an RST to refuse streams. For V99 the
1529 // connection is closed.
1530 const QuicStreamId kMaxStreams = 5;
1531 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
1532 const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
1533 const QuicStreamId kFinalStreamId =
1534 GetNthClientInitiatedBidirectionalId(kMaxStreams);
1535 // Create kMaxStreams data streams, and close them all without receiving a
1536 // FIN or a RST_STREAM from the client.
1537 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
1538 i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
1539 QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT"));
1540 session_.OnStreamFrame(data1);
1541 // EXPECT_EQ(1u, session_.GetNumOpenStreams());
1542 if (transport_version() == QUIC_VERSION_99) {
1543 // Expect two control frames, RST STREAM and STOP SENDING
1544 EXPECT_CALL(*connection_, SendControlFrame(_))
1545 .Times(2)
1546 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
1547 } else {
1548 // Expect one control frame, just RST STREAM
1549 EXPECT_CALL(*connection_, SendControlFrame(_))
1550 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1551 }
1552 // Close stream. Should not make new streams available since
1553 // the stream is not finished.
1554 EXPECT_CALL(*connection_, OnStreamReset(i, _));
1555 session_.CloseStream(i);
1556 }
1557
1558 if (transport_version() == QUIC_VERSION_99) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07001559 EXPECT_CALL(
1560 *connection_,
1561 CloseConnection(QUIC_INVALID_STREAM_ID,
1562 "Stream id 24 would exceed stream count limit 6", _));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001563 } else {
1564 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1565 EXPECT_CALL(*connection_,
1566 OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
1567 .Times(1);
1568 }
1569 // Create one more data streams to exceed limit of open stream.
1570 QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
1571 session_.OnStreamFrame(data1);
1572}
1573
1574TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
1575 // Verify that a draining stream (which has received a FIN but not consumed
1576 // it) does not count against the open quota (because it is closed from the
1577 // protocol point of view).
1578 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1579 QuicStreamId stream_id = stream->id();
1580 QuicStreamFrame data1(stream_id, true, 0, QuicStringPiece("HT"));
1581 session_.OnStreamFrame(data1);
1582 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream()).Times(1);
1583 session_.StreamDraining(stream_id);
1584}
1585
1586TEST_P(QuicSessionTestServer, NoPendingStreams) {
renjietange76b2da2019-05-13 14:50:23 -07001587 session_.set_uses_pending_streams(false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001588
1589 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1590 transport_version(), Perspective::IS_CLIENT);
1591 QuicStreamFrame data1(stream_id, true, 10, QuicStringPiece("HT"));
1592 session_.OnStreamFrame(data1);
1593 EXPECT_EQ(1, session_.num_incoming_streams_created());
1594
1595 QuicStreamFrame data2(stream_id, false, 0, QuicStringPiece("HT"));
1596 session_.OnStreamFrame(data2);
1597 EXPECT_EQ(1, session_.num_incoming_streams_created());
1598}
1599
1600TEST_P(QuicSessionTestServer, PendingStreams) {
1601 if (connection_->transport_version() != QUIC_VERSION_99) {
1602 return;
1603 }
renjietange76b2da2019-05-13 14:50:23 -07001604 session_.set_uses_pending_streams(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001605
1606 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1607 transport_version(), Perspective::IS_CLIENT);
1608 QuicStreamFrame data1(stream_id, true, 10, QuicStringPiece("HT"));
1609 session_.OnStreamFrame(data1);
1610 EXPECT_EQ(0, session_.num_incoming_streams_created());
1611
1612 QuicStreamFrame data2(stream_id, false, 0, QuicStringPiece("HT"));
1613 session_.OnStreamFrame(data2);
1614 EXPECT_EQ(1, session_.num_incoming_streams_created());
1615}
1616
1617TEST_P(QuicSessionTestServer, RstPendingStreams) {
1618 if (connection_->transport_version() != QUIC_VERSION_99) {
1619 return;
1620 }
renjietange76b2da2019-05-13 14:50:23 -07001621 session_.set_uses_pending_streams(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001622
1623 QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1624 transport_version(), Perspective::IS_CLIENT);
1625 QuicStreamFrame data1(stream_id, true, 10, QuicStringPiece("HT"));
1626 session_.OnStreamFrame(data1);
1627 EXPECT_EQ(0, session_.num_incoming_streams_created());
1628
1629 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream()).Times(1);
1630 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1631 EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_RST_ACKNOWLEDGEMENT))
1632 .Times(1);
1633 QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
1634 QUIC_ERROR_PROCESSING_STREAM, 12);
1635 session_.OnRstStream(rst1);
1636 EXPECT_EQ(0, session_.num_incoming_streams_created());
1637
1638 QuicStreamFrame data2(stream_id, false, 0, QuicStringPiece("HT"));
1639 session_.OnStreamFrame(data2);
1640 EXPECT_EQ(0, session_.num_incoming_streams_created());
1641}
1642
1643TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
1644 // Verify that a draining stream (which has received a FIN but not consumed
1645 // it) does not count against the open quota (because it is closed from the
1646 // protocol point of view).
1647 if (transport_version() == QUIC_VERSION_99) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07001648 // On v99, we will expect to see a MAX_STREAMS go out when there are not
QUICHE teama6ef0a62019-03-07 20:34:33 -05001649 // enough streams to create the next one.
1650 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1651 } else {
1652 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1653 }
1654 EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
1655 const QuicStreamId kMaxStreams = 5;
1656 QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
1657
1658 // Create kMaxStreams + 1 data streams, and mark them draining.
1659 const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
1660 const QuicStreamId kFinalStreamId =
1661 GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
1662 for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
1663 i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
1664 QuicStreamFrame data1(i, true, 0, QuicStringPiece("HT"));
1665 session_.OnStreamFrame(data1);
1666 EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
1667 session_.StreamDraining(i);
1668 EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
1669 }
1670}
1671
1672class QuicSessionTestClient : public QuicSessionTestBase {
1673 protected:
1674 QuicSessionTestClient() : QuicSessionTestBase(Perspective::IS_CLIENT) {}
1675};
1676
1677INSTANTIATE_TEST_SUITE_P(Tests,
1678 QuicSessionTestClient,
1679 ::testing::ValuesIn(AllSupportedVersions()));
1680
1681TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
1682 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1683 GetNthServerInitiatedBidirectionalId(2)) != nullptr);
1684 // Smaller bidirectional streams should be available.
1685 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1686 &session_, GetNthServerInitiatedBidirectionalId(0)));
1687 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1688 &session_, GetNthServerInitiatedBidirectionalId(1)));
1689 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1690 GetNthServerInitiatedBidirectionalId(0)) != nullptr);
1691 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1692 GetNthServerInitiatedBidirectionalId(1)) != nullptr);
1693 // And 5 should be not available.
1694 EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
1695 &session_, GetNthClientInitiatedBidirectionalId(1)));
1696}
1697
1698TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
1699 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1700 GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
1701 // Smaller unidirectional streams should be available.
1702 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1703 &session_, GetNthServerInitiatedUnidirectionalId(0)));
1704 EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1705 &session_, GetNthServerInitiatedUnidirectionalId(1)));
1706 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1707 GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
1708 ASSERT_TRUE(session_.GetOrCreateDynamicStream(
1709 GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
1710 // And 5 should be not available.
1711 EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
1712 &session_, GetNthClientInitiatedUnidirectionalId(1)));
1713}
1714
1715TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
1716 // Verify that an incoming FIN is recorded in a stream object even if the read
1717 // side has been closed. This prevents an entry from being made in
1718 // locally_closed_streams_highest_offset_ (which will never be deleted).
1719 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1720 QuicStreamId stream_id = stream->id();
1721
1722 // Close the read side manually.
1723 QuicStreamPeer::CloseReadSide(stream);
1724
1725 // Receive a stream data frame with FIN.
1726 QuicStreamFrame frame(stream_id, true, 0, QuicStringPiece());
1727 session_.OnStreamFrame(frame);
1728 EXPECT_TRUE(stream->fin_received());
1729
1730 // Reset stream locally.
1731 EXPECT_CALL(*connection_, SendControlFrame(_));
1732 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1733 stream->Reset(QUIC_STREAM_CANCELLED);
1734 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
1735
1736 EXPECT_TRUE(connection_->connected());
1737 EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
1738 EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
1739
1740 // The stream is not waiting for the arrival of the peer's final offset as it
1741 // was received with the FIN earlier.
1742 EXPECT_EQ(
1743 0u,
1744 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
1745}
1746
1747TEST_P(QuicSessionTestServer, ZombieStreams) {
1748 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1749 QuicStreamPeer::SetStreamBytesWritten(3, stream2);
1750 EXPECT_TRUE(stream2->IsWaitingForAcks());
1751
1752 EXPECT_CALL(*connection_, SendControlFrame(_));
1753 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
1754 session_.CloseStream(stream2->id());
1755 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
1756 ASSERT_EQ(1u, session_.closed_streams()->size());
1757 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
1758 session_.OnStreamDoneWaitingForAcks(stream2->id());
1759 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
1760 EXPECT_EQ(1u, session_.closed_streams()->size());
1761 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
1762}
1763
1764TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
1765 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1766 QuicStreamPeer::SetStreamBytesWritten(3, stream2);
1767 EXPECT_TRUE(stream2->IsWaitingForAcks());
1768
1769 EXPECT_CALL(*connection_, SendControlFrame(_));
1770 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
1771 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream()).Times(0);
1772 stream2->Reset(quic::QUIC_STREAM_CANCELLED);
1773
1774 QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
1775 QUIC_ERROR_PROCESSING_STREAM, 0);
1776 if (transport_version() != QUIC_VERSION_99) {
1777 EXPECT_CALL(session_, OnCanCreateNewOutgoingStream()).Times(1);
1778 }
1779 session_.OnRstStream(rst1);
1780}
1781
1782// Regression test of b/71548958.
1783TEST_P(QuicSessionTestServer, TestZombieStreams) {
1784 session_.set_writev_consumes_all_data(true);
1785
1786 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
vasilvvc48c8712019-03-11 13:38:16 -07001787 std::string body(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001788 stream2->WriteOrBufferData(body, false, nullptr);
1789 EXPECT_TRUE(stream2->IsWaitingForAcks());
1790 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
1791
1792 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
1793 QUIC_STREAM_CANCELLED, 1234);
1794 // Just for the RST_STREAM
1795 EXPECT_CALL(*connection_, SendControlFrame(_))
1796 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1797 if (transport_version() == QUIC_VERSION_99) {
1798 EXPECT_CALL(*connection_,
1799 OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
1800 } else {
1801 EXPECT_CALL(*connection_,
1802 OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
1803 }
1804 stream2->OnStreamReset(rst_frame);
1805
1806 if (transport_version() == QUIC_VERSION_99) {
1807 // The test is predicated on the stream being fully closed. For V99, the
1808 // RST_STREAM only does one side (the read side from the perspective of the
1809 // node receiving the RST_STREAM). This is needed to fully close the
1810 // stream and therefore fulfill all of the expects.
1811 QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
1812 QUIC_STREAM_CANCELLED);
1813 EXPECT_TRUE(session_.OnStopSendingFrame(frame));
1814 }
1815 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
1816 ASSERT_EQ(1u, session_.closed_streams()->size());
1817 EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
1818
1819 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1820 if (transport_version() == QUIC_VERSION_99) {
1821 // Once for the RST_STREAM, once for the STOP_SENDING
1822 EXPECT_CALL(*connection_, SendControlFrame(_))
1823 .Times(2)
1824 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
1825 } else {
1826 // Just for the RST_STREAM
1827 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1828 }
1829 EXPECT_CALL(*connection_,
1830 OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
1831 stream4->WriteOrBufferData(body, false, nullptr);
1832 // Note well: Reset() actually closes the stream in both directions. For
1833 // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
1834 // QUIC/V99 it sends both a RST_STREAM and a STOP_SENDING (each of which
1835 // closes in only one direction).
1836 stream4->Reset(QUIC_STREAM_CANCELLED);
1837 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
1838 EXPECT_EQ(2u, session_.closed_streams()->size());
1839}
1840
1841TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
1842 QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
1843 InSequence s;
1844
1845 // Drive congestion control manually.
1846 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1847 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1848
1849 TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
1850 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1851 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1852
1853 QuicStreamFrame frame1(
1854 QuicUtils::GetCryptoStreamId(connection_->transport_version()), false, 0,
1855 1300);
1856 QuicStreamFrame frame2(stream2->id(), false, 0, 9);
1857 QuicStreamFrame frame3(stream4->id(), false, 0, 9);
1858
1859 // Lost data on cryption stream, streams 2 and 4.
1860 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
QUICHE teamea740082019-03-11 17:58:43 -07001861 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001862 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
1863 .WillOnce(Return(true));
1864 }
1865 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
1866 session_.OnFrameLost(QuicFrame(frame3));
QUICHE teamea740082019-03-11 17:58:43 -07001867 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001868 session_.OnFrameLost(QuicFrame(frame1));
1869 } else {
QUICHE team6987b4a2019-03-15 16:23:04 -07001870 QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001871 session_.OnFrameLost(QuicFrame(&crypto_frame));
1872 }
1873 session_.OnFrameLost(QuicFrame(frame2));
1874 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1875
1876 // Mark streams 2 and 4 write blocked.
1877 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1878 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1879
1880 // Lost data is retransmitted before new data, and retransmissions for crypto
1881 // stream go first.
1882 // Do not check congestion window when crypto stream has lost data.
1883 EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
QUICHE teamea740082019-03-11 17:58:43 -07001884 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001885 EXPECT_CALL(*crypto_stream, OnCanWrite());
1886 EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
1887 .WillOnce(Return(false));
1888 }
1889 // Check congestion window for non crypto streams.
1890 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1891 EXPECT_CALL(*stream4, OnCanWrite());
1892 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
1893 // Connection is blocked.
1894 EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
1895
1896 session_.OnCanWrite();
1897 EXPECT_TRUE(session_.WillingAndAbleToWrite());
1898
1899 // Unblock connection.
1900 // Stream 2 retransmits lost data.
1901 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1902 EXPECT_CALL(*stream2, OnCanWrite());
1903 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
1904 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1905 // Stream 2 sends new data.
1906 EXPECT_CALL(*stream2, OnCanWrite());
1907 EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
1908 EXPECT_CALL(*stream4, OnCanWrite());
1909 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1910
1911 session_.OnCanWrite();
1912 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1913}
1914
1915TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
1916 QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
1917 InSequence s;
1918
1919 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1920 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1921 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1922
1923 QuicStreamFrame frame1(stream2->id(), false, 0, 9);
1924 QuicStreamFrame frame2(stream4->id(), false, 0, 9);
1925 QuicStreamFrame frame3(stream6->id(), false, 0, 9);
1926
1927 EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
1928 EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
1929 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
1930 session_.OnFrameLost(QuicFrame(frame3));
1931 session_.OnFrameLost(QuicFrame(frame2));
1932 session_.OnFrameLost(QuicFrame(frame1));
1933
1934 session_.MarkConnectionLevelWriteBlocked(stream2->id());
1935 session_.MarkConnectionLevelWriteBlocked(stream4->id());
1936 session_.MarkConnectionLevelWriteBlocked(stream6->id());
1937
1938 // Reset stream 4 locally.
1939 EXPECT_CALL(*connection_, SendControlFrame(_));
1940 EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
1941 stream4->Reset(QUIC_STREAM_CANCELLED);
1942
1943 // Verify stream 4 is removed from streams with lost data list.
1944 EXPECT_CALL(*stream6, OnCanWrite());
1945 EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
1946 EXPECT_CALL(*stream2, OnCanWrite());
1947 EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
1948 EXPECT_CALL(*connection_, SendControlFrame(_))
1949 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
1950 EXPECT_CALL(*stream2, OnCanWrite());
1951 EXPECT_CALL(*stream6, OnCanWrite());
1952 session_.OnCanWrite();
1953}
1954
1955TEST_P(QuicSessionTestServer, RetransmitFrames) {
1956 QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
1957 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1958 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
1959 InSequence s;
1960
1961 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
1962 TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
1963 TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
1964 EXPECT_CALL(*connection_, SendControlFrame(_))
1965 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1966 session_.SendWindowUpdate(stream2->id(), 9);
1967
1968 QuicStreamFrame frame1(stream2->id(), false, 0, 9);
1969 QuicStreamFrame frame2(stream4->id(), false, 0, 9);
1970 QuicStreamFrame frame3(stream6->id(), false, 0, 9);
1971 QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
1972 QuicFrames frames;
1973 frames.push_back(QuicFrame(frame1));
1974 frames.push_back(QuicFrame(&window_update));
1975 frames.push_back(QuicFrame(frame2));
1976 frames.push_back(QuicFrame(frame3));
1977 EXPECT_FALSE(session_.WillingAndAbleToWrite());
1978
1979 EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
1980 EXPECT_CALL(*connection_, SendControlFrame(_))
1981 .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
1982 EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
1983 EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
1984 EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1985 session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
1986}
1987
1988// Regression test of b/110082001.
1989TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
1990 // This test mimics the scenario when a dynamic stream retransmits lost data
1991 // and causes connection close.
1992 QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
1993 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
1994 QuicStreamFrame frame(stream->id(), false, 0, 9);
1995
1996 EXPECT_CALL(*stream, HasPendingRetransmission())
1997 .Times(2)
1998 .WillOnce(Return(true))
1999 .WillOnce(Return(false));
2000 session_.OnFrameLost(QuicFrame(frame));
2001 // Retransmit stream data causes connection close. Stream has not sent fin
2002 // yet, so an RST is sent.
2003 EXPECT_CALL(*stream, OnCanWrite())
2004 .WillOnce(Invoke(stream, &QuicStream::OnClose));
2005 if (transport_version() == QUIC_VERSION_99) {
2006 // Once for the RST_STREAM, once for the STOP_SENDING
2007 EXPECT_CALL(*connection_, SendControlFrame(_))
2008 .Times(2)
2009 .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
2010 } else {
2011 // Just for the RST_STREAM
2012 EXPECT_CALL(*connection_, SendControlFrame(_))
2013 .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
2014 }
2015 EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
2016 session_.OnCanWrite();
2017}
2018
2019TEST_P(QuicSessionTestServer, SendMessage) {
2020 // Cannot send message when encryption is not established.
2021 EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
2022 quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
2023 EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
2024 session_.SendMessage(
2025 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2026 "", &storage)));
2027
2028 // Finish handshake.
2029 CryptoHandshakeMessage handshake_message;
2030 session_.GetMutableCryptoStream()->OnHandshakeMessage(handshake_message);
2031 EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
2032
2033 QuicStringPiece message;
2034 EXPECT_CALL(*connection_, SendMessage(1, _))
2035 .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
2036 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
2037 session_.SendMessage(
2038 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2039 message, &storage)));
2040 // Verify message_id increases.
2041 EXPECT_CALL(*connection_, SendMessage(2, _))
2042 .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
2043 EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
2044 session_.SendMessage(
2045 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2046 message, &storage)));
2047 // Verify unsent message does not consume a message_id.
2048 EXPECT_CALL(*connection_, SendMessage(2, _))
2049 .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
2050 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
2051 session_.SendMessage(
2052 MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(),
2053 message, &storage)));
2054
2055 QuicMessageFrame frame(1);
2056 QuicMessageFrame frame2(2);
2057 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
2058 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
2059
2060 // Lost message 2.
2061 session_.OnMessageLost(2);
2062 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
2063
2064 // message 1 gets acked.
2065 session_.OnMessageAcked(1);
2066 EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
2067}
2068
2069// Regression test of b/115323618.
2070TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
2071 QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
2072
2073 session_.set_writev_consumes_all_data(true);
2074 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
vasilvvc48c8712019-03-11 13:38:16 -07002075 std::string body(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002076 stream2->CloseReadSide();
2077 stream2->WriteOrBufferData(body, true, nullptr);
2078 EXPECT_TRUE(stream2->IsWaitingForAcks());
2079 // Verify stream2 is a zombie streams.
2080 EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2081
2082 QuicStreamFrame frame(stream2->id(), true, 0, 100);
2083 EXPECT_CALL(*stream2, HasPendingRetransmission())
2084 .WillRepeatedly(Return(true));
2085 session_.OnFrameLost(QuicFrame(frame));
2086
2087 // Reset stream2 locally.
2088 EXPECT_CALL(*connection_, SendControlFrame(_))
2089 .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
2090 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2091 stream2->Reset(QUIC_STREAM_CANCELLED);
2092
2093 // Verify stream 2 gets closed.
2094 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2095 EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
2096 EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
2097 session_.OnCanWrite();
2098}
2099
2100TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
2101 EXPECT_FALSE(
2102 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
2103
2104 session_.set_writev_consumes_all_data(true);
2105 TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
2106 EXPECT_FALSE(stream2->IsWaitingForAcks());
2107
2108 EXPECT_CALL(*connection_, SendControlFrame(_));
2109 EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
2110 session_.CloseStream(stream2->id());
2111 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
2112 EXPECT_EQ(1u, session_.closed_streams()->size());
2113 EXPECT_TRUE(
2114 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
2115
2116 alarm_factory_.FireAlarm(
2117 QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
2118 EXPECT_TRUE(session_.closed_streams()->empty());
2119}
2120
2121TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
2122 session_.set_writev_consumes_all_data(true);
2123 TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
2124 &session_, WRITE_UNIDIRECTIONAL);
2125 session_.ActivateStream(QuicWrapUnique(stream4));
vasilvvc48c8712019-03-11 13:38:16 -07002126 std::string body(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002127 stream4->WriteOrBufferData(body, false, nullptr);
2128 EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
2129 stream4->WriteOrBufferData(body, true, nullptr);
2130 EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
2131}
2132
2133TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
2134 TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
2135 &session_, WRITE_UNIDIRECTIONAL);
2136 session_.ActivateStream(QuicWrapUnique(stream4));
2137
2138 EXPECT_CALL(
2139 *connection_,
2140 CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
2141 .Times(1);
2142 QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
2143 0, 2);
2144 session_.OnStreamFrame(stream_frame);
2145}
2146
2147TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
2148 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2149 &session_, READ_UNIDIRECTIONAL);
2150 session_.ActivateStream(QuicWrapUnique(stream4));
2151 EXPECT_FALSE(stream4->IsWaitingForAcks());
2152 // Discard all incoming data.
2153 stream4->StopReading();
2154
vasilvvc48c8712019-03-11 13:38:16 -07002155 std::string data(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002156 QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
2157 0, data);
2158 stream4->OnStreamFrame(stream_frame);
2159 EXPECT_TRUE(session_.closed_streams()->empty());
2160
2161 QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
2162 100, data);
2163 stream4->OnStreamFrame(stream_frame2);
2164 EXPECT_EQ(1u, session_.closed_streams()->size());
2165}
2166
2167TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
2168 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2169 &session_, READ_UNIDIRECTIONAL);
2170 session_.ActivateStream(QuicWrapUnique(stream4));
2171
2172 EXPECT_CALL(*connection_,
2173 CloseConnection(
2174 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2175 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -07002176 std::string body(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002177 stream4->WriteOrBufferData(body, false, nullptr);
2178}
2179
2180TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
2181 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2182 &session_, READ_UNIDIRECTIONAL);
2183 session_.ActivateStream(QuicWrapUnique(stream4));
2184
2185 EXPECT_CALL(*connection_,
2186 CloseConnection(
2187 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2188 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -07002189 std::string body(100, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002190 struct iovec iov = {const_cast<char*>(body.data()), body.length()};
2191 QuicMemSliceStorage storage(
2192 &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
2193 1024);
2194 stream4->WriteMemSlices(storage.ToSpan(), false);
2195}
2196
2197TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
2198 TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
2199 &session_, READ_UNIDIRECTIONAL);
2200 session_.ActivateStream(QuicWrapUnique(stream4));
2201
2202 EXPECT_CALL(*connection_,
2203 CloseConnection(
2204 QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
2205 .Times(1);
2206 char data[1024];
2207 std::vector<std::pair<char*, size_t>> buffers;
2208 buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
2209 buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
2210 QuicTestMemSliceVector vector(buffers);
2211 stream4->WriteMemSlices(vector.span(), false);
2212}
2213
2214// Test code that tests that an incoming stream frame with a new (not previously
2215// seen) stream id is acceptable. The ID must not be larger than has been
2216// advertised. It may be equal to what has been advertised. These tests
2217// invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
2218// QuicSession::OnStreamFrame in order to check that all the steps are connected
2219// properly and that nothing in the call path interferes with the check.
2220// First test make sure that streams with ids below the limit are accepted.
2221TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
2222 if (transport_version() != QUIC_VERSION_99) {
2223 // Applicable only to V99
2224 return;
2225 }
fkastenholz3c4eabf2019-04-22 07:49:59 -07002226 QuicStreamId bidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002227 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002228 ->advertised_max_allowed_incoming_bidirectional_streams() -
2229 1,
2230 Perspective::IS_CLIENT,
2231 /*bidirectional=*/true);
2232
QUICHE teama6ef0a62019-03-07 20:34:33 -05002233 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2234 "Random String");
2235 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2236 session_.OnStreamFrame(bidirectional_stream_frame);
2237
fkastenholz3c4eabf2019-04-22 07:49:59 -07002238 QuicStreamId unidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002239 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002240 ->advertised_max_allowed_incoming_unidirectional_streams() -
2241 1,
2242 Perspective::IS_CLIENT,
2243 /*bidirectional=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002244 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2245 0, "Random String");
2246 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2247 session_.OnStreamFrame(unidirectional_stream_frame);
2248}
2249
2250// Accept a stream with an ID that equals the limit.
2251TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
2252 if (transport_version() != QUIC_VERSION_99) {
2253 // Applicable only to V99
2254 return;
2255 }
fkastenholz3c4eabf2019-04-22 07:49:59 -07002256 QuicStreamId bidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002257 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002258 ->advertised_max_allowed_incoming_bidirectional_streams(),
2259 Perspective::IS_CLIENT, /*bidirectional=*/true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002260 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2261 "Random String");
2262 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2263 session_.OnStreamFrame(bidirectional_stream_frame);
2264
fkastenholz3c4eabf2019-04-22 07:49:59 -07002265 QuicStreamId unidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002266 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002267 ->advertised_max_allowed_incoming_unidirectional_streams(),
2268 Perspective::IS_CLIENT, /*bidirectional=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002269 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2270 0, "Random String");
2271 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2272 session_.OnStreamFrame(unidirectional_stream_frame);
2273}
2274
2275// Close the connection if the id exceeds the limit.
2276TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
2277 if (transport_version() != QUIC_VERSION_99) {
2278 // Applicable only to V99
2279 return;
2280 }
fkastenholz3c4eabf2019-04-22 07:49:59 -07002281 QuicStreamId bidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002282 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002283 ->advertised_max_allowed_incoming_bidirectional_streams() +
2284 1,
2285 Perspective::IS_CLIENT, /*bidirectional=*/true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002286 QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
2287 "Random String");
fkastenholz3c4eabf2019-04-22 07:49:59 -07002288 EXPECT_CALL(
2289 *connection_,
2290 CloseConnection(QUIC_INVALID_STREAM_ID,
2291 "Stream id 404 would exceed stream count limit 101", _));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002292 session_.OnStreamFrame(bidirectional_stream_frame);
2293
fkastenholz3c4eabf2019-04-22 07:49:59 -07002294 QuicStreamId unidirectional_stream_id = StreamCountToId(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002295 QuicSessionPeer::v99_streamid_manager(&session_)
fkastenholz3c4eabf2019-04-22 07:49:59 -07002296 ->advertised_max_allowed_incoming_unidirectional_streams() +
2297 1,
2298 Perspective::IS_CLIENT, /*bidirectional=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002299 QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
2300 0, "Random String");
fkastenholz3c4eabf2019-04-22 07:49:59 -07002301 EXPECT_CALL(
2302 *connection_,
2303 CloseConnection(QUIC_INVALID_STREAM_ID,
2304 "Stream id 402 would exceed stream count limit 100", _));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002305 session_.OnStreamFrame(unidirectional_stream_frame);
2306}
2307
2308// Check that the OnStopSendingFrame upcall handles bad input properly
2309// First test checks that invalid stream ids are handled.
2310TEST_P(QuicSessionTestServer, OnStopSendingInputInvalidStreamId) {
2311 if (transport_version() != QUIC_VERSION_99) {
2312 // Applicable only to V99
2313 return;
2314 }
2315 // Check that "invalid" stream ids are rejected.
2316 // Note that the notion of an invalid stream id is Google-specific.
2317 QuicStopSendingFrame frame(1, -1, 123);
2318 EXPECT_CALL(
2319 *connection_,
2320 CloseConnection(QUIC_INVALID_STREAM_ID,
2321 "Received STOP_SENDING for an invalid stream", _));
2322 EXPECT_FALSE(session_.OnStopSendingFrame(frame));
2323}
2324
2325// Second test, streams in the static stream map are not subject to
2326// STOP_SENDING; it's ignored.
2327TEST_P(QuicSessionTestServer, OnStopSendingInputStaticStreams) {
2328 if (transport_version() != QUIC_VERSION_99) {
2329 // Applicable only to V99
2330 return;
2331 }
2332 // Check that a stream id in the static stream map is ignored.
2333 // Note that the notion of a static stream is Google-specific.
2334 QuicStopSendingFrame frame(1, 0, 123);
2335 EXPECT_CALL(*connection_,
2336 CloseConnection(QUIC_INVALID_STREAM_ID,
2337 "Received STOP_SENDING for a static stream", _));
2338 EXPECT_FALSE(session_.OnStopSendingFrame(frame));
2339}
2340
2341// Third test, if stream id specifies a closed stream:
2342// return true and do not close the connection.
2343TEST_P(QuicSessionTestServer, OnStopSendingInputClosedStream) {
2344 if (transport_version() != QUIC_VERSION_99) {
2345 // Applicable only to V99
2346 return;
2347 }
2348
2349 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2350 QuicStreamId stream_id = stream->id();
2351 // Expect these as side effect of the close operations.
2352 EXPECT_CALL(*connection_, SendControlFrame(_));
2353 EXPECT_CALL(*connection_, OnStreamReset(_, _));
2354 stream->CloseWriteSide();
2355 stream->CloseReadSide();
2356 QuicStopSendingFrame frame(1, stream_id, 123);
2357 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2358 EXPECT_TRUE(session_.OnStopSendingFrame(frame));
2359}
2360
2361// Fourth test, if stream id specifies a nonexistent stream, return false and
2362// close the connection
2363TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentStream) {
2364 if (transport_version() != QUIC_VERSION_99) {
2365 // Applicable only to V99
2366 return;
2367 }
2368
2369 QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
2370 123);
2371 EXPECT_CALL(
2372 *connection_,
2373 CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
2374 "Received STOP_SENDING for a non-existent stream", _))
2375 .Times(1);
2376 EXPECT_FALSE(session_.OnStopSendingFrame(frame));
2377}
2378
2379// For a valid stream, ensure that all works
2380TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
2381 if (transport_version() != QUIC_VERSION_99) {
2382 // Applicable only to V99
2383 return;
2384 }
2385
2386 TestStream* stream = session_.CreateOutgoingBidirectionalStream();
2387
2388 // Ensure that the stream starts out open in both directions.
bncc7d9e0c2019-04-16 10:22:15 -07002389 EXPECT_FALSE(stream->write_side_closed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002390 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
2391
2392 QuicStreamId stream_id = stream->id();
2393 QuicStopSendingFrame frame(1, stream_id, 123);
2394 EXPECT_CALL(*stream, OnStopSending(123));
2395 // Expect a reset to come back out.
2396 EXPECT_CALL(*connection_, SendControlFrame(_));
2397 EXPECT_CALL(
2398 *connection_,
2399 OnStreamReset(stream_id, static_cast<QuicRstStreamErrorCode>(123)));
2400 EXPECT_TRUE(session_.OnStopSendingFrame(frame));
2401 // When the STOP_SENDING is received, the node generates a RST_STREAM,
2402 // which closes the stream in the write direction. Ensure this.
2403 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
bncc7d9e0c2019-04-16 10:22:15 -07002404 EXPECT_TRUE(stream->write_side_closed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002405}
2406
2407} // namespace
2408} // namespace test
2409} // namespace quic