github.com/eagleql/xray-core@v1.4.4/app/router/command/config.go (about)

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