rule_action.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package option
  2. import (
  3. C "github.com/sagernet/sing-box/constant"
  4. E "github.com/sagernet/sing/common/exceptions"
  5. "github.com/sagernet/sing/common/json"
  6. "github.com/sagernet/sing/common/json/badjson"
  7. )
  8. type _RuleAction struct {
  9. Action string `json:"action,omitempty"`
  10. RouteOptions RouteActionOptions `json:"-"`
  11. RejectOptions RejectActionOptions `json:"-"`
  12. SniffOptions RouteActionSniff `json:"-"`
  13. ResolveOptions RouteActionResolve `json:"-"`
  14. }
  15. type RuleAction _RuleAction
  16. func (r RuleAction) MarshalJSON() ([]byte, error) {
  17. var v any
  18. switch r.Action {
  19. case C.RuleActionTypeRoute:
  20. r.Action = ""
  21. v = r.RouteOptions
  22. case C.RuleActionTypeReturn:
  23. v = nil
  24. case C.RuleActionTypeReject:
  25. v = r.RejectOptions
  26. case C.RuleActionTypeHijackDNS:
  27. v = nil
  28. case C.RuleActionTypeSniff:
  29. v = r.SniffOptions
  30. case C.RuleActionTypeResolve:
  31. v = r.ResolveOptions
  32. default:
  33. return nil, E.New("unknown rule action: " + r.Action)
  34. }
  35. if v == nil {
  36. return badjson.MarshallObjects((_RuleAction)(r))
  37. }
  38. return badjson.MarshallObjects((_RuleAction)(r), v)
  39. }
  40. func (r *RuleAction) UnmarshalJSON(data []byte) error {
  41. err := json.Unmarshal(data, (*_RuleAction)(r))
  42. if err != nil {
  43. return err
  44. }
  45. var v any
  46. switch r.Action {
  47. case "", C.RuleActionTypeRoute:
  48. r.Action = C.RuleActionTypeRoute
  49. v = &r.RouteOptions
  50. case C.RuleActionTypeReturn:
  51. v = nil
  52. case C.RuleActionTypeReject:
  53. v = &r.RejectOptions
  54. case C.RuleActionTypeHijackDNS:
  55. v = nil
  56. case C.RuleActionTypeSniff:
  57. v = &r.SniffOptions
  58. case C.RuleActionTypeResolve:
  59. v = &r.ResolveOptions
  60. default:
  61. return E.New("unknown rule action: " + r.Action)
  62. }
  63. if v == nil {
  64. // check unknown fields
  65. return json.UnmarshalDisallowUnknownFields(data, &_RuleAction{})
  66. }
  67. return badjson.UnmarshallExcluded(data, (*_RuleAction)(r), v)
  68. }
  69. type _DNSRuleAction struct {
  70. Action string `json:"action,omitempty"`
  71. RouteOptions DNSRouteActionOptions `json:"-"`
  72. RejectOptions RejectActionOptions `json:"-"`
  73. }
  74. type DNSRuleAction _DNSRuleAction
  75. func (r DNSRuleAction) MarshalJSON() ([]byte, error) {
  76. var v any
  77. switch r.Action {
  78. case C.RuleActionTypeRoute:
  79. r.Action = ""
  80. v = r.RouteOptions
  81. case C.RuleActionTypeReturn:
  82. v = nil
  83. case C.RuleActionTypeReject:
  84. v = r.RejectOptions
  85. default:
  86. return nil, E.New("unknown DNS rule action: " + r.Action)
  87. }
  88. if v == nil {
  89. return badjson.MarshallObjects((_DNSRuleAction)(r))
  90. }
  91. return badjson.MarshallObjects((_DNSRuleAction)(r), v)
  92. }
  93. func (r *DNSRuleAction) UnmarshalJSON(data []byte) error {
  94. err := json.Unmarshal(data, (*_DNSRuleAction)(r))
  95. if err != nil {
  96. return err
  97. }
  98. var v any
  99. switch r.Action {
  100. case "", C.RuleActionTypeRoute:
  101. r.Action = C.RuleActionTypeRoute
  102. v = &r.RouteOptions
  103. case C.RuleActionTypeReturn:
  104. v = nil
  105. case C.RuleActionTypeReject:
  106. v = &r.RejectOptions
  107. default:
  108. return E.New("unknown DNS rule action: " + r.Action)
  109. }
  110. if v == nil {
  111. // check unknown fields
  112. return json.UnmarshalDisallowUnknownFields(data, &_DNSRuleAction{})
  113. }
  114. return badjson.UnmarshallExcluded(data, (*_DNSRuleAction)(r), v)
  115. }
  116. type RouteActionOptions struct {
  117. Outbound string `json:"outbound"`
  118. UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
  119. }
  120. type DNSRouteActionOptions struct {
  121. Server string `json:"server"`
  122. DisableCache bool `json:"disable_cache,omitempty"`
  123. RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
  124. ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
  125. }
  126. type _RejectActionOptions struct {
  127. Method string `json:"method,omitempty"`
  128. NoDrop bool `json:"no_drop,omitempty"`
  129. }
  130. type RejectActionOptions _RejectActionOptions
  131. func (r *RejectActionOptions) UnmarshalJSON(bytes []byte) error {
  132. err := json.Unmarshal(bytes, (*_RejectActionOptions)(r))
  133. if err != nil {
  134. return err
  135. }
  136. switch r.Method {
  137. case "", C.RuleActionRejectMethodDefault:
  138. r.Method = C.RuleActionRejectMethodDefault
  139. case C.RuleActionRejectMethodDrop:
  140. default:
  141. return E.New("unknown reject method: " + r.Method)
  142. }
  143. if r.Method == C.RuleActionRejectMethodDrop && r.NoDrop {
  144. return E.New("no_drop is not allowed when method is drop")
  145. }
  146. return nil
  147. }
  148. type RouteActionSniff struct {
  149. Sniffer Listable[string] `json:"sniffer,omitempty"`
  150. Timeout Duration `json:"timeout,omitempty"`
  151. }
  152. type RouteActionResolve struct {
  153. Strategy DomainStrategy `json:"strategy,omitempty"`
  154. Server string `json:"server,omitempty"`
  155. }