udp_mtu_concurrent_test.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package amneziawgnet
  2. import (
  3. "encoding/binary"
  4. "net/netip"
  5. "sync"
  6. "testing"
  7. "time"
  8. "gvisor.dev/gvisor/pkg/tcpip/header"
  9. )
  10. func TestWriteUDPReplyConcurrentSources(t *testing.T) {
  11. tun, gstack, err := createNetTUNWithStack([]netip.Addr{netip.MustParseAddr("10.77.0.1")}, 1280)
  12. if err != nil {
  13. t.Fatal(err)
  14. }
  15. defer tun.Close()
  16. enablePromiscuousRouting(gstack)
  17. const replies = 32
  18. to := netip.MustParseAddrPort("10.77.0.2:49152")
  19. var wg sync.WaitGroup
  20. errs := make(chan error, replies)
  21. for i := range replies {
  22. wg.Add(1)
  23. go func() {
  24. defer wg.Done()
  25. from := netip.AddrPortFrom(netip.MustParseAddr("203.0.113.9"), uint16(10000+i))
  26. var payload [2]byte
  27. binary.BigEndian.PutUint16(payload[:], uint16(i))
  28. errs <- WriteUDPReply(gstack, from, to, payload[:])
  29. }()
  30. }
  31. wg.Wait()
  32. close(errs)
  33. for err := range errs {
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. }
  38. seen := make(map[uint16]bool)
  39. for range replies {
  40. select {
  41. case v := <-tun.(*stackTun).incomingPacket:
  42. packet := append([]byte(nil), v.AsSlice()...)
  43. v.Release()
  44. if len(packet) > 1280 {
  45. t.Fatalf("packet length %d", len(packet))
  46. }
  47. ip := header.IPv4(packet)
  48. udp := packet[ip.HeaderLength():]
  49. port := binary.BigEndian.Uint16(udp[0:2])
  50. index := binary.BigEndian.Uint16(udp[8:10])
  51. if index >= replies || port != 10000+index || seen[index] || binary.BigEndian.Uint16(udp[2:4]) != to.Port() {
  52. t.Fatalf("duplicate/corrupt concurrent reply: port %d index %d", port, index)
  53. }
  54. seen[index] = true
  55. case <-time.After(time.Second):
  56. t.Fatal("concurrent replies missing")
  57. }
  58. }
  59. }