github.com/kelleygo/clashcore@v1.0.2/rules/common/ipsuffix.go (about) 1 package common 2 3 import ( 4 C "github.com/kelleygo/clashcore/constant" 5 "net/netip" 6 ) 7 8 type IPSuffix struct { 9 *Base 10 ipBytes []byte 11 bits int 12 payload string 13 adapter string 14 isSourceIP bool 15 noResolveIP bool 16 } 17 18 func (is *IPSuffix) RuleType() C.RuleType { 19 if is.isSourceIP { 20 return C.SrcIPSuffix 21 } 22 return C.IPSuffix 23 } 24 25 func (is *IPSuffix) Match(metadata *C.Metadata) (bool, string) { 26 ip := metadata.DstIP 27 if is.isSourceIP { 28 ip = metadata.SrcIP 29 } 30 31 mIPBytes := ip.AsSlice() 32 if len(is.ipBytes) != len(mIPBytes) { 33 return false, "" 34 } 35 36 size := len(mIPBytes) 37 bits := is.bits 38 39 for i := bits / 8; i > 0; i-- { 40 if is.ipBytes[size-i] != mIPBytes[size-i] { 41 return false, "" 42 } 43 } 44 45 if (is.ipBytes[size-bits/8-1] << (8 - bits%8)) != (mIPBytes[size-bits/8-1] << (8 - bits%8)) { 46 return false, "" 47 } 48 49 return true, is.adapter 50 } 51 52 func (is *IPSuffix) Adapter() string { 53 return is.adapter 54 } 55 56 func (is *IPSuffix) Payload() string { 57 return is.payload 58 } 59 60 func (is *IPSuffix) ShouldResolveIP() bool { 61 return !is.noResolveIP 62 } 63 64 func NewIPSuffix(payload, adapter string, isSrc, noResolveIP bool) (*IPSuffix, error) { 65 ipnet, err := netip.ParsePrefix(payload) 66 if err != nil { 67 return nil, errPayload 68 } 69 70 return &IPSuffix{ 71 Base: &Base{}, 72 payload: payload, 73 ipBytes: ipnet.Addr().AsSlice(), 74 bits: ipnet.Bits(), 75 adapter: adapter, 76 isSourceIP: isSrc, 77 noResolveIP: noResolveIP, 78 }, nil 79 }