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 }