2021-11-12 06:37:29 +08:00
|
|
|
package overlay
|
2020-08-10 21:15:55 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2024-07-31 23:18:56 +08:00
|
|
|
"net/netip"
|
2020-08-10 21:15:55 +08:00
|
|
|
"strings"
|
|
|
|
|
2021-03-02 00:09:41 +08:00
|
|
|
"github.com/rcrowley/go-metrics"
|
|
|
|
"github.com/sirupsen/logrus"
|
2021-11-13 01:19:28 +08:00
|
|
|
"github.com/slackhq/nebula/iputil"
|
2020-08-10 21:15:55 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type disabledTun struct {
|
2021-03-26 22:46:30 +08:00
|
|
|
read chan []byte
|
2024-07-31 23:18:56 +08:00
|
|
|
cidr netip.Prefix
|
2021-03-02 00:09:41 +08:00
|
|
|
|
|
|
|
// Track these metrics since we don't have the tun device to do it for us
|
|
|
|
tx metrics.Counter
|
|
|
|
rx metrics.Counter
|
2021-03-26 22:46:30 +08:00
|
|
|
l *logrus.Logger
|
2020-08-10 21:15:55 +08:00
|
|
|
}
|
|
|
|
|
2024-07-31 23:18:56 +08:00
|
|
|
func newDisabledTun(cidr netip.Prefix, queueLen int, metricsEnabled bool, l *logrus.Logger) *disabledTun {
|
2021-03-02 00:09:41 +08:00
|
|
|
tun := &disabledTun{
|
2021-03-26 22:46:30 +08:00
|
|
|
cidr: cidr,
|
|
|
|
read: make(chan []byte, queueLen),
|
|
|
|
l: l,
|
2020-08-10 21:15:55 +08:00
|
|
|
}
|
2021-03-02 00:09:41 +08:00
|
|
|
|
|
|
|
if metricsEnabled {
|
|
|
|
tun.tx = metrics.GetOrRegisterCounter("messages.tx.message", nil)
|
|
|
|
tun.rx = metrics.GetOrRegisterCounter("messages.rx.message", nil)
|
|
|
|
} else {
|
|
|
|
tun.tx = &metrics.NilCounter{}
|
|
|
|
tun.rx = &metrics.NilCounter{}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tun
|
2020-08-10 21:15:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (*disabledTun) Activate() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-07-31 23:18:56 +08:00
|
|
|
func (*disabledTun) RouteFor(addr netip.Addr) netip.Addr {
|
|
|
|
return netip.Addr{}
|
2021-11-13 01:19:28 +08:00
|
|
|
}
|
|
|
|
|
2024-07-31 23:18:56 +08:00
|
|
|
func (t *disabledTun) Cidr() netip.Prefix {
|
2020-08-10 21:15:55 +08:00
|
|
|
return t.cidr
|
|
|
|
}
|
|
|
|
|
2021-11-13 02:47:09 +08:00
|
|
|
func (*disabledTun) Name() string {
|
2020-08-10 21:15:55 +08:00
|
|
|
return "disabled"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *disabledTun) Read(b []byte) (int, error) {
|
2021-03-02 00:09:41 +08:00
|
|
|
r, ok := <-t.read
|
|
|
|
if !ok {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(r) > len(b) {
|
|
|
|
return 0, fmt.Errorf("packet larger than mtu: %d > %d bytes", len(r), len(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
t.tx.Inc(1)
|
2021-03-26 22:46:30 +08:00
|
|
|
if t.l.Level >= logrus.DebugLevel {
|
|
|
|
t.l.WithField("raw", prettyPacket(r)).Debugf("Write payload")
|
2021-03-02 00:09:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return copy(b, r), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *disabledTun) handleICMPEchoRequest(b []byte) bool {
|
2023-03-14 03:08:40 +08:00
|
|
|
out := make([]byte, len(b))
|
|
|
|
out = iputil.CreateICMPEchoResponse(b, out)
|
|
|
|
if out == nil {
|
2021-03-02 00:09:41 +08:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// attempt to write it, but don't block
|
|
|
|
select {
|
2023-03-14 03:08:40 +08:00
|
|
|
case t.read <- out:
|
2021-03-02 00:09:41 +08:00
|
|
|
default:
|
2021-03-26 22:46:30 +08:00
|
|
|
t.l.Debugf("tun_disabled: dropped ICMP Echo Reply response")
|
2021-03-02 00:09:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
2020-08-10 21:15:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *disabledTun) Write(b []byte) (int, error) {
|
2021-03-02 00:09:41 +08:00
|
|
|
t.rx.Inc(1)
|
|
|
|
|
|
|
|
// Check for ICMP Echo Request before spending time doing the full parsing
|
|
|
|
if t.handleICMPEchoRequest(b) {
|
2021-03-26 22:46:30 +08:00
|
|
|
if t.l.Level >= logrus.DebugLevel {
|
|
|
|
t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun responded to ICMP Echo Request")
|
2021-03-02 00:09:41 +08:00
|
|
|
}
|
2021-03-26 22:46:30 +08:00
|
|
|
} else if t.l.Level >= logrus.DebugLevel {
|
|
|
|
t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun received unexpected payload")
|
2021-03-02 00:09:41 +08:00
|
|
|
}
|
2020-08-10 21:15:55 +08:00
|
|
|
return len(b), nil
|
|
|
|
}
|
|
|
|
|
2021-02-26 04:01:14 +08:00
|
|
|
func (t *disabledTun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
2020-08-10 21:15:55 +08:00
|
|
|
func (t *disabledTun) Close() error {
|
2021-03-02 00:09:41 +08:00
|
|
|
if t.read != nil {
|
|
|
|
close(t.read)
|
|
|
|
t.read = nil
|
2020-08-10 21:15:55 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type prettyPacket []byte
|
|
|
|
|
|
|
|
func (p prettyPacket) String() string {
|
|
|
|
var s strings.Builder
|
|
|
|
|
|
|
|
for i, b := range p {
|
|
|
|
if i > 0 && i%8 == 0 {
|
|
|
|
s.WriteString(" ")
|
|
|
|
}
|
|
|
|
s.WriteString(fmt.Sprintf("%02x ", b))
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.String()
|
|
|
|
}
|