shadowsocks / shadowsocks-org

www.shadowsocks.org
MIT License
847 stars 528 forks source link

[News] Rust 实现的 tun2socks #175

Open LuoZijun opened 3 years ago

LuoZijun commented 3 years ago

地址:https://github.com/shadowsocks/tun2socks 状态:完善中

希望在未来可以使用这个库直接当做 sslocal 使用。

madeye commented 3 years ago

Cool! I think you can follow this list to complete all the features:

LuoZijun commented 3 years ago

@madeye

DNS方面

DNS relay 需要等待 https://github.com/shadowsocks/dns 完成,不过我并不打算采用其它项目现有的那种实现方式。

我希望是更接近于 GeoDNS 的那种方式,所以,其实并不是 relay 的概念。

它的工作模式大概是在本地建立 DNS stub resolver,用户给它两个 upstream 地址(典型用例是一个 upstream 是境外的 DNS Server, 另外一个是境内),本地的 stub resolver 将这两个(或者更多) upstream 的结果汇合,并依照 IP-DB 对结果进行排序,将离用户最近的 addr 排在前面。所以,这种实现并不需要什么复杂的规则

ACL规则方面

ACL 会考虑的是利用 IANA-IP-DB 的方式来做,不太需要用户手动维护一个非常复杂的 list.

IANA-IP-DB 和 代码一起编译,大概编译出来的 可执行文件大小会在 12MB 左右(内置了 V4 和 V6 DB),这个大小其实也可以接受。

内存方面,由于是 static array,并没有运行时开销,查找使用的是二分查找,性能也非常快,内存占用几乎没有。

图片 图片

在使用上,也会更加方便,如 acl --exclude "CN"

protect-socket

避免线路回环,一般是两个方法:

  1. 在建立 relay stream 的时候,主动 将 socket bind 到 egress iface (如 en0) 的 addr 上面,然后再去 connect.
  2. 添加路由。

安卓使用的也是 Linux 内核,那么 netlink 的代码我想会对它有效,目前已经写了一个 netlink 的库,可以去操作系统的 路由表(Route table),Neigh table,link, addr:

https://github.com/shadowsocks/tun2socks/blob/master/crates/netlink/src/route/mod.rs#L327

几乎就是等价于 ip linkip routeip neighip addr 这几个 Linux 的命令。

macOS 的路由表控制则是另外一个库来完成:https://github.com/shadowsocks/tun2socks/blob/master/crates/sysconfig/src/route/macos.rs#L690

zonyitoo commented 3 years ago

It seems that the code in tun2socks could be integrated into shadowsocks-rust project. :P

Permission granted from @LuoZijun , I am working on integrating into shadowsocks-rust.

Mygod commented 3 years ago

(Sorry just saw this.) Invoking most of netlink (especially writing) requires root, which you will not be able to get as a normal Android app. You have to manipulate those through Android's VpnService APIs.

zonyitoo commented 3 years ago

Does VpnService APIs can be called from NDK?

Mygod commented 3 years ago

As far as I am concerned, most netlink related things can only be manipulated via VpnService.Builder, meaning that you can only choose one set of ip routes during the VPN service startup and there are no reasons to modify it further. Therefore, I do not think there is such NDK APIs nor the necessity for those.