网络测试【免费下载链接】clumsyclumsy makes your network condition on Windows significantly worse, but in a controlled and interactive manner.项目地址https://gitcode.com/gh_mirrors/cl/clumsy点击查看免费下载导读clumsy 是一款运行在 Windows 上的开源网络故障注入Network Fault Injection工具它利用 WinDivert 内核级数据包捕获/注入能力在系统层面拦截真实网络流量按需执行延迟、丢包、篡改、限速等操作后再放行从而可控地让网络变得更糟。本指南以 README.md 为骨架结合 src 目录下的源码实现与 etc/config.txt 过滤器预设完整讲解其工作原理、过滤规则、八个故障注入模块的参数语义、命令行调用方式以及本地验证方法帮助你用它追踪坏网络下的怪异 Bug或评估应用在弱网环境下的表现。本文所描述的能力、参数范围与行为均以当前仓库clumsy 0.3参见 common.h 中CLUMSY_VERSION的实际源码与配置文件为准。一、它是什么让网络受控地变差的调试利器README 用一句话概括了工具定位clumsy makes your network condition on Windows significantly worse, but in a managed and interactive manner——即以可控且可交互的方式让 Windows 上的网络状况显著变差。其技术路线非常直接借助 WinDivert 停止流转中的网络数据包stops living network packets并将其捕获按需施加 lag延迟/ drop丢包/ tamper篡改等操作再把它们发送出去send them away。用途也很明确追踪与坏网络相关的诡异 Bug在弱网/劣化连接下评估你的应用。与常见方案模拟器、代理、DNS 劫持等相比README 特别强调它具备以下特性无需安装No installation绿色软件解压即用无需代理配置也无需改动应用代码不依赖任何代理层系统级网络捕获对任何应用生效捕获发生在系统网络栈层面而不是某个进程内部离线本地回环也能用例如 localhost 到 localhost 的连接同样可以被捕获和劣化应用持续运行的同时clumsy 可以随时开始/停止无需重启被测应用交互式控制劣化程度提供足够的可视反馈让你随时知道当前正在发生什么。从源码结构看这一随时启停的能力由 src/main.c 的uiStartCb/uiStopCb实现点击 Start 后调用divertStart()启动 WinDivert 句柄并创建后台线程点击 Stop 后调用divertStop()关闭句柄、等待线程退出整个过程被测进程无感知。二、核心工作原理从拦截到放行的完整数据通路2.1 WinDivert内核级数据包拦截引擎clumsy 的捕获能力完全依赖 WinDivert仓库在 external 目录内置了WinDivert-2.2.0-A/B/C三份发行包。WinDivert 允许用户态程序从网络栈中拦截数据包修改后再重新注入reinject。clumsy 在这一层之上构建了完整的数据包处理管线捕获WinDivertRecv从内核持续读取匹配过滤器的数据包排队捕获到的包被包装成PacketNode节点追加进双向链表处理按模块注册顺序由各故障注入模块对链表中的包逐个施加操作发送处理完的包通过WinDivertSend重新注入回网络栈。这一流程对应 src/divert.c 的divertReadLoop接收循环与 src/divert.c 的divertClockLoop时钟循环接收线程每捕获一个包就挂到链表上并触发一次消费步骤时钟线程则以 40ms 为周期CLOCK_WAITMS见 src/divert.c反复消费链表确保即使没有新包到达滞留包也能被及时放行保持网络响应性。两个线程通过互斥锁mutex串行化对链表的访问。2.2 数据包节点模块间流转的载体src/common.h 定义了PacketNode结构typedef struct _NODE { char *packet; // 原始包数据 UINT packetLen; // 包长度 WINDIVERT_ADDRESS addr; // WinDivert 地址信息含方向 Outbound/Inbound DWORD timestamp; // 时间戳仅 Lag 模块用到创建节点时不填 struct _NODE *prev, *next; // 双向链表指针 } PacketNode;src/packet.c 提供了createNode/freeNode/insertBefore/insertAfter/appendNode/popNode等链表原语所有模块都通过这套接口搬运数据包。源码注释也坦承在循环里用 malloc 不是性能最佳方案src/packet.c但对调试工具而言可接受。2.3 模块调度严格有序的处理管线src/main.c 用数组定义了 8 个模块的处理顺序数组顺序即处理优先级Module* modules[MODULE_CNT] { lagModule, // 延迟 dropModule, // 丢包 throttleModule, // 节流 dupModule, // 重复 oodModule, // 乱序 tamperModule, // 篡改 resetModule, // TCP RST bandwidthModule, // 带宽限制 };每次消费步骤divertConsumeStep见 src/divert.c会遍历所有模块模块开启且上次未开启时调用其startUp()模块关闭时调用closeDown()并允许其冲刷缓冲的包每个模块的process()返回是否有包被处理用于点亮 GUI 中的状态指示灯。2.4 方向控制Inbound / Outbound 语义每个模块都带 Inbound / Outbound 复选框由 src/common.h 的checkDirection()统一判断static INLINE_FUNCTION BOOL checkDirection(BOOL outboundPacket, short handleInbound, short handleOutbound) { return (handleInbound !outboundPacket) || (handleOutbound outboundPacket); }也就是说Inbound 勾选 处理入站包Outbound 勾选 处理出站包。注意源码与界面注释src/main.c都特别强调捕获 localhost回环流量时过滤器不能包含 inbound 条件例如想过滤回环 UDP 必须写成udp and outbound而不是udp详见下文过滤器章节。三、过滤器config.txt 预设与 WinDivert 过滤语言3.1 过滤器的加载与格式启动时clumsy 会从可执行文件同目录下的 etc/config.txt 加载过滤器预设见 src/main.c 的loadConfig()。文件格式为filter-name:filter-text每行一条#开头为注释。加载成功后预设会填充进 GUI 顶部的 Presets 下拉框选中某条预设即自动填入过滤器输入框。提示构建脚本会在编译后把 etc/config.txt 拷贝到输出目录见 genie.lua因此最终随程序分发的是拷贝副本你可以在其中自定义常用过滤器。3.2 官方预设逐条解析完整继承配置文件开头明确指出过滤器语法遵循 WinDivert 过滤语言Filter Language。以下为仓库自带预设及语义回环Loopback流量——注释特别说明回环包只能用outbound条件过滤localhost ipv4 all: outbound and loopback localhost ipv4 tcp: tcp and outbound and loopback localhost ipv4 udp: udp and outbound and loopback更通用的方向过滤all sending packets: outbound # 所有出站包 all receiving packets: inbound # 所有入站包针对特定 IP 的过滤all ipv4 against specific ip: ip.DstAddr 198.51.100.1 or ip.SrcAddr 198.51.100.1 tcp ipv4 against specific ip: tcp and (ip.DstAddr 198.51.100.1 or ip.SrcAddr 198.51.100.1) udp ipv4 against specific ip: udp and (ip.DstAddr 198.51.100.1 or ip.SrcAddr 198.51.100.1)针对特定端口的过滤注意同时覆盖 TCP 与 UDP 的源/目的端口all ipv4 against port: tcp.DstPort 12354 or tcp.SrcPort 12354 or udp.DstPort 12354 or udp.SrcPort 12354 tcp ipv4 against port: tcp and (tcp.DstPort 12354 or tcp.SrcPort 12354) udp ipv4 against port: udp and (udp.DstPort 12354 or udp.SrcPort 12354)IPv6 支持注释指出 IPv6 虽受支持但通常不太实用ipv6 all: ipv6自定义预留被注释掉供你按需启用# http requests ONLY (data transmit on other ports): outbound and tcp.DstPort 803.3 过滤器在源码中的落地过滤器输入框回调uiFilterTextCbsrc/main.c会在你手动编辑过滤器时取消 Presets 下拉框选中态uiListSelectCbsrc/main.c在选中某条预设时把对应 filter-text 填入输入框Start 时输入框文本原样传给divertStart(filter, buf)最终作为WinDivertOpen的过滤器参数src/divert.c。若语法错误WinDivertOpen返回ERROR_INVALID_PARAMETER界面提示 filter syntax error若打开设备失败如非管理员运行则提示错误码并要求以管理员身份运行。另外src/main.c 还内置了兜底逻辑当 config.txt 缺失或内容为空/格式非法时自动填入一条回环包过滤器outbound and ip.DstAddr 127.0.0.1 and ip.DstAddr 127.255.255.255保证程序始终有一个可用的起始过滤器。四、八大故障注入模块参数、取值范围与实现原理以下参数取值范围与默认值均取自各模块源码。所有百分比类参数内部以 [0, 10000] 的整数表示calcChance见 src/utils.c界面显示为百分比并在 [0.0, 100.0] 间自动归一。4.1 Lag —— 网络延迟参数Delay(ms)范围 [0, 15000]默认 50msInbound / Outbound 方向开关默认全开。实现src/lag.c按方向筛选符合条件的包记录入队时间戳timeGetTime()放入专用缓冲区当当前时间 时间戳 lagTime时把包放回发送队列实现固定时延。缓冲区最多保留 2000 个包KEEP_AT_MOST一旦打满会一次性冲刷 800 个FLUSH_WHEN_FULL防止无界积压。关闭模块时会冲刷全部滞留包。4.2 Drop —— 丢包参数Chance(%)默认 10.0方向开关默认全开。实现src/drop.c命中概率且方向匹配的包直接freeNode销毁即永久丢失是模拟无线网络丢包最直接的途径。概率判定由calcChance完成chance 10000时必定丢弃否则以rand() % 10000 chance判定。4.3 Throttle —— 节流/突发中断参数Timeframe(ms) 范围 [0, 1000]默认 30、Chance(%)默认 10.0、Drop Throttled 开关、方向开关。实现src/throttle.c以概率触发一次节流窗口——在 time frame 期间持续把包收进缓冲区最多 1000 个窗口结束时间差超过 frame 或缓冲打满后要么统一放行clearBufPackets要么若勾选Drop Throttled则统一丢弃dropBufPackets。这一功能模拟的是网络短暂中断后流量突发/被丢弃的现象。4.4 Duplicate —— 数据包重复参数Count副本数范围 [2, 50]默认 2Chance(%) 默认 10.0方向开关。实现src/duplicate.c对命中的包调用createNode克隆count-1份并通过insertBefore插在原包之前形成连续的重复包序列。4.5 Out of order —— 乱序参数Chance(%) 默认 10.0方向开关。实现src/ood.c两种策略——链表只有一个包时以概率把该包摘下暂存oodPacket等后续包到来或超过KEEP_TURNS_MAX10 轮放弃等待后再放回队首造成该包相对后包乱序链表有多个包时以概率对相邻两个方向匹配的包执行swapNode交换位置。关闭模块时会把暂存的包放回队列避免丢包。4.6 Tamper —— 数据篡改参数Chance(%) 默认 10.0、Redo Checksum 开关默认开启方向开关。实现src/tamper.c先用WinDivertHelperParsePacket解析出 TCP/UDP 载荷payload用 8 种循环位模式0x64, 0x13, 0x88, 0x40, 0x1F, 0xA0, 0xAA, 0x55对载荷做异或破坏——短包≤4 字节整体篡改长包只篡改中间 1/4 载荷以避开头部/尾部的校验和区域。若勾选 Redo Checksum篡改后调用WinDivertHelperCalcChecksums重算校验和源码注释 FIXME 提示校验和重算仍可能存在问题实战中如遇异常可尝试关闭该开关。4.7 Set TCP RST —— 重置 TCP 连接参数Chance(%) 默认 0RST next packet按钮方向开关。实现src/reset.c命中后把 TCP 头中的Rst标志位置 1 并重算校验和模拟连接被对方 RST 强行中断。与其它模块不同它默认概率为 0而是提供一个RST next packet按钮resetSetRSTNextButtonCb——点击后setNextCount递增下一个方向匹配的 TCP 包无论概率如何都会被置 RST适合做按下即中断的确定性演示。注意它要求包长大于 IP 头 TCP 头的最小尺寸TCP_MIN_SIZE因此只作用于真实 TCP 数据包。4.8 Bandwidth —— 带宽限制参数Limit(KB/s) 范围 [0, 99999]默认 10KB/s方向开关。实现src/bandwidth.c实现了一个滑动窗口速率统计器CRateStats窗口 1000ms对每个包先计算当前窗口已累计字节数 本包大小若超过limit * 1024则丢弃该包即超限即丢非整形/排队否则计入累计。limit 0时理论上会丢弃所有包源码注释allow 0 limit which should drop all。五、命令行参数模式脚本化与自动化clumsy 支持纯命令行驱动方便放进测试脚本。解析逻辑在 src/utils.c 的parseArgs()格式为--key value成对出现值会被写入 IUP 全局变量随后在 GUI 初始化阶段通过setFromParameter()src/utils.c反向应用到各控件并手动触发其回调因为 IUP 不会自动触发从而同步到模块参数。各模块的关键字即模块shortName如下模块短名可用参数Laglag--lag on/off总开关、--lag-inbound on/off、--lag-outbound on/off、--lag-time 毫秒Dropdrop--drop on/off、--drop-inbound on/off、--drop-outbound on/off、--drop-chance 百分比Throttlethrottle--throttle on/off、--throttle-inbound on/off、--throttle-outbound on/off、--throttle-chance 百分比、--throttle-frame 毫秒Duplicateduplicate--duplicate on/off、--duplicate-inbound on/off、--duplicate-outbound on/off、--duplicate-chance 百分比、--duplicate-count 副本数Out of orderood--ood on/off、--ood-inbound on/off、--ood-outbound on/off、--ood-chance 百分比Tampertamper--tamper on/off、--tamper-inbound on/off、--tamper-outbound on/off、--tamper-chance 百分比、--tamper-checksum on/offSet TCP RSTreset--reset on/off、--reset-inbound on/off、--reset-outbound on/off、--reset-chance 百分比Bandwidthbandwidth--bandwidth on/off、--bandwidth-inbound on/off、--bandwidth-outbound on/off、--bandwidth-bandwidth KB/s此外还支持两个全局参数--filter 过滤器表达式设置起始过滤器见 src/main.c--timeout 秒程序运行指定秒数后自动退出src/main.c 与uiTimeoutCb适合无人值守的自动化测试。示例以 20% 概率丢弃 UDP 回环出站包并延迟 200ms运行 60 秒后退出clumsy.exe --drop on --drop-chance 20 --drop-inbound off --lag on --lag-time 200 --lag-inbound off --filter udp and outbound and loopback --timeout 60说明GUI 模式仍会启动无界面隐藏机制且参数化模式启动时会跳过 UAC 弹窗的交互等待见 src/main.c 传入parameterized给tryElevate。参数必须严格成对出现格式错误会直接退出fail fast。六、GUI 交互与状态反馈主界面由 IUP 构建见 src/main.c分为两部分Filtering 区过滤器输入框 Start/Stop 按钮 Presets 下拉框左侧有一个 8x8 的圆点状态图标Functions 区8 个模块各占一行左侧为模块开关Toggle与指示灯右侧为参数控件未启用时参数控件置灰uiToggleControlssrc/main.c。状态灯通过 200ms 定时器uiTimerCbsrc/main.c刷新三种颜色语义明确灰色圆点空闲无数据包被处理绿色圆点该模块最近一次消费步骤中确实处理了数据包processTriggered置位或数据包发送成功SEND_STATUS_SEND红色圆点数据包注入失败SEND_STATUS_FAIL例如WinDivertSend失败。底部状态栏会显示当前状态例如 Started filtering. Enable functionalities to take effect. / Stopped. To begin again, edit criteria and click Start.。七、运行前提与注意事项必须以管理员权限运行WinDivert 打开过滤设备需要管理员令牌。src/elevate.c 中的tryElevate()会检测权限IsRunAsAdmin不足时通过ShellExecuteEx以runas动词自我提权用户拒绝 UAC 或提权失败则弹窗并退出。支持的最低系统为 Windows Vista 及以上IsWindowsVistaOrGreater检查README 声明支持 Windows 7/8/10仓库 manifestetc/clumsy.manifest声明兼容 Vista/7/8/8.1/10。不要混用 32 位与 64 位check32RunningOn64src/main.c检测到32 位程序运行在 64 位系统时会弹窗要求改用 64 位版本并退出因此请选择与操作系统位数匹配的构建。单实例限制checkIsRunning()src/main.c通过命名事件Global\CLUMSY_IS_RUNNING_EVENT_NAME防止同时运行多个实例。回环流量的 inbound 限制捕获 localhost 流量时过滤器不能包含 inbound 条件应写成如udp and outbound and loopback。inbound 注入的已知局限源码注释src/divert.c指出入站方向注入成功率偏低并针对入站 ICMP 包提供了转为出站重发的规避逻辑涉及 inbound 注入异常时这是已知的底层限制而非配置问题。八、从源码构建项目使用 GENie。依赖库已在仓库内置WinDivertexternal/WinDivert-2.2.0-A 等与 IUP 3.30external/iup-3.30_Win64_dll16_lib 等四个变体链接目标包括WinDivert、iup、comctl32、Winmm、ws2_32genie.lua编译后自动拷贝 WinDivert 的 dll/sys、iup.dll 与 config.txt 到输出目录genie.lua产物即绿色可运行。Release 版以 WindowedApp 构建无控制台窗口日志走OutputDebugStringDebug 版为 ConsoleAppLOG宏直接 printf见 src/common.h便于开发期观察处理过程。九、自带的本地验证脚本仓库 scripts 目录提供了基于ncat端口 9911的本地验证方案用于肉眼观察各类劣化效果scripts/send_udp_nums.py持续向目标主机发送递增编号的数据包每包一串-默认每 100ms 一发--nosleep为满速--tcp切换为 TCP可配合-s调整发送周期scripts/start_nums_cs.bat启动 ncat UDP 服务器ncat -u -l -C localhost 9911并同时运行编号发送器scripts/start_nums_cs_tcp.bat同上但使用 TCPscripts/start_nums_cs_nosleep.bat满速 UDP 版本。使用方法分别运行start_nums_cs.bat发送端与ncat -u -l -C localhost 9911接收端同时启动 clumsy 并应用localhost ipv4 udp: udp and outbound and loopback过滤器再开启 Lag/Drop 等模块——观察接收端序列号的延迟、缺失、重复或乱序即可直观验证各模块效果。十、Licenseclumsy 以 MIT 许可证发布见 LICENSE源码可自由查看、修改与分发。参考文件索引项目总览README.md过滤器预设etc/config.txt主程序与 GUI、模块调度src/main.cWinDivert 封装与数据通路src/divert.c、src/packet.c八个功能模块src/lag.c、src/drop.c、src/throttle.c、src/duplicate.c、src/ood.c、src/tamper.c、src/reset.c、src/bandwidth.c参数解析与概率判定src/utils.c权限提升src/elevate.c构建工程描述genie.lua本地验证脚本scripts/send_udp_nums.py、scripts/start_nums_cs.bat、scripts/start_nums_cs_tcp.bat、scripts/start_nums_cs_nosleep.bat赞分享网络测试【免费下载链接】clumsyclumsy makes your network condition on Windows significantly worse, but in a controlled and interactive manner.项目地址https://gitcode.com/gh_mirrors/cl/clumsy点击查看免费下载相关推荐Litmus 混沌工程实战pod-network-partition 网络分区故障注入指南Litmus 混沌工程实战pod network partition 网络分区故障注入指南 本文基于 Litmus 开源仓库中 pod network par云原生运维可观测性上一篇30分钟让iPhone跑起Minecraft Java版PojavLauncher iOS上手全记录下一篇Wan2.2开源MoE架构重构视频生成消费级显卡实现电影级创作创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考