forked from v2fly/v2ray-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdestination.go
128 lines (115 loc) · 2.89 KB
/
destination.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package net
import (
"net"
"strings"
)
// Destination represents a network destination including address and protocol (tcp / udp).
type Destination struct {
Address Address
Port Port
Network Network
}
// DestinationFromAddr generates a Destination from a net address.
func DestinationFromAddr(addr net.Addr) Destination {
switch addr := addr.(type) {
case *net.TCPAddr:
return TCPDestination(IPAddress(addr.IP), Port(addr.Port))
case *net.UDPAddr:
return UDPDestination(IPAddress(addr.IP), Port(addr.Port))
case *net.UnixAddr:
return UnixDestination(DomainAddress(addr.Name))
default:
panic("Net: Unknown address type.")
}
}
// ParseDestination converts a destination from its string presentation.
func ParseDestination(dest string) (Destination, error) {
d := Destination{
Address: AnyIP,
Port: Port(0),
}
switch {
case strings.HasPrefix(dest, "tcp:"):
d.Network = Network_TCP
dest = dest[4:]
case strings.HasPrefix(dest, "udp:"):
d.Network = Network_UDP
dest = dest[4:]
case strings.HasPrefix(dest, "unix:"):
d = UnixDestination(DomainAddress(dest[5:]))
return d, nil
}
hstr, pstr, err := SplitHostPort(dest)
if err != nil {
return d, err
}
if len(hstr) > 0 {
d.Address = ParseAddress(hstr)
}
if len(pstr) > 0 {
port, err := PortFromString(pstr)
if err != nil {
return d, err
}
d.Port = port
}
return d, nil
}
// TCPDestination creates a TCP destination with given address
func TCPDestination(address Address, port Port) Destination {
return Destination{
Network: Network_TCP,
Address: address,
Port: port,
}
}
// UDPDestination creates a UDP destination with given address
func UDPDestination(address Address, port Port) Destination {
return Destination{
Network: Network_UDP,
Address: address,
Port: port,
}
}
// UnixDestination creates a Unix destination with given address
func UnixDestination(address Address) Destination {
return Destination{
Network: Network_UNIX,
Address: address,
}
}
// NetAddr returns the network address in this Destination in string form.
func (d Destination) NetAddr() string {
addr := ""
if d.Network == Network_TCP || d.Network == Network_UDP {
addr = d.Address.String() + ":" + d.Port.String()
} else if d.Network == Network_UNIX {
addr = d.Address.String()
}
return addr
}
// String returns the strings form of this Destination.
func (d Destination) String() string {
prefix := "unknown:"
switch d.Network {
case Network_TCP:
prefix = "tcp:"
case Network_UDP:
prefix = "udp:"
case Network_UNIX:
prefix = "unix:"
}
return prefix + d.NetAddr()
}
// IsValid returns true if this Destination is valid.
func (d Destination) IsValid() bool {
return d.Network != Network_Unknown
}
// AsDestination converts current Endpoint into Destination.
func (p *Endpoint) AsDestination() Destination {
return Destination{
Network: p.Network,
Address: p.Address.AsAddress(),
Port: Port(p.Port),
}
}