| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package route
- import (
- "net/netip"
- "strings"
- "github.com/sagernet/sing-box/adapter"
- "github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
- 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 i, prefixString := range prefixStrings {
- prefix, err := netip.ParsePrefix(prefixString)
- if err != nil {
- return nil, E.Cause(err, "parse prefix [", i, "]")
- }
- 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
- }
|