package rule import ( "strings" "github.com/sagernet/sing-box/adapter" F "github.com/sagernet/sing/common/format" ) var _ RuleItem = (*PortItem)(nil) type PortItem struct { ports []uint16 portMap map[uint16]bool isSource bool } func NewPortItem(isSource bool, ports []uint16) *PortItem { portMap := make(map[uint16]bool) for _, port := range ports { portMap[port] = true } return &PortItem{ ports: ports, portMap: portMap, isSource: isSource, } } func (r *PortItem) Match(metadata *adapter.InboundContext) bool { if r.isSource { return r.portMap[metadata.Source.Port] } else { return r.portMap[metadata.Destination.Port] } } func (r *PortItem) String() string { var description string if r.isSource { description = "source_port=" } else { description = "port=" } pLen := len(r.ports) if pLen == 1 { description += F.ToString(r.ports[0]) } else { description += "[" + strings.Join(F.MapToString(r.ports), " ") + "]" } return description }