udp_tester.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package udp
  4. import (
  5. "fmt"
  6. "net"
  7. "github.com/sirupsen/logrus"
  8. "github.com/slackhq/nebula/config"
  9. "github.com/slackhq/nebula/firewall"
  10. "github.com/slackhq/nebula/header"
  11. )
  12. type Packet struct {
  13. ToIp net.IP
  14. ToPort uint16
  15. FromIp net.IP
  16. FromPort uint16
  17. Data []byte
  18. }
  19. func (u *Packet) Copy() *Packet {
  20. n := &Packet{
  21. ToIp: make(net.IP, len(u.ToIp)),
  22. ToPort: u.ToPort,
  23. FromIp: make(net.IP, len(u.FromIp)),
  24. FromPort: u.FromPort,
  25. Data: make([]byte, len(u.Data)),
  26. }
  27. copy(n.ToIp, u.ToIp)
  28. copy(n.FromIp, u.FromIp)
  29. copy(n.Data, u.Data)
  30. return n
  31. }
  32. type TesterConn struct {
  33. Addr *Addr
  34. RxPackets chan *Packet // Packets to receive into nebula
  35. TxPackets chan *Packet // Packets transmitted outside by nebula
  36. l *logrus.Logger
  37. }
  38. func NewListener(l *logrus.Logger, ip net.IP, port int, _ bool, _ int) (Conn, error) {
  39. return &TesterConn{
  40. Addr: &Addr{ip, uint16(port)},
  41. RxPackets: make(chan *Packet, 10),
  42. TxPackets: make(chan *Packet, 10),
  43. l: l,
  44. }, nil
  45. }
  46. // Send will place a UdpPacket onto the receive queue for nebula to consume
  47. // this is an encrypted packet or a handshake message in most cases
  48. // packets were transmitted from another nebula node, you can send them with Tun.Send
  49. func (u *TesterConn) Send(packet *Packet) {
  50. h := &header.H{}
  51. if err := h.Parse(packet.Data); err != nil {
  52. panic(err)
  53. }
  54. if u.l.Level >= logrus.DebugLevel {
  55. u.l.WithField("header", h).
  56. WithField("udpAddr", fmt.Sprintf("%v:%v", packet.FromIp, packet.FromPort)).
  57. WithField("dataLen", len(packet.Data)).
  58. Debug("UDP receiving injected packet")
  59. }
  60. u.RxPackets <- packet
  61. }
  62. // Get will pull a UdpPacket from the transmit queue
  63. // nebula meant to send this message on the network, it will be encrypted
  64. // packets were ingested from the tun side (in most cases), you can send them with Tun.Send
  65. func (u *TesterConn) Get(block bool) *Packet {
  66. if block {
  67. return <-u.TxPackets
  68. }
  69. select {
  70. case p := <-u.TxPackets:
  71. return p
  72. default:
  73. return nil
  74. }
  75. }
  76. //********************************************************************************************************************//
  77. // Below this is boilerplate implementation to make nebula actually work
  78. //********************************************************************************************************************//
  79. func (u *TesterConn) WriteTo(b []byte, addr *Addr) error {
  80. p := &Packet{
  81. Data: make([]byte, len(b), len(b)),
  82. FromIp: make([]byte, 16),
  83. FromPort: u.Addr.Port,
  84. ToIp: make([]byte, 16),
  85. ToPort: addr.Port,
  86. }
  87. copy(p.Data, b)
  88. copy(p.ToIp, addr.IP.To16())
  89. copy(p.FromIp, u.Addr.IP.To16())
  90. u.TxPackets <- p
  91. return nil
  92. }
  93. func (u *TesterConn) ListenOut(r EncReader, lhf LightHouseHandlerFunc, cache *firewall.ConntrackCacheTicker, q int) {
  94. plaintext := make([]byte, MTU)
  95. h := &header.H{}
  96. fwPacket := &firewall.Packet{}
  97. ua := &Addr{IP: make([]byte, 16)}
  98. nb := make([]byte, 12, 12)
  99. for {
  100. p, ok := <-u.RxPackets
  101. if !ok {
  102. return
  103. }
  104. ua.Port = p.FromPort
  105. copy(ua.IP, p.FromIp.To16())
  106. r(ua, plaintext[:0], p.Data, h, fwPacket, lhf, nb, q, cache.Get(u.l))
  107. }
  108. }
  109. func (u *TesterConn) ReloadConfig(*config.C) {}
  110. func NewUDPStatsEmitter(_ []Conn) func() {
  111. // No UDP stats for non-linux
  112. return func() {}
  113. }
  114. func (u *TesterConn) LocalAddr() (*Addr, error) {
  115. return u.Addr, nil
  116. }
  117. func (u *TesterConn) Rebind() error {
  118. return nil
  119. }