mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-10-28 05:56:58 +00:00
Improve idle connection management
This commit is contained in:
@@ -13,7 +13,6 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/protocol/tuic"
|
||||
"github.com/sagernet/sing-quic/hysteria"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
@@ -28,9 +27,10 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
}
|
||||
|
||||
var (
|
||||
_ adapter.Outbound = (*tuic.Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*tuic.Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.Outbound = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -119,6 +119,14 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
h.client.CloseWithError(E.New("network changed"))
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
h.client.SetKeepIdleConnections(keep)
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
h.client.CloseIdleConnections()
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/protocol/tuic"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/hysteria"
|
||||
"github.com/sagernet/sing-quic/hysteria2"
|
||||
@@ -35,9 +34,10 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
}
|
||||
|
||||
var (
|
||||
_ adapter.Outbound = (*tuic.Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*tuic.Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.Outbound = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -211,6 +211,14 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
h.client.CloseWithError(E.New("network changed"))
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
h.client.SetKeepIdleConnections(keep)
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
h.client.CloseIdleConnections()
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
var (
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -140,6 +140,12 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.SetKeepIdleConnections(keep)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.CloseIdleConnections()
|
||||
|
||||
@@ -30,17 +30,20 @@ type Outbound struct {
|
||||
dialer N.Dialer
|
||||
client snellClient
|
||||
serverAddr M.Socksaddr
|
||||
reuse bool
|
||||
}
|
||||
|
||||
var (
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type snellClient interface {
|
||||
snellprotocol.Method
|
||||
DialContext(ctx context.Context, destination M.Socksaddr) (net.Conn, error)
|
||||
Reset()
|
||||
SetKeepIdleConnections(keep bool)
|
||||
CloseIdleConnections()
|
||||
Close() error
|
||||
}
|
||||
@@ -96,6 +99,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
dialer: outboundDialer,
|
||||
client: client,
|
||||
serverAddr: serverAddr,
|
||||
reuse: options.Reuse,
|
||||
}
|
||||
return outbound, nil
|
||||
}
|
||||
@@ -147,6 +151,14 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
h.client.Reset()
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.reuse
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
h.client.SetKeepIdleConnections(keep)
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
h.client.CloseIdleConnections()
|
||||
}
|
||||
|
||||
+22
-14
@@ -34,7 +34,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
|
||||
var (
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -54,7 +55,7 @@ type Outbound struct {
|
||||
clientConn net.Conn
|
||||
client *ssh.Client
|
||||
streams int
|
||||
draining bool
|
||||
closeIdle bool
|
||||
}
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (adapter.Outbound, error) {
|
||||
@@ -137,7 +138,6 @@ func (s *Outbound) connect(ctx context.Context) (client *ssh.Client, err error)
|
||||
|
||||
if s.client != nil {
|
||||
s.streams++
|
||||
s.draining = false
|
||||
return s.client, nil
|
||||
}
|
||||
|
||||
@@ -197,7 +197,6 @@ func (s *Outbound) connect(ctx context.Context) (client *ssh.Client, err error)
|
||||
s.clientConn = conn
|
||||
s.client = client
|
||||
s.streams = 1
|
||||
s.draining = false
|
||||
|
||||
go func() {
|
||||
client.Wait()
|
||||
@@ -217,14 +216,22 @@ func (s *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
common.Close(s.clientConn)
|
||||
}
|
||||
|
||||
func (s *Outbound) MultiplexEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
s.clientAccess.Lock()
|
||||
s.closeIdle = !keep
|
||||
s.clientAccess.Unlock()
|
||||
if !keep {
|
||||
s.CloseIdleConnections()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Outbound) CloseIdleConnections() {
|
||||
s.clientAccess.Lock()
|
||||
if s.client == nil {
|
||||
s.clientAccess.Unlock()
|
||||
return
|
||||
}
|
||||
s.draining = true
|
||||
if s.streams > 0 {
|
||||
if s.client == nil || s.streams > 0 {
|
||||
s.clientAccess.Unlock()
|
||||
return
|
||||
}
|
||||
@@ -235,14 +242,14 @@ func (s *Outbound) CloseIdleConnections() {
|
||||
common.Close(clientConn)
|
||||
}
|
||||
|
||||
func (s *Outbound) releaseStream(client *ssh.Client) {
|
||||
func (s *Outbound) releaseStream(client *ssh.Client, keepSession bool) {
|
||||
s.clientAccess.Lock()
|
||||
if s.client != client {
|
||||
s.clientAccess.Unlock()
|
||||
return
|
||||
}
|
||||
s.streams--
|
||||
if !s.draining || s.streams > 0 {
|
||||
if !s.closeIdle || keepSession || s.streams > 0 {
|
||||
s.clientAccess.Unlock()
|
||||
return
|
||||
}
|
||||
@@ -264,10 +271,11 @@ func (s *Outbound) DialContext(ctx context.Context, network string, destination
|
||||
}
|
||||
conn, err := client.Dial(network, destination.String())
|
||||
if err != nil {
|
||||
s.releaseStream(client)
|
||||
s.releaseStream(client, false)
|
||||
return nil, err
|
||||
}
|
||||
return &chanConnWrapper{Conn: conn, onClose: func() { s.releaseStream(client) }}, nil
|
||||
keepSession := adapter.KeepSessionFromContext(ctx)
|
||||
return &chanConnWrapper{Conn: conn, onClose: func() { s.releaseStream(client, keepSession) }}, nil
|
||||
}
|
||||
|
||||
func (s *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
|
||||
@@ -29,7 +29,7 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
var (
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -114,7 +114,11 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
if h.multiplexDialer != nil {
|
||||
return true
|
||||
}
|
||||
multiplexTransport, isMultiplexTransport := h.transport.(adapter.V2RayMultiplexClientTransport)
|
||||
return isMultiplexTransport && multiplexTransport.MultiplexEnabled()
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
@@ -126,10 +130,20 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.SetKeepIdleConnections(keep)
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.SetKeepIdleConnections(keep)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
transportCloser, isTransportCloser := h.transport.(adapter.IdleConnectionCloser)
|
||||
if isTransportCloser {
|
||||
transportCloser.CloseIdleConnections()
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.CloseIdleConnections()
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.CloseIdleConnections()
|
||||
|
||||
@@ -32,7 +32,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
|
||||
var (
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -148,6 +149,14 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
_ = h.client.CloseWithError(E.New("network changed"))
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
h.client.SetKeepIdleConnections(keep)
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
h.client.CloseIdleConnections()
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
var (
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -134,7 +134,11 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
if h.multiplexDialer != nil {
|
||||
return true
|
||||
}
|
||||
multiplexTransport, isMultiplexTransport := h.transport.(adapter.V2RayMultiplexClientTransport)
|
||||
return isMultiplexTransport && multiplexTransport.MultiplexEnabled()
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
@@ -146,10 +150,20 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.SetKeepIdleConnections(keep)
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.SetKeepIdleConnections(keep)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
transportCloser, isTransportCloser := h.transport.(adapter.IdleConnectionCloser)
|
||||
if isTransportCloser {
|
||||
transportCloser.CloseIdleConnections()
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.CloseIdleConnections()
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.CloseIdleConnections()
|
||||
|
||||
@@ -30,7 +30,7 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
var (
|
||||
_ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionCloser = (*Outbound)(nil)
|
||||
_ adapter.IdleConnectionKeeper = (*Outbound)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
@@ -112,7 +112,11 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
if h.multiplexDialer != nil {
|
||||
return true
|
||||
}
|
||||
multiplexTransport, isMultiplexTransport := h.transport.(adapter.V2RayMultiplexClientTransport)
|
||||
return isMultiplexTransport && multiplexTransport.MultiplexEnabled()
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
@@ -124,10 +128,20 @@ func (h *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) SetKeepIdleConnections(keep bool) {
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.SetKeepIdleConnections(keep)
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.SetKeepIdleConnections(keep)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) CloseIdleConnections() {
|
||||
transportCloser, isTransportCloser := h.transport.(adapter.IdleConnectionCloser)
|
||||
if isTransportCloser {
|
||||
transportCloser.CloseIdleConnections()
|
||||
transportKeeper, isTransportKeeper := h.transport.(adapter.IdleConnectionKeeper)
|
||||
if isTransportKeeper {
|
||||
transportKeeper.CloseIdleConnections()
|
||||
}
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.CloseIdleConnections()
|
||||
|
||||
Reference in New Issue
Block a user