github.com/sagernet/sing-box@v1.9.0-rc.20/route/rule_headless.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/option" 7 E "github.com/sagernet/sing/common/exceptions" 8 ) 9 10 func NewHeadlessRule(router adapter.Router, options option.HeadlessRule) (adapter.HeadlessRule, error) { 11 switch options.Type { 12 case "", C.RuleTypeDefault: 13 if !options.DefaultOptions.IsValid() { 14 return nil, E.New("missing conditions") 15 } 16 return NewDefaultHeadlessRule(router, options.DefaultOptions) 17 case C.RuleTypeLogical: 18 if !options.LogicalOptions.IsValid() { 19 return nil, E.New("missing conditions") 20 } 21 return NewLogicalHeadlessRule(router, options.LogicalOptions) 22 default: 23 return nil, E.New("unknown rule type: ", options.Type) 24 } 25 } 26 27 var _ adapter.HeadlessRule = (*DefaultHeadlessRule)(nil) 28 29 type DefaultHeadlessRule struct { 30 abstractDefaultRule 31 } 32 33 func NewDefaultHeadlessRule(router adapter.Router, options option.DefaultHeadlessRule) (*DefaultHeadlessRule, error) { 34 rule := &DefaultHeadlessRule{ 35 abstractDefaultRule{ 36 invert: options.Invert, 37 }, 38 } 39 if len(options.Network) > 0 { 40 item := NewNetworkItem(options.Network) 41 rule.items = append(rule.items, item) 42 rule.allItems = append(rule.allItems, item) 43 } 44 if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 { 45 item := NewDomainItem(options.Domain, options.DomainSuffix) 46 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 47 rule.allItems = append(rule.allItems, item) 48 } else if options.DomainMatcher != nil { 49 item := NewRawDomainItem(options.DomainMatcher) 50 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 51 rule.allItems = append(rule.allItems, item) 52 } 53 if len(options.DomainKeyword) > 0 { 54 item := NewDomainKeywordItem(options.DomainKeyword) 55 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 56 rule.allItems = append(rule.allItems, item) 57 } 58 if len(options.DomainRegex) > 0 { 59 item, err := NewDomainRegexItem(options.DomainRegex) 60 if err != nil { 61 return nil, E.Cause(err, "domain_regex") 62 } 63 rule.destinationAddressItems = append(rule.destinationAddressItems, item) 64 rule.allItems = append(rule.allItems, item) 65 } 66 if len(options.SourceIPCIDR) > 0 { 67 item, err := NewIPCIDRItem(true, options.SourceIPCIDR) 68 if err != nil { 69 return nil, E.Cause(err, "source_ip_cidr") 70 } 71 rule.sourceAddressItems = append(rule.sourceAddressItems, item) 72 rule.allItems = append(rule.allItems, item) 73 } else if options.SourceIPSet != nil { 74 item := NewRawIPCIDRItem(true, options.SourceIPSet) 75 rule.sourceAddressItems = append(rule.sourceAddressItems, item) 76 rule.allItems = append(rule.allItems, item) 77 } 78 if len(options.IPCIDR) > 0 { 79 item, err := NewIPCIDRItem(false, options.IPCIDR) 80 if err != nil { 81 return nil, E.Cause(err, "ipcidr") 82 } 83 rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item) 84 rule.allItems = append(rule.allItems, item) 85 } else if options.IPSet != nil { 86 item := NewRawIPCIDRItem(false, options.IPSet) 87 rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item) 88 rule.allItems = append(rule.allItems, item) 89 } 90 if len(options.SourcePort) > 0 { 91 item := NewPortItem(true, options.SourcePort) 92 rule.sourcePortItems = append(rule.sourcePortItems, item) 93 rule.allItems = append(rule.allItems, item) 94 } 95 if len(options.SourcePortRange) > 0 { 96 item, err := NewPortRangeItem(true, options.SourcePortRange) 97 if err != nil { 98 return nil, E.Cause(err, "source_port_range") 99 } 100 rule.sourcePortItems = append(rule.sourcePortItems, item) 101 rule.allItems = append(rule.allItems, item) 102 } 103 if len(options.Port) > 0 { 104 item := NewPortItem(false, options.Port) 105 rule.destinationPortItems = append(rule.destinationPortItems, item) 106 rule.allItems = append(rule.allItems, item) 107 } 108 if len(options.PortRange) > 0 { 109 item, err := NewPortRangeItem(false, options.PortRange) 110 if err != nil { 111 return nil, E.Cause(err, "port_range") 112 } 113 rule.destinationPortItems = append(rule.destinationPortItems, item) 114 rule.allItems = append(rule.allItems, item) 115 } 116 if len(options.ProcessName) > 0 { 117 item := NewProcessItem(options.ProcessName) 118 rule.items = append(rule.items, item) 119 rule.allItems = append(rule.allItems, item) 120 } 121 if len(options.ProcessPath) > 0 { 122 item := NewProcessPathItem(options.ProcessPath) 123 rule.items = append(rule.items, item) 124 rule.allItems = append(rule.allItems, item) 125 } 126 if len(options.PackageName) > 0 { 127 item := NewPackageNameItem(options.PackageName) 128 rule.items = append(rule.items, item) 129 rule.allItems = append(rule.allItems, item) 130 } 131 if len(options.WIFISSID) > 0 { 132 if router != nil { 133 item := NewWIFISSIDItem(router, options.WIFISSID) 134 rule.items = append(rule.items, item) 135 rule.allItems = append(rule.allItems, item) 136 } 137 } 138 if len(options.WIFIBSSID) > 0 { 139 if router != nil { 140 item := NewWIFIBSSIDItem(router, options.WIFIBSSID) 141 rule.items = append(rule.items, item) 142 rule.allItems = append(rule.allItems, item) 143 } 144 } 145 return rule, nil 146 } 147 148 var _ adapter.HeadlessRule = (*LogicalHeadlessRule)(nil) 149 150 type LogicalHeadlessRule struct { 151 abstractLogicalRule 152 } 153 154 func NewLogicalHeadlessRule(router adapter.Router, options option.LogicalHeadlessRule) (*LogicalHeadlessRule, error) { 155 r := &LogicalHeadlessRule{ 156 abstractLogicalRule{ 157 rules: make([]adapter.HeadlessRule, len(options.Rules)), 158 invert: options.Invert, 159 }, 160 } 161 switch options.Mode { 162 case C.LogicalTypeAnd: 163 r.mode = C.LogicalTypeAnd 164 case C.LogicalTypeOr: 165 r.mode = C.LogicalTypeOr 166 default: 167 return nil, E.New("unknown logical mode: ", options.Mode) 168 } 169 for i, subRule := range options.Rules { 170 rule, err := NewHeadlessRule(router, subRule) 171 if err != nil { 172 return nil, E.Cause(err, "sub rule[", i, "]") 173 } 174 r.rules[i] = rule 175 } 176 return r, nil 177 }