2024-10-21 15:38:34 +00:00
|
|
|
package rule
|
2022-07-02 14:55:10 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
2022-07-08 15:03:57 +00:00
|
|
|
"github.com/sagernet/sing-box/adapter"
|
2022-07-02 14:55:10 +00:00
|
|
|
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 {
|
2022-07-10 14:00:28 +00:00
|
|
|
description += "[" + strings.Join(F.MapToString(r.ports), " ") + "]"
|
2022-07-02 14:55:10 +00:00
|
|
|
}
|
|
|
|
return description
|
|
|
|
}
|