github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/router/command/config.go (about) 1 package command 2 3 import ( 4 "strings" 5 6 "v2ray.com/core/common/net" 7 "v2ray.com/core/features/routing" 8 ) 9 10 // routingContext is an wrapper of protobuf RoutingContext as implementation of routing.Context and routing.Route. 11 type routingContext struct { 12 *RoutingContext 13 } 14 15 func (c routingContext) GetSourceIPs() []net.IP { 16 return mapBytesToIPs(c.RoutingContext.GetSourceIPs()) 17 } 18 19 func (c routingContext) GetSourcePort() net.Port { 20 return net.Port(c.RoutingContext.GetSourcePort()) 21 } 22 23 func (c routingContext) GetTargetIPs() []net.IP { 24 return mapBytesToIPs(c.RoutingContext.GetTargetIPs()) 25 } 26 27 func (c routingContext) GetTargetPort() net.Port { 28 return net.Port(c.RoutingContext.GetTargetPort()) 29 } 30 31 // AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context. 32 func AsRoutingContext(r *RoutingContext) routing.Context { 33 return routingContext{r} 34 } 35 36 // AsRoutingRoute converts a protobuf RoutingContext into an implementation of routing.Route. 37 func AsRoutingRoute(r *RoutingContext) routing.Route { 38 return routingContext{r} 39 } 40 41 var fieldMap = map[string]func(*RoutingContext, routing.Route){ 42 "inbound": func(s *RoutingContext, r routing.Route) { s.InboundTag = r.GetInboundTag() }, 43 "network": func(s *RoutingContext, r routing.Route) { s.Network = r.GetNetwork() }, 44 "ip_source": func(s *RoutingContext, r routing.Route) { s.SourceIPs = mapIPsToBytes(r.GetSourceIPs()) }, 45 "ip_target": func(s *RoutingContext, r routing.Route) { s.TargetIPs = mapIPsToBytes(r.GetTargetIPs()) }, 46 "port_source": func(s *RoutingContext, r routing.Route) { s.SourcePort = uint32(r.GetSourcePort()) }, 47 "port_target": func(s *RoutingContext, r routing.Route) { s.TargetPort = uint32(r.GetTargetPort()) }, 48 "domain": func(s *RoutingContext, r routing.Route) { s.TargetDomain = r.GetTargetDomain() }, 49 "protocol": func(s *RoutingContext, r routing.Route) { s.Protocol = r.GetProtocol() }, 50 "user": func(s *RoutingContext, r routing.Route) { s.User = r.GetUser() }, 51 "attributes": func(s *RoutingContext, r routing.Route) { s.Attributes = r.GetAttributes() }, 52 "outbound_group": func(s *RoutingContext, r routing.Route) { s.OutboundGroupTags = r.GetOutboundGroupTags() }, 53 "outbound": func(s *RoutingContext, r routing.Route) { s.OutboundTag = r.GetOutboundTag() }, 54 } 55 56 // AsProtobufMessage takes selectors of fields and returns a function to convert routing.Route to protobuf RoutingContext. 57 func AsProtobufMessage(fieldSelectors []string) func(routing.Route) *RoutingContext { 58 initializers := []func(*RoutingContext, routing.Route){} 59 for field, init := range fieldMap { 60 if len(fieldSelectors) == 0 { // If selectors not set, retrieve all fields 61 initializers = append(initializers, init) 62 continue 63 } 64 for _, selector := range fieldSelectors { 65 if strings.HasPrefix(field, selector) { 66 initializers = append(initializers, init) 67 break 68 } 69 } 70 } 71 return func(ctx routing.Route) *RoutingContext { 72 message := new(RoutingContext) 73 for _, init := range initializers { 74 init(message, ctx) 75 } 76 return message 77 } 78 } 79 80 func mapBytesToIPs(bytes [][]byte) []net.IP { 81 var ips []net.IP 82 for _, rawIP := range bytes { 83 ips = append(ips, net.IP(rawIP)) 84 } 85 return ips 86 } 87 88 func mapIPsToBytes(ips []net.IP) [][]byte { 89 var bytes [][]byte 90 for _, ip := range ips { 91 bytes = append(bytes, []byte(ip)) 92 } 93 return bytes 94 }