1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quiche/quic/masque/masque_client.h"
#include <string>
#include "absl/memory/memory.h"
#include "quiche/quic/masque/masque_client_session.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_url.h"
namespace quic {
MasqueClient::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)
: QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
event_loop, std::move(proof_verifier)),
masque_mode_(masque_mode),
uri_template_(uri_template) {}
std::unique_ptr<QuicSession> MasqueClient::CreateQuicClientSession(
const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection) {
QUIC_DLOG(INFO) << "Creating MASQUE session for "
<< connection->connection_id();
return std::make_unique<MasqueClientSession>(
masque_mode_, uri_template_, *config(), supported_versions, connection,
server_id(), crypto_config(), push_promise_index(), this);
}
MasqueClientSession* MasqueClient::masque_client_session() {
return static_cast<MasqueClientSession*>(QuicDefaultClient::session());
}
QuicConnectionId MasqueClient::connection_id() {
return masque_client_session()->connection_id();
}
std::string MasqueClient::authority() const {
QuicUrl url(uri_template_);
return absl::StrCat(url.host(), ":", url.port());
}
// static
std::unique_ptr<MasqueClient> MasqueClient::Create(
const std::string& uri_template, MasqueMode masque_mode,
QuicEventLoop* event_loop, std::unique_ptr<ProofVerifier> proof_verifier) {
QuicUrl url(uri_template);
std::string host = url.host();
uint16_t port = url.port();
// Build the masque_client, and try to connect.
QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
if (!addr.IsInitialized()) {
QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
return nullptr;
}
QuicServerId server_id(host, port);
// Use absl::WrapUnique(new MasqueClient(...)) instead of
// std::make_unique<MasqueClient>(...) because the constructor for
// MasqueClient is private and therefore not accessible from make_unique.
auto masque_client = absl::WrapUnique(
new MasqueClient(addr, server_id, masque_mode, event_loop,
std::move(proof_verifier), uri_template));
if (masque_client == nullptr) {
QUIC_LOG(ERROR) << "Failed to create masque_client";
return nullptr;
}
masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
masque_client->set_drop_response_body(false);
if (!masque_client->Initialize()) {
QUIC_LOG(ERROR) << "Failed to initialize masque_client";
return nullptr;
}
if (!masque_client->Connect()) {
QuicErrorCode error = masque_client->session()->error();
QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
<< ". Error: " << QuicErrorCodeToString(error);
return nullptr;
}
if (!masque_client->WaitUntilSettingsReceived()) {
QUIC_LOG(ERROR) << "Failed to receive settings";
return nullptr;
}
return masque_client;
}
void MasqueClient::OnSettingsReceived() { settings_received_ = true; }
bool MasqueClient::WaitUntilSettingsReceived() {
while (connected() && !settings_received_) {
network_helper()->RunEventLoop();
}
return connected() && settings_received_;
}
} // namespace quic
|