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 文档
This commit is contained in:
2026-04-20 16:35:44 +08:00
parent f038a89771
commit 98ef9e7fcc
52 changed files with 4069 additions and 445 deletions
+139 -38
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/binary"
"errors"
"fmt"
"net"
"sync"
"time"
@@ -132,8 +133,9 @@ func (c *ClientCommon) encodeBulkFastPayload(frame bulkFastFrame) ([]byte, error
if c == nil {
return nil, errBulkClientNil
}
if c.fastPlainEncode != nil {
return encodeBulkFastFramePayloadFast(c.fastPlainEncode, c.SecretKey, frame)
profile := c.clientTransportProtectionSnapshot()
if profile.fastPlainEncode != nil {
return encodeBulkFastFramePayloadFast(profile.fastPlainEncode, profile.secretKey, frame)
}
plain, err := encodeBulkFastFramePayload(frame)
if err != nil {
@@ -146,8 +148,9 @@ func (c *ClientCommon) encodeBulkFastBatchPayload(frames []bulkFastFrame) ([]byt
if c == nil {
return nil, errBulkClientNil
}
if c.fastPlainEncode != nil {
return encodeBulkFastBatchPayloadFast(c.fastPlainEncode, c.SecretKey, frames)
profile := c.clientTransportProtectionSnapshot()
if profile.fastPlainEncode != nil {
return encodeBulkFastBatchPayloadFast(profile.fastPlainEncode, profile.secretKey, frames)
}
plain, err := encodeBulkFastBatchPlain(frames)
if err != nil {
@@ -160,11 +163,12 @@ func (c *ClientCommon) encodeBulkFastPayloadPooled(frame bulkFastFrame) ([]byte,
if c == nil {
return nil, nil, errBulkClientNil
}
if runtime := c.modernPSKRuntime; runtime != nil {
profile := c.clientTransportProtectionSnapshot()
if runtime := profile.runtime; runtime != nil {
return encodeBulkFastFramePayloadPooled(runtime, frame)
}
if c.fastPlainEncode != nil {
payload, err := encodeBulkFastFramePayloadFast(c.fastPlainEncode, c.SecretKey, frame)
if profile.fastPlainEncode != nil {
payload, err := encodeBulkFastFramePayloadFast(profile.fastPlainEncode, profile.secretKey, frame)
return payload, nil, err
}
plain, err := encodeBulkFastFramePayload(frame)
@@ -179,11 +183,12 @@ func (c *ClientCommon) encodeBulkFastBatchPayloadPooled(frames []bulkFastFrame)
if c == nil {
return nil, nil, errBulkClientNil
}
if runtime := c.modernPSKRuntime; runtime != nil {
profile := c.clientTransportProtectionSnapshot()
if runtime := profile.runtime; runtime != nil {
return encodeBulkFastBatchPayloadPooled(runtime, frames)
}
if c.fastPlainEncode != nil {
payload, err := encodeBulkFastBatchPayloadFast(c.fastPlainEncode, c.SecretKey, frames)
if profile.fastPlainEncode != nil {
payload, err := encodeBulkFastBatchPayloadFast(profile.fastPlainEncode, profile.secretKey, frames)
return payload, nil, err
}
plain, err := encodeBulkFastBatchPlain(frames)
@@ -460,28 +465,126 @@ func putBulkFastFrameScratch(buf []byte) {
bulkFastFrameScratchPool.Put(buf[:0])
}
func transportFastPayloadMagic(payload []byte) string {
if len(payload) < 4 {
return ""
}
return string(payload[:4])
}
func (c *ClientCommon) decryptTransportPayloadPooled(payload []byte, release func()) ([]byte, func(), error) {
profile := c.clientTransportProtectionSnapshot()
return decryptTransportPayloadCodecPooled(profile.mode, profile.runtime, profile.msgDe, profile.secretKey, payload, release)
}
func (s *ServerCommon) decryptTransportPayloadLogicalPooled(logical *LogicalConn, payload []byte, release func()) ([]byte, func(), error) {
if logical == nil {
if release != nil {
release()
}
return nil, nil, errTransportDetached
}
return decryptTransportPayloadCodecPooled(logical.protectionModeSnapshot(), logical.modernPSKRuntimeSnapshot(), logical.msgDeSnapshot(), logical.secretKeySnapshot(), payload, release)
}
func (c *ClientCommon) tryDispatchBorrowedTransportPlain(plain []byte, release func()) bool {
switch transportFastPayloadMagic(plain) {
case bulkFastPayloadMagic, bulkFastBatchMagic:
owner := newBulkReadPayloadOwner(release)
matched, walkErr := walkBulkFastFrames(plain, func(frame bulkFastFrame) error {
c.dispatchFastBulkFrameWithOwner(frame, owner)
return nil
})
if owner != nil {
owner.done()
}
if !matched {
walkErr = errBulkFastPayloadInvalid
}
if walkErr != nil && (c.showError || c.debugMode) {
fmt.Println("client decode bulk fast payload error", walkErr)
}
return true
case streamFastPayloadMagic, streamFastBatchMagic:
owner := newStreamReadPayloadOwner(release)
matched, walkErr := walkStreamFastFrames(plain, func(frame streamFastDataFrame) error {
c.dispatchFastStreamDataWithOwner(frame, owner)
return nil
})
if owner != nil {
owner.done()
}
if !matched {
walkErr = errStreamFastPayloadInvalid
}
if walkErr != nil && (c.showError || c.debugMode) {
fmt.Println("client decode stream fast payload error", walkErr)
}
return true
default:
return false
}
}
func (s *ServerCommon) tryDispatchBorrowedTransportPlain(logical *LogicalConn, transport *TransportConn, conn net.Conn, plain []byte, release func()) bool {
switch transportFastPayloadMagic(plain) {
case bulkFastPayloadMagic, bulkFastBatchMagic:
owner := newBulkReadPayloadOwner(release)
matched, walkErr := walkBulkFastFrames(plain, func(frame bulkFastFrame) error {
s.dispatchFastBulkFrameWithOwner(logical, transport, conn, frame, owner)
return nil
})
if owner != nil {
owner.done()
}
if !matched {
walkErr = errBulkFastPayloadInvalid
}
if walkErr != nil && (s.showError || s.debugMode) {
fmt.Println("server decode bulk fast payload error", walkErr)
}
return true
case streamFastPayloadMagic, streamFastBatchMagic:
owner := newStreamReadPayloadOwner(release)
matched, walkErr := walkStreamFastFrames(plain, func(frame streamFastDataFrame) error {
s.dispatchFastStreamDataWithOwner(logical, transport, conn, frame, owner)
return nil
})
if owner != nil {
owner.done()
}
if !matched {
walkErr = errStreamFastPayloadInvalid
}
if walkErr != nil && (s.showError || s.debugMode) {
fmt.Println("server decode stream fast payload error", walkErr)
}
return true
default:
return false
}
}
func (c *ClientCommon) dispatchInboundTransportPayload(payload []byte, now time.Time) error {
plain, err := c.decryptTransportPayload(payload)
if err != nil {
return err
}
if frames, matched, err := decodeBulkFastFrames(plain); matched {
if err != nil {
return err
}
for _, frame := range frames {
c.dispatchFastBulkFrame(frame)
}
return c.dispatchInboundTransportPlain(plain, now)
}
func (c *ClientCommon) dispatchInboundTransportPlain(plain []byte, now time.Time) error {
if matched, err := walkBulkFastFrames(plain, func(frame bulkFastFrame) error {
c.dispatchFastBulkFrame(frame)
return nil
}); matched {
return err
}
if frames, matched, err := decodeStreamFastDataFrames(plain); matched {
if err != nil {
return err
}
for _, frame := range frames {
c.dispatchFastStreamData(frame)
}
if matched, err := walkStreamFastFrames(plain, func(frame streamFastDataFrame) error {
c.dispatchFastStreamData(frame)
return nil
}); matched {
return err
}
env, err := c.decodeEnvelopePlain(plain)
if err != nil {
@@ -502,23 +605,21 @@ func (s *ServerCommon) dispatchInboundTransportPayload(logical *LogicalConn, tra
if err != nil {
return err
}
if frames, matched, err := decodeBulkFastFrames(plain); matched {
if err != nil {
return err
}
for _, frame := range frames {
s.dispatchFastBulkFrame(logical, transport, conn, frame)
}
return s.dispatchInboundTransportPlain(logical, transport, conn, plain, now)
}
func (s *ServerCommon) dispatchInboundTransportPlain(logical *LogicalConn, transport *TransportConn, conn net.Conn, plain []byte, now time.Time) error {
if matched, err := walkBulkFastFrames(plain, func(frame bulkFastFrame) error {
s.dispatchFastBulkFrame(logical, transport, conn, frame)
return nil
}); matched {
return err
}
if frames, matched, err := decodeStreamFastDataFrames(plain); matched {
if err != nil {
return err
}
for _, frame := range frames {
s.dispatchFastStreamData(logical, transport, conn, frame)
}
if matched, err := walkStreamFastFrames(plain, func(frame streamFastDataFrame) error {
s.dispatchFastStreamData(logical, transport, conn, frame)
return nil
}); matched {
return err
}
env, err := s.decodeEnvelopePlain(plain)
if err != nil {