github.com/xmplusdev/xray-core@v1.8.10/common/net/address.go (about) 1 package net 2 3 import ( 4 "bytes" 5 "net" 6 "strings" 7 ) 8 9 var ( 10 // LocalHostIP is a constant value for localhost IP in IPv4. 11 LocalHostIP = IPAddress([]byte{127, 0, 0, 1}) 12 13 // AnyIP is a constant value for any IP in IPv4. 14 AnyIP = IPAddress([]byte{0, 0, 0, 0}) 15 16 // LocalHostDomain is a constant value for localhost domain. 17 LocalHostDomain = DomainAddress("localhost") 18 19 // LocalHostIPv6 is a constant value for localhost IP in IPv6. 20 LocalHostIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}) 21 22 // AnyIPv6 is a constant value for any IP in IPv6. 23 AnyIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) 24 ) 25 26 // AddressFamily is the type of address. 27 type AddressFamily byte 28 29 const ( 30 // AddressFamilyIPv4 represents address as IPv4 31 AddressFamilyIPv4 = AddressFamily(0) 32 33 // AddressFamilyIPv6 represents address as IPv6 34 AddressFamilyIPv6 = AddressFamily(1) 35 36 // AddressFamilyDomain represents address as Domain 37 AddressFamilyDomain = AddressFamily(2) 38 ) 39 40 // IsIPv4 returns true if current AddressFamily is IPv4. 41 func (af AddressFamily) IsIPv4() bool { 42 return af == AddressFamilyIPv4 43 } 44 45 // IsIPv6 returns true if current AddressFamily is IPv6. 46 func (af AddressFamily) IsIPv6() bool { 47 return af == AddressFamilyIPv6 48 } 49 50 // IsIP returns true if current AddressFamily is IPv6 or IPv4. 51 func (af AddressFamily) IsIP() bool { 52 return af == AddressFamilyIPv4 || af == AddressFamilyIPv6 53 } 54 55 // IsDomain returns true if current AddressFamily is Domain. 56 func (af AddressFamily) IsDomain() bool { 57 return af == AddressFamilyDomain 58 } 59 60 // Address represents a network address to be communicated with. It may be an IP address or domain 61 // address, not both. This interface doesn't resolve IP address for a given domain. 62 type Address interface { 63 IP() net.IP // IP of this Address 64 Domain() string // Domain of this Address 65 Family() AddressFamily 66 67 String() string // String representation of this Address 68 } 69 70 func isAlphaNum(c byte) bool { 71 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') 72 } 73 74 // ParseAddress parses a string into an Address. The return value will be an IPAddress when 75 // the string is in the form of IPv4 or IPv6 address, or a DomainAddress otherwise. 76 func ParseAddress(addr string) Address { 77 // Handle IPv6 address in form as "[2001:4860:0:2001::68]" 78 lenAddr := len(addr) 79 if lenAddr > 0 && addr[0] == '[' && addr[lenAddr-1] == ']' { 80 addr = addr[1 : lenAddr-1] 81 lenAddr -= 2 82 } 83 84 if lenAddr > 0 && (!isAlphaNum(addr[0]) || !isAlphaNum(addr[len(addr)-1])) { 85 addr = strings.TrimSpace(addr) 86 } 87 88 ip := net.ParseIP(addr) 89 if ip != nil { 90 return IPAddress(ip) 91 } 92 return DomainAddress(addr) 93 } 94 95 var bytes0 = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 96 97 // IPAddress creates an Address with given IP. 98 func IPAddress(ip []byte) Address { 99 switch len(ip) { 100 case net.IPv4len: 101 var addr ipv4Address = [4]byte{ip[0], ip[1], ip[2], ip[3]} 102 return addr 103 case net.IPv6len: 104 if bytes.Equal(ip[:10], bytes0) && ip[10] == 0xff && ip[11] == 0xff { 105 return IPAddress(ip[12:16]) 106 } 107 var addr ipv6Address = [16]byte{ 108 ip[0], ip[1], ip[2], ip[3], 109 ip[4], ip[5], ip[6], ip[7], 110 ip[8], ip[9], ip[10], ip[11], 111 ip[12], ip[13], ip[14], ip[15], 112 } 113 return addr 114 default: 115 newError("invalid IP format: ", ip).AtError().WriteToLog() 116 return nil 117 } 118 } 119 120 // DomainAddress creates an Address with given domain. 121 func DomainAddress(domain string) Address { 122 return domainAddress(domain) 123 } 124 125 type ipv4Address [4]byte 126 127 func (a ipv4Address) IP() net.IP { 128 return net.IP(a[:]) 129 } 130 131 func (ipv4Address) Domain() string { 132 panic("Calling Domain() on an IPv4Address.") 133 } 134 135 func (ipv4Address) Family() AddressFamily { 136 return AddressFamilyIPv4 137 } 138 139 func (a ipv4Address) String() string { 140 return a.IP().String() 141 } 142 143 type ipv6Address [16]byte 144 145 func (a ipv6Address) IP() net.IP { 146 return net.IP(a[:]) 147 } 148 149 func (ipv6Address) Domain() string { 150 panic("Calling Domain() on an IPv6Address.") 151 } 152 153 func (ipv6Address) Family() AddressFamily { 154 return AddressFamilyIPv6 155 } 156 157 func (a ipv6Address) String() string { 158 return "[" + a.IP().String() + "]" 159 } 160 161 type domainAddress string 162 163 func (domainAddress) IP() net.IP { 164 panic("Calling IP() on a DomainAddress.") 165 } 166 167 func (a domainAddress) Domain() string { 168 return string(a) 169 } 170 171 func (domainAddress) Family() AddressFamily { 172 return AddressFamilyDomain 173 } 174 175 func (a domainAddress) String() string { 176 return a.Domain() 177 } 178 179 // AsAddress translates IPOrDomain to Address. 180 func (d *IPOrDomain) AsAddress() Address { 181 if d == nil { 182 return nil 183 } 184 switch addr := d.Address.(type) { 185 case *IPOrDomain_Ip: 186 return IPAddress(addr.Ip) 187 case *IPOrDomain_Domain: 188 return DomainAddress(addr.Domain) 189 } 190 panic("Common|Net: Invalid address.") 191 } 192 193 // NewIPOrDomain translates Address to IPOrDomain 194 func NewIPOrDomain(addr Address) *IPOrDomain { 195 switch addr.Family() { 196 case AddressFamilyDomain: 197 return &IPOrDomain{ 198 Address: &IPOrDomain_Domain{ 199 Domain: addr.Domain(), 200 }, 201 } 202 case AddressFamilyIPv4, AddressFamilyIPv6: 203 return &IPOrDomain{ 204 Address: &IPOrDomain_Ip{ 205 Ip: addr.IP(), 206 }, 207 } 208 default: 209 panic("Unknown Address type.") 210 } 211 }