blob: 3b55314fcd7f41b3fd4457e8ea9da76d5418082d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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/quartc/quartc_session.h"
6
QUICHE teama6ef0a62019-03-07 20:34:33 -05007#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
8#include "net/third_party/quiche/src/quic/core/quic_types.h"
9#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
10#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
16#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h"
17#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
18#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
19#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
20#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
21#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
22#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h"
23#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
24
25namespace quic {
26
27namespace {
28
QUICHE team68d15a82019-05-31 15:27:25 -070029using ::testing::ElementsAre;
30using ::testing::ElementsAreArray;
31using ::testing::Gt;
32using ::testing::Pair;
33
QUICHE teama6ef0a62019-03-07 20:34:33 -050034constexpr QuicTime::Delta kPropagationDelay =
35 QuicTime::Delta::FromMilliseconds(10);
36// Propagation delay and a bit, but no more than full RTT.
37constexpr QuicTime::Delta kPropagationDelayAndABit =
38 QuicTime::Delta::FromMilliseconds(12);
39
40static QuicByteCount kDefaultMaxPacketSize = 1200;
41
QUICHE team7eef0712019-05-09 09:42:38 -070042test::QuicTestMemSliceVector CreateMemSliceVector(QuicStringPiece data) {
43 return test::QuicTestMemSliceVector(
44 {std::pair<char*, size_t>(const_cast<char*>(data.data()), data.size())});
45}
46
QUICHE teama6ef0a62019-03-07 20:34:33 -050047class QuartcSessionTest : public QuicTest {
48 public:
49 ~QuartcSessionTest() override {}
50
51 void Init(bool create_client_endpoint = true) {
52 client_transport_ =
53 QuicMakeUnique<simulator::SimulatedQuartcPacketTransport>(
54 &simulator_, "client_transport", "server_transport",
55 10 * kDefaultMaxPacketSize);
56 server_transport_ =
57 QuicMakeUnique<simulator::SimulatedQuartcPacketTransport>(
58 &simulator_, "server_transport", "client_transport",
59 10 * kDefaultMaxPacketSize);
60
61 client_filter_ = QuicMakeUnique<simulator::CountingPacketFilter>(
62 &simulator_, "client_filter", client_transport_.get());
63
64 client_server_link_ = QuicMakeUnique<simulator::SymmetricLink>(
65 client_filter_.get(), server_transport_.get(),
66 QuicBandwidth::FromKBitsPerSecond(10 * 1000), kPropagationDelay);
67
68 client_stream_delegate_ = QuicMakeUnique<FakeQuartcStreamDelegate>();
QUICHE team6939de52019-05-15 12:05:21 -070069 client_session_delegate_ = QuicMakeUnique<FakeQuartcEndpointDelegate>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050070 client_stream_delegate_.get(), simulator_.GetClock());
QUICHE teama6ef0a62019-03-07 20:34:33 -050071
72 server_stream_delegate_ = QuicMakeUnique<FakeQuartcStreamDelegate>();
QUICHE team6939de52019-05-15 12:05:21 -070073 server_session_delegate_ = QuicMakeUnique<FakeQuartcEndpointDelegate>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 server_stream_delegate_.get(), simulator_.GetClock());
QUICHE teama6ef0a62019-03-07 20:34:33 -050075
76 // No 0-rtt setup, because server config is empty.
77 // CannotCreateDataStreamBeforeHandshake depends on 1-rtt setup.
78 if (create_client_endpoint) {
79 client_endpoint_ = QuicMakeUnique<QuartcClientEndpoint>(
80 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -070081 simulator_.GetRandomGenerator(), client_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -070082 quic::QuartcSessionConfig(),
QUICHE teama6ef0a62019-03-07 20:34:33 -050083 /*serialized_server_config=*/"");
84 }
85 server_endpoint_ = QuicMakeUnique<QuartcServerEndpoint>(
86 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -070087 simulator_.GetRandomGenerator(), server_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -070088 quic::QuartcSessionConfig());
QUICHE teama6ef0a62019-03-07 20:34:33 -050089 }
90
91 // Note that input session config will apply to both server and client.
92 // Perspective and packet_transport will be overwritten.
dschinazi17d42422019-06-18 16:35:07 -070093 void CreateClientAndServerSessions(
94 const QuartcSessionConfig& /*session_config*/,
95 bool init = true) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050096 if (init) {
97 Init();
98 }
99
100 server_endpoint_->Connect(server_transport_.get());
101 client_endpoint_->Connect(client_transport_.get());
102
103 CHECK(simulator_.RunUntil([this] {
QUICHE team6939de52019-05-15 12:05:21 -0700104 return client_session_delegate_->session() != nullptr &&
105 server_session_delegate_->session() != nullptr;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 }));
107
QUICHE team6939de52019-05-15 12:05:21 -0700108 client_peer_ = client_session_delegate_->session();
109 server_peer_ = server_session_delegate_->session();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 }
111
112 // Runs all tasks scheduled in the next 200 ms.
113 void RunTasks() { simulator_.RunFor(QuicTime::Delta::FromMilliseconds(200)); }
114
115 void AwaitHandshake() {
116 simulator_.RunUntil([this] {
117 return client_peer_->IsCryptoHandshakeConfirmed() &&
118 server_peer_->IsCryptoHandshakeConfirmed();
119 });
120 }
121
122 // Test handshake establishment and sending/receiving of data for two
123 // directions.
124 void TestSendReceiveStreams() {
125 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
126 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
127 ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
128 ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
129
130 // Now we can establish encrypted outgoing stream.
131 QuartcStream* outgoing_stream =
132 server_peer_->CreateOutgoingBidirectionalStream();
133 QuicStreamId stream_id = outgoing_stream->id();
134 ASSERT_NE(nullptr, outgoing_stream);
135 EXPECT_TRUE(server_peer_->ShouldKeepConnectionAlive());
136
137 outgoing_stream->SetDelegate(server_stream_delegate_.get());
138
139 // Send a test message from peer 1 to peer 2.
QUICHE team7eef0712019-05-09 09:42:38 -0700140 test::QuicTestMemSliceVector data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141 outgoing_stream->WriteMemSlices(data.span(), /*fin=*/false);
142 RunTasks();
143
144 // Wait for peer 2 to receive messages.
145 ASSERT_TRUE(client_stream_delegate_->has_data());
146
147 QuartcStream* incoming = client_session_delegate_->last_incoming_stream();
148 ASSERT_TRUE(incoming);
149 EXPECT_EQ(incoming->id(), stream_id);
150 EXPECT_TRUE(client_peer_->ShouldKeepConnectionAlive());
151
QUICHE team7eef0712019-05-09 09:42:38 -0700152 EXPECT_EQ(client_stream_delegate_->data()[stream_id], "Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153 // Send a test message from peer 2 to peer 1.
QUICHE team7eef0712019-05-09 09:42:38 -0700154 test::QuicTestMemSliceVector response = CreateMemSliceVector("Response");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500155 incoming->WriteMemSlices(response.span(), /*fin=*/false);
156 RunTasks();
157 // Wait for peer 1 to receive messages.
158 ASSERT_TRUE(server_stream_delegate_->has_data());
159
QUICHE team7eef0712019-05-09 09:42:38 -0700160 EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Response");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161 }
162
163 // Test sending/receiving of messages for two directions.
164 void TestSendReceiveMessage() {
165 ASSERT_TRUE(server_peer_->CanSendMessage());
166 ASSERT_TRUE(client_peer_->CanSendMessage());
167
QUICHE team136e7852019-05-13 14:10:34 -0700168 int64_t server_datagram_id = 111;
169 int64_t client_datagram_id = 222;
170
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 // Send message from peer 1 to peer 2.
QUICHE team7eef0712019-05-09 09:42:38 -0700172 test::QuicTestMemSliceVector message =
173 CreateMemSliceVector("Message from server");
QUICHE team136e7852019-05-13 14:10:34 -0700174 ASSERT_TRUE(
175 server_peer_->SendOrQueueMessage(message.span(), server_datagram_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176
177 // First message in each direction should not be queued.
178 EXPECT_EQ(server_peer_->send_message_queue_size(), 0u);
179
180 // Wait for peer 2 to receive message.
181 RunTasks();
182
183 EXPECT_THAT(client_session_delegate_->incoming_messages(),
184 testing::ElementsAre("Message from server"));
185
QUICHE team136e7852019-05-13 14:10:34 -0700186 EXPECT_THAT(server_session_delegate_->sent_datagram_ids(),
187 testing::ElementsAre(server_datagram_id));
188
QUICHE team68d15a82019-05-31 15:27:25 -0700189 EXPECT_THAT(
190 server_session_delegate_->acked_datagram_id_to_receive_timestamp(),
191 ElementsAre(Pair(server_datagram_id, Gt(QuicTime::Zero()))));
QUICHE team34df5852019-05-29 16:27:22 -0700192
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193 // Send message from peer 2 to peer 1.
QUICHE team7eef0712019-05-09 09:42:38 -0700194 message = CreateMemSliceVector("Message from client");
QUICHE team136e7852019-05-13 14:10:34 -0700195 ASSERT_TRUE(
196 client_peer_->SendOrQueueMessage(message.span(), client_datagram_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197
198 // First message in each direction should not be queued.
199 EXPECT_EQ(client_peer_->send_message_queue_size(), 0u);
200
201 // Wait for peer 1 to receive message.
202 RunTasks();
203
204 EXPECT_THAT(server_session_delegate_->incoming_messages(),
205 testing::ElementsAre("Message from client"));
QUICHE team136e7852019-05-13 14:10:34 -0700206
207 EXPECT_THAT(client_session_delegate_->sent_datagram_ids(),
208 testing::ElementsAre(client_datagram_id));
QUICHE team34df5852019-05-29 16:27:22 -0700209
QUICHE team68d15a82019-05-31 15:27:25 -0700210 EXPECT_THAT(
211 client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
212 ElementsAre(Pair(client_datagram_id, Gt(QuicTime::Zero()))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213 }
214
215 // Test for sending multiple messages that also result in queueing.
216 // This is one-way test, which is run in given direction.
217 void TestSendReceiveQueuedMessages(bool direction_from_server) {
218 // Send until queue_size number of messages are queued.
219 constexpr size_t queue_size = 10;
220
221 ASSERT_TRUE(server_peer_->CanSendMessage());
222 ASSERT_TRUE(client_peer_->CanSendMessage());
223
224 QuartcSession* const peer_sending =
225 direction_from_server ? server_peer_ : client_peer_;
226
QUICHE team6939de52019-05-15 12:05:21 -0700227 FakeQuartcEndpointDelegate* const delegate_receiving =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228 direction_from_server ? client_session_delegate_.get()
229 : server_session_delegate_.get();
230
QUICHE team6939de52019-05-15 12:05:21 -0700231 FakeQuartcEndpointDelegate* const delegate_sending =
QUICHE team136e7852019-05-13 14:10:34 -0700232 direction_from_server ? server_session_delegate_.get()
233 : client_session_delegate_.get();
234
QUICHE teama6ef0a62019-03-07 20:34:33 -0500235 // There should be no messages in the queue before we start sending.
236 EXPECT_EQ(peer_sending->send_message_queue_size(), 0u);
237
238 // Send messages from peer 1 to peer 2 until required number of messages
239 // are queued in unsent message queue.
vasilvvc48c8712019-03-11 13:38:16 -0700240 std::vector<std::string> sent_messages;
QUICHE team136e7852019-05-13 14:10:34 -0700241 std::vector<int64_t> sent_datagram_ids;
242 int64_t current_datagram_id = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500243 while (peer_sending->send_message_queue_size() < queue_size) {
244 sent_messages.push_back(
245 QuicStrCat("Sending message, index=", sent_messages.size()));
QUICHE team7eef0712019-05-09 09:42:38 -0700246 ASSERT_TRUE(peer_sending->SendOrQueueMessage(
QUICHE team136e7852019-05-13 14:10:34 -0700247 CreateMemSliceVector(sent_messages.back()).span(),
248 current_datagram_id));
249
250 sent_datagram_ids.push_back(current_datagram_id);
251 ++current_datagram_id;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 }
253
254 // Wait for peer 2 to receive all messages.
255 RunTasks();
256
QUICHE team68d15a82019-05-31 15:27:25 -0700257 std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers;
258 for (int64_t id : sent_datagram_ids) {
259 ack_matchers.push_back(Pair(id, Gt(QuicTime::Zero())));
260 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261 EXPECT_EQ(delegate_receiving->incoming_messages(), sent_messages);
QUICHE team136e7852019-05-13 14:10:34 -0700262 EXPECT_EQ(delegate_sending->sent_datagram_ids(), sent_datagram_ids);
QUICHE team68d15a82019-05-31 15:27:25 -0700263 EXPECT_THAT(delegate_sending->acked_datagram_id_to_receive_timestamp(),
264 ElementsAreArray(ack_matchers));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500265 }
266
267 // Test sending long messages:
268 // - message of maximum allowed length should succeed
269 // - message of > maximum allowed length should fail.
270 void TestSendLongMessage() {
271 ASSERT_TRUE(server_peer_->CanSendMessage());
272 ASSERT_TRUE(client_peer_->CanSendMessage());
273
274 // Send message of maximum allowed length.
vasilvvc48c8712019-03-11 13:38:16 -0700275 std::string message_max_long =
ianswettb239f862019-04-05 09:15:06 -0700276 std::string(server_peer_->GetCurrentLargestMessagePayload(), 'A');
QUICHE team7eef0712019-05-09 09:42:38 -0700277 test::QuicTestMemSliceVector message =
278 CreateMemSliceVector(message_max_long);
QUICHE team136e7852019-05-13 14:10:34 -0700279 ASSERT_TRUE(
280 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281
282 // Send long message which should fail.
vasilvvc48c8712019-03-11 13:38:16 -0700283 std::string message_too_long =
ianswettb239f862019-04-05 09:15:06 -0700284 std::string(server_peer_->GetCurrentLargestMessagePayload() + 1, 'B');
QUICHE team7eef0712019-05-09 09:42:38 -0700285 message = CreateMemSliceVector(message_too_long);
QUICHE team136e7852019-05-13 14:10:34 -0700286 ASSERT_FALSE(
287 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288
289 // Wait for peer 2 to receive message.
290 RunTasks();
291
292 // Client should only receive one message of allowed length.
293 EXPECT_THAT(client_session_delegate_->incoming_messages(),
294 testing::ElementsAre(message_max_long));
295 }
296
297 // Test that client and server are not connected after handshake failure.
298 void TestDisconnectAfterFailedHandshake() {
299 EXPECT_TRUE(!client_session_delegate_->connected());
300 EXPECT_TRUE(!server_session_delegate_->connected());
301
302 EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
303 EXPECT_FALSE(client_peer_->IsCryptoHandshakeConfirmed());
304
305 EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
306 EXPECT_FALSE(server_peer_->IsCryptoHandshakeConfirmed());
307 }
308
309 protected:
310 simulator::Simulator simulator_;
311
312 std::unique_ptr<simulator::SimulatedQuartcPacketTransport> client_transport_;
313 std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_;
314 std::unique_ptr<simulator::CountingPacketFilter> client_filter_;
315 std::unique_ptr<simulator::SymmetricLink> client_server_link_;
316
317 std::unique_ptr<FakeQuartcStreamDelegate> client_stream_delegate_;
QUICHE team6939de52019-05-15 12:05:21 -0700318 std::unique_ptr<FakeQuartcEndpointDelegate> client_session_delegate_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500319 std::unique_ptr<FakeQuartcStreamDelegate> server_stream_delegate_;
QUICHE team6939de52019-05-15 12:05:21 -0700320 std::unique_ptr<FakeQuartcEndpointDelegate> server_session_delegate_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500321
322 std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
323 std::unique_ptr<QuartcServerEndpoint> server_endpoint_;
324
325 QuartcSession* client_peer_ = nullptr;
326 QuartcSession* server_peer_ = nullptr;
327};
328
329TEST_F(QuartcSessionTest, SendReceiveStreams) {
330 CreateClientAndServerSessions(QuartcSessionConfig());
331 AwaitHandshake();
332 TestSendReceiveStreams();
333}
334
335TEST_F(QuartcSessionTest, SendReceiveMessages) {
QUICHE team68d15a82019-05-31 15:27:25 -0700336 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
337 SetQuicReloadableFlag(quic_enable_version_99, false);
338
QUICHE teama6ef0a62019-03-07 20:34:33 -0500339 CreateClientAndServerSessions(QuartcSessionConfig());
340 AwaitHandshake();
341 TestSendReceiveMessage();
342}
343
344TEST_F(QuartcSessionTest, SendReceiveQueuedMessages) {
QUICHE team68d15a82019-05-31 15:27:25 -0700345 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
346 SetQuicReloadableFlag(quic_enable_version_99, false);
347
QUICHE teama6ef0a62019-03-07 20:34:33 -0500348 CreateClientAndServerSessions(QuartcSessionConfig());
349 AwaitHandshake();
350 TestSendReceiveQueuedMessages(/*direction_from_server=*/true);
351 TestSendReceiveQueuedMessages(/*direction_from_server=*/false);
352}
353
QUICHE teamea197352019-07-16 16:54:52 -0700354TEST_F(QuartcSessionTest, SendMultiMemSliceMessage) {
355 CreateClientAndServerSessions(QuartcSessionConfig());
356 AwaitHandshake();
357 ASSERT_TRUE(server_peer_->CanSendMessage());
358
359 std::vector<std::pair<char*, size_t>> buffers;
360 char first_piece[] = "Hello, ";
361 char second_piece[] = "world!";
362 buffers.emplace_back(first_piece, 7);
363 buffers.emplace_back(second_piece, 6);
364 test::QuicTestMemSliceVector message(buffers);
365 ASSERT_TRUE(
366 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/1));
367
368 // Wait for the client to receive the message.
369 RunTasks();
370
371 // The message is not fragmented along MemSlice boundaries.
372 EXPECT_THAT(client_session_delegate_->incoming_messages(),
373 testing::ElementsAre("Hello, world!"));
374}
375
QUICHE teama6ef0a62019-03-07 20:34:33 -0500376TEST_F(QuartcSessionTest, SendMessageFails) {
377 CreateClientAndServerSessions(QuartcSessionConfig());
378 AwaitHandshake();
379 TestSendLongMessage();
380}
381
382TEST_F(QuartcSessionTest, TestCryptoHandshakeCanWriteTriggers) {
383 CreateClientAndServerSessions(QuartcSessionConfig());
384
385 AwaitHandshake();
386
387 RunTasks();
388
389 ASSERT_TRUE(client_session_delegate_->writable_time().IsInitialized());
390 ASSERT_TRUE(
391 client_session_delegate_->crypto_handshake_time().IsInitialized());
392 // On client, we are writable 1-rtt before crypto handshake is complete.
393 ASSERT_LT(client_session_delegate_->writable_time(),
394 client_session_delegate_->crypto_handshake_time());
395
396 ASSERT_TRUE(server_session_delegate_->writable_time().IsInitialized());
397 ASSERT_TRUE(
398 server_session_delegate_->crypto_handshake_time().IsInitialized());
399 // On server, the writable time and crypto handshake are the same. (when SHLO
400 // is sent).
401 ASSERT_EQ(server_session_delegate_->writable_time(),
402 server_session_delegate_->crypto_handshake_time());
403}
404
405TEST_F(QuartcSessionTest, PreSharedKeyHandshake) {
QUICHE team68d15a82019-05-31 15:27:25 -0700406 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
407 SetQuicReloadableFlag(quic_enable_version_99, false);
408
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409 QuartcSessionConfig config;
410 config.pre_shared_key = "foo";
411 CreateClientAndServerSessions(config);
412 AwaitHandshake();
413 TestSendReceiveStreams();
414 TestSendReceiveMessage();
415}
416
417// Test that data streams are not created before handshake.
418TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) {
419 CreateClientAndServerSessions(QuartcSessionConfig());
420 EXPECT_EQ(nullptr, server_peer_->CreateOutgoingBidirectionalStream());
421 EXPECT_EQ(nullptr, client_peer_->CreateOutgoingBidirectionalStream());
422}
423
424TEST_F(QuartcSessionTest, CancelQuartcStream) {
425 CreateClientAndServerSessions(QuartcSessionConfig());
426 AwaitHandshake();
427 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
428 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
429
430 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
431 ASSERT_NE(nullptr, stream);
432
433 uint32_t id = stream->id();
434 EXPECT_FALSE(client_peer_->IsClosedStream(id));
435 stream->SetDelegate(client_stream_delegate_.get());
436 client_peer_->CancelStream(id);
437 EXPECT_EQ(stream->stream_error(),
438 QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
439 EXPECT_TRUE(client_peer_->IsClosedStream(id));
440}
441
442// TODO(b/112561077): This is the wrong layer for this test. We should write a
443// test specifically for QuartcPacketWriter with a stubbed-out
444// QuartcPacketTransport and remove
445// SimulatedQuartcPacketTransport::last_packet_number().
446TEST_F(QuartcSessionTest, WriterGivesPacketNumberToTransport) {
447 CreateClientAndServerSessions(QuartcSessionConfig());
448 AwaitHandshake();
449 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
450 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
451
452 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
453 stream->SetDelegate(client_stream_delegate_.get());
454
QUICHE team7eef0712019-05-09 09:42:38 -0700455 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500456 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
457 RunTasks();
458
459 // The transport should see the latest packet number sent by QUIC.
460 EXPECT_EQ(
461 client_transport_->last_packet_number(),
462 client_peer_->connection()->sent_packet_manager().GetLargestSentPacket());
463}
464
465TEST_F(QuartcSessionTest, CloseConnection) {
466 CreateClientAndServerSessions(QuartcSessionConfig());
467 AwaitHandshake();
468 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
469 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
470
471 client_peer_->CloseConnection("Connection closed by client");
472 EXPECT_FALSE(client_session_delegate_->connected());
473 RunTasks();
474 EXPECT_FALSE(server_session_delegate_->connected());
475}
476
477TEST_F(QuartcSessionTest, StreamRetransmissionEnabled) {
478 CreateClientAndServerSessions(QuartcSessionConfig());
479 AwaitHandshake();
480 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
481 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
482
483 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
484 QuicStreamId stream_id = stream->id();
485 stream->SetDelegate(client_stream_delegate_.get());
486 stream->set_cancel_on_loss(false);
487
488 client_filter_->set_packets_to_drop(1);
489
QUICHE team7eef0712019-05-09 09:42:38 -0700490 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500491 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
492 RunTasks();
493
494 // Stream data should make it despite packet loss.
495 ASSERT_TRUE(server_stream_delegate_->has_data());
QUICHE team7eef0712019-05-09 09:42:38 -0700496 EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500497}
498
499TEST_F(QuartcSessionTest, StreamRetransmissionDisabled) {
500 // Disable tail loss probe, otherwise test maybe flaky because dropped
501 // message will be retransmitted to detect tail loss.
502 QuartcSessionConfig session_config;
503 session_config.enable_tail_loss_probe = false;
504 CreateClientAndServerSessions(session_config);
505
506 // Disable probing retransmissions, otherwise test maybe flaky because dropped
507 // message will be retransmitted to to probe for more bandwidth.
508 client_peer_->connection()->set_fill_up_link_during_probing(false);
509
510 AwaitHandshake();
511 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
512 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
513
514 // The client sends an ACK for the crypto handshake next. This must be
515 // flushed before we set the filter to drop the next packet, in order to
516 // ensure that the filter drops a data-bearing packet instead of just an ack.
517 RunTasks();
518
519 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
520 QuicStreamId stream_id = stream->id();
521 stream->SetDelegate(client_stream_delegate_.get());
522 stream->set_cancel_on_loss(true);
523
524 client_filter_->set_packets_to_drop(1);
525
QUICHE team7eef0712019-05-09 09:42:38 -0700526 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500527 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
528 simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
529
530 // Send another packet to trigger loss detection.
531 QuartcStream* stream_1 = client_peer_->CreateOutgoingBidirectionalStream();
532 stream_1->SetDelegate(client_stream_delegate_.get());
533
QUICHE team7eef0712019-05-09 09:42:38 -0700534 test::QuicTestMemSliceVector stream_data_1 =
535 CreateMemSliceVector("Second message");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500536 stream_1->WriteMemSlices(stream_data_1.span(), /*fin=*/false);
537 RunTasks();
538
539 // QUIC should try to retransmit the first stream by loss detection. Instead,
540 // it will cancel itself.
541 EXPECT_THAT(server_stream_delegate_->data()[stream_id], testing::IsEmpty());
542
543 EXPECT_TRUE(client_peer_->IsClosedStream(stream_id));
544 EXPECT_TRUE(server_peer_->IsClosedStream(stream_id));
545 EXPECT_EQ(client_stream_delegate_->stream_error(stream_id),
546 QUIC_STREAM_CANCELLED);
547 EXPECT_EQ(server_stream_delegate_->stream_error(stream_id),
548 QUIC_STREAM_CANCELLED);
549}
550
QUICHE team68d15a82019-05-31 15:27:25 -0700551TEST_F(QuartcSessionTest, LostDatagramNotifications) {
552 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
553 SetQuicReloadableFlag(quic_enable_version_99, false);
554
555 // Disable tail loss probe, otherwise test maybe flaky because dropped
556 // message will be retransmitted to detect tail loss.
557 QuartcSessionConfig session_config;
558 session_config.enable_tail_loss_probe = false;
559 CreateClientAndServerSessions(session_config);
560
561 // Disable probing retransmissions, otherwise test maybe flaky because dropped
562 // message will be retransmitted to to probe for more bandwidth.
563 client_peer_->connection()->set_fill_up_link_during_probing(false);
564 server_peer_->connection()->set_fill_up_link_during_probing(false);
565
566 AwaitHandshake();
567 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
568 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
569
570 // The client sends an ACK for the crypto handshake next. This must be
571 // flushed before we set the filter to drop the next packet, in order to
572 // ensure that the filter drops a data-bearing packet instead of just an ack.
573 RunTasks();
574
575 // Drop the next packet.
576 client_filter_->set_packets_to_drop(1);
577
578 test::QuicTestMemSliceVector message =
579 CreateMemSliceVector("This message will be lost");
580 ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 1));
581
582 RunTasks();
583
584 // Send another packet to elicit an ack and trigger loss detection.
585 message = CreateMemSliceVector("This message will arrive");
586 ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 2));
587
588 RunTasks();
589
590 EXPECT_THAT(server_session_delegate_->incoming_messages(),
591 ElementsAre("This message will arrive"));
592 EXPECT_THAT(client_session_delegate_->sent_datagram_ids(), ElementsAre(1, 2));
593 EXPECT_THAT(
594 client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
595 ElementsAre(Pair(2, Gt(QuicTime::Zero()))));
596 EXPECT_THAT(client_session_delegate_->lost_datagram_ids(), ElementsAre(1));
597}
598
QUICHE teama6ef0a62019-03-07 20:34:33 -0500599TEST_F(QuartcSessionTest, ServerRegistersAsWriteBlocked) {
600 // Initialize client and server session, but with the server write-blocked.
601 Init();
602 server_transport_->SetWritable(false);
603 CreateClientAndServerSessions(QuartcSessionConfig(), /*init=*/false);
604
605 // Let the client send a few copies of the CHLO. The server can't respond, as
606 // it's still write-blocked.
607 RunTasks();
608
609 // Making the server's transport writable should trigger a callback that
610 // reaches the server session, allowing it to write packets.
611 server_transport_->SetWritable(true);
612
613 // Now the server should respond with the SHLO, encryption should be
614 // established, and data should flow normally.
615 // Note that if the server is *not* correctly registered as write-blocked,
616 // it will crash here (see b/124527328 for details).
617 AwaitHandshake();
618 TestSendReceiveStreams();
619}
620
621TEST_F(QuartcSessionTest, PreSharedKeyHandshakeIs0RTT) {
622 QuartcSessionConfig session_config;
623 session_config.pre_shared_key = "foo";
624
625 // Client endpoint is created below. Destructing client endpoint
626 // causes issues with the simulator.
627 Init(/*create_client_endpoint=*/false);
628
629 server_endpoint_->Connect(server_transport_.get());
630
631 client_endpoint_ = QuicMakeUnique<QuartcClientEndpoint>(
632 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -0700633 simulator_.GetRandomGenerator(), client_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -0700634 QuartcSessionConfig(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500635 // This is the key line here. It passes through the server config
636 // from the server to the client.
637 server_endpoint_->server_crypto_config());
638
639 client_endpoint_->Connect(client_transport_.get());
640
641 // Running for 1ms. This is shorter than the RTT, so the
642 // client session should be created, but server won't be created yet.
643 simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
644
QUICHE team6939de52019-05-15 12:05:21 -0700645 client_peer_ = client_session_delegate_->session();
646 server_peer_ = server_session_delegate_->session();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500647
648 ASSERT_NE(client_peer_, nullptr);
649 ASSERT_EQ(server_peer_, nullptr);
650
651 // Write data to the client before running tasks. This should be sent by the
652 // client and received by the server if the handshake is 0RTT.
653 // If this test fails, add 'RunTasks()' above, and see what error is sent
654 // by the server in the rejection message.
655 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
656 ASSERT_NE(stream, nullptr);
657 QuicStreamId stream_id = stream->id();
658 stream->SetDelegate(client_stream_delegate_.get());
659
660 char message[] = "Hello in 0RTTs!";
661 test::QuicTestMemSliceVector data({std::make_pair(message, strlen(message))});
662 stream->WriteMemSlices(data.span(), /*fin=*/false);
663
664 // This will now run the rest of the connection. But the
665 // Server peer will receive the CHLO and message after 1 delay.
666 simulator_.RunFor(kPropagationDelayAndABit);
667
668 // If we can decrypt the data, it means that 0 rtt was successful.
669 // This is because we waited only a propagation delay. So if the decryption
670 // failed, we would send sREJ instead of SHLO, but it wouldn't be delivered to
671 // the client yet.
672 ASSERT_TRUE(server_stream_delegate_->has_data());
673 EXPECT_EQ(server_stream_delegate_->data()[stream_id], message);
674}
675
676} // namespace
677
678} // namespace quic