12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package rule
- import (
- "net/netip"
- "strings"
- "github.com/sagernet/sing-box/adapter"
- C "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing/common"
- "github.com/sagernet/sing/common/json/badjson"
- "github.com/sagernet/sing/common/json/badoption"
- )
- var _ RuleItem = (*NetworkInterfaceAddressItem)(nil)
- type NetworkInterfaceAddressItem struct {
- networkManager adapter.NetworkManager
- interfaceAddresses map[C.InterfaceType][]netip.Prefix
- description string
- }
- func NewNetworkInterfaceAddressItem(networkManager adapter.NetworkManager, interfaceAddresses *badjson.TypedMap[option.InterfaceType, badoption.Listable[*badoption.Prefixable]]) *NetworkInterfaceAddressItem {
- item := &NetworkInterfaceAddressItem{
- networkManager: networkManager,
- interfaceAddresses: make(map[C.InterfaceType][]netip.Prefix, interfaceAddresses.Size()),
- }
- var entryDescriptions []string
- for _, entry := range interfaceAddresses.Entries() {
- prefixes := make([]netip.Prefix, 0, len(entry.Value))
- for _, prefixable := range entry.Value {
- prefixes = append(prefixes, prefixable.Build(netip.Prefix{}))
- }
- item.interfaceAddresses[entry.Key.Build()] = prefixes
- entryDescriptions = append(entryDescriptions, entry.Key.Build().String()+"="+strings.Join(common.Map(prefixes, netip.Prefix.String), ","))
- }
- item.description = "network_interface_address=[" + strings.Join(entryDescriptions, " ") + "]"
- return item
- }
- func (r *NetworkInterfaceAddressItem) Match(metadata *adapter.InboundContext) bool {
- interfaces := r.networkManager.NetworkInterfaces()
- match:
- for ifType, addresses := range r.interfaceAddresses {
- for _, networkInterface := range interfaces {
- if networkInterface.Type != ifType {
- continue
- }
- if common.Any(networkInterface.Addresses, func(it netip.Prefix) bool {
- return common.Any(addresses, func(prefix netip.Prefix) bool {
- return prefix.Overlaps(it)
- })
- }) {
- continue match
- }
- }
- return false
- }
- return true
- }
- func (r *NetworkInterfaceAddressItem) String() string {
- return r.description
- }
|