udp2raw icon indicating copy to clipboard operation
udp2raw copied to clipboard

关于facktcp模式下实际上建立的UDP连接数的问题

Open wwqgtxx opened this issue 8 years ago • 6 comments

请问一下作者,在facktcp下实际上建立的UDP连接是只能单连接么,还是可以实现多条连接分拆传输?

这种需要多条连接的场景在多播以及双线网络中用途很大,比如在我的网络中同时有电信和联通的出口,上层路由随机选择一个出口和外界进行通讯(一般是基于tcp session之类的),如果这里可以建立多个facktcp连接就可以充分理由两个出口同时和服务器进行通讯,从而有效的提高传输效率

wwqgtxx avatar Sep 22 '17 16:09 wwqgtxx

请问一下作者,在facktcp下实际上建立的UDP连接是只能单连接么,还是可以实现多条连接分拆传输?

实际上建立的不是udp连接,是raw socket的连接,因为使用了信道复用(multiplex)的方法,下层连接只有一条,而且目前只能是一条。

下层用单条连接主要是考虑到:

  1. tcp握手需要时间(faketcp也要握手),如果用一个udp连接对应一条faketcp连接的解决方案,会影响udp连接的建立速度。

  2. 有的运营商会限制并发连接数、半开连接数。

这种需要多条连接的场景在多播以及双线网络中用途很大,比如在我的网络中同时有电信和联通的出口,上层路由随机选择一个出口和外界进行通讯(一般是基于tcp session之类的),如果这里可以建立多个facktcp连接就可以充分理由两个出口同时和服务器进行通讯,从而有效的提高传输效率

基本上只要是采用了multiplex方式的tunnel都引入你提到的问题。 一个解决方法是,开启多个upd2raw client实例(server只需要开一个),然后用iptables在本地做一下负载均衡。比如4个udp2raw实例分别监听在127.0.0.1:1111,127.0.0.1:2222,127.0.0.1:3333,127.0.0.1:4444,用iptables把本地的127.0.0.1:5555端口随机转发到前面的4个端口。这是个通用的方法,对其他tunnel也适用。

==note== 之前好像理解错了楼主的意思了,重新编辑了下。

wangyu- avatar Sep 22 '17 17:09 wangyu-

一个解决方法是,开启多个upd2raw client实例(server只需要开一个),然后用iptables在本地做一下负载均衡。比如4个udp2raw实例分别监听在127.0.0.1:1111,127.0.0.1:2222,127.0.0.1:3333,127.0.0.1:4444,用iptables把本地的127.0.0.1:5555端口随机转发到前面的4个端口。

这个的确是个好办法,不过这个功能能不能在程序内部通过一个设置选项直接打开呢,毕竟对于很多普通用户来说,操作iptable规则容易出错,而且经常会达不到想要的效果;如果在程序内部直接可以实现类似的负载均衡可以简化用户的使用,也可以避免很多配置错误,比如kcptun就原生支持n对m的mux:

--conn value                     set num of UDP connections to server (default: 1)

--autoexpire value               set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)

另外实际上,tcp握手需要时间(faketcp也要握手)这个问题貌似并不是很严重,看udp2raw的实现这个握手应该是在程序一开始和服务器进行初始化握手的时候就已经完成了,所以如果在程序开始的时候就直接建立N条通道,然后把接受的UDP包随机的向其中一条通道发送应该就可以比较简化的解决这个问题了

wwqgtxx avatar Sep 23 '17 00:09 wwqgtxx

这个的确是个好办法,不过这个功能能不能在程序内部通过一个设置选项直接打开呢,毕竟对于很多普通用户来说,操作iptable规则容易出错,而且经常会达不到想要的效果;如果在程序内部直接可以实现类似的负载均衡可以简化用户的使用,也可以避免很多配置错误,比如kcptun就原生支持n对m的mux

以后会考虑实现一下。

另外实际上,tcp握手需要时间(faketcp也要握手)这个问题貌似并不是很严重,看udp2raw的实现这个握手应该是在程序一开始和服务器进行初始化握手的时候就已经完成了,所以如果在程序开始的时候就直接建立N条通道,然后把接受的UDP包随机的向其中一条通道发送应该就可以比较简化的解决这个问题了

你说的很对。tcp握手需要时间(faketcp也要握手),如果用一个udp连接对应一条faketcp连接的解决方案,会影响udp连接的建立速度仅是说明一下为什么不能用非muplex方案(一个udp对应一个faketcp连接)。

wangyu- avatar Sep 23 '17 01:09 wangyu-

其实另外一个希望在程序内部实现这个原因是因为haproxy不支持udp代理,而用iptables又很难达到高可用,如果这个N->M的过程可以在程序内部实现,那么程序上层就可以知道下面的某一个链接是否挂掉,从而不会对着一个已经(暂时)失效的连接反复发送数据,从而可以大幅提高用户感知

wwqgtxx avatar Sep 23 '17 01:09 wwqgtxx

其实另外一个希望在程序内部实现这个原因是因为haproxy不支持udp代理,而用iptables又很难达到高可用,如果这个N->M的过程可以在程序内部实现,那么程序上层就可以知道下面的某一个链接是否挂掉,从而不会对着一个已经(暂时)失效的连接反复发送数据,从而可以大幅提高用户感知

在底层(程序内部)实现确实有一些优势,会优先考虑实现。不过底层实现也有缺点,缺点是不通用,实现成类似haproxy这样可能更通用。

wangyu- avatar Sep 23 '17 02:09 wangyu-

的确,我在github上找过很多次,没有找到几个靠谱的支持udp的haproxy,要是能做出来通用性的程序是个好事,不过工程量估计也会很大,在程序内部实现的难度可能会低很多,见效也比较快

wwqgtxx avatar Sep 23 '17 02:09 wwqgtxx