tun_tester.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package overlay
  4. import (
  5. "fmt"
  6. "io"
  7. "net"
  8. "os"
  9. "github.com/sirupsen/logrus"
  10. "github.com/slackhq/nebula/cidr"
  11. "github.com/slackhq/nebula/iputil"
  12. )
  13. type TestTun struct {
  14. Device string
  15. cidr *net.IPNet
  16. Routes []Route
  17. routeTree *cidr.Tree4
  18. l *logrus.Logger
  19. rxPackets chan []byte // Packets to receive into nebula
  20. TxPackets chan []byte // Packets transmitted outside by nebula
  21. }
  22. func newTun(l *logrus.Logger, deviceName string, cidr *net.IPNet, _ int, routes []Route, _ int, _ bool, _ bool) (*TestTun, error) {
  23. routeTree, err := makeRouteTree(l, routes, false)
  24. if err != nil {
  25. return nil, err
  26. }
  27. return &TestTun{
  28. Device: deviceName,
  29. cidr: cidr,
  30. Routes: routes,
  31. routeTree: routeTree,
  32. l: l,
  33. rxPackets: make(chan []byte, 10),
  34. TxPackets: make(chan []byte, 10),
  35. }, nil
  36. }
  37. func newTunFromFd(_ *logrus.Logger, _ int, _ *net.IPNet, _ int, _ []Route, _ int, _ bool) (*TestTun, error) {
  38. return nil, fmt.Errorf("newTunFromFd not supported")
  39. }
  40. // Send will place a byte array onto the receive queue for nebula to consume
  41. // These are unencrypted ip layer frames destined for another nebula node.
  42. // packets should exit the udp side, capture them with udpConn.Get
  43. func (t *TestTun) Send(packet []byte) {
  44. if t.l.Level >= logrus.DebugLevel {
  45. t.l.WithField("dataLen", len(packet)).Debug("Tun receiving injected packet")
  46. }
  47. t.rxPackets <- packet
  48. }
  49. // Get will pull an unencrypted ip layer frame from the transmit queue
  50. // nebula meant to send this message to some application on the local system
  51. // packets were ingested from the udp side, you can send them with udpConn.Send
  52. func (t *TestTun) Get(block bool) []byte {
  53. if block {
  54. return <-t.TxPackets
  55. }
  56. select {
  57. case p := <-t.TxPackets:
  58. return p
  59. default:
  60. return nil
  61. }
  62. }
  63. //********************************************************************************************************************//
  64. // Below this is boilerplate implementation to make nebula actually work
  65. //********************************************************************************************************************//
  66. func (t *TestTun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
  67. r := t.routeTree.MostSpecificContains(ip)
  68. if r != nil {
  69. return r.(iputil.VpnIp)
  70. }
  71. return 0
  72. }
  73. func (t *TestTun) Activate() error {
  74. return nil
  75. }
  76. func (t *TestTun) Cidr() *net.IPNet {
  77. return t.cidr
  78. }
  79. func (t *TestTun) Name() string {
  80. return t.Device
  81. }
  82. func (t *TestTun) Write(b []byte) (n int, err error) {
  83. packet := make([]byte, len(b), len(b))
  84. copy(packet, b)
  85. t.TxPackets <- packet
  86. return len(b), nil
  87. }
  88. func (t *TestTun) Close() error {
  89. close(t.rxPackets)
  90. return nil
  91. }
  92. func (t *TestTun) Read(b []byte) (int, error) {
  93. p, ok := <-t.rxPackets
  94. if !ok {
  95. return 0, os.ErrClosed
  96. }
  97. copy(b, p)
  98. return len(p), nil
  99. }
  100. func (t *TestTun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
  101. return nil, fmt.Errorf("TODO: multiqueue not implemented")
  102. }