machine_lanes_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package handshake
  2. import (
  3. "net/netip"
  4. "testing"
  5. "time"
  6. "github.com/slackhq/nebula/cert"
  7. ct "github.com/slackhq/nebula/cert_test"
  8. "github.com/slackhq/nebula/header"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. )
  12. // newTestLaneMachine is newTestMachine with a lane advert attached.
  13. func newTestLaneMachine(
  14. t *testing.T,
  15. cs *testCertState,
  16. verifier CertVerifier,
  17. initiator bool,
  18. localIndex uint32,
  19. lanes *LaneDetails,
  20. ) *Machine {
  21. t.Helper()
  22. m, err := NewMachine(
  23. cs.version, cs.getCredential,
  24. verifier, func() (uint32, error) { return localIndex, nil },
  25. initiator, header.HandshakeIXPSK0,
  26. lanes,
  27. )
  28. require.NoError(t, err)
  29. return m
  30. }
  31. func doFullLaneHandshake(t *testing.T, initLanes, respLanes *LaneDetails) (initR, respR *Result) {
  32. t.Helper()
  33. ca, _, caKey, _ := ct.NewTestCaCert(
  34. cert.Version2, cert.Curve_CURVE25519, time.Time{}, time.Time{}, nil, nil, nil,
  35. )
  36. caPool := ct.NewTestCAPool(ca)
  37. v := testVerifier(caPool)
  38. initCS := newTestCertState(t, ca, caKey, "initiator", []netip.Prefix{netip.MustParsePrefix("10.0.0.1/24")})
  39. respCS := newTestCertState(t, ca, caKey, "responder", []netip.Prefix{netip.MustParsePrefix("10.0.0.2/24")})
  40. initM := newTestLaneMachine(t, initCS, v, true, 1000, initLanes)
  41. respM := newTestLaneMachine(t, respCS, v, false, 2000, respLanes)
  42. msg1, err := initM.Initiate(nil)
  43. require.NoError(t, err)
  44. resp, respR, err := respM.ProcessPacket(nil, msg1)
  45. require.NoError(t, err)
  46. require.NotNil(t, respR)
  47. _, initR, err = initM.ProcessPacket(nil, resp)
  48. require.NoError(t, err)
  49. require.NotNil(t, initR)
  50. return initR, respR
  51. }
  52. func TestMachineLaneAdvertBothSides(t *testing.T) {
  53. initR, respR := doFullLaneHandshake(t,
  54. &LaneDetails{PortCount: 8, BasePort: 4242},
  55. &LaneDetails{PortCount: 4, BasePort: 5353},
  56. )
  57. // Each side's Result carries the peer's advert.
  58. assert.Equal(t, uint32(4), initR.PeerPortCount)
  59. assert.Equal(t, uint32(5353), initR.PeerBasePort)
  60. assert.Equal(t, uint32(0), initR.PeerLaneIndex)
  61. assert.Equal(t, uint32(8), respR.PeerPortCount)
  62. assert.Equal(t, uint32(4242), respR.PeerBasePort)
  63. assert.Equal(t, uint32(0), respR.PeerLaneIndex)
  64. }
  65. func TestMachineLaneHandshakeCarriesLaneIndex(t *testing.T) {
  66. // A lane handshake: initiator tags its lane number; responder still
  67. // adverts (harmlessly).
  68. initR, respR := doFullLaneHandshake(t,
  69. &LaneDetails{PortCount: 8, BasePort: 4242, LaneIndex: 3},
  70. &LaneDetails{PortCount: 4, BasePort: 5353},
  71. )
  72. assert.Equal(t, uint32(3), respR.PeerLaneIndex)
  73. assert.Equal(t, uint32(0), initR.PeerLaneIndex)
  74. }
  75. func TestMachineLaneAdvertAsymmetric(t *testing.T) {
  76. // Vanilla initiator, multiport responder and vice versa: the nil side
  77. // yields all-zero peer fields on the other end.
  78. initR, respR := doFullLaneHandshake(t, nil, &LaneDetails{PortCount: 4, BasePort: 5353})
  79. assert.Equal(t, uint32(4), initR.PeerPortCount)
  80. assert.Equal(t, uint32(0), respR.PeerPortCount)
  81. assert.Equal(t, uint32(0), respR.PeerBasePort)
  82. initR, respR = doFullLaneHandshake(t, &LaneDetails{PortCount: 8, BasePort: 4242}, nil)
  83. assert.Equal(t, uint32(0), initR.PeerPortCount)
  84. assert.Equal(t, uint32(8), respR.PeerPortCount)
  85. }
  86. func TestMachineLaneAdvertOutOfRangeIgnored(t *testing.T) {
  87. // A BasePort that can't be a real UDP port is ignored, not fatal.
  88. initR, respR := doFullLaneHandshake(t,
  89. &LaneDetails{PortCount: 8, BasePort: 70000},
  90. &LaneDetails{PortCount: 4, BasePort: 5353},
  91. )
  92. assert.Equal(t, uint32(0), respR.PeerPortCount)
  93. assert.Equal(t, uint32(0), respR.PeerBasePort)
  94. // The sane side still negotiates.
  95. assert.Equal(t, uint32(4), initR.PeerPortCount)
  96. }