From b50cac82c07149b32bae8a128f2bad618dbab2d5 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:22:33 +0800 Subject: [PATCH 1/3] Memory exhaustion (#69) --- src/http.rs | 10 +++++----- src/socks.rs | 10 +++++----- src/tun2proxy.rs | 25 ++++++++++++------------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/http.rs b/src/http.rs index 4d3e5bb..7ebd02e 100644 --- a/src/http.rs +++ b/src/http.rs @@ -366,15 +366,15 @@ impl ProxyHandler for HttpConnection { self.state == HttpState::Established } - fn have_data(&mut self, dir: Direction) -> bool { + fn data_len(&self, dir: Direction) -> usize { match dir { Direction::Incoming(incoming) => match incoming { - IncomingDirection::FromServer => !self.server_inbuf.is_empty(), - IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(), + IncomingDirection::FromServer => self.server_inbuf.len(), + IncomingDirection::FromClient => self.client_inbuf.len().max(self.data_buf.len()), }, Direction::Outgoing(outgoing) => match outgoing { - OutgoingDirection::ToServer => !self.server_outbuf.is_empty(), - OutgoingDirection::ToClient => !self.client_outbuf.is_empty(), + OutgoingDirection::ToServer => self.server_outbuf.len(), + OutgoingDirection::ToClient => self.client_outbuf.len(), }, } } diff --git a/src/socks.rs b/src/socks.rs index 7c62aa9..c7b60aa 100644 --- a/src/socks.rs +++ b/src/socks.rs @@ -314,15 +314,15 @@ impl ProxyHandler for SocksProxyImpl { self.state == SocksState::Established } - fn have_data(&mut self, dir: Direction) -> bool { + fn data_len(&self, dir: Direction) -> usize { match dir { Direction::Incoming(incoming) => match incoming { - IncomingDirection::FromServer => !self.server_inbuf.is_empty(), - IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(), + IncomingDirection::FromServer => self.server_inbuf.len(), + IncomingDirection::FromClient => self.client_inbuf.len().max(self.data_buf.len()), }, Direction::Outgoing(outgoing) => match outgoing { - OutgoingDirection::ToServer => !self.server_outbuf.is_empty(), - OutgoingDirection::ToClient => !self.client_outbuf.is_empty(), + OutgoingDirection::ToServer => self.server_outbuf.len(), + OutgoingDirection::ToClient => self.client_outbuf.len(), }, } } diff --git a/src/tun2proxy.rs b/src/tun2proxy.rs index 6ae46ba..652631b 100644 --- a/src/tun2proxy.rs +++ b/src/tun2proxy.rs @@ -174,6 +174,7 @@ const CLIENT_WRITE_CLOSED: u8 = 2; const UDP_ASSO_TIMEOUT: u64 = 10; // seconds const DNS_PORT: u16 = 53; +const IP_PACKAGE_MAX_SIZE: usize = 0xFFFF; struct ConnectionState { smoltcp_handle: SocketHandle, @@ -197,7 +198,7 @@ pub(crate) trait ProxyHandler { fn consume_data(&mut self, dir: OutgoingDirection, size: usize); fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent; 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 get_udp_associate(&self) -> Option; } @@ -395,13 +396,10 @@ impl<'a> TunToProxy<'a> { None => return Ok(()), }; let mut closed_ends = 0; + let handler = state.proxy_handler.as_ref(); if (state.close_state & SERVER_WRITE_CLOSED) == SERVER_WRITE_CLOSED - && !state - .proxy_handler - .have_data(Direction::Incoming(IncomingDirection::FromServer)) - && !state - .proxy_handler - .have_data(Direction::Outgoing(OutgoingDirection::ToClient)) + && handler.data_len(Direction::Incoming(IncomingDirection::FromServer)) == 0 + && handler.data_len(Direction::Outgoing(OutgoingDirection::ToClient)) == 0 { // Close tun interface let socket = self.sockets.get_mut::(state.smoltcp_handle); @@ -411,12 +409,8 @@ impl<'a> TunToProxy<'a> { } if (state.close_state & CLIENT_WRITE_CLOSED) == CLIENT_WRITE_CLOSED - && !state - .proxy_handler - .have_data(Direction::Incoming(IncomingDirection::FromClient)) - && !state - .proxy_handler - .have_data(Direction::Outgoing(OutgoingDirection::ToServer)) + && handler.data_len(Direction::Incoming(IncomingDirection::FromClient)) == 0 + && handler.data_len(Direction::Outgoing(OutgoingDirection::ToServer)) == 0 { // Close remote server if let Err(err) = state.mio_stream.shutdown(Shutdown::Write) { @@ -443,6 +437,11 @@ impl<'a> TunToProxy<'a> { let socket = self.sockets.get_mut::(state.smoltcp_handle); let mut error = 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| { let event = IncomingDataEvent { direction: IncomingDirection::FromClient, From 5d722fc2a3fe92e47f69dc427406b48675eb9171 Mon Sep 17 00:00:00 2001 From: PaperDragon-SH <2678885646@qq.com> Date: Tue, 10 Oct 2023 16:04:13 +0800 Subject: [PATCH 2/3] optimize docker --- Dockerfile | 1 + README.md | 17 ++++++++++++++--- docker/entrypoint.sh | 34 ++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index 59479b6..912fdca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ ENV PROXY= ENV DNS=virtual ENV MODE=auto ENV BYPASS_IP= +ENV VERBOSITY=info RUN apt update && apt install -y iproute2 curl && apt clean all diff --git a/README.md b/README.md index db598a7..b83837a 100644 --- a/README.md +++ b/README.md @@ -119,16 +119,27 @@ Next, start a container from the tun2proxy image: ```bash 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 \ - --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --sysctl net.ipv6.conf.default.disable_ipv6=0 \ --cap-add NET_ADMIN \ --name 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 of the tun interface [default: tun0] | +| PROXY | None | -p, --proxy | Proxy URL in the form proto://[username[:password]@]host:port | +| DNS | virtual | -d, --dns | DNS handling strategy [default: virtual] [possible values: virtual, over-tcp, direct] | +| MODE | auto | -s, --setup | Routing and system setup [possible values: auto] | +| BYPASS_IP | None | -b, --bypass | Public proxy IP used in routing setup which should bypassing the tunnel | +| VERBOSITY | info | -v, --verbosity | 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 docker run -it \ diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index f0e9e5c..661380c 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -2,28 +2,34 @@ run() { - if [ -n "$BYPASS_IP" ]; then - BYPASS_IP="--bypass $BYPASS_IP" - fi - - if [ -n "$DNS" ]; then - DNS="--dns $DNS" - fi - - if [ -n "$MODE" ]; then - MODE="--setup $MODE" + if [ -n "$TUN" ]; then + TUN="--tun $TUN" fi if [ -n "$PROXY" ]; then PROXY="--proxy $PROXY" fi - if [ -n "$TUN" ]; then - TUN="--tun $TUN" + if [ -n "$DNS" ]; then + DNS="--dns $DNS" 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!!" From a9a562029f79cd72d183658b336f85c4754f759f Mon Sep 17 00:00:00 2001 From: "B. Blechschmidt" Date: Tue, 10 Oct 2023 21:04:11 +0200 Subject: [PATCH 3/3] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9b5214e..80b3987 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ 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 of this software and associated documentation files (the "Software"), to deal