rule_headless.go 7.6 KB

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