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