notify/README.md
starainrt 98ef9e7fcc
feat(transport): 完成安全架构拆分并收口 stream/bulk 传输优化
- 新增 managed/external/nested 三种传输保护模式
  - 新增 peer attach 显式认证、抗重放、channel binding 和可选前向保密协商
  - 明确单连接注入与可重拨连接源的语义边界
  - 禁止 ConnectByConn 场景下 dedicated bulk 走 sidecar,auto 模式自动回退 shared
  - 修正 dedicated attach 在 bootstrap/steady profile 切换下的处理逻辑
  - 优化 shared bulk super-batch 与批量 framed write 路径
  - 降低 stream/bulk fast path 的复制和分发损耗
  - 补齐 benchmark、回归测试、运行时快照和 README 文档
2026-04-20 16:35:44 +08:00

6.7 KiB
Raw Permalink Blame History

notify

b612.me/notify 是一个面向点对点直连场景的 Go 通信基础包,覆盖消息信令、流式传输、批量数据通道和文件传输内核能力。

模块定位

  • 消息面:SendSendWaitReplySetLink
  • 流式数据面:OpenStream
  • 记录流数据面:OpenRecordStream
  • 批量数据面:OpenBulkshared / dedicated
  • 文件传输内核transfer control / progress / resume
  • 观测面runtime snapshot / diagnostics summary
  • 会话模型:LogicalConn(逻辑会话)与 TransportConn(物理承载)分离

版本要求

  • Go 1.24+

安全初始化要求

Client / ServerConnect / Listen 前必须完成安全配置。默认使用现代 PSK 方案。

  • 客户端:UseModernPSKClient
  • 服务端:UseModernPSKServer

未配置时会返回 errModernPSKRequired

安全模式选择

  • UseModernPSKClient / UseModernPSKServer
    • bootstrap 和稳态传输都由 notify 自己保护
    • 适合默认场景
    • 支持 peer attach 显式认证、抗重放,以及在需要时协商前向保密
  • UsePSKOverExternalTransportClient / UsePSKOverExternalTransportServer
    • bootstrap 仍用 PSK 做认证
    • 稳态阶段信任外部物理通道,不再做 notify 内层加密
    • 适合 tls.Conn 或调用方自认可信的外部通道
    • 不支持 RequireForwardSecrecy
  • UseNestedSecurityClient / UseNestedSecurityServer
    • 外层已有可信通道,但仍保留 notify 内层保护
    • 适合需要“外层可信 + 内层独立保护”的场景

快速开始

服务端:

package main

import (
	"log"

	"b612.me/notify"
)

func main() {
	srv := notify.NewServer()
	if err := notify.UseModernPSKServer(srv, []byte("shared-secret"), nil); err != nil {
		log.Fatal(err)
	}
	srv.SetLink("ping", func(msg *notify.Message) {
		_ = msg.Reply([]byte("pong"))
	})
	if err := srv.Listen("tcp", "127.0.0.1:28080"); err != nil {
		log.Fatal(err)
	}
	select {}
}

客户端:

package main

import (
	"log"
	"time"

	"b612.me/notify"
)

func main() {
	cli := notify.NewClient()
	if err := notify.UseModernPSKClient(cli, []byte("shared-secret"), nil); err != nil {
		log.Fatal(err)
	}
	if err := cli.Connect("tcp", "127.0.0.1:28080"); err != nil {
		log.Fatal(err)
	}
	defer cli.Stop()

	reply, err := cli.SendWait("ping", []byte("hello"), 5*time.Second)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("reply=%s", string(reply.Value))
}

连接入口与物理连接语义

  • Connect / ConnectTimeout
    • notify 自己拨号
    • 支持重连,也支持 dedicated bulk 额外 sidecar 连接
  • ConnectByFactory
    • 调用方提供 dialFn
    • notify 会在需要时再次调用 dialFn,因此仍支持重连和 dedicated bulk
  • ConnectByConn
    • 调用方注入一个已经建立好的 net.Conn
    • 该模式被视为“单物理连接模式”
    • OpenDedicatedBulk 会直接返回错误
    • OpenBulk 使用 auto 模式时会自动回退到 shared
  • ListenByListener
    • 服务端复用调用方提供的 net.Listener
    • 适合需要和现有 listener 栈整合的场景

dedicated bulk 依赖额外物理连接,因此只适用于可再次拨号的 transport source。

Peer Attach 安全策略

可通过 SetPeerAttachSecurityConfig 配置逻辑会话 attach 阶段的额外保护。

  • RequireExplicitAuth
    • 要求 peer attach 使用显式认证
  • RequireChannelBinding
    • 要求 attach 绑定到底层可信通道
    • 启用后会隐式要求显式认证
  • ChannelBinding
    • 由调用方提供 channel binding 提取函数
    • 适合外层 TLS 或其他可信通道整合
  • ReplayWindow / ReplayCapacity
    • 控制 attach 抗重放窗口和缓存容量

如果你选择 UsePSKOverExternalTransport*,并且希望 attach 阶段显式绑定到外层可信信道,建议同时配置 channel binding。

RecordStream 说明

RecordStream 构建在 Stream 之上,适合“有边界的顺序记录”场景。

  • 写入入口:OpenRecordStreamWriteRecord
  • 接收入口:ReadRecord
  • 确认入口:AckRecord
  • 检查点:BarrierBarrierTo
  • 错误回包:RecordFailure

确认语义:

  • AckRecord 表示“该序号及其之前的连续记录已完成 apply”不是“已收到”
  • Barrier / BarrierTo 等待的是对端 apply-complete 的最大连续序号
  • RecordFailure 会返回 FailedSeqCodeRetryableMessage

兼容与传输:

  • record stream 在打开阶段协商 batch ack 能力
  • 双端都支持时,累计 AckSeq 会随 batch header piggyback 发送
  • 对端不支持时,自动回退到独立 ack frame
  • mixed-version peer 可以互通,不要求双方同时升级

诊断快照

顶层诊断入口:

  • GetClientDiagnosticsSnapshot
  • GetServerDiagnosticsSnapshot

快照内容:

  • 会话运行态client / server runtime
  • 数据面快照:StreamSnapshotBulkSnapshotRecordSnapshot
  • 文件传输快照:TransferSnapshot
  • 汇总视图:DiagnosticsSummary

RecordSnapshot / DiagnosticsSummary.RecordTelemetry 当前覆盖:

  • batch / ack / error frame 收发计数
  • piggyback ack 命中计数
  • barrier 等待时间拆分:flush / apply
  • outstanding records/bytes
  • pending apply / pending ack / peak pending apply

传输与 IPC

  • tcp
  • udp
  • unix
  • npipeWindows

示例目录:

现代 PSK 与兼容入口

现代方案特性:

  • 共享密钥派生Argon2id
  • 消息层加密AES-GCM
  • stream / bulk fast path 复用现代编码栈
  • peer attach 显式认证 / 抗重放
  • 可选 channel binding
  • 可选前向保密(UseModernPSK* / UseNestedSecurity*

兼容入口仍保留,但属于历史路径:

  • UseLegacySecurityClient
  • UseLegacySecurityServer
  • ExchangeKey
  • SetSecretKey
  • SetMsgEn / SetMsgDe

发布前检查

export SENTRUX_SKIP_GRAMMAR_DOWNLOAD='1'
sentrux check .
env GOCACHE=/tmp/b612-gocache GOMODCACHE=/tmp/b612-gomodcache go test ./...
env GOCACHE=/tmp/b612-gocache GOMODCACHE=/tmp/b612-gomodcache go test -race ./...
env GOCACHE=/tmp/b612-gocache GOMODCACHE=/tmp/b612-gomodcache go vet ./...

手工 soak 测试(可选):

env GOCACHE=/tmp/b612-gocache GOMODCACHE=/tmp/b612-gomodcache \
go test -tags notify_manual_soak -run 'Test_ServerTuAndClientCommon|Test_normal|Test_normal_udp'

兼容性说明

  • 对外主入口保留:NewClientNewServerConnectListenSetLinkSetDefaultLinkSendSendWaitSendObjReplyStop
  • 内部主对象已迁移为 LogicalConn / TransportConn
  • ClientConn 作为兼容适配层继续保留