123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- package nebula
- import (
- "net"
- "testing"
- "time"
- "github.com/slackhq/nebula/header"
- "github.com/slackhq/nebula/iputil"
- "github.com/slackhq/nebula/test"
- "github.com/slackhq/nebula/udp"
- "github.com/stretchr/testify/assert"
- )
- func Test_NewHandshakeManagerVpnIp(t *testing.T) {
- l := test.NewLogger()
- _, tuncidr, _ := net.ParseCIDR("172.1.1.1/24")
- _, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
- _, localrange, _ := net.ParseCIDR("10.1.1.1/24")
- ip := iputil.Ip2VpnIp(net.ParseIP("172.1.1.2"))
- preferredRanges := []*net.IPNet{localrange}
- mw := &mockEncWriter{}
- mainHM := NewHostMap(l, "test", vpncidr, preferredRanges)
- lh := &LightHouse{
- atomicStaticList: make(map[iputil.VpnIp]struct{}),
- atomicLighthouses: make(map[iputil.VpnIp]struct{}),
- addrMap: make(map[iputil.VpnIp]*RemoteList),
- }
- blah := NewHandshakeManager(l, tuncidr, preferredRanges, mainHM, lh, &udp.Conn{}, defaultHandshakeConfig)
- now := time.Now()
- blah.NextOutboundHandshakeTimerTick(now, mw)
- var initCalled bool
- initFunc := func(*HostInfo) {
- initCalled = true
- }
- i := blah.AddVpnIp(ip, initFunc)
- assert.True(t, initCalled)
- initCalled = false
- i2 := blah.AddVpnIp(ip, initFunc)
- assert.False(t, initCalled)
- assert.Same(t, i, i2)
- i.remotes = NewRemoteList()
- i.HandshakeReady = true
- // Adding something to pending should not affect the main hostmap
- assert.Len(t, mainHM.Hosts, 0)
- // Confirm they are in the pending index list
- assert.Contains(t, blah.pendingHostMap.Hosts, ip)
- // Jump ahead `HandshakeRetries` ticks, offset by one to get the sleep logic right
- for i := 1; i <= DefaultHandshakeRetries+1; i++ {
- now = now.Add(time.Duration(i) * DefaultHandshakeTryInterval)
- blah.NextOutboundHandshakeTimerTick(now, mw)
- }
- // Confirm they are still in the pending index list
- assert.Contains(t, blah.pendingHostMap.Hosts, ip)
- // Tick 1 more time, a minute will certainly flush it out
- blah.NextOutboundHandshakeTimerTick(now.Add(time.Minute), mw)
- // Confirm they have been removed
- assert.NotContains(t, blah.pendingHostMap.Hosts, ip)
- }
- func Test_NewHandshakeManagerTrigger(t *testing.T) {
- l := test.NewLogger()
- _, tuncidr, _ := net.ParseCIDR("172.1.1.1/24")
- _, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
- _, localrange, _ := net.ParseCIDR("10.1.1.1/24")
- ip := iputil.Ip2VpnIp(net.ParseIP("172.1.1.2"))
- preferredRanges := []*net.IPNet{localrange}
- mw := &mockEncWriter{}
- mainHM := NewHostMap(l, "test", vpncidr, preferredRanges)
- lh := &LightHouse{
- addrMap: make(map[iputil.VpnIp]*RemoteList),
- l: l,
- atomicStaticList: make(map[iputil.VpnIp]struct{}),
- atomicLighthouses: make(map[iputil.VpnIp]struct{}),
- }
- blah := NewHandshakeManager(l, tuncidr, preferredRanges, mainHM, lh, &udp.Conn{}, defaultHandshakeConfig)
- now := time.Now()
- blah.NextOutboundHandshakeTimerTick(now, mw)
- assert.Equal(t, 0, testCountTimerWheelEntries(blah.OutboundHandshakeTimer))
- hi := blah.AddVpnIp(ip, nil)
- hi.HandshakeReady = true
- assert.Equal(t, 1, testCountTimerWheelEntries(blah.OutboundHandshakeTimer))
- assert.Equal(t, 0, hi.HandshakeCounter, "Should not have attempted a handshake yet")
- // Trigger the same method the channel will but, this should set our remotes pointer
- blah.handleOutbound(ip, mw, true)
- assert.Equal(t, 1, hi.HandshakeCounter, "Trigger should have done a handshake attempt")
- assert.NotNil(t, hi.remotes, "Manager should have set my remotes pointer")
- // Make sure the trigger doesn't double schedule the timer entry
- assert.Equal(t, 1, testCountTimerWheelEntries(blah.OutboundHandshakeTimer))
- uaddr := udp.NewAddrFromString("10.1.1.1:4242")
- hi.remotes.unlockedPrependV4(ip, NewIp4AndPort(uaddr.IP, uint32(uaddr.Port)))
- // We now have remotes but only the first trigger should have pushed things forward
- blah.handleOutbound(ip, mw, true)
- assert.Equal(t, 1, hi.HandshakeCounter, "Trigger should have not done a handshake attempt")
- assert.Equal(t, 1, testCountTimerWheelEntries(blah.OutboundHandshakeTimer))
- }
- func testCountTimerWheelEntries(tw *SystemTimerWheel) (c int) {
- for _, i := range tw.wheel {
- n := i.Head
- for n != nil {
- c++
- n = n.Next
- }
- }
- return c
- }
- type mockEncWriter struct {
- }
- func (mw *mockEncWriter) SendMessageToVpnIp(t header.MessageType, st header.MessageSubType, vpnIp iputil.VpnIp, p, nb, out []byte) {
- return
- }
- func (mw *mockEncWriter) SendVia(via interface{}, relay interface{}, ad, nb, out []byte, nocopy bool) {
- return
- }
- func (mw *mockEncWriter) Handshake(vpnIP iputil.VpnIp) {}
|