github.com/database64128/shadowsocks-go@v1.7.0/ss2022/stream_test.go (about) 1 package ss2022 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "io" 7 "net/netip" 8 "testing" 9 10 "github.com/database64128/shadowsocks-go/conn" 11 "github.com/database64128/shadowsocks-go/pipe" 12 "github.com/database64128/shadowsocks-go/zerocopy" 13 ) 14 15 func testShadowStreamReadWriter(t *testing.T, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap, clientInitialPayload, unsafeRequestStreamPrefix, unsafeResponseStreamPrefix []byte) { 16 pl, pr := pipe.NewDuplexPipe() 17 plo := zerocopy.SimpleDirectReadWriteCloserOpener{DirectReadWriteCloser: pl} 18 clientTargetAddr := conn.AddrFromIPPort(netip.AddrPortFrom(netip.IPv6Unspecified(), 53)) 19 c := TCPClient{ 20 rwo: &plo, 21 cipherConfig: clientCipherConfig, 22 unsafeRequestStreamPrefix: unsafeRequestStreamPrefix, 23 unsafeResponseStreamPrefix: unsafeResponseStreamPrefix, 24 } 25 s := NewTCPServer(userCipherConfig, identityCipherConfig, unsafeRequestStreamPrefix, unsafeResponseStreamPrefix) 26 s.ReplaceUserLookupMap(userLookupMap) 27 28 var ( 29 crw zerocopy.ReadWriter 30 srw zerocopy.ReadWriter 31 serverTargetAddr conn.Addr 32 serverInitialPayload []byte 33 cerr, serr error 34 ) 35 36 ctrlCh := make(chan struct{}) 37 38 go func() { 39 _, crw, cerr = c.Dial(clientTargetAddr, clientInitialPayload) 40 ctrlCh <- struct{}{} 41 }() 42 43 go func() { 44 srw, serverTargetAddr, serverInitialPayload, _, serr = s.Accept(pr) 45 if serr == nil && len(serverInitialPayload) < len(clientInitialPayload) { 46 // Read excess payload. 47 b := make([]byte, len(clientInitialPayload)) 48 copy(b, serverInitialPayload) 49 scrw := zerocopy.NewCopyReadWriter(srw) 50 _, serr = io.ReadFull(scrw, b[len(serverInitialPayload):]) 51 serverInitialPayload = b 52 } 53 ctrlCh <- struct{}{} 54 }() 55 56 <-ctrlCh 57 <-ctrlCh 58 if cerr != nil { 59 t.Fatal(cerr) 60 } 61 if serr != nil { 62 t.Fatal(serr) 63 } 64 65 if !clientTargetAddr.Equals(serverTargetAddr) { 66 t.Errorf("Target address mismatch: c: %s, s: %s", clientTargetAddr, serverTargetAddr) 67 } 68 if !bytes.Equal(clientInitialPayload, serverInitialPayload) { 69 t.Errorf("Initial payload mismatch: c: %v, s: %v", clientInitialPayload, serverInitialPayload) 70 } 71 72 zerocopy.ReadWriterTestFunc(t, crw, srw) 73 } 74 75 func testShadowStreamReadWriterReplay(t *testing.T, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) { 76 pl, pr := pipe.NewDuplexPipe() 77 plo := zerocopy.SimpleDirectReadWriteCloserOpener{DirectReadWriteCloser: pl} 78 clientTargetAddr := conn.AddrFromIPPort(netip.AddrPortFrom(netip.IPv6Unspecified(), 53)) 79 c := TCPClient{ 80 rwo: &plo, 81 cipherConfig: clientCipherConfig, 82 } 83 s := NewTCPServer(userCipherConfig, identityCipherConfig, nil, nil) 84 s.ReplaceUserLookupMap(userLookupMap) 85 86 var cerr, serr error 87 ctrlCh := make(chan struct{}) 88 89 // Start client. 90 go func() { 91 _, _, cerr = c.Dial(clientTargetAddr, nil) 92 ctrlCh <- struct{}{} 93 }() 94 95 // Hijack client request and save it in b. 96 b := make([]byte, 1440) 97 n, err := pr.Read(b) 98 if err != nil { 99 t.Fatal(err) 100 } 101 sendFunc := func() { 102 _, err = pl.Write(b[:n]) 103 if err != nil { 104 t.Error(err) 105 } 106 } 107 108 // Ensure client success. 109 <-ctrlCh 110 if cerr != nil { 111 t.Fatal(cerr) 112 } 113 114 // Actually send the request. 115 go sendFunc() 116 117 // Start server. 118 _, _, _, _, serr = s.Accept(pr) 119 if serr != nil { 120 t.Fatal(serr) 121 } 122 123 // Send it again. 124 go sendFunc() 125 126 // Start server from replay. 127 _, _, _, _, serr = s.Accept(pr) 128 if serr != ErrRepeatedSalt { 129 t.Errorf("Expected ErrRepeatedSalt, got %v", serr) 130 } 131 } 132 133 func testShadowStreamReadWriterWithCipher(t *testing.T, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) { 134 smallInitialPayload := make([]byte, 1024) 135 largeInitialPayload := make([]byte, 128*1024) 136 unsafeRequestStreamPrefix := make([]byte, 64) 137 unsafeResponseStreamPrefix := make([]byte, 64) 138 139 if _, err := rand.Read(smallInitialPayload); err != nil { 140 t.Fatal(err) 141 } 142 if _, err := rand.Read(largeInitialPayload); err != nil { 143 t.Fatal(err) 144 } 145 if _, err := rand.Read(unsafeRequestStreamPrefix); err != nil { 146 t.Fatal(err) 147 } 148 if _, err := rand.Read(unsafeResponseStreamPrefix); err != nil { 149 t.Fatal(err) 150 } 151 152 t.Run("NoInitialPayload", func(t *testing.T) { 153 testShadowStreamReadWriter(t, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, nil, nil, nil) 154 }) 155 t.Run("SmallInitialPayload", func(t *testing.T) { 156 testShadowStreamReadWriter(t, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, smallInitialPayload, nil, nil) 157 }) 158 t.Run("LargeInitialPayload", func(t *testing.T) { 159 testShadowStreamReadWriter(t, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, largeInitialPayload, nil, nil) 160 }) 161 t.Run("UnsafeStreamPrefix", func(t *testing.T) { 162 testShadowStreamReadWriter(t, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, nil, unsafeRequestStreamPrefix, unsafeResponseStreamPrefix) 163 }) 164 165 t.Run("Replay", func(t *testing.T) { 166 testShadowStreamReadWriterReplay(t, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap) 167 }) 168 } 169 170 func TestShadowStreamReadWriterNoEIH(t *testing.T) { 171 clientCipherConfig128, userCipherConfig128, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-128-gcm", false) 172 if err != nil { 173 t.Fatal(err) 174 } 175 clientCipherConfig256, userCipherConfig256, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-256-gcm", false) 176 if err != nil { 177 t.Fatal(err) 178 } 179 180 t.Run("128", func(t *testing.T) { 181 testShadowStreamReadWriterWithCipher(t, clientCipherConfig128, userCipherConfig128, ServerIdentityCipherConfig{}, nil) 182 }) 183 t.Run("256", func(t *testing.T) { 184 testShadowStreamReadWriterWithCipher(t, clientCipherConfig256, userCipherConfig256, ServerIdentityCipherConfig{}, nil) 185 }) 186 } 187 188 func TestShadowStreamReadWriterWithEIH(t *testing.T) { 189 clientCipherConfig128, identityCipherConfig128, userLookupMap128, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-128-gcm", false) 190 if err != nil { 191 t.Fatal(err) 192 } 193 clientCipherConfig256, identityCipherConfig256, userLookupMap256, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-256-gcm", false) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 t.Run("128", func(t *testing.T) { 199 testShadowStreamReadWriterWithCipher(t, clientCipherConfig128, UserCipherConfig{}, identityCipherConfig128, userLookupMap128) 200 }) 201 t.Run("256", func(t *testing.T) { 202 testShadowStreamReadWriterWithCipher(t, clientCipherConfig256, UserCipherConfig{}, identityCipherConfig256, userLookupMap256) 203 }) 204 }