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
}
// 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)
updateProxies(cfg.Proxies, cfg.Providers)
updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders)
@ -100,8 +101,6 @@ func ApplyConfig(cfg *config.Config, force bool) {
updateDNS(cfg.DNS, cfg.General.IPv6)
updateListeners(cfg.General, cfg.Listeners, force)
updateIPTables(cfg)
updateTun(cfg.General)
updateExperimental(cfg)
updateTunnels(cfg.Tunnels)
tunnel.OnInnerLoading()
@ -186,6 +185,7 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
listener.ReCreateVmess(general.VmessConfig, tunnel.Tunnel)
listener.ReCreateTuic(general.TuicServer, tunnel.Tunnel)
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
}
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) {
if sniffer.Enable {

View File

@ -62,7 +62,6 @@ type tunSchema struct {
DNSHijack *[]string `yaml:"dns-hijack" json:"dns-hijack"`
AutoRoute *bool `yaml:"auto-route" json:"auto-route"`
AutoDetectInterface *bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
//RedirectToTun []string `yaml:"-" json:"-"`
MTU *uint32 `yaml:"mtu" json:"mtu,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)
}
func pointerOrDefault(p *int, def int) int {
func pointerOrDefault[T any](p *T, def T) T {
if p != nil {
return *p
}
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 {
if p != nil {
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.ReCreateMixed(pointerOrDefault(general.MixedPort, ports.MixedPort), tunnel.Tunnel)
P.ReCreateTun(pointerOrDefaultTun(general.Tun, P.LastTunConf), tunnel.Tunnel)
P.ReCreateShadowSocks(pointerOrDefaultString(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel)
P.ReCreateVmess(pointerOrDefaultString(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel)
P.ReCreateShadowSocks(pointerOrDefault(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel)
P.ReCreateVmess(pointerOrDefault(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel)
P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tunnel.Tunnel)
if general.Mode != nil {

View File

@ -3,7 +3,10 @@ package config
import (
"net/netip"
"github.com/metacubex/mihomo/common/nnip"
C "github.com/metacubex/mihomo/constant"
"golang.org/x/exp/slices"
)
func StringSliceToNetipPrefixSlice(ss []string) ([]netip.Prefix, error) {
@ -25,7 +28,6 @@ type Tun struct {
DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
RedirectToTun []string `yaml:"-" json:"-"`
MTU uint32 `yaml:"mtu" json:"mtu,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"`
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 (
"fmt"
"golang.org/x/exp/slices"
"net"
"sort"
"strconv"
"strings"
"sync"
@ -60,8 +58,6 @@ var (
ssMux sync.Mutex
vmessMux sync.Mutex
tuicMux sync.Mutex
autoRedirMux sync.Mutex
tcMux sync.Mutex
LastTunConf LC.Tun
LastTuicConf LC.TuicServer
@ -499,6 +495,8 @@ func ReCreateMixed(port int, tunnel C.Tunnel) {
}
func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) {
tunConf.Sort()
tunMux.Lock()
defer func() {
LastTunConf = tunConf
@ -513,7 +511,7 @@ func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) {
}
}()
if !hasTunConfigChange(&tunConf) {
if tunConf.Equal(LastTunConf) {
if tunLister != nil {
tunLister.FlushDefaultInterface()
}
@ -717,137 +715,6 @@ func genAddr(host string, port int, allowLan bool) string {
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() {
if tunLister != nil {
tunLister.Close()