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  }