blob: 46a41d925599f0f5f420ca57c084bd8d586e0834 [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// Copyright (c) 2019 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
vasilvv40f15e02022-09-06 06:16:43 -07005#include <memory>
Bence Békybac04052022-04-07 15:44:29 -04006#include <utility>
7
8#include "absl/strings/string_view.h"
vasilvv40f15e02022-09-06 06:16:43 -07009#include "quiche/quic/core/io/quic_default_event_loop.h"
10#include "quiche/quic/core/io/quic_event_loop.h"
Bence Békybac04052022-04-07 15:44:29 -040011#include "quiche/quic/core/proto/crypto_server_config_proto.h"
12#include "quiche/quic/core/quic_alarm_factory.h"
vasilvv40f15e02022-09-06 06:16:43 -070013#include "quiche/quic/core/quic_default_clock.h"
Bence Békybac04052022-04-07 15:44:29 -040014#include "quiche/quic/platform/api/quic_expect_bug.h"
15#include "quiche/quic/platform/api/quic_test.h"
16#include "quiche/quic/platform/api/quic_test_loopback.h"
17#include "quiche/quic/qbone/platform/icmp_packet.h"
18#include "quiche/quic/qbone/qbone_client_session.h"
19#include "quiche/quic/qbone/qbone_constants.h"
20#include "quiche/quic/qbone/qbone_control_placeholder.pb.h"
21#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
22#include "quiche/quic/qbone/qbone_server_session.h"
23#include "quiche/quic/test_tools/crypto_test_utils.h"
24#include "quiche/quic/test_tools/mock_clock.h"
martinduke605dca22022-09-01 10:40:19 -070025#include "quiche/quic/test_tools/mock_connection_id_generator.h"
Bence Békybac04052022-04-07 15:44:29 -040026#include "quiche/quic/test_tools/quic_connection_peer.h"
27#include "quiche/quic/test_tools/quic_session_peer.h"
28#include "quiche/quic/test_tools/quic_test_utils.h"
vasilvv3d870652023-06-05 09:29:16 -070029#include "quiche/common/quiche_callbacks.h"
Bence Békybac04052022-04-07 15:44:29 -040030
31namespace quic {
32namespace test {
33namespace {
34
35using ::testing::_;
36using ::testing::Contains;
37using ::testing::ElementsAre;
38using ::testing::Eq;
39using ::testing::Invoke;
40using ::testing::NiceMock;
41using ::testing::Not;
42
43std::string TestPacketIn(const std::string& body) {
44 return PrependIPv6HeaderForTest(body, 5);
45}
46
47std::string TestPacketOut(const std::string& body) {
48 return PrependIPv6HeaderForTest(body, 4);
49}
50
51ParsedQuicVersionVector GetTestParams() {
fayang6a2c7aa2023-03-23 06:57:57 -070052 SetQuicReloadableFlag(quic_disable_version_q046, false);
fayangfc04b8a2023-05-18 09:26:25 -070053 return CurrentSupportedVersionsWithQuicCrypto();
Bence Békybac04052022-04-07 15:44:29 -040054}
55
56// Used by QuicCryptoServerConfig to provide server credentials, passes
57// everything through to ProofSourceForTesting if success is true,
58// and fails otherwise.
59class IndirectionProofSource : public ProofSource {
60 public:
61 explicit IndirectionProofSource(bool success) {
62 if (success) {
63 proof_source_ = crypto_test_utils::ProofSourceForTesting();
64 }
65 }
66
67 // ProofSource override.
68 void GetProof(const QuicSocketAddress& server_address,
69 const QuicSocketAddress& client_address,
bnc5e9007f2022-04-13 07:50:36 -070070 const std::string& hostname, const std::string& server_config,
Bence Békybac04052022-04-07 15:44:29 -040071 QuicTransportVersion transport_version,
72 absl::string_view chlo_hash,
73 std::unique_ptr<Callback> callback) override {
74 if (!proof_source_) {
75 QuicCryptoProof proof;
76 quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
77 GetCertChain(server_address, client_address, hostname,
78 &proof.cert_matched_sni);
79 callback->Run(/*ok=*/false, chain, proof, /*details=*/nullptr);
80 return;
81 }
82 proof_source_->GetProof(server_address, client_address, hostname,
83 server_config, transport_version, chlo_hash,
84 std::move(callback));
85 }
86
87 quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
88 const QuicSocketAddress& server_address,
89 const QuicSocketAddress& client_address, const std::string& hostname,
90 bool* cert_matched_sni) override {
91 if (!proof_source_) {
92 return quiche::QuicheReferenceCountedPointer<Chain>();
93 }
94 return proof_source_->GetCertChain(server_address, client_address, hostname,
95 cert_matched_sni);
96 }
97
98 void ComputeTlsSignature(
99 const QuicSocketAddress& server_address,
bnc5e9007f2022-04-13 07:50:36 -0700100 const QuicSocketAddress& client_address, const std::string& hostname,
101 uint16_t signature_algorithm, absl::string_view in,
Bence Békybac04052022-04-07 15:44:29 -0400102 std::unique_ptr<SignatureCallback> callback) override {
103 if (!proof_source_) {
104 callback->Run(/*ok=*/true, "Signature", /*details=*/nullptr);
105 return;
106 }
107 proof_source_->ComputeTlsSignature(server_address, client_address, hostname,
108 signature_algorithm, in,
109 std::move(callback));
110 }
111
112 absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
113 const override {
114 if (!proof_source_) {
115 return {};
116 }
117 return proof_source_->SupportedTlsSignatureAlgorithms();
118 }
119
120 TicketCrypter* GetTicketCrypter() override { return nullptr; }
121
122 private:
123 std::unique_ptr<ProofSource> proof_source_;
124};
125
126// Used by QuicCryptoClientConfig to verify server credentials, passes
127// everything through to ProofVerifierForTesting is success is true,
128// otherwise returns a canned response of QUIC_FAILURE.
129class IndirectionProofVerifier : public ProofVerifier {
130 public:
131 explicit IndirectionProofVerifier(bool success) {
132 if (success) {
133 proof_verifier_ = crypto_test_utils::ProofVerifierForTesting();
134 }
135 }
136
137 // ProofVerifier override
138 QuicAsyncStatus VerifyProof(
bnc5e9007f2022-04-13 07:50:36 -0700139 const std::string& hostname, const uint16_t port,
140 const std::string& server_config, QuicTransportVersion transport_version,
141 absl::string_view chlo_hash, const std::vector<std::string>& certs,
142 const std::string& cert_sct, const std::string& signature,
143 const ProofVerifyContext* context, std::string* error_details,
Bence Békybac04052022-04-07 15:44:29 -0400144 std::unique_ptr<ProofVerifyDetails>* verify_details,
145 std::unique_ptr<ProofVerifierCallback> callback) override {
146 if (!proof_verifier_) {
147 return QUIC_FAILURE;
148 }
149 return proof_verifier_->VerifyProof(
150 hostname, port, server_config, transport_version, chlo_hash, certs,
151 cert_sct, signature, context, error_details, verify_details,
152 std::move(callback));
153 }
154
155 QuicAsyncStatus VerifyCertChain(
bnc5e9007f2022-04-13 07:50:36 -0700156 const std::string& hostname, const uint16_t port,
157 const std::vector<std::string>& certs, const std::string& ocsp_response,
158 const std::string& cert_sct, const ProofVerifyContext* context,
159 std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
Bence Békybac04052022-04-07 15:44:29 -0400160 uint8_t* out_alert,
161 std::unique_ptr<ProofVerifierCallback> callback) override {
162 if (!proof_verifier_) {
163 return QUIC_FAILURE;
164 }
165 return proof_verifier_->VerifyCertChain(
166 hostname, port, certs, ocsp_response, cert_sct, context, error_details,
167 details, out_alert, std::move(callback));
168 }
169
170 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
171 if (!proof_verifier_) {
172 return nullptr;
173 }
174 return proof_verifier_->CreateDefaultContext();
175 }
176
177 private:
178 std::unique_ptr<ProofVerifier> proof_verifier_;
179};
180
181class DataSavingQbonePacketWriter : public QbonePacketWriter {
182 public:
183 void WritePacketToNetwork(const char* packet, size_t size) override {
184 data_.push_back(std::string(packet, size));
185 }
186
187 const std::vector<std::string>& data() { return data_; }
188
189 private:
190 std::vector<std::string> data_;
191};
192
193template <class T>
194class DataSavingQboneControlHandler : public QboneControlHandler<T> {
195 public:
196 void OnControlRequest(const T& request) override { data_.push_back(request); }
197
198 void OnControlError() override { error_ = true; }
199
200 const std::vector<T>& data() { return data_; }
201 bool error() { return error_; }
202
203 private:
204 std::vector<T> data_;
205 bool error_ = false;
206};
207
208// Single-threaded scheduled task runner based on a MockClock.
209//
210// Simulates asynchronous execution on a single thread by holding scheduled
211// tasks until Run() is called. Performs no synchronization, assumes that
212// Schedule() and Run() are called on the same thread.
213class FakeTaskRunner {
214 public:
215 explicit FakeTaskRunner(MockQuicConnectionHelper* helper)
216 : tasks_([](const TaskType& l, const TaskType& r) {
217 // Items at a later time should run after items at an earlier time.
218 // Priority queue comparisons should return true if l appears after r.
219 return l->time() > r->time();
220 }),
221 helper_(helper) {}
222
223 // Runs all tasks in time order. Executes tasks scheduled at
224 // the same in an arbitrary order.
225 void Run() {
226 while (!tasks_.empty()) {
227 tasks_.top()->Run();
228 tasks_.pop();
229 }
230 }
231
232 private:
233 class InnerTask {
234 public:
235 InnerTask(std::function<void()> task, QuicTime time)
236 : task_(std::move(task)), time_(time) {}
237
238 void Cancel() { cancelled_ = true; }
239
240 void Run() {
241 if (!cancelled_) {
vasilvv3d870652023-06-05 09:29:16 -0700242 std::move(task_)();
Bence Békybac04052022-04-07 15:44:29 -0400243 }
244 }
245
246 QuicTime time() const { return time_; }
247
248 private:
249 bool cancelled_ = false;
vasilvv3d870652023-06-05 09:29:16 -0700250 quiche::SingleUseCallback<void()> task_;
Bence Békybac04052022-04-07 15:44:29 -0400251 QuicTime time_;
252 };
253
254 public:
255 // Schedules a function to run immediately and advances the time.
256 void Schedule(std::function<void()> task) {
257 tasks_.push(std::shared_ptr<InnerTask>(
258 new InnerTask(std::move(task), helper_->GetClock()->Now())));
259 helper_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
260 }
261
262 private:
263 using TaskType = std::shared_ptr<InnerTask>;
vasilvv3d870652023-06-05 09:29:16 -0700264 std::priority_queue<
265 TaskType, std::vector<TaskType>,
266 quiche::UnretainedCallback<bool(const TaskType&, const TaskType&)>>
Bence Békybac04052022-04-07 15:44:29 -0400267 tasks_;
268 MockQuicConnectionHelper* helper_;
269};
270
271class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
272 public:
273 QboneSessionTest()
274 : supported_versions_({GetParam()}),
275 runner_(&helper_),
276 compressed_certs_cache_(100) {}
277
278 ~QboneSessionTest() override {
279 delete client_connection_;
280 delete server_connection_;
281 }
282
283 const MockClock* GetClock() const {
284 return static_cast<const MockClock*>(helper_.GetClock());
285 }
286
287 // The parameters are used to control whether the handshake will success or
288 // not.
289 void CreateClientAndServerSessions(bool client_handshake_success = true,
290 bool server_handshake_success = true,
291 bool send_qbone_alpn = true) {
292 // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
293 helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
vasilvv40f15e02022-09-06 06:16:43 -0700294 event_loop_ = GetDefaultEventLoop()->Create(QuicDefaultClock::Get());
295 alarm_factory_ = event_loop_->CreateAlarmFactory();
Bence Békybac04052022-04-07 15:44:29 -0400296 client_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
297 server_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
298 client_handler_ =
299 std::make_unique<DataSavingQboneControlHandler<QboneClientRequest>>();
300 server_handler_ =
301 std::make_unique<DataSavingQboneControlHandler<QboneServerRequest>>();
302 QuicSocketAddress server_address(TestLoopback(), 0);
303 QuicSocketAddress client_address;
304 if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
305 client_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
306 } else {
307 client_address = QuicSocketAddress(QuicIpAddress::Any6(), 0);
308 }
309
310 {
311 client_connection_ = new QuicConnection(
312 TestConnectionId(), client_address, server_address, &helper_,
313 alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
martinduke605dca22022-09-01 10:40:19 -0700314 Perspective::IS_CLIENT, supported_versions_,
315 connection_id_generator_);
Bence Békybac04052022-04-07 15:44:29 -0400316 client_connection_->SetSelfAddress(client_address);
317 QuicConfig config;
318 client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
319 std::make_unique<IndirectionProofVerifier>(client_handshake_success));
320 if (send_qbone_alpn) {
321 client_crypto_config_->set_alpn("qbone");
322 }
323 client_peer_ = std::make_unique<QboneClientSession>(
324 client_connection_, client_crypto_config_.get(),
325 /*owner=*/nullptr, config, supported_versions_,
326 QuicServerId("test.example.com", 1234, false), client_writer_.get(),
327 client_handler_.get());
328 }
329
330 {
331 server_connection_ = new QuicConnection(
332 TestConnectionId(), server_address, client_address, &helper_,
333 alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
martinduke605dca22022-09-01 10:40:19 -0700334 Perspective::IS_SERVER, supported_versions_,
335 connection_id_generator_);
Bence Békybac04052022-04-07 15:44:29 -0400336 server_connection_->SetSelfAddress(server_address);
337 QuicConfig config;
338 server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
339 QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
340 std::make_unique<IndirectionProofSource>(server_handshake_success),
341 KeyExchangeSource::Default());
342 QuicCryptoServerConfig::ConfigOptions options;
343 QuicServerConfigProtobuf primary_config =
344 server_crypto_config_->GenerateConfig(QuicRandom::GetInstance(),
345 GetClock(), options);
346 std::unique_ptr<CryptoHandshakeMessage> message(
347 server_crypto_config_->AddConfig(primary_config,
348 GetClock()->WallNow()));
349
350 server_peer_ = std::make_unique<QboneServerSession>(
351 supported_versions_, server_connection_, nullptr, config,
352 server_crypto_config_.get(), &compressed_certs_cache_,
353 server_writer_.get(), TestLoopback6(), TestLoopback6(), 64,
354 server_handler_.get());
355 }
356
357 // Hook everything up!
358 MockPacketWriter* client_writer = static_cast<MockPacketWriter*>(
359 QuicConnectionPeer::GetWriter(client_peer_->connection()));
martindukeacfdb392023-05-23 15:23:55 -0700360 ON_CALL(*client_writer, WritePacket(_, _, _, _, _, _))
Bence Békybac04052022-04-07 15:44:29 -0400361 .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
362 const QuicIpAddress& self_address,
363 const QuicSocketAddress& peer_address,
martindukeacfdb392023-05-23 15:23:55 -0700364 PerPacketOptions* option,
365 const QuicPacketWriterParams& params) {
Bence Békybac04052022-04-07 15:44:29 -0400366 char* copy = new char[1024 * 1024];
367 memcpy(copy, buffer, buf_len);
368 runner_.Schedule([this, copy, buf_len] {
369 QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
370 server_peer_->ProcessUdpPacket(server_connection_->self_address(),
371 client_connection_->self_address(),
372 packet);
373 delete[] copy;
374 });
375 return WriteResult(WRITE_STATUS_OK, buf_len);
376 }));
377 MockPacketWriter* server_writer = static_cast<MockPacketWriter*>(
378 QuicConnectionPeer::GetWriter(server_peer_->connection()));
martindukeacfdb392023-05-23 15:23:55 -0700379 ON_CALL(*server_writer, WritePacket(_, _, _, _, _, _))
Bence Békybac04052022-04-07 15:44:29 -0400380 .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
381 const QuicIpAddress& self_address,
382 const QuicSocketAddress& peer_address,
martindukeacfdb392023-05-23 15:23:55 -0700383 PerPacketOptions* options,
384 const QuicPacketWriterParams& params) {
Bence Békybac04052022-04-07 15:44:29 -0400385 char* copy = new char[1024 * 1024];
386 memcpy(copy, buffer, buf_len);
387 runner_.Schedule([this, copy, buf_len] {
388 QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
389 client_peer_->ProcessUdpPacket(client_connection_->self_address(),
390 server_connection_->self_address(),
391 packet);
392 delete[] copy;
393 });
394 return WriteResult(WRITE_STATUS_OK, buf_len);
395 }));
396 }
397
398 void StartHandshake() {
399 server_peer_->Initialize();
400 client_peer_->Initialize();
401 runner_.Run();
402 }
403
404 void ExpectICMPTooBigResponse(const std::vector<std::string>& written_packets,
bnc5e9007f2022-04-13 07:50:36 -0700405 const int mtu, const std::string& packet) {
Bence Békybac04052022-04-07 15:44:29 -0400406 auto* header = reinterpret_cast<const ip6_hdr*>(packet.data());
407 icmp6_hdr icmp_header{};
408 icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
409 icmp_header.icmp6_mtu = mtu;
410
411 std::string expected;
412 CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
413 [&expected](absl::string_view icmp_packet) {
414 expected = std::string(icmp_packet);
415 });
416
417 EXPECT_THAT(written_packets, Contains(expected));
418 }
419
420 // Test handshake establishment and sending/receiving of data for two
421 // directions.
422 void TestStreamConnection(bool use_messages) {
423 ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
424 ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
425 ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
426 ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
427
428 // Create an outgoing stream from the client and say hello.
429 QUIC_LOG(INFO) << "Sending client -> server";
430 client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello"));
431 client_peer_->ProcessPacketFromNetwork(TestPacketIn("world"));
432 runner_.Run();
433 // The server should see the data, the client hasn't received
434 // anything yet.
435 EXPECT_THAT(server_writer_->data(),
436 ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
437 EXPECT_TRUE(client_writer_->data().empty());
438 EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
439 EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
440
441 // Let's pretend some service responds.
442 QUIC_LOG(INFO) << "Sending server -> client";
443 server_peer_->ProcessPacketFromNetwork(TestPacketIn("Hello Again"));
444 server_peer_->ProcessPacketFromNetwork(TestPacketIn("Again"));
445 runner_.Run();
446 EXPECT_THAT(server_writer_->data(),
447 ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
448 EXPECT_THAT(
449 client_writer_->data(),
450 ElementsAre(TestPacketOut("Hello Again"), TestPacketOut("Again")));
451 EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
452 EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
453
454 // Try to send long payloads that are larger than the QUIC MTU but
455 // smaller than the QBONE max size.
456 // This should trigger the non-ephemeral stream code path.
457 std::string long_data(
458 QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
459 QUIC_LOG(INFO) << "Sending server -> client long data";
460 server_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
461 runner_.Run();
462 if (use_messages) {
463 ExpectICMPTooBigResponse(
464 server_writer_->data(),
465 server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
466 TestPacketOut(long_data));
467 } else {
468 EXPECT_THAT(client_writer_->data(), Contains(TestPacketOut(long_data)));
469 }
470 EXPECT_THAT(server_writer_->data(),
471 Not(Contains(TestPacketOut(long_data))));
472 EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
473 EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
474
475 QUIC_LOG(INFO) << "Sending client -> server long data";
476 client_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
477 runner_.Run();
478 if (use_messages) {
479 ExpectICMPTooBigResponse(
480 client_writer_->data(),
481 client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
482 TestPacketIn(long_data));
483 } else {
484 EXPECT_THAT(server_writer_->data(), Contains(TestPacketOut(long_data)));
485 }
486 EXPECT_FALSE(client_peer_->EarlyDataAccepted());
487 EXPECT_FALSE(client_peer_->ReceivedInchoateReject());
488 EXPECT_THAT(client_peer_->GetNumReceivedServerConfigUpdates(), Eq(0));
489
490 if (!use_messages) {
491 EXPECT_THAT(client_peer_->GetNumStreamedPackets(), Eq(1));
492 EXPECT_THAT(server_peer_->GetNumStreamedPackets(), Eq(1));
493 }
494
495 if (use_messages) {
496 EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
497 EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
498 EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
499 EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
500 } else {
501 EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(2));
502 EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(2));
503 EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(0));
504 EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(0));
505 }
506
507 // All streams are ephemeral and should be gone.
508 EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
509 EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
510 }
511
512 // Test that client and server are not connected after handshake failure.
513 void TestDisconnectAfterFailedHandshake() {
514 EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
515 EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
516
517 EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
518 EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
519 }
520
521 protected:
522 const ParsedQuicVersionVector supported_versions_;
vasilvv40f15e02022-09-06 06:16:43 -0700523 std::unique_ptr<QuicEventLoop> event_loop_;
Bence Békybac04052022-04-07 15:44:29 -0400524 std::unique_ptr<QuicAlarmFactory> alarm_factory_;
525 FakeTaskRunner runner_;
526 MockQuicConnectionHelper helper_;
527 QuicConnection* client_connection_;
528 QuicConnection* server_connection_;
529 QuicCompressedCertsCache compressed_certs_cache_;
530
531 std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
532 std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
533 std::unique_ptr<DataSavingQbonePacketWriter> client_writer_;
534 std::unique_ptr<DataSavingQbonePacketWriter> server_writer_;
535 std::unique_ptr<DataSavingQboneControlHandler<QboneClientRequest>>
536 client_handler_;
537 std::unique_ptr<DataSavingQboneControlHandler<QboneServerRequest>>
538 server_handler_;
539
540 std::unique_ptr<QboneServerSession> server_peer_;
541 std::unique_ptr<QboneClientSession> client_peer_;
martinduke605dca22022-09-01 10:40:19 -0700542 MockConnectionIdGenerator connection_id_generator_;
Bence Békybac04052022-04-07 15:44:29 -0400543};
544
bnc5e9007f2022-04-13 07:50:36 -0700545INSTANTIATE_TEST_SUITE_P(Tests, QboneSessionTest,
Bence Békybac04052022-04-07 15:44:29 -0400546 ::testing::ValuesIn(GetTestParams()),
547 ::testing::PrintToStringParamName());
548
549TEST_P(QboneSessionTest, StreamConnection) {
550 CreateClientAndServerSessions();
551 client_peer_->set_send_packets_as_messages(false);
552 server_peer_->set_send_packets_as_messages(false);
553 StartHandshake();
554 TestStreamConnection(false);
555}
556
557TEST_P(QboneSessionTest, Messages) {
558 CreateClientAndServerSessions();
559 client_peer_->set_send_packets_as_messages(true);
560 server_peer_->set_send_packets_as_messages(true);
561 StartHandshake();
562 TestStreamConnection(true);
563}
564
565TEST_P(QboneSessionTest, ClientRejection) {
566 CreateClientAndServerSessions(false /*client_handshake_success*/,
567 true /*server_handshake_success*/,
568 true /*send_qbone_alpn*/);
569 StartHandshake();
570 TestDisconnectAfterFailedHandshake();
571}
572
573TEST_P(QboneSessionTest, BadAlpn) {
574 CreateClientAndServerSessions(true /*client_handshake_success*/,
575 true /*server_handshake_success*/,
576 false /*send_qbone_alpn*/);
577 StartHandshake();
578 TestDisconnectAfterFailedHandshake();
579}
580
581TEST_P(QboneSessionTest, ServerRejection) {
582 CreateClientAndServerSessions(true /*client_handshake_success*/,
583 false /*server_handshake_success*/,
584 true /*send_qbone_alpn*/);
585 StartHandshake();
586 TestDisconnectAfterFailedHandshake();
587}
588
589// Test that data streams are not created before handshake.
590TEST_P(QboneSessionTest, CannotCreateDataStreamBeforeHandshake) {
591 CreateClientAndServerSessions();
592 EXPECT_QUIC_BUG(client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
593 "Attempting to send packet before encryption established");
594 EXPECT_QUIC_BUG(server_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
595 "Attempting to send packet before encryption established");
596 EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
597 EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
598}
599
600TEST_P(QboneSessionTest, ControlRequests) {
601 CreateClientAndServerSessions();
602 StartHandshake();
603 EXPECT_TRUE(client_handler_->data().empty());
604 EXPECT_FALSE(client_handler_->error());
605 EXPECT_TRUE(server_handler_->data().empty());
606 EXPECT_FALSE(server_handler_->error());
607
608 QboneClientRequest client_request;
609 client_request.SetExtension(client_placeholder, "hello from the server");
610 EXPECT_TRUE(server_peer_->SendClientRequest(client_request));
611 runner_.Run();
612 ASSERT_FALSE(client_handler_->data().empty());
613 EXPECT_THAT(client_handler_->data()[0].GetExtension(client_placeholder),
614 Eq("hello from the server"));
615 EXPECT_FALSE(client_handler_->error());
616
617 QboneServerRequest server_request;
618 server_request.SetExtension(server_placeholder, "hello from the client");
619 EXPECT_TRUE(client_peer_->SendServerRequest(server_request));
620 runner_.Run();
621 ASSERT_FALSE(server_handler_->data().empty());
622 EXPECT_THAT(server_handler_->data()[0].GetExtension(server_placeholder),
623 Eq("hello from the client"));
624 EXPECT_FALSE(server_handler_->error());
625}
626
627} // namespace
628} // namespace test
629} // namespace quic