рабочий вариант, но скороть 10 МБит
This commit is contained in:
@@ -22,6 +22,9 @@ const fabricQUICNextProto = "rap-fabric-data-session-v1"
|
||||
const fabricQUICReverseHelloPrefix = "rap-fabric-reverse-hello-v1:"
|
||||
const defaultQUICFabricConnIdleTTL = 5 * time.Minute
|
||||
const defaultQUICFabricMaxStreamsPerConn = 64
|
||||
const defaultQUICFabricHandshakeIdleTimeout = 8 * time.Second
|
||||
const defaultQUICFabricMaxIdleTimeout = 90 * time.Second
|
||||
const defaultQUICFabricKeepAlivePeriod = 15 * time.Second
|
||||
const ErrQUICFabricStreamLimitReached = quicFabricError("quic fabric stream limit reached")
|
||||
|
||||
type quicFabricError string
|
||||
@@ -31,20 +34,20 @@ func (e quicFabricError) Error() string {
|
||||
}
|
||||
|
||||
type QUICFabricTransport struct {
|
||||
Config *quic.Config
|
||||
LocalPeerID string
|
||||
IdleTTL time.Duration
|
||||
MaxStreamsPerConn int
|
||||
DialAddr func(context.Context, string, *tls.Config, *quic.Config) (*quic.Conn, error)
|
||||
mu sync.Mutex
|
||||
conns map[string]*quicFabricConnEntry
|
||||
reverseConns map[string]*quicFabricConnEntry
|
||||
inboundProductionHandler func(context.Context, ProductionEnvelope) (ProductionForwardResult, error)
|
||||
inboundWebIngressHandler func(context.Context, []byte) ([]byte, error)
|
||||
Config *quic.Config
|
||||
LocalPeerID string
|
||||
IdleTTL time.Duration
|
||||
MaxStreamsPerConn int
|
||||
DialAddr func(context.Context, string, *tls.Config, *quic.Config) (*quic.Conn, error)
|
||||
mu sync.Mutex
|
||||
conns map[string]*quicFabricConnEntry
|
||||
reverseConns map[string]*quicFabricConnEntry
|
||||
inboundProductionHandler func(context.Context, ProductionEnvelope) (ProductionForwardResult, error)
|
||||
inboundWebIngressHandler func(context.Context, []byte) ([]byte, error)
|
||||
inboundFabricControlHandler func(context.Context, []byte) ([]byte, error)
|
||||
inboundSyntheticHandler func(context.Context, SyntheticEnvelope) (SyntheticEnvelope, error)
|
||||
logger FabricSessionEventLogger
|
||||
stats QUICFabricTransportStats
|
||||
inboundSyntheticHandler func(context.Context, SyntheticEnvelope) (SyntheticEnvelope, error)
|
||||
logger FabricSessionEventLogger
|
||||
stats QUICFabricTransportStats
|
||||
}
|
||||
|
||||
type QUICFabricTransportStats struct {
|
||||
@@ -109,7 +112,25 @@ type quicFabricConnEntry struct {
|
||||
}
|
||||
|
||||
func NewQUICFabricTransport(config *quic.Config) *QUICFabricTransport {
|
||||
return &QUICFabricTransport{Config: config, IdleTTL: defaultQUICFabricConnIdleTTL, MaxStreamsPerConn: defaultQUICFabricMaxStreamsPerConn, conns: map[string]*quicFabricConnEntry{}, reverseConns: map[string]*quicFabricConnEntry{}}
|
||||
return &QUICFabricTransport{Config: defaultQUICFabricConfig(config), IdleTTL: defaultQUICFabricConnIdleTTL, MaxStreamsPerConn: defaultQUICFabricMaxStreamsPerConn, conns: map[string]*quicFabricConnEntry{}, reverseConns: map[string]*quicFabricConnEntry{}}
|
||||
}
|
||||
|
||||
func defaultQUICFabricConfig(config *quic.Config) *quic.Config {
|
||||
out := &quic.Config{}
|
||||
if config != nil {
|
||||
clone := *config
|
||||
out = &clone
|
||||
}
|
||||
if out.HandshakeIdleTimeout <= 0 {
|
||||
out.HandshakeIdleTimeout = defaultQUICFabricHandshakeIdleTimeout
|
||||
}
|
||||
if out.MaxIdleTimeout <= 0 {
|
||||
out.MaxIdleTimeout = defaultQUICFabricMaxIdleTimeout
|
||||
}
|
||||
if out.KeepAlivePeriod <= 0 {
|
||||
out.KeepAlivePeriod = defaultQUICFabricKeepAlivePeriod
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (t *QUICFabricTransport) SetInboundHandlers(production func(context.Context, ProductionEnvelope) (ProductionForwardResult, error), synthetic func(context.Context, SyntheticEnvelope) (SyntheticEnvelope, error), logger FabricSessionEventLogger) {
|
||||
@@ -150,6 +171,7 @@ func quicTLSConfigForTarget(target FabricTransportTarget) *tls.Config {
|
||||
expectedFingerprint := normalizeCertSHA256(target.PeerCertSHA256)
|
||||
config := &tls.Config{NextProtos: []string{fabricQUICNextProto}}
|
||||
if expectedFingerprint == "" {
|
||||
config.InsecureSkipVerify = true
|
||||
return config
|
||||
}
|
||||
config.InsecureSkipVerify = true
|
||||
@@ -198,9 +220,12 @@ func (t *QUICFabricTransport) Connect(ctx context.Context, target FabricTranspor
|
||||
stream, err := conn.OpenStreamSync(ctx)
|
||||
if err != nil {
|
||||
t.releaseStream(connKey)
|
||||
t.evictConnByKey(connKey, conn)
|
||||
t.evictConn(target, conn)
|
||||
if closeConn {
|
||||
_ = conn.CloseWithError(1, "open stream failed")
|
||||
} else {
|
||||
_ = conn.CloseWithError(1, "cached stream open failed")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
@@ -680,8 +705,28 @@ func (t *QUICFabricTransport) evictConn(target FabricTransportTarget, conn *quic
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
func (t *QUICFabricTransport) evictConnByKey(key string, conn *quic.Conn) {
|
||||
if t == nil || key == "" || conn == nil {
|
||||
return
|
||||
}
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
if strings.HasPrefix(key, "reverse\x00") {
|
||||
peerID := strings.TrimPrefix(key, "reverse\x00")
|
||||
if entry := t.reverseConns[peerID]; entry != nil && entry.conn == conn {
|
||||
delete(t.reverseConns, peerID)
|
||||
t.stats.ClosedEvicted++
|
||||
}
|
||||
return
|
||||
}
|
||||
if entry := t.conns[key]; entry != nil && entry.conn == conn {
|
||||
delete(t.conns, key)
|
||||
t.stats.ClosedEvicted++
|
||||
}
|
||||
}
|
||||
|
||||
func (t *QUICFabricTransport) pruneIdleLocked(now time.Time) {
|
||||
if t == nil || len(t.conns) == 0 {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
ttl := t.IdleTTL
|
||||
@@ -897,7 +942,13 @@ func (s *quicFabricSession) Send(ctx context.Context, frame fabricproto.Frame) e
|
||||
s.writeMu.Lock()
|
||||
defer s.writeMu.Unlock()
|
||||
s.applyWriteDeadline(ctx)
|
||||
return fabricproto.WriteFrame(s.stream, frame)
|
||||
if err := fabricproto.WriteFrame(s.stream, frame); err != nil {
|
||||
if s.transport != nil && s.conn != nil {
|
||||
s.transport.evictConnByKey(s.connKey, s.conn)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *quicFabricSession) Frames() <-chan fabricproto.Frame {
|
||||
|
||||
Reference in New Issue
Block a user