rule_dns.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package route
  2. import (
  3. "net/netip"
  4. "github.com/sagernet/sing-box/adapter"
  5. C "github.com/sagernet/sing-box/constant"
  6. "github.com/sagernet/sing-box/log"
  7. "github.com/sagernet/sing-box/option"
  8. "github.com/sagernet/sing/common"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. )
  11. func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
  12. switch options.Type {
  13. case "", C.RuleTypeDefault:
  14. if !options.DefaultOptions.IsValid() {
  15. return nil, E.New("missing conditions")
  16. }
  17. if options.DefaultOptions.Server == "" && checkServer {
  18. return nil, E.New("missing server field")
  19. }
  20. return NewDefaultDNSRule(router, logger, options.DefaultOptions)
  21. case C.RuleTypeLogical:
  22. if !options.LogicalOptions.IsValid() {
  23. return nil, E.New("missing conditions")
  24. }
  25. if options.LogicalOptions.Server == "" && checkServer {
  26. return nil, E.New("missing server field")
  27. }
  28. return NewLogicalDNSRule(router, logger, options.LogicalOptions)
  29. default:
  30. return nil, E.New("unknown rule type: ", options.Type)
  31. }
  32. }
  33. var _ adapter.DNSRule = (*DefaultDNSRule)(nil)
  34. type DefaultDNSRule struct {
  35. abstractDefaultRule
  36. disableCache bool
  37. rewriteTTL *uint32
  38. clientSubnet *netip.Prefix
  39. }
  40. func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
  41. rule := &DefaultDNSRule{
  42. abstractDefaultRule: abstractDefaultRule{
  43. invert: options.Invert,
  44. outbound: options.Server,
  45. },
  46. disableCache: options.DisableCache,
  47. rewriteTTL: options.RewriteTTL,
  48. clientSubnet: (*netip.Prefix)(options.ClientSubnet),
  49. }
  50. if len(options.Inbound) > 0 {
  51. item := NewInboundRule(options.Inbound)
  52. rule.items = append(rule.items, item)
  53. rule.allItems = append(rule.allItems, item)
  54. }
  55. if options.IPVersion > 0 {
  56. switch options.IPVersion {
  57. case 4, 6:
  58. item := NewIPVersionItem(options.IPVersion == 6)
  59. rule.items = append(rule.items, item)
  60. rule.allItems = append(rule.allItems, item)
  61. default:
  62. return nil, E.New("invalid ip version: ", options.IPVersion)
  63. }
  64. }
  65. if len(options.QueryType) > 0 {
  66. item := NewQueryTypeItem(options.QueryType)
  67. rule.items = append(rule.items, item)
  68. rule.allItems = append(rule.allItems, item)
  69. }
  70. if len(options.Network) > 0 {
  71. item := NewNetworkItem(options.Network)
  72. rule.items = append(rule.items, item)
  73. rule.allItems = append(rule.allItems, item)
  74. }
  75. if len(options.AuthUser) > 0 {
  76. item := NewAuthUserItem(options.AuthUser)
  77. rule.items = append(rule.items, item)
  78. rule.allItems = append(rule.allItems, item)
  79. }
  80. if len(options.Protocol) > 0 {
  81. item := NewProtocolItem(options.Protocol)
  82. rule.items = append(rule.items, item)
  83. rule.allItems = append(rule.allItems, item)
  84. }
  85. if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 {
  86. item := NewDomainItem(options.Domain, options.DomainSuffix)
  87. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  88. rule.allItems = append(rule.allItems, item)
  89. }
  90. if len(options.DomainKeyword) > 0 {
  91. item := NewDomainKeywordItem(options.DomainKeyword)
  92. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  93. rule.allItems = append(rule.allItems, item)
  94. }
  95. if len(options.DomainRegex) > 0 {
  96. item, err := NewDomainRegexItem(options.DomainRegex)
  97. if err != nil {
  98. return nil, E.Cause(err, "domain_regex")
  99. }
  100. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  101. rule.allItems = append(rule.allItems, item)
  102. }
  103. if len(options.Geosite) > 0 {
  104. item := NewGeositeItem(router, logger, options.Geosite)
  105. rule.destinationAddressItems = append(rule.destinationAddressItems, item)
  106. rule.allItems = append(rule.allItems, item)
  107. }
  108. if len(options.SourceGeoIP) > 0 {
  109. item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
  110. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  111. rule.allItems = append(rule.allItems, item)
  112. }
  113. if len(options.GeoIP) > 0 {
  114. item := NewGeoIPItem(router, logger, false, options.GeoIP)
  115. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  116. rule.allItems = append(rule.allItems, item)
  117. }
  118. if len(options.SourceIPCIDR) > 0 {
  119. item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
  120. if err != nil {
  121. return nil, E.Cause(err, "source_ip_cidr")
  122. }
  123. rule.sourceAddressItems = append(rule.sourceAddressItems, item)
  124. rule.allItems = append(rule.allItems, item)
  125. }
  126. if len(options.IPCIDR) > 0 {
  127. item, err := NewIPCIDRItem(false, options.IPCIDR)
  128. if err != nil {
  129. return nil, E.Cause(err, "ip_cidr")
  130. }
  131. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, 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 options.IPIsPrivate {
  140. item := NewIPIsPrivateItem(false)
  141. rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
  142. rule.allItems = append(rule.allItems, item)
  143. }
  144. if len(options.SourcePort) > 0 {
  145. item := NewPortItem(true, options.SourcePort)
  146. rule.sourcePortItems = append(rule.sourcePortItems, item)
  147. rule.allItems = append(rule.allItems, item)
  148. }
  149. if len(options.SourcePortRange) > 0 {
  150. item, err := NewPortRangeItem(true, options.SourcePortRange)
  151. if err != nil {
  152. return nil, E.Cause(err, "source_port_range")
  153. }
  154. rule.sourcePortItems = append(rule.sourcePortItems, item)
  155. rule.allItems = append(rule.allItems, item)
  156. }
  157. if len(options.Port) > 0 {
  158. item := NewPortItem(false, options.Port)
  159. rule.destinationPortItems = append(rule.destinationPortItems, item)
  160. rule.allItems = append(rule.allItems, item)
  161. }
  162. if len(options.PortRange) > 0 {
  163. item, err := NewPortRangeItem(false, options.PortRange)
  164. if err != nil {
  165. return nil, E.Cause(err, "port_range")
  166. }
  167. rule.destinationPortItems = append(rule.destinationPortItems, item)
  168. rule.allItems = append(rule.allItems, item)
  169. }
  170. if len(options.ProcessName) > 0 {
  171. item := NewProcessItem(options.ProcessName)
  172. rule.items = append(rule.items, item)
  173. rule.allItems = append(rule.allItems, item)
  174. }
  175. if len(options.ProcessPath) > 0 {
  176. item := NewProcessPathItem(options.ProcessPath)
  177. rule.items = append(rule.items, item)
  178. rule.allItems = append(rule.allItems, item)
  179. }
  180. if len(options.PackageName) > 0 {
  181. item := NewPackageNameItem(options.PackageName)
  182. rule.items = append(rule.items, item)
  183. rule.allItems = append(rule.allItems, item)
  184. }
  185. if len(options.User) > 0 {
  186. item := NewUserItem(options.User)
  187. rule.items = append(rule.items, item)
  188. rule.allItems = append(rule.allItems, item)
  189. }
  190. if len(options.UserID) > 0 {
  191. item := NewUserIDItem(options.UserID)
  192. rule.items = append(rule.items, item)
  193. rule.allItems = append(rule.allItems, item)
  194. }
  195. if len(options.Outbound) > 0 {
  196. item := NewOutboundRule(options.Outbound)
  197. rule.items = append(rule.items, item)
  198. rule.allItems = append(rule.allItems, item)
  199. }
  200. if options.ClashMode != "" {
  201. item := NewClashModeItem(router, options.ClashMode)
  202. rule.items = append(rule.items, item)
  203. rule.allItems = append(rule.allItems, item)
  204. }
  205. if len(options.WIFISSID) > 0 {
  206. item := NewWIFISSIDItem(router, options.WIFISSID)
  207. rule.items = append(rule.items, item)
  208. rule.allItems = append(rule.allItems, item)
  209. }
  210. if len(options.WIFIBSSID) > 0 {
  211. item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
  212. rule.items = append(rule.items, item)
  213. rule.allItems = append(rule.allItems, item)
  214. }
  215. if len(options.RuleSet) > 0 {
  216. item := NewRuleSetItem(router, options.RuleSet, options.RuleSetIPCIDRMatchSource)
  217. rule.items = append(rule.items, item)
  218. rule.allItems = append(rule.allItems, item)
  219. }
  220. return rule, nil
  221. }
  222. func (r *DefaultDNSRule) DisableCache() bool {
  223. return r.disableCache
  224. }
  225. func (r *DefaultDNSRule) RewriteTTL() *uint32 {
  226. return r.rewriteTTL
  227. }
  228. func (r *DefaultDNSRule) ClientSubnet() *netip.Prefix {
  229. return r.clientSubnet
  230. }
  231. func (r *DefaultDNSRule) WithAddressLimit() bool {
  232. if len(r.destinationIPCIDRItems) > 0 {
  233. return true
  234. }
  235. for _, rawRule := range r.items {
  236. ruleSet, isRuleSet := rawRule.(*RuleSetItem)
  237. if !isRuleSet {
  238. continue
  239. }
  240. if ruleSet.ContainsDestinationIPCIDRRule() {
  241. return true
  242. }
  243. }
  244. return false
  245. }
  246. func (r *DefaultDNSRule) Match(metadata *adapter.InboundContext) bool {
  247. metadata.IgnoreDestinationIPCIDRMatch = true
  248. defer func() {
  249. metadata.IgnoreDestinationIPCIDRMatch = false
  250. }()
  251. return r.abstractDefaultRule.Match(metadata)
  252. }
  253. func (r *DefaultDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
  254. return r.abstractDefaultRule.Match(metadata)
  255. }
  256. var _ adapter.DNSRule = (*LogicalDNSRule)(nil)
  257. type LogicalDNSRule struct {
  258. abstractLogicalRule
  259. disableCache bool
  260. rewriteTTL *uint32
  261. clientSubnet *netip.Prefix
  262. }
  263. func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
  264. r := &LogicalDNSRule{
  265. abstractLogicalRule: abstractLogicalRule{
  266. rules: make([]adapter.HeadlessRule, len(options.Rules)),
  267. invert: options.Invert,
  268. outbound: options.Server,
  269. },
  270. disableCache: options.DisableCache,
  271. rewriteTTL: options.RewriteTTL,
  272. clientSubnet: (*netip.Prefix)(options.ClientSubnet),
  273. }
  274. switch options.Mode {
  275. case C.LogicalTypeAnd:
  276. r.mode = C.LogicalTypeAnd
  277. case C.LogicalTypeOr:
  278. r.mode = C.LogicalTypeOr
  279. default:
  280. return nil, E.New("unknown logical mode: ", options.Mode)
  281. }
  282. for i, subRule := range options.Rules {
  283. rule, err := NewDNSRule(router, logger, subRule, false)
  284. if err != nil {
  285. return nil, E.Cause(err, "sub rule[", i, "]")
  286. }
  287. r.rules[i] = rule
  288. }
  289. return r, nil
  290. }
  291. func (r *LogicalDNSRule) DisableCache() bool {
  292. return r.disableCache
  293. }
  294. func (r *LogicalDNSRule) RewriteTTL() *uint32 {
  295. return r.rewriteTTL
  296. }
  297. func (r *LogicalDNSRule) ClientSubnet() *netip.Prefix {
  298. return r.clientSubnet
  299. }
  300. func (r *LogicalDNSRule) WithAddressLimit() bool {
  301. for _, rawRule := range r.rules {
  302. switch rule := rawRule.(type) {
  303. case *DefaultDNSRule:
  304. if rule.WithAddressLimit() {
  305. return true
  306. }
  307. case *LogicalDNSRule:
  308. if rule.WithAddressLimit() {
  309. return true
  310. }
  311. }
  312. }
  313. return false
  314. }
  315. func (r *LogicalDNSRule) Match(metadata *adapter.InboundContext) bool {
  316. if r.mode == C.LogicalTypeAnd {
  317. return common.All(r.rules, func(it adapter.HeadlessRule) bool {
  318. metadata.ResetRuleCache()
  319. return it.(adapter.DNSRule).Match(metadata)
  320. }) != r.invert
  321. } else {
  322. return common.Any(r.rules, func(it adapter.HeadlessRule) bool {
  323. metadata.ResetRuleCache()
  324. return it.(adapter.DNSRule).Match(metadata)
  325. }) != r.invert
  326. }
  327. }
  328. func (r *LogicalDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
  329. if r.mode == C.LogicalTypeAnd {
  330. return common.All(r.rules, func(it adapter.HeadlessRule) bool {
  331. metadata.ResetRuleCache()
  332. return it.(adapter.DNSRule).MatchAddressLimit(metadata)
  333. }) != r.invert
  334. } else {
  335. return common.Any(r.rules, func(it adapter.HeadlessRule) bool {
  336. metadata.ResetRuleCache()
  337. return it.(adapter.DNSRule).MatchAddressLimit(metadata)
  338. }) != r.invert
  339. }
  340. }