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