github.com/v2fly/v2ray-core/v4@v4.45.2/app/router/command/config.go (about)

     1  package command
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/v2fly/v2ray-core/v4/common/net"
     7  	"github.com/v2fly/v2ray-core/v4/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  }