github.com/chwjbn/xclash@v0.2.0/rule/ipcidr.go (about)

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