refactor windows dns manager

This commit is contained in:
Nova 2025-03-07 05:45:15 +03:30
parent 818ab3e568
commit 1922600c62
5 changed files with 88 additions and 33 deletions

View File

@ -1,6 +1,7 @@
package boxdns package boxdns
import ( import (
"fmt"
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
"github.com/matsuridayo/libneko/iphlpapi" "github.com/matsuridayo/libneko/iphlpapi"
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
@ -21,19 +22,25 @@ const (
var customDNS []netip.Addr var customDNS []netip.Addr
var dnsIsSet bool var dnsIsSet bool
func HandleInterfaceChange(_ *control.Interface, _ int) { func (d *DnsManager) HandleSystemDNS(ifc *control.Interface, flag int) {
monitorForUnderlyingDNS(customDNS) if d == nil {
fmt.Println("No DnsManager, you may need to restart nekoray")
return
}
if ifc == nil || ifc.Equals(d.lastIfc) {
return
}
if !dnsIsSet { if !dnsIsSet {
return return
} }
_ = SetDefaultDNS(customDNS, false, false) _ = d.SetDefaultDNS(customDNS, false, false)
} }
func getDefaultInterfaceGuid() (string, error) { func (d *DnsManager) getDefaultInterfaceGuid() (string, error) {
if DefaultIfcMonitor == nil { if d.Monitor == nil {
return "", E.New("No default interface monitor") return "", E.New("No Dns Manager, you may need to restart nekoray")
} }
ifc := DefaultIfcMonitor.DefaultInterface() ifc := d.Monitor.DefaultInterface()
if ifc == nil { if ifc == nil {
log.Println("Default interface is nil!") log.Println("Default interface is nil!")
return "", E.New("Default interface is nil!") return "", E.New("Default interface is nil!")
@ -55,11 +62,11 @@ func getDefaultInterfaceGuid() (string, error) {
return guidStr, nil return guidStr, nil
} }
func getDefaultInterfaceLUID() (winipcfg.LUID, error) { func (d *DnsManager) getDefaultInterfaceLUID() (winipcfg.LUID, error) {
if DefaultIfcMonitor == nil { if d.Monitor == nil {
return 0, E.New("No default interface monitor") return 0, E.New("No DnsManager, you may need to restart nekoray")
} }
ifc := DefaultIfcMonitor.DefaultInterface() ifc := d.Monitor.DefaultInterface()
if ifc == nil { if ifc == nil {
log.Println("Default interface is nil!") log.Println("Default interface is nil!")
return 0, E.New("Default interface is nil!") return 0, E.New("Default interface is nil!")
@ -73,8 +80,12 @@ func getDefaultInterfaceLUID() (winipcfg.LUID, error) {
return luid, nil return luid, nil
} }
func GetDefaultDNS() (servers []netip.Addr, dhcp bool, err error) { func (d *DnsManager) GetDefaultDNS() (servers []netip.Addr, dhcp bool, err error) {
guidStr, err := getDefaultInterfaceGuid() if d == nil {
fmt.Println("No DnsManager, you may need to restart nekoray")
return nil, false, E.New("No Dns Manager, you may need to restart nekoray")
}
guidStr, err := d.getDefaultInterfaceGuid()
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
@ -108,15 +119,22 @@ func GetDefaultDNS() (servers []netip.Addr, dhcp bool, err error) {
return resp, false, nil return resp, false, nil
} }
func SetDefaultDNS(servers []netip.Addr, dhcp bool, clear bool) error { func (d *DnsManager) SetDefaultDNS(servers []netip.Addr, dhcp bool, clear bool) error {
if d == nil {
fmt.Println("No DnsManager, you may need to restart nekoray")
return E.New("No dns Manager, you may need to restart nekoray")
}
if clear { if clear {
dnsIsSet = false dnsIsSet = false
} else { } else {
customDNS = servers customDNS = servers
dnsIsSet = true dnsIsSet = true
if ifc := d.Monitor.DefaultInterface(); ifc != nil {
d.lastIfc = *ifc
}
} }
luid, err := getDefaultInterfaceLUID() luid, err := d.getDefaultInterfaceLUID()
if err != nil { if err != nil {
return err return err
} }

View File

@ -7,8 +7,17 @@ import (
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
) )
var DefaultIfcMonitor tun.DefaultInterfaceMonitor var DnsManagerInstance *DnsManager
func HandleInterfaceChange(_ *control.Interface, _ int) { type DnsManager struct {
Monitor tun.DefaultInterfaceMonitor
lastIfc control.Interface
}
func (d *DnsManager) HandleSystemDNS(ifc *control.Interface, flag int) {
return
}
func (d *DnsManager) HandleUnderlyingDNS(ifc *control.Interface, flag int) {
return return
} }

View File

@ -1,9 +1,11 @@
package boxdns package boxdns
import ( import (
"fmt"
"github.com/matsuridayo/libneko/iphlpapi" "github.com/matsuridayo/libneko/iphlpapi"
"github.com/sagernet/sing/common/control"
logger2 "github.com/sagernet/sing/common/logger"
"log" "log"
"net/netip"
"strings" "strings"
tun "github.com/sagernet/sing-tun" tun "github.com/sagernet/sing-tun"
@ -12,14 +14,47 @@ import (
"golang.org/x/sys/windows/registry" "golang.org/x/sys/windows/registry"
) )
var DefaultIfcMonitor tun.DefaultInterfaceMonitor func init() {
logger := logger2.NOP()
func monitorForUnderlyingDNS(customDNS []netip.Addr) { updMonitor, err := tun.NewNetworkUpdateMonitor(logger)
if DefaultIfcMonitor == nil { if err != nil {
log.Println("Default interface monitor not available!") fmt.Println("Could not create NetworkUpdateMonitor")
return
}
monitor, err := tun.NewDefaultInterfaceMonitor(updMonitor, logger, tun.DefaultInterfaceMonitorOptions{
InterfaceFinder: control.NewDefaultInterfaceFinder(),
})
if err != nil {
fmt.Println("Could not create DefaultInterfaceMonitor")
return
}
DnsManagerInstance = &DnsManager{Monitor: monitor}
monitor.RegisterCallback(DnsManagerInstance.HandleUnderlyingDNS)
monitor.RegisterCallback(DnsManagerInstance.HandleSystemDNS)
if err = updMonitor.Start(); err != nil {
fmt.Println("Could not start updMonitor")
return
}
if err = monitor.Start(); err != nil {
fmt.Println("Could not start monitor")
return
}
//DnsManagerInstance.HandleUnderlyingDNS(monitor.DefaultInterface(), 0)
}
var DnsManagerInstance *DnsManager
type DnsManager struct {
Monitor tun.DefaultInterfaceMonitor
lastIfc control.Interface
}
func (d *DnsManager) HandleUnderlyingDNS(ifc *control.Interface, flag int) {
if d == nil {
fmt.Println("No DnsManager, you may need to restart nekoray")
return return
} }
ifc := DefaultIfcMonitor.DefaultInterface()
if ifc == nil { if ifc == nil {
log.Println("Default interface is nil!") log.Println("Default interface is nil!")
return return

View File

@ -15,7 +15,6 @@ import (
"nekobox_core/gen" "nekobox_core/gen"
"nekobox_core/internal/boxapi" "nekobox_core/internal/boxapi"
"nekobox_core/internal/boxbox" "nekobox_core/internal/boxbox"
"nekobox_core/internal/boxdns"
"nekobox_core/internal/boxmain" "nekobox_core/internal/boxmain"
"nekobox_core/internal/sys" "nekobox_core/internal/sys"
"net/http" "net/http"
@ -68,12 +67,6 @@ func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.Err
if err != nil { if err != nil {
return 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") { if runtime.GOOS == "darwin" && strings.Contains(in.CoreConfig, "utun") {
err := sys.SetSystemDNS("172.19.0.2", boxInstance.Network().InterfaceMonitor()) err := sys.SetSystemDNS("172.19.0.2", boxInstance.Network().InterfaceMonitor())
if err != nil { if err != nil {

View File

@ -8,7 +8,7 @@ import (
) )
func (s *server) GetSystemDNS(ctx context.Context, in *gen.EmptyReq) (*gen.GetSystemDNSResponse, error) { func (s *server) GetSystemDNS(ctx context.Context, in *gen.EmptyReq) (*gen.GetSystemDNSResponse, error) {
servers, dhcp, err := boxdns.GetDefaultDNS() servers, dhcp, err := boxdns.DnsManagerInstance.GetDefaultDNS()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -33,7 +33,7 @@ func (s *server) SetSystemDNS(ctx context.Context, in *gen.SetSystemDNSRequest)
} }
servers = append(servers, s) servers = append(servers, s)
} }
err := boxdns.SetDefaultDNS(servers, in.SetDhcp, in.Clear) err := boxdns.DnsManagerInstance.SetDefaultDNS(servers, in.SetDhcp, in.Clear)
if err != nil { if err != nil {
return nil, err return nil, err
} }