Darien Raymond пре 9 година
родитељ
комит
7de7588ec2

+ 2 - 2
app/dns/config_json_test.go

@@ -23,6 +23,6 @@ func TestConfigParsing(t *testing.T) {
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 	assert.Int(len(config.NameServers)).Equals(1)
 	assert.Int(len(config.NameServers)).Equals(1)
 	assert.Destination(config.NameServers[0]).IsUDP()
 	assert.Destination(config.NameServers[0]).IsUDP()
-	assert.Address(config.NameServers[0].Address()).Equals(v2net.IPAddress([]byte{8, 8, 8, 8}))
-	assert.Port(config.NameServers[0].Port()).Equals(v2net.Port(53))
+	assert.Address(config.NameServers[0].Address).Equals(v2net.IPAddress([]byte{8, 8, 8, 8}))
+	assert.Port(config.NameServers[0].Port).Equals(v2net.Port(53))
 }
 }

+ 1 - 1
app/dns/server.go

@@ -42,7 +42,7 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer {
 
 
 		dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
 		dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
 		for idx, ns := range config.NameServers {
 		for idx, ns := range config.NameServers {
-			if ns.Address().Family().IsDomain() && ns.Address().Domain() == "localhost" {
+			if ns.Address.Family().IsDomain() && ns.Address.Domain() == "localhost" {
 				server.servers[idx] = &LocalNameServer{}
 				server.servers[idx] = &LocalNameServer{}
 			} else {
 			} else {
 				server.servers[idx] = NewUDPNameServer(ns, dispatcher)
 				server.servers[idx] = NewUDPNameServer(ns, dispatcher)

+ 10 - 10
app/router/rules/condition.go

@@ -73,10 +73,10 @@ func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
 }
 }
 
 
 func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
 func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
-	if !dest.Address().Family().IsDomain() {
+	if !dest.Address.Family().IsDomain() {
 		return false
 		return false
 	}
 	}
-	domain := dest.Address().Domain()
+	domain := dest.Address.Domain()
 	return strings.Contains(domain, this.pattern)
 	return strings.Contains(domain, this.pattern)
 }
 }
 
 
@@ -95,10 +95,10 @@ func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
 }
 }
 
 
 func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
 func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
-	if !dest.Address().Family().IsDomain() {
+	if !dest.Address.Family().IsDomain() {
 		return false
 		return false
 	}
 	}
-	domain := dest.Address().Domain()
+	domain := dest.Address.Domain()
 	return this.pattern.MatchString(strings.ToLower(domain))
 	return this.pattern.MatchString(strings.ToLower(domain))
 }
 }
 
 
@@ -117,10 +117,10 @@ func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
 }
 }
 
 
 func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
 func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
-	if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
+	if !dest.Address.Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
 		return false
 		return false
 	}
 	}
-	return this.cidr.Contains(dest.Address().IP())
+	return this.cidr.Contains(dest.Address.IP())
 }
 }
 
 
 type IPv4Matcher struct {
 type IPv4Matcher struct {
@@ -134,10 +134,10 @@ func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
 }
 }
 
 
 func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
 func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
-	if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) {
+	if !dest.Address.Family().Either(v2net.AddressFamilyIPv4) {
 		return false
 		return false
 	}
 	}
-	return this.ipv4net.Contains(dest.Address().IP())
+	return this.ipv4net.Contains(dest.Address.IP())
 }
 }
 
 
 type PortMatcher struct {
 type PortMatcher struct {
@@ -151,7 +151,7 @@ func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
 }
 }
 
 
 func (this *PortMatcher) Apply(dest v2net.Destination) bool {
 func (this *PortMatcher) Apply(dest v2net.Destination) bool {
-	return this.port.Contains(dest.Port())
+	return this.port.Contains(dest.Port)
 }
 }
 
 
 type NetworkMatcher struct {
 type NetworkMatcher struct {
@@ -165,5 +165,5 @@ func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
 }
 }
 
 
 func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
 func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
-	return this.network.HasNetwork(dest.Network())
+	return this.network.HasNetwork(dest.Network)
 }
 }

+ 5 - 5
app/router/rules/router.go

@@ -43,16 +43,16 @@ func (this *Router) Release() {
 
 
 // Private: Visible for testing.
 // Private: Visible for testing.
 func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
 func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
-	ips := this.dnsServer.Get(dest.Address().Domain())
+	ips := this.dnsServer.Get(dest.Address.Domain())
 	if len(ips) == 0 {
 	if len(ips) == 0 {
 		return nil
 		return nil
 	}
 	}
 	dests := make([]v2net.Destination, len(ips))
 	dests := make([]v2net.Destination, len(ips))
 	for idx, ip := range ips {
 	for idx, ip := range ips {
-		if dest.Network() == v2net.Network_TCP {
-			dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
+		if dest.Network == v2net.Network_TCP {
+			dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port)
 		} else {
 		} else {
-			dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
+			dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port)
 		}
 		}
 	}
 	}
 	return dests
 	return dests
@@ -64,7 +64,7 @@ func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, erro
 			return rule.Tag, nil
 			return rule.Tag, nil
 		}
 		}
 	}
 	}
-	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().Family().IsDomain() {
+	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address.Family().IsDomain() {
 		log.Info("Router: Looking up IP for ", dest)
 		log.Info("Router: Looking up IP for ", dest)
 		ipDests := this.ResolveIP(dest)
 		ipDests := this.ResolveIP(dest)
 		if ipDests != nil {
 		if ipDests != nil {

+ 1 - 0
common/net/address.pb.go

@@ -13,6 +13,7 @@ It is generated from these files:
 
 
 It has these top-level messages:
 It has these top-level messages:
 	AddressPB
 	AddressPB
+	DestinationPB
 	PortRange
 	PortRange
 */
 */
 package net
 package net

+ 19 - 97
common/net/destination.go

@@ -5,16 +5,10 @@ import (
 )
 )
 
 
 // Destination represents a network destination including address and protocol (tcp / udp).
 // Destination represents a network destination including address and protocol (tcp / udp).
-type Destination interface {
-	Network() Network // Protocol of communication (tcp / udp)
-	Address() Address // Address of destination
-	Port() Port
-	String() string // String representation of the destination
-	NetAddr() string
-	Equals(Destination) bool
-
-	IsTCP() bool // True if destination is reachable via TCP
-	IsUDP() bool // True if destination is reachable via UDP
+type Destination struct {
+	Network Network
+	Address Address
+	Port    Port
 }
 }
 
 
 func DestinationFromAddr(addr net.Addr) Destination {
 func DestinationFromAddr(addr net.Addr) Destination {
@@ -30,102 +24,30 @@ func DestinationFromAddr(addr net.Addr) Destination {
 
 
 // TCPDestination creates a TCP destination with given address
 // TCPDestination creates a TCP destination with given address
 func TCPDestination(address Address, port Port) Destination {
 func TCPDestination(address Address, port Port) Destination {
-	return &tcpDestination{address: address, port: port}
+	return Destination{
+		Network: Network_TCP,
+		Address: address,
+		Port:    port,
+	}
 }
 }
 
 
 // UDPDestination creates a UDP destination with given address
 // UDPDestination creates a UDP destination with given address
 func UDPDestination(address Address, port Port) Destination {
 func UDPDestination(address Address, port Port) Destination {
-	return &udpDestination{address: address, port: port}
-}
-
-type tcpDestination struct {
-	address Address
-	port    Port
-}
-
-func (dest *tcpDestination) Network() Network {
-	return Network_TCP
-}
-
-func (dest *tcpDestination) Address() Address {
-	return dest.address
-}
-
-func (dest *tcpDestination) NetAddr() string {
-	return dest.address.String() + ":" + dest.port.String()
-}
-
-func (dest *tcpDestination) String() string {
-	return "tcp:" + dest.NetAddr()
-}
-
-func (dest *tcpDestination) IsTCP() bool {
-	return true
-}
-
-func (dest *tcpDestination) IsUDP() bool {
-	return false
-}
-
-func (dest *tcpDestination) Port() Port {
-	return dest.port
-}
-
-func (dest *tcpDestination) Equals(another Destination) bool {
-	if dest == nil && another == nil {
-		return true
-	}
-	if dest == nil || another == nil {
-		return false
-	}
-	if another.Network() != Network_TCP {
-		return false
+	return Destination{
+		Network: Network_UDP,
+		Address: address,
+		Port:    port,
 	}
 	}
-	return dest.Port() == another.Port() && dest.Address().Equals(another.Address())
-}
-
-type udpDestination struct {
-	address Address
-	port    Port
-}
-
-func (dest *udpDestination) Network() Network {
-	return Network_UDP
-}
-
-func (dest *udpDestination) Address() Address {
-	return dest.address
 }
 }
 
 
-func (dest *udpDestination) NetAddr() string {
-	return dest.address.String() + ":" + dest.port.String()
+func (this Destination) NetAddr() string {
+	return this.Address.String() + ":" + this.Port.String()
 }
 }
 
 
-func (dest *udpDestination) String() string {
-	return "udp:" + dest.NetAddr()
+func (this Destination) String() string {
+	return this.Network.UrlPrefix() + ":" + this.NetAddr()
 }
 }
 
 
-func (dest *udpDestination) IsTCP() bool {
-	return false
-}
-
-func (dest *udpDestination) IsUDP() bool {
-	return true
-}
-
-func (dest *udpDestination) Port() Port {
-	return dest.port
-}
-
-func (dest *udpDestination) Equals(another Destination) bool {
-	if dest == nil && another == nil {
-		return true
-	}
-	if dest == nil || another == nil {
-		return false
-	}
-	if another.Network() != Network_UDP {
-		return false
-	}
-	return dest.Port() == another.Port() && dest.Address().Equals(another.Address())
+func (this Destination) Equals(another Destination) bool {
+	return this.Network == another.Network && this.Port == another.Port && this.Address.Equals(another.Address)
 }
 }

+ 32 - 4
common/net/destination.pb.go

@@ -13,15 +13,43 @@ var _ = proto.Marshal
 var _ = fmt.Errorf
 var _ = fmt.Errorf
 var _ = math.Inf
 var _ = math.Inf
 
 
+type DestinationPB struct {
+	Network Network    `protobuf:"varint,1,opt,name=network,enum=com.v2ray.core.common.net.Network" json:"network,omitempty"`
+	Address *AddressPB `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
+	Port    uint32     `protobuf:"varint,3,opt,name=port" json:"port,omitempty"`
+}
+
+func (m *DestinationPB) Reset()                    { *m = DestinationPB{} }
+func (m *DestinationPB) String() string            { return proto.CompactTextString(m) }
+func (*DestinationPB) ProtoMessage()               {}
+func (*DestinationPB) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
+
+func (m *DestinationPB) GetAddress() *AddressPB {
+	if m != nil {
+		return m.Address
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*DestinationPB)(nil), "com.v2ray.core.common.net.DestinationPB")
+}
+
 func init() { proto.RegisterFile("v2ray.com/core/common/net/destination.proto", fileDescriptor1) }
 func init() { proto.RegisterFile("v2ray.com/core/common/net/destination.proto", fileDescriptor1) }
 
 
 var fileDescriptor1 = []byte{
 var fileDescriptor1 = []byte{
-	// 98 bytes of a gzipped FileDescriptorProto
+	// 199 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x2e, 0x33, 0x2a, 0x4a,
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x2e, 0x33, 0x2a, 0x4a,
 	0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
 	0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
 	0xcf, 0xd3, 0xcf, 0x4b, 0x2d, 0xd1, 0x4f, 0x49, 0x2d, 0x2e, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0xcc,
 	0xcf, 0xd3, 0xcf, 0x4b, 0x2d, 0xd1, 0x4f, 0x49, 0x2d, 0x2e, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0xcc,
 	0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x4c, 0xce, 0xcf, 0xd5, 0x83, 0x69, 0x28,
 	0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x4c, 0xce, 0xcf, 0xd5, 0x83, 0x69, 0x28,
-	0x4a, 0xd5, 0x83, 0x28, 0xd6, 0xcb, 0x4b, 0x2d, 0x71, 0x62, 0x8d, 0x62, 0xce, 0x4b, 0x2d, 0x49,
-	0x62, 0x03, 0x2b, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x95, 0x64, 0x1f, 0x93, 0x57, 0x00,
-	0x00, 0x00,
+	0x4a, 0xd5, 0x83, 0x28, 0xd6, 0xcb, 0x4b, 0x2d, 0x91, 0x52, 0xc7, 0x6d, 0x4e, 0x5e, 0x6a, 0x49,
+	0x79, 0x7e, 0x51, 0x36, 0xc4, 0x0c, 0x7c, 0x0a, 0x13, 0x53, 0x52, 0x8a, 0x52, 0x8b, 0x8b, 0x21,
+	0x0a, 0x95, 0x16, 0x32, 0x72, 0xf1, 0xba, 0x20, 0x9c, 0x10, 0xe0, 0x24, 0x64, 0xc3, 0xc5, 0x0e,
+	0x35, 0x4b, 0x82, 0x51, 0x81, 0x51, 0x83, 0xcf, 0x48, 0x49, 0x0f, 0xa7, 0x83, 0xf4, 0xfc, 0x20,
+	0x2a, 0x83, 0x60, 0x5a, 0x84, 0xec, 0xb8, 0xd8, 0xa1, 0x16, 0x48, 0x30, 0x29, 0x30, 0x6a, 0x70,
+	0x1b, 0xa9, 0xe0, 0xd1, 0xed, 0x08, 0x51, 0x19, 0xe0, 0x14, 0x04, 0xd3, 0x24, 0x24, 0xc4, 0xc5,
+	0x52, 0x90, 0x5f, 0x54, 0x22, 0xc1, 0xac, 0xc0, 0xa8, 0xc1, 0x1b, 0x04, 0x66, 0x3b, 0xb1, 0x46,
+	0x31, 0xe7, 0xa5, 0x96, 0x24, 0xb1, 0x81, 0x5d, 0x6c, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xec,
+	0x8b, 0x02, 0x91, 0x4d, 0x01, 0x00, 0x00,
 }
 }

+ 9 - 0
common/net/destination.proto

@@ -2,3 +2,12 @@ syntax = "proto3";
 
 
 package com.v2ray.core.common.net;
 package com.v2ray.core.common.net;
 option go_package = "net";
 option go_package = "net";
+
+import "v2ray.com/core/common/net/network.proto";
+import "v2ray.com/core/common/net/address.proto";
+
+message DestinationPB {
+  Network network = 1;
+  AddressPB address = 2;
+  uint32 port = 3;
+}

+ 2 - 2
common/net/destination_test.go

@@ -29,7 +29,7 @@ func TestTCPDestinationEquals(t *testing.T) {
 	assert := assert.On(t)
 	assert := assert.On(t)
 
 
 	dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
-	assert.Bool(dest.Equals(nil)).IsFalse()
+	assert.Bool(dest.Equals(v2net.Destination{})).IsFalse()
 
 
 	dest2 := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	dest2 := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	assert.Bool(dest.Equals(dest2)).IsTrue()
 	assert.Bool(dest.Equals(dest2)).IsTrue()
@@ -45,7 +45,7 @@ func TestUDPDestinationEquals(t *testing.T) {
 	assert := assert.On(t)
 	assert := assert.On(t)
 
 
 	dest := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	dest := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
-	assert.Bool(dest.Equals(nil)).IsFalse()
+	assert.Bool(dest.Equals(v2net.Destination{})).IsFalse()
 
 
 	dest2 := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	dest2 := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
 	assert.Bool(dest.Equals(dest2)).IsTrue()
 	assert.Bool(dest.Equals(dest2)).IsTrue()

+ 15 - 0
common/net/network.go

@@ -40,6 +40,21 @@ func (this Network) SystemString() string {
 	}
 	}
 }
 }
 
 
+func (this Network) UrlPrefix() string {
+	switch this {
+	case Network_TCP, Network_RawTCP:
+		return "tcp"
+	case Network_UDP:
+		return "udp"
+	case Network_KCP:
+		return "kcp"
+	case Network_WebSocket:
+		return "ws"
+	default:
+		return "unknown"
+	}
+}
+
 // NetworkList is a list of Networks.
 // NetworkList is a list of Networks.
 type NetworkList []Network
 type NetworkList []Network
 
 

+ 8 - 8
common/protocol/server_picker_test.go

@@ -19,13 +19,13 @@ func TestServerList(t *testing.T) {
 	assert.Uint32(list.Size()).Equals(2)
 	assert.Uint32(list.Size()).Equals(2)
 
 
 	server := list.GetServer(1)
 	server := list.GetServer(1)
-	assert.Port(server.Destination().Port()).Equals(2)
+	assert.Port(server.Destination().Port).Equals(2)
 	time.Sleep(2 * time.Second)
 	time.Sleep(2 * time.Second)
 	server = list.GetServer(1)
 	server = list.GetServer(1)
 	assert.Pointer(server).IsNil()
 	assert.Pointer(server).IsNil()
 
 
 	server = list.GetServer(0)
 	server = list.GetServer(0)
-	assert.Port(server.Destination().Port()).Equals(1)
+	assert.Port(server.Destination().Port).Equals(1)
 }
 }
 
 
 func TestServerPicker(t *testing.T) {
 func TestServerPicker(t *testing.T) {
@@ -38,17 +38,17 @@ func TestServerPicker(t *testing.T) {
 
 
 	picker := NewRoundRobinServerPicker(list)
 	picker := NewRoundRobinServerPicker(list)
 	server := picker.PickServer()
 	server := picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(1)
+	assert.Port(server.Destination().Port).Equals(1)
 	server = picker.PickServer()
 	server = picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(2)
+	assert.Port(server.Destination().Port).Equals(2)
 	server = picker.PickServer()
 	server = picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(3)
+	assert.Port(server.Destination().Port).Equals(3)
 	server = picker.PickServer()
 	server = picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(1)
+	assert.Port(server.Destination().Port).Equals(1)
 
 
 	time.Sleep(2 * time.Second)
 	time.Sleep(2 * time.Second)
 	server = picker.PickServer()
 	server = picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(1)
+	assert.Port(server.Destination().Port).Equals(1)
 	server = picker.PickServer()
 	server = picker.PickServer()
-	assert.Port(server.Destination().Port()).Equals(1)
+	assert.Port(server.Destination().Port).Equals(1)
 }
 }

+ 5 - 5
proxy/dokodemo/dokodemo.go

@@ -106,10 +106,10 @@ func (this *DokodemoDoor) ListenUDP() error {
 }
 }
 
 
 func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, session *proxy.SessionInfo) {
 func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, session *proxy.SessionInfo) {
-	if session.Destination == nil && this.address != nil && this.port > 0 {
+	if session.Destination.Network == v2net.Network_Unknown && this.address != nil && this.port > 0 {
 		session.Destination = v2net.UDPDestination(this.address, this.port)
 		session.Destination = v2net.UDPDestination(this.address, this.port)
 	}
 	}
-	if session.Destination == nil {
+	if session.Destination.Network == v2net.Network_Unknown {
 		log.Info("Dokodemo: Unknown destination, stop forwarding...")
 		log.Info("Dokodemo: Unknown destination, stop forwarding...")
 		return
 		return
 	}
 	}
@@ -144,16 +144,16 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
 	var dest v2net.Destination
 	var dest v2net.Destination
 	if this.config.FollowRedirect {
 	if this.config.FollowRedirect {
 		originalDest := GetOriginalDestination(conn)
 		originalDest := GetOriginalDestination(conn)
-		if originalDest != nil {
+		if originalDest.Network != v2net.Network_Unknown {
 			log.Info("Dokodemo: Following redirect to: ", originalDest)
 			log.Info("Dokodemo: Following redirect to: ", originalDest)
 			dest = originalDest
 			dest = originalDest
 		}
 		}
 	}
 	}
-	if dest == nil && this.address != nil && this.port > v2net.Port(0) {
+	if dest.Network == v2net.Network_Unknown && this.address != nil && this.port > v2net.Port(0) {
 		dest = v2net.TCPDestination(this.address, this.port)
 		dest = v2net.TCPDestination(this.address, this.port)
 	}
 	}
 
 
-	if dest == nil {
+	if dest.Network == v2net.Network_Unknown {
 		log.Info("Dokodemo: Unknown destination, stop forwarding...")
 		log.Info("Dokodemo: Unknown destination, stop forwarding...")
 		return
 		return
 	}
 	}

+ 3 - 3
proxy/dokodemo/sockopt_linux.go

@@ -16,18 +16,18 @@ func GetOriginalDestination(conn internet.Connection) v2net.Destination {
 	tcpConn, ok := conn.(internet.SysFd)
 	tcpConn, ok := conn.(internet.SysFd)
 	if !ok {
 	if !ok {
 		log.Info("Dokodemo: Failed to get sys fd.")
 		log.Info("Dokodemo: Failed to get sys fd.")
-		return nil
+		return v2net.Destination{}
 	}
 	}
 	fd, err := tcpConn.SysFd()
 	fd, err := tcpConn.SysFd()
 	if err != nil {
 	if err != nil {
 		log.Info("Dokodemo: Failed to get original destination: ", err)
 		log.Info("Dokodemo: Failed to get original destination: ", err)
-		return nil
+		return v2net.Destination{}
 	}
 	}
 
 
 	addr, err := syscall.GetsockoptIPv6Mreq(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST)
 	addr, err := syscall.GetsockoptIPv6Mreq(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST)
 	if err != nil {
 	if err != nil {
 		log.Info("Dokodemo: Failed to call getsockopt: ", err)
 		log.Info("Dokodemo: Failed to call getsockopt: ", err)
-		return nil
+		return v2net.Destination{}
 	}
 	}
 	ip := v2net.IPAddress(addr.Multiaddr[4:8])
 	ip := v2net.IPAddress(addr.Multiaddr[4:8])
 	port := uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])
 	port := uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])

+ 1 - 1
proxy/dokodemo/sockopt_other.go

@@ -8,5 +8,5 @@ import (
 )
 )
 
 
 func GetOriginalDestination(conn internet.Connection) v2net.Destination {
 func GetOriginalDestination(conn internet.Connection) v2net.Destination {
-	return nil
+	return v2net.Destination{}
 }
 }

+ 7 - 7
proxy/freedom/freedom.go

@@ -46,11 +46,11 @@ func NewFreedomConnection(config *Config, space app.Space, meta *proxy.OutboundH
 
 
 // Private: Visible for testing.
 // Private: Visible for testing.
 func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
 func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
-	if !destination.Address().Family().IsDomain() {
+	if !destination.Address.Family().IsDomain() {
 		return destination
 		return destination
 	}
 	}
 
 
-	ips := this.dns.Get(destination.Address().Domain())
+	ips := this.dns.Get(destination.Address.Domain())
 	if len(ips) == 0 {
 	if len(ips) == 0 {
 		log.Info("Freedom: DNS returns nil answer. Keep domain as is.")
 		log.Info("Freedom: DNS returns nil answer. Keep domain as is.")
 		return destination
 		return destination
@@ -58,10 +58,10 @@ func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.De
 
 
 	ip := ips[dice.Roll(len(ips))]
 	ip := ips[dice.Roll(len(ips))]
 	var newDest v2net.Destination
 	var newDest v2net.Destination
-	if destination.Network() == v2net.Network_TCP {
-		newDest = v2net.TCPDestination(v2net.IPAddress(ip), destination.Port())
+	if destination.Network == v2net.Network_TCP {
+		newDest = v2net.TCPDestination(v2net.IPAddress(ip), destination.Port)
 	} else {
 	} else {
-		newDest = v2net.UDPDestination(v2net.IPAddress(ip), destination.Port())
+		newDest = v2net.UDPDestination(v2net.IPAddress(ip), destination.Port)
 	}
 	}
 	log.Info("Freedom: Changing destination from ", destination, " to ", newDest)
 	log.Info("Freedom: Changing destination from ", destination, " to ", newDest)
 	return newDest
 	return newDest
@@ -75,7 +75,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
 	defer ray.OutboundOutput().Close()
 	defer ray.OutboundOutput().Close()
 
 
 	var conn internet.Connection
 	var conn internet.Connection
-	if this.domainStrategy == Config_USE_IP && destination.Address().Family().IsDomain() {
+	if this.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
 		destination = this.ResolveIP(destination)
 		destination = this.ResolveIP(destination)
 	}
 	}
 	err := retry.Timed(5, 100).On(func() error {
 	err := retry.Timed(5, 100).On(func() error {
@@ -112,7 +112,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
 	var reader io.Reader = conn
 	var reader io.Reader = conn
 
 
 	timeout := this.timeout
 	timeout := this.timeout
-	if destination.Network() == v2net.Network_UDP {
+	if destination.Network == v2net.Network_UDP {
 		timeout = 16
 		timeout = 16
 	}
 	}
 	if timeout > 0 {
 	if timeout > 0 {

+ 1 - 1
proxy/freedom/freedom_test.go

@@ -110,5 +110,5 @@ func TestIPResolution(t *testing.T) {
 
 
 	ipDest := freedom.ResolveIP(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), v2net.Port(80)))
 	ipDest := freedom.ResolveIP(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), v2net.Port(80)))
 	assert.Destination(ipDest).IsTCP()
 	assert.Destination(ipDest).IsTCP()
-	assert.Address(ipDest.Address()).Equals(v2net.LocalHostIP)
+	assert.Address(ipDest.Address).Equals(v2net.LocalHostIP)
 }
 }

+ 2 - 2
proxy/http/server.go

@@ -77,12 +77,12 @@ func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error
 		if addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, "missing port") {
 		if addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, "missing port") {
 			host = rawHost
 			host = rawHost
 		} else {
 		} else {
-			return nil, err
+			return v2net.Destination{}, err
 		}
 		}
 	} else {
 	} else {
 		intPort, err := strconv.Atoi(rawPort)
 		intPort, err := strconv.Atoi(rawPort)
 		if err != nil {
 		if err != nil {
-			return nil, err
+			return v2net.Destination{}, err
 		}
 		}
 		port = v2net.Port(intPort)
 		port = v2net.Port(intPort)
 	}
 	}

+ 5 - 5
proxy/socks/server.go

@@ -236,14 +236,14 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err
 
 
 	udpAddr := this.udpAddress
 	udpAddr := this.udpAddress
 
 
-	response.Port = udpAddr.Port()
-	switch udpAddr.Address().Family() {
+	response.Port = udpAddr.Port
+	switch udpAddr.Address.Family() {
 	case v2net.AddressFamilyIPv4:
 	case v2net.AddressFamilyIPv4:
-		response.SetIPv4(udpAddr.Address().IP())
+		response.SetIPv4(udpAddr.Address.IP())
 	case v2net.AddressFamilyIPv6:
 	case v2net.AddressFamilyIPv6:
-		response.SetIPv6(udpAddr.Address().IP())
+		response.SetIPv6(udpAddr.Address.IP())
 	case v2net.AddressFamilyDomain:
 	case v2net.AddressFamilyDomain:
-		response.SetDomain(udpAddr.Address().Domain())
+		response.SetDomain(udpAddr.Address.Domain())
 	}
 	}
 
 
 	response.Write(writer)
 	response.Write(writer)

+ 2 - 2
proxy/socks/server_udp.go

@@ -49,8 +49,8 @@ func (this *Server) handleUDPPayload(payload *alloc.Buffer, session *proxy.Sessi
 	this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination()}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
 	this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination()}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
 		response := &protocol.Socks5UDPRequest{
 		response := &protocol.Socks5UDPRequest{
 			Fragment: 0,
 			Fragment: 0,
-			Address:  request.Destination().Address(),
-			Port:     request.Destination().Port(),
+			Address:  request.Destination().Address,
+			Port:     request.Destination().Port,
 			Data:     payload,
 			Data:     payload,
 		}
 		}
 		log.Info("Socks: Writing back UDP response with ", payload.Len(), " bytes to ", destination)
 		log.Info("Socks: Writing back UDP response with ", payload.Len(), " bytes to ", destination)

+ 1 - 1
proxy/vmess/outbound/command.go

@@ -30,7 +30,7 @@ func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd prot
 	switch typedCommand := cmd.(type) {
 	switch typedCommand := cmd.(type) {
 	case *protocol.CommandSwitchAccount:
 	case *protocol.CommandSwitchAccount:
 		if typedCommand.Host == nil {
 		if typedCommand.Host == nil {
-			typedCommand.Host = dest.Address()
+			typedCommand.Host = dest.Address
 		}
 		}
 		this.handleSwitchAccount(typedCommand)
 		this.handleSwitchAccount(typedCommand)
 	default:
 	default:

+ 3 - 3
proxy/vmess/outbound/outbound.go

@@ -49,15 +49,15 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
 	log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination())
 	log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination())
 
 
 	command := protocol.RequestCommandTCP
 	command := protocol.RequestCommandTCP
-	if target.Network() == v2net.Network_UDP {
+	if target.Network == v2net.Network_UDP {
 		command = protocol.RequestCommandUDP
 		command = protocol.RequestCommandUDP
 	}
 	}
 	request := &protocol.RequestHeader{
 	request := &protocol.RequestHeader{
 		Version: encoding.Version,
 		Version: encoding.Version,
 		User:    rec.PickUser(),
 		User:    rec.PickUser(),
 		Command: command,
 		Command: command,
-		Address: target.Address(),
-		Port:    target.Port(),
+		Address: target.Address,
+		Port:    target.Port,
 		Option:  protocol.RequestOptionChunkStream,
 		Option:  protocol.RequestOptionChunkStream,
 	}
 	}
 
 

+ 6 - 6
testing/assert/destination.go

@@ -20,25 +20,25 @@ type DestinationSubject struct {
 }
 }
 
 
 func (this *DestinationSubject) IsTCP() {
 func (this *DestinationSubject) IsTCP() {
-	if this.value.Network() != v2net.Network_TCP {
+	if this.value.Network != v2net.Network_TCP {
 		this.Fail("is", "a TCP destination")
 		this.Fail("is", "a TCP destination")
 	}
 	}
 }
 }
 
 
 func (this *DestinationSubject) IsNotTCP() {
 func (this *DestinationSubject) IsNotTCP() {
-	if this.value.Network() == v2net.Network_TCP {
+	if this.value.Network == v2net.Network_TCP {
 		this.Fail("is not", "a TCP destination")
 		this.Fail("is not", "a TCP destination")
 	}
 	}
 }
 }
 
 
 func (this *DestinationSubject) IsUDP() {
 func (this *DestinationSubject) IsUDP() {
-	if this.value.Network() != v2net.Network_UDP {
+	if this.value.Network != v2net.Network_UDP {
 		this.Fail("is", "a UDP destination")
 		this.Fail("is", "a UDP destination")
 	}
 	}
 }
 }
 
 
 func (this *DestinationSubject) IsNotUDP() {
 func (this *DestinationSubject) IsNotUDP() {
-	if this.value.Network() == v2net.Network_UDP {
+	if this.value.Network == v2net.Network_UDP {
 		this.Fail("is not", "a UDP destination")
 		this.Fail("is not", "a UDP destination")
 	}
 	}
 }
 }
@@ -50,9 +50,9 @@ func (this *DestinationSubject) EqualsString(another string) {
 }
 }
 
 
 func (this *DestinationSubject) HasAddress() *AddressSubject {
 func (this *DestinationSubject) HasAddress() *AddressSubject {
-	return this.a.Address(this.value.Address())
+	return this.a.Address(this.value.Address)
 }
 }
 
 
 func (this *DestinationSubject) HasPort() *PortSubject {
 func (this *DestinationSubject) HasPort() *PortSubject {
-	return this.a.Port(this.value.Port())
+	return this.a.Port(this.value.Port)
 }
 }

+ 4 - 4
testing/scenarios/socks5_helper.go

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

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

@@ -22,7 +22,7 @@ func (server *Server) Start() (v2net.Destination, error) {
 		Zone: "",
 		Zone: "",
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return v2net.Destination{}, err
 	}
 	}
 	server.Port = v2net.Port(listener.Addr().(*net.TCPAddr).Port)
 	server.Port = v2net.Port(listener.Addr().(*net.TCPAddr).Port)
 	server.listener = listener
 	server.listener = listener

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

@@ -21,7 +21,7 @@ func (server *Server) Start() (v2net.Destination, error) {
 		Zone: "",
 		Zone: "",
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return v2net.Destination{}, err
 	}
 	}
 	server.Port = v2net.Port(conn.LocalAddr().(*net.UDPAddr).Port)
 	server.Port = v2net.Port(conn.LocalAddr().(*net.UDPAddr).Port)
 	server.conn = conn
 	server.conn = conn

+ 3 - 3
transport/internet/dialer.go

@@ -27,7 +27,7 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
 
 
 	var connection Connection
 	var connection Connection
 	var err error
 	var err error
-	if dest.Network() == v2net.Network_TCP {
+	if dest.Network == v2net.Network_TCP {
 		switch {
 		switch {
 		case settings.IsCapableOf(StreamConnectionTypeTCP):
 		case settings.IsCapableOf(StreamConnectionTypeTCP):
 			connection, err = TCPDialer(src, dest)
 			connection, err = TCPDialer(src, dest)
@@ -51,8 +51,8 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
 		}
 		}
 
 
 		config := settings.TLSSettings.GetTLSConfig()
 		config := settings.TLSSettings.GetTLSConfig()
-		if dest.Address().Family().IsDomain() {
-			config.ServerName = dest.Address().Domain()
+		if dest.Address.Family().IsDomain() {
+			config.ServerName = dest.Address.Domain()
 		}
 		}
 		tlsConn := tls.Client(connection, config)
 		tlsConn := tls.Client(connection, config)
 		return v2tls.NewConnection(tlsConn), nil
 		return v2tls.NewConnection(tlsConn), nil

+ 4 - 4
transport/internet/dialer_test.go

@@ -17,9 +17,9 @@ func TestDialDomain(t *testing.T) {
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 	defer server.Close()
 	defer server.Close()
 
 
-	conn, err := DialToDest(nil, v2net.TCPDestination(v2net.DomainAddress("local.v2ray.com"), dest.Port()))
+	conn, err := DialToDest(nil, v2net.TCPDestination(v2net.DomainAddress("local.v2ray.com"), dest.Port))
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
-	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port().String())
+	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
 	conn.Close()
 	conn.Close()
 }
 }
 
 
@@ -31,8 +31,8 @@ func TestDialWithLocalAddr(t *testing.T) {
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 	defer server.Close()
 	defer server.Close()
 
 
-	conn, err := DialToDest(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port()))
+	conn, err := DialToDest(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port))
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
-	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port().String())
+	assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
 	conn.Close()
 	conn.Close()
 }
 }

+ 3 - 3
transport/internet/kcp/dialer.go

@@ -15,9 +15,9 @@ var (
 )
 )
 
 
 func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
 func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
-	udpDest := v2net.UDPDestination(dest.Address(), dest.Port())
-	log.Info("KCP|Dialer: Dialing KCP to ", udpDest)
-	conn, err := internet.DialToDest(src, udpDest)
+	dest.Network = v2net.Network_UDP
+	log.Info("KCP|Dialer: Dialing KCP to ", dest)
+	conn, err := internet.DialToDest(src, dest)
 	if err != nil {
 	if err != nil {
 		log.Error("KCP|Dialer: Failed to dial to dest: ", err)
 		log.Error("KCP|Dialer: Failed to dial to dest: ", err)
 		return nil, err
 		return nil, err

+ 2 - 2
transport/internet/kcp/listener.go

@@ -80,8 +80,8 @@ func (this *Listener) OnReceive(payload *alloc.Buffer, session *proxy.SessionInf
 			listener: this,
 			listener: this,
 		}
 		}
 		srcAddr := &net.UDPAddr{
 		srcAddr := &net.UDPAddr{
-			IP:   src.Address().IP(),
-			Port: int(src.Port()),
+			IP:   src.Address.IP(),
+			Port: int(src.Port),
 		}
 		}
 		auth, err := effectiveConfig.GetAuthenticator()
 		auth, err := effectiveConfig.GetAuthenticator()
 		if err != nil {
 		if err != nil {

+ 3 - 3
transport/internet/system_dialer.go

@@ -25,7 +25,7 @@ func (this *DefaultSystemDialer) Dial(src v2net.Address, dest v2net.Destination)
 	}
 	}
 	if src != nil && src != v2net.AnyIP {
 	if src != nil && src != v2net.AnyIP {
 		var addr net.Addr
 		var addr net.Addr
-		if dest.Network() == v2net.Network_TCP {
+		if dest.Network == v2net.Network_TCP {
 			addr = &net.TCPAddr{
 			addr = &net.TCPAddr{
 				IP:   src.IP(),
 				IP:   src.IP(),
 				Port: 0,
 				Port: 0,
@@ -38,7 +38,7 @@ func (this *DefaultSystemDialer) Dial(src v2net.Address, dest v2net.Destination)
 		}
 		}
 		dialer.LocalAddr = addr
 		dialer.LocalAddr = addr
 	}
 	}
-	return dialer.Dial(dest.Network().SystemString(), dest.NetAddr())
+	return dialer.Dial(dest.Network.SystemString(), dest.NetAddr())
 }
 }
 
 
 type SystemDialerAdapter interface {
 type SystemDialerAdapter interface {
@@ -56,7 +56,7 @@ func WithAdapter(dialer SystemDialerAdapter) SystemDialer {
 }
 }
 
 
 func (this *SimpleSystemDialer) Dial(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
 func (this *SimpleSystemDialer) Dial(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
-	return this.adapter.Dial(dest.Network().SystemString(), dest.NetAddr())
+	return this.adapter.Dial(dest.Network.SystemString(), dest.NetAddr())
 }
 }
 
 
 // UseAlternativeSystemDialer replaces the current system dialer with a given one.
 // UseAlternativeSystemDialer replaces the current system dialer with a given one.

+ 1 - 1
transport/internet/tcp/dialer.go

@@ -19,7 +19,7 @@ func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error
 	}
 	}
 	id := src.String() + "-" + dest.NetAddr()
 	id := src.String() + "-" + dest.NetAddr()
 	var conn net.Conn
 	var conn net.Conn
-	if dest.Network() == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
+	if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
 		conn = globalCache.Get(id)
 		conn = globalCache.Get(id)
 	}
 	}
 	if conn == nil {
 	if conn == nil {

+ 2 - 2
transport/internet/udp/hub.go

@@ -63,8 +63,8 @@ func (this *UDPHub) Close() {
 
 
 func (this *UDPHub) WriteTo(payload []byte, dest v2net.Destination) (int, error) {
 func (this *UDPHub) WriteTo(payload []byte, dest v2net.Destination) (int, error) {
 	return this.conn.WriteToUDP(payload, &net.UDPAddr{
 	return this.conn.WriteToUDP(payload, &net.UDPAddr{
-		IP:   dest.Address().IP(),
-		Port: int(dest.Port()),
+		IP:   dest.Address.IP(),
+		Port: int(dest.Port),
 	})
 	})
 }
 }
 
 

+ 2 - 2
transport/internet/udp/hub_linux.go

@@ -22,7 +22,7 @@ func SetOriginalDestOptions(fd int) error {
 func RetrieveOriginalDest(oob []byte) v2net.Destination {
 func RetrieveOriginalDest(oob []byte) v2net.Destination {
 	msgs, err := syscall.ParseSocketControlMessage(oob)
 	msgs, err := syscall.ParseSocketControlMessage(oob)
 	if err != nil {
 	if err != nil {
-		return nil
+		return v2net.Destination{}
 	}
 	}
 	for _, msg := range msgs {
 	for _, msg := range msgs {
 		if msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_ORIGDSTADDR {
 		if msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_ORIGDSTADDR {
@@ -31,7 +31,7 @@ func RetrieveOriginalDest(oob []byte) v2net.Destination {
 			return v2net.UDPDestination(ip, port)
 			return v2net.UDPDestination(ip, port)
 		}
 		}
 	}
 	}
-	return nil
+	return v2net.Destination{}
 }
 }
 
 
 func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {
 func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {

+ 1 - 1
transport/internet/udp/hub_other.go

@@ -13,7 +13,7 @@ func SetOriginalDestOptions(fd int) error {
 }
 }
 
 
 func RetrieveOriginalDest(oob []byte) v2net.Destination {
 func RetrieveOriginalDest(oob []byte) v2net.Destination {
-	return nil
+	return v2net.Destination{}
 }
 }
 
 
 func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {
 func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {

+ 3 - 3
transport/internet/ws/dialer.go

@@ -23,7 +23,7 @@ func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error
 	}
 	}
 	id := src.String() + "-" + dest.NetAddr()
 	id := src.String() + "-" + dest.NetAddr()
 	var conn *wsconn
 	var conn *wsconn
-	if dest.Network() == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
+	if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
 		connt := globalCache.Get(id)
 		connt := globalCache.Get(id)
 		if connt != nil {
 		if connt != nil {
 			conn = connt.(*wsconn)
 			conn = connt.(*wsconn)
@@ -49,7 +49,7 @@ func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
 		return internet.DialToDest(src, dest)
 		return internet.DialToDest(src, dest)
 	}
 	}
 
 
-	tlsconf := &tls.Config{ServerName: dest.Address().Domain(), InsecureSkipVerify: effectiveConfig.DeveloperInsecureSkipVerify}
+	tlsconf := &tls.Config{ServerName: dest.Address.Domain(), InsecureSkipVerify: effectiveConfig.DeveloperInsecureSkipVerify}
 
 
 	dialer := websocket.Dialer{NetDial: commonDial, ReadBufferSize: 65536, WriteBufferSize: 65536, TLSClientConfig: tlsconf}
 	dialer := websocket.Dialer{NetDial: commonDial, ReadBufferSize: 65536, WriteBufferSize: 65536, TLSClientConfig: tlsconf}
 
 
@@ -80,7 +80,7 @@ func calcPto(dst v2net.Destination) string {
 		return effectiveConfig.Pto
 		return effectiveConfig.Pto
 	}
 	}
 
 
-	switch dst.Port().Value() {
+	switch dst.Port.Value() {
 	/*
 	/*
 		Since the value is not given explicitly,
 		Since the value is not given explicitly,
 		We are guessing it now.
 		We are guessing it now.