Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions adapter/endpoint/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
// 在锁外启动 endpoint(监听端口等耗时操作并行化)
if m.started {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
for _, stage := range adapter.ListStartStages {
Expand All @@ -135,22 +134,21 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
}
}
}
// 注册到管理器(锁内,微秒级)
m.access.Lock()
if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
if m.started {
err = existsEndpoint.Close()
if err != nil {
return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
}
_ = existsEndpoint.Close()
}
existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == existsEndpoint
})
if existsIndex == -1 {
panic("invalid endpoint index")
if existsIndex != -1 {
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
}
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
}
m.endpoints = append(m.endpoints, endpoint)
m.endpointByTag[tag] = endpoint
m.access.Unlock()
return nil
}
17 changes: 8 additions & 9 deletions adapter/inbound/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
// 在锁外启动 inbound(监听端口等耗时操作并行化)
if m.started {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
Expand All @@ -137,22 +136,22 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
}
}
}
// 注册到管理器(锁内,微秒级)
m.access.Lock()
if existsInbound, loaded := m.inboundByTag[tag]; loaded {
if m.started {
err = existsInbound.Close()
if err != nil {
return E.Cause(err, "close inbound/", existsInbound.Type(), "[", existsInbound.Tag(), "]")
}
// 旧 inbound 关闭放在锁外会更好,但这里只是 Close 调用,实际耗时在异步清理
_ = existsInbound.Close()
}
existsIndex := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == existsInbound
})
if existsIndex == -1 {
panic("invalid inbound index")
if existsIndex != -1 {
m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
}
m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
}
m.inbounds = append(m.inbounds, inbound)
m.inboundByTag[tag] = inbound
m.access.Unlock()
return nil
}
2 changes: 1 addition & 1 deletion clients/android
Submodule android updated 1 files
+2 −2 version.properties
2 changes: 1 addition & 1 deletion clients/apple
33 changes: 25 additions & 8 deletions common/dialer/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import (
)

var (
_ ParallelInterfaceDialer = (*DefaultDialer)(nil)
_ WireGuardListener = (*DefaultDialer)(nil)
_ ParallelInterfaceDialer = (*DefaultDialer)(nil)
_ WireGuardListener = (*DefaultDialer)(nil)
_ WireGuardListenerWithBind = (*DefaultDialer)(nil)
)

type DefaultDialer struct {
Expand All @@ -35,6 +36,8 @@ type DefaultDialer struct {
udpListener net.ListenConfig
udpAddr4 string
udpAddr6 string
wireguardBindAddr4 netip.Addr
wireguardBindAddr6 netip.Addr
netns string
connectionManager adapter.ConnectionManager
networkManager adapter.NetworkManager
Expand Down Expand Up @@ -178,26 +181,30 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial
listener.Control = control.Append(listener.Control, control.DisableUDPFragment())
}
var (
dialer4 = dialer
udpDialer4 = dialer
udpAddr4 string
dialer4 = dialer
udpDialer4 = dialer
udpAddr4 string
wireguardBindAddr4 netip.Addr
)
if options.Inet4BindAddress != nil {
bindAddr := options.Inet4BindAddress.Build(netip.IPv4Unspecified())
dialer4.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
udpDialer4.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
udpAddr4 = M.SocksaddrFrom(bindAddr, 0).String()
wireguardBindAddr4 = bindAddr
}
var (
dialer6 = dialer
udpDialer6 = dialer
udpAddr6 string
dialer6 = dialer
udpDialer6 = dialer
udpAddr6 string
wireguardBindAddr6 netip.Addr
)
if options.Inet6BindAddress != nil {
bindAddr := options.Inet6BindAddress.Build(netip.IPv6Unspecified())
dialer6.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
udpDialer6.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
udpAddr6 = M.SocksaddrFrom(bindAddr, 0).String()
wireguardBindAddr6 = bindAddr
}
if options.TCPMultiPath {
dialer4.SetMultipathTCP(true)
Expand All @@ -212,6 +219,8 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial
udpListener: listener,
udpAddr4: udpAddr4,
udpAddr6: udpAddr6,
wireguardBindAddr4: wireguardBindAddr4,
wireguardBindAddr6: wireguardBindAddr6,
netns: options.NetNs,
connectionManager: connectionManager,
networkManager: networkManager,
Expand Down Expand Up @@ -375,6 +384,14 @@ func (d *DefaultDialer) WireGuardControl() control.Func {
return d.udpListener.Control
}

func (d *DefaultDialer) WireGuardBindAddress4() (netip.Addr, bool) {
return d.wireguardBindAddr4, d.wireguardBindAddr4.IsValid()
}

func (d *DefaultDialer) WireGuardBindAddress6() (netip.Addr, bool) {
return d.wireguardBindAddr6, d.wireguardBindAddr6.IsValid()
}

func (d *DefaultDialer) trackConn(conn net.Conn, err error) (net.Conn, error) {
if d.connectionManager == nil || err != nil {
return conn, err
Expand Down
23 changes: 23 additions & 0 deletions common/dialer/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package dialer
import (
"context"
"net"
"net/netip"
"sync"
"time"

"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
Expand Down Expand Up @@ -139,6 +141,27 @@ func (d *resolveDialer) Upstream() any {
return d.dialer
}

func (d *resolveDialer) WireGuardControl() control.Func {
if wg, ok := d.dialer.(WireGuardListener); ok {
return wg.WireGuardControl()
}
return nil
}

func (d *resolveDialer) WireGuardBindAddress4() (netip.Addr, bool) {
if wg, ok := d.dialer.(WireGuardListenerWithBind); ok {
return wg.WireGuardBindAddress4()
}
return netip.Addr{}, false
}

func (d *resolveDialer) WireGuardBindAddress6() (netip.Addr, bool) {
if wg, ok := d.dialer.(WireGuardListenerWithBind); ok {
return wg.WireGuardBindAddress6()
}
return netip.Addr{}, false
}

func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error) {
err := d.initialize()
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions common/dialer/wireguard.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package dialer

import (
"net/netip"

"github.com/sagernet/sing/common/control"
)

type WireGuardListener interface {
WireGuardControl() control.Func
}

// WireGuardListenerWithBind 支持绑定到指定 IP(同网卡多 IP 场景)
type WireGuardListenerWithBind interface {
WireGuardListener
WireGuardBindAddress4() (netip.Addr, bool)
WireGuardBindAddress6() (netip.Addr, bool)
}
Loading