github.com/kelleygo/clashcore@v1.0.2/component/cidr/ipcidr_set.go (about)

     1  package cidr
     2  
     3  import (
     4  	"fmt"
     5  	"net/netip"
     6  	"unsafe"
     7  
     8  	"go4.org/netipx"
     9  )
    10  
    11  type IpCidrSet struct {
    12  	// must same with netipx.IPSet
    13  	rr []netipx.IPRange
    14  }
    15  
    16  func NewIpCidrSet() *IpCidrSet {
    17  	return &IpCidrSet{}
    18  }
    19  
    20  func (set *IpCidrSet) AddIpCidrForString(ipCidr string) error {
    21  	prefix, err := netip.ParsePrefix(ipCidr)
    22  	if err != nil {
    23  		return err
    24  	}
    25  	return set.AddIpCidr(prefix)
    26  }
    27  
    28  func (set *IpCidrSet) AddIpCidr(ipCidr netip.Prefix) (err error) {
    29  	if r := netipx.RangeOfPrefix(ipCidr); r.IsValid() {
    30  		set.rr = append(set.rr, r)
    31  	} else {
    32  		err = fmt.Errorf("not valid ipcidr range: %s", ipCidr)
    33  	}
    34  	return
    35  }
    36  
    37  func (set *IpCidrSet) IsContainForString(ipString string) bool {
    38  	ip, err := netip.ParseAddr(ipString)
    39  	if err != nil {
    40  		return false
    41  	}
    42  	return set.IsContain(ip)
    43  }
    44  
    45  func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
    46  	return set.toIPSet().Contains(ip.WithZone(""))
    47  }
    48  
    49  func (set *IpCidrSet) Merge() error {
    50  	var b netipx.IPSetBuilder
    51  	b.AddSet(set.toIPSet())
    52  	i, err := b.IPSet()
    53  	if err != nil {
    54  		return err
    55  	}
    56  	set.fromIPSet(i)
    57  	return nil
    58  }
    59  
    60  func (set *IpCidrSet) toIPSet() *netipx.IPSet {
    61  	return (*netipx.IPSet)(unsafe.Pointer(set))
    62  }
    63  
    64  func (set *IpCidrSet) fromIPSet(i *netipx.IPSet) {
    65  	*set = *(*IpCidrSet)(unsafe.Pointer(i))
    66  }