Refactor bind control

This commit is contained in:
世界 2022-09-14 12:46:02 +08:00
parent 2373281c41
commit 189f02c802
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
16 changed files with 123 additions and 62 deletions

View File

@ -31,7 +31,7 @@ type Router interface {
Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error)
LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error)
InterfaceBindManager() control.BindManager
InterfaceFinder() control.InterfaceFinder
DefaultInterface() string
AutoDetectInterface() bool
DefaultMark() int

View File

@ -3,6 +3,7 @@ package main
import (
"os"
_ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/spf13/cobra"

View File

@ -65,25 +65,23 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
var listener net.ListenConfig
if options.BindInterface != "" {
warnBindInterfaceOnUnsupportedPlatform.Check()
bindFunc := control.BindToInterface(router.InterfaceBindManager(), options.BindInterface)
bindFunc := control.BindToInterface(router.InterfaceFinder(), options.BindInterface, -1)
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
} else if router.AutoDetectInterface() {
if C.IsWindows {
bindFunc := control.BindToInterfaceIndexFunc(func(network, address string) int {
return router.InterfaceMonitor().DefaultInterfaceIndex(M.ParseSocksaddr(address).Addr)
})
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
} else {
bindFunc := control.BindToInterfaceFunc(router.InterfaceBindManager(), func(network, address string) string {
return router.InterfaceMonitor().DefaultInterfaceName(M.ParseSocksaddr(address).Addr)
})
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
}
const useInterfaceName = C.IsLinux
bindFunc := control.BindToInterfaceFunc(router.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int) {
remoteAddr := M.ParseSocksaddr(address).Addr
if C.IsLinux {
return router.InterfaceMonitor().DefaultInterfaceName(remoteAddr), -1
} else {
return "", router.InterfaceMonitor().DefaultInterfaceIndex(remoteAddr)
}
})
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
} else if router.DefaultInterface() != "" {
bindFunc := control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface())
bindFunc := control.BindToInterface(router.InterfaceFinder(), router.DefaultInterface(), -1)
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
}

View File

@ -1,5 +0,0 @@
//go:build with_quic
package constant
const QUIC_AVAILABLE = true

View File

@ -1,9 +0,0 @@
//go:build !with_quic
package constant
import E "github.com/sagernet/sing/common/exceptions"
const QUIC_AVAILABLE = false
var ErrQUICNotIncluded = E.New(`QUIC is not included in this build, rebuild with -tags with_quic`)

8
go.mod
View File

@ -23,10 +23,10 @@ require (
github.com/refraction-networking/utls v1.1.2
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
github.com/sagernet/shadowsocksr v0.0.0-20220912092645-c9ab93f81bb0
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7
github.com/sagernet/sing v0.0.0-20220914045234-93cc53b60cee
github.com/sagernet/sing-dns v0.0.0-20220913115644-aebff1dfbba8
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
github.com/sagernet/sing-tun v0.0.0-20220911034209-c7dd5d457e24
github.com/sagernet/sing-tun v0.0.0-20220914100102-057dd738a7f7
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
@ -37,7 +37,7 @@ require (
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1

16
go.sum
View File

@ -145,14 +145,14 @@ github.com/sagernet/shadowsocksr v0.0.0-20220912092645-c9ab93f81bb0 h1:lQ4RFWY/w
github.com/sagernet/shadowsocksr v0.0.0-20220912092645-c9ab93f81bb0/go.mod h1:xSHLCsdgy5QIozXFEv6uDgMWzyrRdFFjr3TgL+juu6g=
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921 h1:xUHzlIbdlPV/fkToIO9futp9lmKIY+72ezk/whQ8XsI=
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7 h1:hGmqtoGifhIy/XFczifR4coknjBIE8f1Suyd1SJc2F4=
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7/go.mod h1:NxH8BRDCYo28ZoojuNdRZEt9zbYgyAvC7WxEEkaUBCM=
github.com/sagernet/sing v0.0.0-20220914045234-93cc53b60cee h1:+3w7+QWnhWi3Qz7+Xcais8zViHRUPIkmxq3eYZm/zvk=
github.com/sagernet/sing v0.0.0-20220914045234-93cc53b60cee/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY=
github.com/sagernet/sing-dns v0.0.0-20220913115644-aebff1dfbba8 h1:Iyfl+Rm5jcDvXuy/jpOBI3eu35ujci50tkqYHHwwg+8=
github.com/sagernet/sing-dns v0.0.0-20220913115644-aebff1dfbba8/go.mod h1:bPVnJ5gJ0WmUfN1bJP9Cis0ab8SSByx6JVzyLJjDMwA=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
github.com/sagernet/sing-tun v0.0.0-20220911034209-c7dd5d457e24 h1:LsmPeFvj4GhiV5Y7Rm8I845XysdxVN4MQmfZ36P5bmw=
github.com/sagernet/sing-tun v0.0.0-20220911034209-c7dd5d457e24/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
github.com/sagernet/sing-tun v0.0.0-20220914100102-057dd738a7f7 h1:zdvFDYMz8s0e9UmOxMk0wNGOKh64KfeWpx8UAbJJI60=
github.com/sagernet/sing-tun v0.0.0-20220914100102-057dd738a7f7/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12 h1:4HYGbTDDemgBVTmaspXbkgjJlXc3hYVjNxSddJndq8Y=
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0=
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
@ -266,8 +266,8 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho=
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc h1:dpclq5m2YrqPGStKmtw7IcNbKLfbIqKXvNxDJKdIKYc=
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=

View File

@ -6,11 +6,11 @@ import (
"context"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
I "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HysteriaInboundOptions) (adapter.Inbound, error) {
return nil, C.ErrQUICNotIncluded
return nil, I.ErrQUICNotIncluded
}

View File

@ -15,6 +15,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
@ -105,7 +106,7 @@ func (n *Naive) Start() error {
if common.Contains(n.network, N.NetworkUDP) {
err := n.configureHTTP3Listener()
if !C.QUIC_AVAILABLE && len(n.network) > 1 {
if !include.WithQUIC && len(n.network) > 1 {
log.Warn(E.Cause(err, "naive http3 disabled"))
} else if err != nil {
return err

View File

@ -3,9 +3,9 @@
package inbound
import (
C "github.com/sagernet/sing-box/constant"
I "github.com/sagernet/sing-box/include"
)
func (n *Naive) configureHTTP3Listener() error {
return C.ErrQUICNotIncluded
return I.ErrQUICNotIncluded
}

7
include/quic.go Normal file
View File

@ -0,0 +1,7 @@
//go:build with_quic
package include
import _ "github.com/sagernet/sing-dns/quic"
const WithQUIC = true

21
include/quic_stub.go Normal file
View File

@ -0,0 +1,21 @@
//go:build !with_quic
package include
import (
"context"
"github.com/sagernet/sing-dns"
E "github.com/sagernet/sing/common/exceptions"
N "github.com/sagernet/sing/common/network"
)
const WithQUIC = false
var ErrQUICNotIncluded = E.New(`QUIC is not included in this build, rebuild with -tags with_quic`)
func init() {
dns.RegisterTransport([]string{"quic", "h3"}, func(ctx context.Context, dialer N.Dialer, link string) (dns.Transport, error) {
return nil, ErrQUICNotIncluded
})
}

View File

@ -6,11 +6,11 @@ import (
"context"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
I "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HysteriaOutboundOptions) (adapter.Outbound, error) {
return nil, C.ErrQUICNotIncluded
return nil, I.ErrQUICNotIncluded
}

50
route/interface_finder.go Normal file
View File

@ -0,0 +1,50 @@
package route
import (
"net"
"github.com/sagernet/sing/common/control"
)
var _ control.InterfaceFinder = (*myInterfaceFinder)(nil)
type myInterfaceFinder struct {
ifs []net.Interface
}
func (f *myInterfaceFinder) update() error {
ifs, err := net.Interfaces()
if err != nil {
return err
}
f.ifs = ifs
return nil
}
func (f *myInterfaceFinder) InterfaceIndexByName(name string) (interfaceIndex int, err error) {
for _, netInterface := range f.ifs {
if netInterface.Name == name {
return netInterface.Index, nil
}
}
netInterface, err := net.InterfaceByName(name)
if err != nil {
return
}
f.update()
return netInterface.Index, nil
}
func (f *myInterfaceFinder) InterfaceNameByIndex(index int) (interfaceName string, err error) {
for _, netInterface := range f.ifs {
if netInterface.Index == index {
return netInterface.Name, nil
}
}
netInterface, err := net.InterfaceByIndex(index)
if err != nil {
return
}
f.update()
return netInterface.Name, nil
}

View File

@ -86,7 +86,7 @@ type Router struct {
transports []dns.Transport
transportMap map[string]dns.Transport
transportDomainStrategy map[dns.Transport]dns.DomainStrategy
interfaceBindManager control.BindManager
interfaceFinder myInterfaceFinder
autoDetectInterface bool
defaultInterface string
defaultMark int
@ -123,7 +123,6 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
defaultDetour: options.Final,
dnsClient: dns.NewClient(dnsOptions.DNSClientOptions.DisableCache, dnsOptions.DNSClientOptions.DisableExpire),
defaultDomainStrategy: dns.DomainStrategy(dnsOptions.Strategy),
interfaceBindManager: control.NewBindManager(),
autoDetectInterface: options.AutoDetectInterface,
defaultInterface: options.DefaultInterface,
defaultMark: options.DefaultMark,
@ -196,7 +195,7 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
return nil, E.New("parse dns server[", tag, "]: missing address_resolver")
}
}
transport, err := dns.NewTransport(ctx, detour, server.Address)
transport, err := dns.CreateTransport(ctx, detour, server.Address)
if err != nil {
return nil, E.Cause(err, "parse dns server[", tag, "]")
}
@ -233,7 +232,7 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
}
if defaultTransport == nil {
if len(transports) == 0 {
transports = append(transports, dns.NewLocalTransport())
transports = append(transports, &dns.LocalTransport{})
}
defaultTransport = transports[0]
}
@ -247,13 +246,11 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || C.IsAndroid && inbound.TunOptions.AutoRoute
})
if router.interfaceBindManager != nil || needInterfaceMonitor {
if needInterfaceMonitor {
networkMonitor, err := tun.NewNetworkUpdateMonitor(router)
if err == nil {
router.networkMonitor = networkMonitor
if router.interfaceBindManager != nil {
networkMonitor.RegisterCallback(router.interfaceBindManager.Update)
}
networkMonitor.RegisterCallback(router.interfaceFinder.update)
}
}
@ -714,8 +711,8 @@ func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, de
return nil, defaultOutbound
}
func (r *Router) InterfaceBindManager() control.BindManager {
return r.interfaceBindManager
func (r *Router) InterfaceFinder() control.InterfaceFinder {
return &r.interfaceFinder
}
func (r *Router) AutoDetectInterface() bool {

View File

@ -7,7 +7,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
I "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
@ -15,9 +15,9 @@ import (
)
func NewQUICServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
return nil, C.ErrQUICNotIncluded
return nil, I.ErrQUICNotIncluded
}
func NewQUICClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
return nil, C.ErrQUICNotIncluded
return nil, I.ErrQUICNotIncluded
}