MPTCP测试

1.注意事项

  • 测试主机已替换支持MPTCPv1的内核,并且已使能MPTCP,本次测试中使用的内核版本均为5.18.19

  • 测试主机中确保已经正确配置了iproute2mptcpd,参考文档如下:

  • 测试用的server主机可以只有一个WAN口,但是client主机必须至少有两个WAN

  • 本次测试网络环境如下

2.参考文档

  • 本次测试主要参考文档链接如下, 将其clone到本地后,使用浏览器打开docs/index.html即可查看文档
  • 主要参考章节:《Using Multipath TCP on recent Linux kernels》

https://github.com/mptcp-apps/mptcp-doc/tree/main

  • 懒得clone文档得话,直接参考下面的链接吧

https://mptcp-apps.github.io/mptcp-doc/mptcp-linux.html

3.服务器环境配置

3.1 IP地址

  • 服务器端只有一个网口eth0, IP地址:192.168.16.54, 网关:192.168.16.1

3.2 ip mptcp路径管理

  • 执行如下命令,signal的含义暂时不是很理解(2023/5/5)
sudo ip mptcp endpoint add 192.168.16.54 dev eth0 signal
  • 设置子流的最大数量限制
sudo ip mptcp limits set subflow 4
sudo ip mptcp limits set add_addr_accepted 4

4.客户端环境配置

4.1 IP地址

  • client两个WAN口,相应地有两个IP地址, 网关均为192.168.16.1
eth0: 192.168.16.15
eth1: 192.168.16.53

4.2ip mptcp路径管理

  • 执行如下命令,表示允许通过该网口创建MPTCP子流
# 允许通过eth0创建子流
sudo ip mptcp endpoint add 192.168.16.15 dev eth0 subflow
# 允许通过eth1创建子流
sudo ip mptcp endpoint add 192.168.16.53 dev eth1 subflow
  • 设置子流的最大数量限制
sudo ip mptcp limits set subflow 4
sudo ip mptcp limits set add_addr_accepted 4

4.3 路由表配置

(1)client端还需要配置路由,要保证client端的每个网口均能够和server建立连接,其实我们在局域网中测试应该是不需要配置路由的,但是为了和实际环境保持一致,还是配置一下吧

(2)修改/etc/iproute2/rt_tables, 在其中加入Teth0Teth1这两项,目的是为了让我们在查看路由表时能够通过表名直观得看出路由表和网口的对应关系, 如下

$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default 240 Teth0
241 Teth1 0 unspec
#
# local
#
#1 inr.ruhep

(3)配置eth0路由表

# create eth0 routing tables
sudo ip rule add from 192.168.16.15 table Teth0
sudo ip route add 192.168.16.0/24 dev eth0 scope link table Teth0
sudo ip route add default via 192.168.16.1 dev eth0 table Teth0 # show eth0 routing tables
$ ip route show table Teth0
default via 192.168.16.1 dev eth0
192.168.16.0/24 dev eth0 scope link

(4)配置eth1路由表

# create eth1 routing tables
sudo ip rule add from 192.168.16.53 table Teth1
sudo ip route add 192.168.16.0/24 dev eth1 scope link table Teth1
sudo ip route add default via 192.168.16.1 dev eth1 table Teth1 # show eth1 routing tables
$ ip route show table Teth1
default via 192.168.16.1 dev eth1
192.168.16.0/24 dev eth1 scope link

5. 使用netcat进行测试

(1)必须正确安装mptcpd,否则系统中会没有mptcpize

(2)tcpdump使用指南

https://www.cnblogs.com/wongbingming/p/13212306.html

(3)安装netcat

sudo apt-get install -y netcat

(4)在server启动netcat,监听端口12345

mptcpize run nc -l 12345

(5)在client中运行tcpdump,抓取端口12345的包,并使用-vv参数显示详细信息

sudo tcpdump -ni any port 12345 -vv

(6)在client新开一终端,启动netcat,连接服务器192.168.16.54:12345,并发送测试字符串(67个字符a)

$ mptcpize run nc 192.168.16.54 12345
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

(7)tcpdump抓包结果如下

tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes #1. eth0 192.168.16.15:59254 和 服务器192.168.16.54:12345 建立TCP连接时发送的SYN包[S],注意标识:mptcp capable v1
16:09:32.727979 eth0 Out IP (tos 0x0, ttl 64, id 5322, offset 0, flags [DF], proto TCP (6), length 64)
192.168.16.15.59254 > 192.168.16.54.12345: Flags [S], cksum 0xa1c8 (incorrect -> 0x2337), seq 1143547619, win 65535, options [mss 1460,sackOK,TS val 1682140458 ecr 0,nop,wscale 7,mptcp capable v1], length 0 #2. 服务器发送SYN包,同时对客户端的SYN回复ACK包[S.]
16:09:32.728182 eth0 In IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 72)
192.168.16.54.12345 > 192.168.16.15.59254: Flags [S.], cksum 0x0122 (correct), seq 3458909688, ack 1143547620, win 65160, options [mss 1460,sackOK,TS val 473542376 ecr 1682140458,nop,wscale 7,mptcp capable v1 {0x55e5e6bfda688d17}], length 0
16:09:32.728345 eth0 Out IP (tos 0x0, ttl 64, id 5323, offset 0, flags [DF], proto TCP (6), length 72) #3. 客户端对服务器的SYN回复ACK包[.], 三次握手完成
192.168.16.15.59254 > 192.168.16.54.12345: Flags [.], cksum 0xa1d0 (incorrect -> 0x6312), seq 1, ack 1, win 512, options [nop,nop,TS val 1682140458 ecr 473542376,mptcp capable v1 {0xb68d501d6d0c359d,0x55e5e6bfda688d17}], length 0
16:09:50.591297 eth0 Out IP (tos 0x0, ttl 64, id 5324, offset 0, flags [DF], proto TCP (6), length 143) #4. 客户端发送67byte的payload到server,确实,在这一步发送了67个字符a到server
192.168.16.15.59254 > 192.168.16.54.12345: Flags [P.], cksum 0xa217 (incorrect -> 0x7428), seq 1:68, ack 1, win 512, options [nop,nop,TS val 1682158321 ecr 473542376,mptcp capable v1 {0xb68d501d6d0c359d,0x55e5e6bfda688d17},nop,nop], length 67
16:09:50.591485 eth0 In IP (tos 0x0, ttl 64, id 5783, offset 0, flags [DF], proto TCP (6), length 64) #5. server回复ACK包[.], ack = 68
192.168.16.54.12345 > 192.168.16.15.59254: Flags [.], cksum 0xff34 (correct), seq 1, ack 68, win 509, options [nop,nop,TS val 473560240 ecr 1682158321,mptcp dss ack 6184476764236969448], length 0
16:09:50.591875 eth1 Out IP (tos 0x0, ttl 64, id 21432, offset 0, flags [DF], proto TCP (6), length 72) #6. 注意了:这时MPTCP开始创建子流,网口eth1 192.168.16.53:39509开始和服务器192.168.16.54:12345建立连接, 注意标识:mptcp join id 3 token 0xa781e174 nonce 0x1069cb10
# 这里有疑问:为什么在第一次数据发送完成后才开始建立子流?而不是在发送数据之前就建立子流呢?
# 问题已解决:参考https://mptcp-apps.github.io/mptcp-doc/mptcp.html 的Fig.13,可见MPTCP协议规定如此
192.168.16.53.39509 > 192.168.16.54.12345: Flags [S], cksum 0xa1f6 (incorrect -> 0xa632), seq 3051078268, win 65535, options [mss 1460,sackOK,TS val 2165143953 ecr 0,nop,wscale 7,mptcp join id 3 token 0xa781e174 nonce 0x1069cb10], length 0
16:09:50.592361 eth1 In IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 76) #7. server向eth1发送SYN,同时对client的SYN回复ACK[S.], 注意标识:mptcp join id 0 hmac 0x56c46c3b8b417d nonce 0x2e91a3d2
192.168.16.54.12345 > 192.168.16.53.39509: Flags [S.], cksum 0x4763 (correct), seq 619200371, ack 3051078269, win 65160, options [mss 1460,sackOK,TS val 3121185292 ecr 2165143953,nop,wscale 7,mptcp join id 0 hmac 0x56c46c3b8b417d nonce 0x2e91a3d2], length 0
16:09:50.592485 eth1 Out IP (tos 0x0, ttl 64, id 21433, offset 0, flags [DF], proto TCP (6), length 76) #8. client对server的SYN回复ACK[.], 子流的三次握手完成,子流创建成功
192.168.16.53.39509 > 192.168.16.54.12345: Flags [.], cksum 0xa1fa (incorrect -> 0x6395), seq 1, ack 1, win 512, options [nop,nop,TS val 2165143953 ecr 3121185292,mptcp join hmac 0x505d3849a1f214befb11ee9a55b25f4893fa9148], length 0
16:09:50.592962 eth1 In IP (tos 0x0, ttl 64, id 32872, offset 0, flags [DF], proto TCP (6), length 64)
...

6. 使用iperf3进行测试

(1)必须正确安装mptcpd,否则系统中会没有mptcpize

(2)安装iperf3

sudo apt-get install -y iperf3

(3)在服务器上运行iperf server, 指定端口8888

mptcpize run iperf3 -s -p 8888

(4)在client上运行iperf client, 绑定网口eth0, 分别测试TCP上行/下行; 因为我们绑定了网口eth0,所以如果MPTCP不生效的话,网口eth1上不应该有iperf3测试的流量;反之,如果在eth1上观测到了iperf3测试的流量,说明MPTCP成功生效了

# TCP上行测试
mptcpize run iperf3 -c 192.168.16.54 -p 8888 -B 192.168.16.15 -P 5 -t 30
# TCP下行测试
mptcpize run iperf3 -c 192.168.16.54 -p 8888 -B 192.168.16.15 -P 5 -t 30 -R

(5)在client上安装流量监控工具nload,用来观察所有网口上的实时流量

sudo apt-get -y install nload
sudo nload -m

(6)TCP上行测试时,各个网口实时流量如下

  • 如上图所示,两个网口eth0eth1上均有大流量在传输,MPTCP测试成功
  • 并且在iperf3测速过程中移除一条网线,测速不会中断
  • 当然也可以通过tcpdump抓包进行分析,在此偷个懒,就不演示了

MPTCP(六):MPTCP测试的更多相关文章

  1. 2018.11.23 浪在ACM 集训队第六次测试赛

    2018.11.23 浪在ACM 集训队第六次测试赛 整理人:刘文胜 div 2: A: Jam的计数法 参考博客:[1] 万众 B:数列 参考博客: [1] C:摆花 参考博客: [1] D:文化之 ...

  2. python学习(十六) 测试

    测试驱动开发. 16.1 先测试,后编码 16.1.1 精确的需求说明 16.1.2 为改变而计划 16.1.3 测试的4个步骤 16.2 测试工具 16.2.1 doctest 16.2.2 uni ...

  3. Python学习笔记(六)测试开发之接口开发

    Python的接口开发要使用到flask.Flask(__name__) 下面是一个简单的接口实例程序及访问效果: import flaskserver = flask.Flask(__name__) ...

  4. [App Store Connect帮助]六、测试 Beta 版本(4.4) 管理 Beta 版构建版本:停止测试构建版本

    在首页上,点按“我的 App”,选择您的 App,然后在工具栏中点按“TestFlight”. 在左列中的“构建版本”下,点按您 App 的平台(iOS 或 Apple TVOS). 在右表中,点按该 ...

  5. [App Store Connect帮助]六、测试 Beta 版本(4.2) 管理 Beta 版构建版本:查看构建版本状态和指标

    必要职能:“帐户持有人”职能.“管理”职能.“App 管理”职能.“开发者”职能或“营销”职能.请参见职能权限. 在首页上,点按“我的 App”,选择您的 App,然后在工具栏中点按“TestFlig ...

  6. [App Store Connect帮助]六、测试 Beta 版本(4.1) 管理 Beta 版构建版本:为构建版本添加测试员

    在“TestFlight”部分中,您可以查看您所有 App 版本的构建版本,并深入查看构建版本的详细信息.您也可以为某个构建版本添加群组或独立测试员. 必要职能:“帐户持有人”职能.“管理”职能或“A ...

  7. [App Store Connect帮助]六、测试 Beta 版本(3.3)管理测试员:查看测试员信息

    如果您使用“TestFlight Beta 版测试”,您可以查看关于测试员的信息,并衡量测试员的参与度. 必要职能:“帐户持有人”职能.“管理”职能.“App 管理”职能.“开发者”职能或“营销”职能 ...

  8. [App Store Connect帮助]六、测试 Beta 版本(3.2)管理测试员:邀请外部测试员

    在您上传至少一个构建版本之后,您可以邀请外部测试员(您组织之外的人员)使用“TestFlight Beta 版测试”来测试您的 App.为了使您的构建版本可用于外部测试,请创建一个群组.添加构建版本, ...

  9. [App Store Connect帮助]六、测试 Beta 版本(3.1)管理测试员:添加内部测试员

    您可以添加至多 25 个内部测试员(您的 App Store Connect 用户)使用“TestFlight Beta 版测试”来测试您的 App.在您上传了至少一个构建版本之后,才可添加测试员. ...

  10. [App Store Connect帮助]六、测试 Beta 版本(2)输入测试信息以供外部测试

    如果您向外部测试员分发您的 App,您需要输入关于您 App 的额外 TestFlight 测试信息以供“Beta 版 App 审核”.您可以在添加 App 至您的帐户时,或在您邀请外部测试员时输入此 ...

随机推荐

  1. C#使用Aspose将Word\HTML 转换成PDF文件

    写在前面 Aspose 这个是收费的,直接使用是有水印的 需要用到的dll文件 ==> Aspose.Words.dll.Aspose.HTML.dll.Aspose.Total.lic(授权文 ...

  2. 使用gitea搭建源码管理【0到1架构系列】

    使用开源搭建Git源码方案,gitlab和gitea是两个不错的方案,gitlab以前简单易用,现在功能复杂且对开源并不友好,gitea一直保持功能单一易用且完全开源,个人推荐gitea. 通过容器安 ...

  3. HTTP常见的状态码?

    100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息 200 OK 正常返回信息 201 Created 请求 ...

  4. yb课堂 新版Vue+脚手架Vue-Cli 4.3安装 《二十七》

    本地搭建Vue.CLI.Cube-UI相关框架 什么是Vue 一套用于构建用户界面的渐进式框架.与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用.Vue的核心库只关注视图层,不仅易于上手,还 ...

  5. Oracle 存储过程 捕获异常

    1.带参数插入并带返回值,异常信息 CREATE OR REPLACE PROCEDURE test_pro (v_id in int,v_name in varchar2,app_code out ...

  6. 洛谷P1063

    [NOIP2006 提高组] 能量项链 题目描述 在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链.在项链上有 \(N\) 颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着 ...

  7. 合合TextIn - 大模型加速器

    TextIn是合合信息旗下的智能文档处理平台,在智能文字识别领域深耕17年,致力于图像处理.模式识别.神经网络.深度学习.STR.NLP.知识图谱等人工智能领域研究.凭借行业领先的技术实力,为扫描全能 ...

  8. 自学Java第二周

    本周学习 一.Java能干些什么? 1.共三个版本:Java SE.Java EE.Java ME Java SE:Java语言的(标准版),用于桌面应用开发,是其他两个版本的基础. Java ME: ...

  9. webpack4.15.1 学习笔记(六) — 代码拆分(Code Splitting)

    目录 入口起点 防止重复 动态导入(dynamic imports) 代码拆分能够将代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件.代码拆分可以用于获取更小的 bundle,以 ...

  10. [oeasy]python0117 文字的演化_埃及圣书体_象形文字_楔形文字

    埃及圣书体 回忆上次内容 两河流域 苏美尔文明 所使用的 楔形文字 不是象形文字     ​   添加图片注释,不超过 140 字(可选)   楔形文字的字型 究竟是怎么来的呢?   巴别塔 苏美尔的 ...