github.com/igoogolx/clash@v1.19.8/rule/ipcidr.go (about)

     1  package rules
     2  
     3  import (
     4  	"net"
     5  
     6  	C "github.com/igoogolx/clash/constant"
     7  )
     8  
     9  type IPCIDROption func(*IPCIDR)
    10  
    11  func WithIPCIDRSourceIP(b bool) IPCIDROption {
    12  	return func(i *IPCIDR) {
    13  		i.isSourceIP = b
    14  	}
    15  }
    16  
    17  func WithIPCIDRNoResolve(noResolve bool) IPCIDROption {
    18  	return func(i *IPCIDR) {
    19  		i.noResolveIP = noResolve
    20  	}
    21  }
    22  
    23  // Implements C.Rule
    24  var _ C.Rule = (*IPCIDR)(nil)
    25  
    26  type IPCIDR struct {
    27  	ipnet       *net.IPNet
    28  	adapter     string
    29  	isSourceIP  bool
    30  	noResolveIP bool
    31  }
    32  
    33  func (i *IPCIDR) RuleType() C.RuleType {
    34  	if i.isSourceIP {
    35  		return C.SrcIPCIDR
    36  	}
    37  	return C.IPCIDR
    38  }
    39  
    40  func (i *IPCIDR) Match(metadata *C.Metadata) bool {
    41  	ip := metadata.DstIP
    42  	if i.isSourceIP {
    43  		ip = metadata.SrcIP
    44  	}
    45  	return ip != nil && i.ipnet.Contains(ip)
    46  }
    47  
    48  func (i *IPCIDR) Adapter() string {
    49  	return i.adapter
    50  }
    51  
    52  func (i *IPCIDR) Payload() string {
    53  	return i.ipnet.String()
    54  }
    55  
    56  func (i *IPCIDR) ShouldResolveIP() bool {
    57  	return !i.noResolveIP
    58  }
    59  
    60  func (i *IPCIDR) ShouldFindProcess() bool {
    61  	return false
    62  }
    63  
    64  func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) {
    65  	_, ipnet, err := net.ParseCIDR(s)
    66  	if err != nil {
    67  		return nil, errPayload
    68  	}
    69  
    70  	ipcidr := &IPCIDR{
    71  		ipnet:   ipnet,
    72  		adapter: adapter,
    73  	}
    74  
    75  	for _, o := range opts {
    76  		o(ipcidr)
    77  	}
    78  
    79  	return ipcidr, nil
    80  }