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