mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-06-20 16:10:52 +00:00
:Merge branch 'master' into windows
This commit is contained in:
commit
eede0e9748
7 changed files with 58 additions and 41 deletions
|
@ -19,6 +19,7 @@ ENV PROXY=
|
||||||
ENV DNS=virtual
|
ENV DNS=virtual
|
||||||
ENV MODE=auto
|
ENV MODE=auto
|
||||||
ENV BYPASS_IP=
|
ENV BYPASS_IP=
|
||||||
|
ENV VERBOSITY=info
|
||||||
|
|
||||||
RUN apt update && apt install -y iproute2 curl && apt clean all
|
RUN apt update && apt install -y iproute2 curl && apt clean all
|
||||||
|
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) B. Blechschmidt and contributors
|
Copyright (c) @ssrlive, B. Blechschmidt and contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
17
README.md
17
README.md
|
@ -119,16 +119,27 @@ Next, start a container from the tun2proxy image:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-e PROXY=PROXY_TYPE://PROXY_IP:PROXY_PORT \
|
-e PROXY=proto://[username[:password]@]host:port \
|
||||||
-v /dev/net/tun:/dev/net/tun \
|
-v /dev/net/tun:/dev/net/tun \
|
||||||
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
|
|
||||||
--sysctl net.ipv6.conf.default.disable_ipv6=0 \
|
--sysctl net.ipv6.conf.default.disable_ipv6=0 \
|
||||||
--cap-add NET_ADMIN \
|
--cap-add NET_ADMIN \
|
||||||
--name tun2proxy \
|
--name tun2proxy \
|
||||||
tun2proxy
|
tun2proxy
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then provide the running container's network to another worker container by sharing the network namespace:
|
container env list
|
||||||
|
|
||||||
|
| container env | Default | program option | mean |
|
||||||
|
| ------------- | ------- | ----------------------- | ------------------------------------------------------------ |
|
||||||
|
| TUN | tun0 | -t, --tun <name> | Name of the tun interface [default: tun0] |
|
||||||
|
| PROXY | None | -p, --proxy <URL> | Proxy URL in the form proto://[username[:password]@]host:port |
|
||||||
|
| DNS | virtual | -d, --dns <strategy> | DNS handling strategy [default: virtual] [possible values: virtual, over-tcp, direct] |
|
||||||
|
| MODE | auto | -s, --setup <method> | Routing and system setup [possible values: auto] |
|
||||||
|
| BYPASS_IP | None | -b, --bypass <IP> | Public proxy IP used in routing setup which should bypassing the tunnel |
|
||||||
|
| VERBOSITY | info | -v, --verbosity <level> | Verbosity level [default: info] [possible values: off, error, warn, info, debug, trace] |
|
||||||
|
| | | | |
|
||||||
|
|
||||||
|
You can then provide the running container's network to another worker container by sharing the network namespace (like kubernetes sidecar):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -it \
|
docker run -it \
|
||||||
|
|
|
@ -2,28 +2,34 @@
|
||||||
|
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
if [ -n "$BYPASS_IP" ]; then
|
if [ -n "$TUN" ]; then
|
||||||
BYPASS_IP="--bypass $BYPASS_IP"
|
TUN="--tun $TUN"
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$DNS" ]; then
|
|
||||||
DNS="--dns $DNS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$MODE" ]; then
|
|
||||||
MODE="--setup $MODE"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$PROXY" ]; then
|
if [ -n "$PROXY" ]; then
|
||||||
PROXY="--proxy $PROXY"
|
PROXY="--proxy $PROXY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$TUN" ]; then
|
if [ -n "$DNS" ]; then
|
||||||
TUN="--tun $TUN"
|
DNS="--dns $DNS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec tun2proxy $TUN $PROXY $DNS $MODE $BYPASS_IP
|
if [ -n "$BYPASS_IP" ]; then
|
||||||
|
BYPASS_IP="--bypass $BYPASS_IP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$VERBOSITY" ]; then
|
||||||
|
VERBOSITY="-v $VERBOSITY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$MODE" ]; then
|
||||||
|
MODE="--setup $MODE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Bootstrap ready!! Exec Command: tun2proxy $TUN $PROXY $DNS $VERBOSITY $MODE $BYPASS_IP $@"
|
||||||
|
|
||||||
|
exec tun2proxy $TUN $PROXY $DNS $VERBOSITY $MODE $BYPASS_IP $@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
run || echo "Runing ERROR!!"
|
run $@ || echo "Runing ERROR!!"
|
||||||
|
|
10
src/http.rs
10
src/http.rs
|
@ -366,15 +366,15 @@ impl ProxyHandler for HttpConnection {
|
||||||
self.state == HttpState::Established
|
self.state == HttpState::Established
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_data(&mut self, dir: Direction) -> bool {
|
fn data_len(&self, dir: Direction) -> usize {
|
||||||
match dir {
|
match dir {
|
||||||
Direction::Incoming(incoming) => match incoming {
|
Direction::Incoming(incoming) => match incoming {
|
||||||
IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
|
IncomingDirection::FromServer => self.server_inbuf.len(),
|
||||||
IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
|
IncomingDirection::FromClient => self.client_inbuf.len().max(self.data_buf.len()),
|
||||||
},
|
},
|
||||||
Direction::Outgoing(outgoing) => match outgoing {
|
Direction::Outgoing(outgoing) => match outgoing {
|
||||||
OutgoingDirection::ToServer => !self.server_outbuf.is_empty(),
|
OutgoingDirection::ToServer => self.server_outbuf.len(),
|
||||||
OutgoingDirection::ToClient => !self.client_outbuf.is_empty(),
|
OutgoingDirection::ToClient => self.client_outbuf.len(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/socks.rs
10
src/socks.rs
|
@ -314,15 +314,15 @@ impl ProxyHandler for SocksProxyImpl {
|
||||||
self.state == SocksState::Established
|
self.state == SocksState::Established
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_data(&mut self, dir: Direction) -> bool {
|
fn data_len(&self, dir: Direction) -> usize {
|
||||||
match dir {
|
match dir {
|
||||||
Direction::Incoming(incoming) => match incoming {
|
Direction::Incoming(incoming) => match incoming {
|
||||||
IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
|
IncomingDirection::FromServer => self.server_inbuf.len(),
|
||||||
IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
|
IncomingDirection::FromClient => self.client_inbuf.len().max(self.data_buf.len()),
|
||||||
},
|
},
|
||||||
Direction::Outgoing(outgoing) => match outgoing {
|
Direction::Outgoing(outgoing) => match outgoing {
|
||||||
OutgoingDirection::ToServer => !self.server_outbuf.is_empty(),
|
OutgoingDirection::ToServer => self.server_outbuf.len(),
|
||||||
OutgoingDirection::ToClient => !self.client_outbuf.is_empty(),
|
OutgoingDirection::ToClient => self.client_outbuf.len(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,7 @@ const CLIENT_WRITE_CLOSED: u8 = 2;
|
||||||
|
|
||||||
const UDP_ASSO_TIMEOUT: u64 = 10; // seconds
|
const UDP_ASSO_TIMEOUT: u64 = 10; // seconds
|
||||||
const DNS_PORT: u16 = 53;
|
const DNS_PORT: u16 = 53;
|
||||||
|
const IP_PACKAGE_MAX_SIZE: usize = 0xFFFF;
|
||||||
|
|
||||||
struct ConnectionState {
|
struct ConnectionState {
|
||||||
smoltcp_handle: SocketHandle,
|
smoltcp_handle: SocketHandle,
|
||||||
|
@ -196,7 +197,7 @@ pub(crate) trait ProxyHandler {
|
||||||
fn consume_data(&mut self, dir: OutgoingDirection, size: usize);
|
fn consume_data(&mut self, dir: OutgoingDirection, size: usize);
|
||||||
fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent;
|
fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent;
|
||||||
fn connection_established(&self) -> bool;
|
fn connection_established(&self) -> bool;
|
||||||
fn have_data(&mut self, dir: Direction) -> bool;
|
fn data_len(&self, dir: Direction) -> usize;
|
||||||
fn reset_connection(&self) -> bool;
|
fn reset_connection(&self) -> bool;
|
||||||
fn get_udp_associate(&self) -> Option<SocketAddr>;
|
fn get_udp_associate(&self) -> Option<SocketAddr>;
|
||||||
}
|
}
|
||||||
|
@ -406,13 +407,10 @@ impl<'a> TunToProxy<'a> {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
let mut closed_ends = 0;
|
let mut closed_ends = 0;
|
||||||
|
let handler = state.proxy_handler.as_ref();
|
||||||
if (state.close_state & SERVER_WRITE_CLOSED) == SERVER_WRITE_CLOSED
|
if (state.close_state & SERVER_WRITE_CLOSED) == SERVER_WRITE_CLOSED
|
||||||
&& !state
|
&& handler.data_len(Direction::Incoming(IncomingDirection::FromServer)) == 0
|
||||||
.proxy_handler
|
&& handler.data_len(Direction::Outgoing(OutgoingDirection::ToClient)) == 0
|
||||||
.have_data(Direction::Incoming(IncomingDirection::FromServer))
|
|
||||||
&& !state
|
|
||||||
.proxy_handler
|
|
||||||
.have_data(Direction::Outgoing(OutgoingDirection::ToClient))
|
|
||||||
{
|
{
|
||||||
// Close tun interface
|
// Close tun interface
|
||||||
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||||
|
@ -422,12 +420,8 @@ impl<'a> TunToProxy<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.close_state & CLIENT_WRITE_CLOSED) == CLIENT_WRITE_CLOSED
|
if (state.close_state & CLIENT_WRITE_CLOSED) == CLIENT_WRITE_CLOSED
|
||||||
&& !state
|
&& handler.data_len(Direction::Incoming(IncomingDirection::FromClient)) == 0
|
||||||
.proxy_handler
|
&& handler.data_len(Direction::Outgoing(OutgoingDirection::ToServer)) == 0
|
||||||
.have_data(Direction::Incoming(IncomingDirection::FromClient))
|
|
||||||
&& !state
|
|
||||||
.proxy_handler
|
|
||||||
.have_data(Direction::Outgoing(OutgoingDirection::ToServer))
|
|
||||||
{
|
{
|
||||||
// Close remote server
|
// Close remote server
|
||||||
if let Err(err) = state.mio_stream.shutdown(Shutdown::Write) {
|
if let Err(err) = state.mio_stream.shutdown(Shutdown::Write) {
|
||||||
|
@ -454,6 +448,11 @@ impl<'a> TunToProxy<'a> {
|
||||||
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||||
let mut error = Ok(());
|
let mut error = Ok(());
|
||||||
while socket.can_recv() && error.is_ok() {
|
while socket.can_recv() && error.is_ok() {
|
||||||
|
let dir = Direction::Outgoing(OutgoingDirection::ToServer);
|
||||||
|
if state.proxy_handler.data_len(dir) >= IP_PACKAGE_MAX_SIZE {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
socket.recv(|data| {
|
socket.recv(|data| {
|
||||||
let event = IncomingDataEvent {
|
let event = IncomingDataEvent {
|
||||||
direction: IncomingDirection::FromClient,
|
direction: IncomingDirection::FromClient,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue