IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> packetdrill 深入理解内核网络协议栈的工具集 -> 正文阅读

[网络协议]packetdrill 深入理解内核网络协议栈的工具集

packetdrill 将大事化小

本文是学习和研究内核网络协议栈的一个文笔记录,主要围绕的是一款能帮助大家深入理解内核网络协议栈的工具——packetdrill。packetdrill工具并不能真实的将复杂的内核系统变得更简单,它所做的是让使用者将对象聚焦于一点。换句话说,它构建了一个定量研究某个特定事物的方法。在其他特性保持一致的状态下,不一致的因素成为全局影响因素的导火索。可以说,packetdrill通过另一种形式将大事化小。

深入packetdrill

packetdrill 现支持TCP、UDP、ICMP协议的网络协议栈测试,虽然不多,但已经足够!

QUIC 也可以用packetdrill来测试了。QUIC-mapped-packetdrill

packetdrill 模拟包和验证包

packetdrill是一个测试工具

简洁明了的说,packetdrill工具是通过自定义脚本的形式,探测网络中包传输的实际过程。这里的网络中包传输实际过程指的是真实网络场景下,在内核协议有变化的前提收到的真实包的信息。而用户自定义脚本的意义在于,使用者管控不同的内核网络协议栈状态的变化,任意注入不同格式的数据包和对应预期接收的数据包信息。

这些是深入理解内核网络协议栈的利器。

使用者可以学习和验证内核网络协议栈的某个模块对网络传输的意义。并且深入研究和优化内核网络协议栈的爱好者可以利用packetdrill测试自己的成果是否accept,和对已有的内核网络协议栈bugfix。

packetdrill不算简单,但掌握绝对有意义。

packetdrill 设计

这里并不是必要内容,跳过也不影响本文的阅读和对packetdrill的使用。 但如果你有时间,我希望你能学习一下这个章节,在这里你能得到packetdrill的一些内幕,这对你使用packetdrill绝对是一笔划算的买卖。

网上对packetdrill引擎描述的图很多,我就不贴了!

  1. 执行模块
    这个模块是对自定义脚本的执行,关联的分析器和解释器会将packetdrill格式的脚本变成计算机可读的机器码。
  2. 本地和远端测试
    本地模块是测试在本机网卡和本机构建的一个虚拟网卡之间的交互。本地不是涉及到网络中链路等因素的影响。
    远端模块是测试在两台物理存在的计算机间的交互。packetdrill能测试真实网络中,内核网络协议栈变化的结果。
  3. 时间模块
    脚本是按照时间顺序进行的,每一行脚本语句都会打上时间戳,以被执行模块的解释器翻译成真实时间下的执行动作。

独特的packetdrill脚本语言

packetdrill脚本语言是使用者自定义内核网络协议栈配置和模拟包测试配置在真实网络场景下结果的工具。

注入包和验证包的脚本

packetdrill单独将注入内核网络协议栈的数据包和内核网络协议栈上传预期接收的验证包用一种唯一的脚本语言格式定义。

注入包:

0.100 < S 0:0(0) win 32792 <mss 1000,nop,nop,sack OK,nop,wscale 6>

< 语句是一条注入数据包

0.100 时间戳,后面详细介绍时间模块定义在脚本语句上的不同时间语义。
S SYN包
0:0(0) 起始序号:结束序号(包长度)
win 32792 通告窗口大小
<mss 1000,nop,nop,sack OK,nop,wscale 6> 选项值

0.100 > S. 0:0(0) ack=1 <mss 1460,nop,nop,sack OK,nop,wscale 8>

> 语句是一条预期收到的验证包

S. SYN+ACK包
0:0(0) 起始序号:结束序号(包长度)
ack=1 ack序号
<mss 1000,nop,nop,sack OK,nop,wscale 8> 选项值

实际收到的包会和预期包比较,当发生不吻合的情况,会打印出两条语句的结果。

packetdrill正是通过结果的不同找到内核网络协议栈配置的影响。

系统调用

Linux/Unix的系统调用是用户态到内核态的接口。packetdrill要设计不同的场景,比如测试发送一张图片时,协议栈配置的影响。这个时候模拟太多的包是费力不讨好的,用系统调用的内核函数可以轻松完成这些复杂且麻烦的脚本设计。

// Initialize connection
    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
   +0 bind(3, ..., ...) = 0
   +0 listen(3, 1) = 0

// three-ways handshack 
   +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10>
   +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
   +0 < . 1:1(0) ack 1 win 514

   +0 accept(3, ..., ...) = 4

   +0 open("/tmp/testfile", O_RDONLY) = 5
   +0 sendfile(4, 5, [0], 5) = 5
   +0 > P. 1:6(5) ack 1

用户可以系统调用函数,自定义初始化TCP连接。默认情况下packetdrill把我们完成了这一步,但用户有需求,亦可以自定义。如上面脚本想改变服务端的默认TCP连接,用自定义的int socket=3文件来传输。

找一个最复杂的
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3

socket 调用socket函数
packetdrill中不允许用户改变的参数
SOCK_STREAM, IPPROTO_TCP 用户自定义的参数
= 3 预期得到的系统函数socket调用的返回值

shell命令

+0 `sysctl -q net.ipv4.tcp_timestamps=0`

`` 声明该语句是shell命令,packetdrill下的shell可以在测试脚本下配置测试的机器属性,以及用netstat、ss、top等shell命令查看测试下的机器状态。

sysctl -q net.ipv4.tcp_timestamps=0是关闭测试中TCP报文的时间戳选项。

python命令

packetdrill允许脚本中的python块来打印信息和声明断言,这里的断言是由内核getsockopt函数返回的数据结构TCP_INFO支持的,python可以对TCP_INFO的若干信息断言,判断当前该信息实际是否与预期的有出入。

python语句块用%{ }%声明。
+0 %{assert tcpi_snd_cwnd == 10}%

该语句是断言TCP连接发送方的拥塞窗口是10个包。

时间戳格式

packetdrill每一条语句都有时间戳,脚本里的每一个时间戳都会被packetdrill在测试开始后的真实时间对应执行。

所以,时间戳格式的设计决定你测试脚本的顺利执行。
packetdrill时间戳详解

  • 当你使用绝对时间 0.75,表示脚本测试开始后的时间将发生的事件;
  • 当你使用相对时间 +0.2,表示距离上一个事件发生后的相对时间将发生的事件;
  • 当你使用*, 表示该事件将发生在测试后的任一时间
  • 当你使用0.750~0.900,表示在测试开始后的时间范围内将发生的事件;
  • 当你使用+0.1~+0.2,表示距离上一个事件发生后的相对时间范围内将发生的事件;
  • 当你使用–tolerance_usecs=800,表示在这个误差内允许所有事件发生且正常,特殊的是这个条理不是脚本语言内的,而是通过命令行执行的。
  • 当你使用0.750…0.900,表示阻塞将在该时间段一直进行。

协议栈协议支持

学习内核网络协议栈也需要一些特殊的协议支持,方便在该协议启动的状态下,测试配置对该状态下数据包传输的影响。

IPv4和IPv6

内核网络协议栈中有两种不同的网络协议,IPv4和IPv6。packetdrill支持IPv4、IPv6,以及IPv4协议的IPv6套接字。

当需要分别探究配置对IPv4和IPv6的影响,或者仅测试一种网络协议参与的脚本时,packetdrill可以显示化的通过命令行配置。

--ip_version=ipv4 是脚本在IPv4下执行;
--ip_version=ipv6 是脚本在IPv6下执行;
--ip_version=ipv4-mapped-ipv6 是脚本在IPv4协议和IPv6套接字下执行;

Path MTU

Path MTU协议能提高传输效率,发现网络中最大被允许的MTU值。Packetdrill支持PMTU Discovery,意味着能够显式得到当前状态下被允许的最大MTU值,它会通过ICMP协议通告端设备。

ECN

ECN协议是显示拥塞标识,通过IP报文的两个ECN位判断当前网络的拥塞状态。packetdrill支持ECN协议,代表着开启ECN,端设备能够显式地得知当前网络的拥塞状态。这对研究网络拥塞无疑是一种好的讯息。

安装和执行

packetdrill的安装很简单,可以直接按照google的官方文档来配置。

sudo apt install git gcc make bison flex python
git clone https://github.com/google/packetdrill.git
cd packetdrill/gtests/net/packetdrill
./configure
make
cd …
./packetdrill/run_all.py -S -v -L -l tcp/

详情可见测试工具: packetdrill.

安装和简单测试完成。

如果你想packetdrill本地运行测试脚本,你至少需要./packetdrill foo.pkt。

如果你想远端运行,请在客户端和服务端分别安装packetdrill,然后:
申请根目录权限
客户端至少需要 ./packetdrill --wire_client --wire_server_ip=XXX foo.pkt
服务端至少需要 ./packetdrill --wire_server foo.pkt

如果你要添加什么配置,./packetdrill --help将展示出你可以添加配置的选项。

参考文献:

https://github.com/google/packetdrill
https://www.usenix.org/system/files/login/articles/10_cardwell-online.pdf
https://github.com/google/packetdrill/blob/master/syntax.md

先告一段落吧,如果你有兴趣使用packetdrill,联系我,我们一起进步!问题不大!!!

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:37:38  更:2021-11-28 11:39:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:41:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码