From 89199904d2381fd91191f0b619df26aabb77ae52 Mon Sep 17 00:00:00 2001 From: e1732a364fed <75717694+e1732a364fed@users.noreply.github.com> Date: Thu, 1 Jan 2099 00:00:00 +0000 Subject: [PATCH] minor improve --- README.md | 1 + doc/notes.md | 9 +-- src/net/listen.rs | 69 +++++++++++-------- src/net/mod.rs | 2 +- .../{udp_listen.rs => udp_fixed_listen.rs} | 19 ++++- 5 files changed, 63 insertions(+), 37 deletions(-) rename src/net/{udp_listen.rs => udp_fixed_listen.rs} (96%) diff --git a/README.md b/README.md index 630f7d31..da5edb9d 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ o2node-.->collector - [x] tcp, udp, unix domain socket, ip (tun)([tun example](rucimp/examples/README.md#tun)) - [x] 流量记录 (两种实现, 分别用于记录原始流量(GlobalTrafficRecorder)与实际流量(Counter)) 与实时单连接流量监控 (trace feature) - [x] Direct, Blackhole, Listener, BindDialer, Stdio, Fileio +- [x] fixed_target_addr - [x] Tls, Socks5(+ UDP ASSOCIATE,USERPASS), Http proxy, Socks5http, Trojan - [x] Adder (按字节加法器), Counter, Echo - [x] 路由 (tag_route) diff --git a/doc/notes.md b/doc/notes.md index 58797f49..e6c6aa0e 100644 --- a/doc/notes.md +++ b/doc/notes.md @@ -124,7 +124,7 @@ BindDialer = { } ``` -### udp fixed_target_addr 转发 问题 +### BindDialer 的 udp fixed_target_addr 转发 问题 fixed_target_addr (dokodemo) 对于 udp BindDialer 有一个问题 @@ -156,14 +156,15 @@ www.1.com 的答 是回复给 client1 还是 client2 呢? 不完美方案: 1. 记录连接的顺序,然后按回答顺序回复给源。(如,记录交作业的顺序,按出成绩的顺序 回复)。问题:出成绩的顺序与交作业的顺序不一定一致 -2. 探查 udp 内容,按答案中的内容匹配后回复给源。问题:这样属于侵犯源的隐私 +2. 探查 udp 内容,按答案中的内容匹配后回复给源。问题:这样属于侵犯源的隐私, 且若不为已知协议则做不到 3. 将回复 广播给所有 源。问题:这样属于侵犯源的隐私 +4. 独占性: 让用户自行确保同一段时间内只有唯一的客户端连接 ruci的 BindDialer -都不完美. 唯一的方案是: 不用 BindDialer 做 udp 转发, 而是 使用 Listener +都不完美. 绕过的方案是: 不用 BindDialer 做 udp 转发, 而是 使用 Listener Listener 在 监听 udp, 且 有 udp 的 fixed_target_addr 时, 会对每一个 inbound -连接新建一个 udp , 建立了一对一的转发, 而不是 一对多的转发, 就没问题了 +连接新建一个 udp 连接 , 建立了一对一的转发, 而不是 一对多的转发, 就没问题了 ### 报错示例: socks5 client only support tcplike stream, got NoStream diff --git a/src/net/listen.rs b/src/net/listen.rs index 83a74a08..57f0abf3 100644 --- a/src/net/listen.rs +++ b/src/net/listen.rs @@ -2,14 +2,14 @@ use std::{fs::remove_file, path::PathBuf}; use anyhow::{bail, Context}; use tokio::net::TcpListener; -use tracing::warn; +use tracing::{info, warn}; #[cfg(unix)] use tokio::net::UnixListener; use crate::net::{self, Stream}; -use super::{udp_listen::FixedTargetAddrUDPListener, Addr}; +use super::{udp_fixed_listen::FixedTargetAddrUDPListener, Addr}; #[derive(Debug)] pub enum Listener { @@ -27,30 +27,32 @@ pub async fn listen( ) -> anyhow::Result { match laddr.network { net::Network::TCP => { - let r = TcpListener::bind(laddr.get_socket_addr().expect("a has socket addr")) - .await - .context("tcp listen failed")?; + let r = TcpListener::bind( + laddr + .get_socket_addr() + .context("listen tcp but has no socket addr")?, + ) + .await + .context("tcp listen failed")?; Ok(Listener::TCP(r)) } - net::Network::UDP => Ok(Listener::UDP( - FixedTargetAddrUDPListener::new(laddr.clone(), opt_fixed_target_addr.unwrap()).await?, - )), + net::Network::UDP => { + let ft = match opt_fixed_target_addr { + Some(ft) => ft, + None => bail!("listen udp requires a fixed_target_addr"), + }; + Ok(Listener::UDP( + FixedTargetAddrUDPListener::new(laddr.clone(), ft).await?, + )) + } #[cfg(unix)] net::Network::Unix => { - let file_n = laddr.get_name().expect("a has a name"); + let file_n = laddr.get_name().context("listen unix but has no name")?; let p = PathBuf::from(file_n.clone()); - // is_file returns false for unix domain socket - - if p.exists() && !p.is_dir() { - warn!( - "unix listen: previous {:?} exists, will delete it for new listening.", - p - ); - remove_file(p.clone()).context("unix listen try remove previous file failed")?; - } - let r = UnixListener::bind(p).context("unix listen failed")?; + remove_unix(&p, true)?; + let r = UnixListener::bind(p).context("listen unix failed")?; Ok(Listener::UNIX((r, file_n))) } @@ -58,6 +60,20 @@ pub async fn listen( } } +fn remove_unix(p: &PathBuf, warn: bool) -> anyhow::Result<()> { + // is_file returns false for unix domain socket + + if p.exists() && !p.is_dir() && !p.is_file() { + if warn { + warn!("unix: previous {:?} exists, will remove it!", p); + } else { + info!("removing unix: {:?}", p); + } + remove_file(p.clone()).context("unix try remove previous file failed")?; + } + Ok(()) +} + impl Drop for Listener { fn drop(&mut self) { self.clean_up() @@ -84,7 +100,7 @@ impl Listener { Err(e) => format!("no laddr, e:{e}"), } } - Listener::UDP(u) => format!("{}", u.laddr), + Listener::UDP(u) => format!("{}", u.laddr()), #[cfg(unix)] Listener::UNIX(u) => { @@ -102,17 +118,12 @@ impl Listener { #[cfg(unix)] Listener::UNIX((_, file_n)) => { let p = PathBuf::from(file_n.clone()); - if p.exists() && !p.is_dir() { - warn!("unix clean up: will delete {:?}", p); - let r = remove_file(p.clone()).context("unix clean up delete file failed"); - if let Err(e) = r { - warn!("{}", e) - } + let r = remove_unix(&p, false); + if let Err(e) = r { + warn!("{}", e) } } - Listener::UDP(ul) => { - ul.shutdown(); - } + _ => {} } } diff --git a/src/net/mod.rs b/src/net/mod.rs index 308af0f0..f4914d4f 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -12,7 +12,7 @@ pub mod helpers; pub mod http; pub mod listen; pub mod udp; -mod udp_listen; +mod udp_fixed_listen; pub mod cp; diff --git a/src/net/udp_listen.rs b/src/net/udp_fixed_listen.rs similarity index 96% rename from src/net/udp_listen.rs rename to src/net/udp_fixed_listen.rs index 9a4fb2f6..9a0c3c1e 100644 --- a/src/net/udp_listen.rs +++ b/src/net/udp_fixed_listen.rs @@ -29,8 +29,8 @@ use super::{ /// 只支持 预定义 target_addr #[derive(Debug)] pub struct FixedTargetAddrUDPListener { - pub laddr: Addr, - pub dst: Addr, + laddr: Addr, + fixed_target: Addr, rx: mpsc::Receiver<(AddrConn, Addr)>, shutdown_tx: Option>, } @@ -116,7 +116,7 @@ impl FixedTargetAddrUDPListener { shutdown_tx: Some(shutdown_tx), laddr, rx, - dst, + fixed_target: dst, }) } @@ -136,6 +136,19 @@ impl FixedTargetAddrUDPListener { let _ = tx.send(()); } } + + pub fn laddr(&self) -> &Addr { + &self.laddr + } + pub fn raddr(&self) -> &Addr { + &self.fixed_target + } +} + +impl Drop for FixedTargetAddrUDPListener { + fn drop(&mut self) { + self.shutdown() + } } /// init a AddrConn from a UdpSocket