mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-16 11:26:59 +02:00
port offsets for peer mismatch
This commit is contained in:
+57
-1
@@ -27,7 +27,7 @@ func newTestBaseHostInfo(vpnIp netip.Addr, localIdx, remoteIdx uint32, laneCount
|
||||
HandshakePacket: map[uint8][]byte{},
|
||||
}
|
||||
base.SetRemote(netip.MustParseAddrPort("192.0.2.1:4242"))
|
||||
base.lanes = newLaneState(laneCount, uint16(laneCount), 4242)
|
||||
base.lanes = newLaneState(laneCount, uint16(laneCount), 4242, 0)
|
||||
return base
|
||||
}
|
||||
|
||||
@@ -47,6 +47,62 @@ func newTestLaneHostInfo(base *HostInfo, laneIndex uint16, localIdx, remoteIdx u
|
||||
return lane
|
||||
}
|
||||
|
||||
func TestLanePortOffset(t *testing.T) {
|
||||
a := netip.MustParseAddr("10.0.0.1")
|
||||
b := netip.MustParseAddr("10.0.0.2")
|
||||
|
||||
// Deterministic and in range.
|
||||
for _, count := range []uint16{1, 2, 3, 4, 16, 256} {
|
||||
o := lanePortOffset(a, b, count)
|
||||
assert.Equal(t, o, lanePortOffset(a, b, count), "count %d not deterministic", count)
|
||||
assert.Less(t, o, count, "count %d out of range", count)
|
||||
}
|
||||
assert.Equal(t, uint16(0), lanePortOffset(a, b, 0), "zero port count")
|
||||
|
||||
// The two sides' rotations cancel when port counts match, preserving the
|
||||
// lane-i-reverses-lane-j conntrack pairing.
|
||||
for _, count := range []uint16{2, 3, 4, 7, 16} {
|
||||
for i := range 32 {
|
||||
peer := netip.AddrFrom4([4]byte{192, 0, 2, byte(i)})
|
||||
oA := lanePortOffset(a, peer, count)
|
||||
oB := lanePortOffset(peer, a, count)
|
||||
assert.Equal(t, uint16(0), (oA+oB)%count,
|
||||
"offsets don't cancel for peer %s count %d", peer, count)
|
||||
}
|
||||
}
|
||||
|
||||
// Distinct small peers land on distinct rotations of a big peer's range,
|
||||
// not all on the same first ports.
|
||||
const bigPeerPorts = 16
|
||||
distinct := map[uint16]struct{}{}
|
||||
for i := range 64 {
|
||||
client := netip.AddrFrom4([4]byte{192, 0, 2, byte(i)})
|
||||
distinct[lanePortOffset(client, a, bigPeerPorts)] = struct{}{}
|
||||
}
|
||||
assert.GreaterOrEqual(t, len(distinct), 8, "64 clients only produced %d distinct offsets", len(distinct))
|
||||
}
|
||||
|
||||
func TestLaneTargetPort(t *testing.T) {
|
||||
// No rotation: lane i targets base+i, wrapping past the peer's range.
|
||||
ls := newLaneState(4, 4, 4242, 0)
|
||||
for i, want := range map[int]uint16{1: 4243, 2: 4244, 3: 4245, 5: 4243} {
|
||||
assert.Equal(t, want, ls.laneTargetPort(i), "lane %d", i)
|
||||
}
|
||||
|
||||
// Rotation shifts the whole mapping; the wrapped lane lands on the base
|
||||
// port itself, which is a valid distinct 4-tuple (our source port differs).
|
||||
ls = newLaneState(4, 4, 4242, 3)
|
||||
for i, want := range map[int]uint16{1: 4242, 2: 4243, 3: 4244} {
|
||||
assert.Equal(t, want, ls.laneTargetPort(i), "rotated lane %d", i)
|
||||
}
|
||||
|
||||
// Fewer peer ports than local lanes: rotation still spreads across all of
|
||||
// the peer's ports.
|
||||
ls = newLaneState(16, 2, 4242, 1)
|
||||
assert.Equal(t, uint16(4242), ls.laneTargetPort(1))
|
||||
assert.Equal(t, uint16(4243), ls.laneTargetPort(2))
|
||||
}
|
||||
|
||||
func TestLaneHostmapLifecycle(t *testing.T) {
|
||||
l := test.NewLogger()
|
||||
hostMap := newHostMap(l)
|
||||
|
||||
Reference in New Issue
Block a user