rule_ip.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package option
  2. import (
  3. "reflect"
  4. "github.com/sagernet/sing-box/common/json"
  5. C "github.com/sagernet/sing-box/constant"
  6. tun "github.com/sagernet/sing-tun"
  7. "github.com/sagernet/sing/common"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. )
  10. type _IPRule struct {
  11. Type string `json:"type,omitempty"`
  12. DefaultOptions DefaultIPRule `json:"-"`
  13. LogicalOptions LogicalIPRule `json:"-"`
  14. }
  15. type IPRule _IPRule
  16. func (r IPRule) MarshalJSON() ([]byte, error) {
  17. var v any
  18. switch r.Type {
  19. case C.RuleTypeDefault:
  20. r.Type = ""
  21. v = r.DefaultOptions
  22. case C.RuleTypeLogical:
  23. v = r.LogicalOptions
  24. default:
  25. return nil, E.New("unknown rule type: " + r.Type)
  26. }
  27. return MarshallObjects((_IPRule)(r), v)
  28. }
  29. func (r *IPRule) UnmarshalJSON(bytes []byte) error {
  30. err := json.Unmarshal(bytes, (*_IPRule)(r))
  31. if err != nil {
  32. return err
  33. }
  34. var v any
  35. switch r.Type {
  36. case "", C.RuleTypeDefault:
  37. r.Type = C.RuleTypeDefault
  38. v = &r.DefaultOptions
  39. case C.RuleTypeLogical:
  40. v = &r.LogicalOptions
  41. default:
  42. return E.New("unknown rule type: " + r.Type)
  43. }
  44. err = UnmarshallExcluded(bytes, (*_IPRule)(r), v)
  45. if err != nil {
  46. return E.Cause(err, "ip route rule")
  47. }
  48. return nil
  49. }
  50. type DefaultIPRule struct {
  51. Inbound Listable[string] `json:"inbound,omitempty"`
  52. IPVersion int `json:"ip_version,omitempty"`
  53. Network Listable[string] `json:"network,omitempty"`
  54. Domain Listable[string] `json:"domain,omitempty"`
  55. DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
  56. DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
  57. DomainRegex Listable[string] `json:"domain_regex,omitempty"`
  58. Geosite Listable[string] `json:"geosite,omitempty"`
  59. SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
  60. SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
  61. SourcePort Listable[uint16] `json:"source_port,omitempty"`
  62. SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
  63. Port Listable[uint16] `json:"port,omitempty"`
  64. PortRange Listable[string] `json:"port_range,omitempty"`
  65. Invert bool `json:"invert,omitempty"`
  66. Action RouteAction `json:"action,omitempty"`
  67. Outbound string `json:"outbound,omitempty"`
  68. }
  69. type RouteAction tun.ActionType
  70. func (a RouteAction) MarshalJSON() ([]byte, error) {
  71. switch tun.ActionType(a) {
  72. case tun.ActionTypeReject, tun.ActionTypeDirect:
  73. default:
  74. return nil, E.New("unknown action: ", a)
  75. }
  76. return json.Marshal(tun.ActionTypeName(tun.ActionType(a)))
  77. }
  78. func (a *RouteAction) UnmarshalJSON(bytes []byte) error {
  79. var value string
  80. err := json.Unmarshal(bytes, &value)
  81. if err != nil {
  82. return err
  83. }
  84. actionType, err := tun.ParseActionType(value)
  85. if err != nil {
  86. return err
  87. }
  88. switch actionType {
  89. case tun.ActionTypeReject, tun.ActionTypeDirect:
  90. default:
  91. return E.New("unknown action: ", a)
  92. }
  93. *a = RouteAction(actionType)
  94. return nil
  95. }
  96. func (r DefaultIPRule) IsValid() bool {
  97. var defaultValue DefaultIPRule
  98. defaultValue.Invert = r.Invert
  99. defaultValue.Action = r.Action
  100. defaultValue.Outbound = r.Outbound
  101. return !reflect.DeepEqual(r, defaultValue)
  102. }
  103. type LogicalIPRule struct {
  104. Mode string `json:"mode"`
  105. Rules []DefaultIPRule `json:"rules,omitempty"`
  106. Invert bool `json:"invert,omitempty"`
  107. Action RouteAction `json:"action,omitempty"`
  108. Outbound string `json:"outbound,omitempty"`
  109. }
  110. func (r LogicalIPRule) IsValid() bool {
  111. return len(r.Rules) > 0 && common.All(r.Rules, DefaultIPRule.IsValid)
  112. }