Clash.Meta/component/cidr/ipcidr_set.go

69 lines
1.3 KiB
Go
Raw Normal View History

package cidr
import (
2024-01-13 18:15:30 +08:00
"fmt"
"net/netip"
2024-01-13 18:15:30 +08:00
"unsafe"
"go4.org/netipx"
)
type IpCidrSet struct {
2024-01-13 18:15:30 +08:00
// must same with netipx.IPSet
rr []netipx.IPRange
}
func NewIpCidrSet() *IpCidrSet {
return &IpCidrSet{}
}
func (set *IpCidrSet) AddIpCidrForString(ipCidr string) error {
prefix, err := netip.ParsePrefix(ipCidr)
if err != nil {
return err
}
2024-01-13 18:15:30 +08:00
return set.AddIpCidr(prefix)
}
func (set *IpCidrSet) AddIpCidr(ipCidr netip.Prefix) (err error) {
2024-01-13 18:15:30 +08:00
if r := netipx.RangeOfPrefix(ipCidr); r.IsValid() {
set.rr = append(set.rr, r)
} else {
err = fmt.Errorf("not valid ipcidr range: %s", ipCidr)
}
return
}
func (set *IpCidrSet) IsContainForString(ipString string) bool {
ip, err := netip.ParseAddr(ipString)
if err != nil {
return false
}
return set.IsContain(ip)
}
func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
return set.ToIPSet().Contains(ip.WithZone(""))
2024-01-13 18:15:30 +08:00
}
func (set *IpCidrSet) Merge() error {
var b netipx.IPSetBuilder
b.AddSet(set.ToIPSet())
2024-01-13 18:15:30 +08:00
i, err := b.IPSet()
if err != nil {
return err
}
2024-01-13 18:15:30 +08:00
set.fromIPSet(i)
return nil
}
// ToIPSet not safe convert to *netipx.IPSet
// be careful, must be used after Merge
func (set *IpCidrSet) ToIPSet() *netipx.IPSet {
2024-01-13 18:15:30 +08:00
return (*netipx.IPSet)(unsafe.Pointer(set))
}
2024-01-13 18:15:30 +08:00
func (set *IpCidrSet) fromIPSet(i *netipx.IPSet) {
*set = *(*IpCidrSet)(unsafe.Pointer(i))
}