github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/protocol/address_test.go (about)

     1  package protocol_test
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/google/go-cmp/cmp"
     8  
     9  	"github.com/v2fly/v2ray-core/v5/common"
    10  	"github.com/v2fly/v2ray-core/v5/common/buf"
    11  	"github.com/v2fly/v2ray-core/v5/common/net"
    12  	. "github.com/v2fly/v2ray-core/v5/common/protocol"
    13  )
    14  
    15  func TestAddressReading(t *testing.T) {
    16  	data := []struct {
    17  		Options []AddressOption
    18  		Input   []byte
    19  		Address net.Address
    20  		Port    net.Port
    21  		Error   bool
    22  	}{
    23  		{
    24  			Options: []AddressOption{},
    25  			Input:   []byte{},
    26  			Error:   true,
    27  		},
    28  		{
    29  			Options: []AddressOption{},
    30  			Input:   []byte{0, 0, 0, 0, 0},
    31  			Error:   true,
    32  		},
    33  		{
    34  			Options: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},
    35  			Input:   []byte{1, 0, 0, 0, 0, 0, 53},
    36  			Address: net.IPAddress([]byte{0, 0, 0, 0}),
    37  			Port:    net.Port(53),
    38  		},
    39  		{
    40  			Options: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4), PortThenAddress()},
    41  			Input:   []byte{0, 53, 1, 0, 0, 0, 0},
    42  			Address: net.IPAddress([]byte{0, 0, 0, 0}),
    43  			Port:    net.Port(53),
    44  		},
    45  		{
    46  			Options: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},
    47  			Input:   []byte{1, 0, 0, 0, 0},
    48  			Error:   true,
    49  		},
    50  		{
    51  			Options: []AddressOption{AddressFamilyByte(0x04, net.AddressFamilyIPv6)},
    52  			Input:   []byte{4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 80},
    53  			Address: net.IPAddress([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),
    54  			Port:    net.Port(80),
    55  		},
    56  		{
    57  			Options: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},
    58  			Input:   []byte{3, 9, 118, 50, 102, 108, 121, 46, 111, 114, 103, 0, 80},
    59  			Address: net.DomainAddress("v2fly.org"),
    60  			Port:    net.Port(80),
    61  		},
    62  		{
    63  			Options: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},
    64  			Input:   []byte{3, 9, 118, 50, 102, 108, 121, 46, 111, 114, 103, 0},
    65  			Error:   true,
    66  		},
    67  		{
    68  			Options: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},
    69  			Input:   []byte{3, 7, 56, 46, 56, 46, 56, 46, 56, 0, 80},
    70  			Address: net.ParseAddress("8.8.8.8"),
    71  			Port:    net.Port(80),
    72  		},
    73  		{
    74  			Options: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},
    75  			Input:   []byte{3, 7, 10, 46, 56, 46, 56, 46, 56, 0, 80},
    76  			Error:   true,
    77  		},
    78  		{
    79  			Options: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},
    80  			Input:   append(append([]byte{3, 24}, []byte("2a00:1450:4007:816::200e")...), 0, 80),
    81  			Address: net.ParseAddress("2a00:1450:4007:816::200e"),
    82  			Port:    net.Port(80),
    83  		},
    84  	}
    85  
    86  	for _, tc := range data {
    87  		b := buf.New()
    88  		parser := NewAddressParser(tc.Options...)
    89  		addr, port, err := parser.ReadAddressPort(b, bytes.NewReader(tc.Input))
    90  		b.Release()
    91  		if tc.Error {
    92  			if err == nil {
    93  				t.Errorf("Expect error but not: %v", tc)
    94  			}
    95  		} else {
    96  			if err != nil {
    97  				t.Errorf("Expect no error but: %s %v", err.Error(), tc)
    98  			}
    99  
   100  			if addr != tc.Address {
   101  				t.Error("Got address ", addr.String(), " want ", tc.Address.String())
   102  			}
   103  
   104  			if tc.Port != port {
   105  				t.Error("Got port ", port, " want ", tc.Port)
   106  			}
   107  		}
   108  	}
   109  }
   110  
   111  func TestAddressWriting(t *testing.T) {
   112  	data := []struct {
   113  		Options []AddressOption
   114  		Address net.Address
   115  		Port    net.Port
   116  		Bytes   []byte
   117  		Error   bool
   118  	}{
   119  		{
   120  			Options: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},
   121  			Address: net.LocalHostIP,
   122  			Port:    net.Port(80),
   123  			Bytes:   []byte{1, 127, 0, 0, 1, 0, 80},
   124  		},
   125  	}
   126  
   127  	for _, tc := range data {
   128  		parser := NewAddressParser(tc.Options...)
   129  
   130  		b := buf.New()
   131  		err := parser.WriteAddressPort(b, tc.Address, tc.Port)
   132  		if tc.Error {
   133  			if err == nil {
   134  				t.Error("Expect error but nil")
   135  			}
   136  		} else {
   137  			common.Must(err)
   138  			if diff := cmp.Diff(tc.Bytes, b.Bytes()); diff != "" {
   139  				t.Error(err)
   140  			}
   141  		}
   142  	}
   143  }
   144  
   145  func BenchmarkAddressReadingIPv4(b *testing.B) {
   146  	parser := NewAddressParser(AddressFamilyByte(0x01, net.AddressFamilyIPv4))
   147  	cache := buf.New()
   148  	defer cache.Release()
   149  
   150  	payload := buf.New()
   151  	defer payload.Release()
   152  
   153  	raw := []byte{1, 0, 0, 0, 0, 0, 53}
   154  	payload.Write(raw)
   155  
   156  	b.ResetTimer()
   157  	for i := 0; i < b.N; i++ {
   158  		_, _, err := parser.ReadAddressPort(cache, payload)
   159  		common.Must(err)
   160  		cache.Clear()
   161  		payload.Clear()
   162  		payload.Extend(int32(len(raw)))
   163  	}
   164  }
   165  
   166  func BenchmarkAddressReadingIPv6(b *testing.B) {
   167  	parser := NewAddressParser(AddressFamilyByte(0x04, net.AddressFamilyIPv6))
   168  	cache := buf.New()
   169  	defer cache.Release()
   170  
   171  	payload := buf.New()
   172  	defer payload.Release()
   173  
   174  	raw := []byte{4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 80}
   175  	payload.Write(raw)
   176  
   177  	b.ResetTimer()
   178  	for i := 0; i < b.N; i++ {
   179  		_, _, err := parser.ReadAddressPort(cache, payload)
   180  		common.Must(err)
   181  		cache.Clear()
   182  		payload.Clear()
   183  		payload.Extend(int32(len(raw)))
   184  	}
   185  }
   186  
   187  func BenchmarkAddressReadingDomain(b *testing.B) {
   188  	parser := NewAddressParser(AddressFamilyByte(0x03, net.AddressFamilyDomain))
   189  	cache := buf.New()
   190  	defer cache.Release()
   191  
   192  	payload := buf.New()
   193  	defer payload.Release()
   194  
   195  	raw := []byte{3, 9, 118, 50, 114, 97, 121, 46, 99, 111, 109, 0, 80}
   196  	payload.Write(raw)
   197  
   198  	b.ResetTimer()
   199  	for i := 0; i < b.N; i++ {
   200  		_, _, err := parser.ReadAddressPort(cache, payload)
   201  		common.Must(err)
   202  		cache.Clear()
   203  		payload.Clear()
   204  		payload.Extend(int32(len(raw)))
   205  	}
   206  }
   207  
   208  func BenchmarkAddressWritingIPv4(b *testing.B) {
   209  	parser := NewAddressParser(AddressFamilyByte(0x01, net.AddressFamilyIPv4))
   210  	writer := buf.New()
   211  	defer writer.Release()
   212  
   213  	b.ResetTimer()
   214  	for i := 0; i < b.N; i++ {
   215  		common.Must(parser.WriteAddressPort(writer, net.LocalHostIP, net.Port(80)))
   216  		writer.Clear()
   217  	}
   218  }
   219  
   220  func BenchmarkAddressWritingIPv6(b *testing.B) {
   221  	parser := NewAddressParser(AddressFamilyByte(0x04, net.AddressFamilyIPv6))
   222  	writer := buf.New()
   223  	defer writer.Release()
   224  
   225  	b.ResetTimer()
   226  	for i := 0; i < b.N; i++ {
   227  		common.Must(parser.WriteAddressPort(writer, net.LocalHostIPv6, net.Port(80)))
   228  		writer.Clear()
   229  	}
   230  }
   231  
   232  func BenchmarkAddressWritingDomain(b *testing.B) {
   233  	parser := NewAddressParser(AddressFamilyByte(0x02, net.AddressFamilyDomain))
   234  	writer := buf.New()
   235  	defer writer.Release()
   236  
   237  	b.ResetTimer()
   238  	for i := 0; i < b.N; i++ {
   239  		common.Must(parser.WriteAddressPort(writer, net.DomainAddress("www.v2fly.org"), net.Port(80)))
   240  		writer.Clear()
   241  	}
   242  }