sing-box/common/dialer/dialer.go

104 lines
4 KiB
Go
Raw Normal View History

package dialer
import (
"context"
2024-11-12 19:37:10 +08:00
"net"
"net/netip"
2022-07-08 12:58:43 +08:00
"time"
2022-07-06 15:01:09 +08:00
"github.com/sagernet/sing-box/adapter"
2024-11-12 19:37:10 +08:00
C "github.com/sagernet/sing-box/constant"
2025-01-12 12:45:27 +08:00
"github.com/sagernet/sing-box/experimental/deprecated"
2022-07-06 15:01:09 +08:00
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
2024-11-12 19:37:10 +08:00
M "github.com/sagernet/sing/common/metadata"
2022-07-08 23:03:57 +08:00
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"
)
2025-01-12 12:45:27 +08:00
func New(ctx context.Context, options option.DialerOptions, remoteIsDomain bool) (N.Dialer, error) {
if options.IsWireGuardListener {
2024-12-15 00:45:41 +08:00
return NewDefault(ctx, options)
}
2023-08-08 16:14:03 +08:00
var (
dialer N.Dialer
err error
)
2025-01-12 12:45:27 +08:00
if options.Detour != "" {
outboundManager := service.FromContext[adapter.OutboundManager](ctx)
if outboundManager == nil {
return nil, E.New("missing outbound manager")
}
dialer = NewDetour(outboundManager, options.Detour)
2025-01-12 12:45:27 +08:00
} else {
dialer, err = NewDefault(ctx, options)
if err != nil {
return nil, err
}
}
2025-01-12 12:45:27 +08:00
if remoteIsDomain && options.Detour == "" {
networkManager := service.FromContext[adapter.NetworkManager](ctx)
dnsTransport := service.FromContext[adapter.DNSTransportManager](ctx)
var defaultOptions adapter.NetworkOptions
if networkManager != nil {
defaultOptions = networkManager.DefaultOptions()
}
var (
dnsQueryOptions adapter.DNSQueryOptions
resolveFallbackDelay time.Duration
)
if options.DomainResolver != nil && options.DomainResolver.Server != "" {
transport, loaded := dnsTransport.Transport(options.DomainResolver.Server)
if !loaded {
return nil, E.New("domain resolver not found: " + options.DomainResolver.Server)
}
var strategy C.DomainStrategy
if options.DomainResolver.Strategy != option.DomainStrategy(C.DomainStrategyAsIS) {
strategy = C.DomainStrategy(options.DomainResolver.Strategy)
} else if
//nolint:staticcheck
options.DomainStrategy != option.DomainStrategy(C.DomainStrategyAsIS) {
//nolint:staticcheck
strategy = C.DomainStrategy(options.DomainStrategy)
}
dnsQueryOptions = adapter.DNSQueryOptions{
Transport: transport,
Strategy: strategy,
DisableCache: options.DomainResolver.DisableCache,
RewriteTTL: options.DomainResolver.RewriteTTL,
ClientSubnet: options.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
}
resolveFallbackDelay = time.Duration(options.FallbackDelay)
} else if defaultOptions.DomainResolver != "" {
dnsQueryOptions = defaultOptions.DomainResolveOptions
transport, loaded := dnsTransport.Transport(defaultOptions.DomainResolver)
if !loaded {
return nil, E.New("default domain resolver not found: " + defaultOptions.DomainResolver)
}
dnsQueryOptions.Transport = transport
resolveFallbackDelay = time.Duration(options.FallbackDelay)
} else {
deprecated.Report(ctx, deprecated.OptionMissingDomainResolver)
2024-11-10 12:11:21 +08:00
}
2025-01-12 12:45:27 +08:00
dialer = NewResolveDialer(
ctx,
dialer,
options.Detour == "" && !options.TCPFastOpen,
dnsQueryOptions,
resolveFallbackDelay,
)
}
2023-08-08 16:14:03 +08:00
return dialer, nil
}
2024-11-12 19:37:10 +08:00
type ParallelInterfaceDialer interface {
N.Dialer
2024-12-15 00:45:41 +08:00
DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
ListenSerialInterfacePacket(ctx context.Context, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error)
2024-11-12 19:37:10 +08:00
}
type ParallelNetworkDialer interface {
2024-12-15 00:45:41 +08:00
DialParallelNetwork(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
ListenSerialNetworkPacket(ctx context.Context, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, netip.Addr, error)
2024-11-12 19:37:10 +08:00
}