fix windows underlying dns monitor &&

fix wireguard traffic manager
This commit is contained in:
Nova 2025-02-28 12:52:08 +03:30
parent 335f26dd48
commit 343ff659fc
7 changed files with 66 additions and 55 deletions

View File

@ -19,7 +19,7 @@ require (
google.golang.org/protobuf v1.34.2
)
replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20250224103252-b71e66ac2cc7
replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20250226183822-fbccffb7d54f
replace github.com/sagernet/sing-dns => github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250201180230-3ed9d1ef74d5

View File

@ -1,5 +1,5 @@
github.com/Mahdi-zarei/sing-box v1.3.5-0.20250224103252-b71e66ac2cc7 h1:aKHzrLdePI4IzeDBeJmjeYcd4ONsVTiPc4bCSeTFEQ0=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20250224103252-b71e66ac2cc7/go.mod h1:Gwt2fHum29zmmWw1gXMDQvoiCmu2ikv4ZozjKSxcZ7c=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20250226183822-fbccffb7d54f h1:7BqlzXepzL2ARM8p+1pVUtvWLck89IM4hk6FPXw0LmQ=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20250226183822-fbccffb7d54f/go.mod h1:Gwt2fHum29zmmWw1gXMDQvoiCmu2ikv4ZozjKSxcZ7c=
github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250201180230-3ed9d1ef74d5 h1:AdwcBEKyia7lvdqJq77G0imGej8IFkHGENfjif+OwHs=
github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250201180230-3ed9d1ef74d5/go.mod h1:8wuFcoFkWM4vJuQyg8e97LyvDwe0/Vl7G839WLcKDs8=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=

View File

@ -22,16 +22,22 @@ const (
var customDNS []netip.Addr
var dnsIsSet bool
func handleInterfaceChange(_ *control.Interface, _ int) {
func HandleInterfaceChange(_ *control.Interface, _ int) {
monitorForUnderlyingDNS()
time.Sleep(2 * time.Second)
if !dnsIsSet {
return
}
time.Sleep(2 * time.Second)
_ = SetDefaultDNS(customDNS, false, false)
}
func getDefaultInterfaceGuid() (string, error) {
index := monitorDI.DefaultInterface().Index
ifc := DefaultIfcMonitor.DefaultInterface()
if ifc == nil {
log.Println("Default interface is nil!")
return "", E.New("Default interface is nil!")
}
index := ifc.Index
var guid iphlpapi.GUID
if errno := iphlpapi.Index2GUID(uint64(index), &guid); errno != 0 {
return "", E.New("Failed to convert index to GUID")
@ -49,7 +55,12 @@ func getDefaultInterfaceGuid() (string, error) {
}
func getDefaultInterfaceLUID() (winipcfg.LUID, error) {
index := monitorDI.DefaultInterface().Index
ifc := DefaultIfcMonitor.DefaultInterface()
if ifc == nil {
log.Println("Default interface is nil!")
return 0, E.New("Default interface is nil!")
}
index := ifc.Index
luid, err := winipcfg.LUIDFromIndex(uint32(index))
if err != nil {
return 0, err

View File

@ -0,0 +1,13 @@
//go:build !windows
package boxdns
import (
tun "github.com/sagernet/sing-tun"
)
var DefaultIfcMonitor tun.DefaultInterfaceMonitor
func monitorForUnderlyingDNS() {
return
}

View File

@ -1,58 +1,25 @@
package boxdns
import (
"context"
"github.com/sagernet/sing/common/control"
"github.com/matsuridayo/libneko/iphlpapi"
"log"
"strings"
"time"
"github.com/matsuridayo/libneko/iphlpapi"
L "github.com/sagernet/sing-box/log"
tun "github.com/sagernet/sing-tun"
"github.com/gofrs/uuid/v5"
"golang.org/x/sys/windows/registry"
)
var monitorNU tun.NetworkUpdateMonitor
var monitorDI tun.DefaultInterfaceMonitor
var DefaultIfcMonitor tun.DefaultInterfaceMonitor
func init() {
defer func() {
if err := recover(); err != nil {
log.Println("[Warning] failed to start sing-tun monitor:", err)
}
}()
logFactory, _ := L.New(L.Options{
Context: context.Background(),
BaseTime: time.Now(),
})
logger := logFactory.NewLogger("windows-dns")
ifcFinder := control.NewDefaultInterfaceFinder()
monitorNU, _ = tun.NewNetworkUpdateMonitor(logger)
monitorDI, _ = tun.NewDefaultInterfaceMonitor(monitorNU, logger, tun.DefaultInterfaceMonitorOptions{
InterfaceFinder: ifcFinder,
})
monitorDI.RegisterCallback(monitorForUnderlyingDNS)
monitorDI.RegisterCallback(handleInterfaceChange)
monitorDI.Start()
monitorNU.Start()
ifcFinder.Update()
go func() {
for {
time.Sleep(5 * time.Second)
monitorForUnderlyingDNS(nil, 0) // to handle wifi change
}
}()
}
func monitorForUnderlyingDNS(_ *control.Interface, _ int) {
index := monitorDI.DefaultInterface().Index
func monitorForUnderlyingDNS() {
ifc := DefaultIfcMonitor.DefaultInterface()
if ifc == nil {
log.Println("Default interface is nil!")
return
}
index := ifc.Index
var guid iphlpapi.GUID
if errno := iphlpapi.Index2GUID(uint64(index), &guid); errno != 0 {
return

View File

@ -15,6 +15,7 @@ import (
"nekobox_core/gen"
"nekobox_core/internal/boxapi"
"nekobox_core/internal/boxbox"
"nekobox_core/internal/boxdns"
"nekobox_core/internal/boxmain"
"nekobox_core/internal/sys"
"net/http"
@ -64,7 +65,16 @@ func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.Err
}
boxInstance, instanceCancel, err = boxmain.Create([]byte(in.CoreConfig))
if runtime.GOOS == "darwin" && strings.Contains(in.CoreConfig, "utun") && err == nil {
if err != nil {
return
}
if runtime.GOOS == "windows" {
nm := boxInstance.Network()
boxdns.DefaultIfcMonitor = nm.InterfaceMonitor()
boxdns.HandleInterfaceChange(nil, 0)
boxdns.DefaultIfcMonitor.RegisterCallback(boxdns.HandleInterfaceChange)
}
if runtime.GOOS == "darwin" && strings.Contains(in.CoreConfig, "utun") {
err := sys.SetSystemDNS("172.19.0.2", boxInstance.Network().InterfaceMonitor())
if err != nil {
log.Println("Failed to set system DNS:", err)
@ -186,10 +196,15 @@ func (s *server) QueryStats(ctx context.Context, _ *gen.EmptyReq) (*gen.QuerySta
return nil, E.New("invalid clash server type")
}
outbounds := service.FromContext[adapter.OutboundManager](boxInstance.Context())
endpoints := service.FromContext[adapter.EndpointManager](boxInstance.Context())
if outbounds == nil {
log.Println("Failed to assert outbound manager")
return nil, E.New("invalid outbound manager type")
}
if endpoints == nil {
log.Println("Failed to assert endpoint manager")
return nil, E.New("invalid endpoint manager type")
}
for _, out := range outbounds.Outbounds() {
if len(out.Dependencies()) > 0 {
// ignore, has detour
@ -199,6 +214,15 @@ func (s *server) QueryStats(ctx context.Context, _ *gen.EmptyReq) (*gen.QuerySta
resp.Ups[out.Tag()] = u
resp.Downs[out.Tag()] = d
}
for _, end := range endpoints.Endpoints() {
if len(end.Dependencies()) > 0 {
// ignore, has detour
continue
}
u, d := cApi.TrafficManager().TotalOutbound(end.Tag())
resp.Ups[end.Tag()] = u
resp.Downs[end.Tag()] = d
}
}
}

View File

@ -26,7 +26,6 @@ type URLTestResult struct {
func BatchURLTest(ctx context.Context, i *boxbox.Box, outboundTags []string, url string, maxConcurrency int, twice bool) []*URLTestResult {
outbounds := service.FromContext[adapter.OutboundManager](i.Context())
endpoints := service.FromContext[adapter.EndpointManager](i.Context())
resMap := make(map[string]*URLTestResult)
resAccess := sync.Mutex{}
limiter := make(chan struct{}, maxConcurrency)
@ -50,10 +49,7 @@ func BatchURLTest(ctx context.Context, i *boxbox.Box, outboundTags []string, url
defer wg.Done()
outbound, found := outbounds.Outbound(t)
if !found {
outbound, found = endpoints.Get(t)
if !found {
panic("no outbound with tag " + t + " found")
}
panic("no outbound with tag " + t + " found")
}
client := &http.Client{
Transport: &http.Transport{