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