tun_disabled.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package overlay
  2. import (
  3. "fmt"
  4. "io"
  5. "net/netip"
  6. "strings"
  7. "github.com/rcrowley/go-metrics"
  8. "github.com/sirupsen/logrus"
  9. "github.com/slackhq/nebula/iputil"
  10. "github.com/slackhq/nebula/overlay/tio"
  11. "github.com/slackhq/nebula/routing"
  12. )
  13. type disabledTun struct {
  14. read chan []byte
  15. vpnNetworks []netip.Prefix
  16. // Track these metrics since we don't have the tun device to do it for us
  17. tx metrics.Counter
  18. rx metrics.Counter
  19. l *logrus.Logger
  20. numReaders int
  21. batchRet [1][]byte
  22. }
  23. func (t *disabledTun) Read() ([][]byte, error) {
  24. r, ok := <-t.read
  25. if !ok {
  26. return nil, io.EOF
  27. }
  28. t.tx.Inc(1)
  29. if t.l.Level >= logrus.DebugLevel {
  30. t.l.WithField("raw", prettyPacket(r)).Debugf("Write payload")
  31. }
  32. t.batchRet[0] = r
  33. return t.batchRet[:], nil
  34. }
  35. func newDisabledTun(vpnNetworks []netip.Prefix, queueLen int, metricsEnabled bool, l *logrus.Logger) *disabledTun {
  36. tun := &disabledTun{
  37. vpnNetworks: vpnNetworks,
  38. read: make(chan []byte, queueLen),
  39. l: l,
  40. numReaders: 1,
  41. }
  42. if metricsEnabled {
  43. tun.tx = metrics.GetOrRegisterCounter("messages.tx.message", nil)
  44. tun.rx = metrics.GetOrRegisterCounter("messages.rx.message", nil)
  45. } else {
  46. tun.tx = &metrics.NilCounter{}
  47. tun.rx = &metrics.NilCounter{}
  48. }
  49. return tun
  50. }
  51. func (*disabledTun) Activate() error {
  52. return nil
  53. }
  54. func (*disabledTun) RoutesFor(addr netip.Addr) routing.Gateways {
  55. return routing.Gateways{}
  56. }
  57. func (t *disabledTun) Networks() []netip.Prefix {
  58. return t.vpnNetworks
  59. }
  60. func (*disabledTun) Name() string {
  61. return "disabled"
  62. }
  63. func (t *disabledTun) handleICMPEchoRequest(b []byte) bool {
  64. out := make([]byte, len(b))
  65. out = iputil.CreateICMPEchoResponse(b, out)
  66. if out == nil {
  67. return false
  68. }
  69. // attempt to write it, but don't block
  70. select {
  71. case t.read <- out:
  72. default:
  73. t.l.Debugf("tun_disabled: dropped ICMP Echo Reply response")
  74. }
  75. return true
  76. }
  77. func (t *disabledTun) Write(b []byte) (int, error) {
  78. t.rx.Inc(1)
  79. // Check for ICMP Echo Request before spending time doing the full parsing
  80. if t.handleICMPEchoRequest(b) {
  81. if t.l.Level >= logrus.DebugLevel {
  82. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun responded to ICMP Echo Request")
  83. }
  84. } else if t.l.Level >= logrus.DebugLevel {
  85. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun received unexpected payload")
  86. }
  87. return len(b), nil
  88. }
  89. func (t *disabledTun) WriteReject(b []byte) (int, error) {
  90. return t.Write(b)
  91. }
  92. func (t *disabledTun) SupportsMultiqueue() bool {
  93. return true
  94. }
  95. func (t *disabledTun) NewMultiQueueReader() error {
  96. t.numReaders++
  97. return nil
  98. }
  99. func (t *disabledTun) Readers() []tio.Queue {
  100. out := make([]tio.Queue, t.numReaders)
  101. for i := range t.numReaders {
  102. out[i] = t
  103. }
  104. return out
  105. }
  106. func (t *disabledTun) Close() error {
  107. if t.read != nil {
  108. close(t.read)
  109. t.read = nil
  110. }
  111. return nil
  112. }
  113. type prettyPacket []byte
  114. func (p prettyPacket) String() string {
  115. var s strings.Builder
  116. for i, b := range p {
  117. if i > 0 && i%8 == 0 {
  118. s.WriteString(" ")
  119. }
  120. s.WriteString(fmt.Sprintf("%02x ", b))
  121. }
  122. return s.String()
  123. }