blob: b08ccb4e10163b197abab9536fd495f4d511af65 [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
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
10#include "net/third_party/quiche/src/quic/core/quic_types.h"
11#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
12#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
17#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h"
18#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
19#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
20#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
21#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
22#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
bnc13895832019-11-27 08:40:50 -080023#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050024#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h"
25#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
dmcardlec60e87a2019-12-12 09:43:19 -080026#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
27#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050028
29namespace quic {
30
31namespace {
32
QUICHE team68d15a82019-05-31 15:27:25 -070033using ::testing::ElementsAre;
34using ::testing::ElementsAreArray;
35using ::testing::Gt;
36using ::testing::Pair;
37
QUICHE teama6ef0a62019-03-07 20:34:33 -050038constexpr QuicTime::Delta kPropagationDelay =
39 QuicTime::Delta::FromMilliseconds(10);
40// Propagation delay and a bit, but no more than full RTT.
41constexpr QuicTime::Delta kPropagationDelayAndABit =
42 QuicTime::Delta::FromMilliseconds(12);
43
44static QuicByteCount kDefaultMaxPacketSize = 1200;
45
dmcardlec60e87a2019-12-12 09:43:19 -080046test::QuicTestMemSliceVector CreateMemSliceVector(
47 quiche::QuicheStringPiece data) {
QUICHE team7eef0712019-05-09 09:42:38 -070048 return test::QuicTestMemSliceVector(
49 {std::pair<char*, size_t>(const_cast<char*>(data.data()), data.size())});
50}
51
QUICHE teama6ef0a62019-03-07 20:34:33 -050052class QuartcSessionTest : public QuicTest {
53 public:
54 ~QuartcSessionTest() override {}
55
56 void Init(bool create_client_endpoint = true) {
dschinazi76881f02019-12-09 14:56:14 -080057 quic::test::QuicEnableDefaultEnabledVersions();
58 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
59 SetQuicReloadableFlag(quic_enable_version_q099, false);
60 SetQuicReloadableFlag(quic_enable_version_t099, false);
61
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 client_transport_ =
vasilvv0fc587f2019-09-06 13:33:08 -070063 std::make_unique<simulator::SimulatedQuartcPacketTransport>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050064 &simulator_, "client_transport", "server_transport",
65 10 * kDefaultMaxPacketSize);
66 server_transport_ =
vasilvv0fc587f2019-09-06 13:33:08 -070067 std::make_unique<simulator::SimulatedQuartcPacketTransport>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050068 &simulator_, "server_transport", "client_transport",
69 10 * kDefaultMaxPacketSize);
70
vasilvv0fc587f2019-09-06 13:33:08 -070071 client_filter_ = std::make_unique<simulator::CountingPacketFilter>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 &simulator_, "client_filter", client_transport_.get());
73
vasilvv0fc587f2019-09-06 13:33:08 -070074 client_server_link_ = std::make_unique<simulator::SymmetricLink>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050075 client_filter_.get(), server_transport_.get(),
76 QuicBandwidth::FromKBitsPerSecond(10 * 1000), kPropagationDelay);
77
vasilvv0fc587f2019-09-06 13:33:08 -070078 client_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>();
79 client_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050080 client_stream_delegate_.get(), simulator_.GetClock());
QUICHE teama6ef0a62019-03-07 20:34:33 -050081
vasilvv0fc587f2019-09-06 13:33:08 -070082 server_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>();
83 server_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 server_stream_delegate_.get(), simulator_.GetClock());
QUICHE teama6ef0a62019-03-07 20:34:33 -050085
86 // No 0-rtt setup, because server config is empty.
87 // CannotCreateDataStreamBeforeHandshake depends on 1-rtt setup.
88 if (create_client_endpoint) {
vasilvv0fc587f2019-09-06 13:33:08 -070089 client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -070091 simulator_.GetRandomGenerator(), client_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -070092 quic::QuartcSessionConfig(),
QUICHE teama6ef0a62019-03-07 20:34:33 -050093 /*serialized_server_config=*/"");
94 }
vasilvv0fc587f2019-09-06 13:33:08 -070095 server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050096 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -070097 simulator_.GetRandomGenerator(), server_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -070098 quic::QuartcSessionConfig());
QUICHE teama6ef0a62019-03-07 20:34:33 -050099 }
100
101 // Note that input session config will apply to both server and client.
102 // Perspective and packet_transport will be overwritten.
dschinazi17d42422019-06-18 16:35:07 -0700103 void CreateClientAndServerSessions(
104 const QuartcSessionConfig& /*session_config*/,
105 bool init = true) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 if (init) {
107 Init();
108 }
109
110 server_endpoint_->Connect(server_transport_.get());
111 client_endpoint_->Connect(client_transport_.get());
112
113 CHECK(simulator_.RunUntil([this] {
QUICHE team6939de52019-05-15 12:05:21 -0700114 return client_session_delegate_->session() != nullptr &&
115 server_session_delegate_->session() != nullptr;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116 }));
117
QUICHE team6939de52019-05-15 12:05:21 -0700118 client_peer_ = client_session_delegate_->session();
119 server_peer_ = server_session_delegate_->session();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500120 }
121
122 // Runs all tasks scheduled in the next 200 ms.
123 void RunTasks() { simulator_.RunFor(QuicTime::Delta::FromMilliseconds(200)); }
124
125 void AwaitHandshake() {
126 simulator_.RunUntil([this] {
fayanga3d8df72020-01-14 11:54:39 -0800127 return client_peer_->OneRttKeysAvailable() &&
128 server_peer_->OneRttKeysAvailable();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129 });
130 }
131
132 // Test handshake establishment and sending/receiving of data for two
133 // directions.
134 void TestSendReceiveStreams() {
fayanga3d8df72020-01-14 11:54:39 -0800135 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
136 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
138 ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
139
140 // Now we can establish encrypted outgoing stream.
141 QuartcStream* outgoing_stream =
142 server_peer_->CreateOutgoingBidirectionalStream();
143 QuicStreamId stream_id = outgoing_stream->id();
144 ASSERT_NE(nullptr, outgoing_stream);
145 EXPECT_TRUE(server_peer_->ShouldKeepConnectionAlive());
146
147 outgoing_stream->SetDelegate(server_stream_delegate_.get());
148
149 // Send a test message from peer 1 to peer 2.
QUICHE team7eef0712019-05-09 09:42:38 -0700150 test::QuicTestMemSliceVector data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500151 outgoing_stream->WriteMemSlices(data.span(), /*fin=*/false);
152 RunTasks();
153
154 // Wait for peer 2 to receive messages.
155 ASSERT_TRUE(client_stream_delegate_->has_data());
156
157 QuartcStream* incoming = client_session_delegate_->last_incoming_stream();
158 ASSERT_TRUE(incoming);
159 EXPECT_EQ(incoming->id(), stream_id);
160 EXPECT_TRUE(client_peer_->ShouldKeepConnectionAlive());
161
QUICHE team7eef0712019-05-09 09:42:38 -0700162 EXPECT_EQ(client_stream_delegate_->data()[stream_id], "Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500163 // Send a test message from peer 2 to peer 1.
QUICHE team7eef0712019-05-09 09:42:38 -0700164 test::QuicTestMemSliceVector response = CreateMemSliceVector("Response");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165 incoming->WriteMemSlices(response.span(), /*fin=*/false);
166 RunTasks();
167 // Wait for peer 1 to receive messages.
168 ASSERT_TRUE(server_stream_delegate_->has_data());
169
QUICHE team7eef0712019-05-09 09:42:38 -0700170 EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Response");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 }
172
173 // Test sending/receiving of messages for two directions.
174 void TestSendReceiveMessage() {
175 ASSERT_TRUE(server_peer_->CanSendMessage());
176 ASSERT_TRUE(client_peer_->CanSendMessage());
177
QUICHE team136e7852019-05-13 14:10:34 -0700178 int64_t server_datagram_id = 111;
179 int64_t client_datagram_id = 222;
180
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 // Send message from peer 1 to peer 2.
QUICHE team7eef0712019-05-09 09:42:38 -0700182 test::QuicTestMemSliceVector message =
183 CreateMemSliceVector("Message from server");
QUICHE team136e7852019-05-13 14:10:34 -0700184 ASSERT_TRUE(
185 server_peer_->SendOrQueueMessage(message.span(), server_datagram_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186
187 // First message in each direction should not be queued.
188 EXPECT_EQ(server_peer_->send_message_queue_size(), 0u);
189
190 // Wait for peer 2 to receive message.
191 RunTasks();
192
193 EXPECT_THAT(client_session_delegate_->incoming_messages(),
194 testing::ElementsAre("Message from server"));
195
QUICHE team136e7852019-05-13 14:10:34 -0700196 EXPECT_THAT(server_session_delegate_->sent_datagram_ids(),
197 testing::ElementsAre(server_datagram_id));
198
QUICHE team68d15a82019-05-31 15:27:25 -0700199 EXPECT_THAT(
200 server_session_delegate_->acked_datagram_id_to_receive_timestamp(),
201 ElementsAre(Pair(server_datagram_id, Gt(QuicTime::Zero()))));
QUICHE team34df5852019-05-29 16:27:22 -0700202
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203 // Send message from peer 2 to peer 1.
QUICHE team7eef0712019-05-09 09:42:38 -0700204 message = CreateMemSliceVector("Message from client");
QUICHE team136e7852019-05-13 14:10:34 -0700205 ASSERT_TRUE(
206 client_peer_->SendOrQueueMessage(message.span(), client_datagram_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207
208 // First message in each direction should not be queued.
209 EXPECT_EQ(client_peer_->send_message_queue_size(), 0u);
210
211 // Wait for peer 1 to receive message.
212 RunTasks();
213
214 EXPECT_THAT(server_session_delegate_->incoming_messages(),
215 testing::ElementsAre("Message from client"));
QUICHE team136e7852019-05-13 14:10:34 -0700216
217 EXPECT_THAT(client_session_delegate_->sent_datagram_ids(),
218 testing::ElementsAre(client_datagram_id));
QUICHE team34df5852019-05-29 16:27:22 -0700219
QUICHE team68d15a82019-05-31 15:27:25 -0700220 EXPECT_THAT(
221 client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
222 ElementsAre(Pair(client_datagram_id, Gt(QuicTime::Zero()))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 }
224
225 // Test for sending multiple messages that also result in queueing.
226 // This is one-way test, which is run in given direction.
227 void TestSendReceiveQueuedMessages(bool direction_from_server) {
228 // Send until queue_size number of messages are queued.
229 constexpr size_t queue_size = 10;
230
231 ASSERT_TRUE(server_peer_->CanSendMessage());
232 ASSERT_TRUE(client_peer_->CanSendMessage());
233
234 QuartcSession* const peer_sending =
235 direction_from_server ? server_peer_ : client_peer_;
236
QUICHE team6939de52019-05-15 12:05:21 -0700237 FakeQuartcEndpointDelegate* const delegate_receiving =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 direction_from_server ? client_session_delegate_.get()
239 : server_session_delegate_.get();
240
QUICHE team6939de52019-05-15 12:05:21 -0700241 FakeQuartcEndpointDelegate* const delegate_sending =
QUICHE team136e7852019-05-13 14:10:34 -0700242 direction_from_server ? server_session_delegate_.get()
243 : client_session_delegate_.get();
244
QUICHE teama6ef0a62019-03-07 20:34:33 -0500245 // There should be no messages in the queue before we start sending.
246 EXPECT_EQ(peer_sending->send_message_queue_size(), 0u);
247
248 // Send messages from peer 1 to peer 2 until required number of messages
249 // are queued in unsent message queue.
vasilvvc48c8712019-03-11 13:38:16 -0700250 std::vector<std::string> sent_messages;
QUICHE team136e7852019-05-13 14:10:34 -0700251 std::vector<int64_t> sent_datagram_ids;
252 int64_t current_datagram_id = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 while (peer_sending->send_message_queue_size() < queue_size) {
dmcardlec60e87a2019-12-12 09:43:19 -0800254 sent_messages.push_back(quiche::QuicheStrCat("Sending message, index=",
255 sent_messages.size()));
QUICHE team7eef0712019-05-09 09:42:38 -0700256 ASSERT_TRUE(peer_sending->SendOrQueueMessage(
QUICHE team136e7852019-05-13 14:10:34 -0700257 CreateMemSliceVector(sent_messages.back()).span(),
258 current_datagram_id));
259
260 sent_datagram_ids.push_back(current_datagram_id);
261 ++current_datagram_id;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262 }
263
264 // Wait for peer 2 to receive all messages.
265 RunTasks();
266
QUICHE team68d15a82019-05-31 15:27:25 -0700267 std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers;
268 for (int64_t id : sent_datagram_ids) {
269 ack_matchers.push_back(Pair(id, Gt(QuicTime::Zero())));
270 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271 EXPECT_EQ(delegate_receiving->incoming_messages(), sent_messages);
QUICHE team136e7852019-05-13 14:10:34 -0700272 EXPECT_EQ(delegate_sending->sent_datagram_ids(), sent_datagram_ids);
QUICHE team68d15a82019-05-31 15:27:25 -0700273 EXPECT_THAT(delegate_sending->acked_datagram_id_to_receive_timestamp(),
274 ElementsAreArray(ack_matchers));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500275 }
276
277 // Test sending long messages:
278 // - message of maximum allowed length should succeed
279 // - message of > maximum allowed length should fail.
280 void TestSendLongMessage() {
281 ASSERT_TRUE(server_peer_->CanSendMessage());
282 ASSERT_TRUE(client_peer_->CanSendMessage());
283
284 // Send message of maximum allowed length.
vasilvvc48c8712019-03-11 13:38:16 -0700285 std::string message_max_long =
ianswettb239f862019-04-05 09:15:06 -0700286 std::string(server_peer_->GetCurrentLargestMessagePayload(), 'A');
QUICHE team7eef0712019-05-09 09:42:38 -0700287 test::QuicTestMemSliceVector message =
288 CreateMemSliceVector(message_max_long);
QUICHE team136e7852019-05-13 14:10:34 -0700289 ASSERT_TRUE(
290 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500291
292 // Send long message which should fail.
vasilvvc48c8712019-03-11 13:38:16 -0700293 std::string message_too_long =
ianswettb239f862019-04-05 09:15:06 -0700294 std::string(server_peer_->GetCurrentLargestMessagePayload() + 1, 'B');
QUICHE team7eef0712019-05-09 09:42:38 -0700295 message = CreateMemSliceVector(message_too_long);
QUICHE team136e7852019-05-13 14:10:34 -0700296 ASSERT_FALSE(
297 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298
299 // Wait for peer 2 to receive message.
300 RunTasks();
301
302 // Client should only receive one message of allowed length.
303 EXPECT_THAT(client_session_delegate_->incoming_messages(),
304 testing::ElementsAre(message_max_long));
305 }
306
307 // Test that client and server are not connected after handshake failure.
308 void TestDisconnectAfterFailedHandshake() {
309 EXPECT_TRUE(!client_session_delegate_->connected());
310 EXPECT_TRUE(!server_session_delegate_->connected());
311
312 EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
fayanga3d8df72020-01-14 11:54:39 -0800313 EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314
315 EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
fayanga3d8df72020-01-14 11:54:39 -0800316 EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500317 }
318
319 protected:
320 simulator::Simulator simulator_;
321
322 std::unique_ptr<simulator::SimulatedQuartcPacketTransport> client_transport_;
323 std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_;
324 std::unique_ptr<simulator::CountingPacketFilter> client_filter_;
325 std::unique_ptr<simulator::SymmetricLink> client_server_link_;
326
327 std::unique_ptr<FakeQuartcStreamDelegate> client_stream_delegate_;
QUICHE team6939de52019-05-15 12:05:21 -0700328 std::unique_ptr<FakeQuartcEndpointDelegate> client_session_delegate_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 std::unique_ptr<FakeQuartcStreamDelegate> server_stream_delegate_;
QUICHE team6939de52019-05-15 12:05:21 -0700330 std::unique_ptr<FakeQuartcEndpointDelegate> server_session_delegate_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331
332 std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
333 std::unique_ptr<QuartcServerEndpoint> server_endpoint_;
334
335 QuartcSession* client_peer_ = nullptr;
336 QuartcSession* server_peer_ = nullptr;
337};
338
339TEST_F(QuartcSessionTest, SendReceiveStreams) {
340 CreateClientAndServerSessions(QuartcSessionConfig());
341 AwaitHandshake();
342 TestSendReceiveStreams();
343}
344
345TEST_F(QuartcSessionTest, SendReceiveMessages) {
QUICHE team68d15a82019-05-31 15:27:25 -0700346 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
dschinazi76881f02019-12-09 14:56:14 -0800347 SetQuicReloadableFlag(quic_enable_version_q099, false);
348 SetQuicReloadableFlag(quic_enable_version_t099, false);
QUICHE team68d15a82019-05-31 15:27:25 -0700349
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 CreateClientAndServerSessions(QuartcSessionConfig());
351 AwaitHandshake();
352 TestSendReceiveMessage();
353}
354
355TEST_F(QuartcSessionTest, SendReceiveQueuedMessages) {
QUICHE team68d15a82019-05-31 15:27:25 -0700356 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
dschinazi76881f02019-12-09 14:56:14 -0800357 SetQuicReloadableFlag(quic_enable_version_q099, false);
358 SetQuicReloadableFlag(quic_enable_version_t099, false);
QUICHE team68d15a82019-05-31 15:27:25 -0700359
QUICHE teama6ef0a62019-03-07 20:34:33 -0500360 CreateClientAndServerSessions(QuartcSessionConfig());
361 AwaitHandshake();
362 TestSendReceiveQueuedMessages(/*direction_from_server=*/true);
363 TestSendReceiveQueuedMessages(/*direction_from_server=*/false);
364}
365
QUICHE teamea197352019-07-16 16:54:52 -0700366TEST_F(QuartcSessionTest, SendMultiMemSliceMessage) {
367 CreateClientAndServerSessions(QuartcSessionConfig());
368 AwaitHandshake();
369 ASSERT_TRUE(server_peer_->CanSendMessage());
370
371 std::vector<std::pair<char*, size_t>> buffers;
372 char first_piece[] = "Hello, ";
373 char second_piece[] = "world!";
374 buffers.emplace_back(first_piece, 7);
375 buffers.emplace_back(second_piece, 6);
376 test::QuicTestMemSliceVector message(buffers);
377 ASSERT_TRUE(
378 server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/1));
379
380 // Wait for the client to receive the message.
381 RunTasks();
382
383 // The message is not fragmented along MemSlice boundaries.
384 EXPECT_THAT(client_session_delegate_->incoming_messages(),
385 testing::ElementsAre("Hello, world!"));
386}
387
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388TEST_F(QuartcSessionTest, SendMessageFails) {
389 CreateClientAndServerSessions(QuartcSessionConfig());
390 AwaitHandshake();
391 TestSendLongMessage();
392}
393
394TEST_F(QuartcSessionTest, TestCryptoHandshakeCanWriteTriggers) {
395 CreateClientAndServerSessions(QuartcSessionConfig());
396
397 AwaitHandshake();
398
399 RunTasks();
400
401 ASSERT_TRUE(client_session_delegate_->writable_time().IsInitialized());
402 ASSERT_TRUE(
403 client_session_delegate_->crypto_handshake_time().IsInitialized());
404 // On client, we are writable 1-rtt before crypto handshake is complete.
405 ASSERT_LT(client_session_delegate_->writable_time(),
406 client_session_delegate_->crypto_handshake_time());
407
408 ASSERT_TRUE(server_session_delegate_->writable_time().IsInitialized());
409 ASSERT_TRUE(
410 server_session_delegate_->crypto_handshake_time().IsInitialized());
411 // On server, the writable time and crypto handshake are the same. (when SHLO
412 // is sent).
413 ASSERT_EQ(server_session_delegate_->writable_time(),
414 server_session_delegate_->crypto_handshake_time());
415}
416
417TEST_F(QuartcSessionTest, PreSharedKeyHandshake) {
QUICHE team68d15a82019-05-31 15:27:25 -0700418 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
dschinazi76881f02019-12-09 14:56:14 -0800419 SetQuicReloadableFlag(quic_enable_version_q099, false);
420 SetQuicReloadableFlag(quic_enable_version_t099, false);
QUICHE team68d15a82019-05-31 15:27:25 -0700421
QUICHE teama6ef0a62019-03-07 20:34:33 -0500422 QuartcSessionConfig config;
423 config.pre_shared_key = "foo";
424 CreateClientAndServerSessions(config);
425 AwaitHandshake();
426 TestSendReceiveStreams();
427 TestSendReceiveMessage();
428}
429
430// Test that data streams are not created before handshake.
431TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) {
432 CreateClientAndServerSessions(QuartcSessionConfig());
433 EXPECT_EQ(nullptr, server_peer_->CreateOutgoingBidirectionalStream());
434 EXPECT_EQ(nullptr, client_peer_->CreateOutgoingBidirectionalStream());
435}
436
437TEST_F(QuartcSessionTest, CancelQuartcStream) {
438 CreateClientAndServerSessions(QuartcSessionConfig());
439 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800440 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
441 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500442
443 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
444 ASSERT_NE(nullptr, stream);
445
446 uint32_t id = stream->id();
447 EXPECT_FALSE(client_peer_->IsClosedStream(id));
448 stream->SetDelegate(client_stream_delegate_.get());
449 client_peer_->CancelStream(id);
450 EXPECT_EQ(stream->stream_error(),
451 QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
452 EXPECT_TRUE(client_peer_->IsClosedStream(id));
453}
454
455// TODO(b/112561077): This is the wrong layer for this test. We should write a
456// test specifically for QuartcPacketWriter with a stubbed-out
457// QuartcPacketTransport and remove
458// SimulatedQuartcPacketTransport::last_packet_number().
459TEST_F(QuartcSessionTest, WriterGivesPacketNumberToTransport) {
460 CreateClientAndServerSessions(QuartcSessionConfig());
461 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800462 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
463 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500464
465 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
466 stream->SetDelegate(client_stream_delegate_.get());
467
QUICHE team7eef0712019-05-09 09:42:38 -0700468 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
470 RunTasks();
471
472 // The transport should see the latest packet number sent by QUIC.
473 EXPECT_EQ(
474 client_transport_->last_packet_number(),
475 client_peer_->connection()->sent_packet_manager().GetLargestSentPacket());
476}
477
478TEST_F(QuartcSessionTest, CloseConnection) {
479 CreateClientAndServerSessions(QuartcSessionConfig());
480 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800481 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
482 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500483
484 client_peer_->CloseConnection("Connection closed by client");
485 EXPECT_FALSE(client_session_delegate_->connected());
486 RunTasks();
487 EXPECT_FALSE(server_session_delegate_->connected());
488}
489
490TEST_F(QuartcSessionTest, StreamRetransmissionEnabled) {
491 CreateClientAndServerSessions(QuartcSessionConfig());
492 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800493 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
494 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500495
496 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
497 QuicStreamId stream_id = stream->id();
498 stream->SetDelegate(client_stream_delegate_.get());
499 stream->set_cancel_on_loss(false);
500
501 client_filter_->set_packets_to_drop(1);
502
QUICHE team7eef0712019-05-09 09:42:38 -0700503 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
505 RunTasks();
506
507 // Stream data should make it despite packet loss.
508 ASSERT_TRUE(server_stream_delegate_->has_data());
QUICHE team7eef0712019-05-09 09:42:38 -0700509 EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500510}
511
512TEST_F(QuartcSessionTest, StreamRetransmissionDisabled) {
513 // Disable tail loss probe, otherwise test maybe flaky because dropped
514 // message will be retransmitted to detect tail loss.
515 QuartcSessionConfig session_config;
516 session_config.enable_tail_loss_probe = false;
517 CreateClientAndServerSessions(session_config);
518
519 // Disable probing retransmissions, otherwise test maybe flaky because dropped
520 // message will be retransmitted to to probe for more bandwidth.
521 client_peer_->connection()->set_fill_up_link_during_probing(false);
522
523 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800524 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
525 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526
527 // The client sends an ACK for the crypto handshake next. This must be
528 // flushed before we set the filter to drop the next packet, in order to
529 // ensure that the filter drops a data-bearing packet instead of just an ack.
530 RunTasks();
531
532 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
533 QuicStreamId stream_id = stream->id();
534 stream->SetDelegate(client_stream_delegate_.get());
535 stream->set_cancel_on_loss(true);
536
537 client_filter_->set_packets_to_drop(1);
538
QUICHE team7eef0712019-05-09 09:42:38 -0700539 test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500540 stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
541 simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
542
543 // Send another packet to trigger loss detection.
544 QuartcStream* stream_1 = client_peer_->CreateOutgoingBidirectionalStream();
545 stream_1->SetDelegate(client_stream_delegate_.get());
546
QUICHE team7eef0712019-05-09 09:42:38 -0700547 test::QuicTestMemSliceVector stream_data_1 =
548 CreateMemSliceVector("Second message");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500549 stream_1->WriteMemSlices(stream_data_1.span(), /*fin=*/false);
550 RunTasks();
551
552 // QUIC should try to retransmit the first stream by loss detection. Instead,
553 // it will cancel itself.
554 EXPECT_THAT(server_stream_delegate_->data()[stream_id], testing::IsEmpty());
555
556 EXPECT_TRUE(client_peer_->IsClosedStream(stream_id));
557 EXPECT_TRUE(server_peer_->IsClosedStream(stream_id));
bnc13895832019-11-27 08:40:50 -0800558 EXPECT_THAT(client_stream_delegate_->stream_error(stream_id),
559 test::IsStreamError(QUIC_STREAM_CANCELLED));
560 EXPECT_THAT(server_stream_delegate_->stream_error(stream_id),
561 test::IsStreamError(QUIC_STREAM_CANCELLED));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500562}
563
QUICHE team68d15a82019-05-31 15:27:25 -0700564TEST_F(QuartcSessionTest, LostDatagramNotifications) {
565 // TODO(b/134175506): Remove when IETF QUIC supports receive timestamps.
dschinazi76881f02019-12-09 14:56:14 -0800566 SetQuicReloadableFlag(quic_enable_version_q099, false);
567 SetQuicReloadableFlag(quic_enable_version_t099, false);
QUICHE team68d15a82019-05-31 15:27:25 -0700568
569 // Disable tail loss probe, otherwise test maybe flaky because dropped
570 // message will be retransmitted to detect tail loss.
571 QuartcSessionConfig session_config;
572 session_config.enable_tail_loss_probe = false;
573 CreateClientAndServerSessions(session_config);
574
575 // Disable probing retransmissions, otherwise test maybe flaky because dropped
576 // message will be retransmitted to to probe for more bandwidth.
577 client_peer_->connection()->set_fill_up_link_during_probing(false);
578 server_peer_->connection()->set_fill_up_link_during_probing(false);
579
580 AwaitHandshake();
fayanga3d8df72020-01-14 11:54:39 -0800581 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
582 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
QUICHE team68d15a82019-05-31 15:27:25 -0700583
584 // The client sends an ACK for the crypto handshake next. This must be
585 // flushed before we set the filter to drop the next packet, in order to
586 // ensure that the filter drops a data-bearing packet instead of just an ack.
587 RunTasks();
588
589 // Drop the next packet.
590 client_filter_->set_packets_to_drop(1);
591
592 test::QuicTestMemSliceVector message =
593 CreateMemSliceVector("This message will be lost");
594 ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 1));
595
596 RunTasks();
597
598 // Send another packet to elicit an ack and trigger loss detection.
599 message = CreateMemSliceVector("This message will arrive");
600 ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 2));
601
602 RunTasks();
603
604 EXPECT_THAT(server_session_delegate_->incoming_messages(),
605 ElementsAre("This message will arrive"));
606 EXPECT_THAT(client_session_delegate_->sent_datagram_ids(), ElementsAre(1, 2));
607 EXPECT_THAT(
608 client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
609 ElementsAre(Pair(2, Gt(QuicTime::Zero()))));
610 EXPECT_THAT(client_session_delegate_->lost_datagram_ids(), ElementsAre(1));
611}
612
QUICHE teama6ef0a62019-03-07 20:34:33 -0500613TEST_F(QuartcSessionTest, ServerRegistersAsWriteBlocked) {
614 // Initialize client and server session, but with the server write-blocked.
615 Init();
616 server_transport_->SetWritable(false);
617 CreateClientAndServerSessions(QuartcSessionConfig(), /*init=*/false);
618
619 // Let the client send a few copies of the CHLO. The server can't respond, as
620 // it's still write-blocked.
621 RunTasks();
622
623 // Making the server's transport writable should trigger a callback that
624 // reaches the server session, allowing it to write packets.
625 server_transport_->SetWritable(true);
626
627 // Now the server should respond with the SHLO, encryption should be
628 // established, and data should flow normally.
629 // Note that if the server is *not* correctly registered as write-blocked,
630 // it will crash here (see b/124527328 for details).
631 AwaitHandshake();
632 TestSendReceiveStreams();
633}
634
635TEST_F(QuartcSessionTest, PreSharedKeyHandshakeIs0RTT) {
636 QuartcSessionConfig session_config;
637 session_config.pre_shared_key = "foo";
638
639 // Client endpoint is created below. Destructing client endpoint
640 // causes issues with the simulator.
641 Init(/*create_client_endpoint=*/false);
642
643 server_endpoint_->Connect(server_transport_.get());
644
vasilvv0fc587f2019-09-06 13:33:08 -0700645 client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500646 simulator_.GetAlarmFactory(), simulator_.GetClock(),
QUICHE team6939de52019-05-15 12:05:21 -0700647 simulator_.GetRandomGenerator(), client_session_delegate_.get(),
QUICHE team73957f12019-04-18 16:21:52 -0700648 QuartcSessionConfig(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500649 // This is the key line here. It passes through the server config
650 // from the server to the client.
651 server_endpoint_->server_crypto_config());
652
653 client_endpoint_->Connect(client_transport_.get());
654
655 // Running for 1ms. This is shorter than the RTT, so the
656 // client session should be created, but server won't be created yet.
657 simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
658
QUICHE team6939de52019-05-15 12:05:21 -0700659 client_peer_ = client_session_delegate_->session();
660 server_peer_ = server_session_delegate_->session();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500661
662 ASSERT_NE(client_peer_, nullptr);
663 ASSERT_EQ(server_peer_, nullptr);
664
665 // Write data to the client before running tasks. This should be sent by the
666 // client and received by the server if the handshake is 0RTT.
667 // If this test fails, add 'RunTasks()' above, and see what error is sent
668 // by the server in the rejection message.
669 QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
670 ASSERT_NE(stream, nullptr);
671 QuicStreamId stream_id = stream->id();
672 stream->SetDelegate(client_stream_delegate_.get());
673
674 char message[] = "Hello in 0RTTs!";
675 test::QuicTestMemSliceVector data({std::make_pair(message, strlen(message))});
676 stream->WriteMemSlices(data.span(), /*fin=*/false);
677
678 // This will now run the rest of the connection. But the
679 // Server peer will receive the CHLO and message after 1 delay.
680 simulator_.RunFor(kPropagationDelayAndABit);
681
682 // If we can decrypt the data, it means that 0 rtt was successful.
683 // This is because we waited only a propagation delay. So if the decryption
684 // failed, we would send sREJ instead of SHLO, but it wouldn't be delivered to
685 // the client yet.
686 ASSERT_TRUE(server_stream_delegate_->has_data());
687 EXPECT_EQ(server_stream_delegate_->data()[stream_id], message);
688}
689
690} // namespace
691
692} // namespace quic