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