github.com/EagleQL/Xray-core@v1.4.3/proxy/shadowsocks/protocol_test.go (about)

     1  package shadowsocks_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/google/go-cmp/cmp"
     7  
     8  	"github.com/xtls/xray-core/common"
     9  	"github.com/xtls/xray-core/common/buf"
    10  	"github.com/xtls/xray-core/common/net"
    11  	"github.com/xtls/xray-core/common/protocol"
    12  	. "github.com/xtls/xray-core/proxy/shadowsocks"
    13  )
    14  
    15  func toAccount(a *Account) protocol.Account {
    16  	account, err := a.AsAccount()
    17  	common.Must(err)
    18  	return account
    19  }
    20  
    21  func TestUDPEncoding(t *testing.T) {
    22  	request := &protocol.RequestHeader{
    23  		Version: Version,
    24  		Command: protocol.RequestCommandUDP,
    25  		Address: net.LocalHostIP,
    26  		Port:    1234,
    27  		User: &protocol.MemoryUser{
    28  			Email: "love@example.com",
    29  			Account: toAccount(&Account{
    30  				Password:   "shadowsocks-password",
    31  				CipherType: CipherType_AES_128_GCM,
    32  			}),
    33  		},
    34  	}
    35  
    36  	data := buf.New()
    37  	common.Must2(data.WriteString("test string"))
    38  	encodedData, err := EncodeUDPPacket(request, data.Bytes())
    39  	common.Must(err)
    40  
    41  	validator := new(Validator)
    42  	validator.Add(request.User)
    43  	decodedRequest, decodedData, err := DecodeUDPPacket(validator, encodedData)
    44  	common.Must(err)
    45  
    46  	if r := cmp.Diff(decodedData.Bytes(), data.Bytes()); r != "" {
    47  		t.Error("data: ", r)
    48  	}
    49  
    50  	if r := cmp.Diff(decodedRequest, request, cmp.Comparer(func(a1, a2 protocol.Account) bool { return a1.Equals(a2) })); r != "" {
    51  		t.Error("request: ", r)
    52  	}
    53  }
    54  
    55  func TestTCPRequest(t *testing.T) {
    56  	cases := []struct {
    57  		request *protocol.RequestHeader
    58  		payload []byte
    59  	}{
    60  		{
    61  			request: &protocol.RequestHeader{
    62  				Version: Version,
    63  				Command: protocol.RequestCommandTCP,
    64  				Address: net.LocalHostIP,
    65  				Port:    1234,
    66  				User: &protocol.MemoryUser{
    67  					Email: "love@example.com",
    68  					Account: toAccount(&Account{
    69  						Password:   "tcp-password",
    70  						CipherType: CipherType_CHACHA20_POLY1305,
    71  					}),
    72  				},
    73  			},
    74  			payload: []byte("test string"),
    75  		},
    76  		{
    77  			request: &protocol.RequestHeader{
    78  				Version: Version,
    79  				Command: protocol.RequestCommandTCP,
    80  				Address: net.LocalHostIPv6,
    81  				Port:    1234,
    82  				User: &protocol.MemoryUser{
    83  					Email: "love@example.com",
    84  					Account: toAccount(&Account{
    85  						Password:   "password",
    86  						CipherType: CipherType_AES_256_GCM,
    87  					}),
    88  				},
    89  			},
    90  			payload: []byte("test string"),
    91  		},
    92  		{
    93  			request: &protocol.RequestHeader{
    94  				Version: Version,
    95  				Command: protocol.RequestCommandTCP,
    96  				Address: net.DomainAddress("example.com"),
    97  				Port:    1234,
    98  				User: &protocol.MemoryUser{
    99  					Email: "love@example.com",
   100  					Account: toAccount(&Account{
   101  						Password:   "password",
   102  						CipherType: CipherType_AES_128_GCM,
   103  					}),
   104  				},
   105  			},
   106  			payload: []byte("test string"),
   107  		},
   108  	}
   109  
   110  	runTest := func(request *protocol.RequestHeader, payload []byte) {
   111  		data := buf.New()
   112  		common.Must2(data.Write(payload))
   113  
   114  		cache := buf.New()
   115  		defer cache.Release()
   116  
   117  		writer, err := WriteTCPRequest(request, cache)
   118  		common.Must(err)
   119  
   120  		common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{data}))
   121  
   122  		validator := new(Validator)
   123  		validator.Add(request.User)
   124  		decodedRequest, reader, err := ReadTCPSession(validator, cache)
   125  		common.Must(err)
   126  		if r := cmp.Diff(decodedRequest, request, cmp.Comparer(func(a1, a2 protocol.Account) bool { return a1.Equals(a2) })); r != "" {
   127  			t.Error("request: ", r)
   128  		}
   129  
   130  		decodedData, err := reader.ReadMultiBuffer()
   131  		common.Must(err)
   132  		if r := cmp.Diff(decodedData[0].Bytes(), payload); r != "" {
   133  			t.Error("data: ", r)
   134  		}
   135  	}
   136  
   137  	for _, test := range cases {
   138  		runTest(test.request, test.payload)
   139  	}
   140  }
   141  
   142  func TestUDPReaderWriter(t *testing.T) {
   143  	user := &protocol.MemoryUser{
   144  		Account: toAccount(&Account{
   145  			Password:   "test-password",
   146  			CipherType: CipherType_CHACHA20_POLY1305,
   147  		}),
   148  	}
   149  	cache := buf.New()
   150  	defer cache.Release()
   151  
   152  	writer := &UDPWriter{
   153  		Writer: cache,
   154  		Request: &protocol.RequestHeader{
   155  			Version: Version,
   156  			Address: net.DomainAddress("example.com"),
   157  			Port:    123,
   158  			User:    user,
   159  		},
   160  	}
   161  
   162  	reader := &UDPReader{
   163  		Reader: cache,
   164  		User:   user,
   165  	}
   166  
   167  	{
   168  		b := buf.New()
   169  		common.Must2(b.WriteString("test payload"))
   170  		common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))
   171  
   172  		payload, err := reader.ReadMultiBuffer()
   173  		common.Must(err)
   174  		if payload[0].String() != "test payload" {
   175  			t.Error("unexpected output: ", payload[0].String())
   176  		}
   177  	}
   178  
   179  	{
   180  		b := buf.New()
   181  		common.Must2(b.WriteString("test payload 2"))
   182  		common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))
   183  
   184  		payload, err := reader.ReadMultiBuffer()
   185  		common.Must(err)
   186  		if payload[0].String() != "test payload 2" {
   187  			t.Error("unexpected output: ", payload[0].String())
   188  		}
   189  	}
   190  }