From a03e6e71407959c511019a887d848b269fa03145 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 09809557fc..ac03ea5b43 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 8657fb6f31..5075a331d3 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 d245f511c4..ea1e8d7064 100644 --- a/src/net/tools/naive/naive_proxy.cc +++ b/src/net/tools/naive/naive_proxy.cc @@ -99,6 +99,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 0dd8a7ef5b..6a5af724e5 100644 --- a/src/net/tools/naive/naive_proxy_bin.cc +++ b/src/net/tools/naive/naive_proxy_bin.cc @@ -170,6 +170,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" @@ -255,6 +256,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") { @@ -263,6 +265,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;