Files
MWClash/core/tun.go

96 lines
1.5 KiB
Go
Raw Normal View History

2024-04-30 23:38:49 +08:00
//go:build android
package main
import "C"
import (
"core/platform"
2024-04-30 23:38:49 +08:00
t "core/tun"
"errors"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/log"
"golang.org/x/sync/semaphore"
"strconv"
2024-04-30 23:38:49 +08:00
"sync"
"syscall"
"time"
)
var tunLock sync.Mutex
var tun *t.Tun
var runTime *time.Time
2024-04-30 23:38:49 +08:00
//export startTUN
2024-06-06 22:04:29 +08:00
func startTUN(fd C.int) {
tunLock.Lock()
now := time.Now()
runTime = &now
2024-06-06 22:04:29 +08:00
go func() {
defer tunLock.Unlock()
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
if tun != nil {
tun.Close()
tun = nil
}
f := int(fd)
gateway := "172.16.0.1/30"
portal := "172.16.0.2"
dns := "0.0.0.0"
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
tempTun := &t.Tun{Closed: false, Limit: semaphore.NewWeighted(4)}
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
closer, err := t.Start(f, gateway, portal, dns)
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
if err != nil {
log.Errorln("startTUN error: %v", err)
tempTun.Close()
}
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
tempTun.Closer = closer
2024-04-30 23:38:49 +08:00
2024-06-06 22:04:29 +08:00
tun = tempTun
applyConfig(true)
2024-06-06 22:04:29 +08:00
}()
2024-04-30 23:38:49 +08:00
}
//export getRunTime
func getRunTime() *C.char {
if runTime == nil {
return C.CString("")
}
return C.CString(strconv.FormatInt(runTime.UnixMilli(), 10))
2024-04-30 23:38:49 +08:00
}
//export stopTun
func stopTun() {
tunLock.Lock()
runTime = nil
2024-06-06 22:04:29 +08:00
go func() {
defer tunLock.Unlock()
if tun != nil {
tun.Close()
tun = nil
}
}()
2024-04-30 23:38:49 +08:00
}
func init() {
dialer.DefaultSocketHook = func(network, address string, conn syscall.RawConn) error {
if platform.ShouldBlockConnection() {
return errors.New("blocked")
}
2024-04-30 23:38:49 +08:00
return conn.Control(func(fd uintptr) {
if tun != nil {
tun.MarkSocket(int(fd))
time.Sleep(time.Millisecond * 100)
}
})
}
}