control_tester.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //go:build e2e_testing
  2. package nebula
  3. import (
  4. "net/netip"
  5. "github.com/slackhq/nebula/header"
  6. "github.com/slackhq/nebula/overlay"
  7. "github.com/slackhq/nebula/udp"
  8. )
  9. // WaitForType will pipe all messages from this control device into the pipeTo control device
  10. // returning after a message matching the criteria has been piped
  11. func (c *Control) WaitForType(msgType header.MessageType, subType header.MessageSubType, pipeTo *Control) {
  12. h := &header.H{}
  13. for {
  14. p := c.f.outside.(*udp.TesterConn).Get(true)
  15. if err := h.Parse(p.Data); err != nil {
  16. panic(err)
  17. }
  18. pipeTo.InjectUDPPacket(p)
  19. match := h.Type == msgType && h.Subtype == subType
  20. p.Release()
  21. if match {
  22. return
  23. }
  24. }
  25. }
  26. // WaitForTypeByIndex is similar to WaitForType except it adds an index check
  27. // Useful if you have many nodes communicating and want to wait to find a specific nodes packet
  28. func (c *Control) WaitForTypeByIndex(toIndex uint32, msgType header.MessageType, subType header.MessageSubType, pipeTo *Control) {
  29. h := &header.H{}
  30. for {
  31. p := c.f.outside.(*udp.TesterConn).Get(true)
  32. if err := h.Parse(p.Data); err != nil {
  33. panic(err)
  34. }
  35. pipeTo.InjectUDPPacket(p)
  36. match := h.RemoteIndex == toIndex && h.Type == msgType && h.Subtype == subType
  37. p.Release()
  38. if match {
  39. return
  40. }
  41. }
  42. }
  43. // InjectLightHouseAddr will push toAddr into the local lighthouse cache for the vpnIp
  44. // This is necessary if you did not configure static hosts or are not running a lighthouse
  45. func (c *Control) InjectLightHouseAddr(vpnIp netip.Addr, toAddr netip.AddrPort) {
  46. c.f.lightHouse.Lock()
  47. remoteList := c.f.lightHouse.unlockedGetRemoteList([]netip.Addr{vpnIp})
  48. remoteList.Lock()
  49. defer remoteList.Unlock()
  50. c.f.lightHouse.Unlock()
  51. if toAddr.Addr().Is4() {
  52. remoteList.unlockedPrependV4(vpnIp, netAddrToProtoV4AddrPort(toAddr.Addr(), toAddr.Port()))
  53. } else {
  54. remoteList.unlockedPrependV6(vpnIp, netAddrToProtoV6AddrPort(toAddr.Addr(), toAddr.Port()))
  55. }
  56. }
  57. // InjectRelays will push relayVpnIps into the local lighthouse cache for the vpnIp
  58. // This is necessary to inform an initiator of possible relays for communicating with a responder
  59. func (c *Control) InjectRelays(vpnIp netip.Addr, relayVpnIps []netip.Addr) {
  60. c.f.lightHouse.Lock()
  61. remoteList := c.f.lightHouse.unlockedGetRemoteList([]netip.Addr{vpnIp})
  62. remoteList.Lock()
  63. defer remoteList.Unlock()
  64. c.f.lightHouse.Unlock()
  65. remoteList.unlockedSetRelay(vpnIp, relayVpnIps)
  66. }
  67. // GetFromTun will pull a packet off the tun side of nebula
  68. func (c *Control) GetFromTun(block bool) []byte {
  69. return c.f.inside.(*overlay.TestTun).Get(block)
  70. }
  71. // GetFromUDP will pull a udp packet off the udp side of nebula
  72. func (c *Control) GetFromUDP(block bool) *udp.Packet {
  73. return c.f.outside.(*udp.TesterConn).Get(block)
  74. }
  75. func (c *Control) GetUDPTxChan() <-chan *udp.Packet {
  76. return c.f.outside.(*udp.TesterConn).TxPackets
  77. }
  78. func (c *Control) GetTunTxChan() <-chan []byte {
  79. return c.f.inside.(*overlay.TestTun).TxPackets
  80. }
  81. // InjectUDPPacket injects a packet into the udp side. We copy internally so the caller keeps ownership of p.
  82. // The copy comes from the freelist so steady-state alloc is zero.
  83. func (c *Control) InjectUDPPacket(p *udp.Packet) {
  84. c.f.outside.(*udp.TesterConn).Send(p.Copy())
  85. }
  86. // InjectTunPacket pushes an IP packet onto the tun interface.
  87. func (c *Control) InjectTunPacket(packet []byte) {
  88. c.f.inside.(*overlay.TestTun).Send(packet)
  89. }
  90. func (c *Control) GetVpnAddrs() []netip.Addr {
  91. return c.f.myVpnAddrs
  92. }
  93. func (c *Control) GetUDPAddr() netip.AddrPort {
  94. return c.f.outside.(*udp.TesterConn).Addr
  95. }
  96. func (c *Control) KillPendingTunnel(vpnIp netip.Addr) bool {
  97. hostinfo := c.f.handshakeManager.QueryVpnAddr(vpnIp)
  98. if hostinfo == nil {
  99. return false
  100. }
  101. c.f.handshakeManager.DeleteHostInfo(hostinfo)
  102. return true
  103. }
  104. func (c *Control) GetHostmap() *HostMap {
  105. return c.f.hostMap
  106. }
  107. // GetHostmapIndexCount returns the number of entries in the main hostmap Indexes table, holding
  108. // the hostmap read lock so tests can poll it while connection manager churns tunnels.
  109. func (c *Control) GetHostmapIndexCount() int {
  110. c.f.hostMap.RLock()
  111. defer c.f.hostMap.RUnlock()
  112. return len(c.f.hostMap.Indexes)
  113. }
  114. func (c *Control) GetF() *Interface {
  115. return c.f
  116. }
  117. func (c *Control) GetCertState() *CertState {
  118. return c.f.pki.getCertState()
  119. }
  120. func (c *Control) ReHandshake(vpnIp netip.Addr) {
  121. c.f.handshakeManager.StartHandshake(vpnIp, nil)
  122. }