rule_default_interface_address.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package rule
  2. import (
  3. "net/netip"
  4. "strings"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-tun"
  7. "github.com/sagernet/sing/common"
  8. "github.com/sagernet/sing/common/json/badoption"
  9. )
  10. var _ RuleItem = (*DefaultInterfaceAddressItem)(nil)
  11. type DefaultInterfaceAddressItem struct {
  12. interfaceMonitor tun.DefaultInterfaceMonitor
  13. interfaceAddresses []netip.Prefix
  14. }
  15. func NewDefaultInterfaceAddressItem(networkManager adapter.NetworkManager, interfaceAddresses badoption.Listable[*badoption.Prefixable]) *DefaultInterfaceAddressItem {
  16. item := &DefaultInterfaceAddressItem{
  17. interfaceMonitor: networkManager.InterfaceMonitor(),
  18. interfaceAddresses: make([]netip.Prefix, 0, len(interfaceAddresses)),
  19. }
  20. for _, prefixable := range interfaceAddresses {
  21. item.interfaceAddresses = append(item.interfaceAddresses, prefixable.Build(netip.Prefix{}))
  22. }
  23. return item
  24. }
  25. func (r *DefaultInterfaceAddressItem) Match(metadata *adapter.InboundContext) bool {
  26. defaultInterface := r.interfaceMonitor.DefaultInterface()
  27. if defaultInterface == nil {
  28. return false
  29. }
  30. for _, address := range r.interfaceAddresses {
  31. if common.All(defaultInterface.Addresses, func(it netip.Prefix) bool {
  32. return !address.Overlaps(it)
  33. }) {
  34. return false
  35. }
  36. }
  37. return true
  38. }
  39. func (r *DefaultInterfaceAddressItem) String() string {
  40. addressLen := len(r.interfaceAddresses)
  41. switch {
  42. case addressLen == 1:
  43. return "default_interface_address=" + r.interfaceAddresses[0].String()
  44. case addressLen > 3:
  45. return "default_interface_address=[" + strings.Join(common.Map(r.interfaceAddresses[:3], netip.Prefix.String), " ") + "...]"
  46. default:
  47. return "default_interface_address=[" + strings.Join(common.Map(r.interfaceAddresses, netip.Prefix.String), " ") + "]"
  48. }
  49. }