address.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package net
  2. import (
  3. "net"
  4. "strconv"
  5. "github.com/v2ray/v2ray-core/common/log"
  6. )
  7. // Address represents a network address to be communicated with. It may be an IP address or domain
  8. // address, not both. This interface doesn't resolve IP address for a given domain.
  9. type Address interface {
  10. IP() net.IP // IP of this Address
  11. Domain() string // Domain of this Address
  12. Port() uint16 // Port of this Address
  13. PortBytes() []byte // Port in bytes, network byte order
  14. IsIPv4() bool // True if this Address is an IPv4 address
  15. IsIPv6() bool // True if this Address is an IPv6 address
  16. IsDomain() bool // True if this Address is an domain address
  17. String() string // String representation of this Address
  18. }
  19. // IPAddress creates an Address with given IP and port.
  20. func IPAddress(ip []byte, port uint16) Address {
  21. switch len(ip) {
  22. case net.IPv4len:
  23. return IPv4Address{
  24. PortAddress: PortAddress{port: port},
  25. ip: [4]byte{ip[0], ip[1], ip[2], ip[3]},
  26. }
  27. case net.IPv6len:
  28. return IPv6Address{
  29. PortAddress: PortAddress{port: port},
  30. ip: [16]byte{
  31. ip[0], ip[1], ip[2], ip[3],
  32. ip[4], ip[5], ip[6], ip[7],
  33. ip[8], ip[9], ip[10], ip[11],
  34. ip[12], ip[13], ip[14], ip[15],
  35. },
  36. }
  37. default:
  38. log.Error("Invalid IP format: %v", ip)
  39. return nil
  40. }
  41. }
  42. // DomainAddress creates an Address with given domain and port.
  43. func DomainAddress(domain string, port uint16) Address {
  44. return DomainAddressImpl{
  45. domain: domain,
  46. PortAddress: PortAddress{port: port},
  47. }
  48. }
  49. type PortAddress struct {
  50. port uint16
  51. }
  52. func (addr PortAddress) Port() uint16 {
  53. return addr.port
  54. }
  55. func (addr PortAddress) PortBytes() []byte {
  56. return []byte{byte(addr.port >> 8), byte(addr.port)}
  57. }
  58. type IPv4Address struct {
  59. PortAddress
  60. ip [4]byte
  61. }
  62. func (addr IPv4Address) IP() net.IP {
  63. return net.IP(addr.ip[:])
  64. }
  65. func (addr IPv4Address) Domain() string {
  66. panic("Calling Domain() on an IPv4Address.")
  67. }
  68. func (addr IPv4Address) IsIPv4() bool {
  69. return true
  70. }
  71. func (addr IPv4Address) IsIPv6() bool {
  72. return false
  73. }
  74. func (addr IPv4Address) IsDomain() bool {
  75. return false
  76. }
  77. func (addr IPv4Address) String() string {
  78. return addr.IP().String() + ":" + strconv.Itoa(int(addr.PortAddress.port))
  79. }
  80. type IPv6Address struct {
  81. PortAddress
  82. ip [16]byte
  83. }
  84. func (addr IPv6Address) IP() net.IP {
  85. return net.IP(addr.ip[:])
  86. }
  87. func (addr IPv6Address) Domain() string {
  88. panic("Calling Domain() on an IPv6Address.")
  89. }
  90. func (addr IPv6Address) IsIPv4() bool {
  91. return false
  92. }
  93. func (addr IPv6Address) IsIPv6() bool {
  94. return true
  95. }
  96. func (addr IPv6Address) IsDomain() bool {
  97. return false
  98. }
  99. func (addr IPv6Address) String() string {
  100. return "[" + addr.IP().String() + "]:" + strconv.Itoa(int(addr.PortAddress.port))
  101. }
  102. type DomainAddressImpl struct {
  103. PortAddress
  104. domain string
  105. }
  106. func (addr DomainAddressImpl) IP() net.IP {
  107. panic("Calling IP() on a DomainAddress.")
  108. }
  109. func (addr DomainAddressImpl) Domain() string {
  110. return addr.domain
  111. }
  112. func (addr DomainAddressImpl) IsIPv4() bool {
  113. return false
  114. }
  115. func (addr DomainAddressImpl) IsIPv6() bool {
  116. return false
  117. }
  118. func (addr DomainAddressImpl) IsDomain() bool {
  119. return true
  120. }
  121. func (addr DomainAddressImpl) String() string {
  122. return addr.domain + ":" + strconv.Itoa(int(addr.PortAddress.port))
  123. }