blob: 920372574a1909084114a70ad957b379e5e84a9c [file] [log] [blame]
dschinazi1c99fcf2019-12-13 11:54:22 -08001// 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// This file is reponsible for the masque_client binary. It allows testing
6// our MASQUE client code by connecting to a MASQUE proxy and then sending
7// HTTP/3 requests to web servers tunnelled over that MASQUE connection.
8// e.g.: masque_client $PROXY_HOST:$PROXY_PORT $URL1 $URL2
9
10#include <memory>
11
vasilvv13aa6a02020-12-03 13:02:33 -080012#include "absl/strings/str_cat.h"
vasilvv3049b2b2020-10-08 08:18:31 -070013#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050014#include "quic/core/quic_server_id.h"
15#include "quic/masque/masque_client_tools.h"
16#include "quic/masque/masque_encapsulated_epoll_client.h"
17#include "quic/masque/masque_epoll_client.h"
18#include "quic/masque/masque_utils.h"
19#include "quic/platform/api/quic_default_proof_providers.h"
20#include "quic/platform/api/quic_flags.h"
21#include "quic/platform/api/quic_socket_address.h"
22#include "quic/platform/api/quic_system_event_loop.h"
23#include "quic/tools/fake_proof_verifier.h"
24#include "quic/tools/quic_url.h"
dschinazi1c99fcf2019-12-13 11:54:22 -080025
26DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
27 disable_certificate_verification,
28 false,
29 "If true, don't verify the server certificate.");
30
dschinazida88cd12021-02-25 11:44:05 -080031DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
32 masque_mode,
33 "",
34 "Allows setting MASQUE mode, valid values are "
35 "open and legacy. Defaults to open.");
36
dschinazi1c99fcf2019-12-13 11:54:22 -080037namespace quic {
38
39namespace {
40
41int RunMasqueClient(int argc, char* argv[]) {
42 QuicSystemEventLoop event_loop("masque_client");
43 const char* usage = "Usage: masque_client [options] <url>";
44
45 // The first non-flag argument is the MASQUE server. All subsequent ones are
46 // interpreted as URLs to fetch via the MASQUE server.
47 std::vector<std::string> urls = QuicParseCommandLineFlags(usage, argc, argv);
48 if (urls.empty()) {
49 QuicPrintCommandLineFlagHelp(usage);
50 return 1;
51 }
52
dschinazi388d7f92021-02-25 20:58:46 -080053 SetQuicReloadableFlag(quic_h3_datagram, true);
54
dschinazi1c99fcf2019-12-13 11:54:22 -080055 const bool disable_certificate_verification =
56 GetQuicFlag(FLAGS_disable_certificate_verification);
57 QuicEpollServer epoll_server;
58
59 QuicUrl masque_url(urls[0], "https");
60 if (masque_url.host().empty()) {
vasilvv13aa6a02020-12-03 13:02:33 -080061 masque_url = QuicUrl(absl::StrCat("https://", urls[0]), "https");
dschinazi1c99fcf2019-12-13 11:54:22 -080062 }
63 if (masque_url.host().empty()) {
dschinazida88cd12021-02-25 11:44:05 -080064 std::cerr << "Failed to parse MASQUE server address \"" << urls[0] << "\""
65 << std::endl;
dschinazi1c99fcf2019-12-13 11:54:22 -080066 return 1;
67 }
68 std::unique_ptr<ProofVerifier> proof_verifier;
69 if (disable_certificate_verification) {
70 proof_verifier = std::make_unique<FakeProofVerifier>();
71 } else {
72 proof_verifier = CreateDefaultProofVerifier(masque_url.host());
73 }
dschinazida88cd12021-02-25 11:44:05 -080074 MasqueMode masque_mode = MasqueMode::kOpen;
75 std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
76 if (mode_string == "legacy") {
77 masque_mode = MasqueMode::kLegacy;
78 } else if (!mode_string.empty() && mode_string != "open") {
79 std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
80 return 1;
81 }
82 std::unique_ptr<MasqueEpollClient> masque_client = MasqueEpollClient::Create(
83 masque_url.host(), masque_url.port(), masque_mode, &epoll_server,
84 std::move(proof_verifier));
dschinazi1c99fcf2019-12-13 11:54:22 -080085 if (masque_client == nullptr) {
86 return 1;
87 }
88
89 std::cerr << "MASQUE is connected " << masque_client->connection_id()
dschinazida88cd12021-02-25 11:44:05 -080090 << " in " << masque_mode << " mode" << std::endl;
dschinazi1c99fcf2019-12-13 11:54:22 -080091
92 for (size_t i = 1; i < urls.size(); ++i) {
93 if (!tools::SendEncapsulatedMasqueRequest(
94 masque_client.get(), &epoll_server, urls[i],
95 disable_certificate_verification)) {
96 return 1;
97 }
98 }
99
100 return 0;
101}
102
103} // namespace
104
105} // namespace quic
106
107int main(int argc, char* argv[]) {
108 return quic::RunMasqueClient(argc, argv);
109}