|  | @@ -3,66 +3,142 @@ package net
 | 
											
												
													
														|  |  import (
 |  |  import (
 | 
											
												
													
														|  |  	"net"
 |  |  	"net"
 | 
											
												
													
														|  |  	"strconv"
 |  |  	"strconv"
 | 
											
												
													
														|  | -)
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -const (
 |  | 
 | 
											
												
													
														|  | -	AddrTypeIP     = byte(0x01)
 |  | 
 | 
											
												
													
														|  | -	AddrTypeDomain = byte(0x03)
 |  | 
 | 
											
												
													
														|  | 
 |  | +	"github.com/v2ray/v2ray-core/common/log"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -type Address struct {
 |  | 
 | 
											
												
													
														|  | -	Type   byte
 |  | 
 | 
											
												
													
														|  | -	IP     net.IP
 |  | 
 | 
											
												
													
														|  | -	Domain string
 |  | 
 | 
											
												
													
														|  | -	Port   uint16
 |  | 
 | 
											
												
													
														|  | 
 |  | +type Address interface {
 | 
											
												
													
														|  | 
 |  | +	IP() net.IP
 | 
											
												
													
														|  | 
 |  | +	Domain() string
 | 
											
												
													
														|  | 
 |  | +	Port() uint16
 | 
											
												
													
														|  | 
 |  | +	PortBytes() []byte
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	IsIPv4() bool
 | 
											
												
													
														|  | 
 |  | +	IsIPv6() bool
 | 
											
												
													
														|  | 
 |  | +	IsDomain() bool
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	String() string
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func IPAddress(ip []byte, port uint16) Address {
 |  |  func IPAddress(ip []byte, port uint16) Address {
 | 
											
												
													
														|  | -	ipCopy := make([]byte, len(ip))
 |  | 
 | 
											
												
													
														|  | -	copy(ipCopy, ip)
 |  | 
 | 
											
												
													
														|  | -	// TODO: check IP length
 |  | 
 | 
											
												
													
														|  | -	return Address{
 |  | 
 | 
											
												
													
														|  | -		Type:   AddrTypeIP,
 |  | 
 | 
											
												
													
														|  | -		IP:     net.IP(ipCopy),
 |  | 
 | 
											
												
													
														|  | -		Domain: "",
 |  | 
 | 
											
												
													
														|  | -		Port:   port,
 |  | 
 | 
											
												
													
														|  | 
 |  | +	switch len(ip) {
 | 
											
												
													
														|  | 
 |  | +	case net.IPv4len:
 | 
											
												
													
														|  | 
 |  | +		return IPv4Address{
 | 
											
												
													
														|  | 
 |  | +			PortAddress: PortAddress{port: port},
 | 
											
												
													
														|  | 
 |  | +			ip:          [4]byte{ip[0], ip[1], ip[2], ip[3]},
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	case net.IPv6len:
 | 
											
												
													
														|  | 
 |  | +		return IPv6Address{
 | 
											
												
													
														|  | 
 |  | +			PortAddress: PortAddress{port: port},
 | 
											
												
													
														|  | 
 |  | +			ip:          [16]byte{ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]},
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	default:
 | 
											
												
													
														|  | 
 |  | +		panic(log.Error("Unknown IP format: %v", ip))
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func DomainAddress(domain string, port uint16) Address {
 |  |  func DomainAddress(domain string, port uint16) Address {
 | 
											
												
													
														|  | -	return Address{
 |  | 
 | 
											
												
													
														|  | -		Type:   AddrTypeDomain,
 |  | 
 | 
											
												
													
														|  | -		IP:     nil,
 |  | 
 | 
											
												
													
														|  | -		Domain: domain,
 |  | 
 | 
											
												
													
														|  | -		Port:   port,
 |  | 
 | 
											
												
													
														|  | 
 |  | +	return DomainAddressImpl{
 | 
											
												
													
														|  | 
 |  | +		domain:      domain,
 | 
											
												
													
														|  | 
 |  | +		PortAddress: PortAddress{port: port},
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (addr Address) IsIPv4() bool {
 |  | 
 | 
											
												
													
														|  | -	return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv4len
 |  | 
 | 
											
												
													
														|  | 
 |  | +type PortAddress struct {
 | 
											
												
													
														|  | 
 |  | +	port uint16
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (addr Address) IsIPv6() bool {
 |  | 
 | 
											
												
													
														|  | -	return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv6len
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (addr PortAddress) Port() uint16 {
 | 
											
												
													
														|  | 
 |  | +	return addr.port
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (addr Address) IsDomain() bool {
 |  | 
 | 
											
												
													
														|  | -	return addr.Type == AddrTypeDomain
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (addr PortAddress) PortBytes() []byte {
 | 
											
												
													
														|  | 
 |  | +	return []byte{byte(addr.port >> 8), byte(addr.port)}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (addr Address) String() string {
 |  | 
 | 
											
												
													
														|  | -	var host string
 |  | 
 | 
											
												
													
														|  | -	switch addr.Type {
 |  | 
 | 
											
												
													
														|  | -	case AddrTypeIP:
 |  | 
 | 
											
												
													
														|  | -		host = addr.IP.String()
 |  | 
 | 
											
												
													
														|  | -		if len(addr.IP) == net.IPv6len {
 |  | 
 | 
											
												
													
														|  | -			host = "[" + host + "]"
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | 
 |  | +type IPv4Address struct {
 | 
											
												
													
														|  | 
 |  | +	PortAddress
 | 
											
												
													
														|  | 
 |  | +	ip [4]byte
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	case AddrTypeDomain:
 |  | 
 | 
											
												
													
														|  | -		host = addr.Domain
 |  | 
 | 
											
												
													
														|  | -	default:
 |  | 
 | 
											
												
													
														|  | -		panic("Unknown Address Type " + strconv.Itoa(int(addr.Type)))
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	return host + ":" + strconv.Itoa(int(addr.Port))
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) IP() net.IP {
 | 
											
												
													
														|  | 
 |  | +	return net.IP(addr.ip[:])
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) Domain() string {
 | 
											
												
													
														|  | 
 |  | +	panic("Calling Domain() on an IPv4Address.")
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) IsIPv4() bool {
 | 
											
												
													
														|  | 
 |  | +	return true
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) IsIPv6() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) IsDomain() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv4Address) String() string {
 | 
											
												
													
														|  | 
 |  | +	return addr.IP().String() + ":" + strconv.Itoa(int(addr.PortAddress.port))
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type IPv6Address struct {
 | 
											
												
													
														|  | 
 |  | +	PortAddress
 | 
											
												
													
														|  | 
 |  | +	ip [16]byte
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) IP() net.IP {
 | 
											
												
													
														|  | 
 |  | +	return net.IP(addr.ip[:])
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) Domain() string {
 | 
											
												
													
														|  | 
 |  | +	panic("Calling Domain() on an IPv6Address.")
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) IsIPv4() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) IsIPv6() bool {
 | 
											
												
													
														|  | 
 |  | +	return true
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) IsDomain() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr IPv6Address) String() string {
 | 
											
												
													
														|  | 
 |  | +	return "[" + addr.IP().String() + "]:" + strconv.Itoa(int(addr.PortAddress.port))
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type DomainAddressImpl struct {
 | 
											
												
													
														|  | 
 |  | +	PortAddress
 | 
											
												
													
														|  | 
 |  | +	domain string
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) IP() net.IP {
 | 
											
												
													
														|  | 
 |  | +	panic("Calling IP() on a DomainAddress.")
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) Domain() string {
 | 
											
												
													
														|  | 
 |  | +	return addr.domain
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) IsIPv4() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) IsIPv6() bool {
 | 
											
												
													
														|  | 
 |  | +	return false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) IsDomain() bool {
 | 
											
												
													
														|  | 
 |  | +	return true
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (addr DomainAddressImpl) String() string {
 | 
											
												
													
														|  | 
 |  | +	return addr.domain + ":" + strconv.Itoa(int(addr.PortAddress.port))
 | 
											
												
													
														|  |  }
 |  |  }
 |