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:
+139
-38
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user