udp_tester.go 3.4 KB

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