3
0

tun_disabled.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. )
  11. type disabledTun struct {
  12. read chan []byte
  13. vpnNetworks []netip.Prefix
  14. // Track these metrics since we don't have the tun device to do it for us
  15. tx metrics.Counter
  16. rx metrics.Counter
  17. l *logrus.Logger
  18. }
  19. func newDisabledTun(vpnNetworks []netip.Prefix, queueLen int, metricsEnabled bool, l *logrus.Logger) *disabledTun {
  20. tun := &disabledTun{
  21. vpnNetworks: vpnNetworks,
  22. read: make(chan []byte, queueLen),
  23. l: l,
  24. }
  25. if metricsEnabled {
  26. tun.tx = metrics.GetOrRegisterCounter("messages.tx.message", nil)
  27. tun.rx = metrics.GetOrRegisterCounter("messages.rx.message", nil)
  28. } else {
  29. tun.tx = &metrics.NilCounter{}
  30. tun.rx = &metrics.NilCounter{}
  31. }
  32. return tun
  33. }
  34. func (*disabledTun) Activate() error {
  35. return nil
  36. }
  37. func (*disabledTun) RouteFor(addr netip.Addr) netip.Addr {
  38. return netip.Addr{}
  39. }
  40. func (t *disabledTun) Networks() []netip.Prefix {
  41. return t.vpnNetworks
  42. }
  43. func (*disabledTun) Name() string {
  44. return "disabled"
  45. }
  46. func (t *disabledTun) Read(b []byte) (int, error) {
  47. r, ok := <-t.read
  48. if !ok {
  49. return 0, io.EOF
  50. }
  51. if len(r) > len(b) {
  52. return 0, fmt.Errorf("packet larger than mtu: %d > %d bytes", len(r), len(b))
  53. }
  54. t.tx.Inc(1)
  55. if t.l.Level >= logrus.DebugLevel {
  56. t.l.WithField("raw", prettyPacket(r)).Debugf("Write payload")
  57. }
  58. return copy(b, r), nil
  59. }
  60. func (t *disabledTun) handleICMPEchoRequest(b []byte) bool {
  61. out := make([]byte, len(b))
  62. out = iputil.CreateICMPEchoResponse(b, out)
  63. if out == nil {
  64. return false
  65. }
  66. // attempt to write it, but don't block
  67. select {
  68. case t.read <- out:
  69. default:
  70. t.l.Debugf("tun_disabled: dropped ICMP Echo Reply response")
  71. }
  72. return true
  73. }
  74. func (t *disabledTun) Write(b []byte) (int, error) {
  75. t.rx.Inc(1)
  76. // Check for ICMP Echo Request before spending time doing the full parsing
  77. if t.handleICMPEchoRequest(b) {
  78. if t.l.Level >= logrus.DebugLevel {
  79. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun responded to ICMP Echo Request")
  80. }
  81. } else if t.l.Level >= logrus.DebugLevel {
  82. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun received unexpected payload")
  83. }
  84. return len(b), nil
  85. }
  86. func (t *disabledTun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
  87. return t, nil
  88. }
  89. func (t *disabledTun) Close() error {
  90. if t.read != nil {
  91. close(t.read)
  92. t.read = nil
  93. }
  94. return nil
  95. }
  96. type prettyPacket []byte
  97. func (p prettyPacket) String() string {
  98. var s strings.Builder
  99. for i, b := range p {
  100. if i > 0 && i%8 == 0 {
  101. s.WriteString(" ")
  102. }
  103. s.WriteString(fmt.Sprintf("%02x ", b))
  104. }
  105. return s.String()
  106. }