bench_test.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package e2e
  4. import (
  5. "testing"
  6. "time"
  7. "github.com/slackhq/nebula/cert"
  8. "github.com/slackhq/nebula/cert_test"
  9. "github.com/slackhq/nebula/e2e/router"
  10. )
  11. // BenchmarkHandshake measures end-to-end tunnel establishment time. The two
  12. // nodes and the router are constructed once before the loop so the timed window
  13. // is just the handshake itself: trigger packet -> handshake1 -> handshake2 ->
  14. // cached packet replay -> arrival on the remote TUN. Between iterations we
  15. // tear down both sides locally (no CloseTunnel notification on the wire) and
  16. // re-inject the lighthouse address that closeTunnel cleared, so the next
  17. // iteration runs through a fresh handshake against the same harness.
  18. func BenchmarkHandshake(b *testing.B) {
  19. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version2, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  20. // Default try_interval is 100ms. The handshake manager schedules handshake1
  21. // on its OutboundHandshakeTimer rather than firing immediately on trigger
  22. // (the trigger channel only fast-paths static hosts), so a 100ms default
  23. // drowns the actual handshake cost. Drop it to 1ms so the bench reflects
  24. // the computation, not the wheel cadence.
  25. bovr := m{"handshakes": m{"try_interval": "1ms"}}
  26. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version2, ca, caKey, "me", "10.128.0.1/24", bovr)
  27. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version2, ca, caKey, "them", "10.128.0.2/24", bovr)
  28. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  29. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  30. myControl.Start()
  31. theirControl.Start()
  32. defer myControl.Stop()
  33. defer theirControl.Stop()
  34. r := router.NewR(b, myControl, theirControl)
  35. r.CancelFlowLogs()
  36. r.EnableFanIn()
  37. trigger := BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi from me"))
  38. b.ReportAllocs()
  39. b.ResetTimer()
  40. for n := 0; n < b.N; n++ {
  41. myControl.InjectTunPacket(trigger)
  42. // RouteForAllUntilTxTun returns the moment the cached packet arrives at
  43. // the remote TUN, which is also when both sides are fully established.
  44. _ = r.RouteForAllUntilTxTun(theirControl)
  45. b.StopTimer()
  46. // Local-only close removes hostmap state on both sides without putting a
  47. // CloseTunnel packet on the wire that we'd then have to drain. The
  48. // closeTunnel path also clears learned lighthouse state for the peer
  49. // when the last hostinfo for that addr goes away, so we re-inject.
  50. myControl.CloseTunnel(theirVpnIpNet[0].Addr(), true)
  51. theirControl.CloseTunnel(myVpnIpNet[0].Addr(), true)
  52. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  53. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  54. b.StartTimer()
  55. }
  56. }