mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
Add QUIC client
This commit is contained in:
parent
c407aa756f
commit
41cc39da39
@ -12,20 +12,19 @@
|
|||||||
#include "base/callback_helpers.h"
|
#include "base/callback_helpers.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/rand_util.h"
|
#include "base/rand_util.h"
|
||||||
|
#include "base/strings/strcat.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "net/base/io_buffer.h"
|
#include "net/base/io_buffer.h"
|
||||||
#include "net/base/load_flags.h"
|
#include "net/base/load_flags.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
#include "net/base/privacy_mode.h"
|
#include "net/base/privacy_mode.h"
|
||||||
#include "net/http/http_network_session.h"
|
|
||||||
#include "net/proxy_resolution/proxy_config.h"
|
|
||||||
#include "net/proxy_resolution/proxy_info.h"
|
#include "net/proxy_resolution/proxy_info.h"
|
||||||
#include "net/proxy_resolution/proxy_list.h"
|
|
||||||
#include "net/proxy_resolution/proxy_resolution_service.h"
|
|
||||||
#include "net/socket/client_socket_handle.h"
|
#include "net/socket/client_socket_handle.h"
|
||||||
#include "net/socket/client_socket_pool_manager.h"
|
#include "net/socket/client_socket_pool_manager.h"
|
||||||
#include "net/socket/stream_socket.h"
|
#include "net/socket/stream_socket.h"
|
||||||
#include "net/spdy/spdy_session.h"
|
#include "net/spdy/spdy_session.h"
|
||||||
|
#include "net/tools/naive/http_proxy_socket.h"
|
||||||
|
#include "net/tools/naive/socks5_server_socket.h"
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
@ -38,14 +37,24 @@ constexpr int kMaxPaddingSize = 255;
|
|||||||
|
|
||||||
NaiveConnection::NaiveConnection(
|
NaiveConnection::NaiveConnection(
|
||||||
unsigned int id,
|
unsigned int id,
|
||||||
|
Protocol protocol,
|
||||||
Direction pad_direction,
|
Direction pad_direction,
|
||||||
|
const ProxyInfo& proxy_info,
|
||||||
|
const SSLConfig& server_ssl_config,
|
||||||
|
const SSLConfig& proxy_ssl_config,
|
||||||
|
HttpNetworkSession* session,
|
||||||
|
const NetLogWithSource& net_log,
|
||||||
std::unique_ptr<StreamSocket> accepted_socket,
|
std::unique_ptr<StreamSocket> accepted_socket,
|
||||||
Delegate* delegate,
|
|
||||||
const NetworkTrafficAnnotationTag& traffic_annotation)
|
const NetworkTrafficAnnotationTag& traffic_annotation)
|
||||||
: id_(id),
|
: id_(id),
|
||||||
|
protocol_(protocol),
|
||||||
pad_direction_(pad_direction),
|
pad_direction_(pad_direction),
|
||||||
|
proxy_info_(proxy_info),
|
||||||
|
server_ssl_config_(server_ssl_config),
|
||||||
|
proxy_ssl_config_(proxy_ssl_config),
|
||||||
|
session_(session),
|
||||||
|
net_log_(net_log),
|
||||||
next_state_(STATE_NONE),
|
next_state_(STATE_NONE),
|
||||||
delegate_(delegate),
|
|
||||||
client_socket_(std::move(accepted_socket)),
|
client_socket_(std::move(accepted_socket)),
|
||||||
server_socket_handle_(std::make_unique<ClientSocketHandle>()),
|
server_socket_handle_(std::make_unique<ClientSocketHandle>()),
|
||||||
sockets_{client_socket_.get(), nullptr},
|
sockets_{client_socket_.get(), nullptr},
|
||||||
@ -167,11 +176,31 @@ int NaiveConnection::DoConnectClientComplete(int result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NaiveConnection::DoConnectServer() {
|
int NaiveConnection::DoConnectServer() {
|
||||||
DCHECK(delegate_);
|
|
||||||
next_state_ = STATE_CONNECT_SERVER_COMPLETE;
|
next_state_ = STATE_CONNECT_SERVER_COMPLETE;
|
||||||
|
|
||||||
return delegate_->OnConnectServer(id_, client_socket_.get(),
|
HostPortPair origin;
|
||||||
server_socket_handle_.get(), io_callback_);
|
if (protocol_ == kSocks5) {
|
||||||
|
const auto* socket =
|
||||||
|
static_cast<const Socks5ServerSocket*>(client_socket_.get());
|
||||||
|
origin = socket->request_endpoint();
|
||||||
|
} else if (protocol_ == kHttp) {
|
||||||
|
const auto* socket =
|
||||||
|
static_cast<const HttpProxySocket*>(client_socket_.get());
|
||||||
|
origin = socket->request_endpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origin.IsEmpty()) {
|
||||||
|
LOG(ERROR) << "Connection " << id_ << " to invalid origin";
|
||||||
|
return ERR_ADDRESS_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Connection " << id_ << " to " << origin.ToString();
|
||||||
|
|
||||||
|
// Ignores socket limit set by socket pool for this type of socket.
|
||||||
|
return InitSocketHandleForRawConnect2(
|
||||||
|
origin, session_, LOAD_IGNORE_LIMITS, MAXIMUM_PRIORITY, proxy_info_,
|
||||||
|
server_ssl_config_, proxy_ssl_config_, PRIVACY_MODE_DISABLED, net_log_,
|
||||||
|
server_socket_handle_.get(), io_callback_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NaiveConnection::DoConnectServerComplete(int result) {
|
int NaiveConnection::DoConnectServerComplete(int result) {
|
||||||
|
@ -20,14 +20,23 @@ namespace net {
|
|||||||
|
|
||||||
class ClientSocketHandle;
|
class ClientSocketHandle;
|
||||||
class DrainableIOBuffer;
|
class DrainableIOBuffer;
|
||||||
|
class HttpNetworkSession;
|
||||||
class IOBuffer;
|
class IOBuffer;
|
||||||
|
class NetLogWithSource;
|
||||||
|
class ProxyInfo;
|
||||||
class StreamSocket;
|
class StreamSocket;
|
||||||
struct NetworkTrafficAnnotationTag;
|
struct NetworkTrafficAnnotationTag;
|
||||||
|
struct SSLConfig;
|
||||||
|
|
||||||
class NaiveConnection {
|
class NaiveConnection {
|
||||||
public:
|
public:
|
||||||
using TimeFunc = base::TimeTicks (*)();
|
using TimeFunc = base::TimeTicks (*)();
|
||||||
|
|
||||||
|
enum Protocol {
|
||||||
|
kSocks5,
|
||||||
|
kHttp,
|
||||||
|
};
|
||||||
|
|
||||||
// From this direction.
|
// From this direction.
|
||||||
enum Direction {
|
enum Direction {
|
||||||
kClient = 0,
|
kClient = 0,
|
||||||
@ -36,24 +45,15 @@ class NaiveConnection {
|
|||||||
kNone = 2,
|
kNone = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Delegate {
|
|
||||||
public:
|
|
||||||
Delegate() {}
|
|
||||||
virtual ~Delegate() {}
|
|
||||||
|
|
||||||
virtual int OnConnectServer(unsigned int connection_id,
|
|
||||||
const StreamSocket* accepted_socket,
|
|
||||||
ClientSocketHandle* server_socket,
|
|
||||||
CompletionRepeatingCallback callback) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Delegate);
|
|
||||||
};
|
|
||||||
|
|
||||||
NaiveConnection(unsigned int id,
|
NaiveConnection(unsigned int id,
|
||||||
|
Protocol protocol,
|
||||||
Direction pad_direction,
|
Direction pad_direction,
|
||||||
|
const ProxyInfo& proxy_info,
|
||||||
|
const SSLConfig& server_ssl_config,
|
||||||
|
const SSLConfig& proxy_ssl_config,
|
||||||
|
HttpNetworkSession* session,
|
||||||
|
const NetLogWithSource& net_log,
|
||||||
std::unique_ptr<StreamSocket> accepted_socket,
|
std::unique_ptr<StreamSocket> accepted_socket,
|
||||||
Delegate* delegate,
|
|
||||||
const NetworkTrafficAnnotationTag& traffic_annotation);
|
const NetworkTrafficAnnotationTag& traffic_annotation);
|
||||||
~NaiveConnection();
|
~NaiveConnection();
|
||||||
|
|
||||||
@ -97,7 +97,13 @@ class NaiveConnection {
|
|||||||
void OnPushComplete(Direction from, Direction to, int result);
|
void OnPushComplete(Direction from, Direction to, int result);
|
||||||
|
|
||||||
unsigned int id_;
|
unsigned int id_;
|
||||||
|
Protocol protocol_;
|
||||||
Direction pad_direction_;
|
Direction pad_direction_;
|
||||||
|
const ProxyInfo& proxy_info_;
|
||||||
|
const SSLConfig& server_ssl_config_;
|
||||||
|
const SSLConfig& proxy_ssl_config_;
|
||||||
|
HttpNetworkSession* session_;
|
||||||
|
const NetLogWithSource& net_log_;
|
||||||
|
|
||||||
CompletionRepeatingCallback io_callback_;
|
CompletionRepeatingCallback io_callback_;
|
||||||
CompletionOnceCallback connect_callback_;
|
CompletionOnceCallback connect_callback_;
|
||||||
@ -105,8 +111,6 @@ class NaiveConnection {
|
|||||||
|
|
||||||
State next_state_;
|
State next_state_;
|
||||||
|
|
||||||
Delegate* delegate_;
|
|
||||||
|
|
||||||
std::unique_ptr<StreamSocket> client_socket_;
|
std::unique_ptr<StreamSocket> client_socket_;
|
||||||
std::unique_ptr<ClientSocketHandle> server_socket_handle_;
|
std::unique_ptr<ClientSocketHandle> server_socket_handle_;
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "net/http/http_network_session.h"
|
#include "net/http/http_network_session.h"
|
||||||
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
|
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
|
||||||
#include "net/proxy_resolution/proxy_config.h"
|
#include "net/proxy_resolution/proxy_config.h"
|
||||||
#include "net/proxy_resolution/proxy_info.h"
|
|
||||||
#include "net/proxy_resolution/proxy_list.h"
|
#include "net/proxy_resolution/proxy_list.h"
|
||||||
#include "net/socket/client_socket_pool_manager.h"
|
#include "net/socket/client_socket_pool_manager.h"
|
||||||
#include "net/socket/server_socket.h"
|
#include "net/socket/server_socket.h"
|
||||||
@ -27,18 +26,32 @@
|
|||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
NaiveProxy::NaiveProxy(std::unique_ptr<ServerSocket> listen_socket,
|
NaiveProxy::NaiveProxy(std::unique_ptr<ServerSocket> listen_socket,
|
||||||
Protocol protocol,
|
NaiveConnection::Protocol protocol,
|
||||||
bool use_proxy,
|
bool use_padding,
|
||||||
HttpNetworkSession* session,
|
HttpNetworkSession* session,
|
||||||
const NetworkTrafficAnnotationTag& traffic_annotation)
|
const NetworkTrafficAnnotationTag& traffic_annotation)
|
||||||
: listen_socket_(std::move(listen_socket)),
|
: listen_socket_(std::move(listen_socket)),
|
||||||
protocol_(protocol),
|
protocol_(protocol),
|
||||||
use_proxy_(use_proxy),
|
use_padding_(use_padding),
|
||||||
session_(session),
|
session_(session),
|
||||||
net_log_(
|
net_log_(
|
||||||
NetLogWithSource::Make(session->net_log(), NetLogSourceType::NONE)),
|
NetLogWithSource::Make(session->net_log(), NetLogSourceType::NONE)),
|
||||||
last_id_(0),
|
last_id_(0),
|
||||||
traffic_annotation_(traffic_annotation) {
|
traffic_annotation_(traffic_annotation) {
|
||||||
|
const auto& proxy_config = static_cast<ConfiguredProxyResolutionService*>(
|
||||||
|
session_->proxy_resolution_service())
|
||||||
|
->config();
|
||||||
|
DCHECK(proxy_config);
|
||||||
|
const ProxyList& proxy_list =
|
||||||
|
proxy_config.value().value().proxy_rules().single_proxies;
|
||||||
|
DCHECK(!proxy_list.IsEmpty());
|
||||||
|
proxy_info_.UseProxyList(proxy_list);
|
||||||
|
proxy_info_.set_traffic_annotation(
|
||||||
|
net::MutableNetworkTrafficAnnotationTag(traffic_annotation_));
|
||||||
|
|
||||||
|
session_->GetSSLConfig(&server_ssl_config_, &proxy_ssl_config_);
|
||||||
|
proxy_ssl_config_.disable_cert_verification_network_fetches = true;
|
||||||
|
|
||||||
DCHECK(listen_socket_);
|
DCHECK(listen_socket_);
|
||||||
// Start accepting connections in next run loop in case when delegate is not
|
// Start accepting connections in next run loop in case when delegate is not
|
||||||
// ready to get callbacks.
|
// ready to get callbacks.
|
||||||
@ -78,19 +91,24 @@ void NaiveProxy::HandleAcceptResult(int result) {
|
|||||||
void NaiveProxy::DoConnect() {
|
void NaiveProxy::DoConnect() {
|
||||||
std::unique_ptr<StreamSocket> socket;
|
std::unique_ptr<StreamSocket> socket;
|
||||||
NaiveConnection::Direction pad_direction;
|
NaiveConnection::Direction pad_direction;
|
||||||
if (protocol_ == kSocks5) {
|
if (protocol_ == NaiveConnection::kSocks5) {
|
||||||
socket = std::make_unique<Socks5ServerSocket>(std::move(accepted_socket_),
|
socket = std::make_unique<Socks5ServerSocket>(std::move(accepted_socket_),
|
||||||
traffic_annotation_);
|
traffic_annotation_);
|
||||||
pad_direction = NaiveConnection::kClient;
|
pad_direction = NaiveConnection::kClient;
|
||||||
} else if (protocol_ == kHttp) {
|
} else if (protocol_ == NaiveConnection::kHttp) {
|
||||||
socket = std::make_unique<HttpProxySocket>(std::move(accepted_socket_),
|
socket = std::make_unique<HttpProxySocket>(std::move(accepted_socket_),
|
||||||
traffic_annotation_);
|
traffic_annotation_);
|
||||||
pad_direction = NaiveConnection::kServer;
|
pad_direction = NaiveConnection::kServer;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!use_padding_) {
|
||||||
|
pad_direction = NaiveConnection::kNone;
|
||||||
|
}
|
||||||
auto connection_ptr = std::make_unique<NaiveConnection>(
|
auto connection_ptr = std::make_unique<NaiveConnection>(
|
||||||
++last_id_, pad_direction, std::move(socket), this, traffic_annotation_);
|
++last_id_, protocol_, pad_direction, proxy_info_, server_ssl_config_,
|
||||||
|
proxy_ssl_config_, session_, net_log_, std::move(socket),
|
||||||
|
traffic_annotation_);
|
||||||
auto* connection = connection_ptr.get();
|
auto* connection = connection_ptr.get();
|
||||||
connection_by_id_[connection->id()] = std::move(connection_ptr);
|
connection_by_id_[connection->id()] = std::move(connection_ptr);
|
||||||
int result = connection->Connect(
|
int result = connection->Connect(
|
||||||
@ -101,61 +119,8 @@ void NaiveProxy::DoConnect() {
|
|||||||
HandleConnectResult(connection, result);
|
HandleConnectResult(connection, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NaiveProxy::OnConnectServer(unsigned int connection_id,
|
void NaiveProxy::OnConnectComplete(unsigned int connection_id, int result) {
|
||||||
const StreamSocket* client_socket,
|
auto* connection = FindConnection(connection_id);
|
||||||
ClientSocketHandle* server_socket,
|
|
||||||
CompletionRepeatingCallback callback) {
|
|
||||||
// Ignores socket limit set by socket pool for this type of socket.
|
|
||||||
constexpr int request_load_flags = LOAD_IGNORE_LIMITS;
|
|
||||||
constexpr RequestPriority request_priority = MAXIMUM_PRIORITY;
|
|
||||||
|
|
||||||
ProxyInfo proxy_info;
|
|
||||||
SSLConfig server_ssl_config;
|
|
||||||
SSLConfig proxy_ssl_config;
|
|
||||||
|
|
||||||
if (use_proxy_) {
|
|
||||||
const auto& proxy_config = static_cast<ConfiguredProxyResolutionService*>(
|
|
||||||
session_->proxy_resolution_service())
|
|
||||||
->config();
|
|
||||||
DCHECK(proxy_config);
|
|
||||||
const ProxyList& proxy_list =
|
|
||||||
proxy_config.value().value().proxy_rules().single_proxies;
|
|
||||||
if (proxy_list.IsEmpty())
|
|
||||||
return ERR_MANDATORY_PROXY_CONFIGURATION_FAILED;
|
|
||||||
proxy_info.UseProxyList(proxy_list);
|
|
||||||
proxy_info.set_traffic_annotation(
|
|
||||||
net::MutableNetworkTrafficAnnotationTag(traffic_annotation_));
|
|
||||||
|
|
||||||
session_->GetSSLConfig(&server_ssl_config, &proxy_ssl_config);
|
|
||||||
proxy_ssl_config.disable_cert_verification_network_fetches = true;
|
|
||||||
} else {
|
|
||||||
proxy_info.UseDirect();
|
|
||||||
}
|
|
||||||
|
|
||||||
HostPortPair request_endpoint;
|
|
||||||
if (protocol_ == kSocks5) {
|
|
||||||
const auto* socket = static_cast<const Socks5ServerSocket*>(client_socket);
|
|
||||||
request_endpoint = socket->request_endpoint();
|
|
||||||
} else if (protocol_ == kHttp) {
|
|
||||||
const auto* socket = static_cast<const HttpProxySocket*>(client_socket);
|
|
||||||
request_endpoint = socket->request_endpoint();
|
|
||||||
}
|
|
||||||
if (request_endpoint.IsEmpty()) {
|
|
||||||
LOG(ERROR) << "Connection " << connection_id << " to invalid origin";
|
|
||||||
return ERR_ADDRESS_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(INFO) << "Connection " << connection_id << " to "
|
|
||||||
<< request_endpoint.ToString();
|
|
||||||
|
|
||||||
return InitSocketHandleForRawConnect2(
|
|
||||||
request_endpoint, session_, request_load_flags, request_priority,
|
|
||||||
proxy_info, server_ssl_config, proxy_ssl_config, PRIVACY_MODE_DISABLED,
|
|
||||||
net_log_, server_socket, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NaiveProxy::OnConnectComplete(int connection_id, int result) {
|
|
||||||
NaiveConnection* connection = FindConnection(connection_id);
|
|
||||||
if (!connection)
|
if (!connection)
|
||||||
return;
|
return;
|
||||||
HandleConnectResult(connection, result);
|
HandleConnectResult(connection, result);
|
||||||
@ -178,8 +143,8 @@ void NaiveProxy::DoRun(NaiveConnection* connection) {
|
|||||||
HandleRunResult(connection, result);
|
HandleRunResult(connection, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NaiveProxy::OnRunComplete(int connection_id, int result) {
|
void NaiveProxy::OnRunComplete(unsigned int connection_id, int result) {
|
||||||
NaiveConnection* connection = FindConnection(connection_id);
|
auto* connection = FindConnection(connection_id);
|
||||||
if (!connection)
|
if (!connection)
|
||||||
return;
|
return;
|
||||||
HandleRunResult(connection, result);
|
HandleRunResult(connection, result);
|
||||||
@ -189,7 +154,7 @@ void NaiveProxy::HandleRunResult(NaiveConnection* connection, int result) {
|
|||||||
Close(connection->id(), result);
|
Close(connection->id(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NaiveProxy::Close(int connection_id, int reason) {
|
void NaiveProxy::Close(unsigned int connection_id, int reason) {
|
||||||
auto it = connection_by_id_.find(connection_id);
|
auto it = connection_by_id_.find(connection_id);
|
||||||
if (it == connection_by_id_.end())
|
if (it == connection_by_id_.end())
|
||||||
return;
|
return;
|
||||||
@ -206,19 +171,11 @@ void NaiveProxy::Close(int connection_id, int reason) {
|
|||||||
connection_by_id_.erase(it);
|
connection_by_id_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
NaiveConnection* NaiveProxy::FindConnection(int connection_id) {
|
NaiveConnection* NaiveProxy::FindConnection(unsigned int connection_id) {
|
||||||
auto it = connection_by_id_.find(connection_id);
|
auto it = connection_by_id_.find(connection_id);
|
||||||
if (it == connection_by_id_.end())
|
if (it == connection_by_id_.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called after any delegate callbacks are called to check if Close()
|
|
||||||
// has been called during callback processing. Using the pointer of connection,
|
|
||||||
// |connection| is safe here because Close() deletes the connection in next run
|
|
||||||
// loop.
|
|
||||||
bool NaiveProxy::HasClosedConnection(NaiveConnection* connection) {
|
|
||||||
return FindConnection(connection->id()) != connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "net/base/completion_repeating_callback.h"
|
#include "net/base/completion_repeating_callback.h"
|
||||||
#include "net/log/net_log_with_source.h"
|
#include "net/log/net_log_with_source.h"
|
||||||
|
#include "net/proxy_resolution/proxy_info.h"
|
||||||
|
#include "net/ssl/ssl_config.h"
|
||||||
#include "net/tools/naive/naive_connection.h"
|
#include "net/tools/naive/naive_connection.h"
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -24,24 +26,14 @@ class ServerSocket;
|
|||||||
class StreamSocket;
|
class StreamSocket;
|
||||||
struct NetworkTrafficAnnotationTag;
|
struct NetworkTrafficAnnotationTag;
|
||||||
|
|
||||||
class NaiveProxy : public NaiveConnection::Delegate {
|
class NaiveProxy {
|
||||||
public:
|
public:
|
||||||
enum Protocol {
|
|
||||||
kSocks5,
|
|
||||||
kHttp,
|
|
||||||
};
|
|
||||||
|
|
||||||
NaiveProxy(std::unique_ptr<ServerSocket> server_socket,
|
NaiveProxy(std::unique_ptr<ServerSocket> server_socket,
|
||||||
Protocol protocol,
|
NaiveConnection::Protocol protocol,
|
||||||
bool use_proxy,
|
bool use_padding,
|
||||||
HttpNetworkSession* session,
|
HttpNetworkSession* session,
|
||||||
const NetworkTrafficAnnotationTag& traffic_annotation);
|
const NetworkTrafficAnnotationTag& traffic_annotation);
|
||||||
~NaiveProxy() override;
|
~NaiveProxy();
|
||||||
|
|
||||||
int OnConnectServer(unsigned int connection_id,
|
|
||||||
const StreamSocket* accepted_socket,
|
|
||||||
ClientSocketHandle* server_socket,
|
|
||||||
CompletionRepeatingCallback callback) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DoAcceptLoop();
|
void DoAcceptLoop();
|
||||||
@ -49,21 +41,23 @@ class NaiveProxy : public NaiveConnection::Delegate {
|
|||||||
void HandleAcceptResult(int result);
|
void HandleAcceptResult(int result);
|
||||||
|
|
||||||
void DoConnect();
|
void DoConnect();
|
||||||
void OnConnectComplete(int connection_id, int result);
|
void OnConnectComplete(unsigned int connection_id, int result);
|
||||||
void HandleConnectResult(NaiveConnection* connection, int result);
|
void HandleConnectResult(NaiveConnection* connection, int result);
|
||||||
|
|
||||||
void DoRun(NaiveConnection* connection);
|
void DoRun(NaiveConnection* connection);
|
||||||
void OnRunComplete(int connection_id, int result);
|
void OnRunComplete(unsigned int connection_id, int result);
|
||||||
void HandleRunResult(NaiveConnection* connection, int result);
|
void HandleRunResult(NaiveConnection* connection, int result);
|
||||||
|
|
||||||
void Close(int connection_id, int reason);
|
void Close(unsigned int connection_id, int reason);
|
||||||
|
|
||||||
NaiveConnection* FindConnection(int connection_id);
|
NaiveConnection* FindConnection(unsigned int connection_id);
|
||||||
bool HasClosedConnection(NaiveConnection* connection);
|
|
||||||
|
|
||||||
std::unique_ptr<ServerSocket> listen_socket_;
|
std::unique_ptr<ServerSocket> listen_socket_;
|
||||||
Protocol protocol_;
|
NaiveConnection::Protocol protocol_;
|
||||||
bool use_proxy_;
|
bool use_padding_;
|
||||||
|
ProxyInfo proxy_info_;
|
||||||
|
SSLConfig server_ssl_config_;
|
||||||
|
SSLConfig proxy_ssl_config_;
|
||||||
HttpNetworkSession* session_;
|
HttpNetworkSession* session_;
|
||||||
NetLogWithSource net_log_;
|
NetLogWithSource net_log_;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -47,12 +48,14 @@
|
|||||||
#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/ssl/ssl_key_logger_impl.h"
|
#include "net/ssl/ssl_key_logger_impl.h"
|
||||||
|
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
|
||||||
#include "net/tools/naive/naive_proxy.h"
|
#include "net/tools/naive/naive_proxy.h"
|
||||||
#include "net/traffic_annotation/network_traffic_annotation.h"
|
#include "net/traffic_annotation/network_traffic_annotation.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "net/url_request/url_request_context_builder.h"
|
#include "net/url_request/url_request_context_builder.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
#include "url/scheme_host_port.h"
|
#include "url/scheme_host_port.h"
|
||||||
|
#include "url/url_util.h"
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||||
@ -68,15 +71,16 @@ constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
|
|||||||
net::DefineNetworkTrafficAnnotation("naive", "");
|
net::DefineNetworkTrafficAnnotation("naive", "");
|
||||||
|
|
||||||
struct Params {
|
struct Params {
|
||||||
|
net::NaiveConnection::Protocol protocol;
|
||||||
std::string listen_addr;
|
std::string listen_addr;
|
||||||
int listen_port;
|
int listen_port;
|
||||||
net::NaiveProxy::Protocol protocol;
|
bool use_padding;
|
||||||
bool use_proxy;
|
|
||||||
std::string proxy_url;
|
std::string proxy_url;
|
||||||
std::u16string proxy_user;
|
std::u16string proxy_user;
|
||||||
std::u16string proxy_pass;
|
std::u16string proxy_pass;
|
||||||
std::string host_resolver_rules;
|
std::string host_resolver_rules;
|
||||||
logging::LoggingSettings log_settings;
|
logging::LoggingSettings log_settings;
|
||||||
|
base::FilePath log_path;
|
||||||
base::FilePath net_log_path;
|
base::FilePath net_log_path;
|
||||||
base::FilePath ssl_key_path;
|
base::FilePath ssl_key_path;
|
||||||
};
|
};
|
||||||
@ -103,9 +107,7 @@ std::unique_ptr<net::URLRequestContext> BuildURLRequestContext(
|
|||||||
builder.set_net_log(net_log);
|
builder.set_net_log(net_log);
|
||||||
|
|
||||||
net::ProxyConfig proxy_config;
|
net::ProxyConfig proxy_config;
|
||||||
if (params.use_proxy) {
|
proxy_config.proxy_rules().ParseFromString(params.proxy_url);
|
||||||
proxy_config.proxy_rules().ParseFromString(params.proxy_url);
|
|
||||||
}
|
|
||||||
auto proxy_service =
|
auto proxy_service =
|
||||||
net::ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
net::ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
||||||
std::make_unique<net::ProxyConfigServiceFixed>(
|
std::make_unique<net::ProxyConfigServiceFixed>(
|
||||||
@ -120,11 +122,20 @@ std::unique_ptr<net::URLRequestContext> BuildURLRequestContext(
|
|||||||
|
|
||||||
auto context = builder.Build();
|
auto context = builder.Build();
|
||||||
|
|
||||||
if (params.use_proxy) {
|
if (!params.proxy_url.empty() && !params.proxy_user.empty() &&
|
||||||
net::HttpNetworkSession* session =
|
!params.proxy_pass.empty()) {
|
||||||
context->http_transaction_factory()->GetSession();
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
net::HttpAuthCache* auth_cache = session->http_auth_cache();
|
auto* auth_cache = session->http_auth_cache();
|
||||||
GURL auth_origin(params.proxy_url);
|
std::string proxy_url = params.proxy_url;
|
||||||
|
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
||||||
|
proxy_url.replace(0, 4, "https");
|
||||||
|
auto* quic = context->quic_context()->params();
|
||||||
|
const auto& versions = quic::SupportedVersions();
|
||||||
|
quic->supported_versions.assign(versions.begin(), versions.end());
|
||||||
|
quic->origins_to_force_quic_on.insert(
|
||||||
|
net::HostPortPair::FromURL(GURL(proxy_url)));
|
||||||
|
}
|
||||||
|
GURL auth_origin(proxy_url);
|
||||||
net::AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
net::AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
||||||
auth_cache->Add(auth_origin, net::HttpAuth::AUTH_PROXY,
|
auth_cache->Add(auth_origin, net::HttpAuth::AUTH_PROXY,
|
||||||
/*realm=*/std::string(), net::HttpAuth::AUTH_SCHEME_BASIC,
|
/*realm=*/std::string(), net::HttpAuth::AUTH_SCHEME_BASIC,
|
||||||
@ -139,92 +150,98 @@ bool ParseCommandLineFlags(Params* params) {
|
|||||||
const base::CommandLine& line = *base::CommandLine::ForCurrentProcess();
|
const base::CommandLine& line = *base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
if (line.HasSwitch("h") || line.HasSwitch("help")) {
|
if (line.HasSwitch("h") || line.HasSwitch("help")) {
|
||||||
LOG(INFO) << "Usage: naive [options]\n"
|
std::cout << "Usage: naive [options]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"-h, --help Show this message\n"
|
"-h, --help Show this message\n"
|
||||||
"--version Print version\n"
|
"--version Print version\n"
|
||||||
"--addr=<address> Address to listen on (0.0.0.0)\n"
|
"--listen=<proto>://[addr][:port]\n"
|
||||||
"--port=<port> Port to listen on (1080)\n"
|
" proto: socks, http\n"
|
||||||
"--proto=[socks|http] Protocol to accept (socks)\n"
|
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
||||||
"--proxy=https://<user>:<pass>@<hostname>[:<port>]\n"
|
" proto: https, quic\n"
|
||||||
" Proxy specification.\n"
|
"--padding Use padding\n"
|
||||||
"--log Log to stderr, otherwise no log\n"
|
"--log[=<path>] Log to stderr, or file\n"
|
||||||
"--log-net-log=<path> Save NetLog\n"
|
"--log-net-log=<path> Save NetLog\n"
|
||||||
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n";
|
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n"
|
||||||
|
<< std::endl;
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.HasSwitch("version")) {
|
if (line.HasSwitch("version")) {
|
||||||
LOG(INFO) << "Version: " << version_info::GetVersionNumber();
|
std::cout << "Version: " << version_info::GetVersionNumber() << std::endl;
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params->protocol = net::NaiveConnection::kSocks5;
|
||||||
params->listen_addr = "0.0.0.0";
|
params->listen_addr = "0.0.0.0";
|
||||||
if (line.HasSwitch("addr")) {
|
|
||||||
params->listen_addr = line.GetSwitchValueASCII("addr");
|
|
||||||
}
|
|
||||||
if (params->listen_addr.empty()) {
|
|
||||||
LOG(ERROR) << "Invalid --addr";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->listen_port = 1080;
|
params->listen_port = 1080;
|
||||||
if (line.HasSwitch("port")) {
|
url::AddStandardScheme("socks", url::SCHEME_WITH_HOST_AND_PORT);
|
||||||
if (!base::StringToInt(line.GetSwitchValueASCII("port"),
|
if (line.HasSwitch("listen")) {
|
||||||
¶ms->listen_port)) {
|
GURL url(line.GetSwitchValueASCII("listen"));
|
||||||
LOG(ERROR) << "Invalid --port";
|
if (url.scheme() == "socks") {
|
||||||
return false;
|
params->protocol = net::NaiveConnection::kSocks5;
|
||||||
}
|
params->listen_port = 1080;
|
||||||
if (params->listen_port <= 0 ||
|
} else if (url.scheme() == "http") {
|
||||||
params->listen_port > std::numeric_limits<uint16_t>::max()) {
|
params->protocol = net::NaiveConnection::kHttp;
|
||||||
LOG(ERROR) << "Invalid --port";
|
params->listen_port = 8080;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
params->protocol = net::NaiveProxy::kSocks5;
|
|
||||||
if (line.HasSwitch("proto")) {
|
|
||||||
const auto& proto = line.GetSwitchValueASCII("proto");
|
|
||||||
if (proto == "socks") {
|
|
||||||
params->protocol = net::NaiveProxy::kSocks5;
|
|
||||||
} else if (proto == "http") {
|
|
||||||
params->protocol = net::NaiveProxy::kHttp;
|
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Invalid --proto";
|
LOG(ERROR) << "Invalid scheme in --listen";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!url.host().empty()) {
|
||||||
|
params->listen_addr = url.host();
|
||||||
|
}
|
||||||
|
if (!url.port().empty()) {
|
||||||
|
if (!base::StringToInt(url.port(), ¶ms->listen_port)) {
|
||||||
|
LOG(ERROR) << "Invalid port in --listen";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (params->listen_port <= 0 ||
|
||||||
|
params->listen_port > std::numeric_limits<uint16_t>::max()) {
|
||||||
|
LOG(ERROR) << "Invalid port in --listen";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
params->use_proxy = false;
|
url::AddStandardScheme("quic",
|
||||||
|
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||||
|
params->proxy_url = "direct://";
|
||||||
GURL url(line.GetSwitchValueASCII("proxy"));
|
GURL url(line.GetSwitchValueASCII("proxy"));
|
||||||
if (line.HasSwitch("proxy")) {
|
if (line.HasSwitch("proxy")) {
|
||||||
params->use_proxy = true;
|
|
||||||
if (!url.is_valid()) {
|
if (!url.is_valid()) {
|
||||||
LOG(ERROR) << "Invalid proxy URL";
|
LOG(ERROR) << "Invalid proxy URL";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (url.scheme() != "https") {
|
if (url.scheme() != "https" && url.scheme() != "quic") {
|
||||||
LOG(ERROR) << "Must be HTTPS proxy";
|
LOG(ERROR) << "Must be HTTPS or QUIC proxy";
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (url.username().empty() || url.password().empty()) {
|
|
||||||
LOG(ERROR) << "Missing user or pass";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
params->proxy_url = url::SchemeHostPort(url).Serialize();
|
params->proxy_url = url::SchemeHostPort(url).Serialize();
|
||||||
net::GetIdentityFromURL(url, ¶ms->proxy_user, ¶ms->proxy_pass);
|
net::GetIdentityFromURL(url, ¶ms->proxy_user, ¶ms->proxy_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params->use_padding = false;
|
||||||
|
if (line.HasSwitch("padding")) {
|
||||||
|
params->use_padding = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (line.HasSwitch("host-resolver-rules")) {
|
if (line.HasSwitch("host-resolver-rules")) {
|
||||||
params->host_resolver_rules =
|
params->host_resolver_rules =
|
||||||
line.GetSwitchValueASCII("host-resolver-rules");
|
line.GetSwitchValueASCII("host-resolver-rules");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.HasSwitch("log")) {
|
if (line.HasSwitch("log")) {
|
||||||
params->log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
params->log_settings.logging_dest = logging::LOG_DEFAULT;
|
||||||
|
params->log_path = line.GetSwitchValuePath("log");
|
||||||
|
if (!params->log_path.empty()) {
|
||||||
|
params->log_settings.logging_dest = logging::LOG_TO_FILE;
|
||||||
|
} else if (params->log_settings.logging_dest == logging::LOG_TO_FILE) {
|
||||||
|
params->log_path = base::FilePath::FromUTF8Unsafe("naive.log");
|
||||||
|
}
|
||||||
|
params->log_settings.log_file_path = params->log_path.value().c_str();
|
||||||
} else {
|
} else {
|
||||||
params->log_settings.logging_dest = logging::LOG_NONE;
|
params->log_settings.logging_dest = logging::LOG_NONE;
|
||||||
}
|
}
|
||||||
@ -340,6 +357,7 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto context = BuildURLRequestContext(params, net_log);
|
auto context = BuildURLRequestContext(params, net_log);
|
||||||
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
|
|
||||||
auto listen_socket =
|
auto listen_socket =
|
||||||
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource());
|
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource());
|
||||||
@ -351,9 +369,8 @@ int main(int argc, char* argv[]) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
net::NaiveProxy naive_proxy(
|
net::NaiveProxy naive_proxy(std::move(listen_socket), params.protocol,
|
||||||
std::move(listen_socket), params.protocol, params.use_proxy,
|
params.use_padding, session, kTrafficAnnotation);
|
||||||
context->http_transaction_factory()->GetSession(), kTrafficAnnotation);
|
|
||||||
|
|
||||||
base::RunLoop().Run();
|
base::RunLoop().Run();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user