Skip to content

Commit

Permalink
minor improve
Browse files Browse the repository at this point in the history
  • Loading branch information
e1732a364fed committed Jan 1, 2099
1 parent 2db9f88 commit 8919990
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 37 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 5 additions & 4 deletions doc/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ BindDialer = {
}
```

### udp fixed_target_addr 转发 问题
### BindDialer 的 udp fixed_target_addr 转发 问题

fixed_target_addr (dokodemo) 对于 udp BindDialer 有一个问题

Expand Down Expand Up @@ -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
Expand Down
69 changes: 40 additions & 29 deletions src/net/listen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -27,37 +27,53 @@ pub async fn listen(
) -> anyhow::Result<Listener> {
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)))
}
_ => bail!("listen not implemented for this network: {}", laddr.network),
}
}

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()
Expand All @@ -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) => {
Expand All @@ -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();
}

_ => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
19 changes: 16 additions & 3 deletions src/net/udp_listen.rs → src/net/udp_fixed_listen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<oneshot::Sender<()>>,
}
Expand Down Expand Up @@ -116,7 +116,7 @@ impl FixedTargetAddrUDPListener {
shutdown_tx: Some(shutdown_tx),
laddr,
rx,
dst,
fixed_target: dst,
})
}

Expand All @@ -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
Expand Down

0 comments on commit 8919990

Please sign in to comment.