Posts for: #Work

Wasm Internals - Overview

Wasm 的历史发展

早期(Wasm MVP - 2017)

  • 诞生背景: Wasm 的设计目标是为了替代 asm.js,提供更小、更快、更安全的 Web 二进制格式。
  • 核心模块的初步定义: MVP(Minimum Viable Product)阶段定义了 Wasm Core Module 的基本结构:函数、内存、表、导入、导出、全局变量等。
  • 主要用例: 游戏引擎、音视频编解码、计算密集型任务等。
  • 限制:
    • 没有模块化系统: 模块之间没有标准的链接机制,只能通过宿主环境(如 JavaScript)进行协调。
    • 缺乏垃圾回收(GC): 需要手动内存管理或使用语言自带的 GC 机制(如 Emscripten 的 mimalloc)。
    • 没有线程: 无法直接利用多核 CPU。
    • 没有宿主 API 标准化: 模块与宿主环境的交互方式高度依赖宿主(如浏览器),没有统一的接口定义。
    • 没有组件模型: 模块重用和组合非常困难。

中期(MVP 之后 - 持续演进)

Wasm 社区和工作组认识到 MVP 的局限性,并开始着手扩展 Wasm 的能力,这直接影响了 Core Module 的能力:

  • 多值(Multiple Returns & Parameters): 允许函数返回多个值,接收多个参数,提高表达能力。
  • 引用类型(Reference Types): 引入了 externref 和 funcref,允许 Wasm 直接引用宿主对象和函数,而无需通过数字 ID 传递,为未来的 GC 和组件模型打下基础。
  • 固定大小的 SIMD(Fixed-width SIMD): 引入了新的指令集,允许在 Wasm 中进行向量化操作,进一步提升某些计算密集型任务的性能。
  • 线程(Threads): 引入了共享内存和原子操作,允许 Wasm 模块在多线程环境下运行,极大地提升了并行计算能力。
  • 内存增长和限制(Memory Growth and Limits): 提供了更灵活的内存管理机制。
  • Tail Calls(尾调用): 优化了函数调用的性能。

近期和未来(Wasm Component Model)

这是 Wasm 发展中最重要的方向之一,旨在解决 Core Module 在模块化和互操作性方面的根本性问题:

Spurious Retransmit 导致 NAT 设备响应 RST

在一个线上问题排查过程中,出现了一个新的问题:wget 下载文件在连接建立很短的时间内(1 - 2s)就被 RESET 了。 首先先简要说明一下链路:

客户端经过一个SNAT设备出公网,在服务器上下载一个大文件。端到端的 RTT 大约 90 ms。由于最开始并没有怀疑到 SNAT 设备,并且 server 端无法抓包,我们分别在客户端 和 SNAT 设备到 server 间一台网元设备上抓包。 中间网元设备

SNAT 设备

如上,中间网元设备显示客户端(端口 34567)先发送了 RST 报文,随后服务器(端口 443)响应 RST 报文。但是客户端抓包显示它根本没有发送过 RST 报文。

此时,我们再从 SNAT 设备上抓包,发现就是 SNAT 设备首先给服务器发送了 RST 报文。

这里的 SNAT 设备实际上是一台基于 IPtables 的 Linux 设备。

抓包可以看到,RST 是对一个 TCP Spurious Retransmission 的响应。为什么会发出这个 RST 呢?正好网上有一个相似的场景:Add workaround for spurious retransmits leading to connection resets

总的来说,就是 spurious retransmits 报文在序列号超出 TCP 窗口时,会被 conntrack 认为是 invalid 包,从而不再经过反向 SNAT 规则的处理。由于目的地址没有被转换,报文会按照原来的目的地址送往 INPUT,而本地又没有这个 socket,则响应一个 RST 报文。

Dns Zone Files

CNAME 记录

记录格式

bar.example.com.	CNAME	foo.example.com.
foo.example.com.	A		192.168.0.1

CNAME 记录的限制

  1. 如果一个 domain name 有了一个 CNAME 记录,那么它不能再拥有其它类型的记录
  2. CNAME 记录必须指向另外一个 domain name,而不是一个 IP
  3. CNAME 记录最好不要指向另外一个 CNAME 记录
  4. MX 和 NS 记录不能指向一个 CNAME 记录

SRV 记录

type code:33

记录格式

_service._protocol.name. TTL class SRV priority weight port target.

_sip._tcp.example.com. 86400 IN SRV 0 5 5060 sipserver.example.com.
  • _service: 服务名称 symbolic name
  • protocol: 协议
  • name: domain name,以 . 结束
  • priority: 条目优先级, 值越低优先级越高
  • weight: 同样优先级内不同条目的权重
  • target: canonical hostname,以 . 结束 如果是一个 MX 记录,那么 target 需要是一个 IP 地址(A 或者 AAAA)而不是 CNAME

SOA 记录

start of authority, 一个权威的起始