diff --git a/control_test.go b/control_test.go
index cd6364068..0f21ed92a 100644
--- a/control_test.go
+++ b/control_test.go
@@ -35,7 +35,7 @@ func TestControl_GetHostInfoByVpnIp(t *testing.T) {
Mask: net.IPMask{255, 255, 255, 0},
}
- remotes := NewRemoteList(nil)
+ remotes := NewRemoteList([]netip.Addr{netip.IPv4Unspecified()}, nil)
remotes.unlockedPrependV4(netip.IPv4Unspecified(), netAddrToProtoV4AddrPort(remote1.Addr(), remote1.Port()))
remotes.unlockedPrependV6(netip.IPv4Unspecified(), netAddrToProtoV6AddrPort(remote2.Addr(), remote2.Port()))
diff --git a/e2e/handshakes_test.go b/e2e/handshakes_test.go
index 383478af8..11d2f6724 100644
--- a/e2e/handshakes_test.go
+++ b/e2e/handshakes_test.go
@@ -4,7 +4,6 @@
package e2e
import (
- "fmt"
"net/netip"
"slices"
"testing"
@@ -12,6 +11,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/slackhq/nebula"
+ "github.com/slackhq/nebula/cert"
"github.com/slackhq/nebula/e2e/router"
"github.com/slackhq/nebula/header"
"github.com/slackhq/nebula/udp"
@@ -21,8 +21,8 @@ import (
func BenchmarkHotPath(b *testing.B) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, _, _ := newSimpleServer(ca, caKey, "me", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Put their info in our lighthouse
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -45,8 +45,8 @@ func BenchmarkHotPath(b *testing.B) {
func TestGoodHandshake(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Put their info in our lighthouse
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -100,9 +100,9 @@ func TestWrongResponderHandshake(t *testing.T) {
// The IPs here are chosen on purpose:
// The current remote handling will sort by preference, public, and then lexically.
// So we need them to have a higher address than evil (we could apply a preference though)
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me", "10.128.0.100/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.99/24", nil)
- evilControl, evilVpnIp, evilUdpAddr, _ := newSimpleServer(ca, caKey, "evil", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.100/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.99/24", nil)
+ evilControl, evilVpnIp, evilUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "evil", "10.128.0.2/24", nil)
// Add their real udp addr, which should be tried after evil.
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -165,8 +165,8 @@ func TestStage1Race(t *testing.T) {
// But will eventually collapse down to a single tunnel
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Put their info in our lighthouse and vice versa
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -242,8 +242,8 @@ func TestStage1Race(t *testing.T) {
func TestUncleanShutdownRaceLoser(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -291,8 +291,8 @@ func TestUncleanShutdownRaceLoser(t *testing.T) {
func TestUncleanShutdownRaceWinner(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -342,9 +342,9 @@ func TestUncleanShutdownRaceWinner(t *testing.T) {
func TestRelays(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, _, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
- relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
+ myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
+ relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(relayVpnIpNet[0].Addr(), relayUdpAddr)
@@ -373,9 +373,9 @@ func TestRelays(t *testing.T) {
func TestStage1RaceRelays(t *testing.T) {
//NOTE: this is a race between me and relay resulting in a full tunnel from me to them via relay
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
- relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
+ relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(relayVpnIpNet[0].Addr(), relayUdpAddr)
@@ -422,9 +422,9 @@ func TestStage1RaceRelays(t *testing.T) {
func TestStage1RaceRelays2(t *testing.T) {
//NOTE: this is a race between me and relay resulting in a full tunnel from me to them via relay
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
- relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
+ relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
l := NewTestLogger()
// Teach my how to get to the relay and that their can be reached via the relay
@@ -510,9 +510,9 @@ func TestStage1RaceRelays2(t *testing.T) {
func TestRehandshakingRelays(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, _, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
- relayControl, relayVpnIpNet, relayUdpAddr, relayConfig := newSimpleServer(ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
+ myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
+ relayControl, relayVpnIpNet, relayUdpAddr, relayConfig := newSimpleServer(cert.Version1, ca, caKey, "relay ", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(relayVpnIpNet[0].Addr(), relayUdpAddr)
@@ -539,7 +539,7 @@ func TestRehandshakingRelays(t *testing.T) {
// When I update the certificate for the relay, both me and them will have 2 host infos for the relay,
// and the main host infos will not have any relay state to handle the me<->relay<->them tunnel.
r.Log("Renew relay certificate and spin until me and them sees it")
- _, _, myNextPrivKey, myNextPEM := NewTestCert(ca, caKey, "relay", time.Now(), time.Now().Add(5*time.Minute), relayVpnIpNet, nil, []string{"new group"})
+ _, _, myNextPrivKey, myNextPEM := NewTestCert(cert.Version1, ca, caKey, "relay", time.Now(), time.Now().Add(5*time.Minute), relayVpnIpNet, nil, []string{"new group"})
caB, err := ca.MarshalPEM()
if err != nil {
@@ -614,9 +614,9 @@ func TestRehandshakingRelays(t *testing.T) {
func TestRehandshakingRelaysPrimary(t *testing.T) {
// This test is the same as TestRehandshakingRelays but one of the terminal types is a primary swap winner
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, _, _ := newSimpleServer(ca, caKey, "me ", "10.128.0.128/24", m{"relay": m{"use_relays": true}})
- relayControl, relayVpnIpNet, relayUdpAddr, relayConfig := newSimpleServer(ca, caKey, "relay ", "10.128.0.1/24", m{"relay": m{"am_relay": true}})
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
+ myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.128/24", m{"relay": m{"use_relays": true}})
+ relayControl, relayVpnIpNet, relayUdpAddr, relayConfig := newSimpleServer(cert.Version1, ca, caKey, "relay ", "10.128.0.1/24", m{"relay": m{"am_relay": true}})
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them ", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
// Teach my how to get to the relay and that their can be reached via the relay
myControl.InjectLightHouseAddr(relayVpnIpNet[0].Addr(), relayUdpAddr)
@@ -643,7 +643,7 @@ func TestRehandshakingRelaysPrimary(t *testing.T) {
// When I update the certificate for the relay, both me and them will have 2 host infos for the relay,
// and the main host infos will not have any relay state to handle the me<->relay<->them tunnel.
r.Log("Renew relay certificate and spin until me and them sees it")
- _, _, myNextPrivKey, myNextPEM := NewTestCert(ca, caKey, "relay", time.Now(), time.Now().Add(5*time.Minute), relayVpnIpNet, nil, []string{"new group"})
+ _, _, myNextPrivKey, myNextPEM := NewTestCert(cert.Version1, ca, caKey, "relay", time.Now(), time.Now().Add(5*time.Minute), relayVpnIpNet, nil, []string{"new group"})
caB, err := ca.MarshalPEM()
if err != nil {
@@ -717,8 +717,8 @@ func TestRehandshakingRelaysPrimary(t *testing.T) {
func TestRehandshaking(t *testing.T) {
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, myConfig := newSimpleServer(ca, caKey, "me ", "10.128.0.2/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, theirConfig := newSimpleServer(ca, caKey, "them", "10.128.0.1/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, myConfig := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.2/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, theirConfig := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.1/24", nil)
// Put their info in our lighthouse and vice versa
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -738,7 +738,7 @@ func TestRehandshaking(t *testing.T) {
r.RenderHostmaps("Starting hostmaps", myControl, theirControl)
r.Log("Renew my certificate and spin until their sees it")
- _, _, myNextPrivKey, myNextPEM := NewTestCert(ca, caKey, "me", time.Now(), time.Now().Add(5*time.Minute), myVpnIpNet, nil, []string{"new group"})
+ _, _, myNextPrivKey, myNextPEM := NewTestCert(cert.Version1, ca, caKey, "me", time.Now(), time.Now().Add(5*time.Minute), myVpnIpNet, nil, []string{"new group"})
caB, err := ca.MarshalPEM()
if err != nil {
@@ -814,8 +814,8 @@ func TestRehandshakingLoser(t *testing.T) {
// The purpose of this test is that the race loser renews their certificate and rehandshakes. The final tunnel
// Should be the one with the new certificate
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, myConfig := newSimpleServer(ca, caKey, "me ", "10.128.0.2/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, theirConfig := newSimpleServer(ca, caKey, "them", "10.128.0.1/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, myConfig := newSimpleServer(cert.Version1, ca, caKey, "me ", "10.128.0.2/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, theirConfig := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.1/24", nil)
// Put their info in our lighthouse and vice versa
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -832,14 +832,10 @@ func TestRehandshakingLoser(t *testing.T) {
t.Log("Stand up a tunnel between me and them")
assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
- tt1 := myControl.GetHostInfoByVpnAddr(theirVpnIpNet[0].Addr(), false)
- tt2 := theirControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false)
- fmt.Println(tt1.LocalIndex, tt2.LocalIndex)
-
r.RenderHostmaps("Starting hostmaps", myControl, theirControl)
r.Log("Renew their certificate and spin until mine sees it")
- _, _, theirNextPrivKey, theirNextPEM := NewTestCert(ca, caKey, "them", time.Now(), time.Now().Add(5*time.Minute), theirVpnIpNet, nil, []string{"their new group"})
+ _, _, theirNextPrivKey, theirNextPEM := NewTestCert(cert.Version1, ca, caKey, "them", time.Now(), time.Now().Add(5*time.Minute), theirVpnIpNet, nil, []string{"their new group"})
caB, err := ca.MarshalPEM()
if err != nil {
@@ -914,8 +910,8 @@ func TestRaceRegression(t *testing.T) {
// We had a bug where we were not finding the duplicate handshake and responding to the final stage 1 which
// caused a cross-linked hostinfo
ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
- myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(ca, caKey, "me", "10.128.0.1/24", nil)
- theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(ca, caKey, "them", "10.128.0.2/24", nil)
+ myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
+ theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
// Put their info in our lighthouse
myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
@@ -970,6 +966,40 @@ func TestRaceRegression(t *testing.T) {
theirControl.Stop()
}
+func TestV2NonPrimaryWithLighthouse(t *testing.T) {
+ ca, _, caKey, _ := NewTestCaCert(time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
+ lhControl, lhVpnIpNet, lhUdpAddr, _ := newSimpleServer(cert.Version2, ca, caKey, "lh ", "10.128.0.1/24, ff::1/64", m{"lighthouse": m{"am_lighthouse": true}})
+
+ o := m{
+ "static_host_map": m{
+ lhVpnIpNet[1].Addr().String(): []string{lhUdpAddr.String()},
+ },
+ "lighthouse": m{
+ "hosts": []string{lhVpnIpNet[1].Addr().String()},
+ },
+ }
+ myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version2, ca, caKey, "me ", "10.128.0.2/24, ff::2/64", o)
+ theirControl, theirVpnIpNet, _, _ := newSimpleServer(cert.Version2, ca, caKey, "them", "10.128.0.3/24, ff::3/64", o)
+
+ // Build a router so we don't have to reason who gets which packet
+ r := router.NewR(t, lhControl, myControl, theirControl)
+ defer r.RenderFlow()
+
+ // Start the servers
+ lhControl.Start()
+ myControl.Start()
+ theirControl.Start()
+
+ t.Log("Stand up an ipv6 tunnel between me and them")
+ assert.True(t, myVpnIpNet[1].Addr().Is6())
+ assert.True(t, theirVpnIpNet[1].Addr().Is6())
+ assertTunnel(t, myVpnIpNet[1].Addr(), theirVpnIpNet[1].Addr(), myControl, theirControl, r)
+
+ lhControl.Stop()
+ myControl.Stop()
+ theirControl.Stop()
+}
+
//TODO: test
// Race winner renews and handshakes
// Race loser renews and handshakes
diff --git a/e2e/helpers.go b/e2e/helpers.go
index c0893aca2..d34d15211 100644
--- a/e2e/helpers.go
+++ b/e2e/helpers.go
@@ -48,7 +48,7 @@ func NewTestCaCert(before, after time.Time, networks, unsafeNetworks []netip.Pre
// NewTestCert will generate a signed certificate with the provided details.
// Expiry times are defaulted if you do not pass them in
-func NewTestCert(ca cert.Certificate, key []byte, name string, before, after time.Time, networks, unsafeNetworks []netip.Prefix, groups []string) (cert.Certificate, []byte, []byte, []byte) {
+func NewTestCert(v cert.Version, ca cert.Certificate, key []byte, name string, before, after time.Time, networks, unsafeNetworks []netip.Prefix, groups []string) (cert.Certificate, []byte, []byte, []byte) {
if before.IsZero() {
before = time.Now().Add(time.Second * -60).Round(time.Second)
}
@@ -59,7 +59,7 @@ func NewTestCert(ca cert.Certificate, key []byte, name string, before, after tim
pub, rawPriv := x25519Keypair()
nc := &cert.TBSCertificate{
- Version: cert.Version1,
+ Version: v,
Name: name,
Networks: networks,
UnsafeNetworks: unsafeNetworks,
diff --git a/e2e/helpers_test.go b/e2e/helpers_test.go
index c8b42b007..72e172bcd 100644
--- a/e2e/helpers_test.go
+++ b/e2e/helpers_test.go
@@ -27,12 +27,12 @@ import (
type m map[string]interface{}
// newSimpleServer creates a nebula instance with many assumptions
-func newSimpleServer(caCrt cert.Certificate, caKey []byte, name string, sVpnNetworks string, overrides m) (*nebula.Control, []netip.Prefix, netip.AddrPort, *config.C) {
+func newSimpleServer(v cert.Version, caCrt cert.Certificate, caKey []byte, name string, sVpnNetworks string, overrides m) (*nebula.Control, []netip.Prefix, netip.AddrPort, *config.C) {
l := NewTestLogger()
var vpnNetworks []netip.Prefix
for _, sn := range strings.Split(sVpnNetworks, ",") {
- vpnIpNet, err := netip.ParsePrefix(sn)
+ vpnIpNet, err := netip.ParsePrefix(strings.TrimSpace(sn))
if err != nil {
panic(err)
}
@@ -55,7 +55,7 @@ func newSimpleServer(caCrt cert.Certificate, caKey []byte, name string, sVpnNetw
budpIp[3] = 239
udpAddr = netip.AddrPortFrom(netip.AddrFrom16(budpIp), 4242)
}
- _, _, myPrivKey, myPEM := NewTestCert(caCrt, caKey, name, time.Now(), time.Now().Add(5*time.Minute), vpnNetworks, nil, []string{})
+ _, _, myPrivKey, myPEM := NewTestCert(v, caCrt, caKey, name, time.Now(), time.Now().Add(5*time.Minute), vpnNetworks, nil, []string{})
caB, err := caCrt.MarshalPEM()
if err != nil {
@@ -99,11 +99,16 @@ func newSimpleServer(caCrt cert.Certificate, caKey []byte, name string, sVpnNetw
}
if overrides != nil {
- err = mergo.Merge(&overrides, mc, mergo.WithAppendSlice)
+ final := m{}
+ err = mergo.Merge(&final, overrides, mergo.WithAppendSlice)
if err != nil {
panic(err)
}
- mc = overrides
+ err = mergo.Merge(&final, mc, mergo.WithAppendSlice)
+ if err != nil {
+ panic(err)
+ }
+ mc = final
}
cb, err := yaml.Marshal(mc)
@@ -191,6 +196,33 @@ func assertHostInfoPair(t *testing.T, addrA, addrB netip.AddrPort, vpnNetsA, vpn
}
func assertUdpPacket(t *testing.T, expected, b []byte, fromIp, toIp netip.Addr, fromPort, toPort uint16) {
+ if toIp.Is6() {
+ assertUdpPacket6(t, expected, b, fromIp, toIp, fromPort, toPort)
+ } else {
+ assertUdpPacket4(t, expected, b, fromIp, toIp, fromPort, toPort)
+ }
+}
+
+func assertUdpPacket6(t *testing.T, expected, b []byte, fromIp, toIp netip.Addr, fromPort, toPort uint16) {
+ packet := gopacket.NewPacket(b, layers.LayerTypeIPv6, gopacket.Lazy)
+ v6 := packet.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
+ assert.NotNil(t, v6, "No ipv6 data found")
+
+ assert.Equal(t, fromIp.AsSlice(), []byte(v6.SrcIP), "Source ip was incorrect")
+ assert.Equal(t, toIp.AsSlice(), []byte(v6.DstIP), "Dest ip was incorrect")
+
+ udp := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
+ assert.NotNil(t, udp, "No udp data found")
+
+ assert.Equal(t, fromPort, uint16(udp.SrcPort), "Source port was incorrect")
+ assert.Equal(t, toPort, uint16(udp.DstPort), "Dest port was incorrect")
+
+ data := packet.ApplicationLayer()
+ assert.NotNil(t, data)
+ assert.Equal(t, expected, data.Payload(), "Data was incorrect")
+}
+
+func assertUdpPacket4(t *testing.T, expected, b []byte, fromIp, toIp netip.Addr, fromPort, toPort uint16) {
packet := gopacket.NewPacket(b, layers.LayerTypeIPv4, gopacket.Lazy)
v4 := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
assert.NotNil(t, v4, "No ipv4 data found")
diff --git a/e2e/router/router.go b/e2e/router/router.go
index 5fa382344..492ef3864 100644
--- a/e2e/router/router.go
+++ b/e2e/router/router.go
@@ -10,8 +10,8 @@ import (
"os"
"path/filepath"
"reflect"
+ "regexp"
"sort"
- "strings"
"sync"
"testing"
"time"
@@ -216,7 +216,7 @@ func (r *R) renderFlow() {
continue
}
participants[addr] = struct{}{}
- sanAddr := strings.Replace(addr.String(), ":", "-", 1)
+ sanAddr := normalizeName(addr.String())
participantsVals = append(participantsVals, sanAddr)
fmt.Fprintf(
f, " participant %s as Nebula: %s
UDP: %s\n",
@@ -253,9 +253,9 @@ func (r *R) renderFlow() {
fmt.Fprintf(f,
" %s%s%s: %s(%s), index %v, counter: %v\n",
- strings.Replace(p.from.GetUDPAddr().String(), ":", "-", 1),
+ normalizeName(p.from.GetUDPAddr().String()),
line,
- strings.Replace(p.to.GetUDPAddr().String(), ":", "-", 1),
+ normalizeName(p.to.GetUDPAddr().String()),
h.TypeName(), h.SubTypeName(), h.RemoteIndex, h.MessageCounter,
)
}
@@ -270,6 +270,11 @@ func (r *R) renderFlow() {
}
}
+func normalizeName(s string) string {
+ rx := regexp.MustCompile("[\\[\\]\\:]")
+ return rx.ReplaceAllLiteralString(s, "_")
+}
+
// IgnoreFlow tells the router to stop recording future flows that matches the provided criteria.
// messageType and subType will target nebula underlay packets while tun will target nebula overlay packets
// NOTE: This is a very broad system, if you set tun to true then no more tun traffic will be rendered
@@ -714,30 +719,42 @@ func (r *R) getControl(fromAddr, toAddr netip.AddrPort, p *udp.Packet) *nebula.C
}
func (r *R) formatUdpPacket(p *packet) string {
- packet := gopacket.NewPacket(p.packet.Data, layers.LayerTypeIPv4, gopacket.Lazy)
- v4 := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
- if v4 == nil {
- panic("not an ipv4 packet")
+ var packet gopacket.Packet
+ var srcAddr netip.Addr
+
+ packet = gopacket.NewPacket(p.packet.Data, layers.LayerTypeIPv6, gopacket.Lazy)
+ if packet.ErrorLayer() == nil {
+ v6 := packet.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
+ if v6 == nil {
+ panic("not an ipv6 packet")
+ }
+ srcAddr, _ = netip.AddrFromSlice(v6.SrcIP)
+ } else {
+ packet = gopacket.NewPacket(p.packet.Data, layers.LayerTypeIPv4, gopacket.Lazy)
+ v6 := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
+ if v6 == nil {
+ panic("not an ipv6 packet")
+ }
+ srcAddr, _ = netip.AddrFromSlice(v6.SrcIP)
}
from := "unknown"
- srcAddr, _ := netip.AddrFromSlice(v4.SrcIP)
if c, ok := r.vpnControls[srcAddr]; ok {
from = c.GetUDPAddr().String()
}
- udp := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
- if udp == nil {
+ udpLayer := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
+ if udpLayer == nil {
panic("not a udp packet")
}
data := packet.ApplicationLayer()
return fmt.Sprintf(
" %s-->>%s: src port: %v
dest port: %v
data: \"%v\"\n",
- strings.Replace(from, ":", "-", 1),
- strings.Replace(p.to.GetUDPAddr().String(), ":", "-", 1),
- udp.SrcPort,
- udp.DstPort,
+ normalizeName(from),
+ normalizeName(p.to.GetUDPAddr().String()),
+ udpLayer.SrcPort,
+ udpLayer.DstPort,
string(data.Payload()),
)
}
diff --git a/handshake_manager.go b/handshake_manager.go
index 6b3902dfa..ee1545647 100644
--- a/handshake_manager.go
+++ b/handshake_manager.go
@@ -607,14 +607,16 @@ func (hm *HandshakeManager) DeleteHostInfo(hostinfo *HostInfo) {
}
func (hm *HandshakeManager) unlockedDeleteHostInfo(hostinfo *HostInfo) {
- //TODO: need to iterate hostinfo.vpnAddrs
- delete(hm.vpnIps, hostinfo.vpnAddrs[0])
+ for _, addr := range hostinfo.vpnAddrs {
+ delete(hm.vpnIps, addr)
+ }
+
if len(hm.vpnIps) == 0 {
hm.vpnIps = map[netip.Addr]*HandshakeHostInfo{}
}
delete(hm.indexes, hostinfo.localIndexId)
- if len(hm.vpnIps) == 0 {
+ if len(hm.indexes) == 0 {
hm.indexes = map[uint32]*HandshakeHostInfo{}
}
diff --git a/handshake_manager_test.go b/handshake_manager_test.go
index ef6a88893..c1898384a 100644
--- a/handshake_manager_test.go
+++ b/handshake_manager_test.go
@@ -41,7 +41,7 @@ func Test_NewHandshakeManagerVpnIp(t *testing.T) {
i2 := blah.StartHandshake(ip, nil)
assert.Same(t, i, i2)
- i.remotes = NewRemoteList(nil)
+ i.remotes = NewRemoteList([]netip.Addr{}, nil)
// Adding something to pending should not affect the main hostmap
assert.Len(t, mainHM.Hosts, 0)
diff --git a/hostmap.go b/hostmap.go
index 63601ee37..e3817e7c6 100644
--- a/hostmap.go
+++ b/hostmap.go
@@ -308,7 +308,7 @@ func (hm *HostMap) DeleteHostInfo(hostinfo *HostInfo) bool {
hm.Lock()
// If we have a previous or next hostinfo then we are not the last one for this vpn ip
final := (hostinfo.next == nil && hostinfo.prev == nil)
- hm.unlockedDeleteHostInfo(hostinfo, false)
+ hm.unlockedDeleteHostInfo(hostinfo)
hm.Unlock()
return final
@@ -321,6 +321,8 @@ func (hm *HostMap) MakePrimary(hostinfo *HostInfo) {
}
func (hm *HostMap) unlockedMakePrimary(hostinfo *HostInfo) {
+ //TODO: we may need to promote follow on hostinfos from these vpnAddrs as well since their oldHostinfo might not be the same as this one
+ // this really looks like an ideal spot for memory leaks
oldHostinfo := hm.Hosts[hostinfo.vpnAddrs[0]]
if oldHostinfo == hostinfo {
return
@@ -345,7 +347,19 @@ func (hm *HostMap) unlockedMakePrimary(hostinfo *HostInfo) {
hostinfo.prev = nil
}
-func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo, dontRecurse bool) {
+func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo) {
+ for _, addr := range hostinfo.vpnAddrs {
+ h := hm.Hosts[addr]
+ for h != nil {
+ if h == hostinfo {
+ hm.unlockedInnerDeleteHostInfo(h)
+ }
+ h = h.next
+ }
+ }
+}
+
+func (hm *HostMap) unlockedInnerDeleteHostInfo(hostinfo *HostInfo) {
primary, ok := hm.Hosts[hostinfo.vpnAddrs[0]]
if ok && primary == hostinfo {
// The vpnIp pointer points to the same hostinfo as the local index id, we can remove it
@@ -399,18 +413,6 @@ func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo, dontRecurse bool)
for _, localRelayIdx := range hostinfo.relayState.CopyRelayForIdxs() {
delete(hm.Relays, localRelayIdx)
}
-
- if !dontRecurse {
- for _, addr := range hostinfo.vpnAddrs {
- h := hm.Hosts[addr]
- for h != nil {
- if h == hostinfo {
- hm.unlockedDeleteHostInfo(h, true)
- }
- h = h.next
- }
- }
- }
}
func (hm *HostMap) QueryIndex(index uint32) *HostInfo {
@@ -487,17 +489,8 @@ func (hm *HostMap) queryVpnAddr(vpnIp netip.Addr, promoteIfce *Interface) *HostI
// unlockedAddHostInfo assumes you have a write-lock and will add a hostinfo object to the hostmap Indexes and RemoteIndexes maps.
// If an entry exists for the Hosts table (vpnIp -> hostinfo) then the provided hostinfo will be made primary
func (hm *HostMap) unlockedAddHostInfo(hostinfo *HostInfo, f *Interface) {
- if f.serveDns {
- remoteCert := hostinfo.ConnectionState.peerCert
- dnsR.Add(remoteCert.Certificate.Name()+".", remoteCert.Certificate.Networks()[0].Addr().String())
- }
-
- existing := hm.Hosts[hostinfo.vpnAddrs[0]]
- hm.Hosts[hostinfo.vpnAddrs[0]] = hostinfo
-
- if existing != nil {
- hostinfo.next = existing
- existing.prev = hostinfo
+ for _, addr := range hostinfo.vpnAddrs {
+ hm.unlockedInnerAddHostInfo(addr, hostinfo, f)
}
hm.Indexes[hostinfo.localIndexId] = hostinfo
@@ -508,12 +501,27 @@ func (hm *HostMap) unlockedAddHostInfo(hostinfo *HostInfo, f *Interface) {
"hostinfo": m{"existing": true, "localIndexId": hostinfo.localIndexId, "vpnAddrs": hostinfo.vpnAddrs}}).
Debug("Hostmap vpnIp added")
}
+}
+
+func (hm *HostMap) unlockedInnerAddHostInfo(vpnAddr netip.Addr, hostinfo *HostInfo, f *Interface) {
+ if f.serveDns {
+ remoteCert := hostinfo.ConnectionState.peerCert
+ dnsR.Add(remoteCert.Certificate.Name()+".", vpnAddr.String())
+ }
+
+ existing := hm.Hosts[vpnAddr]
+ hm.Hosts[vpnAddr] = hostinfo
+
+ if existing != nil && existing != hostinfo {
+ hostinfo.next = existing
+ existing.prev = hostinfo
+ }
i := 1
check := hostinfo
for check != nil {
if i > MaxHostInfosPerVpnIp {
- hm.unlockedDeleteHostInfo(check, false)
+ hm.unlockedDeleteHostInfo(check)
}
check = check.next
i++
diff --git a/lighthouse.go b/lighthouse.go
index 5549e8386..32e280b0e 100644
--- a/lighthouse.go
+++ b/lighthouse.go
@@ -523,7 +523,10 @@ func (lh *LightHouse) queryAndPrepMessage(vpnAddr netip.Addr, f func(*cache) (in
lh.RUnlock()
- // vpnIp should also be the owner here since we are a lighthouse.
+ // We may be asking about a non primary address so lets get the primary address
+ if slices.Contains(v.vpnAddrs, vpnAddr) {
+ vpnAddr = v.vpnAddrs[0]
+ }
c := v.cache[vpnAddr]
// Make sure we have
if c != nil {
@@ -637,7 +640,7 @@ func (lh *LightHouse) addCalculatedRemotes(vpnAddr netip.Addr) bool {
func (lh *LightHouse) unlockedGetRemoteList(allAddrs []netip.Addr) *RemoteList {
am, ok := lh.addrMap[allAddrs[0]]
if !ok {
- am = NewRemoteList(func(a netip.Addr) bool { return lh.shouldAdd(allAddrs[0], a) })
+ am = NewRemoteList(allAddrs, func(a netip.Addr) bool { return lh.shouldAdd(allAddrs[0], a) })
for _, addr := range allAddrs {
lh.addrMap[addr] = am
}
@@ -747,12 +750,15 @@ func (lh *LightHouse) innerQueryServer(addr netip.Addr, nb, out []byte) {
}
// Send a query to the lighthouses and hope for the best next time
+ //TODO: this is not sufficient since the version depends on the certs loaded into memory as well
v := lh.protocolVersion.Load()
msg := &NebulaMeta{
Type: NebulaMeta_HostQuery,
Details: &NebulaMetaDetails{},
}
+ //TODO: remove this
+ v = 2
if v == 1 {
if !addr.Is4() {
lh.l.WithField("vpnAddr", addr).Error("Can't query lighthouse for v6 address using a v1 protocol")
@@ -846,6 +852,8 @@ func (lh *LightHouse) SendUpdate() {
},
}
+ //TODO: remove this
+ v = 2
if v == 1 {
var relays []uint32
for _, r := range lh.GetRelaysForMe() {
@@ -856,8 +864,10 @@ func (lh *LightHouse) SendUpdate() {
relays = append(relays, binary.BigEndian.Uint32(b[:]))
}
- //TODO: need an ipv4 vpn addr to use
msg.Details.OldRelayVpnAddrs = relays
+ //TODO: assert ipv4
+ b := lh.myVpnNetworks[0].Addr().As4()
+ msg.Details.OldVpnAddr = binary.BigEndian.Uint32(b[:])
} else if v == 2 {
var relays []*Addr
@@ -865,7 +875,8 @@ func (lh *LightHouse) SendUpdate() {
relays = append(relays, netAddrToProtoAddr(r))
}
- //TODO: need a vpn addr to use
+ // time="lh 15:57:55.871069" level=debug msg="Host sent invalid update" answer="ff::ffff:a80:3" vpnAddrs="[10.128.0.3 ff::3]" what???
+ msg.Details.VpnAddr = netAddrToProtoAddr(lh.myVpnNetworks[0].Addr())
} else {
panic("protocol version not supported")
@@ -931,6 +942,9 @@ func (lhh *LightHouseHandler) resetMeta() *NebulaMeta {
details.V6AddrPorts = details.V6AddrPorts[:0]
details.RelayVpnAddrs = details.RelayVpnAddrs[:0]
details.OldRelayVpnAddrs = details.OldRelayVpnAddrs[:0]
+ //TODO: these are unfortunate
+ details.OldVpnAddr = 0
+ details.VpnAddr = nil
lhh.meta.Details = details
return lhh.meta
@@ -983,16 +997,13 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
var useVersion cert.Version
var queryVpnIp netip.Addr
- var reqVpnIp netip.Addr
if n.Details.OldVpnAddr != 0 {
b := [4]byte{}
binary.BigEndian.PutUint32(b[:], n.Details.OldVpnAddr)
queryVpnIp = netip.AddrFrom4(b)
- reqVpnIp = queryVpnIp
useVersion = 1
} else if n.Details.VpnAddr != nil {
queryVpnIp = protoAddrToNetAddr(n.Details.VpnAddr)
- reqVpnIp = queryVpnIp
useVersion = 2
}
@@ -1001,13 +1012,13 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
n = lhh.resetMeta()
n.Type = NebulaMeta_HostQueryReply
if useVersion == 1 {
- if !reqVpnIp.Is4() {
+ if !queryVpnIp.Is4() {
return 0, fmt.Errorf("invalid vpn ip for v1 handleHostQuery")
}
- b := reqVpnIp.As4()
+ b := queryVpnIp.As4()
n.Details.OldVpnAddr = binary.BigEndian.Uint32(b[:])
} else {
- n.Details.VpnAddr = netAddrToProtoAddr(reqVpnIp)
+ n.Details.VpnAddr = netAddrToProtoAddr(queryVpnIp)
}
lhh.coalesceAnswers(useVersion, c, n)
@@ -1033,7 +1044,7 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
n.Type = NebulaMeta_HostPunchNotification
//TODO: unsure which version to use. If we had access to the hostmap we could see if there is already a tunnel
// and use that version then fallback to our default configuration
- targetHI := lhh.lh.ifce.GetHostInfo(reqVpnIp)
+ targetHI := lhh.lh.ifce.GetHostInfo(queryVpnIp)
useVersion = cert.Version(lhh.lh.protocolVersion.Load())
if targetHI != nil {
useVersion = targetHI.GetCert().Certificate.Version()
@@ -1068,7 +1079,7 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
}
lhh.lh.metricTx(NebulaMeta_HostPunchNotification, 1)
- w.SendMessageToVpnIp(header.LightHouse, 0, reqVpnIp, lhh.pb[:ln], lhh.nb, lhh.out[:0])
+ w.SendMessageToVpnIp(header.LightHouse, 0, queryVpnIp, lhh.pb[:ln], lhh.nb, lhh.out[:0])
}
func (lhh *LightHouseHandler) coalesceAnswers(v cert.Version, c *cache, n *NebulaMeta) {
diff --git a/lighthouse_test.go b/lighthouse_test.go
index 2cdfce79a..116099773 100644
--- a/lighthouse_test.go
+++ b/lighthouse_test.go
@@ -108,7 +108,7 @@ func BenchmarkLighthouseHandleRequest(b *testing.B) {
hAddr2 := netip.MustParseAddrPort("4.5.6.7:12346")
vpnIp3 := netip.MustParseAddr("0.0.0.3")
- lh.addrMap[vpnIp3] = NewRemoteList(nil)
+ lh.addrMap[vpnIp3] = NewRemoteList([]netip.Addr{vpnIp3}, nil)
lh.addrMap[vpnIp3].unlockedSetV4(
vpnIp3,
vpnIp3,
@@ -122,7 +122,7 @@ func BenchmarkLighthouseHandleRequest(b *testing.B) {
rAddr := netip.MustParseAddrPort("1.2.2.3:12345")
rAddr2 := netip.MustParseAddrPort("1.2.2.3:12346")
vpnIp2 := netip.MustParseAddr("0.0.0.3")
- lh.addrMap[vpnIp2] = NewRemoteList(nil)
+ lh.addrMap[vpnIp2] = NewRemoteList([]netip.Addr{vpnIp2}, nil)
lh.addrMap[vpnIp2].unlockedSetV4(
vpnIp3,
vpnIp3,
diff --git a/remote_list.go b/remote_list.go
index 1c7fd4db5..cbbb22a99 100644
--- a/remote_list.go
+++ b/remote_list.go
@@ -189,6 +189,9 @@ type RemoteList struct {
// Every interaction with internals requires a lock!
sync.RWMutex
+ // The full list of vpn addresses assigned to this host
+ vpnAddrs []netip.Addr
+
// A deduplicated set of addresses. Any accessor should lock beforehand.
addrs []netip.AddrPort
@@ -212,13 +215,16 @@ type RemoteList struct {
}
// NewRemoteList creates a new empty RemoteList
-func NewRemoteList(shouldAdd func(netip.Addr) bool) *RemoteList {
- return &RemoteList{
+func NewRemoteList(vpnAddrs []netip.Addr, shouldAdd func(netip.Addr) bool) *RemoteList {
+ r := &RemoteList{
+ vpnAddrs: make([]netip.Addr, len(vpnAddrs)),
addrs: make([]netip.AddrPort, 0),
relays: make([]netip.Addr, 0),
cache: make(map[netip.Addr]*cache),
shouldAdd: shouldAdd,
}
+ copy(r.vpnAddrs, vpnAddrs)
+ return r
}
func (r *RemoteList) unlockedSetHostnamesResults(hr *hostnamesResults) {
diff --git a/remote_list_test.go b/remote_list_test.go
index 33bfbb128..1f548c71e 100644
--- a/remote_list_test.go
+++ b/remote_list_test.go
@@ -9,7 +9,7 @@ import (
)
func TestRemoteList_Rebuild(t *testing.T) {
- rl := NewRemoteList(nil)
+ rl := NewRemoteList([]netip.Addr{netip.MustParseAddr("0.0.0.0")}, nil)
rl.unlockedSetV4(
netip.MustParseAddr("0.0.0.0"),
netip.MustParseAddr("0.0.0.0"),
@@ -98,7 +98,7 @@ func TestRemoteList_Rebuild(t *testing.T) {
}
func BenchmarkFullRebuild(b *testing.B) {
- rl := NewRemoteList(nil)
+ rl := NewRemoteList([]netip.Addr{netip.MustParseAddr("0.0.0.0")}, nil)
rl.unlockedSetV4(
netip.MustParseAddr("0.0.0.0"),
netip.MustParseAddr("0.0.0.0"),
@@ -160,7 +160,7 @@ func BenchmarkFullRebuild(b *testing.B) {
}
func BenchmarkSortRebuild(b *testing.B) {
- rl := NewRemoteList(nil)
+ rl := NewRemoteList([]netip.Addr{netip.MustParseAddr("0.0.0.0")}, nil)
rl.unlockedSetV4(
netip.MustParseAddr("0.0.0.0"),
netip.MustParseAddr("0.0.0.0"),
diff --git a/service/service_test.go b/service/service_test.go
index e9fceef6f..9fbf088d6 100644
--- a/service/service_test.go
+++ b/service/service_test.go
@@ -19,7 +19,7 @@ import (
type m map[string]interface{}
func newSimpleService(caCrt cert.Certificate, caKey []byte, name string, udpIp netip.Addr, overrides m) *Service {
- _, _, myPrivKey, myPEM := e2e.NewTestCert(caCrt, caKey, "a", time.Now(), time.Now().Add(5*time.Minute), []netip.Prefix{netip.PrefixFrom(udpIp, 24)}, nil, []string{})
+ _, _, myPrivKey, myPEM := e2e.NewTestCert(cert.Version2, caCrt, caKey, "a", time.Now(), time.Now().Add(5*time.Minute), []netip.Prefix{netip.PrefixFrom(udpIp, 24)}, nil, []string{})
caB, err := caCrt.MarshalPEM()
if err != nil {
panic(err)