tun2proxy/src/lib.rs

844 lines
31 KiB
Rust
Raw Normal View History

2023-08-06 13:48:56 +08:00
use crate::{
2024-02-01 19:15:32 +08:00
directions::{IncomingDataEvent, IncomingDirection, OutgoingDirection},
2023-08-06 13:48:56 +08:00
http::HttpManager,
2024-04-03 14:20:05 +00:00
no_proxy::NoProxyManager,
2024-02-01 19:15:32 +08:00
session_info::{IpProtocol, SessionInfo},
2024-10-17 13:59:46 +08:00
udpgw::UdpGwClient,
2024-02-01 19:15:32 +08:00
virtual_dns::VirtualDns,
2023-08-06 13:48:56 +08:00
};
2024-02-01 19:15:32 +08:00
use ipstack::stream::{IpStackStream, IpStackTcpStream, IpStackUdpStream};
use proxy_handler::{ProxyHandler, ProxyHandlerManager};
use socks::SocksProxyManager;
2024-02-10 20:21:28 +08:00
pub use socks5_impl::protocol::UserKey;
use std::{
collections::VecDeque,
io::ErrorKind,
2024-10-17 13:59:46 +08:00
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
sync::Arc,
};
2024-02-01 19:15:32 +08:00
use tokio::{
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
net::{TcpSocket, TcpStream, UdpSocket},
sync::{mpsc::Receiver, Mutex},
2024-02-01 19:15:32 +08:00
};
2024-02-12 21:36:18 +08:00
pub use tokio_util::sync::CancellationToken;
2024-02-01 19:15:32 +08:00
use tproxy_config::is_private_ip;
use udp_stream::UdpStream;
2024-10-19 13:40:35 +08:00
use udpgw::{UdpGwClientStream, UdpGwResponse, UDPGW_KEEPALIVE_TIME};
2024-02-01 19:15:32 +08:00
pub use {
args::{ArgDns, ArgProxy, ArgVerbosity, Args, ProxyType},
2024-02-12 21:36:18 +08:00
error::{BoxError, Error, Result},
traffic_status::{tun2proxy_set_traffic_status_callback, TrafficStatus},
2023-07-23 02:03:15 +08:00
};
2023-03-21 00:11:51 +08:00
2024-08-02 10:18:11 +08:00
#[cfg(feature = "mimalloc")]
#[global_allocator]
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
2024-02-13 10:46:13 +08:00
#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
pub use desktop_api::desktop_run_async;
#[cfg(any(target_os = "ios", target_os = "android"))]
pub use mobile_api::{desktop_run_async, mobile_run, mobile_stop};
2024-02-29 07:08:44 +03:30
#[cfg(target_os = "macos")]
pub use mobile_api::{mobile_run, mobile_stop};
2023-04-14 18:44:41 +08:00
mod android;
2024-02-29 07:08:44 +03:30
mod apple;
2024-02-01 19:15:32 +08:00
mod args;
2024-02-13 10:46:13 +08:00
mod desktop_api;
2024-02-01 19:15:32 +08:00
mod directions;
2023-08-06 11:42:19 +08:00
mod dns;
2024-02-01 19:15:32 +08:00
mod dump_logger;
mod error;
mod http;
2024-02-13 10:46:13 +08:00
mod mobile_api;
2024-04-03 14:20:05 +00:00
mod no_proxy;
2024-02-01 19:15:32 +08:00
mod proxy_handler;
mod session_info;
pub mod socket_transfer;
2023-04-15 12:10:30 +02:00
mod socks;
mod traffic_status;
2024-10-17 13:59:46 +08:00
pub mod udpgw;
2024-02-01 19:15:32 +08:00
mod virtual_dns;
2024-09-14 09:55:27 +08:00
#[doc(hidden)]
pub mod win_svc;
2024-02-01 19:15:32 +08:00
const DNS_PORT: u16 = 53;
2023-04-10 23:24:53 +02:00
2024-02-01 19:15:32 +08:00
static TASK_COUNT: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
use std::sync::atomic::Ordering::Relaxed;
#[allow(unused)]
#[derive(Hash, Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(target_os = "linux", derive(serde::Serialize, serde::Deserialize))]
pub enum SocketProtocol {
Tcp,
Udp,
}
#[allow(unused)]
#[derive(Hash, Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(target_os = "linux", derive(serde::Serialize, serde::Deserialize))]
pub enum SocketDomain {
IpV4,
IpV6,
}
impl From<IpAddr> for SocketDomain {
fn from(value: IpAddr) -> Self {
match value {
IpAddr::V4(_) => Self::IpV4,
IpAddr::V6(_) => Self::IpV6,
}
}
}
struct SocketQueue {
tcp_v4: Mutex<Receiver<TcpSocket>>,
tcp_v6: Mutex<Receiver<TcpSocket>>,
udp_v4: Mutex<Receiver<UdpSocket>>,
udp_v6: Mutex<Receiver<UdpSocket>>,
}
impl SocketQueue {
async fn recv_tcp(&self, domain: SocketDomain) -> Result<TcpSocket, std::io::Error> {
match domain {
SocketDomain::IpV4 => &self.tcp_v4,
SocketDomain::IpV6 => &self.tcp_v6,
}
.lock()
.await
.recv()
.await
.ok_or(ErrorKind::Other.into())
}
async fn recv_udp(&self, domain: SocketDomain) -> Result<UdpSocket, std::io::Error> {
match domain {
SocketDomain::IpV4 => &self.udp_v4,
SocketDomain::IpV6 => &self.udp_v6,
}
.lock()
.await
.recv()
.await
.ok_or(ErrorKind::Other.into())
}
}
async fn create_tcp_stream(socket_queue: &Option<Arc<SocketQueue>>, peer: SocketAddr) -> std::io::Result<TcpStream> {
match &socket_queue {
None => TcpStream::connect(peer).await,
Some(queue) => queue.recv_tcp(peer.ip().into()).await?.connect(peer).await,
}
}
async fn create_udp_stream(socket_queue: &Option<Arc<SocketQueue>>, peer: SocketAddr) -> std::io::Result<UdpStream> {
match &socket_queue {
None => UdpStream::connect(peer).await,
Some(queue) => {
let socket = queue.recv_udp(peer.ip().into()).await?;
socket.connect(peer).await?;
2024-06-28 01:35:49 +08:00
UdpStream::from_tokio(socket, peer).await
}
}
}
2024-02-12 21:36:18 +08:00
/// Run the proxy server
/// # Arguments
/// * `device` - The network device to use
/// * `mtu` - The MTU of the network device
/// * `args` - The arguments to use
/// * `shutdown_token` - The token to exit the server
pub async fn run<D>(device: D, mtu: u16, args: Args, shutdown_token: CancellationToken) -> crate::Result<()>
2024-02-01 19:15:32 +08:00
where
D: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
2024-04-14 19:18:18 +08:00
log::info!("{} {} starting...", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
2024-02-25 16:59:18 +08:00
log::info!("Proxy {} server: {}", args.proxy.proxy_type, args.proxy.addr);
2024-02-01 19:15:32 +08:00
let server_addr = args.proxy.addr;
let key = args.proxy.credentials.clone();
let dns_addr = args.dns_addr;
let ipv6_enabled = args.ipv6_enabled;
let virtual_dns = if args.dns == ArgDns::Virtual {
2024-08-28 23:06:37 +02:00
Some(Arc::new(Mutex::new(VirtualDns::new(args.virtual_dns_pool))))
2024-02-01 19:15:32 +08:00
} else {
None
};
#[cfg(target_os = "linux")]
let socket_queue = match args.socket_transfer_fd {
None => None,
Some(fd) => {
use crate::socket_transfer::{reconstruct_socket, reconstruct_transfer_socket, request_sockets};
use tokio::sync::mpsc::channel;
let fd = reconstruct_socket(fd)?;
let socket = reconstruct_transfer_socket(fd)?;
let socket = Arc::new(Mutex::new(socket));
macro_rules! create_socket_queue {
($domain:ident) => {{
const SOCKETS_PER_REQUEST: usize = 64;
let socket = socket.clone();
let (tx, rx) = channel(SOCKETS_PER_REQUEST);
tokio::spawn(async move {
loop {
let sockets =
match request_sockets(socket.lock().await, SocketDomain::$domain, SOCKETS_PER_REQUEST as u32).await {
Ok(sockets) => sockets,
Err(err) => {
log::warn!("Socket allocation request failed: {err}");
continue;
}
};
for s in sockets {
if let Err(_) = tx.send(s).await {
return;
}
}
}
});
Mutex::new(rx)
}};
}
Some(Arc::new(SocketQueue {
tcp_v4: create_socket_queue!(IpV4),
tcp_v6: create_socket_queue!(IpV6),
udp_v4: create_socket_queue!(IpV4),
udp_v6: create_socket_queue!(IpV6),
}))
}
};
#[cfg(not(target_os = "linux"))]
let socket_queue = None;
2024-02-01 19:15:32 +08:00
use socks5_impl::protocol::Version::{V4, V5};
let mgr = match args.proxy.proxy_type {
ProxyType::Socks5 => Arc::new(SocksProxyManager::new(server_addr, V5, key)) as Arc<dyn ProxyHandlerManager>,
ProxyType::Socks4 => Arc::new(SocksProxyManager::new(server_addr, V4, key)) as Arc<dyn ProxyHandlerManager>,
ProxyType::Http => Arc::new(HttpManager::new(server_addr, key)) as Arc<dyn ProxyHandlerManager>,
2024-04-06 16:22:26 +08:00
ProxyType::None => Arc::new(NoProxyManager::new()) as Arc<dyn ProxyHandlerManager>,
2024-02-01 19:15:32 +08:00
};
let mut ipstack_config = ipstack::IpStackConfig::default();
ipstack_config.mtu(mtu);
2024-03-18 13:12:30 +08:00
ipstack_config.tcp_timeout(std::time::Duration::from_secs(args.tcp_timeout));
2024-04-03 14:13:18 +00:00
ipstack_config.udp_timeout(std::time::Duration::from_secs(args.udp_timeout));
2024-02-01 19:15:32 +08:00
let mut ip_stack = ipstack::IpStack::new(ipstack_config, device);
2024-10-17 13:59:46 +08:00
let udpgw_client = match args.udpgw_bind_addr {
None => None,
Some(addr) => {
log::info!("UDPGW enabled");
2024-10-19 13:40:35 +08:00
let client = Arc::new(UdpGwClient::new(mtu, args.max_udpgw_connections, UDPGW_KEEPALIVE_TIME, args.udp_timeout, addr));
2024-10-17 13:59:46 +08:00
let client_keepalive = client.clone();
tokio::spawn(async move {
client_keepalive.heartbeat_task().await;
});
Some(client)
}
};
2024-02-01 19:15:32 +08:00
loop {
let virtual_dns = virtual_dns.clone();
let ip_stack_stream = tokio::select! {
_ = shutdown_token.cancelled() => {
log::info!("Shutdown received");
2024-02-01 19:15:32 +08:00
break;
}
ip_stack_stream = ip_stack.accept() => {
ip_stack_stream?
}
};
2024-10-09 16:57:14 +08:00
let max_sessions = args.max_sessions as u64;
2024-02-01 19:15:32 +08:00
match ip_stack_stream {
IpStackStream::Tcp(tcp) => {
2024-10-09 16:57:14 +08:00
if TASK_COUNT.load(Relaxed) > max_sessions {
2024-10-07 13:23:11 +08:00
if args.exit_on_fatal_error {
2024-10-09 16:57:14 +08:00
log::info!("Too many sessions that over {max_sessions}, exiting...");
2024-10-07 13:23:11 +08:00
break;
}
2024-10-09 16:57:14 +08:00
log::warn!("Too many sessions that over {max_sessions}, dropping new session");
2024-02-01 19:15:32 +08:00
continue;
}
log::trace!("Session count {}", TASK_COUNT.fetch_add(1, Relaxed) + 1);
let info = SessionInfo::new(tcp.local_addr(), tcp.peer_addr(), IpProtocol::Tcp);
let domain_name = if let Some(virtual_dns) = &virtual_dns {
let mut virtual_dns = virtual_dns.lock().await;
virtual_dns.touch_ip(&tcp.peer_addr().ip());
virtual_dns.resolve_ip(&tcp.peer_addr().ip()).cloned()
} else {
None
};
let proxy_handler = mgr.new_proxy_handler(info, domain_name, false).await?;
let socket_queue = socket_queue.clone();
2024-02-01 19:15:32 +08:00
tokio::spawn(async move {
if let Err(err) = handle_tcp_session(tcp, proxy_handler, socket_queue).await {
2024-02-01 19:15:32 +08:00
log::error!("{} error \"{}\"", info, err);
}
2024-10-17 13:59:46 +08:00
2024-02-01 19:15:32 +08:00
log::trace!("Session count {}", TASK_COUNT.fetch_sub(1, Relaxed) - 1);
});
}
IpStackStream::Udp(udp) => {
2024-10-09 16:57:14 +08:00
if TASK_COUNT.load(Relaxed) > max_sessions {
2024-10-07 13:23:11 +08:00
if args.exit_on_fatal_error {
2024-10-09 16:57:14 +08:00
log::info!("Too many sessions that over {max_sessions}, exiting...");
2024-10-07 13:23:11 +08:00
break;
}
2024-10-09 16:57:14 +08:00
log::warn!("Too many sessions that over {max_sessions}, dropping new session");
2024-02-01 19:15:32 +08:00
continue;
}
log::trace!("Session count {}", TASK_COUNT.fetch_add(1, Relaxed) + 1);
let mut info = SessionInfo::new(udp.local_addr(), udp.peer_addr(), IpProtocol::Udp);
if info.dst.port() == DNS_PORT {
if is_private_ip(info.dst.ip()) {
info.dst.set_ip(dns_addr);
}
if args.dns == ArgDns::OverTcp {
2024-04-18 21:45:09 +02:00
info.protocol = IpProtocol::Tcp;
2024-02-01 19:15:32 +08:00
let proxy_handler = mgr.new_proxy_handler(info, None, false).await?;
let socket_queue = socket_queue.clone();
2024-02-01 19:15:32 +08:00
tokio::spawn(async move {
if let Err(err) = handle_dns_over_tcp_session(udp, proxy_handler, socket_queue, ipv6_enabled).await {
2024-02-01 19:15:32 +08:00
log::error!("{} error \"{}\"", info, err);
}
log::trace!("Session count {}", TASK_COUNT.fetch_sub(1, Relaxed) - 1);
});
continue;
}
if args.dns == ArgDns::Virtual {
2024-02-01 19:15:32 +08:00
tokio::spawn(async move {
if let Some(virtual_dns) = virtual_dns {
if let Err(err) = handle_virtual_dns_session(udp, virtual_dns).await {
log::error!("{} error \"{}\"", info, err);
}
}
log::trace!("Session count {}", TASK_COUNT.fetch_sub(1, Relaxed) - 1);
});
continue;
}
assert_eq!(args.dns, ArgDns::Direct);
2024-02-01 19:15:32 +08:00
}
let domain_name = if let Some(virtual_dns) = &virtual_dns {
let mut virtual_dns = virtual_dns.lock().await;
virtual_dns.touch_ip(&udp.peer_addr().ip());
virtual_dns.resolve_ip(&udp.peer_addr().ip()).cloned()
} else {
None
};
2024-10-17 13:59:46 +08:00
if let Some(udpgw) = udpgw_client.clone() {
let tcp_src = match udp.peer_addr() {
SocketAddr::V4(_) => SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)),
SocketAddr::V6(_) => SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0)),
};
let tcpinfo = SessionInfo::new(tcp_src, udpgw.get_udpgw_bind_addr(), IpProtocol::Tcp);
let proxy_handler = mgr.new_proxy_handler(tcpinfo, None, false).await?;
let socket_queue = socket_queue.clone();
tokio::spawn(async move {
if let Err(err) =
handle_udp_gateway_session(udp, udpgw, domain_name, proxy_handler, socket_queue, ipv6_enabled).await
{
log::info!("Ending {} with \"{}\"", info, err);
}
log::trace!("Session count {}", TASK_COUNT.fetch_sub(1, Relaxed) - 1);
});
continue;
}
match mgr.new_proxy_handler(info, domain_name, true).await {
Ok(proxy_handler) => {
let socket_queue = socket_queue.clone();
tokio::spawn(async move {
2024-04-07 10:28:11 +00:00
let ty = args.proxy.proxy_type;
if let Err(err) = handle_udp_associate_session(udp, ty, proxy_handler, socket_queue, ipv6_enabled).await {
2024-03-11 08:57:18 +08:00
log::info!("Ending {} with \"{}\"", info, err);
}
log::trace!("Session count {}", TASK_COUNT.fetch_sub(1, Relaxed) - 1);
});
2024-02-01 19:15:32 +08:00
}
Err(e) => {
log::error!("Failed to create UDP connection: {}", e);
}
}
2024-02-01 19:15:32 +08:00
}
2024-04-23 19:54:19 +08:00
IpStackStream::UnknownTransport(u) => {
let len = u.payload().len();
2024-09-29 18:17:45 +08:00
log::info!("#0 unhandled transport - Ip Protocol 0x{:02X}, length {}", u.ip_protocol(), len);
2024-04-23 19:54:19 +08:00
continue;
}
IpStackStream::UnknownNetwork(pkt) => {
log::info!("#0 unknown transport - {} bytes", pkt.len());
2024-02-01 19:15:32 +08:00
continue;
}
}
2023-04-10 23:24:53 +02:00
}
2024-02-01 19:15:32 +08:00
Ok(())
}
2023-09-26 18:25:59 +08:00
2024-02-01 19:15:32 +08:00
async fn handle_virtual_dns_session(mut udp: IpStackUdpStream, dns: Arc<Mutex<VirtualDns>>) -> crate::Result<()> {
let mut buf = [0_u8; 4096];
loop {
2024-04-10 11:26:34 +08:00
let len = match udp.read(&mut buf).await {
Err(e) => {
// indicate UDP read fails not an error.
log::debug!("Virtual DNS session error: {}", e);
break;
}
Ok(len) => len,
};
2024-02-01 19:15:32 +08:00
if len == 0 {
break;
}
2024-02-01 19:15:32 +08:00
let (msg, qname, ip) = dns.lock().await.generate_query(&buf[..len])?;
udp.write_all(&msg).await?;
log::debug!("Virtual DNS query: {} -> {}", qname, ip);
2023-09-26 18:25:59 +08:00
}
2024-02-01 19:15:32 +08:00
Ok(())
}
async fn copy_and_record_traffic<R, W>(reader: &mut R, writer: &mut W, is_tx: bool) -> tokio::io::Result<u64>
where
R: tokio::io::AsyncRead + Unpin + ?Sized,
W: tokio::io::AsyncWrite + Unpin + ?Sized,
{
let mut buf = vec![0; 8192];
let mut total = 0;
loop {
match reader.read(&mut buf).await? {
0 => break, // EOF
n => {
total += n as u64;
let (tx, rx) = if is_tx { (n, 0) } else { (0, n) };
if let Err(e) = crate::traffic_status::traffic_status_update(tx, rx) {
log::debug!("Record traffic status error: {}", e);
}
writer.write_all(&buf[..n]).await?;
}
}
}
Ok(total)
}
2024-02-01 19:15:32 +08:00
async fn handle_tcp_session(
2024-02-26 00:50:23 +01:00
mut tcp_stack: IpStackTcpStream,
2024-02-01 19:15:32 +08:00
proxy_handler: Arc<Mutex<dyn ProxyHandler>>,
socket_queue: Option<Arc<SocketQueue>>,
2024-02-01 19:15:32 +08:00
) -> crate::Result<()> {
let (session_info, server_addr) = {
let handler = proxy_handler.lock().await;
(handler.get_session_info(), handler.get_server_addr())
};
let mut server = create_tcp_stream(&socket_queue, server_addr).await?;
2024-02-01 19:15:32 +08:00
log::info!("Beginning {}", session_info);
2024-02-26 00:50:23 +01:00
if let Err(e) = handle_proxy_session(&mut server, proxy_handler).await {
tcp_stack.shutdown().await?;
return Err(e);
}
2024-02-01 19:15:32 +08:00
let (mut t_rx, mut t_tx) = tokio::io::split(tcp_stack);
let (mut s_rx, mut s_tx) = tokio::io::split(server);
2024-03-03 19:49:10 +08:00
let res = tokio::join!(
async move {
let r = copy_and_record_traffic(&mut t_rx, &mut s_tx, true).await;
2024-03-03 19:49:10 +08:00
if let Err(err) = s_tx.shutdown().await {
log::trace!("{} s_tx shutdown error {}", session_info, err);
}
r
},
async move {
let r = copy_and_record_traffic(&mut s_rx, &mut t_tx, false).await;
2024-03-03 19:49:10 +08:00
if let Err(err) = t_tx.shutdown().await {
log::trace!("{} t_tx shutdown error {}", session_info, err);
}
r
},
);
log::info!("Ending {} with {:?}", session_info, res);
2024-02-01 19:15:32 +08:00
Ok(())
2023-03-21 00:11:51 +08:00
}
2023-04-14 17:27:37 +08:00
2024-10-17 13:59:46 +08:00
async fn handle_udp_gateway_session(
mut udp_stack: IpStackUdpStream,
udpgw_client: Arc<UdpGwClient>,
domain_name: Option<String>,
proxy_handler: Arc<Mutex<dyn ProxyHandler>>,
socket_queue: Option<Arc<SocketQueue>>,
ipv6_enabled: bool,
) -> crate::Result<()> {
let (session_info, server_addr) = {
let handler = proxy_handler.lock().await;
(handler.get_session_info(), handler.get_server_addr())
};
let udpinfo = SessionInfo::new(udp_stack.local_addr(), udp_stack.peer_addr(), IpProtocol::Udp);
let udp_mtu = udpgw_client.get_udp_mtu();
2024-10-19 13:40:35 +08:00
let udp_timeout = udpgw_client.get_udp_timeout();
2024-10-17 13:59:46 +08:00
let mut server_stream: UdpGwClientStream;
let server = udpgw_client.get_server_connection().await;
match server {
Some(server) => {
server_stream = server;
}
None => {
2024-10-19 13:40:35 +08:00
if udpgw_client.is_full().await {
return Err("max udpgw connection limit reached".into());
}
2024-10-17 13:59:46 +08:00
let mut tcp_server_stream = create_tcp_stream(&socket_queue, server_addr).await?;
if let Err(e) = handle_proxy_session(&mut tcp_server_stream, proxy_handler).await {
2024-10-19 13:40:35 +08:00
return Err(format!("udpgw connection error: {}",e).into());
2024-10-17 13:59:46 +08:00
}
server_stream = UdpGwClientStream::new(udp_mtu, tcp_server_stream);
}
};
let udp_server_addr = udp_stack.peer_addr();
2024-10-19 13:40:35 +08:00
let tcp_local_addr = server_stream.local_addr().clone();
2024-10-17 13:59:46 +08:00
match domain_name {
Some(ref d) => {
2024-10-19 13:40:35 +08:00
log::info!("Beginning {} <- {}, domain:{}", udpinfo, &tcp_local_addr, d);
2024-10-17 13:59:46 +08:00
}
None => {
2024-10-19 13:40:35 +08:00
log::info!("Beginning {} <- {}", udpinfo, &tcp_local_addr);
2024-10-17 13:59:46 +08:00
}
}
2024-10-19 13:40:35 +08:00
let Some(mut stream_reader) = server_stream.get_reader() else {
return Err("get reader failed".into());
};
let Some(mut stream_writer) = server_stream.get_writer() else {
return Err("get writer failed".into());
};
2024-10-17 13:59:46 +08:00
loop {
2024-10-19 13:40:35 +08:00
tokio::select! {
len = UdpGwClient::recv_udp_packet(&mut udp_stack, &mut stream_writer) => {
let read_len;
match len {
Ok(n) => {
if n == 0 {
log::info!("Ending {} <- {}",udpinfo, &tcp_local_addr);
break;
}
read_len = n;
crate::traffic_status::traffic_status_update(n, 0)?;
}
Err(e) => {
log::info!("Ending {} <- {} with recv_udp_packet {}", udpinfo, &tcp_local_addr, e);
break;
}
2024-10-17 13:59:46 +08:00
}
2024-10-19 13:40:35 +08:00
let newid = server_stream.newid();
if let Err(e) =
UdpGwClient::send_udpgw_packet(ipv6_enabled, read_len, udp_server_addr, domain_name.as_ref(),newid,&mut stream_writer).await
{
log::info!(
"Ending {} <- {} with send_udpgw_packet {}",
udpinfo,
&tcp_local_addr,
e
);
2024-10-17 13:59:46 +08:00
break;
}
2024-10-19 13:40:35 +08:00
server_stream.update_activity();
}
ret = UdpGwClient::recv_udpgw_packet(udp_mtu, udp_timeout, &mut stream_reader) => {
match ret {
Ok(packet) => match packet {
//should not received keepalive
UdpGwResponse::KeepAlive => {
log::error!("Ending {} <- {} with recv keepalive", udpinfo, &tcp_local_addr);
server_stream.close();
break;
}
//server udp may be timeout,can continue to receive udp data?
UdpGwResponse::Error => {
log::info!("Ending {} <- {} with recv udp error", udpinfo, &tcp_local_addr);
server_stream.update_activity();
continue;
}
UdpGwResponse::Data(data) => {
let len = data.len();
if let Err(e) = UdpGwClient::send_udp_packet(data, &mut udp_stack).await {
log::error!("Ending {} <- {} with send_udp_packet {}", udpinfo, &tcp_local_addr, e);
break;
}
crate::traffic_status::traffic_status_update(0, len)?;
}
},
Err(e) => {
log::warn!("Ending {} <- {} with recv_udpgw_packet {}", udpinfo, &tcp_local_addr, e);
2024-10-17 13:59:46 +08:00
break;
}
}
2024-10-19 13:40:35 +08:00
server_stream.update_activity();
2024-10-17 13:59:46 +08:00
}
}
}
2024-10-19 13:40:35 +08:00
if !server_stream.is_closed() {
udpgw_client.release_server_connection_with_stream(server_stream,stream_reader,stream_writer).await;
2024-10-17 13:59:46 +08:00
}
Ok(())
}
2024-02-01 19:15:32 +08:00
async fn handle_udp_associate_session(
mut udp_stack: IpStackUdpStream,
proxy_type: ProxyType,
2024-02-01 19:15:32 +08:00
proxy_handler: Arc<Mutex<dyn ProxyHandler>>,
socket_queue: Option<Arc<SocketQueue>>,
2024-02-01 19:15:32 +08:00
ipv6_enabled: bool,
) -> crate::Result<()> {
use socks5_impl::protocol::{Address, StreamOperation, UdpHeader};
let (session_info, server_addr, domain_name, udp_addr) = {
let handler = proxy_handler.lock().await;
(
handler.get_session_info(),
handler.get_server_addr(),
handler.get_domain_name(),
handler.get_udp_associate(),
)
};
2024-02-01 19:15:32 +08:00
log::info!("Beginning {}", session_info);
2024-04-07 19:02:57 +08:00
// `_server` is meaningful here, it must be alive all the time
// to ensure that UDP transmission will not be interrupted accidentally.
2024-04-07 10:28:11 +00:00
let (_server, udp_addr) = match udp_addr {
Some(udp_addr) => (None, udp_addr),
None => {
let mut server = create_tcp_stream(&socket_queue, server_addr).await?;
let udp_addr = handle_proxy_session(&mut server, proxy_handler).await?;
2024-04-07 10:28:11 +00:00
(Some(server), udp_addr.ok_or("udp associate failed")?)
}
};
2024-02-01 19:15:32 +08:00
let mut udp_server = create_udp_stream(&socket_queue, udp_addr).await?;
2024-02-01 19:15:32 +08:00
let mut buf1 = [0_u8; 4096];
let mut buf2 = [0_u8; 4096];
loop {
tokio::select! {
len = udp_stack.read(&mut buf1) => {
let len = len?;
if len == 0 {
break;
}
let buf1 = &buf1[..len];
crate::traffic_status::traffic_status_update(len, 0)?;
if let ProxyType::Socks4 | ProxyType::Socks5 = proxy_type {
let s5addr = if let Some(domain_name) = &domain_name {
Address::DomainAddress(domain_name.clone(), session_info.dst.port())
} else {
session_info.dst.into()
};
2024-02-01 19:15:32 +08:00
// Add SOCKS5 UDP header to the incoming data
let mut s5_udp_data = Vec::<u8>::new();
UdpHeader::new(0, s5addr).write_to_stream(&mut s5_udp_data)?;
s5_udp_data.extend_from_slice(buf1);
2024-02-01 19:15:32 +08:00
udp_server.write_all(&s5_udp_data).await?;
} else {
udp_server.write_all(buf1).await?;
}
2024-02-01 19:15:32 +08:00
}
len = udp_server.read(&mut buf2) => {
let len = len?;
if len == 0 {
break;
}
let buf2 = &buf2[..len];
crate::traffic_status::traffic_status_update(0, len)?;
if let ProxyType::Socks4 | ProxyType::Socks5 = proxy_type {
// Remove SOCKS5 UDP header from the server data
let header = UdpHeader::retrieve_from_stream(&mut &buf2[..])?;
let data = &buf2[header.len()..];
let buf = if session_info.dst.port() == DNS_PORT {
let mut message = dns::parse_data_to_dns_message(data, false)?;
if !ipv6_enabled {
dns::remove_ipv6_entries(&mut message);
}
message.to_vec()?
} else {
data.to_vec()
};
udp_stack.write_all(&buf).await?;
2024-02-01 19:15:32 +08:00
} else {
udp_stack.write_all(buf2).await?;
}
2024-02-01 19:15:32 +08:00
}
}
}
log::info!("Ending {}", session_info);
Ok(())
}
async fn handle_dns_over_tcp_session(
mut udp_stack: IpStackUdpStream,
proxy_handler: Arc<Mutex<dyn ProxyHandler>>,
socket_queue: Option<Arc<SocketQueue>>,
2024-02-01 19:15:32 +08:00
ipv6_enabled: bool,
) -> crate::Result<()> {
let (session_info, server_addr) = {
let handler = proxy_handler.lock().await;
(handler.get_session_info(), handler.get_server_addr())
};
let mut server = create_tcp_stream(&socket_queue, server_addr).await?;
2024-02-01 19:15:32 +08:00
log::info!("Beginning {}", session_info);
let _ = handle_proxy_session(&mut server, proxy_handler).await?;
let mut buf1 = [0_u8; 4096];
let mut buf2 = [0_u8; 4096];
loop {
tokio::select! {
len = udp_stack.read(&mut buf1) => {
let len = len?;
if len == 0 {
break;
}
let buf1 = &buf1[..len];
_ = dns::parse_data_to_dns_message(buf1, false)?;
// Insert the DNS message length in front of the payload
let len = u16::try_from(buf1.len())?;
let mut buf = Vec::with_capacity(std::mem::size_of::<u16>() + usize::from(len));
buf.extend_from_slice(&len.to_be_bytes());
buf.extend_from_slice(buf1);
server.write_all(&buf).await?;
crate::traffic_status::traffic_status_update(buf.len(), 0)?;
2024-02-01 19:15:32 +08:00
}
len = server.read(&mut buf2) => {
let len = len?;
if len == 0 {
break;
}
let mut buf = buf2[..len].to_vec();
crate::traffic_status::traffic_status_update(0, len)?;
2024-02-01 19:15:32 +08:00
let mut to_send: VecDeque<Vec<u8>> = VecDeque::new();
loop {
if buf.len() < 2 {
break;
}
let len = u16::from_be_bytes([buf[0], buf[1]]) as usize;
if buf.len() < len + 2 {
break;
}
// remove the length field
let data = buf[2..len + 2].to_vec();
let mut message = dns::parse_data_to_dns_message(&data, false)?;
let name = dns::extract_domain_from_dns_message(&message)?;
let ip = dns::extract_ipaddr_from_dns_message(&message);
log::trace!("DNS over TCP query result: {} -> {:?}", name, ip);
if !ipv6_enabled {
dns::remove_ipv6_entries(&mut message);
}
to_send.push_back(message.to_vec()?);
if len + 2 == buf.len() {
break;
}
buf = buf[len + 2..].to_vec();
}
while let Some(packet) = to_send.pop_front() {
udp_stack.write_all(&packet).await?;
}
}
}
}
log::info!("Ending {}", session_info);
2023-08-05 15:52:32 +08:00
Ok(())
2023-04-14 17:27:37 +08:00
}
2024-02-01 19:15:32 +08:00
2024-04-07 19:02:57 +08:00
/// This function is used to handle the business logic of tun2proxy and SOCKS5 server.
/// When handling UDP proxy, the return value UDP associate IP address is the result of this business logic.
/// However, when handling TCP business logic, the return value Ok(None) is meaningless, just indicating that the operation was successful.
2024-02-01 19:15:32 +08:00
async fn handle_proxy_session(server: &mut TcpStream, proxy_handler: Arc<Mutex<dyn ProxyHandler>>) -> crate::Result<Option<SocketAddr>> {
let mut launched = false;
let mut proxy_handler = proxy_handler.lock().await;
let dir = OutgoingDirection::ToServer;
let (mut tx, mut rx) = (0, 0);
2024-02-01 19:15:32 +08:00
loop {
if proxy_handler.connection_established() {
break;
}
if !launched {
let data = proxy_handler.peek_data(dir).buffer;
let len = data.len();
if len == 0 {
return Err("proxy_handler launched went wrong".into());
}
server.write_all(data).await?;
proxy_handler.consume_data(dir, len);
tx += len;
2024-02-01 19:15:32 +08:00
launched = true;
}
let mut buf = [0_u8; 4096];
let len = server.read(&mut buf).await?;
if len == 0 {
return Err("server closed accidentially".into());
}
rx += len;
2024-02-01 19:15:32 +08:00
let event = IncomingDataEvent {
direction: IncomingDirection::FromServer,
buffer: &buf[..len],
};
proxy_handler.push_data(event).await?;
let data = proxy_handler.peek_data(dir).buffer;
let len = data.len();
if len > 0 {
server.write_all(data).await?;
proxy_handler.consume_data(dir, len);
tx += len;
2024-02-01 19:15:32 +08:00
}
}
crate::traffic_status::traffic_status_update(tx, rx)?;
2024-02-01 19:15:32 +08:00
Ok(proxy_handler.get_udp_associate())
}