github.com/imannamdari/v2ray-core/v5@v5.0.5/app/router/command/config.go (about) 1 package command 2 3 import ( 4 "strings" 5 6 "github.com/imannamdari/v2ray-core/v5/common/net" 7 "github.com/imannamdari/v2ray-core/v5/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 // GetSkipDNSResolve is a mock implementation here to match the interface, 32 // SkipDNSResolve is set from dns module, no use if coming from a protobuf object? 33 // TODO: please confirm @Vigilans 34 func (c routingContext) GetSkipDNSResolve() bool { 35 return false 36 } 37 38 // AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context. 39 func AsRoutingContext(r *RoutingContext) routing.Context { 40 return routingContext{r} 41 } 42 43 // AsRoutingRoute converts a protobuf RoutingContext into an implementation of routing.Route. 44 func AsRoutingRoute(r *RoutingContext) routing.Route { 45 return routingContext{r} 46 } 47 48 var fieldMap = map[string]func(*RoutingContext, routing.Route){ 49 "inbound": func(s *RoutingContext, r routing.Route) { s.InboundTag = r.GetInboundTag() }, 50 "network": func(s *RoutingContext, r routing.Route) { s.Network = r.GetNetwork() }, 51 "ip_source": func(s *RoutingContext, r routing.Route) { s.SourceIPs = mapIPsToBytes(r.GetSourceIPs()) }, 52 "ip_target": func(s *RoutingContext, r routing.Route) { s.TargetIPs = mapIPsToBytes(r.GetTargetIPs()) }, 53 "port_source": func(s *RoutingContext, r routing.Route) { s.SourcePort = uint32(r.GetSourcePort()) }, 54 "port_target": func(s *RoutingContext, r routing.Route) { s.TargetPort = uint32(r.GetTargetPort()) }, 55 "domain": func(s *RoutingContext, r routing.Route) { s.TargetDomain = r.GetTargetDomain() }, 56 "protocol": func(s *RoutingContext, r routing.Route) { s.Protocol = r.GetProtocol() }, 57 "user": func(s *RoutingContext, r routing.Route) { s.User = r.GetUser() }, 58 "attributes": func(s *RoutingContext, r routing.Route) { s.Attributes = r.GetAttributes() }, 59 "outbound_group": func(s *RoutingContext, r routing.Route) { s.OutboundGroupTags = r.GetOutboundGroupTags() }, 60 "outbound": func(s *RoutingContext, r routing.Route) { s.OutboundTag = r.GetOutboundTag() }, 61 } 62 63 // AsProtobufMessage takes selectors of fields and returns a function to convert routing.Route to protobuf RoutingContext. 64 func AsProtobufMessage(fieldSelectors []string) func(routing.Route) *RoutingContext { 65 initializers := []func(*RoutingContext, routing.Route){} 66 for field, init := range fieldMap { 67 if len(fieldSelectors) == 0 { // If selectors not set, retrieve all fields 68 initializers = append(initializers, init) 69 continue 70 } 71 for _, selector := range fieldSelectors { 72 if strings.HasPrefix(field, selector) { 73 initializers = append(initializers, init) 74 break 75 } 76 } 77 } 78 return func(ctx routing.Route) *RoutingContext { 79 message := new(RoutingContext) 80 for _, init := range initializers { 81 init(message, ctx) 82 } 83 return message 84 } 85 } 86 87 func mapBytesToIPs(bytes [][]byte) []net.IP { 88 var ips []net.IP 89 for _, rawIP := range bytes { 90 ips = append(ips, net.IP(rawIP)) 91 } 92 return ips 93 } 94 95 func mapIPsToBytes(ips []net.IP) [][]byte { 96 var bytes [][]byte 97 for _, ip := range ips { 98 bytes = append(bytes, []byte(ip)) 99 } 100 return bytes 101 }