mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-04-01 19:07:35 +03:00
Explicitly reject detour to empty direct outbounds
This commit is contained in:
parent
acf433fb83
commit
b710519728
20 changed files with 142 additions and 65 deletions
|
@ -45,10 +45,10 @@ type RDRCStore interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSTransport interface {
|
type DNSTransport interface {
|
||||||
|
Lifecycle
|
||||||
Type() string
|
Type() string
|
||||||
Tag() string
|
Tag() string
|
||||||
Dependencies() []string
|
Dependencies() []string
|
||||||
Reset()
|
|
||||||
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
|
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,26 +6,39 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DirectDialer interface {
|
||||||
|
IsEmpty() bool
|
||||||
|
}
|
||||||
|
|
||||||
type DetourDialer struct {
|
type DetourDialer struct {
|
||||||
outboundManager adapter.OutboundManager
|
outboundManager adapter.OutboundManager
|
||||||
detour string
|
detour string
|
||||||
|
legacyDNSDialer bool
|
||||||
dialer N.Dialer
|
dialer N.Dialer
|
||||||
initOnce sync.Once
|
initOnce sync.Once
|
||||||
initErr error
|
initErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDetour(outboundManager adapter.OutboundManager, detour string) N.Dialer {
|
func NewDetour(outboundManager adapter.OutboundManager, detour string, legacyDNSDialer bool) N.Dialer {
|
||||||
return &DetourDialer{outboundManager: outboundManager, detour: detour}
|
return &DetourDialer{
|
||||||
|
outboundManager: outboundManager,
|
||||||
|
detour: detour,
|
||||||
|
legacyDNSDialer: legacyDNSDialer,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DetourDialer) Start() error {
|
func InitializeDetour(dialer N.Dialer) error {
|
||||||
_, err := d.Dialer()
|
detourDialer, isDetour := common.Cast[*DetourDialer](dialer)
|
||||||
return err
|
if !isDetour {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return common.Error(detourDialer.Dialer())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DetourDialer) Dialer() (N.Dialer, error) {
|
func (d *DetourDialer) Dialer() (N.Dialer, error) {
|
||||||
|
@ -34,11 +47,20 @@ func (d *DetourDialer) Dialer() (N.Dialer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DetourDialer) init() {
|
func (d *DetourDialer) init() {
|
||||||
var loaded bool
|
dialer, loaded := d.outboundManager.Outbound(d.detour)
|
||||||
d.dialer, loaded = d.outboundManager.Outbound(d.detour)
|
|
||||||
if !loaded {
|
if !loaded {
|
||||||
d.initErr = E.New("outbound detour not found: ", d.detour)
|
d.initErr = E.New("outbound detour not found: ", d.detour)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if !d.legacyDNSDialer {
|
||||||
|
if directDialer, isDirect := dialer.(DirectDialer); isDirect {
|
||||||
|
if directDialer.IsEmpty() {
|
||||||
|
d.initErr = E.New("detour to an empty direct outbound makes no sense")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.dialer = dialer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DetourDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
func (d *DetourDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ type Options struct {
|
||||||
DirectResolver bool
|
DirectResolver bool
|
||||||
ResolverOnDetour bool
|
ResolverOnDetour bool
|
||||||
NewDialer bool
|
NewDialer bool
|
||||||
|
LegacyDNSDialer bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: merge with NewWithOptions
|
// TODO: merge with NewWithOptions
|
||||||
|
@ -45,7 +46,7 @@ func NewWithOptions(options Options) (N.Dialer, error) {
|
||||||
if outboundManager == nil {
|
if outboundManager == nil {
|
||||||
return nil, E.New("missing outbound manager")
|
return nil, E.New("missing outbound manager")
|
||||||
}
|
}
|
||||||
dialer = NewDetour(outboundManager, dialOptions.Detour)
|
dialer = NewDetour(outboundManager, dialOptions.Detour, options.LegacyDNSDialer)
|
||||||
} else {
|
} else {
|
||||||
dialer, err = NewDefault(options.Context, dialOptions)
|
dialer, err = NewDefault(options.Context, dialOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -449,6 +449,6 @@ func (r *Router) LookupReverseMapping(ip netip.Addr) (string, bool) {
|
||||||
func (r *Router) ResetNetwork() {
|
func (r *Router) ResetNetwork() {
|
||||||
r.ClearCache()
|
r.ClearCache()
|
||||||
for _, transport := range r.transport.Transports() {
|
for _, transport := range r.transport.Transports() {
|
||||||
transport.Reset()
|
transport.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func (t *Transport) Start(stage adapter.StartStage) error {
|
||||||
|
|
||||||
func (t *Transport) Close() error {
|
func (t *Transport) Close() error {
|
||||||
for _, transport := range t.transports {
|
for _, transport := range t.transports {
|
||||||
transport.Reset()
|
transport.Close()
|
||||||
}
|
}
|
||||||
if t.interfaceCallback != nil {
|
if t.interfaceCallback != nil {
|
||||||
t.networkManager.InterfaceMonitor().UnregisterCallback(t.interfaceCallback)
|
t.networkManager.InterfaceMonitor().UnregisterCallback(t.interfaceCallback)
|
||||||
|
@ -89,12 +89,6 @@ func (t *Transport) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Reset() {
|
|
||||||
for _, transport := range t.transports {
|
|
||||||
transport.Reset()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
err := t.fetchServers()
|
err := t.fetchServers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -252,7 +246,7 @@ func (t *Transport) recreateServers(iface *control.Interface, serverAddrs []M.So
|
||||||
transports = append(transports, transport.NewUDPRaw(t.logger, t.TransportAdapter, serverDialer, serverAddr))
|
transports = append(transports, transport.NewUDPRaw(t.logger, t.TransportAdapter, serverDialer, serverAddr))
|
||||||
}
|
}
|
||||||
for _, transport := range t.transports {
|
for _, transport := range t.transports {
|
||||||
transport.Reset()
|
transport.Close()
|
||||||
}
|
}
|
||||||
t.transports = transports
|
t.transports = transports
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -51,7 +51,12 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Reset() {
|
func (t *Transport) Start(stage adapter.StartStage) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transport) Close() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
"github.com/sagernet/sing-box/common/tls"
|
"github.com/sagernet/sing-box/common/tls"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/dns"
|
"github.com/sagernet/sing-box/dns"
|
||||||
|
@ -149,9 +150,17 @@ func NewHTTPSRaw(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HTTPSTransport) Reset() {
|
func (t *HTTPSTransport) Start(stage adapter.StartStage) error {
|
||||||
|
if stage != adapter.StartStateStart {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return dialer.InitializeDetour(t.dialer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HTTPSTransport) Close() error {
|
||||||
t.transport.CloseIdleConnections()
|
t.transport.CloseIdleConnections()
|
||||||
t.transport = t.transport.Clone()
|
t.transport = t.transport.Clone()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -40,7 +40,12 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Reset() {
|
func (t *Transport) Start(stage adapter.StartStage) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transport) Close() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -111,8 +111,12 @@ func NewHTTP3(ctx context.Context, logger log.ContextLogger, tag string, options
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HTTP3Transport) Reset() {
|
func (t *HTTP3Transport) Start(stage adapter.StartStage) error {
|
||||||
t.transport.Close()
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HTTP3Transport) Close() error {
|
||||||
|
return t.transport.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HTTP3Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *HTTP3Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -68,13 +68,18 @@ func NewQUIC(ctx context.Context, logger log.ContextLogger, tag string, options
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Reset() {
|
func (t *Transport) Start(stage adapter.StartStage) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transport) Close() error {
|
||||||
t.access.Lock()
|
t.access.Lock()
|
||||||
defer t.access.Unlock()
|
defer t.access.Unlock()
|
||||||
connection := t.connection
|
connection := t.connection
|
||||||
if connection != nil {
|
if connection != nil {
|
||||||
connection.CloseWithError(0, "")
|
connection.CloseWithError(0, "")
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/dns"
|
"github.com/sagernet/sing-box/dns"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
|
@ -46,7 +47,15 @@ func NewTCP(ctx context.Context, logger log.ContextLogger, tag string, options o
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TCPTransport) Reset() {
|
func (t *TCPTransport) Start(stage adapter.StartStage) error {
|
||||||
|
if stage != adapter.StartStateStart {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return dialer.InitializeDetour(t.dialer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCPTransport) Close() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TCPTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *TCPTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
"github.com/sagernet/sing-box/common/tls"
|
"github.com/sagernet/sing-box/common/tls"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/dns"
|
"github.com/sagernet/sing-box/dns"
|
||||||
|
@ -65,13 +66,21 @@ func NewTLS(ctx context.Context, logger log.ContextLogger, tag string, options o
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TLSTransport) Reset() {
|
func (t *TLSTransport) Start(stage adapter.StartStage) error {
|
||||||
|
if stage != adapter.StartStateStart {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return dialer.InitializeDetour(t.dialer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TLSTransport) Close() error {
|
||||||
t.access.Lock()
|
t.access.Lock()
|
||||||
defer t.access.Unlock()
|
defer t.access.Unlock()
|
||||||
for connection := t.connections.Front(); connection != nil; connection = connection.Next() {
|
for connection := t.connections.Front(); connection != nil; connection = connection.Next() {
|
||||||
connection.Value.Close()
|
connection.Value.Close()
|
||||||
}
|
}
|
||||||
t.connections.Init()
|
t.connections.Init()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TLSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *TLSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/dns"
|
"github.com/sagernet/sing-box/dns"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
|
@ -64,11 +65,19 @@ func NewUDPRaw(logger logger.ContextLogger, adapter dns.TransportAdapter, dialer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *UDPTransport) Reset() {
|
func (t *UDPTransport) Start(stage adapter.StartStage) error {
|
||||||
|
if stage != adapter.StartStateStart {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return dialer.InitializeDetour(t.dialer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *UDPTransport) Close() error {
|
||||||
t.access.Lock()
|
t.access.Lock()
|
||||||
defer t.access.Unlock()
|
defer t.access.Unlock()
|
||||||
close(t.done)
|
close(t.done)
|
||||||
t.done = make(chan struct{})
|
t.done = make(chan struct{})
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *UDPTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (t *UDPTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -20,9 +20,10 @@ func NewLocalDialer(ctx context.Context, options option.LocalDNSServerOptions) (
|
||||||
return dialer.NewDefaultOutbound(ctx), nil
|
return dialer.NewDefaultOutbound(ctx), nil
|
||||||
} else {
|
} else {
|
||||||
return dialer.NewWithOptions(dialer.Options{
|
return dialer.NewWithOptions(dialer.Options{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Options: options.DialerOptions,
|
Options: options.DialerOptions,
|
||||||
DirectResolver: true,
|
DirectResolver: true,
|
||||||
|
LegacyDNSDialer: options.Legacy,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,10 +44,11 @@ func NewRemoteDialer(ctx context.Context, options option.RemoteDNSServerOptions)
|
||||||
return transportDialer, nil
|
return transportDialer, nil
|
||||||
} else {
|
} else {
|
||||||
return dialer.NewWithOptions(dialer.Options{
|
return dialer.NewWithOptions(dialer.Options{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Options: options.DialerOptions,
|
Options: options.DialerOptions,
|
||||||
RemoteIsDomain: options.ServerIsDomain(),
|
RemoteIsDomain: options.ServerIsDomain(),
|
||||||
DirectResolver: true,
|
DirectResolver: true,
|
||||||
|
LegacyDNSDialer: options.Legacy,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ func (m *TransportManager) Remove(tag string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if started {
|
if started {
|
||||||
transport.Reset()
|
transport.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,12 @@ func newPlatformTransport(iif LocalDNSTransport, tag string, options option.Loca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *platformTransport) Reset() {
|
func (p *platformTransport) Start(stage adapter.StartStage) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *platformTransport) Close() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||||
|
|
|
@ -191,34 +191,24 @@ func (o *DNSServerOptions) Upgrade(ctx context.Context) error {
|
||||||
serverType = C.DNSTypeUDP
|
serverType = C.DNSTypeUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var remoteOptions RemoteDNSServerOptions
|
remoteOptions := RemoteDNSServerOptions{
|
||||||
if options.Detour == "" {
|
LocalDNSServerOptions: LocalDNSServerOptions{
|
||||||
remoteOptions = RemoteDNSServerOptions{
|
DialerOptions: DialerOptions{
|
||||||
LocalDNSServerOptions: LocalDNSServerOptions{
|
Detour: options.Detour,
|
||||||
LegacyStrategy: options.Strategy,
|
DomainResolver: &DomainResolveOptions{
|
||||||
LegacyDefaultDialer: options.Detour == "",
|
Server: options.AddressResolver,
|
||||||
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
Strategy: options.AddressStrategy,
|
||||||
},
|
|
||||||
LegacyAddressResolver: options.AddressResolver,
|
|
||||||
LegacyAddressStrategy: options.AddressStrategy,
|
|
||||||
LegacyAddressFallbackDelay: options.AddressFallbackDelay,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
remoteOptions = RemoteDNSServerOptions{
|
|
||||||
LocalDNSServerOptions: LocalDNSServerOptions{
|
|
||||||
DialerOptions: DialerOptions{
|
|
||||||
Detour: options.Detour,
|
|
||||||
DomainResolver: &DomainResolveOptions{
|
|
||||||
Server: options.AddressResolver,
|
|
||||||
Strategy: options.AddressStrategy,
|
|
||||||
},
|
|
||||||
FallbackDelay: options.AddressFallbackDelay,
|
|
||||||
},
|
},
|
||||||
LegacyStrategy: options.Strategy,
|
FallbackDelay: options.AddressFallbackDelay,
|
||||||
LegacyDefaultDialer: options.Detour == "",
|
|
||||||
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
|
||||||
},
|
},
|
||||||
}
|
Legacy: true,
|
||||||
|
LegacyStrategy: options.Strategy,
|
||||||
|
LegacyDefaultDialer: options.Detour == "",
|
||||||
|
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
||||||
|
},
|
||||||
|
LegacyAddressResolver: options.AddressResolver,
|
||||||
|
LegacyAddressStrategy: options.AddressStrategy,
|
||||||
|
LegacyAddressFallbackDelay: options.AddressFallbackDelay,
|
||||||
}
|
}
|
||||||
switch serverType {
|
switch serverType {
|
||||||
case C.DNSTypeLocal:
|
case C.DNSTypeLocal:
|
||||||
|
@ -362,6 +352,7 @@ type HostsDNSServerOptions struct {
|
||||||
|
|
||||||
type LocalDNSServerOptions struct {
|
type LocalDNSServerOptions struct {
|
||||||
DialerOptions
|
DialerOptions
|
||||||
|
Legacy bool `json:"-"`
|
||||||
LegacyStrategy DomainStrategy `json:"-"`
|
LegacyStrategy DomainStrategy `json:"-"`
|
||||||
LegacyDefaultDialer bool `json:"-"`
|
LegacyDefaultDialer bool `json:"-"`
|
||||||
LegacyClientSubnet netip.Prefix `json:"-"`
|
LegacyClientSubnet netip.Prefix `json:"-"`
|
||||||
|
|
|
@ -125,10 +125,9 @@ func (r *DefaultRule) UnmarshalJSON(data []byte) error {
|
||||||
return badjson.UnmarshallExcluded(data, &r.RawDefaultRule, &r.RuleAction)
|
return badjson.UnmarshallExcluded(data, &r.RawDefaultRule, &r.RuleAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DefaultRule) IsValid() bool {
|
func (r DefaultRule) IsValid() bool {
|
||||||
var defaultValue DefaultRule
|
var defaultValue DefaultRule
|
||||||
defaultValue.Invert = r.Invert
|
defaultValue.Invert = r.Invert
|
||||||
defaultValue.Action = r.Action
|
|
||||||
return !reflect.DeepEqual(r, defaultValue)
|
return !reflect.DeepEqual(r, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,6 @@ func (r *DefaultDNSRule) UnmarshalJSONContext(ctx context.Context, data []byte)
|
||||||
func (r DefaultDNSRule) IsValid() bool {
|
func (r DefaultDNSRule) IsValid() bool {
|
||||||
var defaultValue DefaultDNSRule
|
var defaultValue DefaultDNSRule
|
||||||
defaultValue.Invert = r.Invert
|
defaultValue.Invert = r.Invert
|
||||||
defaultValue.DNSRuleAction = r.DNSRuleAction
|
|
||||||
return !reflect.DeepEqual(r, defaultValue)
|
return !reflect.DeepEqual(r, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
@ -27,6 +28,7 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||||
var (
|
var (
|
||||||
_ N.ParallelDialer = (*Outbound)(nil)
|
_ N.ParallelDialer = (*Outbound)(nil)
|
||||||
_ dialer.ParallelNetworkDialer = (*Outbound)(nil)
|
_ dialer.ParallelNetworkDialer = (*Outbound)(nil)
|
||||||
|
_ dialer.DirectDialer = (*Outbound)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
type Outbound struct {
|
type Outbound struct {
|
||||||
|
@ -37,6 +39,7 @@ type Outbound struct {
|
||||||
fallbackDelay time.Duration
|
fallbackDelay time.Duration
|
||||||
overrideOption int
|
overrideOption int
|
||||||
overrideDestination M.Socksaddr
|
overrideDestination M.Socksaddr
|
||||||
|
isEmpty bool
|
||||||
// loopBack *loopBackDetector
|
// loopBack *loopBackDetector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +59,8 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||||
domainStrategy: C.DomainStrategy(options.DomainStrategy),
|
domainStrategy: C.DomainStrategy(options.DomainStrategy),
|
||||||
fallbackDelay: time.Duration(options.FallbackDelay),
|
fallbackDelay: time.Duration(options.FallbackDelay),
|
||||||
dialer: outboundDialer.(dialer.ParallelInterfaceDialer),
|
dialer: outboundDialer.(dialer.ParallelInterfaceDialer),
|
||||||
|
//nolint:staticcheck
|
||||||
|
isEmpty: reflect.DeepEqual(options.DialerOptions, option.DialerOptions{UDPFragmentDefault: true}) && options.OverrideAddress == "" && options.OverridePort == 0,
|
||||||
// loopBack: newLoopBackDetector(router),
|
// loopBack: newLoopBackDetector(router),
|
||||||
}
|
}
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
|
@ -242,6 +247,10 @@ func (h *Outbound) ListenSerialNetworkPacket(ctx context.Context, destination M.
|
||||||
return conn, newDestination, nil
|
return conn, newDestination, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Outbound) IsEmpty() bool {
|
||||||
|
return h.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
/*func (h *Outbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
/*func (h *Outbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||||
if h.loopBack.CheckConn(metadata.Source.AddrPort(), M.AddrPortFromNet(conn.LocalAddr())) {
|
if h.loopBack.CheckConn(metadata.Source.AddrPort(), M.AddrPortFromNet(conn.LocalAddr())) {
|
||||||
return E.New("reject loopback connection to ", metadata.Destination)
|
return E.New("reject loopback connection to ", metadata.Destination)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue