1️⃣ 项目难点

  流量线程 会根据 虚拟地址 高频查询客户端信息,但客户端断连时 pcc 会从 在线上下文 里移除。如果流量线程直接依赖 pccMap,就会面临 pcc 生命周期不稳定的问题。
  所以我没有让 流量线程 直接访问 pcc,而是专门维护了一个 virtual_address_map,把流量线程需要的字段提前从 pcc 中抽出来,按 virtual_address -> Json 的形式保存。这样流量线程只读 轻量级映射,不依赖 pcc 本身,从而规避了断连场景下访问失效上下文的问题,同时也减少了重复组装 JSON 的开销。

2️⃣ 项目优化

请求链路优化

  根据场景不同,将 证书校验用户规则下载连接状态上报 进行拆分:

  • 证书校验 走 **同步 fast_fail**(服务器不可访问则立即返回),因为证书校验在主链路上,必须立即返回;
  • 用户访问规则下载 走 **异步 gRPC**,基于用户的 完成队列 (Completion Queue) 提前下载用户规则,同时避免阻塞 OpenVPN 主流程;
  • 连接状态上报 走 **异步 gRPC**,基于全局的 **完成队列 (Completion Queue)**,避免阻塞 OpenVPN 主流程;

规则下发和更新优化

  • 访问控制不是每次 全量重建,而是按用户维度生成独立 nftables chain;
  • 通过 map虚拟地址 跳到 用户规则链;
  • 新增、删除、更新某个用户时只改这个用户对应的链,开销更小;
  • 服务端规则变化时,也不是轮询,而是通过 gRPC 双向流推送,插件收到后做增量更新;

稳定性和一致性优化

  对不同 RPC 设置了不同的 超时失败 策略

  • 证书校验: 使用 fail-fast
  • 状态上报: 使用 wait-for-ready
  • 双向推送流: 使用 指数退避重连
  • 定时全量状态同步:3 分钟把当前在线用户状态重新上报一次,避免长连接抖动或偶发失败后服务端状态漂移。

并发优化

  项目里维护了 在线用户虚拟地址 的映射,我把访问模式拆开了

  • 流量线程查看用户信息高频读:所以用了 shared_mutex
  • 新增/删除用户高频写:所以用了 unique_lock

3️⃣ 做这些优化的出发点是什么?

  • OpenVPN 插件在认证接入阶段不能被远程服务拖住;
  • 防火墙规则更新不能每次全量重建;
  • 控制面消息不能只靠一次事件成功,必须考虑断连、丢消息和状态漂移;

4️⃣ 项目模块问题

1️⃣ 你项目里 PcapPlusPlus 干了什么

  OpenVPN 插件里封装了一个 tcap 模块,在插件启动后根据 OpenVPN 提供的网卡名 dev 打开对应设备,注册抓包回调,实时捕获经过 VPN 网卡的流量。拿到原始包之后,我会用 PcapPlusPlus 做协议层解析,解析到网络层、传输层,配置允许的话还能继续到应用层,比如 DNSHTTPSSL。然后把解析出的字段连同节点信息、服务器信息、时间戳、VPN 用户信息一起组织成 JSON,最后发送到 Kafka,供后续审计和流量分析使用。