github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/route/rule_dns.go (about) 1 package route 2 3 import ( 4 "github.com/inazumav/sing-box/adapter" 5 C "github.com/inazumav/sing-box/constant" 6 "github.com/inazumav/sing-box/log" 7 "github.com/inazumav/sing-box/option" 8 E "github.com/sagernet/sing/common/exceptions" 9 ) 10 11 func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule) (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 == "" { 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 == "" { 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 34 var _ adapter.DNSRule = (*DefaultDNSRule)(nil) 35 36 type DefaultDNSRule struct { 37 abstractDefaultRule 38 disableCache bool 39 rewriteTTL *uint32 40 } 41 42 func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) { 43 rule := &DefaultDNSRule{ 44 abstractDefaultRule: abstractDefaultRule{ 45 invert: options.Invert, 46 outbound: options.Server, 47 }, 48 disableCache: options.DisableCache, 49 rewriteTTL: options.RewriteTTL, 50 } 51 if len(options.Inbound) > 0 { 52 item := NewInboundRule(options.Inbound) 53 rule.items = append(rule.items, item) 54 rule.allItems = append(rule.allItems, item) 55 } 56 if options.IPVersion > 0 { 57 switch options.IPVersion { 58 case 4, 6: 59 item := NewIPVersionItem(options.IPVersion == 6) 60 rule.items = append(rule.items, item) 61 rule.allItems = append(rule.allItems, item) 62 default: 63 return nil, E.New("invalid ip version: ", options.IPVersion) 64 } 65 } 66 if len(options.QueryType) > 0 { 67 item := NewQueryTypeItem(options.QueryType) 68 rule.items = append(rule.items, item) 69 rule.allItems = append(rule.allItems, item) 70 } 71 if len(options.Network) > 0 { 72 item := NewNetworkItem(options.Network) 73 rule.items = append(rule.items, item) 74 rule.allItems = append(rule.allItems, item) 75 } 76 if len(options.AuthUser) > 0 { 77 item := NewAuthUserItem(options.AuthUser) 78 rule.items = append(rule.items, item) 79 rule.allItems = append(rule.allItems, item) 80 } 81 if len(options.Protocol) > 0 { 82 item := NewProtocolItem(options.Protocol) 83 rule.items = append(rule.items, item) 84 rule.allItems = append(rule.allItems, item) 85 } 86 if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 { 87 item := NewDomainItem(options.Domain, options.DomainSuffix) 88 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 89 rule.allItems = append(rule.allItems, item) 90 } 91 if len(options.DomainKeyword) > 0 { 92 item := NewDomainKeywordItem(options.DomainKeyword) 93 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 94 rule.allItems = append(rule.allItems, item) 95 } 96 if len(options.DomainRegex) > 0 { 97 item, err := NewDomainRegexItem(options.DomainRegex) 98 if err != nil { 99 return nil, E.Cause(err, "domain_regex") 100 } 101 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 102 rule.allItems = append(rule.allItems, item) 103 } 104 if len(options.Geosite) > 0 { 105 item := NewGeositeItem(router, logger, options.Geosite) 106 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 107 rule.allItems = append(rule.allItems, item) 108 } 109 if len(options.SourceGeoIP) > 0 { 110 item := NewGeoIPItem(router, logger, true, options.SourceGeoIP) 111 rule.sourceAddressItems = append(rule.sourceAddressItems, item) 112 rule.allItems = append(rule.allItems, item) 113 } 114 if len(options.SourceIPCIDR) > 0 { 115 item, err := NewIPCIDRItem(true, options.SourceIPCIDR) 116 if err != nil { 117 return nil, E.Cause(err, "source_ipcidr") 118 } 119 rule.sourceAddressItems = append(rule.sourceAddressItems, item) 120 rule.allItems = append(rule.allItems, item) 121 } 122 if len(options.SourcePort) > 0 { 123 item := NewPortItem(true, options.SourcePort) 124 rule.sourcePortItems = append(rule.sourcePortItems, item) 125 rule.allItems = append(rule.allItems, item) 126 } 127 if len(options.SourcePortRange) > 0 { 128 item, err := NewPortRangeItem(true, options.SourcePortRange) 129 if err != nil { 130 return nil, E.Cause(err, "source_port_range") 131 } 132 rule.sourcePortItems = append(rule.sourcePortItems, item) 133 rule.allItems = append(rule.allItems, item) 134 } 135 if len(options.Port) > 0 { 136 item := NewPortItem(false, options.Port) 137 rule.destinationPortItems = append(rule.destinationPortItems, item) 138 rule.allItems = append(rule.allItems, item) 139 } 140 if len(options.PortRange) > 0 { 141 item, err := NewPortRangeItem(false, options.PortRange) 142 if err != nil { 143 return nil, E.Cause(err, "port_range") 144 } 145 rule.destinationPortItems = append(rule.destinationPortItems, item) 146 rule.allItems = append(rule.allItems, item) 147 } 148 if len(options.ProcessName) > 0 { 149 item := NewProcessItem(options.ProcessName) 150 rule.items = append(rule.items, item) 151 rule.allItems = append(rule.allItems, item) 152 } 153 if len(options.ProcessPath) > 0 { 154 item := NewProcessPathItem(options.ProcessPath) 155 rule.items = append(rule.items, item) 156 rule.allItems = append(rule.allItems, item) 157 } 158 if len(options.PackageName) > 0 { 159 item := NewPackageNameItem(options.PackageName) 160 rule.items = append(rule.items, item) 161 rule.allItems = append(rule.allItems, item) 162 } 163 if len(options.User) > 0 { 164 item := NewUserItem(options.User) 165 rule.items = append(rule.items, item) 166 rule.allItems = append(rule.allItems, item) 167 } 168 if len(options.UserID) > 0 { 169 item := NewUserIDItem(options.UserID) 170 rule.items = append(rule.items, item) 171 rule.allItems = append(rule.allItems, item) 172 } 173 if len(options.Outbound) > 0 { 174 item := NewOutboundRule(options.Outbound) 175 rule.items = append(rule.items, item) 176 rule.allItems = append(rule.allItems, item) 177 } 178 if options.ClashMode != "" { 179 item := NewClashModeItem(router, options.ClashMode) 180 rule.items = append(rule.items, item) 181 rule.allItems = append(rule.allItems, item) 182 } 183 return rule, nil 184 } 185 186 func (r *DefaultDNSRule) DisableCache() bool { 187 return r.disableCache 188 } 189 190 func (r *DefaultDNSRule) RewriteTTL() *uint32 { 191 return r.rewriteTTL 192 } 193 194 var _ adapter.DNSRule = (*LogicalDNSRule)(nil) 195 196 type LogicalDNSRule struct { 197 abstractLogicalRule 198 disableCache bool 199 rewriteTTL *uint32 200 } 201 202 func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) { 203 r := &LogicalDNSRule{ 204 abstractLogicalRule: abstractLogicalRule{ 205 rules: make([]adapter.Rule, len(options.Rules)), 206 invert: options.Invert, 207 outbound: options.Server, 208 }, 209 disableCache: options.DisableCache, 210 rewriteTTL: options.RewriteTTL, 211 } 212 switch options.Mode { 213 case C.LogicalTypeAnd: 214 r.mode = C.LogicalTypeAnd 215 case C.LogicalTypeOr: 216 r.mode = C.LogicalTypeOr 217 default: 218 return nil, E.New("unknown logical mode: ", options.Mode) 219 } 220 for i, subRule := range options.Rules { 221 rule, err := NewDefaultDNSRule(router, logger, subRule) 222 if err != nil { 223 return nil, E.Cause(err, "sub rule[", i, "]") 224 } 225 r.rules[i] = rule 226 } 227 return r, nil 228 } 229 230 func (r *LogicalDNSRule) DisableCache() bool { 231 return r.disableCache 232 } 233 234 func (r *LogicalDNSRule) RewriteTTL() *uint32 { 235 return r.rewriteTTL 236 }