sing-box/route/rule_cidr.go

69 lines
1.4 KiB
Go
Raw Normal View History

2022-07-02 14:55:10 +00:00
package route
import (
"net/netip"
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*IPCIDRItem)(nil)
type IPCIDRItem struct {
prefixes []netip.Prefix
isSource bool
}
func NewIPCIDRItem(isSource bool, prefixStrings []string) (*IPCIDRItem, error) {
prefixes := make([]netip.Prefix, 0, len(prefixStrings))
for _, prefixString := range prefixStrings {
prefix, err := netip.ParsePrefix(prefixString)
if err != nil {
return nil, err
}
prefixes = append(prefixes, prefix)
}
return &IPCIDRItem{
prefixes: prefixes,
isSource: isSource,
}, nil
}
func (r *IPCIDRItem) Match(metadata *adapter.InboundContext) bool {
if r.isSource {
for _, prefix := range r.prefixes {
if prefix.Contains(metadata.Source.Addr) {
return true
}
}
} else {
if metadata.Destination.IsFqdn() {
return false
}
for _, prefix := range r.prefixes {
if prefix.Contains(metadata.Destination.Addr) {
return true
}
}
}
return false
}
func (r *IPCIDRItem) String() string {
var description string
if r.isSource {
description = "source_ipcidr="
} else {
description = "ipcidr="
}
pLen := len(r.prefixes)
if pLen == 1 {
description += r.prefixes[0].String()
} else {
description += "[" + strings.Join(common.Map(r.prefixes, F.ToString0[netip.Prefix]), " ") + "]"
}
return description
}