rule_default.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package rule
  2. import (
  3. "context"
  4. "github.com/sagernet/sing-box/adapter"
  5. C "github.com/sagernet/sing-box/constant"
  6. "github.com/sagernet/sing-box/experimental/deprecated"
  7. "github.com/sagernet/sing-box/log"
  8. "github.com/sagernet/sing-box/option"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. )
  11. func NewRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) {
  12. switch options.Type {
  13. case "", C.RuleTypeDefault:
  14. if !options.DefaultOptions.IsValid() {
  15. return nil, E.New("missing conditions")
  16. }
  17. switch options.DefaultOptions.Action {
  18. case "", C.RuleActionTypeRoute:
  19. if options.DefaultOptions.RouteOptions.Outbound == "" && checkOutbound {
  20. return nil, E.New("missing outbound field")
  21. }
  22. }
  23. return NewDefaultRule(ctx, router, logger, options.DefaultOptions)
  24. case C.RuleTypeLogical:
  25. if !options.LogicalOptions.IsValid() {
  26. return nil, E.New("missing conditions")
  27. }
  28. switch options.LogicalOptions.Action {
  29. case "", C.RuleActionTypeRoute:
  30. if options.LogicalOptions.RouteOptions.Outbound == "" && checkOutbound {
  31. return nil, E.New("missing outbound field")
  32. }
  33. }
  34. return NewLogicalRule(ctx, router, logger, options.LogicalOptions)
  35. default:
  36. return nil, E.New("unknown rule type: ", options.Type)
  37. }
  38. }
  39. var _ adapter.Rule = (*DefaultRule)(nil)
  40. type DefaultRule struct {
  41. abstractDefaultRule
  42. }
  43. type RuleItem interface {
  44. Match(metadata *adapter.InboundContext) bool
  45. String() string
  46. }
  47. func NewDefaultRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) {
  48. action, err := NewRuleAction(logger, options.RuleAction)
  49. if err != nil {
  50. return nil, E.Cause(err, "action")
  51. }
  52. rule := &DefaultRule{
  53. abstractDefaultRule{
  54. invert: options.Invert,
  55. action: action,
  56. },
  57. }
  58. if len(options.Inbound) > 0 {
  59. item := NewInboundRule(options.Inbound)
  60. rule.items = append(rule.items, item)
  61. rule.allItems = append(rule.allItems, item)
  62. }
  63. if options.IPVersion > 0 {
  64. switch options.IPVersion {
  65. case 4, 6:
  66. item := NewIPVersionItem(options.IPVersion == 6)
  67. rule.items = append(rule.items, item)
  68. rule.allItems = append(rule.allItems, item)
  69. default:
  70. return nil, E.New("invalid ip version: ", options.IPVersion)
  71. }
  72. }
  73. if len(options.Network) > 0 {
  74. item := NewNetworkItem(options.Network)
  75. rule.items = append(rule.items, item)
  76. rule.allItems = append(rule.allItems, item)
  77. }
  78. if len(options.AuthUser) > 0 {
  79. item := NewAuthUserItem(options.AuthUser)
  80. rule.items = append(rule.items, item)
  81. rule.allItems = append(rule.allItems, item)
  82. }
  83. if len(options.Protocol) > 0 {
  84. item := NewProtocolItem(options.Protocol)
  85. rule.items = append(rule.items, item)
  86. rule.allItems = append(rule.allItems, item)
  87. }
  88. if len(options.Client) > 0 {
  89. item := NewClientItem(options.Client)
  90. rule.items = append(rule.items, item)
  91. rule.allItems = append(rule.allItems, item)
  92. }
  93. if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 {
  94. item := NewDomainItem(options.Domain, options.DomainSuffix)
  95. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  96. rule.allItems = append(rule.allItems, item)
  97. }
  98. if len(options.DomainKeyword) > 0 {
  99. item := NewDomainKeywordItem(options.DomainKeyword)
  100. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  101. rule.allItems = append(rule.allItems, item)
  102. }
  103. if len(options.DomainRegex) > 0 {
  104. item, err := NewDomainRegexItem(options.DomainRegex)
  105. if err != nil {
  106. return nil, E.Cause(err, "domain_regex")
  107. }
  108. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  109. rule.allItems = append(rule.allItems, item)
  110. }
  111. if len(options.Geosite) > 0 {
  112. item := NewGeositeItem(router, logger, options.Geosite)
  113. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  114. rule.allItems = append(rule.allItems, item)
  115. }
  116. if len(options.SourceGeoIP) > 0 {
  117. item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
  118. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  119. rule.allItems = append(rule.allItems, item)
  120. }
  121. if len(options.GeoIP) > 0 {
  122. item := NewGeoIPItem(router, logger, false, options.GeoIP)
  123. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  124. rule.allItems = append(rule.allItems, item)
  125. }
  126. if len(options.SourceIPCIDR) > 0 {
  127. item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
  128. if err != nil {
  129. return nil, E.Cause(err, "source_ip_cidr")
  130. }
  131. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  132. rule.allItems = append(rule.allItems, item)
  133. }
  134. if options.SourceIPIsPrivate {
  135. item := NewIPIsPrivateItem(true)
  136. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  137. rule.allItems = append(rule.allItems, item)
  138. }
  139. if len(options.IPCIDR) > 0 {
  140. item, err := NewIPCIDRItem(false, options.IPCIDR)
  141. if err != nil {
  142. return nil, E.Cause(err, "ipcidr")
  143. }
  144. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  145. rule.allItems = append(rule.allItems, item)
  146. }
  147. if options.IPIsPrivate {
  148. item := NewIPIsPrivateItem(false)
  149. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  150. rule.allItems = append(rule.allItems, item)
  151. }
  152. if len(options.SourcePort) > 0 {
  153. item := NewPortItem(true, options.SourcePort)
  154. rule.sourcePortItems = append(rule.sourcePortItems, item)
  155. rule.allItems = append(rule.allItems, item)
  156. }
  157. if len(options.SourcePortRange) > 0 {
  158. item, err := NewPortRangeItem(true, options.SourcePortRange)
  159. if err != nil {
  160. return nil, E.Cause(err, "source_port_range")
  161. }
  162. rule.sourcePortItems = append(rule.sourcePortItems, item)
  163. rule.allItems = append(rule.allItems, item)
  164. }
  165. if len(options.Port) > 0 {
  166. item := NewPortItem(false, options.Port)
  167. rule.destinationPortItems = append(rule.destinationPortItems, item)
  168. rule.allItems = append(rule.allItems, item)
  169. }
  170. if len(options.PortRange) > 0 {
  171. item, err := NewPortRangeItem(false, options.PortRange)
  172. if err != nil {
  173. return nil, E.Cause(err, "port_range")
  174. }
  175. rule.destinationPortItems = append(rule.destinationPortItems, item)
  176. rule.allItems = append(rule.allItems, item)
  177. }
  178. if len(options.ProcessName) > 0 {
  179. item := NewProcessItem(options.ProcessName)
  180. rule.items = append(rule.items, item)
  181. rule.allItems = append(rule.allItems, item)
  182. }
  183. if len(options.ProcessPath) > 0 {
  184. item := NewProcessPathItem(options.ProcessPath)
  185. rule.items = append(rule.items, item)
  186. rule.allItems = append(rule.allItems, item)
  187. }
  188. if len(options.ProcessPathRegex) > 0 {
  189. item, err := NewProcessPathRegexItem(options.ProcessPathRegex)
  190. if err != nil {
  191. return nil, E.Cause(err, "process_path_regex")
  192. }
  193. rule.items = append(rule.items, item)
  194. rule.allItems = append(rule.allItems, item)
  195. }
  196. if len(options.PackageName) > 0 {
  197. item := NewPackageNameItem(options.PackageName)
  198. rule.items = append(rule.items, item)
  199. rule.allItems = append(rule.allItems, item)
  200. }
  201. if len(options.User) > 0 {
  202. item := NewUserItem(options.User)
  203. rule.items = append(rule.items, item)
  204. rule.allItems = append(rule.allItems, item)
  205. }
  206. if len(options.UserID) > 0 {
  207. item := NewUserIDItem(options.UserID)
  208. rule.items = append(rule.items, item)
  209. rule.allItems = append(rule.allItems, item)
  210. }
  211. if options.ClashMode != "" {
  212. item := NewClashModeItem(router, options.ClashMode)
  213. rule.items = append(rule.items, item)
  214. rule.allItems = append(rule.allItems, item)
  215. }
  216. if len(options.WIFISSID) > 0 {
  217. item := NewWIFISSIDItem(router, options.WIFISSID)
  218. rule.items = append(rule.items, item)
  219. rule.allItems = append(rule.allItems, item)
  220. }
  221. if len(options.WIFIBSSID) > 0 {
  222. item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
  223. rule.items = append(rule.items, item)
  224. rule.allItems = append(rule.allItems, item)
  225. }
  226. if len(options.RuleSet) > 0 {
  227. var matchSource bool
  228. if options.RuleSetIPCIDRMatchSource {
  229. matchSource = true
  230. } else
  231. //nolint:staticcheck
  232. if options.Deprecated_RulesetIPCIDRMatchSource {
  233. matchSource = true
  234. deprecated.Report(ctx, deprecated.OptionBadMatchSource)
  235. }
  236. item := NewRuleSetItem(router, options.RuleSet, matchSource, false)
  237. rule.items = append(rule.items, item)
  238. rule.allItems = append(rule.allItems, item)
  239. }
  240. return rule, nil
  241. }
  242. var _ adapter.Rule = (*LogicalRule)(nil)
  243. type LogicalRule struct {
  244. abstractLogicalRule
  245. }
  246. func NewLogicalRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) {
  247. action, err := NewRuleAction(logger, options.RuleAction)
  248. if err != nil {
  249. return nil, E.Cause(err, "action")
  250. }
  251. rule := &LogicalRule{
  252. abstractLogicalRule{
  253. rules: make([]adapter.HeadlessRule, len(options.Rules)),
  254. invert: options.Invert,
  255. action: action,
  256. },
  257. }
  258. switch options.Mode {
  259. case C.LogicalTypeAnd:
  260. rule.mode = C.LogicalTypeAnd
  261. case C.LogicalTypeOr:
  262. rule.mode = C.LogicalTypeOr
  263. default:
  264. return nil, E.New("unknown logical mode: ", options.Mode)
  265. }
  266. for i, subOptions := range options.Rules {
  267. subRule, err := NewRule(ctx, router, logger, subOptions, false)
  268. if err != nil {
  269. return nil, E.Cause(err, "sub rule[", i, "]")
  270. }
  271. rule.rules[i] = subRule
  272. }
  273. return rule, nil
  274. }