route.go 4.3 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. "github.com/sagernet/sing/common"
  7. E "github.com/sagernet/sing/common/exceptions"
  8. )
  9. type RouteOptions struct {
  10. GeoIP *GeoIPOptions `json:"geoip,omitempty"`
  11. Geosite *GeositeOptions `json:"geosite,omitempty"`
  12. Rules []Rule `json:"rules,omitempty"`
  13. Final string `json:"final,omitempty"`
  14. FindProcess bool `json:"find_process,omitempty"`
  15. AutoDetectInterface bool `json:"auto_detect_interface,omitempty"`
  16. OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
  17. DefaultInterface string `json:"default_interface,omitempty"`
  18. DefaultMark int `json:"default_mark,omitempty"`
  19. }
  20. type GeoIPOptions struct {
  21. Path string `json:"path,omitempty"`
  22. DownloadURL string `json:"download_url,omitempty"`
  23. DownloadDetour string `json:"download_detour,omitempty"`
  24. }
  25. type GeositeOptions struct {
  26. Path string `json:"path,omitempty"`
  27. DownloadURL string `json:"download_url,omitempty"`
  28. DownloadDetour string `json:"download_detour,omitempty"`
  29. }
  30. type _Rule struct {
  31. Type string `json:"type,omitempty"`
  32. DefaultOptions DefaultRule `json:"-"`
  33. LogicalOptions LogicalRule `json:"-"`
  34. }
  35. type Rule _Rule
  36. func (r Rule) MarshalJSON() ([]byte, error) {
  37. var v any
  38. switch r.Type {
  39. case C.RuleTypeDefault:
  40. r.Type = ""
  41. v = r.DefaultOptions
  42. case C.RuleTypeLogical:
  43. v = r.LogicalOptions
  44. default:
  45. return nil, E.New("unknown rule type: " + r.Type)
  46. }
  47. return MarshallObjects((_Rule)(r), v)
  48. }
  49. func (r *Rule) UnmarshalJSON(bytes []byte) error {
  50. err := json.Unmarshal(bytes, (*_Rule)(r))
  51. if err != nil {
  52. return err
  53. }
  54. var v any
  55. switch r.Type {
  56. case "", C.RuleTypeDefault:
  57. r.Type = C.RuleTypeDefault
  58. v = &r.DefaultOptions
  59. case C.RuleTypeLogical:
  60. v = &r.LogicalOptions
  61. default:
  62. return E.New("unknown rule type: " + r.Type)
  63. }
  64. err = UnmarshallExcluded(bytes, (*_Rule)(r), v)
  65. if err != nil {
  66. return E.Cause(err, "route rule")
  67. }
  68. return nil
  69. }
  70. type DefaultRule struct {
  71. Inbound Listable[string] `json:"inbound,omitempty"`
  72. IPVersion int `json:"ip_version,omitempty"`
  73. Network string `json:"network,omitempty"`
  74. AuthUser Listable[string] `json:"auth_user,omitempty"`
  75. Protocol Listable[string] `json:"protocol,omitempty"`
  76. Domain Listable[string] `json:"domain,omitempty"`
  77. DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
  78. DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
  79. DomainRegex Listable[string] `json:"domain_regex,omitempty"`
  80. Geosite Listable[string] `json:"geosite,omitempty"`
  81. SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
  82. GeoIP Listable[string] `json:"geoip,omitempty"`
  83. SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
  84. IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
  85. SourcePort Listable[uint16] `json:"source_port,omitempty"`
  86. SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
  87. Port Listable[uint16] `json:"port,omitempty"`
  88. PortRange Listable[string] `json:"port_range,omitempty"`
  89. ProcessName Listable[string] `json:"process_name,omitempty"`
  90. ProcessPath Listable[string] `json:"process_path,omitempty"`
  91. PackageName Listable[string] `json:"package_name,omitempty"`
  92. User Listable[string] `json:"user,omitempty"`
  93. UserID Listable[int32] `json:"user_id,omitempty"`
  94. ClashMode string `json:"clash_mode,omitempty"`
  95. Invert bool `json:"invert,omitempty"`
  96. Outbound string `json:"outbound,omitempty"`
  97. }
  98. func (r DefaultRule) IsValid() bool {
  99. var defaultValue DefaultRule
  100. defaultValue.Invert = r.Invert
  101. defaultValue.Outbound = r.Outbound
  102. return !reflect.DeepEqual(r, defaultValue)
  103. }
  104. type LogicalRule struct {
  105. Mode string `json:"mode"`
  106. Rules []DefaultRule `json:"rules,omitempty"`
  107. Invert bool `json:"invert,omitempty"`
  108. Outbound string `json:"outbound,omitempty"`
  109. }
  110. func (r LogicalRule) IsValid() bool {
  111. return len(r.Rules) > 0 && common.All(r.Rules, DefaultRule.IsValid)
  112. }