我正在为 tun2socks 实现 Cone NAT (NAT Type 1/2/3):https://github.com/eycorsican/go-tun2socks/tree/nat3 ,但发现 V2Ray 并没有提供相关的接口。
为了能够实现 Cone NAT,希望能够有以下接口:
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error)
所返回的 UDPConn 至少实现了以下方法( https://golang.org/pkg/net/#PacketConn ):
func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error)
func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error)
其中 ReadFrom 需要返回目的地址(非代理服务器地址),WriteTo 中的地址也是目的地址。
另一个 issue 提到了实现 NAT 2,看起来目前 VMess 从协议层面上缺乏支持,不过这似乎并不影响对其它协议提供支持,比如 Freedom, Socks, Shadowsocks。
是的,目前的框架不能方便地添加这一特性。如果你只需要本地Freedom的话,可以用ListenPacket 获取一个系统的 PacketConn。我也正打算把所有 Dial(UDP) 的操作改为 ListenPacket。这个做法无法获取最终的目标地址(协议不支持),但能一定程度上改善UDP NAT的状况。
如果你需要一个类似 socks port binding 的功能的话,实现起来会需要一点时间。
不需要绑定端口啊,不管是本地freedom 还是服务端的socks/shadowsocks,跟目的服务器通讯的 UDP 端口由系统随机挑就行。
我是希望有个统一的接口,像 functions.go 里面的 Dial 一样,但因为 目前VMess不支持获取
UDP的目的地址,那对于Vmess,这个接口可以返回一个空的目的地址,其它能支持的协议就返回真实的目的地址,这样子。
然后实际使用时可以利用路由功能,把那些需要 Cone NAT 的UDP 流量路由到非vmess的outbound,其它流量依然可以继续用vmess
哦,这个不难,VMess也是可以的。
VMess 怎么可以?我没看到协议中的答应部分有地址和端口字段啊,没有这些字段就无法判断数据是哪个机器发来的
已经添加 DialUDP 方法 ( https://github.com/v2ray/v2ray-core/commit/b52725cf659e0f7a38fed2eb36a5a792843bd54f ),另外现在 Freedom 已可以接收 NAT 2的数据 ( https://github.com/v2ray/v2ray-core/commit/a1b552f9487d2687228dd1d89003087331f62eab )。
现在的问题是,部分UDP包的源地址不能正确返回。但这不是这个issue的问题。
现在 dokodemo-door, socks5 与 shadowsocks 协议的 NAT 支持如何了?我目前了解到的:
正在尝试用 v2ray + mellow 做一站式配置,需要在用 ZeroTier 建立的内网里用 socks5/ss 作代理加速网络不好的朋友的局域网联机,所以想知道 v2ray 在这些方面的支持度……
@Vigilans
目前 v2ray-core 不支持 Full Cone(尽管有某些测试软件结果显示 Full Cone),原因 @VictoriaRaymond 前面也说了有部分 UDP 包的源地址不能正确返回。
关于 UDP 源地址不正确返回的问题,简单来说,正常情况,假设本地 1.1.1.1:1111 用 UDP 先后分别发 abc 和 def 两条信息给 2.2.2.2:2222 和 3.3.3.3:3333,然后他们分别返回 cba 和 fed 给 1.1.1.1:1111,1.1.1.1:1111 接收这两条返回的信息,会看到 cba 来自 2.2.2.2:2222,fed 来自 3.3.3.3:3333,但如果中间插了个 v2ray-core 进来,1.1.1.1:1111 看到的是 cba 和 fed 都同样来自 2.2.2.2:2222(因为它是先),所以这里 fed 这条信息的 3.3.3.3:3333 地址没有正确返回(被 v2ray-core 改写为 2.2.2.2:2222 了)。
另外在 Mellow 中使用 freedom/socks/shadowsocks 是支持 Full Cone 的,Mellow 修改过 v2ray-core 的代码让这些协议的 UDP 包源地址可以正确返回。
@eycorsican
好的,我理解了这里面的问题了……我查了一下相关的 commit,请问 Mellow 是通过 go-tun2socks 的这个commit一样,在 v2ray-core 上包装一层中间接口来实现正确返回 UDP 包源地址,以及添加扩展功能的吗?
如果是这样的话,是不是应当考虑只以 Mellow 作为 V2ray 的 Client 比较合适?
并没这么简单,这里的根本问题在于 v2ray-core 设计初只考虑到流式 IO,在它的核心 IO 模块(https://github.com/v2ray/v2ray-core/blob/master/transport/pipe/impl.go) 中没有像 ReadFrom/WriteTo 这类可以带上地址的 IO 机制,导致就算在 outbound 读到远端地址信息,也没办法通过中间 IO 传给 inbound,inbound 也就没办法把地址传给客户端,所以 inbound 只是保存着第一次客户端传过来的目的地址,然后所有返回的数据都当作是这个地址的。
需要 Full Cone NAT 的情况真不多,也就 Mellow 这种全局透明代理适用,还有路由器透明代理。
@eycorsican 了解了。
Most helpful comment
已经添加 DialUDP 方法 ( https://github.com/v2ray/v2ray-core/commit/b52725cf659e0f7a38fed2eb36a5a792843bd54f ),另外现在 Freedom 已可以接收 NAT 2的数据 ( https://github.com/v2ray/v2ray-core/commit/a1b552f9487d2687228dd1d89003087331f62eab )。
现在的问题是,部分UDP包的源地址不能正确返回。但这不是这个issue的问题。