如何在 debian 上使用 pppd 和 tcp 内核设置使 ppp 在有损无线电调制解调器上可靠?

如何在 debian 上使用 pppd 和 tcp 内核设置使 ppp 在有损无线电调制解调器上可靠?

我在通过无线电调制解调器在两个 debian 系统之间建立可靠的 ppp / tcpip 链接时遇到了很多麻烦。

我的硬件拓扑有点复杂。

该系统使用:

  • Raspberry Pi 3B 在无线电链路的每一端运行 raspbianstretch (RPI)
  • RFDesign RFD900x 无线电调制解调器(通过 FTDI 电缆通过 USB 连接到 RPI)(RFD900)
  • 一个 linksys wifi 路由器,它通过 NAT (WIFI) 到卫星服务(SkyMuster - 澳大利亚)到澳大利亚的未知 POP 到互联网 (SAT)
  • 通过 SAT 到另一个由路由器终止的澳大利亚 ISP 静态 IP 的 VPN (vpnc)。 (这是 RPI3B 的默认路由)
  • (VPN) VPN 端点使用静态 IP 连接到网络 (END)

我相信问题出在 RFD900x 调制解调器上,与无线电丢弃数据包时发生的 TCP 拥塞回退有关,尽管我提供了上下文的其他详细信息,以防万一我错过了一些愚蠢的东西。

这些问题在 RFD900 上的 RPI 之间是可以重现的。

从端点(最麻烦)到互联网的链接如下:

RPI -> RFD900 -> RFD900 -> RPI -> VPN -> WIFI -> SAT -> END。

再次参考上面的上下文。

由于距离和障碍物的影响,RFD900 会大量丢包。我尝试过各种空中配置,但均无济于事(全向、亚吉、直接与从花岗岩悬崖上弹跳)。我尝试过调整调制解调器、mtu、ppp 设置等中的各种参数来实现 TCP/IP 可靠性,但没有成功。

空速为64kb。串行速度为57kb。

诊断注释:

  • 在通过 RFD900 在不同距离进行简单的串行到串行通信时,131 字节或 151 字节的无线电 MTU 大小具有最佳吞吐量。
  • 吞吐量是可靠的,尽管是“突发”->突发、突发、突发,而不是连续流。
  • 我怀疑这种“突发性”是 TCP 将无线电数据包丢失视为拥塞而导致不可避免的重试饱和的函数。
  • 当它饱和时,会话(ssh、scp、apt 等)似乎会冻结不同数量的延长时间(几秒,通常是 2-3 分钟,有时 > 10 分钟)。
  • apt 通常会失败。 scp 和 ssh 往往会继续前进并最终到达目的地,尽管通常会出现多个停顿和疯狂的延迟时间。
  • 通过 ssh 交互,该链接是可用的,前提是不涉及长响应 - 例如长 ls -la。
  • 调制解调器的流量控制(无、RTSCTS、XONXOFF)对我的测试来说似乎无关紧要。
  • 不同形式的 ppp 有效负载压缩似乎无关紧要(BSD、Predictor、deflate 等)。
  • Van Jacobsen 报头压缩增加了每次突发的吞吐量,但加剧了停顿和延迟
  • 我广泛搜索了解决方案(甚至返回并阅读 RFC)。
  • 似乎 VJ 头压缩被认为是有损链路的问题,并且 RFC 在压缩技术方面取得了进展,例如 ROHC - RObust 头压缩,包括一个 ROHC 工作组,该工作组似乎已经出现了各种专有压缩协议,这些协议在开源。
  • 对于依赖专有协议的蜂窝链路(使用 ppp 和 RLP)来说,这个问题似乎得到了很好的解决。

我还在这里发布了我当前运行 pppd 的脚本(包括我尝试过的各种选项 - 请参阅#commented 行。):

# set up the pppd to allow the remote unit to connect as an IP peer
# additional options for remote end: usepeerdns defaultroute replacedefultroute

pppd /dev/ttyUSB0 57600 mru 131 mtu 131 noauth crtscts nocdtrcts lock passive 192.168.10.1:192.168.10.2 local maxfail 0 persist proxyarp updetach

#pppd /dev/ttyUSB0 57600 novj novjccomp mru 131 mtu 131 noauth crtscts nocdtrcts lock passive 192.168.10.1:192.168.10.2 local maxfail 0 persist proxyarp updetach

#pppd /dev/ttyUSB0 57600 192.168.10.1:192.168.10.2 mru 131 mtu 131 proxyarp noauth crtscts nocdtrcts noaccomp nobsdcomp nodeflate nopcomp nopredictor1 novj novjccomp lock mru 131 mtu 131 passive local maxfail 0 persist updetach

#debug ktune bsdcomp 12 xonxoff nocrtscts mru 296 mtu 296
#pppd /dev/ttyUSB0 57600 debug mru 131 mtu 131 noauth crtscts nocdtrcts lock passive 192.168.10.1:192.168.10.2 local maxfail 0 persist updetach proxyarp

#pppd /dev/ttyUSB0 57600 noaccomp nobsdcomp nodeflate nopcomp nopredictor1 novj novjccomp mru 131 mtu 131 noauth crtscts nocdtrcts lock passive 192.168.10.1:192.168.10.2 local maxfail 0 persist proxyarp updetach

#pppd /dev/ttyUSB0 57600 novjccomp mru 131 mtu 131 noauth crtscts nocdtrcts lock passive 192.168.10.1:192.168.10.2 local maxfail 0 persist proxyarp updetach

有人用开源 pppd 解决了这个问题吗?是否有其他选择或技术可以替代?

内核 TCP 拥塞设置值得研究吗?

答案1

作为对我自己问题的部分回答,我通过以下措施取得了显着的可靠性改进:

将 tcp_congestion_control 内核插件从默认的立方更改为 bbr 已显着解决了缓冲区膨胀问题,而缓冲区膨胀和有损无线电连接是问题的核心。

这需要加载 tcp_bbr 内核模块,并将 net.core 排队规则模型更改为公平排队,以便为 bbr 模块提供节奏。

RPI 上的默认值是:

net.ipv4.tcp_congestion_control=立方

net.core.default_qdisc=pfifo_fast

在运行时更改此设置的命令是:

modprobe tcp_bbr
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr

我目前从 /etc/rc.local 调用的脚本运行这些。通过修改 modprode.d 和 sysctl.conf 或作为 sysctl.d 中的文件,可以轻松地使它们永久化。

结果是 ssh 的响应更加平滑,批量传输更加可靠,虽然仍处于停滞状态,但能够快速可靠地恢复,立即返回到命令提示符(而不是在 100% 处长时间暂停 - 例如 1 - 3返回前几分钟,就像立方拥塞控制的情况一样)。

权衡是整体速度,但可靠性更重要。例如,使用 scp 通过无线电链路传输 283k 文件现在会导致:

100%  283KB   2.5KB/s   01:51

这是目前我很满意的妥协。然而,长时间运行的批量传输过程仍然存在问题,并最终停滞并且永远无法完成。

例如,apt-get update 运行了一个多小时(在 11.7MB 文件上停滞),需要通过 ssh 终端偶尔回车才能继续运行,并最终陷入非常长的延迟,尽管不会全部失败。

在下面的屏幕抓取中,该过程持续了 1 个多小时,每 10-15 分钟就会出现一些 CR,发送 ^C 与终端响应之间大约有 5 分钟的延迟:

root@priotdev2:~# apt-get update
Get:1 http://mirror.internode.on.net/pub/raspbian/raspbian stretch InRelease [15.0 kB]
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
Get:2 http://archive.raspberrypi.org/debian stretch InRelease [25.3 kB]                                                            
Get:2 http://archive.raspberrypi.org/debian stretch InRelease [25.3 kB]                                                            
Get:4 http://archive.raspberrypi.org/debian stretch/main armhf Packages [145 kB]                                                   
Get:5 http://archive.raspberrypi.org/debian stretch/ui armhf Packages [30.7 kB]                                                    
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
23% [3 Packages 270 kB/11.7 MB 2%]                                                                            2,864 B/s 1h 6min 15s
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
29% [3 Packages 1,263 kB/11.7 MB 11%]                                                                          131 B/s 22h 2min 19s
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
60% [3 Packages 5,883 kB/11.7 MB 50%]                                                                        16 B/s 4d 4h 13min 58s
60% [3 Packages 5,902 kB/11.7 MB 51%]                                                                         1,531 B/s 1h 2min 38s
66% [3 Packages 6,704 kB/11.7 MB 58%]                                                                                              

66% [3 Packages 6,704 kB/11.7 MB 58%]
Get:3 http://mirror.internode.on.net/pub/raspbian/raspbian stretch/main armhf Packages [11.7 MB]                                   
66% [3 Packages 6,735 kB/11.7 MB 58%]                                                                                              
66% [3 Packages 6,735 kB/11.7 MB 58%]
66% [3 Packages 6,745 kB/11.7 MB 58%]                                                                       32 B/s 1d 18h 37min 55s
66% [3 Packages 6,745 kB/11.7 MB 58%]                                                                       32 B/s 1d 18h 37min 55s
66% [3 Packages 6,745 kB/11.7 MB 58%]                                                                                              
66% [3 Packages 6,745 kB/11.7 MB 58%]
66% [3 Packages 6,746 kB/11.7 MB 58%]                                                                          230 B/s 5h 55min 46s

66% [3 Packages 6,747 kB/11.7 MB 58%]                                                                          148 B/s 9h 12min 47s^C
root@priotdev2:~# ^C
root@priotdev2:~# 
root@priotdev2:~# 

滚动到上面转储的右侧可以看到糟糕的吞吐量(在某些情况下降至每秒 16 和 32 字节)。

为了删除也涉及卫星链路的端到端变量,apt 进程实际上使用上游 RPI 作为 apt 缓存(这是最新的),传输仅代表无线电链路上的流量。

我们非常欢迎社区提供有关进一步改进的任何见解。

相关内容