xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/masque/masque_client.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 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 "quiche/quic/masque/masque_client.h"
6 
7 #include <cstdint>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "absl/memory/memory.h"
13 #include "absl/strings/str_cat.h"
14 #include "quiche/quic/core/crypto/proof_verifier.h"
15 #include "quiche/quic/core/io/quic_event_loop.h"
16 #include "quiche/quic/core/quic_connection.h"
17 #include "quiche/quic/core/quic_connection_id.h"
18 #include "quiche/quic/core/quic_error_codes.h"
19 #include "quiche/quic/core/quic_session.h"
20 #include "quiche/quic/core/quic_versions.h"
21 #include "quiche/quic/masque/masque_client_session.h"
22 #include "quiche/quic/masque/masque_utils.h"
23 #include "quiche/quic/platform/api/quic_logging.h"
24 #include "quiche/quic/platform/api/quic_socket_address.h"
25 #include "quiche/quic/tools/quic_default_client.h"
26 #include "quiche/quic/tools/quic_name_lookup.h"
27 #include "quiche/quic/tools/quic_url.h"
28 
29 namespace quic {
30 
MasqueClient(QuicSocketAddress server_address,const QuicServerId & server_id,MasqueMode masque_mode,QuicEventLoop * event_loop,std::unique_ptr<ProofVerifier> proof_verifier,const std::string & uri_template)31 MasqueClient::MasqueClient(QuicSocketAddress server_address,
32                            const QuicServerId& server_id,
33                            MasqueMode masque_mode, QuicEventLoop* event_loop,
34                            std::unique_ptr<ProofVerifier> proof_verifier,
35                            const std::string& uri_template)
36     : QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
37                         event_loop, std::move(proof_verifier)),
38       masque_mode_(masque_mode),
39       uri_template_(uri_template) {}
40 
CreateQuicClientSession(const ParsedQuicVersionVector & supported_versions,QuicConnection * connection)41 std::unique_ptr<QuicSession> MasqueClient::CreateQuicClientSession(
42     const ParsedQuicVersionVector& supported_versions,
43     QuicConnection* connection) {
44   QUIC_DLOG(INFO) << "Creating MASQUE session for "
45                   << connection->connection_id();
46   return std::make_unique<MasqueClientSession>(
47       masque_mode_, uri_template_, *config(), supported_versions, connection,
48       server_id(), crypto_config(), this);
49 }
50 
masque_client_session()51 MasqueClientSession* MasqueClient::masque_client_session() {
52   return static_cast<MasqueClientSession*>(QuicDefaultClient::session());
53 }
54 
connection_id()55 QuicConnectionId MasqueClient::connection_id() {
56   return masque_client_session()->connection_id();
57 }
58 
authority() const59 std::string MasqueClient::authority() const {
60   QuicUrl url(uri_template_);
61   return absl::StrCat(url.host(), ":", url.port());
62 }
63 
64 // static
Create(const std::string & uri_template,MasqueMode masque_mode,QuicEventLoop * event_loop,std::unique_ptr<ProofVerifier> proof_verifier)65 std::unique_ptr<MasqueClient> MasqueClient::Create(
66     const std::string& uri_template, MasqueMode masque_mode,
67     QuicEventLoop* event_loop, std::unique_ptr<ProofVerifier> proof_verifier) {
68   QuicUrl url(uri_template);
69   std::string host = url.host();
70   uint16_t port = url.port();
71   // Build the masque_client, and try to connect.
72   QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
73   if (!addr.IsInitialized()) {
74     QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
75     return nullptr;
76   }
77   QuicServerId server_id(host, port);
78   // Use absl::WrapUnique(new MasqueClient(...)) instead of
79   // std::make_unique<MasqueClient>(...) because the constructor for
80   // MasqueClient is private and therefore not accessible from make_unique.
81   auto masque_client = absl::WrapUnique(
82       new MasqueClient(addr, server_id, masque_mode, event_loop,
83                        std::move(proof_verifier), uri_template));
84 
85   if (masque_client == nullptr) {
86     QUIC_LOG(ERROR) << "Failed to create masque_client";
87     return nullptr;
88   }
89 
90   masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
91   masque_client->set_drop_response_body(false);
92   if (!masque_client->Initialize()) {
93     QUIC_LOG(ERROR) << "Failed to initialize masque_client";
94     return nullptr;
95   }
96   if (!masque_client->Connect()) {
97     QuicErrorCode error = masque_client->session()->error();
98     QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
99                     << ". Error: " << QuicErrorCodeToString(error);
100     return nullptr;
101   }
102 
103   if (!masque_client->WaitUntilSettingsReceived()) {
104     QUIC_LOG(ERROR) << "Failed to receive settings";
105     return nullptr;
106   }
107 
108   return masque_client;
109 }
110 
OnSettingsReceived()111 void MasqueClient::OnSettingsReceived() { settings_received_ = true; }
112 
WaitUntilSettingsReceived()113 bool MasqueClient::WaitUntilSettingsReceived() {
114   while (connected() && !settings_received_) {
115     network_helper()->RunEventLoop();
116   }
117   return connected() && settings_received_;
118 }
119 
120 }  // namespace quic
121