summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc154
1 files changed, 154 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
new file mode 100644
index 00000000000..6d6470bc099
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
@@ -0,0 +1,154 @@
+// 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_epoll_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_url.h"
+
+namespace quic {
+
+MasqueEpollClient::MasqueEpollClient(
+ QuicSocketAddress server_address, const QuicServerId& server_id,
+ MasqueMode masque_mode, QuicEpollServer* epoll_server,
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ const std::string& uri_template)
+ : QuicClient(server_address, server_id, MasqueSupportedVersions(),
+ epoll_server, std::move(proof_verifier)),
+ masque_mode_(masque_mode),
+ uri_template_(uri_template) {}
+
+std::unique_ptr<QuicSession> MasqueEpollClient::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* MasqueEpollClient::masque_client_session() {
+ return static_cast<MasqueClientSession*>(QuicClient::session());
+}
+
+QuicConnectionId MasqueEpollClient::connection_id() {
+ return masque_client_session()->connection_id();
+}
+
+std::string MasqueEpollClient::authority() const {
+ QuicUrl url(uri_template_);
+ return absl::StrCat(url.host(), ":", url.port());
+}
+
+// static
+std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
+ const std::string& uri_template, MasqueMode masque_mode,
+ QuicEpollServer* epoll_server,
+ 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 MasqueEpollClient(...)) instead of
+ // std::make_unique<MasqueEpollClient>(...) because the constructor for
+ // MasqueEpollClient is private and therefore not accessible from make_unique.
+ auto masque_client = absl::WrapUnique(
+ new MasqueEpollClient(addr, server_id, masque_mode, epoll_server,
+ 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;
+ }
+
+ if (masque_client->masque_mode() == MasqueMode::kLegacy) {
+ // Construct the legacy mode init request.
+ spdy::Http2HeaderBlock header_block;
+ header_block[":method"] = "POST";
+ header_block[":scheme"] = "https";
+ header_block[":authority"] = masque_client->authority();
+ header_block[":path"] = "/.well-known/masque/init";
+ std::string body = "foo";
+
+ // Make sure to store the response, for later output.
+ masque_client->set_store_response(true);
+
+ // Send the MASQUE init command.
+ masque_client->SendRequestAndWaitForResponse(header_block, body,
+ /*fin=*/true);
+
+ if (!masque_client->connected()) {
+ QUIC_LOG(ERROR)
+ << "MASQUE init request caused connection failure. Error: "
+ << QuicErrorCodeToString(masque_client->session()->error());
+ return nullptr;
+ }
+
+ const int response_code = masque_client->latest_response_code();
+ if (response_code != 200) {
+ QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
+ << response_code;
+ return nullptr;
+ }
+ }
+ return masque_client;
+}
+
+void MasqueEpollClient::OnSettingsReceived() { settings_received_ = true; }
+
+bool MasqueEpollClient::WaitUntilSettingsReceived() {
+ while (connected() && !settings_received_) {
+ network_helper()->RunEventLoop();
+ }
+ return connected() && settings_received_;
+}
+
+void MasqueEpollClient::UnregisterClientConnectionId(
+ QuicConnectionId client_connection_id) {
+ std::string body(client_connection_id.data(), client_connection_id.length());
+
+ // Construct a GET or POST request for supplied URL.
+ spdy::Http2HeaderBlock header_block;
+ header_block[":method"] = "POST";
+ header_block[":scheme"] = "https";
+ header_block[":authority"] = authority();
+ header_block[":path"] = "/.well-known/masque/unregister";
+
+ // Make sure to store the response, for later output.
+ set_store_response(true);
+
+ // Send the MASQUE unregister command.
+ SendRequest(header_block, body, /*fin=*/true);
+}
+
+} // namespace quic