Support TCP transparent proxying

Enable with naive --listen=redir:// and iptables ... -j REDIRECT
--to-ports 1080.
This commit is contained in:
klzgrad 2019-06-23 05:20:30 +08:00
parent 4aab76466a
commit 75c9bab359
4 changed files with 36 additions and 0 deletions

View File

@ -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 <linux/netfilter_ipv4.h>
#include <netinet/in.h>
#include <sys/socket.h>
#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<const HttpProxySocket*>(client_socket_.get());
origin = socket->request_endpoint();
} else if (protocol_ == kRedir) {
#if defined(OS_LINUX)
const auto* socket =
static_cast<const TCPClientSocket*>(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<void>(resolver_);
#endif
}
if (origin.IsEmpty()) {

View File

@ -35,6 +35,7 @@ class NaiveConnection {
enum Protocol {
kSocks5,
kHttp,
kRedir,
};
// From this direction.

View File

@ -99,6 +99,9 @@ void NaiveProxy::DoConnect() {
socket = std::make_unique<HttpProxySocket>(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;
}

View File

@ -171,6 +171,7 @@ void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) {
"--version Print version\n"
"--listen=<proto>://[addr][:port]\n"
" proto: socks, http\n"
" redir (Linux only)\n"
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\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;