config.go 4.2 KB

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