chore: code cleanup

This commit is contained in:
wwqgtxx 2024-08-24 13:25:23 +08:00
parent 16c95fca87
commit f5834dd5e2
5 changed files with 185 additions and 168 deletions

View File

@ -51,3 +51,23 @@ func UnMasked(p netip.Prefix) netip.Addr {
} }
return addr return addr
} }
// PrefixCompare returns an integer comparing two prefixes.
// The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
// modify from https://github.com/golang/go/issues/61642#issuecomment-1848587909
func PrefixCompare(p, p2 netip.Prefix) int {
// compare by validity, address family and prefix base address
if c := p.Masked().Addr().Compare(p2.Masked().Addr()); c != 0 {
return c
}
// compare by prefix length
f1, f2 := p.Bits(), p2.Bits()
if f1 < f2 {
return -1
}
if f1 > f2 {
return 1
}
// compare by prefix address
return p.Addr().Compare(p2.Addr())
}

View File

@ -90,6 +90,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
} }
} }
updateExperimental(cfg)
updateUsers(cfg.Users) updateUsers(cfg.Users)
updateProxies(cfg.Proxies, cfg.Providers) updateProxies(cfg.Proxies, cfg.Providers)
updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders) updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders)
@ -100,8 +101,6 @@ func ApplyConfig(cfg *config.Config, force bool) {
updateDNS(cfg.DNS, cfg.General.IPv6) updateDNS(cfg.DNS, cfg.General.IPv6)
updateListeners(cfg.General, cfg.Listeners, force) updateListeners(cfg.General, cfg.Listeners, force)
updateIPTables(cfg) updateIPTables(cfg)
updateTun(cfg.General)
updateExperimental(cfg)
updateTunnels(cfg.Tunnels) updateTunnels(cfg.Tunnels)
tunnel.OnInnerLoading() tunnel.OnInnerLoading()
@ -186,6 +185,7 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel) listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
listener.ReCreateVmess(general.VmessConfig, tunnel.Tunnel) listener.ReCreateVmess(general.VmessConfig, tunnel.Tunnel)
listener.ReCreateTuic(general.TuicServer, tunnel.Tunnel) listener.ReCreateTuic(general.TuicServer, tunnel.Tunnel)
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
} }
func updateExperimental(c *config.Config) { func updateExperimental(c *config.Config) {
@ -343,12 +343,6 @@ func hcCompatibleProvider(proxyProviders map[string]provider.ProxyProvider) {
} }
} }
func updateTun(general *config.General) {
if general == nil {
return
}
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
}
func updateSniffer(sniffer *config.Sniffer) { func updateSniffer(sniffer *config.Sniffer) {
if sniffer.Enable { if sniffer.Enable {

View File

@ -62,7 +62,6 @@ type tunSchema struct {
DNSHijack *[]string `yaml:"dns-hijack" json:"dns-hijack"` DNSHijack *[]string `yaml:"dns-hijack" json:"dns-hijack"`
AutoRoute *bool `yaml:"auto-route" json:"auto-route"` AutoRoute *bool `yaml:"auto-route" json:"auto-route"`
AutoDetectInterface *bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` AutoDetectInterface *bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
//RedirectToTun []string `yaml:"-" json:"-"`
MTU *uint32 `yaml:"mtu" json:"mtu,omitempty"` MTU *uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO *bool `yaml:"gso" json:"gso,omitempty"` GSO *bool `yaml:"gso" json:"gso,omitempty"`
@ -118,21 +117,13 @@ func getConfigs(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, general) render.JSON(w, r, general)
} }
func pointerOrDefault(p *int, def int) int { func pointerOrDefault[T any](p *T, def T) T {
if p != nil { if p != nil {
return *p return *p
} }
return def return def
} }
func pointerOrDefaultString(p *string, def string) string {
if p != nil {
return *p
}
return def
}
func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun { func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
if p != nil { if p != nil {
def.Enable = p.Enable def.Enable = p.Enable
@ -336,8 +327,8 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) {
P.ReCreateTProxy(pointerOrDefault(general.TProxyPort, ports.TProxyPort), tunnel.Tunnel) P.ReCreateTProxy(pointerOrDefault(general.TProxyPort, ports.TProxyPort), tunnel.Tunnel)
P.ReCreateMixed(pointerOrDefault(general.MixedPort, ports.MixedPort), tunnel.Tunnel) P.ReCreateMixed(pointerOrDefault(general.MixedPort, ports.MixedPort), tunnel.Tunnel)
P.ReCreateTun(pointerOrDefaultTun(general.Tun, P.LastTunConf), tunnel.Tunnel) P.ReCreateTun(pointerOrDefaultTun(general.Tun, P.LastTunConf), tunnel.Tunnel)
P.ReCreateShadowSocks(pointerOrDefaultString(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel) P.ReCreateShadowSocks(pointerOrDefault(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel)
P.ReCreateVmess(pointerOrDefaultString(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel) P.ReCreateVmess(pointerOrDefault(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel)
P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tunnel.Tunnel) P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tunnel.Tunnel)
if general.Mode != nil { if general.Mode != nil {

View File

@ -3,7 +3,10 @@ package config
import ( import (
"net/netip" "net/netip"
"github.com/metacubex/mihomo/common/nnip"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
"golang.org/x/exp/slices"
) )
func StringSliceToNetipPrefixSlice(ss []string) ([]netip.Prefix, error) { func StringSliceToNetipPrefixSlice(ss []string) ([]netip.Prefix, error) {
@ -25,7 +28,6 @@ type Tun struct {
DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"` DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
AutoRoute bool `yaml:"auto-route" json:"auto-route"` AutoRoute bool `yaml:"auto-route" json:"auto-route"`
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
RedirectToTun []string `yaml:"-" json:"-"`
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"` MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO bool `yaml:"gso" json:"gso,omitempty"` GSO bool `yaml:"gso" json:"gso,omitempty"`
@ -60,3 +62,146 @@ type Tun struct {
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"` Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"` Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
} }
func (t *Tun) Sort() {
slices.Sort(t.DNSHijack)
slices.SortFunc(t.Inet4Address, nnip.PrefixCompare)
slices.SortFunc(t.Inet6Address, nnip.PrefixCompare)
slices.SortFunc(t.RouteAddress, nnip.PrefixCompare)
slices.Sort(t.RouteAddressSet)
slices.SortFunc(t.RouteExcludeAddress, nnip.PrefixCompare)
slices.Sort(t.RouteExcludeAddressSet)
slices.Sort(t.IncludeInterface)
slices.Sort(t.ExcludeInterface)
slices.Sort(t.IncludeUID)
slices.Sort(t.IncludeUIDRange)
slices.Sort(t.ExcludeUID)
slices.Sort(t.ExcludeUIDRange)
slices.Sort(t.IncludeAndroidUser)
slices.Sort(t.IncludePackage)
slices.Sort(t.ExcludePackage)
slices.SortFunc(t.Inet4RouteAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet6RouteAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet4RouteExcludeAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet6RouteExcludeAddress, nnip.PrefixCompare)
}
func (t *Tun) Equal(other Tun) bool {
if t.Enable != other.Enable {
return false
}
if t.Device != other.Device {
return false
}
if t.Stack != other.Stack {
return false
}
if !slices.Equal(t.DNSHijack, other.DNSHijack) {
return false
}
if t.AutoRoute != other.AutoRoute {
return false
}
if t.AutoDetectInterface != other.AutoDetectInterface {
return false
}
if t.MTU != other.MTU {
return false
}
if t.GSO != other.GSO {
return false
}
if t.GSOMaxSize != other.GSOMaxSize {
return false
}
if !slices.Equal(t.Inet4Address, other.Inet4Address) {
return false
}
if !slices.Equal(t.Inet6Address, other.Inet6Address) {
return false
}
if t.IPRoute2TableIndex != other.IPRoute2TableIndex {
return false
}
if t.IPRoute2RuleIndex != other.IPRoute2RuleIndex {
return false
}
if t.AutoRedirect != other.AutoRedirect {
return false
}
if t.AutoRedirectInputMark != other.AutoRedirectInputMark {
return false
}
if t.AutoRedirectOutputMark != other.AutoRedirectOutputMark {
return false
}
if t.StrictRoute != other.StrictRoute {
return false
}
if !slices.Equal(t.RouteAddress, other.RouteAddress) {
return false
}
if !slices.Equal(t.RouteAddressSet, other.RouteAddressSet) {
return false
}
if !slices.Equal(t.RouteExcludeAddress, other.RouteExcludeAddress) {
return false
}
if !slices.Equal(t.RouteExcludeAddressSet, other.RouteExcludeAddressSet) {
return false
}
if !slices.Equal(t.IncludeInterface, other.IncludeInterface) {
return false
}
if !slices.Equal(t.ExcludeInterface, other.ExcludeInterface) {
return false
}
if !slices.Equal(t.IncludeUID, other.IncludeUID) {
return false
}
if !slices.Equal(t.IncludeUIDRange, other.IncludeUIDRange) {
return false
}
if !slices.Equal(t.ExcludeUID, other.ExcludeUID) {
return false
}
if !slices.Equal(t.ExcludeUIDRange, other.ExcludeUIDRange) {
return false
}
if !slices.Equal(t.IncludeAndroidUser, other.IncludeAndroidUser) {
return false
}
if !slices.Equal(t.IncludePackage, other.IncludePackage) {
return false
}
if !slices.Equal(t.ExcludePackage, other.ExcludePackage) {
return false
}
if t.EndpointIndependentNat != other.EndpointIndependentNat {
return false
}
if t.UDPTimeout != other.UDPTimeout {
return false
}
if t.FileDescriptor != other.FileDescriptor {
return false
}
if !slices.Equal(t.Inet4RouteAddress, other.Inet4RouteAddress) {
return false
}
if !slices.Equal(t.Inet6RouteAddress, other.Inet6RouteAddress) {
return false
}
if !slices.Equal(t.Inet4RouteExcludeAddress, other.Inet4RouteExcludeAddress) {
return false
}
if !slices.Equal(t.Inet6RouteExcludeAddress, other.Inet6RouteExcludeAddress) {
return false
}
return true
}

View File

@ -2,9 +2,7 @@ package listener
import ( import (
"fmt" "fmt"
"golang.org/x/exp/slices"
"net" "net"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -49,19 +47,17 @@ var (
tuicListener *tuic.Listener tuicListener *tuic.Listener
// lock for recreate function // lock for recreate function
socksMux sync.Mutex socksMux sync.Mutex
httpMux sync.Mutex httpMux sync.Mutex
redirMux sync.Mutex redirMux sync.Mutex
tproxyMux sync.Mutex tproxyMux sync.Mutex
mixedMux sync.Mutex mixedMux sync.Mutex
tunnelMux sync.Mutex tunnelMux sync.Mutex
inboundMux sync.Mutex inboundMux sync.Mutex
tunMux sync.Mutex tunMux sync.Mutex
ssMux sync.Mutex ssMux sync.Mutex
vmessMux sync.Mutex vmessMux sync.Mutex
tuicMux sync.Mutex tuicMux sync.Mutex
autoRedirMux sync.Mutex
tcMux sync.Mutex
LastTunConf LC.Tun LastTunConf LC.Tun
LastTuicConf LC.TuicServer LastTuicConf LC.TuicServer
@ -499,6 +495,8 @@ func ReCreateMixed(port int, tunnel C.Tunnel) {
} }
func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) { func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) {
tunConf.Sort()
tunMux.Lock() tunMux.Lock()
defer func() { defer func() {
LastTunConf = tunConf LastTunConf = tunConf
@ -513,7 +511,7 @@ func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) {
} }
}() }()
if !hasTunConfigChange(&tunConf) { if tunConf.Equal(LastTunConf) {
if tunLister != nil { if tunLister != nil {
tunLister.FlushDefaultInterface() tunLister.FlushDefaultInterface()
} }
@ -717,137 +715,6 @@ func genAddr(host string, port int, allowLan bool) string {
return fmt.Sprintf("127.0.0.1:%d", port) return fmt.Sprintf("127.0.0.1:%d", port)
} }
func hasTunConfigChange(tunConf *LC.Tun) bool {
if LastTunConf.Enable != tunConf.Enable ||
LastTunConf.Device != tunConf.Device ||
LastTunConf.Stack != tunConf.Stack ||
LastTunConf.AutoRoute != tunConf.AutoRoute ||
LastTunConf.AutoDetectInterface != tunConf.AutoDetectInterface ||
LastTunConf.MTU != tunConf.MTU ||
LastTunConf.GSO != tunConf.GSO ||
LastTunConf.GSOMaxSize != tunConf.GSOMaxSize ||
LastTunConf.IPRoute2TableIndex != tunConf.IPRoute2TableIndex ||
LastTunConf.IPRoute2RuleIndex != tunConf.IPRoute2RuleIndex ||
LastTunConf.AutoRedirect != tunConf.AutoRedirect ||
LastTunConf.AutoRedirectInputMark != tunConf.AutoRedirectInputMark ||
LastTunConf.AutoRedirectOutputMark != tunConf.AutoRedirectOutputMark ||
LastTunConf.StrictRoute != tunConf.StrictRoute ||
LastTunConf.EndpointIndependentNat != tunConf.EndpointIndependentNat ||
LastTunConf.UDPTimeout != tunConf.UDPTimeout ||
LastTunConf.FileDescriptor != tunConf.FileDescriptor {
return true
}
if len(LastTunConf.DNSHijack) != len(tunConf.DNSHijack) {
return true
}
sort.Slice(tunConf.DNSHijack, func(i, j int) bool {
return tunConf.DNSHijack[i] < tunConf.DNSHijack[j]
})
sort.Slice(tunConf.RouteAddress, func(i, j int) bool {
return tunConf.RouteAddress[i].String() < tunConf.RouteAddress[j].String()
})
sort.Slice(tunConf.RouteAddressSet, func(i, j int) bool {
return tunConf.RouteAddressSet[i] < tunConf.RouteAddressSet[j]
})
sort.Slice(tunConf.RouteExcludeAddress, func(i, j int) bool {
return tunConf.RouteExcludeAddress[i].String() < tunConf.RouteExcludeAddress[j].String()
})
sort.Slice(tunConf.RouteExcludeAddressSet, func(i, j int) bool {
return tunConf.RouteExcludeAddressSet[i] < tunConf.RouteExcludeAddressSet[j]
})
sort.Slice(tunConf.Inet4Address, func(i, j int) bool {
return tunConf.Inet4Address[i].String() < tunConf.Inet4Address[j].String()
})
sort.Slice(tunConf.Inet6Address, func(i, j int) bool {
return tunConf.Inet6Address[i].String() < tunConf.Inet6Address[j].String()
})
sort.Slice(tunConf.Inet4RouteAddress, func(i, j int) bool {
return tunConf.Inet4RouteAddress[i].String() < tunConf.Inet4RouteAddress[j].String()
})
sort.Slice(tunConf.Inet6RouteAddress, func(i, j int) bool {
return tunConf.Inet6RouteAddress[i].String() < tunConf.Inet6RouteAddress[j].String()
})
sort.Slice(tunConf.Inet4RouteExcludeAddress, func(i, j int) bool {
return tunConf.Inet4RouteExcludeAddress[i].String() < tunConf.Inet4RouteExcludeAddress[j].String()
})
sort.Slice(tunConf.Inet6RouteExcludeAddress, func(i, j int) bool {
return tunConf.Inet6RouteExcludeAddress[i].String() < tunConf.Inet6RouteExcludeAddress[j].String()
})
sort.Slice(tunConf.IncludeInterface, func(i, j int) bool {
return tunConf.IncludeInterface[i] < tunConf.IncludeInterface[j]
})
sort.Slice(tunConf.ExcludeInterface, func(i, j int) bool {
return tunConf.ExcludeInterface[i] < tunConf.ExcludeInterface[j]
})
sort.Slice(tunConf.IncludeUID, func(i, j int) bool {
return tunConf.IncludeUID[i] < tunConf.IncludeUID[j]
})
sort.Slice(tunConf.IncludeUIDRange, func(i, j int) bool {
return tunConf.IncludeUIDRange[i] < tunConf.IncludeUIDRange[j]
})
sort.Slice(tunConf.ExcludeUID, func(i, j int) bool {
return tunConf.ExcludeUID[i] < tunConf.ExcludeUID[j]
})
sort.Slice(tunConf.ExcludeUIDRange, func(i, j int) bool {
return tunConf.ExcludeUIDRange[i] < tunConf.ExcludeUIDRange[j]
})
sort.Slice(tunConf.IncludeAndroidUser, func(i, j int) bool {
return tunConf.IncludeAndroidUser[i] < tunConf.IncludeAndroidUser[j]
})
sort.Slice(tunConf.IncludePackage, func(i, j int) bool {
return tunConf.IncludePackage[i] < tunConf.IncludePackage[j]
})
sort.Slice(tunConf.ExcludePackage, func(i, j int) bool {
return tunConf.ExcludePackage[i] < tunConf.ExcludePackage[j]
})
if !slices.Equal(tunConf.DNSHijack, LastTunConf.DNSHijack) ||
!slices.Equal(tunConf.RouteAddress, LastTunConf.RouteAddress) ||
!slices.Equal(tunConf.RouteAddressSet, LastTunConf.RouteAddressSet) ||
!slices.Equal(tunConf.RouteExcludeAddress, LastTunConf.RouteExcludeAddress) ||
!slices.Equal(tunConf.RouteExcludeAddressSet, LastTunConf.RouteExcludeAddressSet) ||
!slices.Equal(tunConf.Inet4Address, LastTunConf.Inet4Address) ||
!slices.Equal(tunConf.Inet6Address, LastTunConf.Inet6Address) ||
!slices.Equal(tunConf.Inet4RouteAddress, LastTunConf.Inet4RouteAddress) ||
!slices.Equal(tunConf.Inet6RouteAddress, LastTunConf.Inet6RouteAddress) ||
!slices.Equal(tunConf.Inet4RouteExcludeAddress, LastTunConf.Inet4RouteExcludeAddress) ||
!slices.Equal(tunConf.Inet6RouteExcludeAddress, LastTunConf.Inet6RouteExcludeAddress) ||
!slices.Equal(tunConf.IncludeInterface, LastTunConf.IncludeInterface) ||
!slices.Equal(tunConf.ExcludeInterface, LastTunConf.ExcludeInterface) ||
!slices.Equal(tunConf.IncludeUID, LastTunConf.IncludeUID) ||
!slices.Equal(tunConf.IncludeUIDRange, LastTunConf.IncludeUIDRange) ||
!slices.Equal(tunConf.ExcludeUID, LastTunConf.ExcludeUID) ||
!slices.Equal(tunConf.ExcludeUIDRange, LastTunConf.ExcludeUIDRange) ||
!slices.Equal(tunConf.IncludeAndroidUser, LastTunConf.IncludeAndroidUser) ||
!slices.Equal(tunConf.IncludePackage, LastTunConf.IncludePackage) ||
!slices.Equal(tunConf.ExcludePackage, LastTunConf.ExcludePackage) {
return true
}
return false
}
func closeTunListener() { func closeTunListener() {
if tunLister != nil { if tunLister != nil {
tunLister.Close() tunLister.Close()