Jay's some notes
type: channel
link: https://notes.leconiot.com/
description: 重剑无锋，大巧不工
items: ChatTerm —— 把终端会话当聊天来管理
items: 从 FACK 到 RACK-TLP：TCP 丢包检测机制的演进与现代化之路
items: TLS 1.3 新特性剖析
items: NS-3 Wi-Fi 仿真模型测试
items: NS-3 Wi-Fi 仿真模型概述
items: GCC 隐藏符号
items: Linux TC
items: GAP Bond Manager 和 LE 安全连接
items: 聊聊 GCC 中的 int 类型和字节对齐
items: Thread 路由协议

ChatTerm —— 把终端会话当聊天来管理
type: item
date: 2026-05-22T11:27:13+08:00
description: 这两年写代码的方式变了。以前是一个终端、一个项目、一条命令跑到底。现在桌面上常年开着三四个 AI 编程 Agent —— Claude Code 在改一个模块,Codex 在另一个仓库跑重构,Kiro CLI 在补测试,旁边还挂着 SSH、构建、日志。然后传统终端就有点撑不住了。Tab 和窗口多到记不清哪个是哪个;哪个 Agent 跑完了在等我、哪个还在 thinking、哪个报错停住了,全靠一个个点过去看;AI 会话、普通 Shell、日志窗口混在一排 Tab 里,切换成本高得离谱;手一抖关掉终端,一堆上下文就没了。但是微信我们可以同时和十几个人聊天:谁有新消息就亮个红点,点进去就是完整上下文。为什么终端会话不能这样管?于是有了 ChatTerm。把终端会话当成聊天对话ChatTerm 是一个终端工作区 —— 在真实终端之上,加了一层 IM 风格的会话管理。一句话:把终端会话,当成聊天软件里的对话来管。左边一列 IM 风格的会话列表,每个会话有头像、有最新输出预览、有未读红点;它能认出哪个会话是 Claude Code、哪个是 Codex、哪个是 Kiro、哪个只是普通 Shell,自动配上对应的头像和状态;它能看出一个 Agent 此刻是在 thinking 还是 idle —— 侧边栏一眼就分清谁在干活、谁在等你回话;Agent 回了什么,侧边栏直接给你回复预览,不用切进去看。预览这块,我没用"截屏 OCR"那种脆办法。Claude Code、Codex、Kiro 都支持在 Stop、PostToolUse 这类事件上挂 hook —— ChatTerm 就在这些 hook 上挂一个小脚本,通过命名管道(FIFO)把事件喂回应用。干净、实时;而且 ChatTerm 没开着的时候,消息直接丢弃,绝不会卡住你的 Agent。情绪价值:萌宠头像初次之外，还是提供了情绪价值 —— 萌宠头像。一键就能把头像方块换成会眨眼、会摇摆、会喊「!」的小动物,表情和气泡还跟着会话状态走:thinking、asking、error、done、idle、有未读…… 各有各的反应。盯一整天 AI 写代码,侧边栏有只小动物陪你一起 thinking。还有些顺手的细节会话持久化 —— 重启后会话列表自动恢复,Agent 会话还能 --resume 接上次的上下文;⌘K 搜索 —— 按名字、工作目录,甚至按输出内容,快速跳到某个会话;主题 —— 内置几套配色,macOS 还能直接导入系统 Terminal 的 .terminal 主题。技术上,前端是 React 19 + TypeScript + xterm.js,后端 Rust + Tauri 2 + portable-pty —— 一个轻量的原生应用,不是又一个 Electron 壳。试试看macOS、Linux、Windows 都有包。最快的方式是一行装好 App,再一行配 Agent hooks:curl -fsSL https://raw.githubusercontent.com/chatterm/chatterm/main/scripts/install-remote.sh | bash curl -fsSL https://raw.githubusercontent.com/chatterm/chatterm/main/scripts/setup-hooks.sh | bash源码、Releases、各平台详细安装说明都在 GitHub —— github.com/chatterm/chatterm。如果你也同时盯着好几个 AI Agent 干活,欢迎试试,也欢迎来提 issue。

从 FACK 到 RACK-TLP：TCP 丢包检测机制的演进与现代化之路
type: item
date: 2025-07-09T15:40:00+08:00
description: 在传输控制协议（TCP）数十年的演进中，丢包检测与恢复机制始终是影响传输性能的核心环节。从最初依赖序列号判断丢包的 Reno 模式，到引入选择性确认的 SACK，再到基于时间判定的 RACK，乃至进一步强化的 RACK-TLP，TCP 的恢复能力经历了逐步现代化的升级。本文将带你从理论层面，深入理解 TCP 的四种关键丢包检测机制：FACK、SACK、RACK 与 RACK-TLP，并对比它们的工作原理、适用场景与演进关系。TCP 丢包检测：为什么重要？丢包是 TCP 面临的常见网络问题。能否及时发现丢包并快速恢复，直接决定了 TCP 在以下场景中的表现：弱网或移动网络（丢包率高、时延抖动大）；数据中心高吞吐场景（对恢复速度敏感）；中间设备存在乱序、ACK 压缩行为。传统 TCP 采用 RTO（Retransmission Timeout） 机制来兜底触发重传。但初始 RTO 延迟高达 1 秒，误判多，恢复慢，成为瓶颈。因此，TCP 社区不断探索更快、更精准的丢包检测算法。SACK：Selective Acknowledgment（选择性确认）原理：接收方在 ACK 中显式告诉发送方：“我已经收到哪些数据段”，而不是仅告诉“收到到哪了”。例如：如果收到了第 1、2、5 段，SACK 可以告诉发送方：我收到了 [1-2] 和 [5]，中间 [3-4] 丢失。优点：精确指出哪些段被接收；适用于多段丢包场景；避免不必要的重复重传。局限：虽然能知道“哪里没收到”，但仍依赖序列号判断丢包；容易受到网络乱序、ACK 压缩的干扰，误判丢包或延迟重传。FACK：Forward Acknowledgment（前向确认）原理：FACK 在 SACK 的基础上进一步演化。它不仅看 SACK 报告了哪些段，还估算：“接收方到底收到了多少字节？”通过前向确认值（Forward ACK），FACK 推测数据流的最前进位置，从而判断哪些段在这个位置之前却没被确认，更可能丢失。优点：提升丢包恢复的粒度与速度；可以更准确判断哪些段未收到。局限：依然依赖序列号推断；在中间设备导致乱序或 ACK 抖动时仍可能误判。RACK：Recent Acknowledgment（基于时间的确认）定义于 RFC 8985原理：RACK 完全抛弃了“序列号先后”来判断丢包，转而使用“发送时间”作为核心依据。核心思想：如果一个数据段比其他段更早发送，但对方先确认了后发的数据，那么早发未确认的很可能丢了。举个例子：第 10、11、12 段几乎同时发送；ACK 收到 11 和 12，唯独没收到 10；RACK 判断：第 10 段被丢了，不等 RTO，直接重传。优点：更快发现丢包；不受乱序、ACK 压缩等影响；大幅提升弱网或数据中心 TCP 的表现。前提：TCP 栈需准确记录每个段的发送时间；依赖 SACK 辅助判断哪些段被确认。TLP：Tail Loss Probe（尾部丢包探测）原理：TLP 设计是为了解决“尾部最后几个数据段被丢，但连接进入沉默”的问题。在传统 TCP 中，这种场景只能等待 RTO 超时，可能导致 1 秒以上延迟！TLP 的做法是：检测连接是否在“尾部”安静阶段；主动发一个探测包（probe）来“敲门”；如果 ACK 回来，一切正常；如果没有，尽快触发重传。优点：避免长时间挂起；恢复速度远快于 RTO。RACK-TLP：现代 TCP 的黄金组合RACK + TLP = 快速、鲁棒的 TCP 丢包检测与恢复体系RACK 提供 时间驱动的准确丢包检测，TLP 提供 尾部沉默保护，两者组合应对大多数网络复杂场景。这种组合是目前 Google、Facebook、AWS 等大规模生产网络中的默认选择，也正逐步成为现代 TCP 栈的主流机制。对比总结特性SACKFACKRACKRACK-TLP丢包判断依据序号 + SACK序号 + 前向确认发送时间发送时间 + 探测包抗乱序能力一般一般强强响应速度中等较快快快速且稳健实现复杂度中较高高高是否现代推荐（已基础）（中间形态）（现代默认）（最佳实践）TCP 的丢包检测机制已经从最早的基于序号推测，演进到现在以“发送时间 + 探测包”为核心的智能模型：FACK 是对 SACK 的增强，更好地衡量未确认数据；RACK 是范式转移，开创“时间驱动的丢包检测”；TLP 补齐了边界条件，保护连接不被挂起；RACK-TLP 组合，代表了现代 TCP 的最佳丢包恢复路径。

TLS 1.3 新特性剖析
type: item
date: 2025-04-13T16:43:00+08:00
description: 这里结合 RFC8446，MbedTLS 源码， Wireshark 抓包对 TLS 1.3 几个重要特性做深入剖析。一 特性剖析1. TLS 1.3 VS 1.2https://datatracker.ietf.org/doc/html/rfc8446#section-1.2 。TLS 1.3 对比 TLS 1.2 的主要差异。项目条目TLS 1.2TLS 1.3加密与算法对称加密算法支持多种，包括已废弃的 CBC、RC4仅支持 AEAD 算法（如 AES-GCM、ChaCha20-Poly1305） 密钥派生算法自定义复杂结构 KDF使用统一的 HKDF（HMAC-based Extract-and-Expand） 密钥交换机制支持 RSA、DH、ECDHE，包括静态密钥移除静态 RSA/DH，统一使用 ECDHE，具备前向安全 签名算法支持RSA、DSA、ECDSARSA、DSA、ECDSA安全改进前向安全（PFS）可选，取决于是否使用 (EC)DHE所有公钥交换均具备前向安全 报文完整性保护加密和 MAC 分离（MAC-then-encrypt）使用 AEAD（集成加密+认证） 证书扩展等隐私保护扩展字段如 SNI 以明文发送扩展通过 EncryptedExtensions 加密传输握手机制握手消息加密ServerHello 后部分消息仍明文ServerHello 后全部握手消息加密 握手流程结构含 ServerHelloDone、ChangeCipherSpec精简状态机，移除冗余消息 0-RTT 数据支持不支持支持 0-RTT，允许部分早期数据发送（有安全限制）会话恢复会话恢复机制Session ID / Session ticket 两种方式统一为 PSK-based 会话恢复，使用 SessionTicket + Binder PSK 模式较少使用明确支持 PSK-only / PSK + ECDHE兼容性机制版本协商通过 ClientHello.version，存在兼容问题使用 extension 提供版本列表，增强兼容性 压缩与 DSA支持 TLS-level 压缩、支持 DSA移除压缩与 DSA，避免压缩攻击重点介绍全新特性前。介绍下 TLS 1.3 的完整握手流程。https://datatracker.ietf.org/doc/html/rfc8446#section-2如上完整握手流程，包含密钥交换（Key Exchange）和双向认证（Authentication，可选）流程。对于密钥交换仅支持 ECDHE。对于认证支持证书认证和 PSK 认证，当然也可以不做认证。如上 KE 和 Auth 流程组合，TLS 1.3 共支持如下5种模式。握手模式描述完整握手ECDHE使用 ECDHE 密钥交换，无认证。 PSK ECHDE使用预设密钥 PSK 快速认证 + ECDHE 密钥交换 证书 ECHDE使用证书进行身份验证 + ECDHE 密钥交换会话恢复PSK ECDHE基于 Session Ticket 快速恢复会话，流程与 PSK-ECDHE 类似，区别在于 PSK 来源不同：完整 PSK-ECDHE 使用预共享凭据；会话恢复则使用前次握手后协商出的临时 PSK。 PSK Only基于 Session Ticket 快速恢复会话，但是不做 ECHDE。需要说明的是，尽管不做 ECHDE，但是还有一个简单 KE，同 TLS 1.2 PSK KE 原理相似。在后面章节会详细介绍。2. 安全增强2.1 PSK KE VS PSK ECHDETLS 1.2 PSK KE 对比 TLS 1.3 PSK ECDHE 一个安全特性就是前向安全。 前向安全确保了长期密钥泄露不会影响历史会话的安全性。以下是 TLS 1.2 PSK KE 与 TLS 1.3 PSK ECDHE 的握手流程对比。在密钥交换过程中，最大的区别在于是否引入了临时椭圆曲线 Diffie-Hellman 的密钥交换。注意：如上为简化公式。完整的密钥派生会在后面详细介绍。在 TLS 1.2 PSK KE 模式下，会话密钥完全依赖预共享密钥（PSK），如果 PSK 泄露，攻击者可以离线解密之前或当前的通信内容。提示：ClientRandom 和 ServerRandom 为明文交换，所以 PSK 泄漏，MasterSecret 就会泄漏。在 TLS 1.3 PSK ECDHE 模式下，引入了临时的 ECDHE ClientShare 和 ServerShare 公钥交换，即使 PSK 被泄露，也无法恢复会话密钥，因此提供了前向安全性。提示：尽管 ClientShare、ServerShare、ClientRandom、ServerRandom 都是明…

NS-3 Wi-Fi 仿真模型测试
type: item
date: 2024-11-22T01:49:00+08:00
description: 本文翻译自，https://www.nsnam.org/docs/release/3.43/models/html/wifi-testing.html#spectrumwifiphy 。目前，大多数关于测试和验证的文档都存在于出版物中，以下列出了一些参考文献。1 错误模型802.11b 错误模型的验证结果可在以下 技术报告 中查看。需要注意以下两点说明： 上述参考文献中的图 1-4 对应的是 ns-3 NIST 比特错误率（BER）模型。在该论文附录的程序（80211b.c）中，有两个用于生成数据的常量。第一个是分组大小，设置为 1024 字节。第二个是“噪声”，其值设为 7 dB；这一值是通过经验选取的，以使曲线与 CMU 测试床的报告数据最契合。虽然值为 1.55 dB 更符合 CMU 论文报告的 -99 dBm 噪声底限，但噪声系数 7 dB 最适合与 CMU 实验数据拟合。这一默认值 7 dB 是 ns3::YansWifiPhy 模型中的 RxNoiseFigure。更改噪声系数会使曲线向左或向右移动，但不会改变其斜率。可以通过运行 examples/wireless/wifi-clear-channel-cmu.cc 示例程序重现这些曲线。当启用 GNU 科学库（GSL）时，会生成以下图表：802.11b 的清晰信道（AWGN）错误模型。802.11b 的清晰信道（AWGN）错误模型802.11a/g OFDM 错误模型的验证结果可在以下 技术报告 中查看。 可以通过运行 examples/wireless/wifi-ofdm-validation.cc 示例程序重现这些曲线，以下图表展示了 802.11a/g（OFDM）Wi-Fi 的帧错误率（NIST 模型）。802.11a/g（OFDM）Wi-Fi 的帧错误率（NIST 模型）对于 802.11n/ac/ax，可以通过运行 wifi-ofdm-ht-validation.cc、wifi-ofdm-vht-validation.cc 和 wifi-ofdm-he-validation.cc 示例程序生成类似曲线。以下分别展示了 802.11n（HT OFDM）Wi-Fi 的帧错误率（NIST 模型）、802.11ac（VHT OFDM）Wi-Fi 的帧错误率（NIST 模型） 和 802.11ax（HE OFDM）Wi-Fi 的帧错误率（NIST 模型）。但这些曲线目前尚无验证。802.11b 的清晰信道（AWGN）错误模型802.11n（HT OFDM）Wi-Fi 的帧错误率（NIST 模型）802.11ax（HE OFDM）Wi-Fi 的帧错误率（NIST 模型）2 MAC 验证802.11 DCF MAC 层的验证已在 [baldo2010] 中完成。802.11 PCF 的操作通过运行 wifi-pcf 示例（启用 PCAP 文件生成），并使用 Wireshark 观察帧交换得以验证。3 SpectrumWiFiPhySpectrumWifiPhy 实现已通过饱和和分组错误率程序（下文描述）进行验证，其结果与传统的 YansWifiPhy 一致。测试中通过切换这两种物理层实现进行比较。一个基本单元测试通过手动构造的分组注入接收的 PHY 对象，控制每个分组到达的时间和接收功率，并检查接收结果。然而，大多数对 SpectrumWifiPhy 的测试是使用下文描述的示例程序，以及一个独立的 LTE/Wi-Fi 共存研究中完成的（未在此文档中记录）。3.1 饱和性能程序 examples/wireless/wifi-spectrum-saturation-example.cc 允许用户选择 SpectrumWifiPhy 或 YansWifiPhy 进行饱和测试。用户可以通过参数 '--wifiType=ns3::YansWifiPhy' 或 '--wifiType=ns3::SpectrumWifiPhy' 切换物理层类型。输出结果没有差异，这符合预期，因为该测试主要验证的是 DCF，而不是物理层。默认情况下，程序将使用 SpectrumWifiPhy，并在 10 秒内发送饱和 UDP 数据，启用 802.11n 功能。输出显示主流 802.11n 速率（短保护间隔和长保护间隔）的结果：wifiType: ns3::SpectrumWifiPhy distance: 1m index MCS width Rate (Mb/s) Tput (Mb/s) Received 0 0 20 6.5 5.81381 4937 1 1 20 13 11.8266 10043 2 2 20 19.5 17.7935 15110 3 3 20 26 23.7958 2020…

NS-3 Wi-Fi 仿真模型概述
type: item
date: 2024-11-21T23:00:00+08:00
description: 最近太想进步了，开始研究 NS-3 Wi-Fi 仿真模型。本文翻译自，https://www.nsnam.org/docs/models/html/wifi-design.html 。ns-3 节点可以包含多个 NetDevice 对象，就像一台实际的计算机可以包含多个独立的网络接口卡（如以太网、Wi-Fi、蓝牙等）。本章节描述了 ns-3 的 WifiNetDevice 及其相关模型。通过将 WifiNetDevice 对象添加到 ns-3 节点中，可以创建基于 802.11 的基础设施网络和自组织（Ad Hoc）网络模型。1. 模型概览WifiNetDevice 模拟了基于 IEEE 802.11 标准的无线网络接口控制器 [ieee80211]。我们将在后续章节中详细说明，但简单来说，ns-3 提供了以下 802.11 相关模型：基本的 802.11 分布式协调功能（DCF），支持 基础设施模式 和 自组织模式802.11a、802.11b、802.11g、802.11n（支持 2.4 GHz 和 5 GHz 频段）、802.11ac、802.11ax（支持 2.4 GHz、5 GHz 和 6 GHz 频段）以及 802.11be 的物理层MSDU 聚合 和 MPDU 聚合 的 802.11n 扩展，并支持两者组合（两级聚合）802.11ax 的 下行链路 OFDMA（DL OFDMA） 和 上行链路 OFDMA（UL OFDMA）（包括多用户增强分布式协调功能（MU EDCA）参数集的支持）802.11be 的 多链路 发现与设置基于 QoS 的增强分布式协调功能（EDCA）以及 802.11e 的队列扩展支持使用不同的传播损耗模型和传播延迟模型，详细信息请参见 Propagation 章节经验证的分组错误模型和帧检测模型，与链路仿真和其他参考一致多种速率控制算法，包括 Aarf、Arf、Cara、Onoe、Rraa、ConstantRate、Minstrel 和 Minstrel-HT802.11s（网状网络），另见其他章节802.11p 和 WAVE（车联网），另见其他章节ns-3 提供的 802.11 模型尝试准确实现 802.11 规范的 MAC 层功能，同时为 802.11a/b/e/g/n/ac/ax/be 物理层提供基于分组的抽象。在 ns-3 中，节点可以在不同的信道上拥有多个 WifiNetDevice，且 WifiNetDevice 能与其他设备类型共存。通过使用 SpectrumWifiPhy 框架，还可以创建涉及跨信道干扰或单个信道上多种无线技术共存的场景。WifiNetDevice 及其模型的源代码位于目录 src/wifi。实现是模块化的，主要包括三个子层模型：物理层模型（PHY layer models）：模拟具体修正案的物理层操作及通用物理层功能。低层 MAC 模型（lower MAC models）：模拟诸如介质访问（DCF 和 EDCA）、帧保护（RTS/CTS）以及确认（ACK/BlockAck）等功能。在 ns-3 中，低层 MAC 包括一个 帧交换管理器（Frame Exchange Manager） 层级结构、一个 信道访问管理器（Channel Access Manager）、Txop 对象、BlockAckManager 对象和一个 MAC 中间实体（MAC middle entity）。高层 MAC 模型（upper MAC models）：实现 Wi-Fi 中非时间关键的过程，如 MAC 层信标生成、探测和关联状态机，以及一组 速率控制算法。在文献中，这一子层有时称为 高层 MAC（upper MAC），相较于时间关键的硬件实现，它更偏向软件实现。接下来，我们将概述每一层的设计，具体结构如图 WifiNetDevice 架构 所示。对于 802.11be 的多链路设备（MLDs），WifiPhy、FrameExchangeManager 和 ChannelAccessManager 的实例数量与链路数量相同。WifiNetDevice 架构1.1. 高层 MAC 模型目前，高层 MAC 的父类 ns3::WifiMac 有三种变体：接入点（AP）（ns3::ApWifiMac）、非 AP 站点（STA）（ns3::StaWifiMac）以及独立基本服务集（IBSS）中的 STA（通常称为自组织网络）（ns3::AdhocWifiMac）。其中最简单的是 ns3::AdhocWifiMac，它实现了一个不执行信标生成、探测或关联的 Wi-Fi MAC。ns3::StaWifiMac 类实现了一个主动探测和关联状态机，能够在错过过多信标时自动重新关联。而 ns3::ApW…

GCC 隐藏符号
type: item
date: 2024-09-14T11:39:00+08:00
description: 1. 问题分析日常被 GCC 折磨，GCC 链接报错，提示未定义符号。ld: Undefined symbols: _ssl_print_string, referenced from: _tls13_get_quic_secret in packet-tls.c.o _tls13_get_quic_secret in packet-tls.c.o排查编译流程确认该符号其最终被链接进入 third_party/wireshark/build/run/libwireshark.dylib。而我最终又链接了 libwireshark.dylib。usr/bin/cc -lwireshark packet-tls.c.o -o tls_dissector.so并且确认该符号并非 static。extern void ssl_print_string(const gchar* name, const StringInfo* data); void ssl_print_string(const gchar* name, const StringInfo* data) { ssl_print_data(name, data->data, data->data_len); }直接查找二进制文件也能够确认其符号已经被链接进入 dylib。 grep "packet-tls-utils.c.o" -r . --include=*.dylib Binary file ./third_party/wireshark/build/run/libwireshark.17.0.5.dylib matches通过 nm 确认符号属性发现其为 t。$ nm third_party/wireshark/build/run/libwireshark.17.0.5.dylib|grep _ssl_print_string 0000000000ad2108 t _ssl_print_string符号类型描述U未定义符号 (undefined)A绝对符号 (absolute)T全局可见的文本段符号 (global text section symbol)t本地文本段符号 (local text section symbol)D全局可见的数据段符号 (global data section symbol)d本地数据段符号 (local data section symbol)B全局可见的 BSS 段符号 (global bss section symbol)b本地 BSS 段符号 (local bss section symbol)C公共符号 (common symbol)c本地公共符号 (local common symbol)-调试符号表条目 (for debugger symbol table entries)S全局可见的其他段中的符号 (global symbol in a section other than those above)s本地其他段中的符号 (local symbol in a section other than those above)I全局可见的间接符号 (global indirect symbol)i本地间接符号 (local indirect symbol)u动态共享库中的小写 u 表示对同一库中另一个模块的私有外部未定义引用 (an undefined reference to a private external in another module in the same library)再次查看对应的 .o 确认其为 T。$ nm third_party/wireshark/./build/epan/dissectors/CMakeFiles/dissectors.dir/packet-tls-utils.c.o |grep _ssl_print_string 0000000000001c00 T _ssl_print_string2. 问题结论那么该文本符号从 T 变成了 t 只能够是在链接阶段了。最后确认了 -fvisibility=hidden。这个选项会将所有符号的默认可见性设置为隐藏，除非显式地声明为 default。这意味着，尽管在编译 .o 文件时符号是全局可见的，但在链接生成 .dylib 文件时符号变成了局部可见。那为什么要这么做呢？https://gitlab.com/wireshark/wireshark/-/blob/4aa814ac25a18ea48d4002351ed45d4b245b0c08/CMakeLists.txt#L1070-1104# # Try to have the compiler …

Linux TC
type: item
date: 2024-07-22T14:13:00+08:00
description: TC1. 名称tc - 显示/操作流量控制（traffic control）设置2. 语法tc [ OPTIONS ] qdisc [ add | change | replace | link | delete ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] [ ingress_block BLOCK_INDEX ] [ egress_block BLOCK_INDEX ] qdisc [ qdisc specific parameters ] tc [ OPTIONS ] class [ add | change | replace | delete ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ] tc [ OPTIONS ] filter [ add | change | replace | delete | get ] dev DEV [ parent qdisc-id | root ] [ handle filter-id ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id tc [ OPTIONS ] filter [ add | change | replace | delete | get ] block BLOCK_INDEX [ handle filter-id ] protocol protocol prio priority filtertype [filtertype specific parameters ] flowid flow-id tc [ OPTIONS ] chain [ add | delete | get ] dev DEV [ parent qdisc-id | root ] filtertype [ filtertype specific parameters ] tc [ OPTIONS ] chain [ add | delete | get ] block BLOCK_INDEX filtertype [ filtertype specific parameters ] tc [ OPTIONS ] [ FORMAT ] qdisc { show | list } [ dev DEV ] [ root | ingress | handle QHANDLE | parent CLASSID ] [ invisible ] tc [ OPTIONS ] [ FORMAT ] class show dev DEV tc [ OPTIONS ] filter show dev DEV tc [ OPTIONS ] filter show block BLOCK_INDEX tc [ OPTIONS ] chain show dev DEV tc [ OPTIONS ] chain show block BLOCK_INDEX tc [ OPTIONS ] monitor [ file FILENAME ]3. 选项OPTIONS := { [ -force ] -b[atch] [ filename ] | [ -n[etns] name ] | [ -N[umeric] ] | [ -nm | -nam[es] ] | [ { -cf | -c[onf] } [ filename ] ] [-t[imestamp] ] | [ -t[short] | [ -o[neline] ] } css Copy code FORMAT := { -s[tatistics] | -d[etails] | -r[aw] | -i[ec] | -g[raph] | -j[json] | -p[retty] | -col[or] }4. 描述tc 用于配置 Linux 内核中的流量控制。流量控制包括以下几个方面：整形（SHAPING）当流量被整形时，其传输速率会受到控制。整形不仅仅是降低可用带宽，它还用于平滑流量的突发，以改善网络行为。整形发生在出口端（egress）。调度（SCHEDULING）通过调度数据包的传输，可以改善需要交互的流量的表现，同时保证大流量传输的带宽。重新排序也称为优先级设置，仅在出口端发生。检测（POLICING）整形处理的是传输中的流量，而检测处理的是到达的流量。因此，检测发生在入口端（ingress）。丢弃（DROPPING）超出设定带宽的流量也可能会被…

GAP Bond Manager 和 LE 安全连接
type: item
date: 2024-06-18T18:29:00+08:00
description: GAP Bond Manager 和 LE 安全连接GAP Bond Manager (GAPBondMgr) 是一个可配置模块，用于从应用程序中承担大部分与安全管理器 (SM) 协议相关的配对和绑定安全机制。GAPBondMgr 在协议栈任务的上下文中执行。术语描述配对 (Pairing)生成和交换密钥的过程。不要与建立两个设备之间的 BLE 连接混淆。加密 (Encryption)配对后或重新连接时加密数据。关联 (Association)基于设备的 I/O 能力选择的配对方法。支持 Just Works、数字比较、密码输入和带外 (OOB) 配对。认证 (Authentication)使用支持 MITM 保护的关联方法进行的配对过程。绑定 (Bonding)将配对过程中生成的密钥存储在非易失性内存中，以用于下次加密。授权 (Authorization)除了认证之外的附加应用级别验证。OOB (Out of Band)配对密钥不是通过 RF 交换，而是通过串口或 NFC 等其他方式交换。这也提供了 MITM 保护。MITM (Man in the Middle)中间人攻击保护。在配对过程中提供认证，防止恶意攻击者在密钥交换期间冒充对等设备。Just Works无认证的配对关联方法，密钥交换不受 MITM 保护。配对过程：通过 配对方法选择 中描述的方法交换密钥。加密过程：使用步骤 1 中的密钥加密链路。绑定过程：将密钥存储在安全闪存 (Simple Non Volatile memory, SNV) 中。重新连接：使用存储在 SNV 中的密钥加密链路。配对方法选择蓝牙核心规范版本 4.2 添加了支持 LE Secure Connections 的功能，以增强 BLE 配对过程的强度。详细描述请参见 Bluetooth Core Specification Version 5.1 的 Security Architecture 部分 ([Vol 1], Part A, Section 5.1)。以前版本 (4.1 和 4.0) 使用的方法定义为 LE Legacy Pairing。主要区别在于 Secure Connection 使用椭圆曲线 Diffie-Hellman (ECDH) 密码术，而 LE Legacy Pairing 则不使用。以下是核心规范中定义的四种配对方法，每种配对方法在 不同配对方法的 GAPBondMgr 示例 中有详细描述。Just Works (LE Secure Connections 或 LE Legacy)密码输入 (Passkey Entry, LE Secure Connections 或 LE Legacy)数字比较 (Numeric Comparison, LE Secure Connections)带外 (Out Of Band, LE Secure Connections 或 LE Legacy)配对方法的选择以及配对是否成功取决于配对过程中双方设备的以下参数：带外 (OOB) 设置 / 未设置中间人攻击保护 (MITM) 设置 / 未设置输入/输出 (IO) 能力支持 / 不支持 LE 安全连接GAPBondMgr 参数与以下参数相对应，详情请参见 BLE Stack API 参考 (GAPBondMgr 部分)。GAPBOND_OOB_ENABLED: 带外 (OOB) 设置 / 未设置GAPBOND_MITM_PROTECTION: 中间人攻击保护 (MITM) 设置 / 未设置GAPBOND_IO_CAPABILITIES: 输入/输出 (IO) 能力GAPBOND_SECURE_CONNECTION: 支持 / 不支持 LE 安全连接超出 Bluetooth Core Specification Version 5.1 定义的内容，本参数还会影响配对是否成功，详情参见 BLE Stack API 参考 (GAPBondMgr 部分)。以下是从 Bluetooth Core Specification Version 5.1 的 Selecting Key Generation Method 部分 ([Vol 3], Part H, Section 2.3.5.1) 中的表格。使用这些表格确定任何参数组合下选择的配对模式。如果两台设备都支持 LE 安全连接，请使用 Figure 83 确定下一步。图 83. 当两台设备都支持 LE 安全连接时的 GAPBondMgr 参数。如果至少有一台设备 不 支持 LE 安全连接，请使用 Figure 84 确定下一步。图 84. 当一台或两台设备不支持 LE Secure Connections 时的 GAPBondMgr 参数。…

聊聊 GCC 中的 int 类型和字节对齐
type: item
date: 2024-04-17T17:10:00+08:00
description: 聊聊 GCC 中的对齐最近看到一个问题，在 64 位操作系统中。实际测试环境 Ubuntu 22.04，GCC 11。struct test{ long a int b; char c }问 sizeof(stuct test) =？当然我知道这道题想考察的 int/long 定义以及对齐问题，之前编码也不会太在意这类似问题，直接打印出来就行，但是作为考题这里有诸多不严谨地方。我们好好探索下。不管三七二十一，直接编译打印。$ gcc test.c $ ./a.out 16显然地，这里 int 为4个字节，char 被4字节对齐。看几个 GCC 选项-m64https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/x86-Options.html#x86-Options-m32 -m64 -mx32 -m16 -miamcu Generate code for a 16-bit, 32-bit or 64-bit environment. The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system. The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options. The -mx32 option sets int, long, and pointer types to 32 bits, and generates code for the x86-64 architecture. The -m16 option is the same as -m32, except for that it outputs the .code16gcc assembly directive at the beginning of the assembly output so that the binary can run in 16-bit mode. The -miamcu option generates code which conforms to Intel MCU psABI. It requires the -m32 option to be turned on.看起来这里默认最大设置都是4字节对齐。$ gcc test.c -m16 #编译失败 $ gcc test.c -m32 $ ./a.out 12 $ gcc test.c -m64 $ ./a.out 16-fpack-structhttps://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/Code-Gen-Options.html#Code-Gen-Options-fpack-struct[=n] Without a value specified, pack all structure members together without holes. When a value is specified (which must be a small power of two), pack structure members according to this value, representing the maximum alignment (that is, objects with default alignment requirements larger than this are output potentially unaligned at the next fitting location.显然地，这里的编译选项能够设置 long 类型和对齐。先看默认值。$ gcc test.c -fpack-struct=1 $ ./a.out 13 $ gcc test.c -fpack-struct=2 $ ./a.out 14 $ gcc test.c -fpack-struct=4 $ ./a.out 16 $ gcc test.c -fpack-struct=8 $ ./a.out 16\_attrribute_这里能够设置 -m32 将 long 和指针类型设置为 4字节，但是对齐方式还是 …

Thread 路由协议
type: item
date: 2024-01-18T16:38:00+08:00
description: 5.9 路由协议本文为 Thread 路由协议相关规范，翻译自Thread Specification->5.9 Routing Protocol，作为理论储备。这里未做任何解释，接下来会结合其他系列文档从抓包、代码实现结合协议规范去理解该路由协议。本节描述了 Thread 网络中使用的路由协议。Thread 路由协议是一个简单的距离向量路由协议。协议的主要目标是最大化地可以在单个消息中传输的路由信息量。因此，该协议限制了包含最多 MAX_ROUTERS 或更少路由器的网络。注意：可以使用超过 MAX_ROUTERS 的路由地址，以便在重新使用路由器地址之前等待超时。路由器定期向 Thread 网络分区中的所有其他路由器广播其路由成本以及与邻居之间的单跳链路质量。到达特定目的地的路由成本是所有邻居对该目的地广播的成本中的最小值加上到该邻居的成本。 Advertisement 发送的速率由 Trickle 算法的一个实例确定RFC 6206。提示：Trickle 算法是一种用于网络协议中的算法，旨在有效地维护和更新网络中的信息。它通常用于自组织网络（例如传感器网络）中，以确保网络中的路由信息、邻居信息或其他状态信息得到及时更新，同时尽量减少网络中的控制消息的数量。Trickle 算法的核心思想是在保持低开销的同时，仍然能够快速地传播重要的变更。该算法通过引入慢速的消息传播机制和快速的消息传播机制来实现这一目标。具体来说，Trickle 算法的工作方式如下：慢速传播： 定期（例如每分钟）发送一条慢速消息，其中包含节点当前的信息。这有助于保持网络中的信息更新。快速传播： 在检测到信息变更时，立即发送一条快速消息。这有助于迅速传播关键信息。定时器机制： 每个节点都维护一个定时器，定期触发慢速消息的发送。当接收到慢速或快速消息时，可以重置定时器。Trickle 算法通过这种方式实现了一种自适应机制，可以根据网络的实际变化来动态调整消息的传播频率。这有助于在网络拓扑结构变化较小的情况下，降低消息传播的开销，提高网络的效率。 Trickle 算法在许多自组织网络协议中都得到了应用，例如RPL（适用于低功耗和有限能量的网络中的IPv6路由协议）。5.9.1 路由数据库路由器维护一个路由数据库，记录使用 Thread 距离向量路由的每个单独接口的信息。这些数据库包含以下各小节中描述的数据集。5.9.1.1 路由器 ID 集接口的路由器 ID 集包含两个值：ID_set 是当前有效路由器 ID 的集合。ID_sequence_number 是分配给当前 ID_set 的序列号。5.9.1.2 链路集接口的链路集记录了与该接口上的其他路由器是或曾是邻居的信息。路由器为与每个邻居的链接维护一个元组，如下所示：(L_router_id, L_link_margin, L_incoming_quality, L_outgoing_quality, L_age)其中：L_router_id 是分配给该邻居的路由器 ID。L_link_margin 是从该邻居接收到的消息的测得链路余量。L_incoming_quality 是根据 L_link_margin 计算得到的传入链路质量度量。L_outgoing_quality 是由该邻居报告的从本路由器发送消息的传出链路质量度量。L_age 是自上次从该邻居接收到 MLE Advertisement 以来经过的时间。5.9.2 路由集接口的路由集记录了关于其他路由器的路由成本和下一跳信息，这些路由器是从该路由器出发可达（具有有限路由成本）的或最近可达的。路由器为每个可达路由器维护一个元组，如下所示：(R_destination, R_next_hop, R_route_cost)其中：R_destination 是该路由的目的地分配的路由器 ID。R_next_hop 是沿路由的下一跳分配的路由器 ID。R_route_cost 是由 R_next_hop 报告给 R_destination 的路由成本。5.9.3 Leader 数据库作为 Leader 的路由器维护一个额外的数据库，用于跟踪路由器 ID 的分配情况。与路由数据库类似，Leader 为设备作为 Leader 的每个接口维护一个单独的 Leader 数据库。5.9.3.1 ID 分配集接口的分配集记录了每个路由器 ID 的状态。Leader 为每个路由器 ID 维护一个元组，如下所示：(ID_id, ID_owner, ID_reuse_time)其中：ID_id 是一个路由器 ID。ID_owner 是当前分配给该路由器 ID 的 IEEE 802.15.4 扩展地址，或者如果未分配，则是最近分配给它的路由器的 IEEE 802.15.4 扩展…