bitflip / bitflip6 使用指南

nettools · 大规模物理网络丢包与 bitflip 检测工具

Usage Guide — 涵盖安装、配置、运行模式及典型使用场景。

目录

1. 概述

bitflipbitflip6 是百度系统部物理网络黑盒监控团队开发的高频 UDP 探测工具,用于检测大规模物理网络中的丢包和 bitflip(比特翻转)错误。支持单向(unidirectional)丢包和改包检测。

bitflip 架构示意图

工作原理:Client 以高频率向 Server 发送 UDP 报文,Server 原样回复。双端独立检测:

单向定位:对比 Client 端和 Server 端的丢包率,可判断丢包发生在正向路径(Client→Server)还是回程路径(Server→Client)。

bitflip

  • IPv4 网络探测
  • 支持多端口并发探测
  • 可配置速率、TOS/DSCP
  • 自动检测本机 IP
  • Client + Server 双端统计

bitflip6

  • IPv6 网络探测
  • 与 bitflip 使用方式一致
  • 支持 IPv6 地址格式
  • 独立的 sonar6 模块
  • Client + Server 双端统计

2. 比特翻转背景

比特翻转(Bit Flip)是数字数据存储或传输中的一种常见错误,指单个二进制位从 0 变为 1,或从 1 变为 0 的现象。这通常由宇宙射线、电磁干扰、硬件老化或过热引起,可能导致静默数据损坏(Silent Data Corruption)或系统崩溃。

现象描述

交换机和服务器的CPU 寄存器、缓存(Cache)、DRAM 内存或 Flash 闪存中的一个或多个位(bit)在没有软件参与的情况下,被硬件故障意外地由 0 反转为 1,或由 1 反转为 0。

TCP/IP Checksum 与比特翻转原理图

主要原因

影响与危害

日益严重:随着芯片工艺缩小(DRAM 单元减小、晶体管密度增大),比特翻转问题正变得越来越频繁。传统防御手段如 ECC(纠错码)内存、奇偶校验(Parity Check)和校验和(Checksum)可以缓解存储层面的问题,但网络传输链路上的比特翻转——在交换机 ASIC、SerDes、光模块等设备中发生的改包——往往更难发现和定位。

举例说明

如果一个代表重要数据的二进制位发生翻转,可能导致严重的错误。例如,计算机内部的一个指令可能因此从正确的代码 13 + 0 意外变成 13 ÷ 0,从而引发崩溃。在网络场景中,交换机端口的单个比特翻转可能导致报文 checksum 校验通过但数据错误,造成上层应用静默错误。

本工具的价值

bitflip / bitflip6 正是为解决网络传输链路上比特翻转的检测和定位而设计的。传统网络监控工具只能检测丢包,无法发现"报文到达但内容被篡改"的情况。本工具通过高频发送已知模式的 UDP 报文,在收端逐字节校验,能够:

Tip:四种互补的 Salt 填充模式(全 1、全 0、交替位、互补交替)确保无论翻转发生在哪个 bit 位,至少有一种模式能检测到。配合五元组记录,可直接定位到故障交换机端口。

3. 安装

从源码编译

# 克隆仓库
git clone https://github.com/baidu/nettools.git
cd nettools

# 编译全部
make compile

# 或单独编译
make build    # 仅 bitflip (IPv4)
make build6   # 仅 bitflip6 (IPv6)

使用 GoReleaser 构建发行版

# 本地测试构建 (snapshot)
make snapshot

# 正式发布 (需要 git tag + GITHUB_TOKEN)
git tag v1.0.0
make deploy
Tip:GoReleaser 自动为 Linux/macOS 的 AMD64 和 ARM64 架构构建二进制文件。产物位于 dist/ 目录。

支持的平台

操作系统架构bitflipbitflip6
LinuxAMD64
LinuxARM64
macOSAMD64
macOSARM64

4. 快速开始

Server 端

# 最简启动 — 自动检测本机 IP,收到未知 Client 自动注册
./bitflip

# 指定服务端 IP
./bitflip -r server -s 10.0.0.1

Client 端

# 指定目标 Server 地址
sudo ./bitflip -r client -s 10.0.0.1

# 指定双端地址
sudo ./bitflip -r client -c 10.0.0.2 -s 10.0.0.1
Note:Client 端通常需要 sudo 权限来设置 IP TOS/DSCP 值。

IPv6 模式 (bitflip6)

# Server
./bitflip6

# Client
sudo ./bitflip6 -r client -s fd00::1

5. 命令行参数

bitflip 和 bitflip6 使用相同的参数格式,区别仅在于地址使用 IPv4 或 IPv6。

短标志长标志默认值说明
-r--roleserver运行角色: client 或 server
-c--client-addr""客户端 IP 地址 (为空则自动检测)
-s--server-addr""服务端 IP 地址 (server 角色可自动检测)
-t--tos64IP TOS/DSCP 值
-n--count0最大发包数 (0 = 不限制)
-d--duration0最大发送时长 (0 = 不限制)
--client-ports43500,43599客户端端口范围 [min,max]
--server-ports43500,43509服务端端口范围 [min,max]
--rate5000每个 span 发包速率
--msglen1024消息体大小 (不含 32 字节头部)
--delay3s统计处理延迟 (等待在途报文)
--verbosefalse丢包时打印详细端口信息 (Client 和 Server 均支持)

6. 使用示例

基础探测

# Server 端 (目标机器) — 无需指定 -c,自动注册 Client
./bitflip -s 10.0.0.1

# Client 端 (发起探测)
sudo ./bitflip -r client -s 10.0.0.1

高速率探测

# 10000 pps, 发送 60 秒后自动停止
sudo ./bitflip -r client -s 10.0.0.1 --rate 10000 --duration 60s

限定发包数量

# 发送 100000 个报文后停止
sudo ./bitflip -r client -s 10.0.0.1 -n 100000

自定义端口范围

# 客户端使用 50000-50099 端口, 服务端使用 50000-50009 端口
sudo ./bitflip -r client -s 10.0.0.1 \
  --client-ports 50000,50099 \
  --server-ports 50000,50009

调整 TOS/DSCP

# 设置 TOS 值为 128 (DSCP CS4)
sudo ./bitflip -r client -s 10.0.0.1 -t 128

大包探测

# 使用 8KB payload 检测 MTU 相关问题
sudo ./bitflip -r client -s 10.0.0.1 --msglen 8192

Verbose 丢包详情

# Client 端开启 --verbose,丢包时打印详细端口信息
sudo ./bitflip -r client -s 10.0.0.1 --verbose

# Server 端开启 --verbose,丢包时打印单向丢包五元组
./bitflip -s 10.0.0.1 --verbose

IPv6 多地址探测

# 探测多个 Server (逗号分隔)
sudo ./bitflip6 -r client -s fd00::1,fd00::2,fd00::3

7. 报文格式

每个 UDP 报文的 payload 由 32 字节固定头部 + N 字节 Salt 填充组成:

Magic 8 bytes Seq 8 bytes Timestamp 8 bytes LastSent 4 bytes LastSrcPort 2 bytes LastDstPort 2 bytes Salt (payload) N bytes (--msglen)
字段大小说明
Magic8 bytes魔术字标识,用于过滤非本工具的报文
Seq8 bytes递增序列号,用于丢包检测和排序
Timestamp8 bytes纳秒级时间戳,用于 RTT 计算
LastSent4 bytes上一个 span 的发送计数(Server 端用于计算单向丢包率)
LastSrcPort2 bytes上一个 span 的起始源端口
LastDstPort2 bytes上一个 span 的起始目的端口
SaltN bytes填充数据,用于 bitflip 校验
精巧设计:端口对的生成是确定性的"里程表"序列(dstPort 递增,溢出时 srcPort 进位)。Server 端仅需 LastSrcPort + LastDstPort + LastSent 三个字段,通过 GetNextPorts 即可还原上一个 span 中每一个包的端口对——从而实现单向丢包的五元组级定位,仅增加 4 字节开销。

8. bitflip 检测原理

Client 使用 4 种 Salt 填充模式(由 seq % 4 决定),覆盖不同的位模式以最大化检测概率:

IndexPattern二进制用途
00xFF11111111全 1 — 检测 1→0 翻转
10x0000000000全 0 — 检测 0→1 翻转
20x5A01011010交替位 — 检测相邻位翻转
30xAA/0x55 交替10101010 / 01010101互补 16-bit word 交替 — 专门检测 TCP/IP Checksum 无法发现的互补翻转

Server 端使用相同的 4 种模式验证返回报文。当检测到 bitflip 时,记录对应五元组 (srcIP:srcPort → dstIP:dstPort + protocol) 以便定位故障链路。

Tip:Salt[3] 的互补交替模式(0xAAAA, 0x5555, 0xAAAA, 0x5555...)专门针对 TCP/IP Checksum 的盲区设计:相邻 16-bit word 在每个 bit 位都是互补的(一个 1 一个 0),完美模拟硬件互补翻转的前置条件。当硬件故障导致同一 bit 列的互补翻转(+2^k 与 -2^k 抵消,Checksum 无感知)时,逐字节 Salt 校验立即可见。

9. 单向丢包检测

bitflip / bitflip6 支持单向(unidirectional)丢包和改包检测,这是其核心能力之一。通过 Client 端和 Server 端的双重统计,可以精确定位丢包发生在网络的哪个方向。

Client 端统计(往返)

Client 发送报文并等待 Server 回包。如果报文在任一方向丢失,均计为丢包。Client 端统计反映的是全链路往返的丢包和 bitflip 情况。日志包含 RTT(往返时延)。

Server 端统计(单向 Client→Server)

Server 端仅统计 Client→Server 方向的丢包和 bitflip。每个报文中的 LastSentLastSrcPortLastDstPort 字段携带 Client 上一时间窗口的实际发送计数和起始端口对,Server 据此计算丢包率并通过确定性的 GetNextPorts 算法还原上一个窗口中每一个包的端口对——实现单向丢包的五元组级定位无需时钟同步或跟踪 Client 发送状态。Server 端日志不包含 RTT(因双端时钟不同步,RTT 无意义)。

精巧设计:Server 仅需每个报文中的 3 个字段(LastSrcPort + LastDstPort + LastSent)加上确定性端口递进算法,即可完整还原上一 span 的所有 (srcPort, dstPort) 对。开启 --verbose 后,Server 端将对比预期端口对与实际收到的端口对,输出丢失的五元组信息。
自动注册:Server 收到未知 Client 的第一个报文时自动创建统计实例,无需通过 -c 参数预配置客户端地址。

方向定位方法

Client 端丢包Server 端丢包丢包方向
正向路径 (Client→Server) 存在丢包
回程路径 (Server→Client) 存在丢包
链路正常
Tip:若 Client 端丢包率远高于 Server 端,说明丢包主要发生在回程路径。若两端丢包率接近,则丢包主要在正向路径。

10. FAQ

Q: 为什么 Client 需要 sudo?

Client 需要设置 socket 的 IP_TOS 选项来标记 DSCP 值,某些系统需要特权才能设置非默认 TOS。

Q: Server 端口范围和 Client 端口范围有什么区别?

Server 端口范围定义 Server 监听的端口集合(默认 10 个端口)。Client 端口范围定义 Client 发送报文时使用的源端口集合(默认 100 个端口)。多端口设计用于覆盖交换机 ECMP 哈希的不同路径。

Q: rate 参数的含义?

--rate 表示每个 span(默认 1 秒)内的发包数量。默认 5000 即 5000 pps。所有端口对共享该速率。

Q: 如何优雅停止?

发送 SIGINT (Ctrl+C) 或 SIGTERM 信号即可。程序会等待 1 秒让在途报文回来后退出。

Q: bitflip 和 bitflip6 可以同时运行吗?

可以。它们使用独立的端口空间,不会冲突。但注意确保端口范围不与其他服务重叠。

Q: 如何判断丢包发生在哪个方向?

对比 Client 端(往返)和 Server 端(单向 Client→Server)的丢包率。若 Server 端有丢包,说明正向路径有问题;若仅 Client 端有丢包而 Server 端正常,说明回程路径有问题。详见"单向丢包检测"章节。

Q: Server 端需要提前配置 Client IP 吗?

不需要。Server 收到未知 Client 的第一个报文时自动注册并开始统计。仍可通过 -c 参数预配置,但已非必需。