github.com/slackhq/nebula@v1.9.0/control_tester.go (about) 1 //go:build e2e_testing 2 // +build e2e_testing 3 4 package nebula 5 6 import ( 7 "net" 8 9 "github.com/slackhq/nebula/cert" 10 11 "github.com/google/gopacket" 12 "github.com/google/gopacket/layers" 13 "github.com/slackhq/nebula/header" 14 "github.com/slackhq/nebula/iputil" 15 "github.com/slackhq/nebula/overlay" 16 "github.com/slackhq/nebula/udp" 17 ) 18 19 // WaitForType will pipe all messages from this control device into the pipeTo control device 20 // returning after a message matching the criteria has been piped 21 func (c *Control) WaitForType(msgType header.MessageType, subType header.MessageSubType, pipeTo *Control) { 22 h := &header.H{} 23 for { 24 p := c.f.outside.(*udp.TesterConn).Get(true) 25 if err := h.Parse(p.Data); err != nil { 26 panic(err) 27 } 28 pipeTo.InjectUDPPacket(p) 29 if h.Type == msgType && h.Subtype == subType { 30 return 31 } 32 } 33 } 34 35 // WaitForTypeByIndex is similar to WaitForType except it adds an index check 36 // Useful if you have many nodes communicating and want to wait to find a specific nodes packet 37 func (c *Control) WaitForTypeByIndex(toIndex uint32, msgType header.MessageType, subType header.MessageSubType, pipeTo *Control) { 38 h := &header.H{} 39 for { 40 p := c.f.outside.(*udp.TesterConn).Get(true) 41 if err := h.Parse(p.Data); err != nil { 42 panic(err) 43 } 44 pipeTo.InjectUDPPacket(p) 45 if h.RemoteIndex == toIndex && h.Type == msgType && h.Subtype == subType { 46 return 47 } 48 } 49 } 50 51 // InjectLightHouseAddr will push toAddr into the local lighthouse cache for the vpnIp 52 // This is necessary if you did not configure static hosts or are not running a lighthouse 53 func (c *Control) InjectLightHouseAddr(vpnIp net.IP, toAddr *net.UDPAddr) { 54 c.f.lightHouse.Lock() 55 remoteList := c.f.lightHouse.unlockedGetRemoteList(iputil.Ip2VpnIp(vpnIp)) 56 remoteList.Lock() 57 defer remoteList.Unlock() 58 c.f.lightHouse.Unlock() 59 60 iVpnIp := iputil.Ip2VpnIp(vpnIp) 61 if v4 := toAddr.IP.To4(); v4 != nil { 62 remoteList.unlockedPrependV4(iVpnIp, NewIp4AndPort(v4, uint32(toAddr.Port))) 63 } else { 64 remoteList.unlockedPrependV6(iVpnIp, NewIp6AndPort(toAddr.IP, uint32(toAddr.Port))) 65 } 66 } 67 68 // InjectRelays will push relayVpnIps into the local lighthouse cache for the vpnIp 69 // This is necessary to inform an initiator of possible relays for communicating with a responder 70 func (c *Control) InjectRelays(vpnIp net.IP, relayVpnIps []net.IP) { 71 c.f.lightHouse.Lock() 72 remoteList := c.f.lightHouse.unlockedGetRemoteList(iputil.Ip2VpnIp(vpnIp)) 73 remoteList.Lock() 74 defer remoteList.Unlock() 75 c.f.lightHouse.Unlock() 76 77 iVpnIp := iputil.Ip2VpnIp(vpnIp) 78 uVpnIp := []uint32{} 79 for _, rVPnIp := range relayVpnIps { 80 uVpnIp = append(uVpnIp, uint32(iputil.Ip2VpnIp(rVPnIp))) 81 } 82 83 remoteList.unlockedSetRelay(iVpnIp, iVpnIp, uVpnIp) 84 } 85 86 // GetFromTun will pull a packet off the tun side of nebula 87 func (c *Control) GetFromTun(block bool) []byte { 88 return c.f.inside.(*overlay.TestTun).Get(block) 89 } 90 91 // GetFromUDP will pull a udp packet off the udp side of nebula 92 func (c *Control) GetFromUDP(block bool) *udp.Packet { 93 return c.f.outside.(*udp.TesterConn).Get(block) 94 } 95 96 func (c *Control) GetUDPTxChan() <-chan *udp.Packet { 97 return c.f.outside.(*udp.TesterConn).TxPackets 98 } 99 100 func (c *Control) GetTunTxChan() <-chan []byte { 101 return c.f.inside.(*overlay.TestTun).TxPackets 102 } 103 104 // InjectUDPPacket will inject a packet into the udp side of nebula 105 func (c *Control) InjectUDPPacket(p *udp.Packet) { 106 c.f.outside.(*udp.TesterConn).Send(p) 107 } 108 109 // InjectTunUDPPacket puts a udp packet on the tun interface. Using UDP here because it's a simpler protocol 110 func (c *Control) InjectTunUDPPacket(toIp net.IP, toPort uint16, fromPort uint16, data []byte) { 111 ip := layers.IPv4{ 112 Version: 4, 113 TTL: 64, 114 Protocol: layers.IPProtocolUDP, 115 SrcIP: c.f.inside.Cidr().IP, 116 DstIP: toIp, 117 } 118 119 udp := layers.UDP{ 120 SrcPort: layers.UDPPort(fromPort), 121 DstPort: layers.UDPPort(toPort), 122 } 123 err := udp.SetNetworkLayerForChecksum(&ip) 124 if err != nil { 125 panic(err) 126 } 127 128 buffer := gopacket.NewSerializeBuffer() 129 opt := gopacket.SerializeOptions{ 130 ComputeChecksums: true, 131 FixLengths: true, 132 } 133 err = gopacket.SerializeLayers(buffer, opt, &ip, &udp, gopacket.Payload(data)) 134 if err != nil { 135 panic(err) 136 } 137 138 c.f.inside.(*overlay.TestTun).Send(buffer.Bytes()) 139 } 140 141 func (c *Control) GetVpnIp() iputil.VpnIp { 142 return c.f.myVpnIp 143 } 144 145 func (c *Control) GetUDPAddr() string { 146 return c.f.outside.(*udp.TesterConn).Addr.String() 147 } 148 149 func (c *Control) KillPendingTunnel(vpnIp net.IP) bool { 150 hostinfo := c.f.handshakeManager.QueryVpnIp(iputil.Ip2VpnIp(vpnIp)) 151 if hostinfo == nil { 152 return false 153 } 154 155 c.f.handshakeManager.DeleteHostInfo(hostinfo) 156 return true 157 } 158 159 func (c *Control) GetHostmap() *HostMap { 160 return c.f.hostMap 161 } 162 163 func (c *Control) GetCert() *cert.NebulaCertificate { 164 return c.f.pki.GetCertState().Certificate 165 } 166 167 func (c *Control) ReHandshake(vpnIp iputil.VpnIp) { 168 c.f.handshakeManager.StartHandshake(vpnIp, nil) 169 }