github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/ss2022/udp_test.go (about) 1 package ss2022 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "errors" 8 "net/netip" 9 "testing" 10 "time" 11 12 "github.com/database64128/shadowsocks-go/conn" 13 ) 14 15 const ( 16 name = "test" 17 mtu = 1500 18 packetSize = 1452 19 payloadLen = 1280 20 fwmark = 10240 21 ) 22 23 // UDP jumbograms. 24 const ( 25 jumboMTU = 128 * 1024 26 jumboPacketSize = 128*1024 - 40 - 8 - 8 27 jumboPayloadLen = 127 * 1024 28 ) 29 30 var ( 31 targetAddr = conn.AddrFromIPPort(targetAddrPort) 32 serverAddr = conn.AddrFromIPPort(serverAddrPort) 33 targetAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 53) 34 serverAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 1080) 35 clientAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 10800) 36 replayClientAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 10801) 37 replayServerAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 10802) 38 ) 39 40 func testUDPClientServer(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap, clientShouldPad, serverShouldPad PaddingPolicy, mtu, packetSize, payloadLen int) { 41 c := NewUDPClient(name, "ip", serverAddr, mtu, conn.DefaultUDPClientListenConfig, DefaultSlidingWindowFilterSize, clientCipherConfig, clientShouldPad) 42 s := NewUDPServer(DefaultSlidingWindowFilterSize, userCipherConfig, identityCipherConfig, serverShouldPad) 43 s.ReplaceUserLookupMap(userLookupMap) 44 45 clientInfo := c.Info() 46 if clientInfo.Name != name { 47 t.Errorf("Fixed name mismatch: in: %s, out: %s", name, clientInfo.Name) 48 } 49 50 _, clientSession, err := c.NewSession(ctx) 51 if err != nil { 52 t.Fatal(err) 53 } 54 defer clientSession.Close() 55 56 if clientSession.MaxPacketSize != packetSize { 57 t.Errorf("Fixed MTU mismatch: in: %d, out: %d", mtu, clientSession.MaxPacketSize) 58 } 59 60 frontHeadroom := clientInfo.PackerHeadroom.Front + 8 // Compensate for server message overhead. 61 rearHeadroom := clientInfo.PackerHeadroom.Rear 62 b := make([]byte, frontHeadroom+payloadLen+rearHeadroom) 63 payload := b[frontHeadroom : frontHeadroom+payloadLen] 64 65 // Fill random payload. 66 _, err = rand.Read(payload) 67 if err != nil { 68 t.Fatal(err) 69 } 70 71 // Backup payload. 72 payloadBackup := make([]byte, len(payload)) 73 copy(payloadBackup, payload) 74 75 // Client packs. 76 dap, pkts, pktl, err := clientSession.Packer.PackInPlace(ctx, b, targetAddr, frontHeadroom, payloadLen) 77 if err != nil { 78 t.Fatal(err) 79 } 80 if dap != serverAddrPort { 81 t.Errorf("Expected packed client packet destAddrPort %s, got %s", serverAddrPort, dap) 82 } 83 p := b[pkts : pkts+pktl] 84 85 // Server unpacks. 86 csid, err := s.SessionInfo(p) 87 if err != nil { 88 t.Fatal(err) 89 } 90 serverUnpacker, _, err := s.NewUnpacker(p, csid) 91 if err != nil { 92 t.Fatal(err) 93 } 94 ta, ps, pl, err := serverUnpacker.UnpackInPlace(b, clientAddrPort, pkts, pktl) 95 if err != nil { 96 t.Error(err) 97 } 98 99 // Check target address. 100 if !ta.Equals(targetAddr) { 101 t.Errorf("Target address mismatch: c: %s, s: %s", targetAddr, ta) 102 } 103 104 // Check payload. 105 p = b[ps : ps+pl] 106 if !bytes.Equal(payloadBackup, p) { 107 t.Errorf("Payload mismatch: c: %v, s: %v", payloadBackup, p) 108 } 109 110 // Fill random again. 111 _, err = rand.Read(payload) 112 if err != nil { 113 t.Fatal(err) 114 } 115 copy(payloadBackup, payload) 116 117 // Server packs. 118 serverPacker, err := serverUnpacker.NewPacker() 119 if err != nil { 120 t.Fatal(err) 121 } 122 pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize) 123 if err != nil { 124 t.Fatal(err) 125 } 126 127 // Client unpacks. 128 tap, ps, pl, err := clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl) 129 if err != nil { 130 t.Error(err) 131 } 132 133 // Check target address. 134 if tap != targetAddrPort { 135 t.Errorf("Target address mismatch: s: %s, c: %s", targetAddrPort, tap) 136 } 137 138 // Check payload. 139 p = b[ps : ps+pl] 140 if !bytes.Equal(payloadBackup, p) { 141 t.Errorf("Payload mismatch: s: %v, c: %v", payloadBackup, p) 142 } 143 } 144 145 func testUDPClientServerSessionChangeAndReplay(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) { 146 shouldPad, err := ParsePaddingPolicy("") 147 if err != nil { 148 t.Fatal(err) 149 } 150 151 c := NewUDPClient(name, "ip", serverAddr, mtu, conn.DefaultUDPClientListenConfig, DefaultSlidingWindowFilterSize, clientCipherConfig, shouldPad) 152 s := NewUDPServer(DefaultSlidingWindowFilterSize, userCipherConfig, identityCipherConfig, shouldPad) 153 s.ReplaceUserLookupMap(userLookupMap) 154 155 clientInfo, clientSession, err := c.NewSession(ctx) 156 if err != nil { 157 t.Fatal(err) 158 } 159 defer clientSession.Close() 160 161 frontHeadroom := clientInfo.PackerHeadroom.Front + 8 // Compensate for server message overhead. 162 rearHeadroom := clientInfo.PackerHeadroom.Rear 163 b := make([]byte, frontHeadroom+payloadLen+rearHeadroom) 164 165 // Client packs. 166 dap, pkts, pktl, err := clientSession.Packer.PackInPlace(ctx, b, targetAddr, frontHeadroom, payloadLen) 167 if err != nil { 168 t.Fatal(err) 169 } 170 if dap != serverAddrPort { 171 t.Errorf("Expected packed client packet destAddrPort %s, got %s", serverAddrPort, dap) 172 } 173 p := b[pkts : pkts+pktl] 174 175 // Server processes client packet. 176 csid, err := s.SessionInfo(p) 177 if err != nil { 178 t.Fatal(err) 179 } 180 serverUnpacker, _, err := s.NewUnpacker(p, csid) 181 if err != nil { 182 t.Fatal(err) 183 } 184 185 // Backup processed client packet. 186 pb := make([]byte, pktl) 187 copy(pb, p) 188 189 // Server unpacks. 190 _, _, _, err = serverUnpacker.UnpackInPlace(b, clientAddrPort, pkts, pktl) 191 if err != nil { 192 t.Error(err) 193 } 194 195 // Server unpacks the same packet again. 196 _, _, _, err = serverUnpacker.UnpackInPlace(pb, replayClientAddrPort, 0, pktl) 197 var sprErr *ShadowPacketReplayError 198 if !errors.As(err, &sprErr) { 199 t.Errorf("Expected ShadowPacketReplayError, got %T", err) 200 } 201 if sprErr.srcAddr != replayClientAddrPort { 202 t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayClientAddrPort, sprErr.srcAddr) 203 } 204 if sprErr.sid != csid { 205 t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", csid, sprErr.sid) 206 } 207 if sprErr.pid != 0 { 208 t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid) 209 } 210 211 // Server packs. 212 serverPacker, err := serverUnpacker.NewPacker() 213 if err != nil { 214 t.Fatal(err) 215 } 216 pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize) 217 if err != nil { 218 t.Fatal(err) 219 } 220 ssid0 := serverPacker.(*ShadowPacketServerPacker).ssid 221 222 // Backup packed server packet. 223 pb0 := make([]byte, pktl) 224 copy(pb0, b[pkts:pkts+pktl]) 225 226 // Client unpacks. 227 _, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl) 228 if err != nil { 229 t.Error(err) 230 } 231 232 // Refresh server session. 233 serverPacker, err = serverUnpacker.NewPacker() 234 if err != nil { 235 t.Fatal(err) 236 } 237 pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize) 238 if err != nil { 239 t.Fatal(err) 240 } 241 ssid1 := serverPacker.(*ShadowPacketServerPacker).ssid 242 243 // Backup packed server packet. 244 pb1 := make([]byte, pktl) 245 copy(pb1, b[pkts:pkts+pktl]) 246 247 // Trick client into accepting refreshed server session. 248 spcu := clientSession.Unpacker.(*ShadowPacketClientUnpacker) 249 spcu.oldServerSessionLastSeenTime = spcu.oldServerSessionLastSeenTime.Add(-time.Minute - time.Nanosecond) 250 251 // Client unpacks. 252 _, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl) 253 if err != nil { 254 t.Error(err) 255 } 256 257 // Refresh server session again. No tricks this time! 258 serverPacker, err = serverUnpacker.NewPacker() 259 if err != nil { 260 t.Fatal(err) 261 } 262 pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize) 263 if err != nil { 264 t.Fatal(err) 265 } 266 267 // Client unpacks. 268 _, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl) 269 if err != ErrTooManyServerSessions { 270 t.Errorf("Expected ErrTooManyServerSessions, got %v", err) 271 } 272 273 // Client unpacks pb0. 274 _, _, _, err = clientSession.Unpacker.UnpackInPlace(pb0, replayServerAddrPort, 0, len(pb0)) 275 if !errors.As(err, &sprErr) { 276 t.Errorf("Expected ShadowPacketReplayError, got %T", err) 277 } 278 if sprErr.srcAddr != replayServerAddrPort { 279 t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayServerAddrPort, sprErr.srcAddr) 280 } 281 if sprErr.sid != ssid0 { 282 t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", ssid0, sprErr.sid) 283 } 284 if sprErr.pid != 0 { 285 t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid) 286 } 287 288 // Client unpacks pb1. 289 _, _, _, err = clientSession.Unpacker.UnpackInPlace(pb1, replayServerAddrPort, 0, len(pb1)) 290 if !errors.As(err, &sprErr) { 291 t.Errorf("Expected ShadowPacketReplayError, got %T", err) 292 } 293 if sprErr.srcAddr != replayServerAddrPort { 294 t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayServerAddrPort, sprErr.srcAddr) 295 } 296 if sprErr.sid != ssid1 { 297 t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", ssid1, sprErr.sid) 298 } 299 if sprErr.pid != 0 { 300 t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid) 301 } 302 } 303 304 func testUDPClientServerPaddingPolicy(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap, mtu, packetSize, payloadLen int) { 305 t.Run("NoPadding", func(t *testing.T) { 306 testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, NoPadding, NoPadding, mtu, packetSize, payloadLen) 307 }) 308 t.Run("PadPlainDNS", func(t *testing.T) { 309 testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, PadPlainDNS, PadPlainDNS, mtu, packetSize, payloadLen) 310 }) 311 t.Run("PadAll", func(t *testing.T) { 312 testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, PadAll, PadAll, mtu, packetSize, payloadLen) 313 }) 314 } 315 316 func testUDPClientServerWithCipher(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) { 317 t.Run("Typical", func(t *testing.T) { 318 testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, mtu, packetSize, payloadLen) 319 }) 320 t.Run("EmptyPayload", func(t *testing.T) { 321 testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, mtu, packetSize, 0) 322 }) 323 t.Run("Jumbogram", func(t *testing.T) { 324 testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, jumboMTU, jumboPacketSize, jumboPayloadLen) 325 }) 326 t.Run("SessionChangeAndReplay", func(t *testing.T) { 327 testUDPClientServerSessionChangeAndReplay(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap) 328 }) 329 } 330 331 func TestUDPClientServerNoEIH(t *testing.T) { 332 ctx := context.Background() 333 clientCipherConfig128, userCipherConfig128, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-128-gcm", true) 334 if err != nil { 335 t.Fatal(err) 336 } 337 clientCipherConfig256, userCipherConfig256, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-256-gcm", true) 338 if err != nil { 339 t.Fatal(err) 340 } 341 342 t.Run("128", func(t *testing.T) { 343 testUDPClientServerWithCipher(t, ctx, clientCipherConfig128, userCipherConfig128, ServerIdentityCipherConfig{}, nil) 344 }) 345 t.Run("256", func(t *testing.T) { 346 testUDPClientServerWithCipher(t, ctx, clientCipherConfig256, userCipherConfig256, ServerIdentityCipherConfig{}, nil) 347 }) 348 } 349 350 func TestUDPClientServerWithEIH(t *testing.T) { 351 ctx := context.Background() 352 clientCipherConfig128, identityCipherConfig128, userLookupMap128, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-128-gcm", true) 353 if err != nil { 354 t.Fatal(err) 355 } 356 clientCipherConfig256, identityCipherConfig256, userLookupMap256, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-256-gcm", true) 357 if err != nil { 358 t.Fatal(err) 359 } 360 361 t.Run("128", func(t *testing.T) { 362 testUDPClientServerWithCipher(t, ctx, clientCipherConfig128, UserCipherConfig{}, identityCipherConfig128, userLookupMap128) 363 }) 364 t.Run("256", func(t *testing.T) { 365 testUDPClientServerWithCipher(t, ctx, clientCipherConfig256, UserCipherConfig{}, identityCipherConfig256, userLookupMap256) 366 }) 367 }