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  }