github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/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  }