From f2bd5e1ce9706d08830869435c2c103acf859408 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 | 25 +++++++++++++++++++++++++ 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, 34 insertions(+) diff --git a/src/net/tools/naive/naive_connection.cc b/src/net/tools/naive/naive_connection.cc index 8d03e3d604..9bbf5e6d58 100644 --- a/src/net/tools/naive/naive_connection.cc +++ b/src/net/tools/naive/naive_connection.cc @@ -25,6 +25,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,21 @@ 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); + } + } +#endif } if (origin.IsEmpty()) { diff --git a/src/net/tools/naive/naive_connection.h b/src/net/tools/naive/naive_connection.h index 4561c2695c..f16abfb81e 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 c9b23059cf..0118a88cad 100644 --- a/src/net/tools/naive/naive_proxy.cc +++ b/src/net/tools/naive/naive_proxy.cc @@ -98,6 +98,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 da64c9701c..65247e61e1 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;