Browse Source

move port out of address

v2ray 10 years ago
parent
commit
34a0cb0b70

+ 1 - 1
app/router/router_test.go

@@ -24,7 +24,7 @@ func TestRouter(t *testing.T) {
 	router, err := CreateRouter(pointConfig.RouterConfig().Strategy(), pointConfig.RouterConfig().Settings())
 	assert.Error(err).IsNil()
 
-	dest := v2net.NewTCPDestination(v2net.IPAddress(net.ParseIP("120.135.126.1"), 80))
+	dest := v2net.TCPDestination(v2net.IPAddress(net.ParseIP("120.135.126.1")), 80)
 	tag, err := router.TakeDetour(dest)
 	assert.Error(err).IsNil()
 	assert.StringLiteral(tag).Equals("direct")

+ 1 - 1
app/router/rules/json/chinaip_test.go

@@ -10,7 +10,7 @@ import (
 )
 
 func makeDestination(ip string) v2net.Destination {
-	return v2net.NewTCPDestination(v2net.IPAddress(net.ParseIP(ip), 80))
+	return v2net.TCPDestination(v2net.IPAddress(net.ParseIP(ip)), 80)
 }
 
 func TestChinaIP(t *testing.T) {

+ 1 - 1
app/router/rules/json/chinasites_test.go

@@ -9,7 +9,7 @@ import (
 )
 
 func makeDomainDestination(domain string) v2net.Destination {
-	return v2net.NewTCPDestination(v2net.DomainAddress(domain, 80))
+	return v2net.TCPDestination(v2net.DomainAddress(domain), 80)
 }
 
 func TestChinaSites(t *testing.T) {

+ 1 - 1
app/router/rules/json/fieldrule.go

@@ -121,7 +121,7 @@ func (this *FieldRule) Apply(dest v2net.Destination) bool {
 	}
 
 	if this.Port != nil {
-		port := address.Port()
+		port := dest.Port()
 		if port.Value() < this.Port.From().Value() || port.Value() > this.Port.To().Value() {
 			return false
 		}

+ 8 - 8
app/router/rules/json/fieldrule_test.go

@@ -39,7 +39,7 @@ func TestDomainMatching(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80))
+	dest := v2net.TCPDestination(v2net.DomainAddress("www.v2ray.com"), 80)
 	assert.Bool(rule.Apply(dest)).IsTrue()
 }
 
@@ -52,7 +52,7 @@ func TestPortMatching(t *testing.T) {
 			ToValue:   100,
 		},
 	}
-	dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80))
+	dest := v2net.TCPDestination(v2net.DomainAddress("www.v2ray.com"), 80)
 	assert.Bool(rule.Apply(dest)).IsTrue()
 }
 
@@ -65,7 +65,7 @@ func TestIPMatching(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}, 80))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80)
 	assert.Bool(rule.Apply(dest)).IsTrue()
 }
 
@@ -78,7 +78,7 @@ func TestIPListMatching(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{192, 168, 1, 1}, 80))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{192, 168, 1, 1}), 80)
 	assert.Bool(rule.Apply(dest)).IsTrue()
 }
 
@@ -91,7 +91,7 @@ func TestPortNotMatching(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}, 79))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 79)
 	assert.Bool(rule.Apply(dest)).IsFalse()
 }
 
@@ -104,7 +104,7 @@ func TestDomainNotMatching(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}, 80))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80)
 	assert.Bool(rule.Apply(dest)).IsFalse()
 }
 
@@ -117,9 +117,9 @@ func TestDomainNotMatchingDomain(t *testing.T) {
     "tag": "test"
   }`
 	rule := parseRule([]byte(rawJson))
-	dest := v2net.NewTCPDestination(v2net.DomainAddress("baidu.com", 80))
+	dest := v2net.TCPDestination(v2net.DomainAddress("baidu.com"), 80)
 	assert.Bool(rule.Apply(dest)).IsFalse()
 
-	dest = v2net.NewTCPDestination(v2net.DomainAddress("www.google.com", 80))
+	dest = v2net.TCPDestination(v2net.DomainAddress("www.google.com"), 80)
 	assert.Bool(rule.Apply(dest)).IsTrue()
 }

+ 1 - 1
app/router/rules/router_test.go

@@ -21,7 +21,7 @@ func TestSimpleRouter(t *testing.T) {
 			},
 		})
 
-	tag, err := router.TakeDetour(v2net.NewTCPDestination(v2net.DomainAddress("v2ray.com", 80)))
+	tag, err := router.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80))
 	assert.Error(err).IsNil()
 	assert.StringLiteral(tag).Equals("test")
 }

+ 12 - 28
common/net/address.go

@@ -11,7 +11,6 @@ import (
 type Address interface {
 	IP() net.IP     // IP of this Address
 	Domain() string // Domain of this Address
-	Port() Port     // Port of this Address
 
 	IsIPv4() bool   // True if this Address is an IPv4 address
 	IsIPv6() bool   // True if this Address is an IPv6 address
@@ -30,19 +29,17 @@ func allZeros(data []byte) bool {
 }
 
 // IPAddress creates an Address with given IP and port.
-func IPAddress(ip []byte, port Port) Address {
+func IPAddress(ip []byte) Address {
 	switch len(ip) {
 	case net.IPv4len:
 		return &IPv4Address{
-			port: port,
-			ip:   [4]byte{ip[0], ip[1], ip[2], ip[3]},
+			ip: [4]byte{ip[0], ip[1], ip[2], ip[3]},
 		}
 	case net.IPv6len:
 		if allZeros(ip[0:10]) && ip[10] == 0xff && ip[11] == 0xff {
-			return IPAddress(ip[12:16], port)
+			return IPAddress(ip[12:16])
 		}
 		return &IPv6Address{
-			port: Port(port),
 			ip: [16]byte{
 				ip[0], ip[1], ip[2], ip[3],
 				ip[4], ip[5], ip[6], ip[7],
@@ -57,26 +54,23 @@ func IPAddress(ip []byte, port Port) Address {
 }
 
 // DomainAddress creates an Address with given domain and port.
-func DomainAddress(domain string, port Port) Address {
+func DomainAddress(domain string) Address {
 	return &DomainAddressImpl{
 		domain: domain,
-		port:   port,
 	}
 }
 
+type address struct {
+}
+
 type IPv4Address struct {
-	port Port
-	ip   [4]byte
+	ip [4]byte
 }
 
 func (addr *IPv4Address) IP() net.IP {
 	return net.IP(addr.ip[:])
 }
 
-func (this *IPv4Address) Port() Port {
-	return this.port
-}
-
 func (addr *IPv4Address) Domain() string {
 	panic("Calling Domain() on an IPv4Address.")
 }
@@ -94,22 +88,17 @@ func (addr *IPv4Address) IsDomain() bool {
 }
 
 func (this *IPv4Address) String() string {
-	return this.IP().String() + ":" + this.port.String()
+	return this.IP().String()
 }
 
 type IPv6Address struct {
-	port Port
-	ip   [16]byte
+	ip [16]byte
 }
 
 func (addr *IPv6Address) IP() net.IP {
 	return net.IP(addr.ip[:])
 }
 
-func (this *IPv6Address) Port() Port {
-	return this.port
-}
-
 func (addr *IPv6Address) Domain() string {
 	panic("Calling Domain() on an IPv6Address.")
 }
@@ -127,11 +116,10 @@ func (addr *IPv6Address) IsDomain() bool {
 }
 
 func (this *IPv6Address) String() string {
-	return "[" + this.IP().String() + "]:" + this.port.String()
+	return "[" + this.IP().String() + "]"
 }
 
 type DomainAddressImpl struct {
-	port   Port
 	domain string
 }
 
@@ -139,10 +127,6 @@ func (addr *DomainAddressImpl) IP() net.IP {
 	panic("Calling IP() on a DomainAddress.")
 }
 
-func (this *DomainAddressImpl) Port() Port {
-	return this.port
-}
-
 func (addr *DomainAddressImpl) Domain() string {
 	return addr.domain
 }
@@ -160,5 +144,5 @@ func (addr *DomainAddressImpl) IsDomain() bool {
 }
 
 func (this *DomainAddressImpl) String() string {
-	return this.domain + ":" + this.port.String()
+	return this.domain
 }

+ 8 - 15
common/net/address_test.go

@@ -14,15 +14,13 @@ func TestIPv4Address(t *testing.T) {
 	v2testing.Current(t)
 
 	ip := []byte{byte(1), byte(2), byte(3), byte(4)}
-	port := v2net.Port(80)
-	addr := v2net.IPAddress(ip, port)
+	addr := v2net.IPAddress(ip)
 
 	v2netassert.Address(addr).IsIPv4()
 	v2netassert.Address(addr).IsNotIPv6()
 	v2netassert.Address(addr).IsNotDomain()
 	assert.Bytes(addr.IP()).Equals(ip)
-	v2netassert.Port(addr.Port()).Equals(port)
-	assert.String(addr).Equals("1.2.3.4:80")
+	assert.String(addr).Equals("1.2.3.4")
 }
 
 func TestIPv6Address(t *testing.T) {
@@ -34,38 +32,33 @@ func TestIPv6Address(t *testing.T) {
 		byte(1), byte(2), byte(3), byte(4),
 		byte(1), byte(2), byte(3), byte(4),
 	}
-	port := v2net.Port(443)
-	addr := v2net.IPAddress(ip, port)
+	addr := v2net.IPAddress(ip)
 
 	v2netassert.Address(addr).IsIPv6()
 	v2netassert.Address(addr).IsNotIPv4()
 	v2netassert.Address(addr).IsNotDomain()
 	assert.Bytes(addr.IP()).Equals(ip)
-	v2netassert.Port(addr.Port()).Equals(port)
-	assert.String(addr).Equals("[102:304:102:304:102:304:102:304]:443")
+	assert.String(addr).Equals("[102:304:102:304:102:304:102:304]")
 }
 
 func TestDomainAddress(t *testing.T) {
 	v2testing.Current(t)
 
 	domain := "v2ray.com"
-	port := v2net.Port(443)
-	addr := v2net.DomainAddress(domain, port)
+	addr := v2net.DomainAddress(domain)
 
 	v2netassert.Address(addr).IsDomain()
 	v2netassert.Address(addr).IsNotIPv6()
 	v2netassert.Address(addr).IsNotIPv4()
 	assert.StringLiteral(addr.Domain()).Equals(domain)
-	v2netassert.Port(addr.Port()).Equals(port)
-	assert.String(addr).Equals("v2ray.com:443")
+	assert.String(addr).Equals("v2ray.com")
 }
 
 func TestNetIPv4Address(t *testing.T) {
 	v2testing.Current(t)
 
 	ip := net.IPv4(1, 2, 3, 4)
-	port := v2net.Port(80)
-	addr := v2net.IPAddress(ip, port)
+	addr := v2net.IPAddress(ip)
 	v2netassert.Address(addr).IsIPv4()
-	assert.String(addr).Equals("1.2.3.4:80")
+	assert.String(addr).Equals("1.2.3.4")
 }

+ 41 - 21
common/net/destination.go

@@ -4,66 +4,86 @@ package net
 type Destination interface {
 	Network() string  // Protocol of communication (tcp / udp)
 	Address() Address // Address of destination
-	String() string   // String representation of the destination
+	Port() Port
+	String() string // String representation of the destination
+	NetAddr() string
 
 	IsTCP() bool // True if destination is reachable via TCP
 	IsUDP() bool // True if destination is reachable via UDP
 }
 
-// NewTCPDestination creates a TCP destination with given address
-func NewTCPDestination(address Address) Destination {
-	return TCPDestination{address: address}
+// TCPDestination creates a TCP destination with given address
+func TCPDestination(address Address, port Port) Destination {
+	return &tcpDestination{address: address, port: port}
 }
 
-// NewUDPDestination creates a UDP destination with given address
-func NewUDPDestination(address Address) Destination {
-	return UDPDestination{address: address}
+// UDPDestination creates a UDP destination with given address
+func UDPDestination(address Address, port Port) Destination {
+	return &udpDestination{address: address, port: port}
 }
 
-type TCPDestination struct {
+type tcpDestination struct {
 	address Address
+	port    Port
 }
 
-func (dest TCPDestination) Network() string {
+func (dest *tcpDestination) Network() string {
 	return "tcp"
 }
 
-func (dest TCPDestination) Address() Address {
+func (dest *tcpDestination) Address() Address {
 	return dest.address
 }
 
-func (dest TCPDestination) String() string {
-	return "tcp:" + dest.address.String()
+func (dest *tcpDestination) NetAddr() string {
+	return dest.address.String() + ":" + dest.port.String()
 }
 
-func (dest TCPDestination) IsTCP() bool {
+func (dest *tcpDestination) String() string {
+	return "tcp:" + dest.NetAddr()
+}
+
+func (dest *tcpDestination) IsTCP() bool {
 	return true
 }
 
-func (dest TCPDestination) IsUDP() bool {
+func (dest *tcpDestination) IsUDP() bool {
 	return false
 }
 
-type UDPDestination struct {
+func (dest *tcpDestination) Port() Port {
+	return dest.port
+}
+
+type udpDestination struct {
 	address Address
+	port    Port
 }
 
-func (dest UDPDestination) Network() string {
+func (dest *udpDestination) Network() string {
 	return "udp"
 }
 
-func (dest UDPDestination) Address() Address {
+func (dest *udpDestination) Address() Address {
 	return dest.address
 }
 
-func (dest UDPDestination) String() string {
-	return "udp:" + dest.address.String()
+func (dest *udpDestination) NetAddr() string {
+	return dest.address.String() + ":" + dest.port.String()
 }
 
-func (dest UDPDestination) IsTCP() bool {
+func (dest *udpDestination) String() string {
+	return "udp:" + dest.NetAddr()
+}
+
+func (dest *udpDestination) IsTCP() bool {
 	return false
 }
 
-func (dest UDPDestination) IsUDP() bool {
+func (dest *udpDestination) IsUDP() bool {
 	return true
 }
+
+func (dest *udpDestination) Port() Port {
+	return dest.port
+}

+ 2 - 2
common/net/destination_test.go

@@ -12,7 +12,7 @@ import (
 func TestTCPDestination(t *testing.T) {
 	v2testing.Current(t)
 
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}, 80))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	v2netassert.Destination(dest).IsTCP()
 	v2netassert.Destination(dest).IsNotUDP()
 	assert.String(dest).Equals("tcp:1.2.3.4:80")
@@ -21,7 +21,7 @@ func TestTCPDestination(t *testing.T) {
 func TestUDPDestination(t *testing.T) {
 	v2testing.Current(t)
 
-	dest := v2net.NewUDPDestination(v2net.IPAddress([]byte{0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}, 53))
+	dest := v2net.UDPDestination(v2net.IPAddress([]byte{0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}), 53)
 	v2netassert.Destination(dest).IsNotTCP()
 	v2netassert.Destination(dest).IsUDP()
 	assert.String(dest).Equals("udp:[2001:4860:4860::8888]:53")

+ 1 - 0
proxy/dokodemo/config.go

@@ -6,6 +6,7 @@ import (
 
 type Config interface {
 	Address() v2net.Address
+	Port() v2net.Port
 	Network() v2net.NetworkList
 	Timeout() int
 }

+ 4 - 2
proxy/dokodemo/dokodemo.go

@@ -16,6 +16,7 @@ type DokodemoDoor struct {
 	config    Config
 	accepting bool
 	address   v2net.Address
+	port      v2net.Port
 	space     app.Space
 }
 
@@ -24,6 +25,7 @@ func NewDokodemoDoor(space app.Space, config Config) *DokodemoDoor {
 		config:  config,
 		space:   space,
 		address: config.Address(),
+		port:    config.Port(),
 	}
 }
 
@@ -71,7 +73,7 @@ func (this *DokodemoDoor) handleUDPPackets(udpConn *net.UDPConn) {
 			return
 		}
 
-		packet := v2net.NewPacket(v2net.NewUDPDestination(this.address), buffer, false)
+		packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), buffer, false)
 		ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
 		close(ray.InboundInput())
 
@@ -112,7 +114,7 @@ func (this *DokodemoDoor) AcceptTCPConnections(tcpListener *net.TCPListener) {
 func (this *DokodemoDoor) HandleTCPConnection(conn *net.TCPConn) {
 	defer conn.Close()
 
-	packet := v2net.NewPacket(v2net.NewTCPDestination(this.address), nil, true)
+	packet := v2net.NewPacket(v2net.TCPDestination(this.address, this.port), nil, true)
 	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
 
 	var inputFinish, outputFinish sync.Mutex

+ 2 - 2
proxy/dokodemo/dokodemo_test.go

@@ -43,7 +43,7 @@ func TestDokodemoTCP(t *testing.T) {
 			ProtocolValue: "dokodemo-door",
 			SettingsValue: &json.DokodemoConfig{
 				Host:         v2netjson.NewIPHost(net.ParseIP("127.0.0.1")),
-				Port:         port,
+				PortValue:    port,
 				NetworkList:  &networkList,
 				TimeoutValue: 0,
 			},
@@ -105,7 +105,7 @@ func TestDokodemoUDP(t *testing.T) {
 			ProtocolValue: "dokodemo-door",
 			SettingsValue: &json.DokodemoConfig{
 				Host:         v2netjson.NewIPHost(net.ParseIP("127.0.0.1")),
-				Port:         port,
+				PortValue:    port,
 				NetworkList:  &networkList,
 				TimeoutValue: 0,
 			},

+ 7 - 3
proxy/dokodemo/json/json.go

@@ -8,19 +8,23 @@ import (
 
 type DokodemoConfig struct {
 	Host         *v2netjson.Host        `json:"address"`
-	Port         v2net.Port             `json:"port"`
+	PortValue    v2net.Port             `json:"port"`
 	NetworkList  *v2netjson.NetworkList `json:"network"`
 	TimeoutValue int                    `json:"timeout"`
 }
 
 func (this *DokodemoConfig) Address() v2net.Address {
 	if this.Host.IsIP() {
-		return v2net.IPAddress(this.Host.IP(), this.Port)
+		return v2net.IPAddress(this.Host.IP())
 	} else {
-		return v2net.DomainAddress(this.Host.Domain(), this.Port)
+		return v2net.DomainAddress(this.Host.Domain())
 	}
 }
 
+func (this *DokodemoConfig) Port() v2net.Port {
+	return this.PortValue
+}
+
 func (this *DokodemoConfig) Network() v2net.NetworkList {
 	return this.NetworkList
 }

+ 1 - 1
proxy/freedom/freedom.go

@@ -15,7 +15,7 @@ type FreedomConnection struct {
 }
 
 func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
-	conn, err := net.Dial(firstPacket.Destination().Network(), firstPacket.Destination().Address().String())
+	conn, err := net.Dial(firstPacket.Destination().Network(), firstPacket.Destination().NetAddr())
 	log.Info("Freedom: Opening connection to %s", firstPacket.Destination().String())
 	if err != nil {
 		close(ray.OutboundOutput())

+ 1 - 2
proxy/freedom/freedom_test.go

@@ -70,8 +70,7 @@ func TestUDPSend(t *testing.T) {
 
 	data2SendBuffer := alloc.NewBuffer().Clear()
 	data2SendBuffer.Append([]byte(data2Send))
-	dest := v2net.NewUDPDestination(udpServerAddr)
-	ich.Communicate(v2net.NewPacket(dest, data2SendBuffer, false))
+	ich.Communicate(v2net.NewPacket(udpServerAddr, data2SendBuffer, false))
 	assert.Bytes(connOutput.Bytes()).Equals([]byte("Processed: Data to be sent to remote"))
 }
 

+ 8 - 8
proxy/http/http.go

@@ -53,7 +53,7 @@ func (this *HttpProxyServer) accept(listener *net.TCPListener) {
 	}
 }
 
-func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Address, error) {
+func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error) {
 	port := defaultPort
 	host, rawPort, err := net.SplitHostPort(rawHost)
 	if err != nil {
@@ -71,9 +71,9 @@ func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Address, error) {
 	}
 
 	if ip := net.ParseIP(host); ip != nil {
-		return v2net.IPAddress(ip, port), nil
+		return v2net.TCPDestination(v2net.IPAddress(ip), port), nil
 	}
-	return v2net.DomainAddress(host, port), nil
+	return v2net.TCPDestination(v2net.DomainAddress(host), port), nil
 }
 
 func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {
@@ -93,12 +93,12 @@ func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {
 		if len(host) == 0 {
 			host = request.URL.Host
 		}
-		address, err := parseHost(host, defaultPort)
+		dest, err := parseHost(host, defaultPort)
 		if err != nil {
 			log.Warning("Malformed proxy host (%s): %v", host, err)
 		}
 		if strings.ToUpper(request.Method) == "CONNECT" {
-			this.handleConnect(request, address, reader, conn)
+			this.handleConnect(request, dest, reader, conn)
 		} else if len(request.URL.Host) > 0 {
 			request.Host = request.URL.Host
 			request.Header.Set("Connection", "keep-alive")
@@ -106,7 +106,7 @@ func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {
 			buffer := alloc.NewBuffer().Clear()
 			request.Write(buffer)
 			log.Info("Request to remote: %s", string(buffer.Value))
-			packet := v2net.NewPacket(v2net.NewTCPDestination(address), buffer, true)
+			packet := v2net.NewPacket(dest, buffer, true)
 			ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
 			go func() {
 				defer close(ray.InboundInput())
@@ -142,7 +142,7 @@ func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {
 	}
 }
 
-func (this *HttpProxyServer) handleConnect(request *http.Request, address v2net.Address, reader io.Reader, writer io.Writer) {
+func (this *HttpProxyServer) handleConnect(request *http.Request, destination v2net.Destination, reader io.Reader, writer io.Writer) {
 	response := &http.Response{
 		Status:        "200 OK",
 		StatusCode:    200,
@@ -160,7 +160,7 @@ func (this *HttpProxyServer) handleConnect(request *http.Request, address v2net.
 	writer.Write(buffer.Value)
 	buffer.Release()
 
-	packet := v2net.NewPacket(v2net.NewTCPDestination(address), nil, true)
+	packet := v2net.NewPacket(destination, nil, true)
 	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
 	this.transport(reader, writer, ray)
 }

+ 4 - 6
proxy/socks/protocol/socks.go

@@ -261,23 +261,21 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
 }
 
 func (request *Socks5Request) Destination() v2net.Destination {
-	var address v2net.Address
 	switch request.AddrType {
 	case AddrTypeIPv4:
-		address = v2net.IPAddress(request.IPv4[:], request.Port)
+		return v2net.TCPDestination(v2net.IPAddress(request.IPv4[:]), request.Port)
 	case AddrTypeIPv6:
-		address = v2net.IPAddress(request.IPv6[:], request.Port)
+		return v2net.TCPDestination(v2net.IPAddress(request.IPv6[:]), request.Port)
 	case AddrTypeDomain:
 		maybeIP := net.ParseIP(request.Domain)
 		if maybeIP != nil {
-			address = v2net.IPAddress(maybeIP, request.Port)
+			return v2net.TCPDestination(v2net.IPAddress(maybeIP), request.Port)
 		} else {
-			address = v2net.DomainAddress(request.Domain, request.Port)
+			return v2net.TCPDestination(v2net.DomainAddress(request.Domain), request.Port)
 		}
 	default:
 		panic("Unknown address type")
 	}
-	return v2net.NewTCPDestination(address)
 }
 
 const (

+ 10 - 9
proxy/socks/protocol/udp.go

@@ -17,11 +17,12 @@ var (
 type Socks5UDPRequest struct {
 	Fragment byte
 	Address  v2net.Address
+	Port     v2net.Port
 	Data     *alloc.Buffer
 }
 
 func (request *Socks5UDPRequest) Destination() v2net.Destination {
-	return v2net.NewUDPDestination(request.Address)
+	return v2net.UDPDestination(request.Address, request.Port)
 }
 
 func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) {
@@ -34,7 +35,7 @@ func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) {
 	case request.Address.IsDomain():
 		buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))).Append([]byte(request.Address.Domain()))
 	}
-	buffer.Append(request.Address.Port().Bytes())
+	buffer.Append(request.Port.Bytes())
 	buffer.Append(request.Data.Value)
 }
 
@@ -56,16 +57,16 @@ func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
 			return nil, transport.CorruptedPacket
 		}
 		ip := packet[4:8]
-		port := v2net.PortFromBytes(packet[8:10])
-		request.Address = v2net.IPAddress(ip, port)
+		request.Port = v2net.PortFromBytes(packet[8:10])
+		request.Address = v2net.IPAddress(ip)
 		dataBegin = 10
 	case AddrTypeIPv6:
 		if len(packet) < 22 {
 			return nil, transport.CorruptedPacket
 		}
 		ip := packet[4:20]
-		port := v2net.PortFromBytes(packet[20:22])
-		request.Address = v2net.IPAddress(ip, port)
+		request.Port = v2net.PortFromBytes(packet[20:22])
+		request.Address = v2net.IPAddress(ip)
 		dataBegin = 22
 	case AddrTypeDomain:
 		domainLength := int(packet[4])
@@ -73,12 +74,12 @@ func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
 			return nil, transport.CorruptedPacket
 		}
 		domain := string(packet[5 : 5+domainLength])
-		port := v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
+		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
 		maybeIP := net.ParseIP(domain)
 		if maybeIP != nil {
-			request.Address = v2net.IPAddress(maybeIP, port)
+			request.Address = v2net.IPAddress(maybeIP)
 		} else {
-			request.Address = v2net.DomainAddress(domain, port)
+			request.Address = v2net.DomainAddress(domain)
 		}
 		dataBegin = 5 + domainLength + 2
 	default:

+ 4 - 1
proxy/socks/protocol/udp_test.go

@@ -3,6 +3,8 @@ package protocol
 import (
 	"testing"
 
+	v2net "github.com/v2ray/v2ray-core/common/net"
+	netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
 	v2testing "github.com/v2ray/v2ray-core/testing"
 	"github.com/v2ray/v2ray-core/testing/assert"
 	"github.com/v2ray/v2ray-core/transport"
@@ -31,6 +33,7 @@ func TestDomainAddressRequest(t *testing.T) {
 	assert.Error(err).IsNil()
 
 	assert.Byte(request.Fragment).Equals(1)
-	assert.String(request.Address).Equals("v2ray.com:80")
+	assert.String(request.Address).Equals("v2ray.com")
+	netassert.Port(request.Port).Equals(v2net.Port(80))
 	assert.Bytes(request.Data.Value).Equals([]byte("Actual payload"))
 }

+ 7 - 7
proxy/socks/socks.go

@@ -191,12 +191,12 @@ func (this *SocksServer) handleUDP(reader *v2net.TimeOutReader, writer io.Writer
 
 	response.Port = udpAddr.Port()
 	switch {
-	case udpAddr.IsIPv4():
-		response.SetIPv4(udpAddr.IP())
-	case udpAddr.IsIPv6():
-		response.SetIPv6(udpAddr.IP())
-	case udpAddr.IsDomain():
-		response.SetDomain(udpAddr.Domain())
+	case udpAddr.Address().IsIPv4():
+		response.SetIPv4(udpAddr.Address().IP())
+	case udpAddr.Address().IsIPv6():
+		response.SetIPv6(udpAddr.Address().IP())
+	case udpAddr.Address().IsDomain():
+		response.SetDomain(udpAddr.Address().Domain())
 	}
 
 	responseBuffer := alloc.NewSmallBuffer().Clear()
@@ -236,7 +236,7 @@ func (this *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth p
 		return UnsupportedSocksCommand
 	}
 
-	dest := v2net.NewTCPDestination(v2net.IPAddress(auth.IP[:], auth.Port))
+	dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port)
 	packet := v2net.NewPacket(dest, nil, true)
 	this.transport(reader, writer, packet)
 	return nil

+ 2 - 2
proxy/socks/socks_test.go

@@ -71,7 +71,7 @@ func TestSocksTcpConnect(t *testing.T) {
 
 	assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
 	assert.Bytes(dataReturned).Equals(connInput)
-	assert.StringLiteral(targetServer).Equals(och.Destination.Address().String())
+	assert.StringLiteral(targetServer).Equals(och.Destination.NetAddr())
 }
 
 func TestSocksTcpConnectWithUserPass(t *testing.T) {
@@ -129,7 +129,7 @@ func TestSocksTcpConnectWithUserPass(t *testing.T) {
 
 	assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
 	assert.Bytes(dataReturned).Equals(connInput)
-	assert.StringLiteral(targetServer).Equals(och.Destination.Address().String())
+	assert.StringLiteral(targetServer).Equals(och.Destination.NetAddr())
 }
 
 func TestSocksTcpConnectWithWrongUserPass(t *testing.T) {

+ 6 - 5
proxy/socks/udp.go

@@ -9,7 +9,7 @@ import (
 	"github.com/v2ray/v2ray-core/proxy/socks/protocol"
 )
 
-var udpAddress v2net.Address
+var udpAddress v2net.Destination
 
 func (this *SocksServer) ListenUDP(port v2net.Port) error {
 	addr := &net.UDPAddr{
@@ -22,13 +22,13 @@ func (this *SocksServer) ListenUDP(port v2net.Port) error {
 		log.Error("Socks failed to listen UDP on port %d: %v", port, err)
 		return err
 	}
-	udpAddress = v2net.IPAddress(this.config.IP(), port)
+	udpAddress = v2net.UDPDestination(v2net.IPAddress(this.config.IP()), port)
 
 	go this.AcceptPackets(conn)
 	return nil
 }
 
-func (this *SocksServer) getUDPAddr() v2net.Address {
+func (this *SocksServer) getUDPAddr() v2net.Destination {
 	return udpAddress
 }
 
@@ -60,11 +60,11 @@ func (this *SocksServer) AcceptPackets(conn *net.UDPConn) error {
 
 		udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
 		log.Info("Send packet to %s with %d bytes", udpPacket.Destination().String(), request.Data.Len())
-		go this.handlePacket(conn, udpPacket, addr, request.Address)
+		go this.handlePacket(conn, udpPacket, addr, request.Address, request.Port)
 	}
 }
 
-func (this *SocksServer) handlePacket(conn *net.UDPConn, packet v2net.Packet, clientAddr *net.UDPAddr, targetAddr v2net.Address) {
+func (this *SocksServer) handlePacket(conn *net.UDPConn, packet v2net.Packet, clientAddr *net.UDPAddr, targetAddr v2net.Address, port v2net.Port) {
 	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
 	close(ray.InboundInput())
 
@@ -72,6 +72,7 @@ func (this *SocksServer) handlePacket(conn *net.UDPConn, packet v2net.Packet, cl
 		response := &protocol.Socks5UDPRequest{
 			Fragment: 0,
 			Address:  targetAddr,
+			Port:     port,
 			Data:     data,
 		}
 		log.Info("Writing back UDP response with %d bytes from %s to %s", data.Len(), targetAddr.String(), clientAddr.String())

+ 6 - 6
proxy/vmess/outbound/json/outbound.go

@@ -14,8 +14,8 @@ import (
 )
 
 type ConfigTarget struct {
-	Address v2net.Address
-	Users   []*vmessjson.ConfigUser
+	Destination v2net.Destination
+	Users       []*vmessjson.ConfigUser
 }
 
 func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
@@ -38,9 +38,9 @@ func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
 		return proxyconfig.BadConfiguration
 	}
 	if rawConfig.Address.IsIP() {
-		t.Address = v2net.IPAddress(rawConfig.Address.IP(), rawConfig.Port)
+		t.Destination = v2net.TCPDestination(v2net.IPAddress(rawConfig.Address.IP()), rawConfig.Port)
 	} else {
-		t.Address = v2net.DomainAddress(rawConfig.Address.Domain(), rawConfig.Port)
+		t.Destination = v2net.TCPDestination(v2net.DomainAddress(rawConfig.Address.Domain()), rawConfig.Port)
 	}
 	return nil
 }
@@ -74,8 +74,8 @@ func (o *Outbound) Receivers() []*outbound.Receiver {
 			users = append(users, rawUser)
 		}
 		targets = append(targets, &outbound.Receiver{
-			Address:  rawTarget.Address,
-			Accounts: users,
+			Destination: rawTarget.Destination,
+			Accounts:    users,
 		})
 	}
 	return targets

+ 1 - 1
proxy/vmess/outbound/json/outbound_test.go

@@ -27,7 +27,7 @@ func TestConfigTargetParsing(t *testing.T) {
 	var target *jsonconfig.ConfigTarget
 	err := json.Unmarshal([]byte(rawJson), &target)
 	assert.Error(err).IsNil()
-	assert.String(target.Address).Equals("127.0.0.1:80")
+	assert.String(target.Destination).Equals("tcp:127.0.0.1:80")
 	assert.Int(len(target.Users)).Equals(1)
 	assert.String(target.Users[0].ID()).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
 }

+ 17 - 5
proxy/vmess/outbound/outbound.go

@@ -34,6 +34,7 @@ func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.Out
 		User:    vNextUser,
 		Command: command,
 		Address: firstPacket.Destination().Address(),
+		Port:    firstPacket.Destination().Port(),
 	}
 
 	buffer := alloc.NewSmallBuffer()
@@ -46,8 +47,21 @@ func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.Out
 	return startCommunicate(request, vNextAddress, ray, firstPacket)
 }
 
-func startCommunicate(request *protocol.VMessRequest, dest v2net.Address, ray ray.OutboundRay, firstPacket v2net.Packet) error {
-	conn, err := net.Dial("tcp", dest.String())
+func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray ray.OutboundRay, firstPacket v2net.Packet) error {
+	var destIp net.IP
+	if dest.Address().IsIPv4() || dest.Address().IsIPv6() {
+		destIp = dest.Address().IP()
+	} else {
+		ips, err := net.LookupIP(dest.Address().Domain())
+		if err != nil {
+			return err
+		}
+		destIp = ips[0]
+	}
+	conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
+		IP:   destIp,
+		Port: int(dest.Port()),
+	})
 	if err != nil {
 		log.Error("Failed to open %s: %v", dest.String(), err)
 		if ray != nil {
@@ -69,9 +83,7 @@ func startCommunicate(request *protocol.VMessRequest, dest v2net.Address, ray ra
 	go handleResponse(conn, request, output, &responseFinish, (request.Command == protocol.CmdUDP))
 
 	requestFinish.Lock()
-	if tcpConn, ok := conn.(*net.TCPConn); ok {
-		tcpConn.CloseWrite()
-	}
+	conn.CloseWrite()
 	responseFinish.Lock()
 	return nil
 }

+ 4 - 4
proxy/vmess/outbound/receiver.go

@@ -8,8 +8,8 @@ import (
 )
 
 type Receiver struct {
-	Address  v2net.Address
-	Accounts []vmess.User
+	Destination v2net.Destination
+	Accounts    []vmess.User
 }
 
 type ReceiverManager struct {
@@ -22,7 +22,7 @@ func NewReceiverManager(receivers []*Receiver) *ReceiverManager {
 	}
 }
 
-func (this *ReceiverManager) PickReceiver() (v2net.Address, vmess.User) {
+func (this *ReceiverManager) PickReceiver() (v2net.Destination, vmess.User) {
 	receiverLen := len(this.receivers)
 	receiverIdx := 0
 	if receiverLen > 1 {
@@ -37,5 +37,5 @@ func (this *ReceiverManager) PickReceiver() (v2net.Address, vmess.User) {
 		userIdx = rand.Intn(userLen)
 	}
 	user := receiver.Accounts[userIdx]
-	return receiver.Address, user
+	return receiver.Destination, user
 }

+ 8 - 7
proxy/vmess/protocol/vmess.go

@@ -41,14 +41,15 @@ type VMessRequest struct {
 	ResponseHeader []byte
 	Command        byte
 	Address        v2net.Address
+	Port           v2net.Port
 }
 
 // Destination is the final destination of this request.
 func (this *VMessRequest) Destination() v2net.Destination {
 	if this.Command == CmdTCP {
-		return v2net.NewTCPDestination(this.Address)
+		return v2net.TCPDestination(this.Address, this.Port)
 	} else {
-		return v2net.NewUDPDestination(this.Address)
+		return v2net.UDPDestination(this.Address, this.Port)
 	}
 }
 
@@ -106,7 +107,7 @@ func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 	request.ResponseHeader = buffer.Value[33:37] // 4 bytes
 	request.Command = buffer.Value[37]
 
-	port := v2net.PortFromBytes(buffer.Value[38:40])
+	request.Port = v2net.PortFromBytes(buffer.Value[38:40])
 
 	switch buffer.Value[40] {
 	case addrTypeIPv4:
@@ -115,14 +116,14 @@ func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 		if err != nil {
 			return nil, err
 		}
-		request.Address = v2net.IPAddress(buffer.Value[41:45], port)
+		request.Address = v2net.IPAddress(buffer.Value[41:45])
 	case addrTypeIPv6:
 		_, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:57]) // 16 bytes
 		bufferLen += 16
 		if err != nil {
 			return nil, err
 		}
-		request.Address = v2net.IPAddress(buffer.Value[41:57], port)
+		request.Address = v2net.IPAddress(buffer.Value[41:57])
 	case addrTypeDomain:
 		_, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:42])
 		if err != nil {
@@ -134,7 +135,7 @@ func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 			return nil, err
 		}
 		bufferLen += 1 + domainLength
-		request.Address = v2net.DomainAddress(string(buffer.Value[42:42+domainLength]), port)
+		request.Address = v2net.DomainAddress(string(buffer.Value[42 : 42+domainLength]))
 	}
 
 	_, err = v2net.ReadAllBytes(decryptor, buffer.Value[bufferLen:bufferLen+4])
@@ -172,7 +173,7 @@ func (this *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user
 	buffer.Append(this.RequestKey)
 	buffer.Append(this.ResponseHeader)
 	buffer.AppendBytes(this.Command)
-	buffer.Append(this.Address.Port().Bytes())
+	buffer.Append(this.Port.Bytes())
 
 	switch {
 	case this.Address.IsIPv4():

+ 4 - 2
proxy/vmess/protocol/vmess_test.go

@@ -55,7 +55,8 @@ func TestVMessSerialization(t *testing.T) {
 	request.ResponseHeader = randBytes[32:]
 
 	request.Command = byte(0x01)
-	request.Address = v2net.DomainAddress("v2ray.com", 80)
+	request.Address = v2net.DomainAddress("v2ray.com")
+	request.Port = v2net.Port(80)
 
 	mockTime := int64(1823730)
 
@@ -113,7 +114,8 @@ func BenchmarkVMessRequestWriting(b *testing.B) {
 	request.ResponseHeader = randBytes[32:]
 
 	request.Command = byte(0x01)
-	request.Address = v2net.DomainAddress("v2ray.com", 80)
+	request.Address = v2net.DomainAddress("v2ray.com")
+	request.Port = v2net.Port(80)
 
 	for i := 0; i < b.N; i++ {
 		request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, nil)

+ 2 - 2
proxy/vmess/vmess_test.go

@@ -52,7 +52,7 @@ func TestVMessInAndOut(t *testing.T) {
 			SettingsValue: &outboundjson.Outbound{
 				[]*outboundjson.ConfigTarget{
 					&outboundjson.ConfigTarget{
-						Address: v2net.IPAddress([]byte{127, 0, 0, 1}, portB),
+						Destination: v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), portB),
 						Users: []*vmessjson.ConfigUser{
 							&vmessjson.ConfigUser{Id: testAccount},
 						},
@@ -99,7 +99,7 @@ func TestVMessInAndOut(t *testing.T) {
 	err = pointB.Start()
 	assert.Error(err).IsNil()
 
-	dest := v2net.NewTCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}, 80))
+	dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	ich.Communicate(v2net.NewPacket(dest, nil, true))
 	assert.Bytes(ichConnInput).Equals(ochConnOutput.Bytes())
 	assert.Bytes(ichConnOutput.Bytes()).Equals(ochConnInput)

+ 6 - 5
testing/scenarios/socks5_helper.go

@@ -29,20 +29,21 @@ func appendAddress(request []byte, address v2net.Address) []byte {
 		request = append(request, []byte(address.Domain())...)
 
 	}
-	request = append(request, address.Port().Bytes()...)
 	return request
 }
 
-func socks5Request(command byte, address v2net.Address) []byte {
+func socks5Request(command byte, address v2net.Destination) []byte {
 	request := []byte{socks5Version, command, 0}
-	request = appendAddress(request, address)
+	request = appendAddress(request, address.Address())
+	request = append(request, address.Port().Bytes()...)
 	return request
 }
 
-func socks5UDPRequest(address v2net.Address, payload []byte) []byte {
+func socks5UDPRequest(address v2net.Destination, payload []byte) []byte {
 	request := make([]byte, 0, 1024)
 	request = append(request, 0, 0, 0)
-	request = appendAddress(request, address)
+	request = appendAddress(request, address.Address())
+	request = append(request, address.Port().Bytes()...)
 	request = append(request, payload...)
 	return request
 }

+ 5 - 5
testing/scenarios/socks_end_test.go

@@ -53,7 +53,7 @@ func TestTCPConnection(t *testing.T) {
 		assert.Error(err).IsNil()
 		assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0})
 
-		connectRequest := socks5Request(byte(1), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort))
+		connectRequest := socks5Request(byte(1), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort))
 		nBytes, err = conn.Write(connectRequest)
 		assert.Int(nBytes).Equals(len(connectRequest))
 		assert.Error(err).IsNil()
@@ -124,7 +124,7 @@ func TestTCPBind(t *testing.T) {
 	assert.Error(err).IsNil()
 	assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0})
 
-	connectRequest := socks5Request(byte(2), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort))
+	connectRequest := socks5Request(byte(2), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort))
 	nBytes, err = conn.Write(connectRequest)
 	assert.Int(nBytes).Equals(len(connectRequest))
 	assert.Error(err).IsNil()
@@ -173,7 +173,7 @@ func TestUDPAssociate(t *testing.T) {
 	assert.Error(err).IsNil()
 	assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0})
 
-	connectRequest := socks5Request(byte(3), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort))
+	connectRequest := socks5Request(byte(3), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort))
 	nBytes, err = conn.Write(connectRequest)
 	assert.Int(nBytes).Equals(len(connectRequest))
 	assert.Error(err).IsNil()
@@ -190,7 +190,7 @@ func TestUDPAssociate(t *testing.T) {
 	assert.Error(err).IsNil()
 
 	udpPayload := "UDP request to udp server."
-	udpRequest := socks5UDPRequest(v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort), []byte(udpPayload))
+	udpRequest := socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte(udpPayload))
 
 	nBytes, err = udpConn.Write(udpRequest)
 	assert.Int(nBytes).Equals(len(udpRequest))
@@ -200,7 +200,7 @@ func TestUDPAssociate(t *testing.T) {
 	nBytes, err = udpConn.Read(udpResponse)
 	assert.Error(err).IsNil()
 	assert.Bytes(udpResponse[:nBytes]).Equals(
-		socks5UDPRequest(v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort), []byte("Processed: UDP request to udp server.")))
+		socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte("Processed: UDP request to udp server.")))
 
 	udpConn.Close()
 	conn.Close()

+ 2 - 2
testing/servers/tcp/tcp.go

@@ -13,7 +13,7 @@ type Server struct {
 	accepting    bool
 }
 
-func (server *Server) Start() (v2net.Address, error) {
+func (server *Server) Start() (v2net.Destination, error) {
 	listener, err := net.ListenTCP("tcp", &net.TCPAddr{
 		IP:   []byte{0, 0, 0, 0},
 		Port: int(server.Port),
@@ -24,7 +24,7 @@ func (server *Server) Start() (v2net.Address, error) {
 	}
 	go server.acceptConnections(listener)
 	localAddr := listener.Addr().(*net.TCPAddr)
-	return v2net.IPAddress(localAddr.IP, v2net.Port(localAddr.Port)), nil
+	return v2net.TCPDestination(v2net.IPAddress(localAddr.IP), v2net.Port(localAddr.Port)), nil
 }
 
 func (server *Server) acceptConnections(listener *net.TCPListener) {

+ 2 - 2
testing/servers/udp/udp.go

@@ -13,7 +13,7 @@ type Server struct {
 	accepting    bool
 }
 
-func (server *Server) Start() (v2net.Address, error) {
+func (server *Server) Start() (v2net.Destination, error) {
 	conn, err := net.ListenUDP("udp", &net.UDPAddr{
 		IP:   []byte{0, 0, 0, 0},
 		Port: int(server.Port),
@@ -24,7 +24,7 @@ func (server *Server) Start() (v2net.Address, error) {
 	}
 	go server.handleConnection(conn)
 	localAddr := conn.LocalAddr().(*net.UDPAddr)
-	return v2net.IPAddress(localAddr.IP, v2net.Port(localAddr.Port)), nil
+	return v2net.UDPDestination(v2net.IPAddress(localAddr.IP), v2net.Port(localAddr.Port)), nil
 }
 
 func (server *Server) handleConnection(conn *net.UDPConn) {