mirror of https://github.com/slackhq/nebula.git
Pull hostmap and pending hostmap apart, remove unused functions (#843)
This commit is contained in:
parent
52c9e360e7
commit
a10baeee92
|
@ -42,7 +42,7 @@ func Test_NewConnectionManagerTest(t *testing.T) {
|
||||||
preferredRanges := []*net.IPNet{localrange}
|
preferredRanges := []*net.IPNet{localrange}
|
||||||
|
|
||||||
// Very incomplete mock objects
|
// Very incomplete mock objects
|
||||||
hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
|
hostMap := NewHostMap(l, vpncidr, preferredRanges)
|
||||||
cs := &CertState{
|
cs := &CertState{
|
||||||
rawCertificate: []byte{},
|
rawCertificate: []byte{},
|
||||||
privateKey: []byte{},
|
privateKey: []byte{},
|
||||||
|
@ -121,7 +121,7 @@ func Test_NewConnectionManagerTest2(t *testing.T) {
|
||||||
preferredRanges := []*net.IPNet{localrange}
|
preferredRanges := []*net.IPNet{localrange}
|
||||||
|
|
||||||
// Very incomplete mock objects
|
// Very incomplete mock objects
|
||||||
hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
|
hostMap := NewHostMap(l, vpncidr, preferredRanges)
|
||||||
cs := &CertState{
|
cs := &CertState{
|
||||||
rawCertificate: []byte{},
|
rawCertificate: []byte{},
|
||||||
privateKey: []byte{},
|
privateKey: []byte{},
|
||||||
|
@ -207,7 +207,7 @@ func Test_NewConnectionManagerTest_DisconnectInvalid(t *testing.T) {
|
||||||
_, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
|
_, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
|
||||||
_, localrange, _ := net.ParseCIDR("10.1.1.1/24")
|
_, localrange, _ := net.ParseCIDR("10.1.1.1/24")
|
||||||
preferredRanges := []*net.IPNet{localrange}
|
preferredRanges := []*net.IPNet{localrange}
|
||||||
hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
|
hostMap := NewHostMap(l, vpncidr, preferredRanges)
|
||||||
|
|
||||||
// Generate keys for CA and peer's cert.
|
// Generate keys for CA and peer's cert.
|
||||||
pubCA, privCA, _ := ed25519.GenerateKey(rand.Reader)
|
pubCA, privCA, _ := ed25519.GenerateKey(rand.Reader)
|
||||||
|
@ -268,12 +268,16 @@ func Test_NewConnectionManagerTest_DisconnectInvalid(t *testing.T) {
|
||||||
punchy := NewPunchyFromConfig(l, config.NewC(l))
|
punchy := NewPunchyFromConfig(l, config.NewC(l))
|
||||||
nc := newConnectionManager(ctx, l, ifce, 5, 10, punchy)
|
nc := newConnectionManager(ctx, l, ifce, 5, 10, punchy)
|
||||||
ifce.connectionManager = nc
|
ifce.connectionManager = nc
|
||||||
hostinfo, _ := nc.hostMap.AddVpnIp(vpnIp, nil)
|
|
||||||
hostinfo.ConnectionState = &ConnectionState{
|
hostinfo := &HostInfo{
|
||||||
|
vpnIp: vpnIp,
|
||||||
|
ConnectionState: &ConnectionState{
|
||||||
certState: cs,
|
certState: cs,
|
||||||
peerCert: &peerCert,
|
peerCert: &peerCert,
|
||||||
H: &noise.HandshakeState{},
|
H: &noise.HandshakeState{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
nc.hostMap.unlockedAddHostInfo(hostinfo, ifce)
|
||||||
|
|
||||||
// Move ahead 45s.
|
// Move ahead 45s.
|
||||||
// Check if to disconnect with invalid certificate.
|
// Check if to disconnect with invalid certificate.
|
||||||
|
|
63
control.go
63
control.go
|
@ -17,6 +17,15 @@ import (
|
||||||
// Every interaction here needs to take extra care to copy memory and not return or use arguments "as is" when touching
|
// Every interaction here needs to take extra care to copy memory and not return or use arguments "as is" when touching
|
||||||
// core. This means copying IP objects, slices, de-referencing pointers and taking the actual value, etc
|
// core. This means copying IP objects, slices, de-referencing pointers and taking the actual value, etc
|
||||||
|
|
||||||
|
type controlEach func(h *HostInfo)
|
||||||
|
|
||||||
|
type controlHostLister interface {
|
||||||
|
QueryVpnIp(vpnIp iputil.VpnIp) *HostInfo
|
||||||
|
ForEachIndex(each controlEach)
|
||||||
|
ForEachVpnIp(each controlEach)
|
||||||
|
GetPreferredRanges() []*net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
type Control struct {
|
type Control struct {
|
||||||
f *Interface
|
f *Interface
|
||||||
l *logrus.Logger
|
l *logrus.Logger
|
||||||
|
@ -98,7 +107,7 @@ func (c *Control) RebindUDPServer() {
|
||||||
// ListHostmapHosts returns details about the actual or pending (handshaking) hostmap by vpn ip
|
// ListHostmapHosts returns details about the actual or pending (handshaking) hostmap by vpn ip
|
||||||
func (c *Control) ListHostmapHosts(pendingMap bool) []ControlHostInfo {
|
func (c *Control) ListHostmapHosts(pendingMap bool) []ControlHostInfo {
|
||||||
if pendingMap {
|
if pendingMap {
|
||||||
return listHostMapHosts(c.f.handshakeManager.pendingHostMap)
|
return listHostMapHosts(c.f.handshakeManager)
|
||||||
} else {
|
} else {
|
||||||
return listHostMapHosts(c.f.hostMap)
|
return listHostMapHosts(c.f.hostMap)
|
||||||
}
|
}
|
||||||
|
@ -107,7 +116,7 @@ func (c *Control) ListHostmapHosts(pendingMap bool) []ControlHostInfo {
|
||||||
// ListHostmapIndexes returns details about the actual or pending (handshaking) hostmap by local index id
|
// ListHostmapIndexes returns details about the actual or pending (handshaking) hostmap by local index id
|
||||||
func (c *Control) ListHostmapIndexes(pendingMap bool) []ControlHostInfo {
|
func (c *Control) ListHostmapIndexes(pendingMap bool) []ControlHostInfo {
|
||||||
if pendingMap {
|
if pendingMap {
|
||||||
return listHostMapIndexes(c.f.handshakeManager.pendingHostMap)
|
return listHostMapIndexes(c.f.handshakeManager)
|
||||||
} else {
|
} else {
|
||||||
return listHostMapIndexes(c.f.hostMap)
|
return listHostMapIndexes(c.f.hostMap)
|
||||||
}
|
}
|
||||||
|
@ -115,15 +124,15 @@ func (c *Control) ListHostmapIndexes(pendingMap bool) []ControlHostInfo {
|
||||||
|
|
||||||
// GetHostInfoByVpnIp returns a single tunnels hostInfo, or nil if not found
|
// GetHostInfoByVpnIp returns a single tunnels hostInfo, or nil if not found
|
||||||
func (c *Control) GetHostInfoByVpnIp(vpnIp iputil.VpnIp, pending bool) *ControlHostInfo {
|
func (c *Control) GetHostInfoByVpnIp(vpnIp iputil.VpnIp, pending bool) *ControlHostInfo {
|
||||||
var hm *HostMap
|
var hl controlHostLister
|
||||||
if pending {
|
if pending {
|
||||||
hm = c.f.handshakeManager.pendingHostMap
|
hl = c.f.handshakeManager
|
||||||
} else {
|
} else {
|
||||||
hm = c.f.hostMap
|
hl = c.f.hostMap
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := hm.QueryVpnIp(vpnIp)
|
h := hl.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if h == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +142,8 @@ func (c *Control) GetHostInfoByVpnIp(vpnIp iputil.VpnIp, pending bool) *ControlH
|
||||||
|
|
||||||
// SetRemoteForTunnel forces a tunnel to use a specific remote
|
// SetRemoteForTunnel forces a tunnel to use a specific remote
|
||||||
func (c *Control) SetRemoteForTunnel(vpnIp iputil.VpnIp, addr udp.Addr) *ControlHostInfo {
|
func (c *Control) SetRemoteForTunnel(vpnIp iputil.VpnIp, addr udp.Addr) *ControlHostInfo {
|
||||||
hostInfo, err := c.f.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := c.f.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +154,8 @@ func (c *Control) SetRemoteForTunnel(vpnIp iputil.VpnIp, addr udp.Addr) *Control
|
||||||
|
|
||||||
// CloseTunnel closes a fully established tunnel. If localOnly is false it will notify the remote end as well.
|
// CloseTunnel closes a fully established tunnel. If localOnly is false it will notify the remote end as well.
|
||||||
func (c *Control) CloseTunnel(vpnIp iputil.VpnIp, localOnly bool) bool {
|
func (c *Control) CloseTunnel(vpnIp iputil.VpnIp, localOnly bool) bool {
|
||||||
hostInfo, err := c.f.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := c.f.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,28 +250,20 @@ func copyHostInfo(h *HostInfo, preferredRanges []*net.IPNet) ControlHostInfo {
|
||||||
return chi
|
return chi
|
||||||
}
|
}
|
||||||
|
|
||||||
func listHostMapHosts(hm *HostMap) []ControlHostInfo {
|
func listHostMapHosts(hl controlHostLister) []ControlHostInfo {
|
||||||
hm.RLock()
|
hosts := make([]ControlHostInfo, 0)
|
||||||
hosts := make([]ControlHostInfo, len(hm.Hosts))
|
pr := hl.GetPreferredRanges()
|
||||||
i := 0
|
hl.ForEachVpnIp(func(hostinfo *HostInfo) {
|
||||||
for _, v := range hm.Hosts {
|
hosts = append(hosts, copyHostInfo(hostinfo, pr))
|
||||||
hosts[i] = copyHostInfo(v, hm.preferredRanges)
|
})
|
||||||
i++
|
|
||||||
}
|
|
||||||
hm.RUnlock()
|
|
||||||
|
|
||||||
return hosts
|
return hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
func listHostMapIndexes(hm *HostMap) []ControlHostInfo {
|
func listHostMapIndexes(hl controlHostLister) []ControlHostInfo {
|
||||||
hm.RLock()
|
hosts := make([]ControlHostInfo, 0)
|
||||||
hosts := make([]ControlHostInfo, len(hm.Indexes))
|
pr := hl.GetPreferredRanges()
|
||||||
i := 0
|
hl.ForEachIndex(func(hostinfo *HostInfo) {
|
||||||
for _, v := range hm.Indexes {
|
hosts = append(hosts, copyHostInfo(hostinfo, pr))
|
||||||
hosts[i] = copyHostInfo(v, hm.preferredRanges)
|
})
|
||||||
i++
|
|
||||||
}
|
|
||||||
hm.RUnlock()
|
|
||||||
|
|
||||||
return hosts
|
return hosts
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func TestControl_GetHostInfoByVpnIp(t *testing.T) {
|
||||||
l := test.NewLogger()
|
l := test.NewLogger()
|
||||||
// Special care must be taken to re-use all objects provided to the hostmap and certificate in the expectedInfo object
|
// Special care must be taken to re-use all objects provided to the hostmap and certificate in the expectedInfo object
|
||||||
// To properly ensure we are not exposing core memory to the caller
|
// To properly ensure we are not exposing core memory to the caller
|
||||||
hm := NewHostMap(l, "test", &net.IPNet{}, make([]*net.IPNet, 0))
|
hm := NewHostMap(l, &net.IPNet{}, make([]*net.IPNet, 0))
|
||||||
remote1 := udp.NewAddr(net.ParseIP("0.0.0.100"), 4444)
|
remote1 := udp.NewAddr(net.ParseIP("0.0.0.100"), 4444)
|
||||||
remote2 := udp.NewAddr(net.ParseIP("1:2:3:4:5:6:7:8"), 4444)
|
remote2 := udp.NewAddr(net.ParseIP("1:2:3:4:5:6:7:8"), 4444)
|
||||||
ipNet := net.IPNet{
|
ipNet := net.IPNet{
|
||||||
|
@ -50,7 +50,7 @@ func TestControl_GetHostInfoByVpnIp(t *testing.T) {
|
||||||
remotes := NewRemoteList(nil)
|
remotes := NewRemoteList(nil)
|
||||||
remotes.unlockedPrependV4(0, NewIp4AndPort(remote1.IP, uint32(remote1.Port)))
|
remotes.unlockedPrependV4(0, NewIp4AndPort(remote1.IP, uint32(remote1.Port)))
|
||||||
remotes.unlockedPrependV6(0, NewIp6AndPort(remote2.IP, uint32(remote2.Port)))
|
remotes.unlockedPrependV6(0, NewIp6AndPort(remote2.IP, uint32(remote2.Port)))
|
||||||
hm.Add(iputil.Ip2VpnIp(ipNet.IP), &HostInfo{
|
hm.unlockedAddHostInfo(&HostInfo{
|
||||||
remote: remote1,
|
remote: remote1,
|
||||||
remotes: remotes,
|
remotes: remotes,
|
||||||
ConnectionState: &ConnectionState{
|
ConnectionState: &ConnectionState{
|
||||||
|
@ -64,9 +64,9 @@ func TestControl_GetHostInfoByVpnIp(t *testing.T) {
|
||||||
relayForByIp: map[iputil.VpnIp]*Relay{},
|
relayForByIp: map[iputil.VpnIp]*Relay{},
|
||||||
relayForByIdx: map[uint32]*Relay{},
|
relayForByIdx: map[uint32]*Relay{},
|
||||||
},
|
},
|
||||||
})
|
}, &Interface{})
|
||||||
|
|
||||||
hm.Add(iputil.Ip2VpnIp(ipNet2.IP), &HostInfo{
|
hm.unlockedAddHostInfo(&HostInfo{
|
||||||
remote: remote1,
|
remote: remote1,
|
||||||
remotes: remotes,
|
remotes: remotes,
|
||||||
ConnectionState: &ConnectionState{
|
ConnectionState: &ConnectionState{
|
||||||
|
@ -80,7 +80,7 @@ func TestControl_GetHostInfoByVpnIp(t *testing.T) {
|
||||||
relayForByIp: map[iputil.VpnIp]*Relay{},
|
relayForByIp: map[iputil.VpnIp]*Relay{},
|
||||||
relayForByIdx: map[uint32]*Relay{},
|
relayForByIdx: map[uint32]*Relay{},
|
||||||
},
|
},
|
||||||
})
|
}, &Interface{})
|
||||||
|
|
||||||
c := Control{
|
c := Control{
|
||||||
f: &Interface{
|
f: &Interface{
|
||||||
|
|
|
@ -147,12 +147,12 @@ func (c *Control) GetUDPAddr() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Control) KillPendingTunnel(vpnIp net.IP) bool {
|
func (c *Control) KillPendingTunnel(vpnIp net.IP) bool {
|
||||||
hostinfo, ok := c.f.handshakeManager.pendingHostMap.Hosts[iputil.Ip2VpnIp(vpnIp)]
|
hostinfo := c.f.handshakeManager.QueryVpnIp(iputil.Ip2VpnIp(vpnIp))
|
||||||
if !ok {
|
if hostinfo == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
c.f.handshakeManager.pendingHostMap.DeleteHostInfo(hostinfo)
|
c.f.handshakeManager.DeleteHostInfo(hostinfo)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ func (d *dnsRecords) QueryCert(data string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
iip := iputil.Ip2VpnIp(ip)
|
iip := iputil.Ip2VpnIp(ip)
|
||||||
hostinfo, err := d.hostMap.QueryVpnIp(iip)
|
hostinfo := d.hostMap.QueryVpnIp(iip)
|
||||||
if err != nil {
|
if hostinfo == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
q := hostinfo.GetCert()
|
q := hostinfo.GetCert()
|
||||||
|
|
|
@ -20,7 +20,7 @@ func HandleIncomingHandshake(f *Interface, addr *udp.Addr, via *ViaSender, packe
|
||||||
case 1:
|
case 1:
|
||||||
ixHandshakeStage1(f, addr, via, packet, h)
|
ixHandshakeStage1(f, addr, via, packet, h)
|
||||||
case 2:
|
case 2:
|
||||||
newHostinfo, _ := f.handshakeManager.QueryIndex(h.RemoteIndex)
|
newHostinfo := f.handshakeManager.QueryIndex(h.RemoteIndex)
|
||||||
tearDown := ixHandshakeStage2(f, addr, via, newHostinfo, packet, h)
|
tearDown := ixHandshakeStage2(f, addr, via, newHostinfo, packet, h)
|
||||||
if tearDown && newHostinfo != nil {
|
if tearDown && newHostinfo != nil {
|
||||||
f.handshakeManager.DeleteHostInfo(newHostinfo)
|
f.handshakeManager.DeleteHostInfo(newHostinfo)
|
||||||
|
|
|
@ -422,7 +422,7 @@ func ixHandshakeStage2(f *Interface, addr *udp.Addr, via *ViaSender, hostinfo *H
|
||||||
Info("Incorrect host responded to handshake")
|
Info("Incorrect host responded to handshake")
|
||||||
|
|
||||||
// Release our old handshake from pending, it should not continue
|
// Release our old handshake from pending, it should not continue
|
||||||
f.handshakeManager.pendingHostMap.DeleteHostInfo(hostinfo)
|
f.handshakeManager.DeleteHostInfo(hostinfo)
|
||||||
|
|
||||||
// Create a new hostinfo/handshake for the intended vpn ip
|
// Create a new hostinfo/handshake for the intended vpn ip
|
||||||
//TODO: this adds it to the timer wheel in a way that aggressively retries
|
//TODO: this adds it to the timer wheel in a way that aggressively retries
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rcrowley/go-metrics"
|
"github.com/rcrowley/go-metrics"
|
||||||
|
@ -42,7 +43,12 @@ type HandshakeConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type HandshakeManager struct {
|
type HandshakeManager struct {
|
||||||
pendingHostMap *HostMap
|
// Mutex for interacting with the vpnIps and indexes maps
|
||||||
|
sync.RWMutex
|
||||||
|
|
||||||
|
vpnIps map[iputil.VpnIp]*HostInfo
|
||||||
|
indexes map[uint32]*HostInfo
|
||||||
|
|
||||||
mainHostMap *HostMap
|
mainHostMap *HostMap
|
||||||
lightHouse *LightHouse
|
lightHouse *LightHouse
|
||||||
outside udp.Conn
|
outside udp.Conn
|
||||||
|
@ -59,7 +65,8 @@ type HandshakeManager struct {
|
||||||
|
|
||||||
func NewHandshakeManager(l *logrus.Logger, tunCidr *net.IPNet, preferredRanges []*net.IPNet, mainHostMap *HostMap, lightHouse *LightHouse, outside udp.Conn, config HandshakeConfig) *HandshakeManager {
|
func NewHandshakeManager(l *logrus.Logger, tunCidr *net.IPNet, preferredRanges []*net.IPNet, mainHostMap *HostMap, lightHouse *LightHouse, outside udp.Conn, config HandshakeConfig) *HandshakeManager {
|
||||||
return &HandshakeManager{
|
return &HandshakeManager{
|
||||||
pendingHostMap: NewHostMap(l, "pending", tunCidr, preferredRanges),
|
vpnIps: map[iputil.VpnIp]*HostInfo{},
|
||||||
|
indexes: map[uint32]*HostInfo{},
|
||||||
mainHostMap: mainHostMap,
|
mainHostMap: mainHostMap,
|
||||||
lightHouse: lightHouse,
|
lightHouse: lightHouse,
|
||||||
outside: outside,
|
outside: outside,
|
||||||
|
@ -101,8 +108,8 @@ func (c *HandshakeManager) NextOutboundHandshakeTimerTick(now time.Time, f EncWr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, lighthouseTriggered bool) {
|
func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, lighthouseTriggered bool) {
|
||||||
hostinfo, err := c.pendingHostMap.QueryVpnIp(vpnIp)
|
hostinfo := c.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostinfo == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hostinfo.Lock()
|
hostinfo.Lock()
|
||||||
|
@ -111,7 +118,7 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
// We may have raced to completion but now that we have a lock we should ensure we have not yet completed.
|
// We may have raced to completion but now that we have a lock we should ensure we have not yet completed.
|
||||||
if hostinfo.HandshakeComplete {
|
if hostinfo.HandshakeComplete {
|
||||||
// Ensure we don't exist in the pending hostmap anymore since we have completed
|
// Ensure we don't exist in the pending hostmap anymore since we have completed
|
||||||
c.pendingHostMap.DeleteHostInfo(hostinfo)
|
c.DeleteHostInfo(hostinfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,14 +132,14 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
|
|
||||||
// If we are out of time, clean up
|
// If we are out of time, clean up
|
||||||
if hostinfo.HandshakeCounter >= c.config.retries {
|
if hostinfo.HandshakeCounter >= c.config.retries {
|
||||||
hostinfo.logger(c.l).WithField("udpAddrs", hostinfo.remotes.CopyAddrs(c.pendingHostMap.preferredRanges)).
|
hostinfo.logger(c.l).WithField("udpAddrs", hostinfo.remotes.CopyAddrs(c.mainHostMap.preferredRanges)).
|
||||||
WithField("initiatorIndex", hostinfo.localIndexId).
|
WithField("initiatorIndex", hostinfo.localIndexId).
|
||||||
WithField("remoteIndex", hostinfo.remoteIndexId).
|
WithField("remoteIndex", hostinfo.remoteIndexId).
|
||||||
WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
|
WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
|
||||||
WithField("durationNs", time.Since(hostinfo.handshakeStart).Nanoseconds()).
|
WithField("durationNs", time.Since(hostinfo.handshakeStart).Nanoseconds()).
|
||||||
Info("Handshake timed out")
|
Info("Handshake timed out")
|
||||||
c.metricTimedOut.Inc(1)
|
c.metricTimedOut.Inc(1)
|
||||||
c.pendingHostMap.DeleteHostInfo(hostinfo)
|
c.DeleteHostInfo(hostinfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +151,7 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
hostinfo.remotes = c.lightHouse.QueryCache(vpnIp)
|
hostinfo.remotes = c.lightHouse.QueryCache(vpnIp)
|
||||||
}
|
}
|
||||||
|
|
||||||
remotes := hostinfo.remotes.CopyAddrs(c.pendingHostMap.preferredRanges)
|
remotes := hostinfo.remotes.CopyAddrs(c.mainHostMap.preferredRanges)
|
||||||
remotesHaveChanged := !udp.AddrSlice(remotes).Equal(hostinfo.HandshakeLastRemotes)
|
remotesHaveChanged := !udp.AddrSlice(remotes).Equal(hostinfo.HandshakeLastRemotes)
|
||||||
|
|
||||||
// We only care about a lighthouse trigger if we have new remotes to send to.
|
// We only care about a lighthouse trigger if we have new remotes to send to.
|
||||||
|
@ -168,9 +175,9 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
|
|
||||||
// Send the handshake to all known ips, stage 2 takes care of assigning the hostinfo.remote based on the first to reply
|
// Send the handshake to all known ips, stage 2 takes care of assigning the hostinfo.remote based on the first to reply
|
||||||
var sentTo []*udp.Addr
|
var sentTo []*udp.Addr
|
||||||
hostinfo.remotes.ForEach(c.pendingHostMap.preferredRanges, func(addr *udp.Addr, _ bool) {
|
hostinfo.remotes.ForEach(c.mainHostMap.preferredRanges, func(addr *udp.Addr, _ bool) {
|
||||||
c.messageMetrics.Tx(header.Handshake, header.MessageSubType(hostinfo.HandshakePacket[0][1]), 1)
|
c.messageMetrics.Tx(header.Handshake, header.MessageSubType(hostinfo.HandshakePacket[0][1]), 1)
|
||||||
err = c.outside.WriteTo(hostinfo.HandshakePacket[0], addr)
|
err := c.outside.WriteTo(hostinfo.HandshakePacket[0], addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hostinfo.logger(c.l).WithField("udpAddr", addr).
|
hostinfo.logger(c.l).WithField("udpAddr", addr).
|
||||||
WithField("initiatorIndex", hostinfo.localIndexId).
|
WithField("initiatorIndex", hostinfo.localIndexId).
|
||||||
|
@ -204,9 +211,9 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
if *relay == vpnIp || *relay == c.lightHouse.myVpnIp {
|
if *relay == vpnIp || *relay == c.lightHouse.myVpnIp {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
relayHostInfo, err := c.mainHostMap.QueryVpnIp(*relay)
|
relayHostInfo := c.mainHostMap.QueryVpnIp(*relay)
|
||||||
if err != nil || relayHostInfo.remote == nil {
|
if relayHostInfo == nil || relayHostInfo.remote == nil {
|
||||||
hostinfo.logger(c.l).WithError(err).WithField("relay", relay.String()).Info("Establish tunnel to relay target")
|
hostinfo.logger(c.l).WithField("relay", relay.String()).Info("Establish tunnel to relay target")
|
||||||
f.Handshake(*relay)
|
f.Handshake(*relay)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -289,14 +296,35 @@ func (c *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, f EncWriter, light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddVpnIp will try to handshake with the provided vpn ip and return the hostinfo for it.
|
||||||
func (c *HandshakeManager) AddVpnIp(vpnIp iputil.VpnIp, init func(*HostInfo)) *HostInfo {
|
func (c *HandshakeManager) AddVpnIp(vpnIp iputil.VpnIp, init func(*HostInfo)) *HostInfo {
|
||||||
hostinfo, created := c.pendingHostMap.AddVpnIp(vpnIp, init)
|
// A write lock is used to avoid having to recheck the map and trading a read lock for a write lock
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
if created {
|
if hostinfo, ok := c.vpnIps[vpnIp]; ok {
|
||||||
c.OutboundHandshakeTimer.Add(vpnIp, c.config.tryInterval)
|
// We are already tracking this vpn ip
|
||||||
c.metricInitiated.Inc(1)
|
return hostinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostinfo := &HostInfo{
|
||||||
|
vpnIp: vpnIp,
|
||||||
|
HandshakePacket: make(map[uint8][]byte, 0),
|
||||||
|
relayState: RelayState{
|
||||||
|
relays: map[iputil.VpnIp]struct{}{},
|
||||||
|
relayForByIp: map[iputil.VpnIp]*Relay{},
|
||||||
|
relayForByIdx: map[uint32]*Relay{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if init != nil {
|
||||||
|
init(hostinfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.vpnIps[vpnIp] = hostinfo
|
||||||
|
c.metricInitiated.Inc(1)
|
||||||
|
c.OutboundHandshakeTimer.Add(vpnIp, c.config.tryInterval)
|
||||||
|
|
||||||
return hostinfo
|
return hostinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +346,8 @@ var (
|
||||||
// ErrLocalIndexCollision if we already have an entry in the main or pending
|
// ErrLocalIndexCollision if we already have an entry in the main or pending
|
||||||
// hostmap for the hostinfo.localIndexId.
|
// hostmap for the hostinfo.localIndexId.
|
||||||
func (c *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface) (*HostInfo, error) {
|
func (c *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface) (*HostInfo, error) {
|
||||||
c.pendingHostMap.Lock()
|
c.Lock()
|
||||||
defer c.pendingHostMap.Unlock()
|
defer c.Unlock()
|
||||||
c.mainHostMap.Lock()
|
c.mainHostMap.Lock()
|
||||||
defer c.mainHostMap.Unlock()
|
defer c.mainHostMap.Unlock()
|
||||||
|
|
||||||
|
@ -350,7 +378,7 @@ func (c *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket
|
||||||
return existingIndex, ErrLocalIndexCollision
|
return existingIndex, ErrLocalIndexCollision
|
||||||
}
|
}
|
||||||
|
|
||||||
existingIndex, found = c.pendingHostMap.Indexes[hostinfo.localIndexId]
|
existingIndex, found = c.indexes[hostinfo.localIndexId]
|
||||||
if found && existingIndex != hostinfo {
|
if found && existingIndex != hostinfo {
|
||||||
// We have a collision, but for a different hostinfo
|
// We have a collision, but for a different hostinfo
|
||||||
return existingIndex, ErrLocalIndexCollision
|
return existingIndex, ErrLocalIndexCollision
|
||||||
|
@ -373,8 +401,8 @@ func (c *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket
|
||||||
// won't have a localIndexId collision because we already have an entry in the
|
// won't have a localIndexId collision because we already have an entry in the
|
||||||
// pendingHostMap. An existing hostinfo is returned if there was one.
|
// pendingHostMap. An existing hostinfo is returned if there was one.
|
||||||
func (c *HandshakeManager) Complete(hostinfo *HostInfo, f *Interface) {
|
func (c *HandshakeManager) Complete(hostinfo *HostInfo, f *Interface) {
|
||||||
c.pendingHostMap.Lock()
|
c.Lock()
|
||||||
defer c.pendingHostMap.Unlock()
|
defer c.Unlock()
|
||||||
c.mainHostMap.Lock()
|
c.mainHostMap.Lock()
|
||||||
defer c.mainHostMap.Unlock()
|
defer c.mainHostMap.Unlock()
|
||||||
|
|
||||||
|
@ -388,7 +416,7 @@ func (c *HandshakeManager) Complete(hostinfo *HostInfo, f *Interface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to remove from the pending hostmap first to avoid undoing work when after to the main hostmap.
|
// We need to remove from the pending hostmap first to avoid undoing work when after to the main hostmap.
|
||||||
c.pendingHostMap.unlockedDeleteHostInfo(hostinfo)
|
c.unlockedDeleteHostInfo(hostinfo)
|
||||||
c.mainHostMap.unlockedAddHostInfo(hostinfo, f)
|
c.mainHostMap.unlockedAddHostInfo(hostinfo, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,8 +424,8 @@ func (c *HandshakeManager) Complete(hostinfo *HostInfo, f *Interface) {
|
||||||
// and adds it to the pendingHostMap. Will error if we are unable to generate
|
// and adds it to the pendingHostMap. Will error if we are unable to generate
|
||||||
// a unique localIndexId
|
// a unique localIndexId
|
||||||
func (c *HandshakeManager) AddIndexHostInfo(h *HostInfo) error {
|
func (c *HandshakeManager) AddIndexHostInfo(h *HostInfo) error {
|
||||||
c.pendingHostMap.Lock()
|
c.Lock()
|
||||||
defer c.pendingHostMap.Unlock()
|
defer c.Unlock()
|
||||||
c.mainHostMap.RLock()
|
c.mainHostMap.RLock()
|
||||||
defer c.mainHostMap.RUnlock()
|
defer c.mainHostMap.RUnlock()
|
||||||
|
|
||||||
|
@ -407,12 +435,12 @@ func (c *HandshakeManager) AddIndexHostInfo(h *HostInfo) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, inPending := c.pendingHostMap.Indexes[index]
|
_, inPending := c.indexes[index]
|
||||||
_, inMain := c.mainHostMap.Indexes[index]
|
_, inMain := c.mainHostMap.Indexes[index]
|
||||||
|
|
||||||
if !inMain && !inPending {
|
if !inMain && !inPending {
|
||||||
h.localIndexId = index
|
h.localIndexId = index
|
||||||
c.pendingHostMap.Indexes[index] = h
|
c.indexes[index] = h
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,22 +448,73 @@ func (c *HandshakeManager) AddIndexHostInfo(h *HostInfo) error {
|
||||||
return errors.New("failed to generate unique localIndexId")
|
return errors.New("failed to generate unique localIndexId")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HandshakeManager) addRemoteIndexHostInfo(index uint32, h *HostInfo) {
|
|
||||||
c.pendingHostMap.addRemoteIndexHostInfo(index, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *HandshakeManager) DeleteHostInfo(hostinfo *HostInfo) {
|
func (c *HandshakeManager) DeleteHostInfo(hostinfo *HostInfo) {
|
||||||
//l.Debugln("Deleting pending hostinfo :", hostinfo)
|
c.Lock()
|
||||||
c.pendingHostMap.DeleteHostInfo(hostinfo)
|
defer c.Unlock()
|
||||||
|
c.unlockedDeleteHostInfo(hostinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HandshakeManager) QueryIndex(index uint32) (*HostInfo, error) {
|
func (c *HandshakeManager) unlockedDeleteHostInfo(hostinfo *HostInfo) {
|
||||||
return c.pendingHostMap.QueryIndex(index)
|
delete(c.vpnIps, hostinfo.vpnIp)
|
||||||
|
if len(c.vpnIps) == 0 {
|
||||||
|
c.vpnIps = map[iputil.VpnIp]*HostInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(c.indexes, hostinfo.localIndexId)
|
||||||
|
if len(c.vpnIps) == 0 {
|
||||||
|
c.indexes = map[uint32]*HostInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.l.Level >= logrus.DebugLevel {
|
||||||
|
c.l.WithField("hostMap", m{"mapTotalSize": len(c.vpnIps),
|
||||||
|
"vpnIp": hostinfo.vpnIp, "indexNumber": hostinfo.localIndexId, "remoteIndexNumber": hostinfo.remoteIndexId}).
|
||||||
|
Debug("Pending hostmap hostInfo deleted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandshakeManager) QueryVpnIp(vpnIp iputil.VpnIp) *HostInfo {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
return c.vpnIps[vpnIp]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandshakeManager) QueryIndex(index uint32) *HostInfo {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
return c.indexes[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandshakeManager) GetPreferredRanges() []*net.IPNet {
|
||||||
|
return c.mainHostMap.preferredRanges
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandshakeManager) ForEachVpnIp(f controlEach) {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
|
||||||
|
for _, v := range c.vpnIps {
|
||||||
|
f(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandshakeManager) ForEachIndex(f controlEach) {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
|
||||||
|
for _, v := range c.indexes {
|
||||||
|
f(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HandshakeManager) EmitStats() {
|
func (c *HandshakeManager) EmitStats() {
|
||||||
c.pendingHostMap.EmitStats("pending")
|
c.RLock()
|
||||||
c.mainHostMap.EmitStats("main")
|
hostLen := len(c.vpnIps)
|
||||||
|
indexLen := len(c.indexes)
|
||||||
|
c.RUnlock()
|
||||||
|
|
||||||
|
metrics.GetOrRegisterGauge("hostmap.pending.hosts", nil).Update(int64(hostLen))
|
||||||
|
metrics.GetOrRegisterGauge("hostmap.pending.indexes", nil).Update(int64(indexLen))
|
||||||
|
c.mainHostMap.EmitStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility functions below
|
// Utility functions below
|
||||||
|
|
|
@ -20,7 +20,7 @@ func Test_NewHandshakeManagerVpnIp(t *testing.T) {
|
||||||
ip := iputil.Ip2VpnIp(net.ParseIP("172.1.1.2"))
|
ip := iputil.Ip2VpnIp(net.ParseIP("172.1.1.2"))
|
||||||
preferredRanges := []*net.IPNet{localrange}
|
preferredRanges := []*net.IPNet{localrange}
|
||||||
mw := &mockEncWriter{}
|
mw := &mockEncWriter{}
|
||||||
mainHM := NewHostMap(l, "test", vpncidr, preferredRanges)
|
mainHM := NewHostMap(l, vpncidr, preferredRanges)
|
||||||
lh := newTestLighthouse()
|
lh := newTestLighthouse()
|
||||||
|
|
||||||
blah := NewHandshakeManager(l, tuncidr, preferredRanges, mainHM, lh, &udp.NoopConn{}, defaultHandshakeConfig)
|
blah := NewHandshakeManager(l, tuncidr, preferredRanges, mainHM, lh, &udp.NoopConn{}, defaultHandshakeConfig)
|
||||||
|
@ -48,7 +48,7 @@ func Test_NewHandshakeManagerVpnIp(t *testing.T) {
|
||||||
assert.Len(t, mainHM.Hosts, 0)
|
assert.Len(t, mainHM.Hosts, 0)
|
||||||
|
|
||||||
// Confirm they are in the pending index list
|
// Confirm they are in the pending index list
|
||||||
assert.Contains(t, blah.pendingHostMap.Hosts, ip)
|
assert.Contains(t, blah.vpnIps, ip)
|
||||||
|
|
||||||
// Jump ahead `HandshakeRetries` ticks, offset by one to get the sleep logic right
|
// Jump ahead `HandshakeRetries` ticks, offset by one to get the sleep logic right
|
||||||
for i := 1; i <= DefaultHandshakeRetries+1; i++ {
|
for i := 1; i <= DefaultHandshakeRetries+1; i++ {
|
||||||
|
@ -57,13 +57,13 @@ func Test_NewHandshakeManagerVpnIp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Confirm they are still in the pending index list
|
// Confirm they are still in the pending index list
|
||||||
assert.Contains(t, blah.pendingHostMap.Hosts, ip)
|
assert.Contains(t, blah.vpnIps, ip)
|
||||||
|
|
||||||
// Tick 1 more time, a minute will certainly flush it out
|
// Tick 1 more time, a minute will certainly flush it out
|
||||||
blah.NextOutboundHandshakeTimerTick(now.Add(time.Minute), mw)
|
blah.NextOutboundHandshakeTimerTick(now.Add(time.Minute), mw)
|
||||||
|
|
||||||
// Confirm they have been removed
|
// Confirm they have been removed
|
||||||
assert.NotContains(t, blah.pendingHostMap.Hosts, ip)
|
assert.NotContains(t, blah.vpnIps, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCountTimerWheelEntries(tw *LockingTimerWheel[iputil.VpnIp]) (c int) {
|
func testCountTimerWheelEntries(tw *LockingTimerWheel[iputil.VpnIp]) (c int) {
|
||||||
|
|
175
hostmap.go
175
hostmap.go
|
@ -2,7 +2,6 @@ package nebula
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -52,7 +51,6 @@ type Relay struct {
|
||||||
|
|
||||||
type HostMap struct {
|
type HostMap struct {
|
||||||
sync.RWMutex //Because we concurrently read and write to our maps
|
sync.RWMutex //Because we concurrently read and write to our maps
|
||||||
name string
|
|
||||||
Indexes map[uint32]*HostInfo
|
Indexes map[uint32]*HostInfo
|
||||||
Relays map[uint32]*HostInfo // Maps a Relay IDX to a Relay HostInfo object
|
Relays map[uint32]*HostInfo // Maps a Relay IDX to a Relay HostInfo object
|
||||||
RemoteIndexes map[uint32]*HostInfo
|
RemoteIndexes map[uint32]*HostInfo
|
||||||
|
@ -208,7 +206,7 @@ type HostInfo struct {
|
||||||
HandshakeCounter int //todo: another handshake manager entry
|
HandshakeCounter int //todo: another handshake manager entry
|
||||||
HandshakeLastRemotes []*udp.Addr //todo: another handshake manager entry, which remotes we sent to last time
|
HandshakeLastRemotes []*udp.Addr //todo: another handshake manager entry, which remotes we sent to last time
|
||||||
HandshakeComplete bool //todo: this should go away in favor of ConnectionState.ready
|
HandshakeComplete bool //todo: this should go away in favor of ConnectionState.ready
|
||||||
HandshakePacket map[uint8][]byte //todo: this is other handshake manager entry
|
HandshakePacket map[uint8][]byte
|
||||||
packetStore []*cachedPacket //todo: this is other handshake manager entry
|
packetStore []*cachedPacket //todo: this is other handshake manager entry
|
||||||
remoteIndexId uint32
|
remoteIndexId uint32
|
||||||
localIndexId uint32
|
localIndexId uint32
|
||||||
|
@ -255,13 +253,12 @@ type cachedPacketMetrics struct {
|
||||||
dropped metrics.Counter
|
dropped metrics.Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHostMap(l *logrus.Logger, name string, vpnCIDR *net.IPNet, preferredRanges []*net.IPNet) *HostMap {
|
func NewHostMap(l *logrus.Logger, vpnCIDR *net.IPNet, preferredRanges []*net.IPNet) *HostMap {
|
||||||
h := map[iputil.VpnIp]*HostInfo{}
|
h := map[iputil.VpnIp]*HostInfo{}
|
||||||
i := map[uint32]*HostInfo{}
|
i := map[uint32]*HostInfo{}
|
||||||
r := map[uint32]*HostInfo{}
|
r := map[uint32]*HostInfo{}
|
||||||
relays := map[uint32]*HostInfo{}
|
relays := map[uint32]*HostInfo{}
|
||||||
m := HostMap{
|
m := HostMap{
|
||||||
name: name,
|
|
||||||
Indexes: i,
|
Indexes: i,
|
||||||
Relays: relays,
|
Relays: relays,
|
||||||
RemoteIndexes: r,
|
RemoteIndexes: r,
|
||||||
|
@ -273,8 +270,8 @@ func NewHostMap(l *logrus.Logger, name string, vpnCIDR *net.IPNet, preferredRang
|
||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateStats takes a name and reports host and index counts to the stats collection system
|
// EmitStats reports host, index, and relay counts to the stats collection system
|
||||||
func (hm *HostMap) EmitStats(name string) {
|
func (hm *HostMap) EmitStats() {
|
||||||
hm.RLock()
|
hm.RLock()
|
||||||
hostLen := len(hm.Hosts)
|
hostLen := len(hm.Hosts)
|
||||||
indexLen := len(hm.Indexes)
|
indexLen := len(hm.Indexes)
|
||||||
|
@ -282,10 +279,10 @@ func (hm *HostMap) EmitStats(name string) {
|
||||||
relaysLen := len(hm.Relays)
|
relaysLen := len(hm.Relays)
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
|
|
||||||
metrics.GetOrRegisterGauge("hostmap."+name+".hosts", nil).Update(int64(hostLen))
|
metrics.GetOrRegisterGauge("hostmap.main.hosts", nil).Update(int64(hostLen))
|
||||||
metrics.GetOrRegisterGauge("hostmap."+name+".indexes", nil).Update(int64(indexLen))
|
metrics.GetOrRegisterGauge("hostmap.main.indexes", nil).Update(int64(indexLen))
|
||||||
metrics.GetOrRegisterGauge("hostmap."+name+".remoteIndexes", nil).Update(int64(remoteIndexLen))
|
metrics.GetOrRegisterGauge("hostmap.main.remoteIndexes", nil).Update(int64(remoteIndexLen))
|
||||||
metrics.GetOrRegisterGauge("hostmap."+name+".relayIndexes", nil).Update(int64(relaysLen))
|
metrics.GetOrRegisterGauge("hostmap.main.relayIndexes", nil).Update(int64(relaysLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) RemoveRelay(localIdx uint32) {
|
func (hm *HostMap) RemoveRelay(localIdx uint32) {
|
||||||
|
@ -299,88 +296,6 @@ func (hm *HostMap) RemoveRelay(localIdx uint32) {
|
||||||
hm.Unlock()
|
hm.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) GetIndexByVpnIp(vpnIp iputil.VpnIp) (uint32, error) {
|
|
||||||
hm.RLock()
|
|
||||||
if i, ok := hm.Hosts[vpnIp]; ok {
|
|
||||||
index := i.localIndexId
|
|
||||||
hm.RUnlock()
|
|
||||||
return index, nil
|
|
||||||
}
|
|
||||||
hm.RUnlock()
|
|
||||||
return 0, errors.New("vpn IP not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hm *HostMap) Add(ip iputil.VpnIp, hostinfo *HostInfo) {
|
|
||||||
hm.Lock()
|
|
||||||
hm.Hosts[ip] = hostinfo
|
|
||||||
hm.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hm *HostMap) AddVpnIp(vpnIp iputil.VpnIp, init func(hostinfo *HostInfo)) (hostinfo *HostInfo, created bool) {
|
|
||||||
hm.RLock()
|
|
||||||
if h, ok := hm.Hosts[vpnIp]; !ok {
|
|
||||||
hm.RUnlock()
|
|
||||||
h = &HostInfo{
|
|
||||||
vpnIp: vpnIp,
|
|
||||||
HandshakePacket: make(map[uint8][]byte, 0),
|
|
||||||
relayState: RelayState{
|
|
||||||
relays: map[iputil.VpnIp]struct{}{},
|
|
||||||
relayForByIp: map[iputil.VpnIp]*Relay{},
|
|
||||||
relayForByIdx: map[uint32]*Relay{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if init != nil {
|
|
||||||
init(h)
|
|
||||||
}
|
|
||||||
hm.Lock()
|
|
||||||
hm.Hosts[vpnIp] = h
|
|
||||||
hm.Unlock()
|
|
||||||
return h, true
|
|
||||||
} else {
|
|
||||||
hm.RUnlock()
|
|
||||||
return h, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only used by pendingHostMap when the remote index is not initially known
|
|
||||||
func (hm *HostMap) addRemoteIndexHostInfo(index uint32, h *HostInfo) {
|
|
||||||
hm.Lock()
|
|
||||||
h.remoteIndexId = index
|
|
||||||
hm.RemoteIndexes[index] = h
|
|
||||||
hm.Unlock()
|
|
||||||
|
|
||||||
if hm.l.Level > logrus.DebugLevel {
|
|
||||||
hm.l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes),
|
|
||||||
"hostinfo": m{"existing": true, "localIndexId": h.localIndexId, "hostId": h.vpnIp}}).
|
|
||||||
Debug("Hostmap remoteIndex added")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteReverseIndex is used to clean up on recv_error
|
|
||||||
// This function should only ever be called on the pending hostmap
|
|
||||||
func (hm *HostMap) DeleteReverseIndex(index uint32) {
|
|
||||||
hm.Lock()
|
|
||||||
hostinfo, ok := hm.RemoteIndexes[index]
|
|
||||||
if ok {
|
|
||||||
delete(hm.Indexes, hostinfo.localIndexId)
|
|
||||||
delete(hm.RemoteIndexes, index)
|
|
||||||
|
|
||||||
// Check if we have an entry under hostId that matches the same hostinfo
|
|
||||||
// instance. Clean it up as well if we do (they might not match in pendingHostmap)
|
|
||||||
var hostinfo2 *HostInfo
|
|
||||||
hostinfo2, ok = hm.Hosts[hostinfo.vpnIp]
|
|
||||||
if ok && hostinfo2 == hostinfo {
|
|
||||||
delete(hm.Hosts, hostinfo.vpnIp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hm.Unlock()
|
|
||||||
|
|
||||||
if hm.l.Level >= logrus.DebugLevel {
|
|
||||||
hm.l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes)}).
|
|
||||||
Debug("Hostmap remote index deleted")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteHostInfo will fully unlink the hostinfo and return true if it was the final hostinfo for this vpn ip
|
// DeleteHostInfo will fully unlink the hostinfo and return true if it was the final hostinfo for this vpn ip
|
||||||
func (hm *HostMap) DeleteHostInfo(hostinfo *HostInfo) bool {
|
func (hm *HostMap) DeleteHostInfo(hostinfo *HostInfo) bool {
|
||||||
// Delete the host itself, ensuring it's not modified anymore
|
// Delete the host itself, ensuring it's not modified anymore
|
||||||
|
@ -393,12 +308,6 @@ func (hm *HostMap) DeleteHostInfo(hostinfo *HostInfo) bool {
|
||||||
return final
|
return final
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) DeleteRelayIdx(localIdx uint32) {
|
|
||||||
hm.Lock()
|
|
||||||
defer hm.Unlock()
|
|
||||||
delete(hm.RemoteIndexes, localIdx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hm *HostMap) MakePrimary(hostinfo *HostInfo) {
|
func (hm *HostMap) MakePrimary(hostinfo *HostInfo) {
|
||||||
hm.Lock()
|
hm.Lock()
|
||||||
defer hm.Unlock()
|
defer hm.Unlock()
|
||||||
|
@ -476,7 +385,7 @@ func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hm.l.Level >= logrus.DebugLevel {
|
if hm.l.Level >= logrus.DebugLevel {
|
||||||
hm.l.WithField("hostMap", m{"mapName": hm.name, "mapTotalSize": len(hm.Hosts),
|
hm.l.WithField("hostMap", m{"mapTotalSize": len(hm.Hosts),
|
||||||
"vpnIp": hostinfo.vpnIp, "indexNumber": hostinfo.localIndexId, "remoteIndexNumber": hostinfo.remoteIndexId}).
|
"vpnIp": hostinfo.vpnIp, "indexNumber": hostinfo.localIndexId, "remoteIndexNumber": hostinfo.remoteIndexId}).
|
||||||
Debug("Hostmap hostInfo deleted")
|
Debug("Hostmap hostInfo deleted")
|
||||||
}
|
}
|
||||||
|
@ -486,55 +395,41 @@ func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) QueryIndex(index uint32) (*HostInfo, error) {
|
func (hm *HostMap) QueryIndex(index uint32) *HostInfo {
|
||||||
//TODO: we probably just want to return bool instead of error, or at least a static error
|
|
||||||
hm.RLock()
|
hm.RLock()
|
||||||
if h, ok := hm.Indexes[index]; ok {
|
if h, ok := hm.Indexes[index]; ok {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return h, nil
|
return h
|
||||||
} else {
|
} else {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return nil, errors.New("unable to find index")
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves a HostInfo by Index. Returns whether the HostInfo is primary at time of query.
|
func (hm *HostMap) QueryRelayIndex(index uint32) *HostInfo {
|
||||||
// This helper exists so that the hostinfo.prev pointer can be read while the hostmap lock is held.
|
|
||||||
func (hm *HostMap) QueryIndexIsPrimary(index uint32) (*HostInfo, bool, error) {
|
|
||||||
//TODO: we probably just want to return bool instead of error, or at least a static error
|
|
||||||
hm.RLock()
|
|
||||||
if h, ok := hm.Indexes[index]; ok {
|
|
||||||
hm.RUnlock()
|
|
||||||
return h, h.prev == nil, nil
|
|
||||||
} else {
|
|
||||||
hm.RUnlock()
|
|
||||||
return nil, false, errors.New("unable to find index")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (hm *HostMap) QueryRelayIndex(index uint32) (*HostInfo, error) {
|
|
||||||
//TODO: we probably just want to return bool instead of error, or at least a static error
|
//TODO: we probably just want to return bool instead of error, or at least a static error
|
||||||
hm.RLock()
|
hm.RLock()
|
||||||
if h, ok := hm.Relays[index]; ok {
|
if h, ok := hm.Relays[index]; ok {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return h, nil
|
return h
|
||||||
} else {
|
} else {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return nil, errors.New("unable to find index")
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) QueryReverseIndex(index uint32) (*HostInfo, error) {
|
func (hm *HostMap) QueryReverseIndex(index uint32) *HostInfo {
|
||||||
hm.RLock()
|
hm.RLock()
|
||||||
if h, ok := hm.RemoteIndexes[index]; ok {
|
if h, ok := hm.RemoteIndexes[index]; ok {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return h, nil
|
return h
|
||||||
} else {
|
} else {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return nil, fmt.Errorf("unable to find reverse index or connectionstate nil in %s hostmap", hm.name)
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) QueryVpnIp(vpnIp iputil.VpnIp) (*HostInfo, error) {
|
func (hm *HostMap) QueryVpnIp(vpnIp iputil.VpnIp) *HostInfo {
|
||||||
return hm.queryVpnIp(vpnIp, nil)
|
return hm.queryVpnIp(vpnIp, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,11 +453,11 @@ func (hm *HostMap) QueryVpnIpRelayFor(targetIp, relayHostIp iputil.VpnIp) (*Host
|
||||||
|
|
||||||
// PromoteBestQueryVpnIp will attempt to lazily switch to the best remote every
|
// PromoteBestQueryVpnIp will attempt to lazily switch to the best remote every
|
||||||
// `PromoteEvery` calls to this function for a given host.
|
// `PromoteEvery` calls to this function for a given host.
|
||||||
func (hm *HostMap) PromoteBestQueryVpnIp(vpnIp iputil.VpnIp, ifce *Interface) (*HostInfo, error) {
|
func (hm *HostMap) PromoteBestQueryVpnIp(vpnIp iputil.VpnIp, ifce *Interface) *HostInfo {
|
||||||
return hm.queryVpnIp(vpnIp, ifce)
|
return hm.queryVpnIp(vpnIp, ifce)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HostMap) queryVpnIp(vpnIp iputil.VpnIp, promoteIfce *Interface) (*HostInfo, error) {
|
func (hm *HostMap) queryVpnIp(vpnIp iputil.VpnIp, promoteIfce *Interface) *HostInfo {
|
||||||
hm.RLock()
|
hm.RLock()
|
||||||
if h, ok := hm.Hosts[vpnIp]; ok {
|
if h, ok := hm.Hosts[vpnIp]; ok {
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
|
@ -570,12 +465,12 @@ func (hm *HostMap) queryVpnIp(vpnIp iputil.VpnIp, promoteIfce *Interface) (*Host
|
||||||
if promoteIfce != nil && !promoteIfce.lightHouse.amLighthouse {
|
if promoteIfce != nil && !promoteIfce.lightHouse.amLighthouse {
|
||||||
h.TryPromoteBest(hm.preferredRanges, promoteIfce)
|
h.TryPromoteBest(hm.preferredRanges, promoteIfce)
|
||||||
}
|
}
|
||||||
return h, nil
|
return h
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hm.RUnlock()
|
hm.RUnlock()
|
||||||
return nil, errors.New("unable to find host")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlockedAddHostInfo assumes you have a write-lock and will add a hostinfo object to the hostmap Indexes and RemoteIndexes maps.
|
// unlockedAddHostInfo assumes you have a write-lock and will add a hostinfo object to the hostmap Indexes and RemoteIndexes maps.
|
||||||
|
@ -598,7 +493,7 @@ func (hm *HostMap) unlockedAddHostInfo(hostinfo *HostInfo, f *Interface) {
|
||||||
hm.RemoteIndexes[hostinfo.remoteIndexId] = hostinfo
|
hm.RemoteIndexes[hostinfo.remoteIndexId] = hostinfo
|
||||||
|
|
||||||
if hm.l.Level >= logrus.DebugLevel {
|
if hm.l.Level >= logrus.DebugLevel {
|
||||||
hm.l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": hostinfo.vpnIp, "mapTotalSize": len(hm.Hosts),
|
hm.l.WithField("hostMap", m{"vpnIp": hostinfo.vpnIp, "mapTotalSize": len(hm.Hosts),
|
||||||
"hostinfo": m{"existing": true, "localIndexId": hostinfo.localIndexId, "hostId": hostinfo.vpnIp}}).
|
"hostinfo": m{"existing": true, "localIndexId": hostinfo.localIndexId, "hostId": hostinfo.vpnIp}}).
|
||||||
Debug("Hostmap vpnIp added")
|
Debug("Hostmap vpnIp added")
|
||||||
}
|
}
|
||||||
|
@ -614,6 +509,28 @@ func (hm *HostMap) unlockedAddHostInfo(hostinfo *HostInfo, f *Interface) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hm *HostMap) GetPreferredRanges() []*net.IPNet {
|
||||||
|
return hm.preferredRanges
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HostMap) ForEachVpnIp(f controlEach) {
|
||||||
|
hm.RLock()
|
||||||
|
defer hm.RUnlock()
|
||||||
|
|
||||||
|
for _, v := range hm.Hosts {
|
||||||
|
f(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HostMap) ForEachIndex(f controlEach) {
|
||||||
|
hm.RLock()
|
||||||
|
defer hm.RUnlock()
|
||||||
|
|
||||||
|
for _, v := range hm.Indexes {
|
||||||
|
f(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TryPromoteBest handles re-querying lighthouses and probing for better paths
|
// TryPromoteBest handles re-querying lighthouses and probing for better paths
|
||||||
// NOTE: It is an error to call this if you are a lighthouse since they should not roam clients!
|
// NOTE: It is an error to call this if you are a lighthouse since they should not roam clients!
|
||||||
func (i *HostInfo) TryPromoteBest(preferredRanges []*net.IPNet, ifce *Interface) {
|
func (i *HostInfo) TryPromoteBest(preferredRanges []*net.IPNet, ifce *Interface) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
func TestHostMap_MakePrimary(t *testing.T) {
|
func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
l := test.NewLogger()
|
l := test.NewLogger()
|
||||||
hm := NewHostMap(
|
hm := NewHostMap(
|
||||||
l, "test",
|
l,
|
||||||
&net.IPNet{
|
&net.IPNet{
|
||||||
IP: net.IP{10, 0, 0, 1},
|
IP: net.IP{10, 0, 0, 1},
|
||||||
Mask: net.IPMask{255, 255, 255, 0},
|
Mask: net.IPMask{255, 255, 255, 0},
|
||||||
|
@ -32,7 +32,7 @@ func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
hm.unlockedAddHostInfo(h1, f)
|
hm.unlockedAddHostInfo(h1, f)
|
||||||
|
|
||||||
// Make sure we go h1 -> h2 -> h3 -> h4
|
// Make sure we go h1 -> h2 -> h3 -> h4
|
||||||
prim, _ := hm.QueryVpnIp(1)
|
prim := hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h1.localIndexId, prim.localIndexId)
|
assert.Equal(t, h1.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h2.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h2.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -47,7 +47,7 @@ func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
hm.MakePrimary(h3)
|
hm.MakePrimary(h3)
|
||||||
|
|
||||||
// Make sure we go h3 -> h1 -> h2 -> h4
|
// Make sure we go h3 -> h1 -> h2 -> h4
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h3.localIndexId, prim.localIndexId)
|
assert.Equal(t, h3.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h1.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h1.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -62,7 +62,7 @@ func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
hm.MakePrimary(h4)
|
hm.MakePrimary(h4)
|
||||||
|
|
||||||
// Make sure we go h4 -> h3 -> h1 -> h2
|
// Make sure we go h4 -> h3 -> h1 -> h2
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -77,7 +77,7 @@ func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
hm.MakePrimary(h4)
|
hm.MakePrimary(h4)
|
||||||
|
|
||||||
// Make sure we go h4 -> h3 -> h1 -> h2
|
// Make sure we go h4 -> h3 -> h1 -> h2
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -92,7 +92,7 @@ func TestHostMap_MakePrimary(t *testing.T) {
|
||||||
func TestHostMap_DeleteHostInfo(t *testing.T) {
|
func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
l := test.NewLogger()
|
l := test.NewLogger()
|
||||||
hm := NewHostMap(
|
hm := NewHostMap(
|
||||||
l, "test",
|
l,
|
||||||
&net.IPNet{
|
&net.IPNet{
|
||||||
IP: net.IP{10, 0, 0, 1},
|
IP: net.IP{10, 0, 0, 1},
|
||||||
Mask: net.IPMask{255, 255, 255, 0},
|
Mask: net.IPMask{255, 255, 255, 0},
|
||||||
|
@ -119,11 +119,11 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
// h6 should be deleted
|
// h6 should be deleted
|
||||||
assert.Nil(t, h6.next)
|
assert.Nil(t, h6.next)
|
||||||
assert.Nil(t, h6.prev)
|
assert.Nil(t, h6.prev)
|
||||||
_, err := hm.QueryIndex(h6.localIndexId)
|
h := hm.QueryIndex(h6.localIndexId)
|
||||||
assert.Error(t, err)
|
assert.Nil(t, h)
|
||||||
|
|
||||||
// Make sure we go h1 -> h2 -> h3 -> h4 -> h5
|
// Make sure we go h1 -> h2 -> h3 -> h4 -> h5
|
||||||
prim, _ := hm.QueryVpnIp(1)
|
prim := hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h1.localIndexId, prim.localIndexId)
|
assert.Equal(t, h1.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h2.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h2.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -142,7 +142,7 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
assert.Nil(t, h1.next)
|
assert.Nil(t, h1.next)
|
||||||
|
|
||||||
// Make sure we go h2 -> h3 -> h4 -> h5
|
// Make sure we go h2 -> h3 -> h4 -> h5
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h3.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -160,7 +160,7 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
assert.Nil(t, h3.next)
|
assert.Nil(t, h3.next)
|
||||||
|
|
||||||
// Make sure we go h2 -> h4 -> h5
|
// Make sure we go h2 -> h4 -> h5
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h4.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h4.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -176,7 +176,7 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
assert.Nil(t, h5.next)
|
assert.Nil(t, h5.next)
|
||||||
|
|
||||||
// Make sure we go h2 -> h4
|
// Make sure we go h2 -> h4
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
assert.Equal(t, h2.localIndexId, prim.localIndexId)
|
||||||
assert.Equal(t, h4.localIndexId, prim.next.localIndexId)
|
assert.Equal(t, h4.localIndexId, prim.next.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
|
@ -190,7 +190,7 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
assert.Nil(t, h2.next)
|
assert.Nil(t, h2.next)
|
||||||
|
|
||||||
// Make sure we only have h4
|
// Make sure we only have h4
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
assert.Equal(t, h4.localIndexId, prim.localIndexId)
|
||||||
assert.Nil(t, prim.prev)
|
assert.Nil(t, prim.prev)
|
||||||
assert.Nil(t, prim.next)
|
assert.Nil(t, prim.next)
|
||||||
|
@ -202,6 +202,6 @@ func TestHostMap_DeleteHostInfo(t *testing.T) {
|
||||||
assert.Nil(t, h4.next)
|
assert.Nil(t, h4.next)
|
||||||
|
|
||||||
// Make sure we have nil
|
// Make sure we have nil
|
||||||
prim, _ = hm.QueryVpnIp(1)
|
prim = hm.QueryVpnIp(1)
|
||||||
assert.Nil(t, prim)
|
assert.Nil(t, prim)
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,15 +121,11 @@ func (f *Interface) getOrHandshake(vpnIp iputil.VpnIp) *HostInfo {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hostinfo, err := f.hostMap.PromoteBestQueryVpnIp(vpnIp, f)
|
|
||||||
|
|
||||||
//if err != nil || hostinfo.ConnectionState == nil {
|
hostinfo := f.hostMap.PromoteBestQueryVpnIp(vpnIp, f)
|
||||||
if err != nil {
|
if hostinfo == nil {
|
||||||
hostinfo, err = f.handshakeManager.pendingHostMap.QueryVpnIp(vpnIp)
|
|
||||||
if err != nil {
|
|
||||||
hostinfo = f.handshakeManager.AddVpnIp(vpnIp, f.initHostInfo)
|
hostinfo = f.handshakeManager.AddVpnIp(vpnIp, f.initHostInfo)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ci := hostinfo.ConnectionState
|
ci := hostinfo.ConnectionState
|
||||||
|
|
||||||
if ci != nil && ci.eKey != nil && ci.ready {
|
if ci != nil && ci.eKey != nil && ci.ready {
|
||||||
|
@ -137,6 +133,7 @@ func (f *Interface) getOrHandshake(vpnIp iputil.VpnIp) *HostInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handshake is not ready, we need to grab the lock now before we start the handshake process
|
// Handshake is not ready, we need to grab the lock now before we start the handshake process
|
||||||
|
//TODO: move this to handshake manager
|
||||||
hostinfo.Lock()
|
hostinfo.Lock()
|
||||||
defer hostinfo.Unlock()
|
defer hostinfo.Unlock()
|
||||||
|
|
||||||
|
|
4
main.go
4
main.go
|
@ -212,7 +212,7 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostMap := NewHostMap(l, "main", tunCidr, preferredRanges)
|
hostMap := NewHostMap(l, tunCidr, preferredRanges)
|
||||||
hostMap.metricsEnabled = c.GetBool("stats.message_metrics", false)
|
hostMap.metricsEnabled = c.GetBool("stats.message_metrics", false)
|
||||||
|
|
||||||
l.
|
l.
|
||||||
|
@ -339,7 +339,7 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
||||||
//TODO: check if we _should_ be emitting stats
|
//TODO: check if we _should_ be emitting stats
|
||||||
go ifce.emitStats(ctx, c.GetDuration("stats.interval", time.Second*10))
|
go ifce.emitStats(ctx, c.GetDuration("stats.interval", time.Second*10))
|
||||||
|
|
||||||
attachCommands(l, c, ssh, hostMap, handshakeManager.pendingHostMap, lightHouse, ifce)
|
attachCommands(l, c, ssh, ifce)
|
||||||
|
|
||||||
// Start DNS server last to allow using the nebula IP as lighthouse.dns.host
|
// Start DNS server last to allow using the nebula IP as lighthouse.dns.host
|
||||||
var dnsStart func()
|
var dnsStart func()
|
||||||
|
|
17
outside.go
17
outside.go
|
@ -64,9 +64,9 @@ func (f *Interface) readOutsidePackets(addr *udp.Addr, via *ViaSender, out []byt
|
||||||
var hostinfo *HostInfo
|
var hostinfo *HostInfo
|
||||||
// verify if we've seen this index before, otherwise respond to the handshake initiation
|
// verify if we've seen this index before, otherwise respond to the handshake initiation
|
||||||
if h.Type == header.Message && h.Subtype == header.MessageRelay {
|
if h.Type == header.Message && h.Subtype == header.MessageRelay {
|
||||||
hostinfo, _ = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
hostinfo = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
||||||
} else {
|
} else {
|
||||||
hostinfo, _ = f.hostMap.QueryIndex(h.RemoteIndex)
|
hostinfo = f.hostMap.QueryIndex(h.RemoteIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ci *ConnectionState
|
var ci *ConnectionState
|
||||||
|
@ -449,12 +449,9 @@ func (f *Interface) handleRecvError(addr *udp.Addr, h *header.H) {
|
||||||
Debug("Recv error received")
|
Debug("Recv error received")
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, clean up in the pending hostmap
|
hostinfo := f.hostMap.QueryReverseIndex(h.RemoteIndex)
|
||||||
f.handshakeManager.pendingHostMap.DeleteReverseIndex(h.RemoteIndex)
|
if hostinfo == nil {
|
||||||
|
f.l.WithField("remoteIndex", h.RemoteIndex).Debugln("Did not find remote index in main hostmap")
|
||||||
hostinfo, err := f.hostMap.QueryReverseIndex(h.RemoteIndex)
|
|
||||||
if err != nil {
|
|
||||||
f.l.Debugln(err, ": ", h.RemoteIndex)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,14 +461,14 @@ func (f *Interface) handleRecvError(addr *udp.Addr, h *header.H) {
|
||||||
if !hostinfo.RecvErrorExceeded() {
|
if !hostinfo.RecvErrorExceeded() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if hostinfo.remote != nil && !hostinfo.remote.Equals(addr) {
|
if hostinfo.remote != nil && !hostinfo.remote.Equals(addr) {
|
||||||
f.l.Infoln("Someone spoofing recv_errors? ", addr, hostinfo.remote)
|
f.l.Infoln("Someone spoofing recv_errors? ", addr, hostinfo.remote)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f.closeTunnel(hostinfo)
|
f.closeTunnel(hostinfo)
|
||||||
// We also delete it from pending hostmap to allow for
|
// We also delete it from pending hostmap to allow for fast reconnect.
|
||||||
// fast reconnect.
|
|
||||||
f.handshakeManager.DeleteHostInfo(hostinfo)
|
f.handshakeManager.DeleteHostInfo(hostinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,9 +131,9 @@ func (rm *relayManager) handleCreateRelayResponse(h *HostInfo, f *Interface, m *
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// I'm the middle man. Let the initiator know that the I've established the relay they requested.
|
// I'm the middle man. Let the initiator know that the I've established the relay they requested.
|
||||||
peerHostInfo, err := rm.hostmap.QueryVpnIp(relay.PeerIp)
|
peerHostInfo := rm.hostmap.QueryVpnIp(relay.PeerIp)
|
||||||
if err != nil {
|
if peerHostInfo == nil {
|
||||||
rm.l.WithError(err).WithField("relayTo", relay.PeerIp).Error("Can't find a HostInfo for peer")
|
rm.l.WithField("relayTo", relay.PeerIp).Error("Can't find a HostInfo for peer")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
peerRelay, ok := peerHostInfo.relayState.QueryRelayForByIp(target)
|
peerRelay, ok := peerHostInfo.relayState.QueryRelayForByIp(target)
|
||||||
|
@ -240,8 +240,8 @@ func (rm *relayManager) handleCreateRelayRequest(h *HostInfo, f *Interface, m *N
|
||||||
if !rm.GetAmRelay() {
|
if !rm.GetAmRelay() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
peer, err := rm.hostmap.QueryVpnIp(target)
|
peer := rm.hostmap.QueryVpnIp(target)
|
||||||
if err != nil {
|
if peer == nil {
|
||||||
// Try to establish a connection to this host. If we get a future relay request,
|
// Try to establish a connection to this host. If we get a future relay request,
|
||||||
// we'll be ready!
|
// we'll be ready!
|
||||||
f.getOrHandshake(target)
|
f.getOrHandshake(target)
|
||||||
|
@ -253,6 +253,7 @@ func (rm *relayManager) handleCreateRelayRequest(h *HostInfo, f *Interface, m *N
|
||||||
}
|
}
|
||||||
sendCreateRequest := false
|
sendCreateRequest := false
|
||||||
var index uint32
|
var index uint32
|
||||||
|
var err error
|
||||||
targetRelay, ok := peer.relayState.QueryRelayForByIp(from)
|
targetRelay, ok := peer.relayState.QueryRelayForByIp(from)
|
||||||
if ok {
|
if ok {
|
||||||
index = targetRelay.LocalIndex
|
index = targetRelay.LocalIndex
|
||||||
|
|
61
ssh.go
61
ssh.go
|
@ -3,6 +3,7 @@ package nebula
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -168,7 +169,7 @@ func configSSH(l *logrus.Logger, ssh *sshd.SSHServer, c *config.C) (func(), erro
|
||||||
return runner, nil
|
return runner, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap *HostMap, pendingHostMap *HostMap, lightHouse *LightHouse, ifce *Interface) {
|
func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, f *Interface) {
|
||||||
ssh.RegisterCommand(&sshd.Command{
|
ssh.RegisterCommand(&sshd.Command{
|
||||||
Name: "list-hostmap",
|
Name: "list-hostmap",
|
||||||
ShortDescription: "List all known previously connected hosts",
|
ShortDescription: "List all known previously connected hosts",
|
||||||
|
@ -181,7 +182,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshListHostMap(hostMap, fs, w)
|
return sshListHostMap(f.hostMap, fs, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshListHostMap(pendingHostMap, fs, w)
|
return sshListHostMap(f.handshakeManager, fs, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshListLighthouseMap(lightHouse, fs, w)
|
return sshListLighthouseMap(f.lightHouse, fs, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -277,7 +278,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
Name: "version",
|
Name: "version",
|
||||||
ShortDescription: "Prints the currently running version of nebula",
|
ShortDescription: "Prints the currently running version of nebula",
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshVersion(ifce, fs, a, w)
|
return sshVersion(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshPrintCert(ifce, fs, a, w)
|
return sshPrintCert(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -307,7 +308,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshPrintTunnel(ifce, fs, a, w)
|
return sshPrintTunnel(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -321,7 +322,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshPrintRelays(ifce, fs, a, w)
|
return sshPrintRelays(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -335,7 +336,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshChangeRemote(ifce, fs, a, w)
|
return sshChangeRemote(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -349,7 +350,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshCloseTunnel(ifce, fs, a, w)
|
return sshCloseTunnel(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -364,7 +365,7 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
return fl, &s
|
return fl, &s
|
||||||
},
|
},
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshCreateTunnel(ifce, fs, a, w)
|
return sshCreateTunnel(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -373,12 +374,12 @@ func attachCommands(l *logrus.Logger, c *config.C, ssh *sshd.SSHServer, hostMap
|
||||||
ShortDescription: "Query the lighthouses for the provided vpn ip",
|
ShortDescription: "Query the lighthouses for the provided vpn ip",
|
||||||
Help: "This command is asynchronous. Only currently known udp ips will be printed.",
|
Help: "This command is asynchronous. Only currently known udp ips will be printed.",
|
||||||
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
Callback: func(fs interface{}, a []string, w sshd.StringWriter) error {
|
||||||
return sshQueryLighthouse(ifce, fs, a, w)
|
return sshQueryLighthouse(f, fs, a, w)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshListHostMap(hostMap *HostMap, a interface{}, w sshd.StringWriter) error {
|
func sshListHostMap(hl controlHostLister, a interface{}, w sshd.StringWriter) error {
|
||||||
fs, ok := a.(*sshListHostMapFlags)
|
fs, ok := a.(*sshListHostMapFlags)
|
||||||
if !ok {
|
if !ok {
|
||||||
//TODO: error
|
//TODO: error
|
||||||
|
@ -387,9 +388,9 @@ func sshListHostMap(hostMap *HostMap, a interface{}, w sshd.StringWriter) error
|
||||||
|
|
||||||
var hm []ControlHostInfo
|
var hm []ControlHostInfo
|
||||||
if fs.ByIndex {
|
if fs.ByIndex {
|
||||||
hm = listHostMapIndexes(hostMap)
|
hm = listHostMapIndexes(hl)
|
||||||
} else {
|
} else {
|
||||||
hm = listHostMapHosts(hostMap)
|
hm = listHostMapHosts(hl)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(hm, func(i, j int) bool {
|
sort.Slice(hm, func(i, j int) bool {
|
||||||
|
@ -546,8 +547,8 @@ func sshCloseTunnel(ifce *Interface, fs interface{}, a []string, w sshd.StringWr
|
||||||
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, err := ifce.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,12 +589,12 @@ func sshCreateTunnel(ifce *Interface, fs interface{}, a []string, w sshd.StringW
|
||||||
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, _ := ifce.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if hostInfo != nil {
|
if hostInfo != nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Tunnel already exists"))
|
return w.WriteLine(fmt.Sprintf("Tunnel already exists"))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, _ = ifce.handshakeManager.pendingHostMap.QueryVpnIp(vpnIp)
|
hostInfo = ifce.handshakeManager.QueryVpnIp(vpnIp)
|
||||||
if hostInfo != nil {
|
if hostInfo != nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Tunnel already handshaking"))
|
return w.WriteLine(fmt.Sprintf("Tunnel already handshaking"))
|
||||||
}
|
}
|
||||||
|
@ -645,8 +646,8 @@ func sshChangeRemote(ifce *Interface, fs interface{}, a []string, w sshd.StringW
|
||||||
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, err := ifce.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,8 +766,8 @@ func sshPrintCert(ifce *Interface, fs interface{}, a []string, w sshd.StringWrit
|
||||||
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, err := ifce.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,9 +852,9 @@ func sshPrintRelays(ifce *Interface, fs interface{}, a []string, w sshd.StringWr
|
||||||
for k, v := range relays {
|
for k, v := range relays {
|
||||||
ro := RelayOutput{NebulaIp: v.vpnIp}
|
ro := RelayOutput{NebulaIp: v.vpnIp}
|
||||||
co.Relays = append(co.Relays, &ro)
|
co.Relays = append(co.Relays, &ro)
|
||||||
relayHI, err := ifce.hostMap.QueryVpnIp(v.vpnIp)
|
relayHI := ifce.hostMap.QueryVpnIp(v.vpnIp)
|
||||||
if err != nil {
|
if relayHI == nil {
|
||||||
ro.RelayForIps = append(ro.RelayForIps, RelayFor{Error: err})
|
ro.RelayForIps = append(ro.RelayForIps, RelayFor{Error: errors.New("could not find hostinfo")})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, vpnIp := range relayHI.relayState.CopyRelayForIps() {
|
for _, vpnIp := range relayHI.relayState.CopyRelayForIps() {
|
||||||
|
@ -889,8 +890,8 @@ func sshPrintRelays(ifce *Interface, fs interface{}, a []string, w sshd.StringWr
|
||||||
rf.Error = fmt.Errorf("hostmap LocalIndex '%v' does not match RelayState LocalIndex", k)
|
rf.Error = fmt.Errorf("hostmap LocalIndex '%v' does not match RelayState LocalIndex", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
relayedHI, err := ifce.hostMap.QueryVpnIp(vpnIp)
|
relayedHI := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err == nil {
|
if relayedHI != nil {
|
||||||
rf.RelayedThrough = append(rf.RelayedThrough, relayedHI.relayState.CopyRelayIps()...)
|
rf.RelayedThrough = append(rf.RelayedThrough, relayedHI.relayState.CopyRelayIps()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,8 +926,8 @@ func sshPrintTunnel(ifce *Interface, fs interface{}, a []string, w sshd.StringWr
|
||||||
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
return w.WriteLine(fmt.Sprintf("The provided vpn ip could not be parsed: %s", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
hostInfo, err := ifce.hostMap.QueryVpnIp(vpnIp)
|
hostInfo := ifce.hostMap.QueryVpnIp(vpnIp)
|
||||||
if err != nil {
|
if hostInfo == nil {
|
||||||
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
return w.WriteLine(fmt.Sprintf("Could not find tunnel for vpn ip: %v", a[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue