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

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