- 新增 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 文档
6.7 KiB
6.7 KiB
notify
b612.me/notify 是一个面向点对点直连场景的 Go 通信基础包,覆盖消息信令、流式传输、批量数据通道和文件传输内核能力。
模块定位
- 消息面:
Send、SendWait、Reply、SetLink - 流式数据面:
OpenStream - 记录流数据面:
OpenRecordStream - 批量数据面:
OpenBulk(shared/dedicated) - 文件传输内核:transfer control / progress / resume
- 观测面:runtime snapshot / diagnostics summary
- 会话模型:
LogicalConn(逻辑会话)与TransportConn(物理承载)分离
版本要求
- Go
1.24+
安全初始化要求
Client / Server 在 Connect / Listen 前必须完成安全配置。默认使用现代 PSK 方案。
- 客户端:
UseModernPSKClient - 服务端:
UseModernPSKServer
未配置时会返回 errModernPSKRequired。
安全模式选择
UseModernPSKClient/UseModernPSKServer- bootstrap 和稳态传输都由
notify自己保护 - 适合默认场景
- 支持 peer attach 显式认证、抗重放,以及在需要时协商前向保密
- bootstrap 和稳态传输都由
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 之上,适合“有边界的顺序记录”场景。
- 写入入口:
OpenRecordStream、WriteRecord - 接收入口:
ReadRecord - 确认入口:
AckRecord - 检查点:
Barrier、BarrierTo - 错误回包:
RecordFailure
确认语义:
AckRecord表示“该序号及其之前的连续记录已完成 apply”,不是“已收到”Barrier/BarrierTo等待的是对端apply-complete的最大连续序号RecordFailure会返回FailedSeq、Code、Retryable、Message
兼容与传输:
- record stream 在打开阶段协商 batch ack 能力
- 双端都支持时,累计
AckSeq会随 batch header piggyback 发送 - 对端不支持时,自动回退到独立 ack frame
- mixed-version peer 可以互通,不要求双方同时升级
诊断快照
顶层诊断入口:
GetClientDiagnosticsSnapshotGetServerDiagnosticsSnapshot
快照内容:
- 会话运行态:client / server runtime
- 数据面快照:
StreamSnapshot、BulkSnapshot、RecordSnapshot - 文件传输快照:
TransferSnapshot - 汇总视图:
DiagnosticsSummary
RecordSnapshot / DiagnosticsSummary.RecordTelemetry 当前覆盖:
- batch / ack / error frame 收发计数
- piggyback ack 命中计数
- barrier 等待时间拆分:
flush/apply outstanding records/bytespending apply / pending ack / peak pending apply
传输与 IPC
tcpudpunixnpipe(Windows)
示例目录:
现代 PSK 与兼容入口
现代方案特性:
- 共享密钥派生(Argon2id)
- 消息层加密(AES-GCM)
stream/bulkfast path 复用现代编码栈- peer attach 显式认证 / 抗重放
- 可选 channel binding
- 可选前向保密(
UseModernPSK*/UseNestedSecurity*)
兼容入口仍保留,但属于历史路径:
UseLegacySecurityClientUseLegacySecurityServerExchangeKeySetSecretKeySetMsgEn/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'
兼容性说明
- 对外主入口保留:
NewClient、NewServer、Connect、Listen、SetLink、SetDefaultLink、Send、SendWait、SendObj、Reply、Stop - 内部主对象已迁移为
LogicalConn/TransportConn ClientConn作为兼容适配层继续保留