github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/route/rule_default.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 NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule) (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 == "" { 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 == "" { 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.destinationAddressItems = append(rule.destinationAddressItems, 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_ipcidr") 119 } 120 rule.sourceAddressItems = append(rule.sourceAddressItems, item) 121 rule.allItems = append(rule.allItems, item) 122 } 123 if len(options.IPCIDR) > 0 { 124 item, err := NewIPCIDRItem(false, options.IPCIDR) 125 if err != nil { 126 return nil, E.Cause(err, "ipcidr") 127 } 128 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 129 rule.allItems = append(rule.allItems, item) 130 } 131 if len(options.SourcePort) > 0 { 132 item := NewPortItem(true, options.SourcePort) 133 rule.sourcePortItems = append(rule.sourcePortItems, item) 134 rule.allItems = append(rule.allItems, item) 135 } 136 if len(options.SourcePortRange) > 0 { 137 item, err := NewPortRangeItem(true, options.SourcePortRange) 138 if err != nil { 139 return nil, E.Cause(err, "source_port_range") 140 } 141 rule.sourcePortItems = append(rule.sourcePortItems, item) 142 rule.allItems = append(rule.allItems, item) 143 } 144 if len(options.Port) > 0 { 145 item := NewPortItem(false, options.Port) 146 rule.destinationPortItems = append(rule.destinationPortItems, item) 147 rule.allItems = append(rule.allItems, item) 148 } 149 if len(options.PortRange) > 0 { 150 item, err := NewPortRangeItem(false, options.PortRange) 151 if err != nil { 152 return nil, E.Cause(err, "port_range") 153 } 154 rule.destinationPortItems = append(rule.destinationPortItems, item) 155 rule.allItems = append(rule.allItems, item) 156 } 157 if len(options.ProcessName) > 0 { 158 item := NewProcessItem(options.ProcessName) 159 rule.items = append(rule.items, item) 160 rule.allItems = append(rule.allItems, item) 161 } 162 if len(options.ProcessPath) > 0 { 163 item := NewProcessPathItem(options.ProcessPath) 164 rule.items = append(rule.items, item) 165 rule.allItems = append(rule.allItems, item) 166 } 167 if len(options.PackageName) > 0 { 168 item := NewPackageNameItem(options.PackageName) 169 rule.items = append(rule.items, item) 170 rule.allItems = append(rule.allItems, item) 171 } 172 if len(options.User) > 0 { 173 item := NewUserItem(options.User) 174 rule.items = append(rule.items, item) 175 rule.allItems = append(rule.allItems, item) 176 } 177 if len(options.UserID) > 0 { 178 item := NewUserIDItem(options.UserID) 179 rule.items = append(rule.items, item) 180 rule.allItems = append(rule.allItems, item) 181 } 182 if options.ClashMode != "" { 183 item := NewClashModeItem(router, options.ClashMode) 184 rule.items = append(rule.items, item) 185 rule.allItems = append(rule.allItems, item) 186 } 187 return rule, nil 188 } 189 190 var _ adapter.Rule = (*LogicalRule)(nil) 191 192 type LogicalRule struct { 193 abstractLogicalRule 194 } 195 196 func NewLogicalRule(router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) { 197 r := &LogicalRule{ 198 abstractLogicalRule{ 199 rules: make([]adapter.Rule, len(options.Rules)), 200 invert: options.Invert, 201 outbound: options.Outbound, 202 }, 203 } 204 switch options.Mode { 205 case C.LogicalTypeAnd: 206 r.mode = C.LogicalTypeAnd 207 case C.LogicalTypeOr: 208 r.mode = C.LogicalTypeOr 209 default: 210 return nil, E.New("unknown logical mode: ", options.Mode) 211 } 212 for i, subRule := range options.Rules { 213 rule, err := NewDefaultRule(router, logger, subRule) 214 if err != nil { 215 return nil, E.Cause(err, "sub rule[", i, "]") 216 } 217 r.rules[i] = rule 218 } 219 return r, nil 220 }