From c1e1deeca86945e18f6739d37cf0882603699547 Mon Sep 17 00:00:00 2001 From: klzgrad Date: Sun, 23 Jun 2019 05:20:30 +0800 Subject: [PATCH] Support TCP transparent proxying Enable with naive --listen=redir:// and iptables ... -j REDIRECT --to-ports 1080. --- src/net/tools/naive/naive_connection.cc | 27 +++++++++++++++++++++++++ src/net/tools/naive/naive_connection.h | 1 + src/net/tools/naive/naive_proxy.cc | 3 +++ src/net/tools/naive/naive_proxy_bin.cc | 5 +++++ 4 files changed, 36 insertions(+) diff --git a/src/net/tools/naive/naive_connection.cc b/src/net/tools/naive/naive_connection.cc index 31a0040b06..674aba407f 100644 --- a/src/net/tools/naive/naive_connection.cc +++ b/src/net/tools/naive/naive_connection.cc @@ -26,6 +26,16 @@ #include "net/tools/naive/http_proxy_socket.h" #include "net/tools/naive/socks5_server_socket.h" +#if defined(OS_LINUX) +#include +#include +#include + +#include "net/base/ip_endpoint.h" +#include "net/base/sockaddr_storage.h" +#include "net/socket/tcp_client_socket.h" +#endif + namespace net { namespace { @@ -187,6 +197,23 @@ int NaiveConnection::DoConnectServer() { const auto* socket = static_cast(client_socket_.get()); origin = socket->request_endpoint(); + } else if (protocol_ == kRedir) { +#if defined(OS_LINUX) + const auto* socket = + static_cast(client_socket_.get()); + int sd = socket->SocketDescriptorForTesting(); + SockaddrStorage dst; + int rv; + rv = getsockopt(sd, SOL_IP, SO_ORIGINAL_DST, dst.addr, &dst.addr_len); + if (rv == 0) { + IPEndPoint ipe; + if (ipe.FromSockAddr(dst.addr, dst.addr_len)) { + origin = HostPortPair::FromIPEndPoint(ipe); + } + } +#else + static_cast(resolver_); +#endif } if (origin.IsEmpty()) { diff --git a/src/net/tools/naive/naive_connection.h b/src/net/tools/naive/naive_connection.h index ff1e68ec52..ca6657ca5d 100644 --- a/src/net/tools/naive/naive_connection.h +++ b/src/net/tools/naive/naive_connection.h @@ -35,6 +35,7 @@ class NaiveConnection { enum Protocol { kSocks5, kHttp, + kRedir, }; // From this direction. diff --git a/src/net/tools/naive/naive_proxy.cc b/src/net/tools/naive/naive_proxy.cc index e5671be37c..dda0d9b27a 100644 --- a/src/net/tools/naive/naive_proxy.cc +++ b/src/net/tools/naive/naive_proxy.cc @@ -96,6 +96,9 @@ void NaiveProxy::DoConnect() { socket = std::make_unique(std::move(accepted_socket_), traffic_annotation_); pad_direction = NaiveConnection::kServer; + } else if (protocol_ == NaiveConnection::kRedir) { + socket = std::move(accepted_socket_); + pad_direction = NaiveConnection::kClient; } else { return; } diff --git a/src/net/tools/naive/naive_proxy_bin.cc b/src/net/tools/naive/naive_proxy_bin.cc index 75f4118e63..0301ecaec5 100644 --- a/src/net/tools/naive/naive_proxy_bin.cc +++ b/src/net/tools/naive/naive_proxy_bin.cc @@ -171,6 +171,7 @@ void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) { "--version Print version\n" "--listen=://[addr][:port]\n" " proto: socks, http\n" + " redir (Linux only)\n" "--proxy=://[:@][:]\n" " proto: https, quic\n" "--padding Use padding\n" @@ -256,6 +257,7 @@ bool ParseCommandLine(const CommandLine& cmdline, Params* params) { params->listen_addr = "0.0.0.0"; params->listen_port = 1080; url::AddStandardScheme("socks", url::SCHEME_WITH_HOST_AND_PORT); + url::AddStandardScheme("redir", url::SCHEME_WITH_HOST_AND_PORT); if (!cmdline.listen.empty()) { GURL url(cmdline.listen); if (url.scheme() == "socks") { @@ -264,6 +266,9 @@ bool ParseCommandLine(const CommandLine& cmdline, Params* params) { } else if (url.scheme() == "http") { params->protocol = net::NaiveConnection::kHttp; params->listen_port = 8080; + } else if (url.scheme() == "redir") { + params->protocol = net::NaiveConnection::kRedir; + params->listen_port = 1080; } else { std::cerr << "Invalid scheme in --listen" << std::endl; return false;