config.go 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package command
  2. import (
  3. "strings"
  4. "v2ray.com/core/common/net"
  5. "v2ray.com/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. // AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context.
  24. func AsRoutingContext(r *RoutingContext) routing.Context {
  25. return routingContext{r}
  26. }
  27. // AsRoutingRoute converts a protobuf RoutingContext into an implementation of routing.Route.
  28. func AsRoutingRoute(r *RoutingContext) routing.Route {
  29. return routingContext{r}
  30. }
  31. var fieldMap = map[string]func(*RoutingContext, routing.Route){
  32. "inbound": func(s *RoutingContext, r routing.Route) { s.InboundTag = r.GetInboundTag() },
  33. "network": func(s *RoutingContext, r routing.Route) { s.Network = r.GetNetwork() },
  34. "ip_source": func(s *RoutingContext, r routing.Route) { s.SourceIPs = mapIPsToBytes(r.GetSourceIPs()) },
  35. "ip_target": func(s *RoutingContext, r routing.Route) { s.TargetIPs = mapIPsToBytes(r.GetTargetIPs()) },
  36. "port_source": func(s *RoutingContext, r routing.Route) { s.SourcePort = uint32(r.GetSourcePort()) },
  37. "port_target": func(s *RoutingContext, r routing.Route) { s.TargetPort = uint32(r.GetTargetPort()) },
  38. "domain": func(s *RoutingContext, r routing.Route) { s.TargetDomain = r.GetTargetDomain() },
  39. "protocol": func(s *RoutingContext, r routing.Route) { s.Protocol = r.GetProtocol() },
  40. "user": func(s *RoutingContext, r routing.Route) { s.User = r.GetUser() },
  41. "attributes": func(s *RoutingContext, r routing.Route) { s.Attributes = r.GetAttributes() },
  42. "outbound_group": func(s *RoutingContext, r routing.Route) { s.OutboundGroupTags = r.GetOutboundGroupTags() },
  43. "outbound": func(s *RoutingContext, r routing.Route) { s.OutboundTag = r.GetOutboundTag() },
  44. }
  45. // AsProtobufMessage takes selectors of fields and returns a function to convert routing.Route to protobuf RoutingContext.
  46. func AsProtobufMessage(fieldSelectors []string) func(routing.Route) *RoutingContext {
  47. initializers := []func(*RoutingContext, routing.Route){}
  48. for field, init := range fieldMap {
  49. if len(fieldSelectors) == 0 { // If selectors not set, retrieve all fields
  50. initializers = append(initializers, init)
  51. continue
  52. }
  53. for _, selector := range fieldSelectors {
  54. if strings.HasPrefix(field, selector) {
  55. initializers = append(initializers, init)
  56. break
  57. }
  58. }
  59. }
  60. return func(ctx routing.Route) *RoutingContext {
  61. message := new(RoutingContext)
  62. for _, init := range initializers {
  63. init(message, ctx)
  64. }
  65. return message
  66. }
  67. }
  68. func mapBytesToIPs(bytes [][]byte) []net.IP {
  69. var ips []net.IP
  70. for _, rawIP := range bytes {
  71. ips = append(ips, net.IP(rawIP))
  72. }
  73. return ips
  74. }
  75. func mapIPsToBytes(ips []net.IP) [][]byte {
  76. var bytes [][]byte
  77. for _, ip := range ips {
  78. bytes = append(bytes, []byte(ip))
  79. }
  80. return bytes
  81. }