From e7d557fd9e3f818b7f3636c7469df0f3acde5f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 13 Jul 2022 19:01:20 +0800 Subject: [PATCH] Add tun inbound for windows --- common/dialer/auto_other.go | 2 +- common/dialer/auto_windows.go | 68 ++++++++++++++++++ common/iffmonitor/monitor.go | 9 --- common/iffmonitor/monitor_linux.go | 108 ---------------------------- common/iffmonitor/monitor_other.go | 13 ---- docs/configuration/inbound/index.md | 1 + docs/configuration/inbound/tun.md | 2 +- docs/configuration/route/index.md | 2 +- go.mod | 6 +- go.sum | 8 +-- inbound/tun.go | 30 +++----- inbound/tun_disabled.go | 16 ----- log/default.go | 14 ++-- log/observable.go | 14 ++-- route/router.go | 12 ++-- test/go.mod | 4 +- test/go.sum | 8 +-- 17 files changed, 116 insertions(+), 201 deletions(-) create mode 100644 common/dialer/auto_windows.go delete mode 100644 common/iffmonitor/monitor.go delete mode 100644 common/iffmonitor/monitor_linux.go delete mode 100644 common/iffmonitor/monitor_other.go delete mode 100644 inbound/tun_disabled.go diff --git a/common/dialer/auto_other.go b/common/dialer/auto_other.go index 653c100f..96dc1f22 100644 --- a/common/dialer/auto_other.go +++ b/common/dialer/auto_other.go @@ -1,4 +1,4 @@ -//go:build !linux +//go:build !linux && !windows package dialer diff --git a/common/dialer/auto_windows.go b/common/dialer/auto_windows.go new file mode 100644 index 00000000..e80d94b5 --- /dev/null +++ b/common/dialer/auto_windows.go @@ -0,0 +1,68 @@ +package dialer + +import ( + "encoding/binary" + "net" + "net/netip" + "syscall" + "unsafe" + + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing/common/control" + E "github.com/sagernet/sing/common/exceptions" + + "golang.org/x/sys/windows" +) + +const ( + IP_UNICAST_IF = 31 + IPV6_UNICAST_IF = 31 +) + +func bind4(handle windows.Handle, ifaceIdx int) error { + var bytes [4]byte + binary.BigEndian.PutUint32(bytes[:], uint32(ifaceIdx)) + idx := *(*uint32)(unsafe.Pointer(&bytes[0])) + return windows.SetsockoptInt(handle, windows.IPPROTO_IP, IP_UNICAST_IF, int(idx)) +} + +func bind6(handle windows.Handle, ifaceIdx int) error { + return windows.SetsockoptInt(handle, windows.IPPROTO_IPV6, IPV6_UNICAST_IF, int(ifaceIdx)) +} + +func BindToInterface(router adapter.Router) control.Func { + return func(network, address string, conn syscall.RawConn) error { + interfaceName := router.DefaultInterfaceName() + if interfaceName == "" { + return nil + } + ipStr, _, err := net.SplitHostPort(address) + if err == nil { + if ip, err := netip.ParseAddr(ipStr); err == nil && !ip.IsGlobalUnicast() { + return err + } + } + var innerErr error + err = conn.Control(func(fd uintptr) { + handle := windows.Handle(fd) + // handle ip empty, e.g. net.Listen("udp", ":0") + if ipStr == "" { + innerErr = bind4(handle, router.DefaultInterfaceIndex()) + if innerErr != nil { + return + } + // try bind ipv6, if failed, ignore. it's a workaround for windows disable interface ipv6 + bind6(handle, router.DefaultInterfaceIndex()) + return + } + + switch network { + case "tcp4", "udp4", "ip4": + innerErr = bind4(handle, router.DefaultInterfaceIndex()) + case "tcp6", "udp6": + innerErr = bind6(handle, router.DefaultInterfaceIndex()) + } + }) + return E.Errors(innerErr, err) + } +} diff --git a/common/iffmonitor/monitor.go b/common/iffmonitor/monitor.go deleted file mode 100644 index 7aae0663..00000000 --- a/common/iffmonitor/monitor.go +++ /dev/null @@ -1,9 +0,0 @@ -package iffmonitor - -import "github.com/sagernet/sing-box/adapter" - -type InterfaceMonitor interface { - adapter.Service - DefaultInterfaceName() string - DefaultInterfaceIndex() int -} diff --git a/common/iffmonitor/monitor_linux.go b/common/iffmonitor/monitor_linux.go deleted file mode 100644 index 19b196a2..00000000 --- a/common/iffmonitor/monitor_linux.go +++ /dev/null @@ -1,108 +0,0 @@ -package iffmonitor - -import ( - "os" - - "github.com/sagernet/sing-box/log" - E "github.com/sagernet/sing/common/exceptions" - - "github.com/vishvananda/netlink" -) - -var _ InterfaceMonitor = (*monitor)(nil) - -type monitor struct { - logger log.Logger - defaultInterfaceName string - defaultInterfaceIndex int - update chan netlink.RouteUpdate - close chan struct{} -} - -func New(logger log.Logger) (InterfaceMonitor, error) { - return &monitor{ - logger: logger, - update: make(chan netlink.RouteUpdate, 2), - close: make(chan struct{}), - }, nil -} - -func (m *monitor) Start() error { - err := netlink.RouteSubscribe(m.update, m.close) - if err != nil { - return err - } - err = m.checkUpdate() - if err != nil { - return err - } - go m.loopUpdate() - return nil -} - -func (m *monitor) loopUpdate() { - for { - select { - case <-m.close: - return - case <-m.update: - err := m.checkUpdate() - if err != nil { - m.logger.Error(E.Cause(err, "check default interface")) - } - } - } -} - -func (m *monitor) checkUpdate() error { - routes, err := netlink.RouteList(nil, netlink.FAMILY_V4) - if err != nil { - return err - } - for _, route := range routes { - if route.Dst != nil { - continue - } - var link netlink.Link - link, err = netlink.LinkByIndex(route.LinkIndex) - if err != nil { - return err - } - - if link.Type() == "tuntap" { - continue - } - - oldInterface := m.defaultInterfaceName - oldIndex := m.defaultInterfaceIndex - - m.defaultInterfaceName = link.Attrs().Name - m.defaultInterfaceIndex = link.Attrs().Index - - if oldInterface == m.defaultInterfaceName && oldIndex == m.defaultInterfaceIndex { - return nil - } - - m.logger.Info("updated default interface ", m.defaultInterfaceName, ", index ", m.defaultInterfaceIndex) - return nil - } - return E.New("no route to internet") -} - -func (m *monitor) Close() error { - select { - case <-m.close: - return os.ErrClosed - default: - } - close(m.close) - return nil -} - -func (m *monitor) DefaultInterfaceName() string { - return m.defaultInterfaceName -} - -func (m *monitor) DefaultInterfaceIndex() int { - return m.defaultInterfaceIndex -} diff --git a/common/iffmonitor/monitor_other.go b/common/iffmonitor/monitor_other.go deleted file mode 100644 index acfdb9e6..00000000 --- a/common/iffmonitor/monitor_other.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build !linux - -package iffmonitor - -import ( - "os" - - "github.com/sagernet/sing-box/log" -) - -func New(logger log.Logger) (InterfaceMonitor, error) { - return nil, os.ErrInvalid -} diff --git a/docs/configuration/inbound/index.md b/docs/configuration/inbound/index.md index b2c1d6bb..8351797b 100644 --- a/docs/configuration/inbound/index.md +++ b/docs/configuration/inbound/index.md @@ -15,6 +15,7 @@ | Type | Format | |---------------|------------------------------| +| `tun` | [Tun](./tun) | | `direct` | [Direct](./direct) | | `mixed` | [Mixed](./mixed) | | `socks` | [Socks](./socks) | diff --git a/docs/configuration/inbound/tun.md b/docs/configuration/inbound/tun.md index 55a1e042..e640e6b2 100644 --- a/docs/configuration/inbound/tun.md +++ b/docs/configuration/inbound/tun.md @@ -1,6 +1,6 @@ !!! error "" - Linux only + Linux and Windows only ### Structure diff --git a/docs/configuration/route/index.md b/docs/configuration/route/index.md index ab234406..a6f31ac3 100644 --- a/docs/configuration/route/index.md +++ b/docs/configuration/route/index.md @@ -28,7 +28,7 @@ Default outbound tag. the first outbound will be used if empty. !!! error "" - Linux only + Linux and Windows only Bind outbound connections to the default NIC by default to prevent routing loops under Tun. diff --git a/go.mod b/go.mod index 5e9a72c6..5f007158 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/sagernet/sing v0.0.0-20220712060558-029ab1ce4f91 github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619 github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 - github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96 + github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 - github.com/vishvananda/netlink v1.1.0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d golang.org/x/net v0.0.0-20220708220712-1185a9018129 + golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e ) require ( @@ -26,8 +26,8 @@ require ( github.com/kr/pretty v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/vishvananda/netlink v1.1.0 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ea4632e5..2a536437 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619 h1:oHbOmq1WS0XaZ github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619/go.mod h1:y2fpvoxukw3G7eApIZwkcpcG/NE4AB8pCQI0Qd8rMqk= github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k= github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw= -github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96 h1:BPsCEEKmww4PCuL2qCKGpwuS/HllNz4/G7EjvSHlXXg= -github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96/go.mod h1:OLQnVTGk8NMVdoegQvenGHsGEv3diSMWe9Uh02cel0E= +github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76 h1:/nvko0np1sAZrY5s+0HIn99SXbAkN7lPWiBZ22nDEL0= +github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76/go.mod h1:oIK1kg8hkeA5zNSv9BcbTPzdR00bbVBt6eYvJp+rsck= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -53,8 +53,8 @@ golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6fl golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I= -golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/inbound/tun.go b/inbound/tun.go index e6888551..286c0b4f 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -1,12 +1,9 @@ -//go:build !no_tun - package inbound import ( "context" "net" "net/netip" - "os" "runtime" "strconv" "strings" @@ -17,6 +14,7 @@ import ( "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-dns" "github.com/sagernet/sing-tun" + "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" F "github.com/sagernet/sing/common/format" M "github.com/sagernet/sing/common/metadata" @@ -40,8 +38,8 @@ type Tun struct { autoRoute bool hijackDNS bool - tunFd uintptr - tun *tun.GVisorTun + tunIf tun.Tun + tunStack *tun.GVisorTun } func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (*Tun, error) { @@ -77,17 +75,13 @@ func (t *Tun) Tag() string { } func (t *Tun) Start() error { - tunFd, err := tun.Open(t.tunName) - if err != nil { - return E.Cause(err, "create tun interface") - } - err = tun.Configure(t.tunName, t.inet4Address, t.inet6Address, t.tunMTU, t.autoRoute) + tunIf, err := tun.Open(t.tunName, t.inet4Address, t.inet6Address, t.tunMTU, t.autoRoute) if err != nil { return E.Cause(err, "configure tun interface") } - t.tunFd = tunFd - t.tun = tun.NewGVisor(t.ctx, tunFd, t.tunMTU, t) - err = t.tun.Start() + t.tunIf = tunIf + t.tunStack = tun.NewGVisor(t.ctx, tunIf, t.tunMTU, t) + err = t.tunStack.Start() if err != nil { return err } @@ -96,13 +90,9 @@ func (t *Tun) Start() error { } func (t *Tun) Close() error { - err := tun.UnConfigure(t.tunName, t.inet4Address, t.inet6Address, t.autoRoute) - if err != nil { - return err - } - return E.Errors( - t.tun.Close(), - os.NewFile(t.tunFd, "tun").Close(), + return common.Close( + t.tunStack, + t.tunIf, ) } diff --git a/inbound/tun_disabled.go b/inbound/tun_disabled.go deleted file mode 100644 index 2867b279..00000000 --- a/inbound/tun_disabled.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build no_tun - -package inbound - -import ( - "context" - - "github.com/sagernet/sing-box/adapter" - "github.com/sagernet/sing-box/log" - "github.com/sagernet/sing-box/option" - E "github.com/sagernet/sing/common/exceptions" -) - -func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (adapter.Inbound, error) { - return nil, E.New("tun disabled in this build") -} diff --git a/log/default.go b/log/default.go index bff2a39d..d8014489 100644 --- a/log/default.go +++ b/log/default.go @@ -63,31 +63,31 @@ func (l *simpleLogger) Log(ctx context.Context, level Level, args []any) { } func (l *simpleLogger) Trace(args ...any) { - l.Log(nil, LevelTrace, args) + l.TraceContext(context.Background(), args...) } func (l *simpleLogger) Debug(args ...any) { - l.Log(nil, LevelDebug, args) + l.DebugContext(context.Background(), args...) } func (l *simpleLogger) Info(args ...any) { - l.Log(nil, LevelInfo, args) + l.InfoContext(context.Background(), args...) } func (l *simpleLogger) Warn(args ...any) { - l.Log(nil, LevelWarn, args) + l.WarnContext(context.Background(), args...) } func (l *simpleLogger) Error(args ...any) { - l.Log(nil, LevelError, args) + l.ErrorContext(context.Background(), args...) } func (l *simpleLogger) Fatal(args ...any) { - l.Log(nil, LevelFatal, args) + l.FatalContext(context.Background(), args...) } func (l *simpleLogger) Panic(args ...any) { - l.Log(nil, LevelPanic, args) + l.PanicContext(context.Background(), args...) } func (l *simpleLogger) TraceContext(ctx context.Context, args ...any) { diff --git a/log/observable.go b/log/observable.go index 15eea5e3..ce0ed34a 100644 --- a/log/observable.go +++ b/log/observable.go @@ -80,31 +80,31 @@ func (l *observableLogger) Log(ctx context.Context, level Level, args []any) { } func (l *observableLogger) Trace(args ...any) { - l.Log(nil, LevelTrace, args) + l.TraceContext(context.Background(), args...) } func (l *observableLogger) Debug(args ...any) { - l.Log(nil, LevelDebug, args) + l.DebugContext(context.Background(), args...) } func (l *observableLogger) Info(args ...any) { - l.Log(nil, LevelInfo, args) + l.InfoContext(context.Background(), args...) } func (l *observableLogger) Warn(args ...any) { - l.Log(nil, LevelWarn, args) + l.WarnContext(context.Background(), args...) } func (l *observableLogger) Error(args ...any) { - l.Log(nil, LevelError, args) + l.ErrorContext(context.Background(), args...) } func (l *observableLogger) Fatal(args ...any) { - l.Log(nil, LevelFatal, args) + l.FatalContext(context.Background(), args...) } func (l *observableLogger) Panic(args ...any) { - l.Log(nil, LevelPanic, args) + l.PanicContext(context.Background(), args...) } func (l *observableLogger) TraceContext(ctx context.Context, args ...any) { diff --git a/route/router.go b/route/router.go index 5dee2ec9..a89af693 100644 --- a/route/router.go +++ b/route/router.go @@ -17,12 +17,12 @@ import ( "github.com/sagernet/sing-box/common/dialer" "github.com/sagernet/sing-box/common/geoip" "github.com/sagernet/sing-box/common/geosite" - "github.com/sagernet/sing-box/common/iffmonitor" "github.com/sagernet/sing-box/common/sniff" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-dns" + tun "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/bufio" @@ -65,7 +65,7 @@ type Router struct { transportMap map[string]dns.Transport autoDetectInterface bool - interfaceMonitor iffmonitor.InterfaceMonitor + interfaceMonitor tun.InterfaceMonitor } func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.ContextLogger, options option.RouteOptions, dnsOptions option.DNSOptions) (*Router, error) { @@ -176,7 +176,7 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont return nil, E.New("found circular reference in dns servers: ", strings.Join(unresolvedTags, " ")) } var defaultTransport dns.Transport - if options.Final != "" { + if dnsOptions.Final != "" { defaultTransport = dummyTransportMap[options.Final] if defaultTransport == nil { return nil, E.New("default dns server not found: ", options.Final) @@ -193,9 +193,11 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont router.transportMap = transportMap if options.AutoDetectInterface { - monitor, err := iffmonitor.New(router.logger) + monitor, err := tun.NewMonitor(func() { + router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(), ", index ", router.interfaceMonitor.DefaultInterfaceIndex()) + }) if err != nil { - return nil, E.Cause(err, "create default interface monitor") + return nil, E.New("auto_detect_interface unsupported on current platform") } router.interfaceMonitor = monitor } diff --git a/test/go.mod b/test/go.mod index 9007141a..b402bf17 100644 --- a/test/go.mod +++ b/test/go.mod @@ -35,11 +35,11 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619 // indirect github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 // indirect - github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96 // indirect + github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76 // indirect github.com/vishvananda/netlink v1.1.0 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect - golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect + golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.3.0 // indirect diff --git a/test/go.sum b/test/go.sum index 6119fbea..21a1a98f 100644 --- a/test/go.sum +++ b/test/go.sum @@ -58,8 +58,8 @@ github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619 h1:oHbOmq1WS0XaZ github.com/sagernet/sing-dns v0.0.0-20220711062726-c64e938e4619/go.mod h1:y2fpvoxukw3G7eApIZwkcpcG/NE4AB8pCQI0Qd8rMqk= github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k= github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw= -github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96 h1:BPsCEEKmww4PCuL2qCKGpwuS/HllNz4/G7EjvSHlXXg= -github.com/sagernet/sing-tun v0.0.0-20220711091522-4f7247190c96/go.mod h1:OLQnVTGk8NMVdoegQvenGHsGEv3diSMWe9Uh02cel0E= +github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76 h1:/nvko0np1sAZrY5s+0HIn99SXbAkN7lPWiBZ22nDEL0= +github.com/sagernet/sing-tun v0.0.0-20220713125153-6c2c28da9d76/go.mod h1:oIK1kg8hkeA5zNSv9BcbTPzdR00bbVBt6eYvJp+rsck= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -103,8 +103,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I= -golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=