xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // 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 
5 #include <memory>
6 #include <utility>
7 
8 #include "absl/strings/string_view.h"
9 #include "quiche/quic/core/io/quic_default_event_loop.h"
10 #include "quiche/quic/core/io/quic_event_loop.h"
11 #include "quiche/quic/core/proto/crypto_server_config_proto.h"
12 #include "quiche/quic/core/quic_alarm_factory.h"
13 #include "quiche/quic/core/quic_default_clock.h"
14 #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"
25 #include "quiche/quic/test_tools/mock_connection_id_generator.h"
26 #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 #include "quiche/common/quiche_callbacks.h"
30 
31 namespace quic {
32 namespace test {
33 namespace {
34 
35 using ::testing::_;
36 using ::testing::Contains;
37 using ::testing::ElementsAre;
38 using ::testing::Eq;
39 using ::testing::Invoke;
40 using ::testing::NiceMock;
41 using ::testing::Not;
42 
TestPacketIn(const std::string & body)43 std::string TestPacketIn(const std::string& body) {
44   return PrependIPv6HeaderForTest(body, 5);
45 }
46 
TestPacketOut(const std::string & body)47 std::string TestPacketOut(const std::string& body) {
48   return PrependIPv6HeaderForTest(body, 4);
49 }
50 
GetTestParams()51 ParsedQuicVersionVector GetTestParams() {
52   SetQuicReloadableFlag(quic_disable_version_q046, false);
53   return CurrentSupportedVersionsWithQuicCrypto();
54 }
55 
56 // Used by QuicCryptoServerConfig to provide server credentials, passes
57 // everything through to ProofSourceForTesting if success is true,
58 // and fails otherwise.
59 class IndirectionProofSource : public ProofSource {
60  public:
IndirectionProofSource(bool success)61   explicit IndirectionProofSource(bool success) {
62     if (success) {
63       proof_source_ = crypto_test_utils::ProofSourceForTesting();
64     }
65   }
66 
67   // ProofSource override.
GetProof(const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const std::string & hostname,const std::string & server_config,QuicTransportVersion transport_version,absl::string_view chlo_hash,std::unique_ptr<Callback> callback)68   void GetProof(const QuicSocketAddress& server_address,
69                 const QuicSocketAddress& client_address,
70                 const std::string& hostname, const std::string& server_config,
71                 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 
GetCertChain(const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const std::string & hostname,bool * cert_matched_sni)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 
ComputeTlsSignature(const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const std::string & hostname,uint16_t signature_algorithm,absl::string_view in,std::unique_ptr<SignatureCallback> callback)98   void ComputeTlsSignature(
99       const QuicSocketAddress& server_address,
100       const QuicSocketAddress& client_address, const std::string& hostname,
101       uint16_t signature_algorithm, absl::string_view in,
102       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 
SupportedTlsSignatureAlgorithms() const112   absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
113       const override {
114     if (!proof_source_) {
115       return {};
116     }
117     return proof_source_->SupportedTlsSignatureAlgorithms();
118   }
119 
GetTicketCrypter()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.
129 class IndirectionProofVerifier : public ProofVerifier {
130  public:
IndirectionProofVerifier(bool success)131   explicit IndirectionProofVerifier(bool success) {
132     if (success) {
133       proof_verifier_ = crypto_test_utils::ProofVerifierForTesting();
134     }
135   }
136 
137   // ProofVerifier override
VerifyProof(const std::string & hostname,const uint16_t port,const std::string & server_config,QuicTransportVersion transport_version,absl::string_view chlo_hash,const std::vector<std::string> & certs,const std::string & cert_sct,const std::string & signature,const ProofVerifyContext * context,std::string * error_details,std::unique_ptr<ProofVerifyDetails> * verify_details,std::unique_ptr<ProofVerifierCallback> callback)138   QuicAsyncStatus VerifyProof(
139       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,
144       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 
VerifyCertChain(const std::string & hostname,const uint16_t port,const std::vector<std::string> & certs,const std::string & ocsp_response,const std::string & cert_sct,const ProofVerifyContext * context,std::string * error_details,std::unique_ptr<ProofVerifyDetails> * details,uint8_t * out_alert,std::unique_ptr<ProofVerifierCallback> callback)155   QuicAsyncStatus VerifyCertChain(
156       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,
160       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 
CreateDefaultContext()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 
181 class DataSavingQbonePacketWriter : public QbonePacketWriter {
182  public:
WritePacketToNetwork(const char * packet,size_t size)183   void WritePacketToNetwork(const char* packet, size_t size) override {
184     data_.push_back(std::string(packet, size));
185   }
186 
data()187   const std::vector<std::string>& data() { return data_; }
188 
189  private:
190   std::vector<std::string> data_;
191 };
192 
193 template <class T>
194 class DataSavingQboneControlHandler : public QboneControlHandler<T> {
195  public:
OnControlRequest(const T & request)196   void OnControlRequest(const T& request) override { data_.push_back(request); }
197 
OnControlError()198   void OnControlError() override { error_ = true; }
199 
data()200   const std::vector<T>& data() { return data_; }
error()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.
213 class FakeTaskRunner {
214  public:
FakeTaskRunner(MockQuicConnectionHelper * helper)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.
Run()225   void Run() {
226     while (!tasks_.empty()) {
227       tasks_.top()->Run();
228       tasks_.pop();
229     }
230   }
231 
232  private:
233   class InnerTask {
234    public:
InnerTask(std::function<void ()> task,QuicTime time)235     InnerTask(std::function<void()> task, QuicTime time)
236         : task_(std::move(task)), time_(time) {}
237 
Cancel()238     void Cancel() { cancelled_ = true; }
239 
Run()240     void Run() {
241       if (!cancelled_) {
242         std::move(task_)();
243       }
244     }
245 
time() const246     QuicTime time() const { return time_; }
247 
248    private:
249     bool cancelled_ = false;
250     quiche::SingleUseCallback<void()> task_;
251     QuicTime time_;
252   };
253 
254  public:
255   // Schedules a function to run immediately and advances the time.
Schedule(std::function<void ()> task)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>;
264   std::priority_queue<
265       TaskType, std::vector<TaskType>,
266       quiche::UnretainedCallback<bool(const TaskType&, const TaskType&)>>
267       tasks_;
268   MockQuicConnectionHelper* helper_;
269 };
270 
271 class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
272  public:
QboneSessionTest()273   QboneSessionTest()
274       : supported_versions_({GetParam()}),
275         runner_(&helper_),
276         compressed_certs_cache_(100) {}
277 
~QboneSessionTest()278   ~QboneSessionTest() override {
279     delete client_connection_;
280     delete server_connection_;
281   }
282 
GetClock() const283   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.
CreateClientAndServerSessions(bool client_handshake_success=true,bool server_handshake_success=true,bool send_qbone_alpn=true)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));
294     event_loop_ = GetDefaultEventLoop()->Create(QuicDefaultClock::Get());
295     alarm_factory_ = event_loop_->CreateAlarmFactory();
296     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,
314           Perspective::IS_CLIENT, supported_versions_,
315           connection_id_generator_);
316       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,
334           Perspective::IS_SERVER, supported_versions_,
335           connection_id_generator_);
336       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()));
360     ON_CALL(*client_writer, WritePacket(_, _, _, _, _, _))
361         .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
362                                      const QuicIpAddress& self_address,
363                                      const QuicSocketAddress& peer_address,
364                                      PerPacketOptions* option,
365                                      const QuicPacketWriterParams& params) {
366           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()));
379     ON_CALL(*server_writer, WritePacket(_, _, _, _, _, _))
380         .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
381                                      const QuicIpAddress& self_address,
382                                      const QuicSocketAddress& peer_address,
383                                      PerPacketOptions* options,
384                                      const QuicPacketWriterParams& params) {
385           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 
StartHandshake()398   void StartHandshake() {
399     server_peer_->Initialize();
400     client_peer_->Initialize();
401     runner_.Run();
402   }
403 
ExpectICMPTooBigResponse(const std::vector<std::string> & written_packets,const int mtu,const std::string & packet)404   void ExpectICMPTooBigResponse(const std::vector<std::string>& written_packets,
405                                 const int mtu, const std::string& packet) {
406     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.
TestStreamConnection(bool use_messages)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.
TestDisconnectAfterFailedHandshake()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_;
523   std::unique_ptr<QuicEventLoop> event_loop_;
524   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_;
542   MockConnectionIdGenerator connection_id_generator_;
543 };
544 
545 INSTANTIATE_TEST_SUITE_P(Tests, QboneSessionTest,
546                          ::testing::ValuesIn(GetTestParams()),
547                          ::testing::PrintToStringParamName());
548 
TEST_P(QboneSessionTest,StreamConnection)549 TEST_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 
TEST_P(QboneSessionTest,Messages)557 TEST_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 
TEST_P(QboneSessionTest,ClientRejection)565 TEST_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 
TEST_P(QboneSessionTest,BadAlpn)573 TEST_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 
TEST_P(QboneSessionTest,ServerRejection)581 TEST_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.
TEST_P(QboneSessionTest,CannotCreateDataStreamBeforeHandshake)590 TEST_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 
TEST_P(QboneSessionTest,ControlRequests)600 TEST_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
630