mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-25 06:46:09 +03:00
Refactor config parsing
This commit is contained in:
parent
c975384d22
commit
d434781c6a
@ -1744,6 +1744,12 @@ static_library("preload_decoder") {
|
|||||||
|
|
||||||
executable("naive") {
|
executable("naive") {
|
||||||
sources = [
|
sources = [
|
||||||
|
"tools/naive/http_proxy_server_socket.cc",
|
||||||
|
"tools/naive/http_proxy_server_socket.h",
|
||||||
|
"tools/naive/naive_command_line.cc",
|
||||||
|
"tools/naive/naive_command_line.h",
|
||||||
|
"tools/naive/naive_config.cc",
|
||||||
|
"tools/naive/naive_config.h",
|
||||||
"tools/naive/naive_connection.cc",
|
"tools/naive/naive_connection.cc",
|
||||||
"tools/naive/naive_connection.h",
|
"tools/naive/naive_connection.h",
|
||||||
"tools/naive/naive_padding_framer.cc",
|
"tools/naive/naive_padding_framer.cc",
|
||||||
@ -1752,15 +1758,13 @@ executable("naive") {
|
|||||||
"tools/naive/naive_padding_socket.h",
|
"tools/naive/naive_padding_socket.h",
|
||||||
"tools/naive/naive_protocol.cc",
|
"tools/naive/naive_protocol.cc",
|
||||||
"tools/naive/naive_protocol.h",
|
"tools/naive/naive_protocol.h",
|
||||||
|
"tools/naive/naive_proxy_bin.cc",
|
||||||
|
"tools/naive/naive_proxy_delegate.cc",
|
||||||
|
"tools/naive/naive_proxy_delegate.h",
|
||||||
"tools/naive/naive_proxy.cc",
|
"tools/naive/naive_proxy.cc",
|
||||||
"tools/naive/naive_proxy.h",
|
"tools/naive/naive_proxy.h",
|
||||||
"tools/naive/naive_proxy_bin.cc",
|
|
||||||
"tools/naive/naive_proxy_delegate.h",
|
|
||||||
"tools/naive/naive_proxy_delegate.cc",
|
|
||||||
"tools/naive/http_proxy_server_socket.cc",
|
|
||||||
"tools/naive/http_proxy_server_socket.h",
|
|
||||||
"tools/naive/redirect_resolver.h",
|
|
||||||
"tools/naive/redirect_resolver.cc",
|
"tools/naive/redirect_resolver.cc",
|
||||||
|
"tools/naive/redirect_resolver.h",
|
||||||
"tools/naive/socks5_server_socket.cc",
|
"tools/naive/socks5_server_socket.cc",
|
||||||
"tools/naive/socks5_server_socket.h",
|
"tools/naive/socks5_server_socket.h",
|
||||||
]
|
]
|
||||||
|
61
src/net/tools/naive/naive_command_line.cc
Normal file
61
src/net/tools/naive/naive_command_line.cc
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
#include "net/tools/naive/naive_command_line.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
|
||||||
|
DuplicateSwitchCollector::DuplicateSwitchCollector() = default;
|
||||||
|
DuplicateSwitchCollector::~DuplicateSwitchCollector() = default;
|
||||||
|
|
||||||
|
void DuplicateSwitchCollector::ResolveDuplicate(
|
||||||
|
std::string_view key,
|
||||||
|
base::CommandLine::StringPieceType new_value,
|
||||||
|
base::CommandLine::StringType& out_value) {
|
||||||
|
out_value = new_value;
|
||||||
|
values_by_key_[std::string(key)].push_back(
|
||||||
|
base::CommandLine::StringType(new_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<base::CommandLine::StringType>&
|
||||||
|
DuplicateSwitchCollector::GetValuesByKey(std::string_view key) {
|
||||||
|
return values_by_key_[std::string(key)];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
DuplicateSwitchCollector* g_duplicate_switch_collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DuplicateSwitchCollector::InitInstance() {
|
||||||
|
auto new_duplicate_switch_collector =
|
||||||
|
std::make_unique<DuplicateSwitchCollector>();
|
||||||
|
g_duplicate_switch_collector = new_duplicate_switch_collector.get();
|
||||||
|
base::CommandLine::SetDuplicateSwitchHandler(
|
||||||
|
std::move(new_duplicate_switch_collector));
|
||||||
|
}
|
||||||
|
|
||||||
|
DuplicateSwitchCollector& DuplicateSwitchCollector::GetInstance() {
|
||||||
|
CHECK(g_duplicate_switch_collector != nullptr);
|
||||||
|
return *g_duplicate_switch_collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
base::Value::Dict GetSwitchesAsValue(const base::CommandLine& cmdline) {
|
||||||
|
base::Value::Dict dict;
|
||||||
|
for (const auto& [key, value] : cmdline.GetSwitches()) {
|
||||||
|
const std::vector<base::CommandLine::StringType>& values =
|
||||||
|
DuplicateSwitchCollector::GetInstance().GetValuesByKey(key);
|
||||||
|
if (values.size() > 1) {
|
||||||
|
base::Value::List list;
|
||||||
|
for (const base::CommandLine::StringType& v : values) {
|
||||||
|
list.Append(v);
|
||||||
|
}
|
||||||
|
dict.Set(key, std::move(list));
|
||||||
|
} else {
|
||||||
|
dict.Set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
36
src/net/tools/naive/naive_command_line.h
Normal file
36
src/net/tools/naive/naive_command_line.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
#ifndef NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
||||||
|
#define NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/command_line.h"
|
||||||
|
#include "base/values.h"
|
||||||
|
|
||||||
|
class DuplicateSwitchCollector : public base::DuplicateSwitchHandler {
|
||||||
|
public:
|
||||||
|
DuplicateSwitchCollector();
|
||||||
|
~DuplicateSwitchCollector() override;
|
||||||
|
|
||||||
|
void ResolveDuplicate(std::string_view key,
|
||||||
|
base::CommandLine::StringPieceType new_value,
|
||||||
|
base::CommandLine::StringType& out_value) override;
|
||||||
|
|
||||||
|
const std::vector<base::CommandLine::StringType>& GetValuesByKey(
|
||||||
|
std::string_view key);
|
||||||
|
|
||||||
|
static void InitInstance();
|
||||||
|
static DuplicateSwitchCollector& GetInstance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, std::vector<base::CommandLine::StringType>>
|
||||||
|
values_by_key_;
|
||||||
|
};
|
||||||
|
|
||||||
|
base::Value::Dict GetSwitchesAsValue(const base::CommandLine& cmdline);
|
||||||
|
#endif // NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
198
src/net/tools/naive/naive_config.cc
Normal file
198
src/net/tools/naive/naive_config.cc
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
#include "net/tools/naive/naive_config.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "base/strings/escape.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "net/base/url_util.h"
|
||||||
|
#include "url/gurl.h"
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
NaiveListenConfig::NaiveListenConfig() = default;
|
||||||
|
NaiveListenConfig::NaiveListenConfig(const NaiveListenConfig&) = default;
|
||||||
|
NaiveListenConfig::~NaiveListenConfig() = default;
|
||||||
|
|
||||||
|
bool NaiveListenConfig::Parse(const std::string& str) {
|
||||||
|
GURL url(str);
|
||||||
|
if (url.scheme() == "socks") {
|
||||||
|
protocol = ClientProtocol::kSocks5;
|
||||||
|
} else if (url.scheme() == "http") {
|
||||||
|
protocol = ClientProtocol::kHttp;
|
||||||
|
} else if (url.scheme() == "redir") {
|
||||||
|
#if BUILDFLAG(IS_LINUX)
|
||||||
|
protocol = ClientProtocol::kRedir;
|
||||||
|
#else
|
||||||
|
std::cerr << "Redir protocol only supports Linux." << std::endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid scheme in " << str << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url.username().empty()) {
|
||||||
|
user = base::UnescapeBinaryURLComponent(url.username());
|
||||||
|
}
|
||||||
|
if (!url.password().empty()) {
|
||||||
|
pass = base::UnescapeBinaryURLComponent(url.password());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url.host().empty()) {
|
||||||
|
addr = url.HostNoBrackets();
|
||||||
|
}
|
||||||
|
|
||||||
|
int effective_port = url.EffectiveIntPort();
|
||||||
|
if (effective_port == url::PORT_INVALID) {
|
||||||
|
std::cerr << "Invalid port in " << str << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (effective_port != url::PORT_UNSPECIFIED) {
|
||||||
|
port = effective_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NaiveConfig::NaiveConfig() = default;
|
||||||
|
NaiveConfig::NaiveConfig(const NaiveConfig&) = default;
|
||||||
|
NaiveConfig::~NaiveConfig() = default;
|
||||||
|
|
||||||
|
bool NaiveConfig::Parse(const base::Value::Dict& value) {
|
||||||
|
if (const base::Value* v = value.Find("listen")) {
|
||||||
|
listen.clear();
|
||||||
|
if (const std::string* str = v->GetIfString()) {
|
||||||
|
if (!listen.emplace_back().Parse(*str)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (const base::Value::List* strs = v->GetIfList()) {
|
||||||
|
for (const auto& str_e : *strs) {
|
||||||
|
if (const std::string* s = str_e.GetIfString()) {
|
||||||
|
if (!listen.emplace_back().Parse(*s)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid listen element" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid listen" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("insecure-concurrency")) {
|
||||||
|
if (std::optional<int> i = v->GetIfInt()) {
|
||||||
|
insecure_concurrency = *i;
|
||||||
|
} else if (const std::string* str = v->GetIfString()) {
|
||||||
|
if (!base::StringToInt(*str, &insecure_concurrency)) {
|
||||||
|
std::cerr << "Invalid concurrency" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid concurrency" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (insecure_concurrency < 1) {
|
||||||
|
std::cerr << "Invalid concurrency" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("extra-headers")) {
|
||||||
|
if (const std::string* str = v->GetIfString()) {
|
||||||
|
extra_headers.AddHeadersFromString(*str);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid extra-headers" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("proxy")) {
|
||||||
|
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||||
|
GURL url(*str);
|
||||||
|
net::GetIdentityFromURL(url, &proxy_user, &proxy_pass);
|
||||||
|
|
||||||
|
GURL::Replacements remove_auth;
|
||||||
|
remove_auth.ClearUsername();
|
||||||
|
remove_auth.ClearPassword();
|
||||||
|
GURL url_no_auth = url.ReplaceComponents(remove_auth);
|
||||||
|
proxy_url = url_no_auth.GetWithEmptyPath().spec();
|
||||||
|
if (proxy_url.empty()) {
|
||||||
|
std::cerr << "Invalid proxy" << std::endl;
|
||||||
|
return false;
|
||||||
|
} else if (proxy_url.back() == '/') {
|
||||||
|
proxy_url.pop_back();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid proxy" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("host-resolver-rules")) {
|
||||||
|
if (const std::string* str = v->GetIfString()) {
|
||||||
|
host_resolver_rules = *str;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid host-resolver-rules" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("resolver-range")) {
|
||||||
|
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||||
|
if (!net::ParseCIDRBlock(*str, &resolver_range, &resolver_prefix)) {
|
||||||
|
std::cerr << "Invalid resolver-range" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (resolver_range.IsIPv6()) {
|
||||||
|
std::cerr << "IPv6 resolver range not supported" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid resolver-range" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("log")) {
|
||||||
|
if (const std::string* str = v->GetIfString()) {
|
||||||
|
if (!str->empty()) {
|
||||||
|
log.logging_dest = logging::LOG_TO_FILE;
|
||||||
|
log_file = base::FilePath::FromUTF8Unsafe(*str);
|
||||||
|
log.log_file_path = log_file.value().c_str();
|
||||||
|
} else {
|
||||||
|
log.logging_dest = logging::LOG_TO_STDERR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid log" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("log-net-log")) {
|
||||||
|
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||||
|
log_net_log = base::FilePath::FromUTF8Unsafe(*str);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid log-net-log" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const base::Value* v = value.Find("ssl-key-log-file")) {
|
||||||
|
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||||
|
ssl_key_log_file = base::FilePath::FromUTF8Unsafe(*str);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid ssl-key-log-file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace net
|
64
src/net/tools/naive/naive_config.h
Normal file
64
src/net/tools/naive/naive_config.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
#ifndef NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
||||||
|
#define NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/values.h"
|
||||||
|
#include "net/base/ip_address.h"
|
||||||
|
#include "net/http/http_request_headers.h"
|
||||||
|
#include "net/tools/naive/naive_protocol.h"
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
struct NaiveListenConfig {
|
||||||
|
ClientProtocol protocol = ClientProtocol::kSocks5;
|
||||||
|
std::string user;
|
||||||
|
std::string pass;
|
||||||
|
std::string addr = "0.0.0.0";
|
||||||
|
int port = 1080;
|
||||||
|
|
||||||
|
NaiveListenConfig();
|
||||||
|
NaiveListenConfig(const NaiveListenConfig&);
|
||||||
|
~NaiveListenConfig();
|
||||||
|
bool Parse(const std::string& str);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NaiveConfig {
|
||||||
|
std::vector<NaiveListenConfig> listen = {NaiveListenConfig()};
|
||||||
|
|
||||||
|
int insecure_concurrency = 1;
|
||||||
|
|
||||||
|
HttpRequestHeaders extra_headers;
|
||||||
|
|
||||||
|
std::string proxy_url = "direct://";
|
||||||
|
|
||||||
|
std::u16string proxy_user;
|
||||||
|
std::u16string proxy_pass;
|
||||||
|
|
||||||
|
std::string host_resolver_rules;
|
||||||
|
|
||||||
|
IPAddress resolver_range = {100, 64, 0, 0};
|
||||||
|
size_t resolver_prefix = 10;
|
||||||
|
|
||||||
|
logging::LoggingSettings log = {.logging_dest = logging::LOG_NONE};
|
||||||
|
base::FilePath log_file;
|
||||||
|
|
||||||
|
base::FilePath log_net_log;
|
||||||
|
|
||||||
|
base::FilePath ssl_key_log_file;
|
||||||
|
|
||||||
|
NaiveConfig();
|
||||||
|
NaiveConfig(const NaiveConfig&);
|
||||||
|
~NaiveConfig();
|
||||||
|
bool Parse(const base::Value::Dict& value);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace net
|
||||||
|
#endif // NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
@ -7,6 +7,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/allocator/allocator_check.h"
|
#include "base/allocator/allocator_check.h"
|
||||||
@ -60,8 +61,11 @@
|
|||||||
#include "net/socket/ssl_client_socket.h"
|
#include "net/socket/ssl_client_socket.h"
|
||||||
#include "net/socket/tcp_server_socket.h"
|
#include "net/socket/tcp_server_socket.h"
|
||||||
#include "net/socket/udp_server_socket.h"
|
#include "net/socket/udp_server_socket.h"
|
||||||
|
#include "net/ssl/ssl_config_service.h"
|
||||||
#include "net/ssl/ssl_key_logger_impl.h"
|
#include "net/ssl/ssl_key_logger_impl.h"
|
||||||
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
|
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
|
||||||
|
#include "net/tools/naive/naive_command_line.h"
|
||||||
|
#include "net/tools/naive/naive_config.h"
|
||||||
#include "net/tools/naive/naive_protocol.h"
|
#include "net/tools/naive/naive_protocol.h"
|
||||||
#include "net/tools/naive/naive_proxy.h"
|
#include "net/tools/naive/naive_proxy.h"
|
||||||
#include "net/tools/naive/naive_proxy_delegate.h"
|
#include "net/tools/naive/naive_proxy_delegate.h"
|
||||||
@ -87,42 +91,6 @@ constexpr int kExpectedMaxUsers = 8;
|
|||||||
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
|
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
|
||||||
net::DefineNetworkTrafficAnnotation("naive", "");
|
net::DefineNetworkTrafficAnnotation("naive", "");
|
||||||
|
|
||||||
struct CommandLine {
|
|
||||||
std::vector<std::string> listens;
|
|
||||||
std::string proxy;
|
|
||||||
std::string concurrency;
|
|
||||||
std::string extra_headers;
|
|
||||||
std::string host_resolver_rules;
|
|
||||||
std::string resolver_range;
|
|
||||||
bool no_log;
|
|
||||||
base::FilePath log;
|
|
||||||
base::FilePath log_net_log;
|
|
||||||
base::FilePath ssl_key_log_file;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ListenParams {
|
|
||||||
net::ClientProtocol protocol;
|
|
||||||
std::string listen_user;
|
|
||||||
std::string listen_pass;
|
|
||||||
std::string listen_addr;
|
|
||||||
int listen_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
std::vector<ListenParams> listens;
|
|
||||||
int concurrency;
|
|
||||||
net::HttpRequestHeaders extra_headers;
|
|
||||||
std::string proxy_url;
|
|
||||||
std::u16string proxy_user;
|
|
||||||
std::u16string proxy_pass;
|
|
||||||
std::string host_resolver_rules;
|
|
||||||
net::IPAddress resolver_range;
|
|
||||||
size_t resolver_prefix;
|
|
||||||
logging::LoggingSettings log_settings;
|
|
||||||
base::FilePath net_log_path;
|
|
||||||
base::FilePath ssl_key_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<base::Value::Dict> GetConstants() {
|
std::unique_ptr<base::Value::Dict> GetConstants() {
|
||||||
base::Value::Dict constants_dict = net::GetNetConstants();
|
base::Value::Dict constants_dict = net::GetNetConstants();
|
||||||
base::Value::Dict dict;
|
base::Value::Dict dict;
|
||||||
@ -134,278 +102,6 @@ std::unique_ptr<base::Value::Dict> GetConstants() {
|
|||||||
constants_dict.Set("clientInfo", std::move(dict));
|
constants_dict.Set("clientInfo", std::move(dict));
|
||||||
return std::make_unique<base::Value::Dict>(std::move(constants_dict));
|
return std::make_unique<base::Value::Dict>(std::move(constants_dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultipleListenCollector : public base::DuplicateSwitchHandler {
|
|
||||||
public:
|
|
||||||
void ResolveDuplicate(std::string_view key,
|
|
||||||
base::CommandLine::StringPieceType new_value,
|
|
||||||
base::CommandLine::StringType& out_value) override {
|
|
||||||
out_value = new_value;
|
|
||||||
if (key == "listen") {
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
|
||||||
all_values_.push_back(base::WideToUTF8(new_value));
|
|
||||||
#else
|
|
||||||
all_values_.push_back(std::string(new_value));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& GetAllValues() const {
|
|
||||||
return all_values_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::string> all_values_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void GetCommandLine(const base::CommandLine& proc,
|
|
||||||
CommandLine* cmdline,
|
|
||||||
MultipleListenCollector& multiple_listens) {
|
|
||||||
if (proc.HasSwitch("h") || proc.HasSwitch("help")) {
|
|
||||||
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
|
||||||
"\n"
|
|
||||||
"Options:\n"
|
|
||||||
"-h, --help Show this message\n"
|
|
||||||
"--version Print version\n"
|
|
||||||
"--listen=<proto>://[addr][:port] [--listen=...]\n"
|
|
||||||
" proto: socks, http\n"
|
|
||||||
" redir (Linux only)\n"
|
|
||||||
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
|
||||||
" proto: https, quic\n"
|
|
||||||
"--insecure-concurrency=<N> Use N connections, insecure\n"
|
|
||||||
"--extra-headers=... Extra headers split by CRLF\n"
|
|
||||||
"--host-resolver-rules=... Resolver rules\n"
|
|
||||||
"--resolver-range=... Redirect resolver range\n"
|
|
||||||
"--log[=<path>] Log to stderr, or file\n"
|
|
||||||
"--log-net-log=<path> Save NetLog\n"
|
|
||||||
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n"
|
|
||||||
<< std::endl;
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proc.HasSwitch("version")) {
|
|
||||||
std::cout << "naive " << version_info::GetVersionNumber() << std::endl;
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdline->listens = multiple_listens.GetAllValues();
|
|
||||||
cmdline->proxy = proc.GetSwitchValueASCII("proxy");
|
|
||||||
cmdline->concurrency = proc.GetSwitchValueASCII("insecure-concurrency");
|
|
||||||
cmdline->extra_headers = proc.GetSwitchValueASCII("extra-headers");
|
|
||||||
cmdline->host_resolver_rules =
|
|
||||||
proc.GetSwitchValueASCII("host-resolver-rules");
|
|
||||||
cmdline->resolver_range = proc.GetSwitchValueASCII("resolver-range");
|
|
||||||
cmdline->no_log = !proc.HasSwitch("log");
|
|
||||||
cmdline->log = proc.GetSwitchValuePath("log");
|
|
||||||
cmdline->log_net_log = proc.GetSwitchValuePath("log-net-log");
|
|
||||||
cmdline->ssl_key_log_file = proc.GetSwitchValuePath("ssl-key-log-file");
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetCommandLineFromConfig(const base::FilePath& config_path,
|
|
||||||
CommandLine* cmdline) {
|
|
||||||
JSONFileValueDeserializer reader(config_path);
|
|
||||||
int error_code;
|
|
||||||
std::string error_message;
|
|
||||||
std::unique_ptr<base::Value> value =
|
|
||||||
reader.Deserialize(&error_code, &error_message);
|
|
||||||
if (value == nullptr) {
|
|
||||||
std::cerr << "Error reading " << config_path << ": (" << error_code << ") "
|
|
||||||
<< error_message << std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
base::Value::Dict* value_dict = value->GetIfDict();
|
|
||||||
if (value_dict == nullptr) {
|
|
||||||
std::cerr << "Invalid config format" << std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
const std::string* listen = value_dict->FindString("listen");
|
|
||||||
if (listen != nullptr) {
|
|
||||||
cmdline->listens = {*listen};
|
|
||||||
} else {
|
|
||||||
const base::Value::List* listen_list = value_dict->FindList("listen");
|
|
||||||
if (listen_list != nullptr) {
|
|
||||||
for (const auto& listen_element : *listen_list) {
|
|
||||||
const std::string* listen_elemet_str = listen_element.GetIfString();
|
|
||||||
if (listen_elemet_str == nullptr) {
|
|
||||||
std::cerr << "Invalid listen element" << std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
cmdline->listens.push_back(*listen_elemet_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const std::string* proxy = value_dict->FindString("proxy");
|
|
||||||
if (proxy) {
|
|
||||||
cmdline->proxy = *proxy;
|
|
||||||
}
|
|
||||||
const std::string* concurrency =
|
|
||||||
value_dict->FindString("insecure-concurrency");
|
|
||||||
if (concurrency) {
|
|
||||||
cmdline->concurrency = *concurrency;
|
|
||||||
}
|
|
||||||
const std::string* extra_headers = value_dict->FindString("extra-headers");
|
|
||||||
if (extra_headers) {
|
|
||||||
cmdline->extra_headers = *extra_headers;
|
|
||||||
}
|
|
||||||
const std::string* host_resolver_rules =
|
|
||||||
value_dict->FindString("host-resolver-rules");
|
|
||||||
if (host_resolver_rules) {
|
|
||||||
cmdline->host_resolver_rules = *host_resolver_rules;
|
|
||||||
}
|
|
||||||
const std::string* resolver_range = value_dict->FindString("resolver-range");
|
|
||||||
if (resolver_range) {
|
|
||||||
cmdline->resolver_range = *resolver_range;
|
|
||||||
}
|
|
||||||
cmdline->no_log = true;
|
|
||||||
const std::string* log = value_dict->FindString("log");
|
|
||||||
if (log) {
|
|
||||||
cmdline->no_log = false;
|
|
||||||
cmdline->log = base::FilePath::FromUTF8Unsafe(*log);
|
|
||||||
}
|
|
||||||
const std::string* log_net_log = value_dict->FindString("log-net-log");
|
|
||||||
if (log_net_log) {
|
|
||||||
cmdline->log_net_log = base::FilePath::FromUTF8Unsafe(*log_net_log);
|
|
||||||
}
|
|
||||||
const std::string* ssl_key_log_file =
|
|
||||||
value_dict->FindString("ssl-key-log-file");
|
|
||||||
if (ssl_key_log_file) {
|
|
||||||
cmdline->ssl_key_log_file =
|
|
||||||
base::FilePath::FromUTF8Unsafe(*ssl_key_log_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ParseListenParams(const std::string& listen_str,
|
|
||||||
ListenParams& listen_params) {
|
|
||||||
GURL url(listen_str);
|
|
||||||
if (url.scheme() == "socks") {
|
|
||||||
listen_params.protocol = net::ClientProtocol::kSocks5;
|
|
||||||
} else if (url.scheme() == "http") {
|
|
||||||
listen_params.protocol = net::ClientProtocol::kHttp;
|
|
||||||
} else if (url.scheme() == "redir") {
|
|
||||||
#if BUILDFLAG(IS_LINUX)
|
|
||||||
listen_params.protocol = net::ClientProtocol::kRedir;
|
|
||||||
#else
|
|
||||||
std::cerr << "Redir protocol only supports Linux." << std::endl;
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
std::cerr << "Invalid scheme in --listen" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!url.username().empty()) {
|
|
||||||
listen_params.listen_user =
|
|
||||||
base::UnescapeBinaryURLComponent(url.username());
|
|
||||||
}
|
|
||||||
if (!url.password().empty()) {
|
|
||||||
listen_params.listen_pass =
|
|
||||||
base::UnescapeBinaryURLComponent(url.password());
|
|
||||||
}
|
|
||||||
if (!url.host().empty()) {
|
|
||||||
listen_params.listen_addr = url.HostNoBrackets();
|
|
||||||
} else {
|
|
||||||
listen_params.listen_addr = "0.0.0.0";
|
|
||||||
}
|
|
||||||
int port = url.EffectiveIntPort();
|
|
||||||
if (port == url::PORT_INVALID) {
|
|
||||||
std::cerr << "Invalid port in --listen" << std::endl;
|
|
||||||
return false;
|
|
||||||
} else if (port == url::PORT_UNSPECIFIED) {
|
|
||||||
port = 1080;
|
|
||||||
}
|
|
||||||
listen_params.listen_port = port;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ParseCommandLine(const CommandLine& cmdline, Params* params) {
|
|
||||||
url::AddStandardScheme("socks",
|
|
||||||
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
|
||||||
url::AddStandardScheme("redir", url::SCHEME_WITH_HOST_AND_PORT);
|
|
||||||
|
|
||||||
bool any_redir_protocol = false;
|
|
||||||
if (!cmdline.listens.empty()) {
|
|
||||||
for (const std::string& listen : cmdline.listens) {
|
|
||||||
ListenParams listen_params;
|
|
||||||
if (!ParseListenParams(listen, listen_params)) {
|
|
||||||
std::cerr << "Invalid listen: " << listen << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (listen_params.protocol == net::ClientProtocol::kRedir) {
|
|
||||||
any_redir_protocol = true;
|
|
||||||
}
|
|
||||||
params->listens.push_back(listen_params);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ListenParams default_listen = {
|
|
||||||
.protocol = net::ClientProtocol::kSocks5,
|
|
||||||
.listen_addr = "0.0.0.0",
|
|
||||||
.listen_port = 1080,
|
|
||||||
};
|
|
||||||
params->listens = {default_listen};
|
|
||||||
}
|
|
||||||
|
|
||||||
params->proxy_url = "direct://";
|
|
||||||
GURL url(cmdline.proxy);
|
|
||||||
GURL::Replacements remove_auth;
|
|
||||||
remove_auth.ClearUsername();
|
|
||||||
remove_auth.ClearPassword();
|
|
||||||
GURL url_no_auth = url.ReplaceComponents(remove_auth);
|
|
||||||
if (!cmdline.proxy.empty()) {
|
|
||||||
params->proxy_url = url_no_auth.GetWithEmptyPath().spec();
|
|
||||||
if (params->proxy_url.empty()) {
|
|
||||||
std::cerr << "Invalid proxy URL" << std::endl;
|
|
||||||
return false;
|
|
||||||
} else if (params->proxy_url.back() == '/') {
|
|
||||||
params->proxy_url.pop_back();
|
|
||||||
}
|
|
||||||
net::GetIdentityFromURL(url, ¶ms->proxy_user, ¶ms->proxy_pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmdline.concurrency.empty()) {
|
|
||||||
if (!base::StringToInt(cmdline.concurrency, ¶ms->concurrency) ||
|
|
||||||
params->concurrency < 1) {
|
|
||||||
std::cerr << "Invalid concurrency" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
params->concurrency = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->extra_headers.AddHeadersFromString(cmdline.extra_headers);
|
|
||||||
|
|
||||||
params->host_resolver_rules = cmdline.host_resolver_rules;
|
|
||||||
|
|
||||||
if (any_redir_protocol) {
|
|
||||||
std::string range = "100.64.0.0/10";
|
|
||||||
if (!cmdline.resolver_range.empty())
|
|
||||||
range = cmdline.resolver_range;
|
|
||||||
|
|
||||||
if (!net::ParseCIDRBlock(range, ¶ms->resolver_range,
|
|
||||||
¶ms->resolver_prefix)) {
|
|
||||||
std::cerr << "Invalid resolver range" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (params->resolver_range.IsIPv6()) {
|
|
||||||
std::cerr << "IPv6 resolver range not supported" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmdline.no_log) {
|
|
||||||
if (!cmdline.log.empty()) {
|
|
||||||
params->log_settings.logging_dest = logging::LOG_TO_FILE;
|
|
||||||
params->log_settings.log_file_path = cmdline.log.value().c_str();
|
|
||||||
} else {
|
|
||||||
params->log_settings.logging_dest = logging::LOG_TO_STDERR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
params->log_settings.logging_dest = logging::LOG_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->net_log_path = cmdline.log_net_log;
|
|
||||||
params->ssl_key_path = cmdline.ssl_key_log_file;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -471,7 +167,7 @@ std::unique_ptr<URLRequestContext> BuildCertURLRequestContext(NetLog* net_log) {
|
|||||||
|
|
||||||
// Builds a URLRequestContext assuming there's only a single loop.
|
// Builds a URLRequestContext assuming there's only a single loop.
|
||||||
std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||||
const Params& params,
|
const NaiveConfig& config,
|
||||||
scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher,
|
scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher,
|
||||||
NetLog* net_log) {
|
NetLog* net_log) {
|
||||||
URLRequestContextBuilder builder;
|
URLRequestContextBuilder builder;
|
||||||
@ -479,7 +175,7 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
|||||||
builder.DisableHttpCache();
|
builder.DisableHttpCache();
|
||||||
builder.set_net_log(net_log);
|
builder.set_net_log(net_log);
|
||||||
|
|
||||||
std::string proxy_url = params.proxy_url;
|
std::string proxy_url = config.proxy_url;
|
||||||
bool force_quic = false;
|
bool force_quic = false;
|
||||||
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
||||||
proxy_url.replace(0, 4, "https");
|
proxy_url.replace(0, 4, "https");
|
||||||
@ -505,21 +201,21 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
|||||||
proxy_service->ForceReloadProxyConfig();
|
proxy_service->ForceReloadProxyConfig();
|
||||||
builder.set_proxy_resolution_service(std::move(proxy_service));
|
builder.set_proxy_resolution_service(std::move(proxy_service));
|
||||||
|
|
||||||
if (!params.host_resolver_rules.empty()) {
|
if (!config.host_resolver_rules.empty()) {
|
||||||
builder.set_host_mapping_rules(params.host_resolver_rules);
|
builder.set_host_mapping_rules(config.host_resolver_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.SetCertVerifier(
|
builder.SetCertVerifier(
|
||||||
CertVerifier::CreateDefault(std::move(cert_net_fetcher)));
|
CertVerifier::CreateDefault(std::move(cert_net_fetcher)));
|
||||||
|
|
||||||
builder.set_proxy_delegate(std::make_unique<NaiveProxyDelegate>(
|
builder.set_proxy_delegate(std::make_unique<NaiveProxyDelegate>(
|
||||||
params.extra_headers,
|
config.extra_headers,
|
||||||
std::vector<PaddingType>{PaddingType::kVariant1, PaddingType::kNone}));
|
std::vector<PaddingType>{PaddingType::kVariant1, PaddingType::kNone}));
|
||||||
|
|
||||||
auto context = builder.Build();
|
auto context = builder.Build();
|
||||||
|
|
||||||
if (!params.proxy_url.empty() && !params.proxy_user.empty() &&
|
if (!config.proxy_url.empty() && !config.proxy_user.empty() &&
|
||||||
!params.proxy_pass.empty()) {
|
!config.proxy_pass.empty()) {
|
||||||
auto* session = context->http_transaction_factory()->GetSession();
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
auto* auth_cache = session->http_auth_cache();
|
auto* auth_cache = session->http_auth_cache();
|
||||||
GURL proxy_gurl(proxy_url);
|
GURL proxy_gurl(proxy_url);
|
||||||
@ -530,7 +226,7 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
|||||||
net::HostPortPair::FromURL(proxy_gurl));
|
net::HostPortPair::FromURL(proxy_gurl));
|
||||||
}
|
}
|
||||||
url::SchemeHostPort auth_origin(proxy_gurl);
|
url::SchemeHostPort auth_origin(proxy_gurl);
|
||||||
AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
AuthCredentials credentials(config.proxy_user, config.proxy_pass);
|
||||||
auth_cache->Add(auth_origin, HttpAuth::AUTH_PROXY,
|
auth_cache->Add(auth_origin, HttpAuth::AUTH_PROXY,
|
||||||
/*realm=*/{}, HttpAuth::AUTH_SCHEME_BASIC, {},
|
/*realm=*/{}, HttpAuth::AUTH_SCHEME_BASIC, {},
|
||||||
/*challenge=*/"Basic", credentials, /*path=*/"/");
|
/*challenge=*/"Basic", credentials, /*path=*/"/");
|
||||||
@ -565,9 +261,7 @@ int main(int argc, char* argv[]) {
|
|||||||
// content/app/content_main.cc: RunContentProcess()
|
// content/app/content_main.cc: RunContentProcess()
|
||||||
base::EnableTerminationOnOutOfMemory();
|
base::EnableTerminationOnOutOfMemory();
|
||||||
|
|
||||||
auto multiple_listens = std::make_unique<MultipleListenCollector>();
|
DuplicateSwitchCollector::InitInstance();
|
||||||
MultipleListenCollector& multiple_listens_ref = *multiple_listens;
|
|
||||||
base::CommandLine::SetDuplicateSwitchHandler(std::move(multiple_listens));
|
|
||||||
|
|
||||||
// content/app/content_main.cc: RunContentProcess()
|
// content/app/content_main.cc: RunContentProcess()
|
||||||
base::CommandLine::Init(argc, argv);
|
base::CommandLine::Init(argc, argv);
|
||||||
@ -606,6 +300,9 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
url::AddStandardScheme("quic",
|
url::AddStandardScheme("quic",
|
||||||
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||||
|
url::AddStandardScheme("socks",
|
||||||
|
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||||
|
url::AddStandardScheme("redir", url::SCHEME_WITH_HOST_AND_PORT);
|
||||||
net::ClientSocketPoolManager::set_max_sockets_per_pool(
|
net::ClientSocketPoolManager::set_max_sockets_per_pool(
|
||||||
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
||||||
kDefaultMaxSocketsPerPool * kExpectedMaxUsers);
|
kDefaultMaxSocketsPerPool * kExpectedMaxUsers);
|
||||||
@ -616,30 +313,69 @@ int main(int argc, char* argv[]) {
|
|||||||
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
||||||
kDefaultMaxSocketsPerGroup * kExpectedMaxUsers);
|
kDefaultMaxSocketsPerGroup * kExpectedMaxUsers);
|
||||||
|
|
||||||
CommandLine cmdline;
|
|
||||||
|
|
||||||
Params params;
|
|
||||||
const auto& proc = *base::CommandLine::ForCurrentProcess();
|
const auto& proc = *base::CommandLine::ForCurrentProcess();
|
||||||
const auto& args = proc.GetArgs();
|
const auto& args = proc.GetArgs();
|
||||||
if (args.empty()) {
|
base::Value::Dict config_dict;
|
||||||
if (proc.argv().size() >= 2) {
|
if (args.empty() && proc.argv().size() >= 2) {
|
||||||
GetCommandLine(proc, &cmdline, multiple_listens_ref);
|
config_dict = GetSwitchesAsValue(proc);
|
||||||
} else {
|
|
||||||
auto path = base::FilePath::FromUTF8Unsafe("config.json");
|
|
||||||
GetCommandLineFromConfig(path, &cmdline);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
base::FilePath path(args[0]);
|
base::FilePath config_file;
|
||||||
GetCommandLineFromConfig(path, &cmdline);
|
if (!args.empty()) {
|
||||||
|
config_file = base::FilePath(args[0]);
|
||||||
|
} else {
|
||||||
|
config_file = base::FilePath::FromUTF8Unsafe("config.json");
|
||||||
|
}
|
||||||
|
JSONFileValueDeserializer reader(config_file);
|
||||||
|
int error_code;
|
||||||
|
std::string error_message;
|
||||||
|
std::unique_ptr<base::Value> value =
|
||||||
|
reader.Deserialize(&error_code, &error_message);
|
||||||
|
if (value == nullptr) {
|
||||||
|
std::cerr << "Error reading " << config_file << ": (" << error_code
|
||||||
|
<< ") " << error_message << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (const base::Value::Dict* dict = value->GetIfDict()) {
|
||||||
|
config_dict = dict->Clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!ParseCommandLine(cmdline, ¶ms)) {
|
|
||||||
|
if (config_dict.contains("h") || config_dict.contains("help")) {
|
||||||
|
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
"-h, --help Show this message\n"
|
||||||
|
"--version Print version\n"
|
||||||
|
"--listen=<proto>://[addr][:port] [--listen=...]\n"
|
||||||
|
" proto: socks, http\n"
|
||||||
|
" redir (Linux only)\n"
|
||||||
|
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
||||||
|
" proto: https, quic\n"
|
||||||
|
"--insecure-concurrency=<N> Use N connections, insecure\n"
|
||||||
|
"--extra-headers=... Extra headers split by CRLF\n"
|
||||||
|
"--host-resolver-rules=... Resolver rules\n"
|
||||||
|
"--resolver-range=... Redirect resolver range\n"
|
||||||
|
"--log[=<path>] Log to stderr, or file\n"
|
||||||
|
"--log-net-log=<path> Save NetLog\n"
|
||||||
|
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n"
|
||||||
|
<< std::endl;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_dict.contains("version")) {
|
||||||
|
std::cout << "naive " << version_info::GetVersionNumber() << std::endl;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
net::NaiveConfig config;
|
||||||
|
if (!config.Parse(config_dict)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
CHECK(logging::InitLogging(params.log_settings));
|
CHECK(logging::InitLogging(config.log));
|
||||||
|
|
||||||
if (!params.ssl_key_path.empty()) {
|
if (!config.ssl_key_log_file.empty()) {
|
||||||
net::SSLClientSocket::SetSSLKeyLogger(
|
net::SSLClientSocket::SetSSLKeyLogger(
|
||||||
std::make_unique<net::SSLKeyLoggerImpl>(params.ssl_key_path));
|
std::make_unique<net::SSLKeyLoggerImpl>(config.ssl_key_log_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The declaration order for net_log and printing_log_observer is
|
// The declaration order for net_log and printing_log_observer is
|
||||||
@ -648,15 +384,15 @@ int main(int argc, char* argv[]) {
|
|||||||
// printing_log_observer.
|
// printing_log_observer.
|
||||||
net::NetLog* net_log = net::NetLog::Get();
|
net::NetLog* net_log = net::NetLog::Get();
|
||||||
std::unique_ptr<net::FileNetLogObserver> observer;
|
std::unique_ptr<net::FileNetLogObserver> observer;
|
||||||
if (!params.net_log_path.empty()) {
|
if (!config.log_net_log.empty()) {
|
||||||
observer = net::FileNetLogObserver::CreateUnbounded(
|
observer = net::FileNetLogObserver::CreateUnbounded(
|
||||||
params.net_log_path, net::NetLogCaptureMode::kDefault, GetConstants());
|
config.log_net_log, net::NetLogCaptureMode::kDefault, GetConstants());
|
||||||
observer->StartObserving(net_log);
|
observer->StartObserving(net_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoids net log overhead if verbose logging is disabled.
|
// Avoids net log overhead if verbose logging is disabled.
|
||||||
std::unique_ptr<net::PrintingLogObserver> printing_log_observer;
|
std::unique_ptr<net::PrintingLogObserver> printing_log_observer;
|
||||||
if (params.log_settings.logging_dest != logging::LOG_NONE && VLOG_IS_ON(1)) {
|
if (config.log.logging_dest != logging::LOG_NONE && VLOG_IS_ON(1)) {
|
||||||
printing_log_observer = std::make_unique<net::PrintingLogObserver>();
|
printing_log_observer = std::make_unique<net::PrintingLogObserver>();
|
||||||
net_log->AddObserver(printing_log_observer.get(),
|
net_log->AddObserver(printing_log_observer.get(),
|
||||||
net::NetLogCaptureMode::kDefault);
|
net::NetLogCaptureMode::kDefault);
|
||||||
@ -675,43 +411,41 @@ int main(int argc, char* argv[]) {
|
|||||||
cert_net_fetcher->SetURLRequestContext(cert_context.get());
|
cert_net_fetcher->SetURLRequestContext(cert_context.get());
|
||||||
#endif
|
#endif
|
||||||
auto context =
|
auto context =
|
||||||
net::BuildURLRequestContext(params, std::move(cert_net_fetcher), net_log);
|
net::BuildURLRequestContext(config, std::move(cert_net_fetcher), net_log);
|
||||||
auto* session = context->http_transaction_factory()->GetSession();
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
|
|
||||||
std::vector<std::unique_ptr<net::NaiveProxy>> naive_proxies;
|
std::vector<std::unique_ptr<net::NaiveProxy>> naive_proxies;
|
||||||
std::unique_ptr<net::RedirectResolver> resolver;
|
std::unique_ptr<net::RedirectResolver> resolver;
|
||||||
|
|
||||||
for (const ListenParams& listen_params : params.listens) {
|
for (const net::NaiveListenConfig& listen_config : config.listen) {
|
||||||
auto listen_socket =
|
auto listen_socket =
|
||||||
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource());
|
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource());
|
||||||
|
|
||||||
int result = listen_socket->ListenWithAddressAndPort(
|
int result = listen_socket->ListenWithAddressAndPort(
|
||||||
listen_params.listen_addr, listen_params.listen_port, kListenBackLog);
|
listen_config.addr, listen_config.port, kListenBackLog);
|
||||||
if (result != net::OK) {
|
if (result != net::OK) {
|
||||||
LOG(ERROR) << "Failed to listen on "
|
LOG(ERROR) << "Failed to listen on "
|
||||||
<< net::ToString(listen_params.protocol) << "://"
|
<< net::ToString(listen_config.protocol) << "://"
|
||||||
<< listen_params.listen_addr << " "
|
<< listen_config.addr << " " << listen_config.port << ": "
|
||||||
<< listen_params.listen_port << ": "
|
|
||||||
<< net::ErrorToShortString(result);
|
<< net::ErrorToShortString(result);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
LOG(INFO) << "Listening on " << net::ToString(listen_params.protocol)
|
LOG(INFO) << "Listening on " << net::ToString(listen_config.protocol)
|
||||||
<< "://" << listen_params.listen_addr << ":"
|
<< "://" << listen_config.addr << ":" << listen_config.port;
|
||||||
<< listen_params.listen_port;
|
|
||||||
|
|
||||||
if (resolver == nullptr &&
|
if (resolver == nullptr &&
|
||||||
listen_params.protocol == net::ClientProtocol::kRedir) {
|
listen_config.protocol == net::ClientProtocol::kRedir) {
|
||||||
auto resolver_socket =
|
auto resolver_socket =
|
||||||
std::make_unique<net::UDPServerSocket>(net_log, net::NetLogSource());
|
std::make_unique<net::UDPServerSocket>(net_log, net::NetLogSource());
|
||||||
resolver_socket->AllowAddressReuse();
|
resolver_socket->AllowAddressReuse();
|
||||||
net::IPAddress listen_addr;
|
net::IPAddress listen_addr;
|
||||||
if (!listen_addr.AssignFromIPLiteral(listen_params.listen_addr)) {
|
if (!listen_addr.AssignFromIPLiteral(listen_config.addr)) {
|
||||||
LOG(ERROR) << "Failed to open resolver: " << listen_params.listen_addr;
|
LOG(ERROR) << "Failed to open resolver: " << listen_config.addr;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = resolver_socket->Listen(
|
result = resolver_socket->Listen(
|
||||||
net::IPEndPoint(listen_addr, listen_params.listen_port));
|
net::IPEndPoint(listen_addr, listen_config.port));
|
||||||
if (result != net::OK) {
|
if (result != net::OK) {
|
||||||
LOG(ERROR) << "Failed to open resolver: "
|
LOG(ERROR) << "Failed to open resolver: "
|
||||||
<< net::ErrorToShortString(result);
|
<< net::ErrorToShortString(result);
|
||||||
@ -719,14 +453,14 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolver = std::make_unique<net::RedirectResolver>(
|
resolver = std::make_unique<net::RedirectResolver>(
|
||||||
std::move(resolver_socket), params.resolver_range,
|
std::move(resolver_socket), config.resolver_range,
|
||||||
params.resolver_prefix);
|
config.resolver_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto naive_proxy = std::make_unique<net::NaiveProxy>(
|
auto naive_proxy = std::make_unique<net::NaiveProxy>(
|
||||||
std::move(listen_socket), listen_params.protocol,
|
std::move(listen_socket), listen_config.protocol, listen_config.user,
|
||||||
listen_params.listen_user, listen_params.listen_pass,
|
listen_config.pass, config.insecure_concurrency, resolver.get(),
|
||||||
params.concurrency, resolver.get(), session, kTrafficAnnotation,
|
session, kTrafficAnnotation,
|
||||||
std::vector<net::PaddingType>{net::PaddingType::kVariant1,
|
std::vector<net::PaddingType>{net::PaddingType::kVariant1,
|
||||||
net::PaddingType::kNone});
|
net::PaddingType::kNone});
|
||||||
naive_proxies.push_back(std::move(naive_proxy));
|
naive_proxies.push_back(std::move(naive_proxy));
|
||||||
|
Loading…
Reference in New Issue
Block a user