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