diff --git a/adapter/router.go b/adapter/router.go index 91c45674..0af0a452 100644 --- a/adapter/router.go +++ b/adapter/router.go @@ -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 diff --git a/cmd/sing-box/main.go b/cmd/sing-box/main.go index 7bebefed..aee754a6 100644 --- a/cmd/sing-box/main.go +++ b/cmd/sing-box/main.go @@ -3,6 +3,7 @@ package main import ( "os" + _ "github.com/sagernet/sing-box/include" "github.com/sagernet/sing-box/log" "github.com/spf13/cobra" diff --git a/common/dialer/default.go b/common/dialer/default.go index 590456c6..e53de09a 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -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) } diff --git a/constant/quic.go b/constant/quic.go deleted file mode 100644 index 8df79d16..00000000 --- a/constant/quic.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build with_quic - -package constant - -const QUIC_AVAILABLE = true diff --git a/constant/quic_stub.go b/constant/quic_stub.go deleted file mode 100644 index 7cf7a0a8..00000000 --- a/constant/quic_stub.go +++ /dev/null @@ -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`) diff --git a/go.mod b/go.mod index 5c233b44..285cad17 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 7600c86c..5b68eb0f 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/inbound/hysteria_stub.go b/inbound/hysteria_stub.go index 1a56a5b6..182b993d 100644 --- a/inbound/hysteria_stub.go +++ b/inbound/hysteria_stub.go @@ -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 } diff --git a/inbound/naive.go b/inbound/naive.go index 14d31a44..a479db7c 100644 --- a/inbound/naive.go +++ b/inbound/naive.go @@ -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 diff --git a/inbound/naive_quic_stub.go b/inbound/naive_quic_stub.go index 90f697e4..336f2840 100644 --- a/inbound/naive_quic_stub.go +++ b/inbound/naive_quic_stub.go @@ -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 } diff --git a/include/quic.go b/include/quic.go new file mode 100644 index 00000000..3f6ea8da --- /dev/null +++ b/include/quic.go @@ -0,0 +1,7 @@ +//go:build with_quic + +package include + +import _ "github.com/sagernet/sing-dns/quic" + +const WithQUIC = true diff --git a/include/quic_stub.go b/include/quic_stub.go new file mode 100644 index 00000000..22267c92 --- /dev/null +++ b/include/quic_stub.go @@ -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 + }) +} diff --git a/outbound/hysteria_stub.go b/outbound/hysteria_stub.go index 62fae20c..6c333636 100644 --- a/outbound/hysteria_stub.go +++ b/outbound/hysteria_stub.go @@ -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 } diff --git a/route/interface_finder.go b/route/interface_finder.go new file mode 100644 index 00000000..20688c9d --- /dev/null +++ b/route/interface_finder.go @@ -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 +} diff --git a/route/router.go b/route/router.go index 012f535f..ed4c5bf2 100644 --- a/route/router.go +++ b/route/router.go @@ -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 { diff --git a/transport/v2ray/quic_stub.go b/transport/v2ray/quic_stub.go index 27c8cb65..59775907 100644 --- a/transport/v2ray/quic_stub.go +++ b/transport/v2ray/quic_stub.go @@ -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 }