mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
Add tun inbound for windows
This commit is contained in:
parent
4fc763cfa2
commit
e7d557fd9e
|
@ -1,4 +1,4 @@
|
|||
//go:build !linux
|
||||
//go:build !linux && !windows
|
||||
|
||||
package dialer
|
||||
|
||||
|
|
68
common/dialer/auto_windows.go
Normal file
68
common/dialer/auto_windows.go
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package iffmonitor
|
||||
|
||||
import "github.com/sagernet/sing-box/adapter"
|
||||
|
||||
type InterfaceMonitor interface {
|
||||
adapter.Service
|
||||
DefaultInterfaceName() string
|
||||
DefaultInterfaceIndex() int
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
| Type | Format |
|
||||
|---------------|------------------------------|
|
||||
| `tun` | [Tun](./tun) |
|
||||
| `direct` | [Direct](./direct) |
|
||||
| `mixed` | [Mixed](./mixed) |
|
||||
| `socks` | [Socks](./socks) |
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
!!! error ""
|
||||
|
||||
Linux only
|
||||
Linux and Windows only
|
||||
|
||||
### Structure
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
6
go.mod
6
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
|
||||
|
|
8
go.sum
8
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=
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
Loading…
Reference in a new issue