mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-12 20:26:37 +08:00
fix(agent): retire replaced tunnel sessions (#541)
This commit is contained in:
@@ -19,20 +19,23 @@ func (session *muxSession) Accept() (net.Conn, error) {
|
||||
}
|
||||
|
||||
func (session *muxSession) Close() error {
|
||||
if session.session == nil {
|
||||
if session == nil || session.session == nil {
|
||||
return nil
|
||||
}
|
||||
return session.session.Close()
|
||||
}
|
||||
|
||||
func (session *muxSession) IsClosed() bool {
|
||||
if session.session == nil {
|
||||
if session == nil || session.session == nil {
|
||||
return true
|
||||
}
|
||||
return session.session.IsClosed()
|
||||
}
|
||||
|
||||
func (session *muxSession) NumStreams() int {
|
||||
if session == nil || session.session == nil {
|
||||
return 0
|
||||
}
|
||||
return session.session.NumStreams()
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
kcp_util "github.com/go-gost/x/internal/util/kcp"
|
||||
"github.com/go-gost/x/internal/util/sessionretire"
|
||||
mdutil "github.com/go-gost/x/metadata/util"
|
||||
"github.com/go-gost/x/registry"
|
||||
"github.com/xtaci/kcp-go/v5"
|
||||
@@ -25,6 +26,7 @@ func init() {
|
||||
type kcpDialer struct {
|
||||
sessions map[string]*muxSession
|
||||
sessionMutex sync.Mutex
|
||||
retired bool
|
||||
logger logger.Logger
|
||||
md metadata
|
||||
options dialer.Options
|
||||
@@ -64,6 +66,9 @@ func (d *kcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
|
||||
d.sessionMutex.Lock()
|
||||
defer d.sessionMutex.Unlock()
|
||||
if d.retired {
|
||||
return nil, net.ErrClosed
|
||||
}
|
||||
|
||||
session, ok := d.sessions[addr]
|
||||
if session != nil && session.IsClosed() {
|
||||
@@ -171,3 +176,36 @@ func (d *kcpDialer) initSession(ctx context.Context, addr net.Addr, conn net.Pac
|
||||
func (d *kcpDialer) Multiplex() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Retire drains existing streams and closes their backing sessions once idle.
|
||||
func (d *kcpDialer) Retire() {
|
||||
for _, session := range d.detachSessions() {
|
||||
sessionretire.Gracefully(session)
|
||||
}
|
||||
}
|
||||
|
||||
// Close immediately releases all cached multiplex sessions.
|
||||
func (d *kcpDialer) Close() error {
|
||||
var errs []error
|
||||
for _, session := range d.detachSessions() {
|
||||
errs = append(errs, session.Close())
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (d *kcpDialer) detachSessions() []*muxSession {
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
d.sessionMutex.Lock()
|
||||
d.retired = true
|
||||
sessions := make([]*muxSession, 0, len(d.sessions))
|
||||
for _, session := range d.sessions {
|
||||
if session != nil {
|
||||
sessions = append(sessions, session)
|
||||
}
|
||||
}
|
||||
d.sessions = make(map[string]*muxSession)
|
||||
d.sessionMutex.Unlock()
|
||||
return sessions
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package kcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRetiredDialerRejectsNewConnections(t *testing.T) {
|
||||
dialer := NewDialer().(*kcpDialer)
|
||||
dialer.Retire()
|
||||
|
||||
if _, err := dialer.Dial(context.Background(), "127.0.0.1:1"); !errors.Is(err, net.ErrClosed) {
|
||||
t.Fatalf("Dial error = %v, want net.ErrClosed", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user