github.com/sagernet/sing-box@v1.9.0-rc.20/route/rule_item_port_range.go (about) 1 package route 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/sagernet/sing-box/adapter" 8 E "github.com/sagernet/sing/common/exceptions" 9 ) 10 11 var ErrBadPortRange = E.New("bad port range") 12 13 var _ RuleItem = (*PortRangeItem)(nil) 14 15 type PortRangeItem struct { 16 isSource bool 17 portRanges []string 18 portRangeList []rangeItem 19 } 20 21 type rangeItem struct { 22 start uint16 23 end uint16 24 } 25 26 func NewPortRangeItem(isSource bool, rangeList []string) (*PortRangeItem, error) { 27 portRangeList := make([]rangeItem, 0, len(rangeList)) 28 for _, portRange := range rangeList { 29 if !strings.Contains(portRange, ":") { 30 return nil, E.Extend(ErrBadPortRange, portRange) 31 } 32 subIndex := strings.Index(portRange, ":") 33 var start, end uint64 34 var err error 35 if subIndex > 0 { 36 start, err = strconv.ParseUint(portRange[:subIndex], 10, 16) 37 if err != nil { 38 return nil, E.Cause(err, E.Extend(ErrBadPortRange, portRange)) 39 } 40 } 41 if subIndex == len(portRange)-1 { 42 end = 0xFF 43 } else { 44 end, err = strconv.ParseUint(portRange[subIndex+1:], 10, 16) 45 if err != nil { 46 return nil, E.Cause(err, E.Extend(ErrBadPortRange, portRange)) 47 } 48 } 49 portRangeList = append(portRangeList, rangeItem{uint16(start), uint16(end)}) 50 } 51 return &PortRangeItem{ 52 isSource: isSource, 53 portRanges: rangeList, 54 portRangeList: portRangeList, 55 }, nil 56 } 57 58 func (r *PortRangeItem) Match(metadata *adapter.InboundContext) bool { 59 var port uint16 60 if r.isSource { 61 port = metadata.Source.Port 62 } else { 63 port = metadata.Destination.Port 64 } 65 for _, portRange := range r.portRangeList { 66 if port >= portRange.start && port <= portRange.end { 67 return true 68 } 69 } 70 return false 71 } 72 73 func (r *PortRangeItem) String() string { 74 var description string 75 if r.isSource { 76 description = "source_port_range=" 77 } else { 78 description = "port_range=" 79 } 80 pLen := len(r.portRanges) 81 if pLen == 1 { 82 description += r.portRanges[0] 83 } else { 84 description += "[" + strings.Join(r.portRanges, " ") + "]" 85 } 86 return description 87 }