Skip to content

Commit d78d1d3

Browse files
committed
Merge branch 'dev' of https://github.com/SagerNet/sing-tun into meta
2 parents 10fb882 + e212724 commit d78d1d3

16 files changed

+319
-99
lines changed

go.mod

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ go 1.18
44

55
require (
66
github.com/fsnotify/fsnotify v1.6.0
7-
github.com/go-ole/go-ole v1.2.6
7+
github.com/go-ole/go-ole v1.3.0
88
github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475
99
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61
1010
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
11-
github.com/sagernet/sing v0.2.9
11+
github.com/sagernet/sing v0.2.11
1212
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9
13-
golang.org/x/net v0.12.0
14-
golang.org/x/sys v0.10.0
13+
golang.org/x/net v0.15.0
14+
golang.org/x/sys v0.12.0
1515
)
1616

1717
require (

go.sum

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
22
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
3-
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
4-
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
3+
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
4+
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
55
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
66
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
77
github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475 h1:qSEOvPPaMrWggFyFhFYGyMR8i1HKyhXjdi1QYUAa2ww=
@@ -11,19 +11,19 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h
1111
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
1212
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
1313
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
14-
github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo=
15-
github.com/sagernet/sing v0.2.9/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
14+
github.com/sagernet/sing v0.2.11 h1:mu0S6d8y/xSVxilOqRd32Fmire5SZz9nT3t9NEHwUMY=
15+
github.com/sagernet/sing v0.2.11/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg=
1616
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
1717
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
1818
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
1919
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
20-
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
21-
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
22-
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20+
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
21+
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
2322
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2423
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2524
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
26-
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
27-
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
25+
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
26+
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
27+
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2828
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
2929
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

monitor.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ import (
1010
var ErrNoRoute = E.New("no route to internet")
1111

1212
type (
13-
NetworkUpdateCallback = func() error
14-
DefaultInterfaceUpdateCallback = func(event int) error
13+
NetworkUpdateCallback = func()
14+
DefaultInterfaceUpdateCallback = func(event int)
1515
)
1616

1717
const (
1818
EventInterfaceUpdate = 1
1919
EventAndroidVPNUpdate = 2
20+
EventNoRoute = 4
2021
)
2122

2223
type NetworkUpdateMonitor interface {
2324
Start() error
2425
Close() error
2526
RegisterCallback(callback NetworkUpdateCallback) *list.Element[NetworkUpdateCallback]
2627
UnregisterCallback(element *list.Element[NetworkUpdateCallback])
27-
E.Handler
2828
}
2929

3030
type DefaultInterfaceMonitor interface {

monitor_darwin.go

+53-37
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,94 @@
11
package tun
22

33
import (
4-
"context"
54
"net"
65
"net/netip"
76
"os"
87
"sync"
9-
"syscall"
108
"time"
119

12-
"github.com/sagernet/sing/common"
10+
"github.com/sagernet/sing/common/buf"
1311
E "github.com/sagernet/sing/common/exceptions"
12+
"github.com/sagernet/sing/common/logger"
1413
"github.com/sagernet/sing/common/x/list"
1514

1615
"golang.org/x/net/route"
1716
"golang.org/x/sys/unix"
1817
)
1918

2019
type networkUpdateMonitor struct {
21-
errorHandler E.Handler
22-
23-
access sync.Mutex
24-
callbacks list.List[NetworkUpdateCallback]
25-
routeSocket *os.File
20+
access sync.Mutex
21+
callbacks list.List[NetworkUpdateCallback]
22+
routeSocketFile *os.File
23+
closeOnce sync.Once
24+
done chan struct{}
25+
logger logger.Logger
2626
}
2727

28-
func NewNetworkUpdateMonitor(errorHandler E.Handler) (NetworkUpdateMonitor, error) {
28+
func NewNetworkUpdateMonitor(logger logger.Logger) (NetworkUpdateMonitor, error) {
2929
return &networkUpdateMonitor{
30-
errorHandler: errorHandler,
30+
logger: logger,
31+
done: make(chan struct{}),
3132
}, nil
3233
}
3334

3435
func (m *networkUpdateMonitor) Start() error {
35-
routeSocket, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0)
36-
if err != nil {
37-
return err
36+
go m.loopUpdate()
37+
return nil
38+
}
39+
40+
func (m *networkUpdateMonitor) loopUpdate() {
41+
for {
42+
select {
43+
case <-m.done:
44+
return
45+
case <-time.After(time.Second):
46+
}
47+
err := m.loopUpdate0()
48+
if err != nil {
49+
m.logger.Error("listen network update: ", err)
50+
return
51+
}
3852
}
39-
err = unix.SetNonblock(routeSocket, true)
53+
}
54+
55+
func (m *networkUpdateMonitor) loopUpdate0() error {
56+
routeSocket, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0)
4057
if err != nil {
4158
return err
4259
}
43-
m.routeSocket = os.NewFile(uintptr(routeSocket), "route")
44-
go m.loopUpdate()
60+
routeSocketFile := os.NewFile(uintptr(routeSocket), "route")
61+
m.routeSocketFile = routeSocketFile
62+
m.loopUpdate1(routeSocketFile)
4563
return nil
4664
}
4765

48-
func (m *networkUpdateMonitor) loopUpdate() {
49-
rawConn, err := m.routeSocket.SyscallConn()
66+
func (m *networkUpdateMonitor) loopUpdate1(routeSocketFile *os.File) {
67+
defer routeSocketFile.Close()
68+
buffer := buf.NewPacket()
69+
defer buffer.Release()
70+
n, err := routeSocketFile.Read(buffer.FreeBytes())
5071
if err != nil {
51-
m.errorHandler.NewError(context.Background(), E.Cause(err, "create raw route connection"))
5272
return
5373
}
54-
for {
55-
var innerErr error
56-
err = rawConn.Read(func(fd uintptr) (done bool) {
57-
var msg [2048]byte
58-
_, innerErr = unix.Read(int(fd), msg[:])
59-
return innerErr != unix.EWOULDBLOCK
60-
})
61-
if innerErr != nil {
62-
err = innerErr
63-
}
64-
if err != nil {
65-
break
66-
}
67-
m.emit()
74+
buffer.Truncate(n)
75+
messages, err := route.ParseRIB(route.RIBTypeRoute, buffer.Bytes())
76+
if err != nil {
77+
return
6878
}
69-
if err != syscall.EAGAIN {
70-
m.errorHandler.NewError(context.Background(), E.Cause(err, "read route message"))
79+
for _, message := range messages {
80+
if _, isRouteMessage := message.(*route.RouteMessage); isRouteMessage {
81+
m.emit()
82+
return
83+
}
7184
}
7285
}
7386

7487
func (m *networkUpdateMonitor) Close() error {
75-
return common.Close(common.PtrOrNil(m.routeSocket))
88+
m.closeOnce.Do(func() {
89+
close(m.done)
90+
})
91+
return nil
7692
}
7793

7894
func (m *defaultInterfaceMonitor) checkUpdate() error {
@@ -116,7 +132,7 @@ func (m *defaultInterfaceMonitor) checkUpdate() error {
116132
continue
117133
}
118134
if routeMessage.Flags&unix.RTF_IFSCOPE != 0 {
119-
continue
135+
// continue
120136
}
121137
defaultInterface = routeInterface
122138
break

monitor_linux.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ import (
55
"sync"
66

77
"github.com/sagernet/netlink"
8-
E "github.com/sagernet/sing/common/exceptions"
8+
"github.com/sagernet/sing/common/logger"
99
"github.com/sagernet/sing/common/x/list"
1010
)
1111

1212
type networkUpdateMonitor struct {
13-
routeUpdate chan netlink.RouteUpdate
14-
linkUpdate chan netlink.LinkUpdate
15-
close chan struct{}
16-
errorHandler E.Handler
13+
routeUpdate chan netlink.RouteUpdate
14+
linkUpdate chan netlink.LinkUpdate
15+
close chan struct{}
1716

1817
access sync.Mutex
1918
callbacks list.List[NetworkUpdateCallback]
19+
logger logger.Logger
2020
}
2121

22-
func NewNetworkUpdateMonitor(errorHandler E.Handler) (NetworkUpdateMonitor, error) {
22+
func NewNetworkUpdateMonitor(logger logger.Logger) (NetworkUpdateMonitor, error) {
2323
return &networkUpdateMonitor{
24-
routeUpdate: make(chan netlink.RouteUpdate, 2),
25-
linkUpdate: make(chan netlink.LinkUpdate, 2),
26-
close: make(chan struct{}),
27-
errorHandler: errorHandler,
24+
routeUpdate: make(chan netlink.RouteUpdate, 2),
25+
linkUpdate: make(chan netlink.LinkUpdate, 2),
26+
close: make(chan struct{}),
27+
logger: logger,
2828
}, nil
2929
}
3030

monitor_linux_default.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package tun
44

55
import (
66
"github.com/sagernet/netlink"
7-
E "github.com/sagernet/sing/common/exceptions"
87

98
"golang.org/x/sys/unix"
109
)
@@ -37,5 +36,5 @@ func (m *defaultInterfaceMonitor) checkUpdate() error {
3736
m.emit(EventInterfaceUpdate)
3837
return nil
3938
}
40-
return E.New("no route to internet")
39+
return ErrNoRoute
4140
}

monitor_other.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ package tun
55
import (
66
"os"
77

8-
E "github.com/sagernet/sing/common/exceptions"
8+
"github.com/sagernet/sing/common/logger"
99
)
1010

11-
func NewNetworkUpdateMonitor(errorHandler E.Handler) (NetworkUpdateMonitor, error) {
11+
func NewNetworkUpdateMonitor(logger logger.Logger) (NetworkUpdateMonitor, error) {
1212
return nil, os.ErrInvalid
1313
}
1414

15-
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, options DefaultInterfaceMonitorOptions) (DefaultInterfaceMonitor, error) {
15+
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, logger logger.Logger, options DefaultInterfaceMonitorOptions) (DefaultInterfaceMonitor, error) {
1616
return nil, os.ErrInvalid
1717
}

monitor_shared.go

+16-19
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
package tun
44

55
import (
6-
"context"
6+
"errors"
77
"net"
88
"net/netip"
99
"sync"
1010
"time"
1111

1212
"github.com/sagernet/sing/common"
13-
E "github.com/sagernet/sing/common/exceptions"
13+
"github.com/sagernet/sing/common/logger"
1414
M "github.com/sagernet/sing/common/metadata"
1515
"github.com/sagernet/sing/common/x/list"
1616
)
@@ -32,17 +32,10 @@ func (m *networkUpdateMonitor) emit() {
3232
callbacks := m.callbacks.Array()
3333
m.access.Unlock()
3434
for _, callback := range callbacks {
35-
err := callback()
36-
if err != nil {
37-
m.NewError(context.Background(), err)
38-
}
35+
callback()
3936
}
4037
}
4138

42-
func (m *networkUpdateMonitor) NewError(ctx context.Context, err error) {
43-
m.errorHandler.NewError(ctx, err)
44-
}
45-
4639
type defaultInterfaceMonitor struct {
4740
options DefaultInterfaceMonitorOptions
4841
networkAddresses []networkAddress
@@ -53,6 +46,7 @@ type defaultInterfaceMonitor struct {
5346
element *list.Element[NetworkUpdateCallback]
5447
access sync.Mutex
5548
callbacks list.List[DefaultInterfaceUpdateCallback]
49+
logger logger.Logger
5650
}
5751

5852
type networkAddress struct {
@@ -61,30 +55,36 @@ type networkAddress struct {
6155
addresses []netip.Prefix
6256
}
6357

64-
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, options DefaultInterfaceMonitorOptions) (DefaultInterfaceMonitor, error) {
58+
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, logger logger.Logger, options DefaultInterfaceMonitorOptions) (DefaultInterfaceMonitor, error) {
6559
return &defaultInterfaceMonitor{
6660
options: options,
6761
networkMonitor: networkMonitor,
6862
defaultInterfaceIndex: -1,
63+
logger: logger,
6964
}, nil
7065
}
7166

7267
func (m *defaultInterfaceMonitor) Start() error {
7368
err := m.checkUpdate()
7469
if err != nil {
75-
m.networkMonitor.NewError(context.Background(), err)
70+
m.logger.Error("initialize default interface: ", err)
7671
}
7772
m.element = m.networkMonitor.RegisterCallback(m.delayCheckUpdate)
7873
return nil
7974
}
8075

81-
func (m *defaultInterfaceMonitor) delayCheckUpdate() error {
76+
func (m *defaultInterfaceMonitor) delayCheckUpdate() {
8277
time.Sleep(time.Second)
8378
err := m.updateInterfaces()
8479
if err != nil {
85-
m.networkMonitor.NewError(context.Background(), E.Cause(err, "update interfaces"))
80+
m.logger.Error("update interfaces: ", err)
81+
}
82+
err = m.checkUpdate()
83+
if errors.Is(err, ErrNoRoute) {
84+
m.defaultInterfaceName = ""
85+
m.defaultInterfaceIndex = -1
86+
m.emit(EventNoRoute)
8687
}
87-
return m.checkUpdate()
8888
}
8989

9090
func (m *defaultInterfaceMonitor) updateInterfaces() error {
@@ -175,9 +175,6 @@ func (m *defaultInterfaceMonitor) emit(event int) {
175175
callbacks := m.callbacks.Array()
176176
m.access.Unlock()
177177
for _, callback := range callbacks {
178-
err := callback(event)
179-
if err != nil {
180-
m.networkMonitor.NewError(context.Background(), err)
181-
}
178+
callback(event)
182179
}
183180
}

0 commit comments

Comments
 (0)