github.com/kelleygo/clashcore@v1.0.2/rules/common/ipcidr.go (about)

     1  package common
     2  
     3  import (
     4  	"net/netip"
     5  
     6  	C "github.com/kelleygo/clashcore/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  type IPCIDR struct {
    24  	*Base
    25  	ipnet       netip.Prefix
    26  	adapter     string
    27  	isSourceIP  bool
    28  	noResolveIP bool
    29  }
    30  
    31  func (i *IPCIDR) RuleType() C.RuleType {
    32  	if i.isSourceIP {
    33  		return C.SrcIPCIDR
    34  	}
    35  	return C.IPCIDR
    36  }
    37  
    38  func (i *IPCIDR) Match(metadata *C.Metadata) (bool, string) {
    39  	ip := metadata.DstIP
    40  	if i.isSourceIP {
    41  		ip = metadata.SrcIP
    42  	}
    43  	return ip.IsValid() && i.ipnet.Contains(ip), i.adapter
    44  }
    45  
    46  func (i *IPCIDR) Adapter() string {
    47  	return i.adapter
    48  }
    49  
    50  func (i *IPCIDR) Payload() string {
    51  	return i.ipnet.String()
    52  }
    53  
    54  func (i *IPCIDR) ShouldResolveIP() bool {
    55  	return !i.noResolveIP
    56  }
    57  
    58  func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) {
    59  	ipnet, err := netip.ParsePrefix(s)
    60  	if err != nil {
    61  		return nil, errPayload
    62  	}
    63  
    64  	ipcidr := &IPCIDR{
    65  		Base:    &Base{},
    66  		ipnet:   ipnet,
    67  		adapter: adapter,
    68  	}
    69  
    70  	for _, o := range opts {
    71  		o(ipcidr)
    72  	}
    73  
    74  	return ipcidr, nil
    75  }
    76  
    77  //var _ C.Rule = (*IPCIDR)(nil)