Skip to content

Latest commit

 

History

History
87 lines (51 loc) · 4.16 KB

README.zh_CN.md

File metadata and controls

87 lines (51 loc) · 4.16 KB

mptunnel

MultiPath Tunnel (多路 UDP 隧道的用户空间实现)

README in English

关于

mptunnel 是一个在用户空间实现的多路 UDP(类似 MPTCP),其创建一个虚拟隧道,将该隧道中的数据包通过多条路径转发到目标服务器。

MPTCP 旨在提高网络稳定性,但它只支持 TCP 协议。似乎目前还没有 MPUDP 的实现,于是我就写了这个小工具。

原理

                        .---- 桥 1 ----.
                       /                \
 服务器 A --- mpclient ------ 桥 2 ----- mpserver --- 服务器 B
                       \                /
                        `---- 桥 3 ----`

有两台服务器,分别是服务器 A 和服务器 B,它们之间的网络连接不是很稳定,丢包率很高。为了提高网络稳定性,我们希望降低丢包率。为达到这一目标,我们将 A 和 B 之间的数据包复制多份,然后通过不同的路径发送出去。这样,除非所有路径上的数据包都丢了,A 和 B 之间的数据包才会真的丢失,只要有一条路径上的数据包能够到达目的地,A 和 B 之间就不会感觉到丢包。

mpserver 运行在服务器端(可以直接在服务器 B 上运行),它接收从多条路径上发来的数据包,并将数据包转发给服务器 B,它也会将服务器 B 的数据包复制多份,然后转发到各个桥。运行 mpserver 时,需要指定监听端口和目标服务器地址及端口。

mpclient 运行在客户端,它会在本地监听一个端口,将收到的数据包复制多份,然后通过桥转发给目标服务器。启动 mpclient 时需要指定远程桥地址和端口。

就是一个简单的数据包转发服务器,你可以用 socat 或者 nc 等工具来实现。桥应该原封不动地在 mpclient 和 mpserver 之间转发数据包。

例子

我有一台 OpenVPN 服务器,但是本机到 OpenVPN 服务器的网络丢包率很高,这很影响 OpenVPN 隧道之上的数据传输吞吐量。为了提高吞吐量,就需要降低丢包率。我可以先建立一条 MPUDP 隧道,然后在这个隧道上再建立 OpenVPN 连接。

OpenVPN 监听服务器的 1194 端口,在 OpenVPN 上运行 mpserver:

mpserver 2000 127.0.0.1 1194

mpserver 会监听 2000 端口,并将数据包转发到本机的 1194 端口。

在本机上,运行 mpclient:

mpclient mpclient.conf

mpclient.conf 的内容是:

1.2.3.4 4000
bridge1.myhost.com 4000
bridge2.myhost.com 4000

1.2.3.4 是 OpenVPN 服务器的 IP 地址。把目标服务器当成一个桥是完全没有问题的。

在桥服务器上,用 socat 来转发数据包:

socat udp-listen:4000 udp4:1.2.3.4:2000

这样,桥服务器就会在监听端口 4000 和 1.2.3.4 的 2000 端口之间转发数据包。

现在,MPUDP 隧道已经建立起来了,接下来要把 OpenVPN 客户端配置文件中的服务器地址改为 127.0.0.1:3000。3000 是 mpclient 在本地监听的端口。启动 OpenVPN 客户端后,OpenVPN 客户端就会在 MPUDP 隧道上建立 OpenVPN 服务器连接了。

已知问题

  • mptunnel 会在转发的数据包中添加一些控制和包同步信息。如果 mpclient 或者 mpserver 其中的一个被停止了,那么必须重新启动 mpserver 和 mpclient 才能重建 MPUDP 隧道。

  • 目前 mptunnel 只支持指定一个目标服务器。事实上我觉得将 mpclient 做成 SOCKS 代理的话会更好用,但是我找了很久也没发现好用的 C 语言的 SOCKS 库,自己实现一个又太麻烦了。有谁知道有什么好用的 SOCKS 库吗?

  • mptunnel 自带数据加密功能,但加密速度较慢,在一台 AMD Athlon II P320 CPU 机器上实测,在 3 通道的情况下,实际数据流量仅为 3Mbps。如果你不需要 mptunnel 对数据进行加密,可以设定环境变量 MPTUNNEL_ENCRYPT=0 以禁用 mptunnel 自带的加密功能。在禁用加密功能后,吞吐量从 3Mbps 提高到了 300Mbps。

依赖关系

编译 mptunnel 时,需要先安装下面的库

  • libev

参见

mlvpn 也是一个可以用来做多路 UDP 的项目。