github.com/yaling888/clash@v1.53.0/component/script/util.go (about) 1 package script 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand/v2" 7 "net/netip" 8 "path/filepath" 9 "strings" 10 11 "github.com/yaling888/clash/component/ipset" 12 "github.com/yaling888/clash/component/mmdb" 13 P "github.com/yaling888/clash/component/process" 14 "github.com/yaling888/clash/component/resolver" 15 C "github.com/yaling888/clash/constant" 16 ) 17 18 func uResolveIP(mtd *C.Metadata, host string) string { 19 var ip string 20 21 if mtd.Resolved() { 22 ip = mtd.DstIP.String() 23 } else if rAddrs, err := resolver.LookupIP(context.Background(), host); err == nil { 24 addr := rAddrs[0] 25 if l := len(rAddrs); l > 1 && mtd.NetWork != C.UDP { 26 addr = rAddrs[rand.IntN(l)] 27 } 28 ip = addr.String() 29 mtd.DstIP = addr 30 } 31 32 return ip 33 } 34 35 func uInCidr(ip, cidr string) (bool, error) { 36 var ( 37 mIP netip.Addr 38 mCidr netip.Prefix 39 err error 40 ) 41 42 if mIP, err = netip.ParseAddr(ip); err != nil { 43 return false, err 44 } 45 46 if mCidr, err = netip.ParsePrefix(cidr); err != nil { 47 return false, err 48 } 49 50 return mCidr.Contains(mIP), nil 51 } 52 53 func uInIPSet(name, ip string) bool { 54 dstIP, err := netip.ParseAddr(ip) 55 if err != nil { 56 return false 57 } 58 rs, err := ipset.Test(name, dstIP) 59 if err != nil { 60 return false 61 } 62 return rs 63 } 64 65 func uGeoIP(ip string) string { 66 dstIP, err := netip.ParseAddr(ip) 67 if err != nil { 68 return "" 69 } 70 71 if dstIP.IsPrivate() || 72 dstIP.IsUnspecified() || 73 dstIP.IsLoopback() || 74 dstIP.IsMulticast() || 75 dstIP.IsLinkLocalUnicast() || 76 resolver.IsFakeBroadcastIP(dstIP) { 77 78 return "LAN" 79 } 80 81 record, _ := mmdb.Instance().Country(dstIP.AsSlice()) 82 83 return strings.ToUpper(record.Country.IsoCode) 84 } 85 86 func uMatchProvider(mtd *C.Metadata, name string) (bool, error) { 87 providerName := strings.ToLower(name) 88 89 rule := C.GetScriptRuleProviders()[providerName] 90 if rule == nil { 91 return false, fmt.Errorf("call match_provider error: rule provider [%s] not found", name) 92 } 93 94 return rule.Match(mtd), nil 95 } 96 97 func uResolveProcess(mtd *C.Metadata) { 98 if mtd.ProcessPath != "" || !mtd.OriginDst.IsValid() { 99 return 100 } 101 102 path, err := P.FindProcessPath(mtd.NetWork.String(), netip.AddrPortFrom(mtd.SrcIP, uint16(mtd.SrcPort)), mtd.OriginDst) 103 if err == nil { 104 mtd.Process = filepath.Base(path) 105 mtd.ProcessPath = path 106 } 107 }