github.com/xmplusdev/xray-core@v1.8.10/common/net/destination.go (about) 1 package net 2 3 import ( 4 "net" 5 "strings" 6 ) 7 8 // Destination represents a network destination including address and protocol (tcp / udp). 9 type Destination struct { 10 Address Address 11 Port Port 12 Network Network 13 } 14 15 // DestinationFromAddr generates a Destination from a net address. 16 func DestinationFromAddr(addr net.Addr) Destination { 17 switch addr := addr.(type) { 18 case *net.TCPAddr: 19 return TCPDestination(IPAddress(addr.IP), Port(addr.Port)) 20 case *net.UDPAddr: 21 return UDPDestination(IPAddress(addr.IP), Port(addr.Port)) 22 case *net.UnixAddr: 23 return UnixDestination(DomainAddress(addr.Name)) 24 default: 25 panic("Net: Unknown address type.") 26 } 27 } 28 29 // ParseDestination converts a destination from its string presentation. 30 func ParseDestination(dest string) (Destination, error) { 31 d := Destination{ 32 Address: AnyIP, 33 Port: Port(0), 34 } 35 if strings.HasPrefix(dest, "tcp:") { 36 d.Network = Network_TCP 37 dest = dest[4:] 38 } else if strings.HasPrefix(dest, "udp:") { 39 d.Network = Network_UDP 40 dest = dest[4:] 41 } else if strings.HasPrefix(dest, "unix:") { 42 d = UnixDestination(DomainAddress(dest[5:])) 43 return d, nil 44 } 45 46 hstr, pstr, err := SplitHostPort(dest) 47 if err != nil { 48 return d, err 49 } 50 if len(hstr) > 0 { 51 d.Address = ParseAddress(hstr) 52 } 53 if len(pstr) > 0 { 54 port, err := PortFromString(pstr) 55 if err != nil { 56 return d, err 57 } 58 d.Port = port 59 } 60 return d, nil 61 } 62 63 // TCPDestination creates a TCP destination with given address 64 func TCPDestination(address Address, port Port) Destination { 65 return Destination{ 66 Network: Network_TCP, 67 Address: address, 68 Port: port, 69 } 70 } 71 72 // UDPDestination creates a UDP destination with given address 73 func UDPDestination(address Address, port Port) Destination { 74 return Destination{ 75 Network: Network_UDP, 76 Address: address, 77 Port: port, 78 } 79 } 80 81 // UnixDestination creates a Unix destination with given address 82 func UnixDestination(address Address) Destination { 83 return Destination{ 84 Network: Network_UNIX, 85 Address: address, 86 } 87 } 88 89 // NetAddr returns the network address in this Destination in string form. 90 func (d Destination) NetAddr() string { 91 addr := "" 92 if d.Network == Network_TCP || d.Network == Network_UDP { 93 addr = d.Address.String() + ":" + d.Port.String() 94 } else if d.Network == Network_UNIX { 95 addr = d.Address.String() 96 } 97 return addr 98 } 99 100 // RawNetAddr converts a net.Addr from its Destination presentation. 101 func (d Destination) RawNetAddr() net.Addr { 102 var addr net.Addr 103 switch d.Network { 104 case Network_TCP: 105 if d.Address.Family().IsIP() { 106 addr = &net.TCPAddr{ 107 IP: d.Address.IP(), 108 Port: int(d.Port), 109 } 110 } 111 case Network_UDP: 112 if d.Address.Family().IsIP() { 113 addr = &net.UDPAddr{ 114 IP: d.Address.IP(), 115 Port: int(d.Port), 116 } 117 } 118 case Network_UNIX: 119 if d.Address.Family().IsDomain() { 120 addr = &net.UnixAddr{ 121 Name: d.Address.String(), 122 Net: d.Network.SystemString(), 123 } 124 } 125 } 126 return addr 127 } 128 129 // String returns the strings form of this Destination. 130 func (d Destination) String() string { 131 prefix := "unknown:" 132 switch d.Network { 133 case Network_TCP: 134 prefix = "tcp:" 135 case Network_UDP: 136 prefix = "udp:" 137 case Network_UNIX: 138 prefix = "unix:" 139 } 140 return prefix + d.NetAddr() 141 } 142 143 // IsValid returns true if this Destination is valid. 144 func (d Destination) IsValid() bool { 145 return d.Network != Network_Unknown 146 } 147 148 // AsDestination converts current Endpoint into Destination. 149 func (p *Endpoint) AsDestination() Destination { 150 return Destination{ 151 Network: p.Network, 152 Address: p.Address.AsAddress(), 153 Port: Port(p.Port), 154 } 155 }