From 9e3bf14b1aa17027e8b231fe3d01cb0891d72ad3 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Fri, 23 May 2025 20:59:02 +0800 Subject: [PATCH] chore: handle two interfaces have the same prefix but different address --- component/iface/iface.go | 21 +++++++++++++++------ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/component/iface/iface.go b/component/iface/iface.go index 92e0ccf3..ddb779aa 100644 --- a/component/iface/iface.go +++ b/component/iface/iface.go @@ -26,8 +26,9 @@ var ( ) type ifaceCache struct { - ifMap map[string]*Interface - ifTable bart.Table[*Interface] + ifMapByName map[string]*Interface + ifMapByAddr map[netip.Addr]*Interface + ifTable bart.Table[*Interface] } var caches = singledo.NewSingle[*ifaceCache](time.Second * 20) @@ -40,7 +41,8 @@ func getCache() (*ifaceCache, error) { } cache := &ifaceCache{ - ifMap: make(map[string]*Interface), + ifMapByName: make(map[string]*Interface), + ifMapByAddr: make(map[netip.Addr]*Interface), } for _, iface := range ifaces { @@ -78,12 +80,13 @@ func getCache() (*ifaceCache, error) { Flags: iface.Flags, Addresses: ipNets, } - cache.ifMap[iface.Name] = ifaceObj + cache.ifMapByName[iface.Name] = ifaceObj if iface.Flags&net.FlagUp == 0 { continue // interface down } for _, prefix := range ipNets { + cache.ifMapByAddr[prefix.Addr()] = ifaceObj cache.ifTable.Insert(prefix, ifaceObj) } } @@ -98,7 +101,7 @@ func Interfaces() (map[string]*Interface, error) { if err != nil { return nil, err } - return cache.ifMap, nil + return cache.ifMapByName, nil } func ResolveInterface(name string) (*Interface, error) { @@ -120,6 +123,11 @@ func ResolveInterfaceByAddr(addr netip.Addr) (*Interface, error) { if err != nil { return nil, err } + // maybe two interfaces have the same prefix but different address + // so direct check address equal before do a route lookup (longest prefix match) + if iface, ok := cache.ifMapByAddr[addr]; ok { + return iface, nil + } iface, ok := cache.ifTable.Lookup(addr) if !ok { return nil, ErrIfaceNotFound @@ -133,7 +141,8 @@ func IsLocalIp(addr netip.Addr) (bool, error) { if err != nil { return false, err } - return cache.ifTable.Contains(addr), nil + _, ok := cache.ifMapByAddr[addr] + return ok, nil } func FlushCache() { diff --git a/go.mod b/go.mod index cffcde9e..cf9ce2c7 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 github.com/metacubex/quic-go v0.52.1-0.20250522021943-aef454b9e639 github.com/metacubex/randv2 v0.2.0 - github.com/metacubex/sing v0.5.3-0.20250504031621-1f99e54c15b7 + github.com/metacubex/sing v0.5.3 github.com/metacubex/sing-mux v0.3.2 github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f github.com/metacubex/sing-shadowsocks v0.2.9 diff --git a/go.sum b/go.sum index cd8787ee..6b0c9373 100644 --- a/go.sum +++ b/go.sum @@ -116,8 +116,8 @@ github.com/metacubex/quic-go v0.52.1-0.20250522021943-aef454b9e639/go.mod h1:Kc6 github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs= github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY= github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= -github.com/metacubex/sing v0.5.3-0.20250504031621-1f99e54c15b7 h1:m4nSxvw46JEgxMzzmnXams+ebwabcry4Ydep/zNiesQ= -github.com/metacubex/sing v0.5.3-0.20250504031621-1f99e54c15b7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= +github.com/metacubex/sing v0.5.3 h1:QWdN16WFKMk06x4nzkc8SvZ7y2x+TLQrpkPoHs+WSVM= +github.com/metacubex/sing v0.5.3/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= github.com/metacubex/sing-mux v0.3.2 h1:nJv52pyRivHcaZJKk2JgxpaVvj1GAXG81scSa9N7ncw= github.com/metacubex/sing-mux v0.3.2/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw= github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f h1:mP3vIm+9hRFI0C0Vl3pE0NESF/L85FDbuB0tGgUii6I=