tun_tester.go 2.9 KB

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