github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/router/config.go (about)

     1  // +build !confonly
     2  
     3  package router
     4  
     5  import (
     6  	"v2ray.com/core/common/net"
     7  	"v2ray.com/core/features/outbound"
     8  	"v2ray.com/core/features/routing"
     9  )
    10  
    11  // CIDRList is an alias of []*CIDR to provide sort.Interface.
    12  type CIDRList []*CIDR
    13  
    14  // Len implements sort.Interface.
    15  func (l *CIDRList) Len() int {
    16  	return len(*l)
    17  }
    18  
    19  // Less implements sort.Interface.
    20  func (l *CIDRList) Less(i int, j int) bool {
    21  	ci := (*l)[i]
    22  	cj := (*l)[j]
    23  
    24  	if len(ci.Ip) < len(cj.Ip) {
    25  		return true
    26  	}
    27  
    28  	if len(ci.Ip) > len(cj.Ip) {
    29  		return false
    30  	}
    31  
    32  	for k := 0; k < len(ci.Ip); k++ {
    33  		if ci.Ip[k] < cj.Ip[k] {
    34  			return true
    35  		}
    36  
    37  		if ci.Ip[k] > cj.Ip[k] {
    38  			return false
    39  		}
    40  	}
    41  
    42  	return ci.Prefix < cj.Prefix
    43  }
    44  
    45  // Swap implements sort.Interface.
    46  func (l *CIDRList) Swap(i int, j int) {
    47  	(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
    48  }
    49  
    50  type Rule struct {
    51  	Tag       string
    52  	Balancer  *Balancer
    53  	Condition Condition
    54  }
    55  
    56  func (r *Rule) GetTag() (string, error) {
    57  	if r.Balancer != nil {
    58  		return r.Balancer.PickOutbound()
    59  	}
    60  	return r.Tag, nil
    61  }
    62  
    63  // Apply checks rule matching of current routing context.
    64  func (r *Rule) Apply(ctx routing.Context) bool {
    65  	return r.Condition.Apply(ctx)
    66  }
    67  
    68  func (rr *RoutingRule) BuildCondition() (Condition, error) {
    69  	conds := NewConditionChan()
    70  
    71  	if len(rr.Domain) > 0 {
    72  		matcher, err := NewDomainMatcher(rr.Domain)
    73  		if err != nil {
    74  			return nil, newError("failed to build domain condition").Base(err)
    75  		}
    76  		conds.Add(matcher)
    77  	}
    78  
    79  	if len(rr.UserEmail) > 0 {
    80  		conds.Add(NewUserMatcher(rr.UserEmail))
    81  	}
    82  
    83  	if len(rr.InboundTag) > 0 {
    84  		conds.Add(NewInboundTagMatcher(rr.InboundTag))
    85  	}
    86  
    87  	if rr.PortList != nil {
    88  		conds.Add(NewPortMatcher(rr.PortList, false))
    89  	} else if rr.PortRange != nil {
    90  		conds.Add(NewPortMatcher(&net.PortList{Range: []*net.PortRange{rr.PortRange}}, false))
    91  	}
    92  
    93  	if rr.SourcePortList != nil {
    94  		conds.Add(NewPortMatcher(rr.SourcePortList, true))
    95  	}
    96  
    97  	if len(rr.Networks) > 0 {
    98  		conds.Add(NewNetworkMatcher(rr.Networks))
    99  	} else if rr.NetworkList != nil {
   100  		conds.Add(NewNetworkMatcher(rr.NetworkList.Network))
   101  	}
   102  
   103  	if len(rr.Geoip) > 0 {
   104  		cond, err := NewMultiGeoIPMatcher(rr.Geoip, false)
   105  		if err != nil {
   106  			return nil, err
   107  		}
   108  		conds.Add(cond)
   109  	} else if len(rr.Cidr) > 0 {
   110  		cond, err := NewMultiGeoIPMatcher([]*GeoIP{{Cidr: rr.Cidr}}, false)
   111  		if err != nil {
   112  			return nil, err
   113  		}
   114  		conds.Add(cond)
   115  	}
   116  
   117  	if len(rr.SourceGeoip) > 0 {
   118  		cond, err := NewMultiGeoIPMatcher(rr.SourceGeoip, true)
   119  		if err != nil {
   120  			return nil, err
   121  		}
   122  		conds.Add(cond)
   123  	} else if len(rr.SourceCidr) > 0 {
   124  		cond, err := NewMultiGeoIPMatcher([]*GeoIP{{Cidr: rr.SourceCidr}}, true)
   125  		if err != nil {
   126  			return nil, err
   127  		}
   128  		conds.Add(cond)
   129  	}
   130  
   131  	if len(rr.Protocol) > 0 {
   132  		conds.Add(NewProtocolMatcher(rr.Protocol))
   133  	}
   134  
   135  	if len(rr.Attributes) > 0 {
   136  		cond, err := NewAttributeMatcher(rr.Attributes)
   137  		if err != nil {
   138  			return nil, err
   139  		}
   140  		conds.Add(cond)
   141  	}
   142  
   143  	if conds.Len() == 0 {
   144  		return nil, newError("this rule has no effective fields").AtWarning()
   145  	}
   146  
   147  	return conds, nil
   148  }
   149  
   150  func (br *BalancingRule) Build(ohm outbound.Manager) (*Balancer, error) {
   151  	return &Balancer{
   152  		selectors: br.OutboundSelector,
   153  		strategy:  &RandomStrategy{},
   154  		ohm:       ohm,
   155  	}, nil
   156  }