WireGuard 的单条隧道怎样并行加密?sanstun 把状态记账与密码运算拆开了。 1)先分离副作用。这个 Rust 用户态实现采用 sans-IO:… · @BaiBtw · TwKit
@BaiBtw
WireGuard 的单条隧道怎样并行加密?sanstun 把状态记账与密码运算拆开了。 1)先分离副作用。这个 Rust 用户态实现采用 sans-IO:网络读写、时间和随机性都与协议状态分开。库内不缓存待发包;尚未建立会话时,由调用方决定如何缓存,并显式发起握手。 2)入口统一,处理分类。WireGuard 有握手发起、握手响应、cookie 回复和加密数据四类消息。原始数据报先进入 Interface::receive,完成解析、校验与接口级限流,再分派到 Tunnel。握手发起按发起方静态公钥路由,其余消息携带 TunnelId。HandshakeInitiation 等握手输入类型的构造器仅在库内部可用,使调用方不能绕过这个入口直接构造握手输入。 3)并行的是重活,不是随意共享状态。同一会话共用包计数器。发送时先检查会话、预留计数器、更新定时状态,再把待加密任务交给工作线程;接收时先准备解密任务,解密完成后回到状态所属线程提交并检查重放。库不自动创建线程,也允许原地执行加解密。 4)性能数字要分清口径。文中微基准里,1280 字节包的发送准备约 21 ns,加密约 934 ns;接收准备约 38 ns,解密约 915 ns,提交约 18 ns。记账部分基本不随包大小变化,密码运算则会增长。所谓“超过 45 倍”是忽略跨线程传递等开销后的理论潜力,不是实测端到端吞吐提升。这些数字来自项目文中的微基准,未作独立复测。 这里的设计重点是:把必须串行维护的协议状态留在所属线程,把可独立执行的密码运算交出去。Interface 保持单线程,也让其内部限流器不必使用锁或原子计数器;这不等于整个应用都无锁。
曝光 238 · 评论 2 · 点赞 3 · 书签 0
查看原帖