rule_headless.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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/option"
  7. E "github.com/sagernet/sing/common/exceptions"
  8. "github.com/sagernet/sing/service"
  9. )
  10. func NewHeadlessRule(ctx context.Context, options option.HeadlessRule) (adapter.HeadlessRule, error) {
  11. switch options.Type {
  12. case "", C.RuleTypeDefault:
  13. if !options.DefaultOptions.IsValid() {
  14. return nil, E.New("missing conditions")
  15. }
  16. return NewDefaultHeadlessRule(ctx, options.DefaultOptions)
  17. case C.RuleTypeLogical:
  18. if !options.LogicalOptions.IsValid() {
  19. return nil, E.New("missing conditions")
  20. }
  21. return NewLogicalHeadlessRule(ctx, options.LogicalOptions)
  22. default:
  23. return nil, E.New("unknown rule type: ", options.Type)
  24. }
  25. }
  26. var _ adapter.HeadlessRule = (*DefaultHeadlessRule)(nil)
  27. type DefaultHeadlessRule struct {
  28. abstractDefaultRule
  29. }
  30. func NewDefaultHeadlessRule(ctx context.Context, options option.DefaultHeadlessRule) (*DefaultHeadlessRule, error) {
  31. networkManager := service.FromContext[adapter.NetworkManager](ctx)
  32. rule := &DefaultHeadlessRule{
  33. abstractDefaultRule{
  34. invert: options.Invert,
  35. },
  36. }
  37. if len(options.Network) > 0 {
  38. item := NewNetworkItem(options.Network)
  39. rule.items = append(rule.items, item)
  40. rule.allItems = append(rule.allItems, item)
  41. }
  42. if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 {
  43. item := NewDomainItem(options.Domain, options.DomainSuffix)
  44. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  45. rule.allItems = append(rule.allItems, item)
  46. } else if options.DomainMatcher != nil {
  47. item := NewRawDomainItem(options.DomainMatcher)
  48. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  49. rule.allItems = append(rule.allItems, item)
  50. }
  51. if len(options.DomainKeyword) > 0 {
  52. item := NewDomainKeywordItem(options.DomainKeyword)
  53. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  54. rule.allItems = append(rule.allItems, item)
  55. }
  56. if len(options.DomainRegex) > 0 {
  57. item, err := NewDomainRegexItem(options.DomainRegex)
  58. if err != nil {
  59. return nil, E.Cause(err, "domain_regex")
  60. }
  61. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  62. rule.allItems = append(rule.allItems, item)
  63. }
  64. if len(options.SourceIPCIDR) > 0 {
  65. item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
  66. if err != nil {
  67. return nil, E.Cause(err, "source_ip_cidr")
  68. }
  69. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  70. rule.allItems = append(rule.allItems, item)
  71. } else if options.SourceIPSet != nil {
  72. item := NewRawIPCIDRItem(true, options.SourceIPSet)
  73. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  74. rule.allItems = append(rule.allItems, item)
  75. }
  76. if len(options.IPCIDR) > 0 {
  77. item, err := NewIPCIDRItem(false, options.IPCIDR)
  78. if err != nil {
  79. return nil, E.Cause(err, "ipcidr")
  80. }
  81. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  82. rule.allItems = append(rule.allItems, item)
  83. } else if options.IPSet != nil {
  84. item := NewRawIPCIDRItem(false, options.IPSet)
  85. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  86. rule.allItems = append(rule.allItems, item)
  87. }
  88. if len(options.SourcePort) > 0 {
  89. item := NewPortItem(true, options.SourcePort)
  90. rule.sourcePortItems = append(rule.sourcePortItems, item)
  91. rule.allItems = append(rule.allItems, item)
  92. }
  93. if len(options.SourcePortRange) > 0 {
  94. item, err := NewPortRangeItem(true, options.SourcePortRange)
  95. if err != nil {
  96. return nil, E.Cause(err, "source_port_range")
  97. }
  98. rule.sourcePortItems = append(rule.sourcePortItems, item)
  99. rule.allItems = append(rule.allItems, item)
  100. }
  101. if len(options.Port) > 0 {
  102. item := NewPortItem(false, options.Port)
  103. rule.destinationPortItems = append(rule.destinationPortItems, item)
  104. rule.allItems = append(rule.allItems, item)
  105. }
  106. if len(options.PortRange) > 0 {
  107. item, err := NewPortRangeItem(false, options.PortRange)
  108. if err != nil {
  109. return nil, E.Cause(err, "port_range")
  110. }
  111. rule.destinationPortItems = append(rule.destinationPortItems, item)
  112. rule.allItems = append(rule.allItems, item)
  113. }
  114. if len(options.ProcessName) > 0 {
  115. item := NewProcessItem(options.ProcessName)
  116. rule.items = append(rule.items, item)
  117. rule.allItems = append(rule.allItems, item)
  118. }
  119. if len(options.ProcessPath) > 0 {
  120. item := NewProcessPathItem(options.ProcessPath)
  121. rule.items = append(rule.items, item)
  122. rule.allItems = append(rule.allItems, item)
  123. }
  124. if len(options.ProcessPathRegex) > 0 {
  125. item, err := NewProcessPathRegexItem(options.ProcessPathRegex)
  126. if err != nil {
  127. return nil, E.Cause(err, "process_path_regex")
  128. }
  129. rule.items = append(rule.items, item)
  130. rule.allItems = append(rule.allItems, item)
  131. }
  132. if len(options.PackageName) > 0 {
  133. item := NewPackageNameItem(options.PackageName)
  134. rule.items = append(rule.items, item)
  135. rule.allItems = append(rule.allItems, item)
  136. }
  137. if networkManager != nil {
  138. if len(options.NetworkType) > 0 {
  139. item := NewNetworkTypeItem(networkManager, options.NetworkType)
  140. rule.items = append(rule.items, item)
  141. rule.allItems = append(rule.allItems, item)
  142. }
  143. if options.NetworkIsExpensive {
  144. item := NewNetworkIsExpensiveItem(networkManager)
  145. rule.items = append(rule.items, item)
  146. rule.allItems = append(rule.allItems, item)
  147. }
  148. if options.NetworkIsConstrained {
  149. item := NewNetworkIsConstrainedItem(networkManager)
  150. rule.items = append(rule.items, item)
  151. rule.allItems = append(rule.allItems, item)
  152. }
  153. if len(options.WIFISSID) > 0 {
  154. item := NewWIFISSIDItem(networkManager, options.WIFISSID)
  155. rule.items = append(rule.items, item)
  156. rule.allItems = append(rule.allItems, item)
  157. }
  158. if len(options.WIFIBSSID) > 0 {
  159. item := NewWIFIBSSIDItem(networkManager, options.WIFIBSSID)
  160. rule.items = append(rule.items, item)
  161. rule.allItems = append(rule.allItems, item)
  162. }
  163. }
  164. if len(options.AdGuardDomain) > 0 {
  165. item := NewAdGuardDomainItem(options.AdGuardDomain)
  166. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  167. rule.allItems = append(rule.allItems, item)
  168. } else if options.AdGuardDomainMatcher != nil {
  169. item := NewRawAdGuardDomainItem(options.AdGuardDomainMatcher)
  170. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  171. rule.allItems = append(rule.allItems, item)
  172. }
  173. return rule, nil
  174. }
  175. var _ adapter.HeadlessRule = (*LogicalHeadlessRule)(nil)
  176. type LogicalHeadlessRule struct {
  177. abstractLogicalRule
  178. }
  179. func NewLogicalHeadlessRule(ctx context.Context, options option.LogicalHeadlessRule) (*LogicalHeadlessRule, error) {
  180. r := &LogicalHeadlessRule{
  181. abstractLogicalRule{
  182. rules: make([]adapter.HeadlessRule, len(options.Rules)),
  183. invert: options.Invert,
  184. },
  185. }
  186. switch options.Mode {
  187. case C.LogicalTypeAnd:
  188. r.mode = C.LogicalTypeAnd
  189. case C.LogicalTypeOr:
  190. r.mode = C.LogicalTypeOr
  191. default:
  192. return nil, E.New("unknown logical mode: ", options.Mode)
  193. }
  194. for i, subRule := range options.Rules {
  195. rule, err := NewHeadlessRule(ctx, subRule)
  196. if err != nil {
  197. return nil, E.Cause(err, "sub rule[", i, "]")
  198. }
  199. r.rules[i] = rule
  200. }
  201. return r, nil
  202. }