udp_ecn_outer_linux_test.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. //go:build linux && !android && !e2e_testing
  2. package udp
  3. import (
  4. "net/netip"
  5. "testing"
  6. )
  7. // TestPlanRunBreaksOnECNChange confirms that two same-destination, same-size
  8. // packets with different outer ECN end up in separate sendmmsg entries (the
  9. // kernel stamps one outer codepoint per entry, so a run that straddled the
  10. // boundary would silently lose information).
  11. func TestPlanRunBreaksOnECNChange(t *testing.T) {
  12. u := &batchWriter{gsoSupported: true, maxGSOSegments: 63}
  13. dst := netip.MustParseAddrPort("10.0.0.1:4242")
  14. bufs := [][]byte{
  15. make([]byte, 1200),
  16. make([]byte, 1200),
  17. make([]byte, 1200),
  18. }
  19. addrs := []netip.AddrPort{dst, dst, dst}
  20. t.Run("uniform_ecn_runs_together", func(t *testing.T) {
  21. ecns := []byte{0x02, 0x02, 0x02}
  22. runLen, segSize := u.planRun(bufs, addrs, ecns, 0, 64)
  23. if runLen != 3 {
  24. t.Errorf("runLen=%d want 3 (uniform ECT(0))", runLen)
  25. }
  26. if segSize != 1200 {
  27. t.Errorf("segSize=%d want 1200", segSize)
  28. }
  29. })
  30. t.Run("ecn_change_truncates_run", func(t *testing.T) {
  31. // 0,0,3: first two run together, CE seeds a fresh entry.
  32. ecns := []byte{0x00, 0x00, 0x03}
  33. runLen, _ := u.planRun(bufs, addrs, ecns, 0, 64)
  34. if runLen != 2 {
  35. t.Errorf("runLen=%d want 2 (ECN changes at index 2)", runLen)
  36. }
  37. })
  38. t.Run("nil_ecns_runs_full", func(t *testing.T) {
  39. runLen, _ := u.planRun(bufs, addrs, nil, 0, 64)
  40. if runLen != 3 {
  41. t.Errorf("runLen=%d want 3 (nil ecns means no break)", runLen)
  42. }
  43. })
  44. t.Run("first_ecn_is_singleton", func(t *testing.T) {
  45. // Second packet has different ECN from the first → run halts at 1
  46. // (the first packet alone forms the run).
  47. ecns := []byte{0x00, 0x03, 0x03}
  48. runLen, _ := u.planRun(bufs, addrs, ecns, 0, 64)
  49. if runLen != 1 {
  50. t.Errorf("runLen=%d want 1 (different ECN immediately)", runLen)
  51. }
  52. })
  53. }