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