net, wgengine/capture: encode NAT addresses in pcap stream

Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
Tom DNetto
2023-03-30 12:39:39 -07:00
committed by Tom
parent 92459a9248
commit 6a627e5a33
7 changed files with 94 additions and 28 deletions

View File

@ -15,6 +15,7 @@ import (
_ "embed"
"tailscale.com/net/packet"
"tailscale.com/util/set"
)
@ -26,7 +27,7 @@ var DissectorLua string
// Such callbacks must not take ownership of the
// provided data slice: it may only copy out of it
// within the lifetime of the function.
type Callback func(Path, time.Time, []byte)
type Callback func(Path, time.Time, []byte, packet.CaptureMeta)
var bufferPool = sync.Pool{
New: func() any {
@ -159,24 +160,50 @@ func (s *Sink) WaitCh() <-chan struct{} {
return s.ctx.Done()
}
func customDataLen(meta packet.CaptureMeta) int {
length := 4
if meta.DidSNAT {
length += meta.OriginalSrc.Addr().BitLen() / 8
}
if meta.DidDNAT {
length += meta.OriginalDst.Addr().BitLen() / 8
}
return length
}
// LogPacket is called to insert a packet into the capture.
//
// This function does not take ownership of the provided data slice.
func (s *Sink) LogPacket(path Path, when time.Time, data []byte) {
func (s *Sink) LogPacket(path Path, when time.Time, data []byte, meta packet.CaptureMeta) {
select {
case <-s.ctx.Done():
return
default:
}
extraLen := customDataLen(meta)
b := bufferPool.Get().(*bytes.Buffer)
b.Reset()
b.Grow(16 + 2 + len(data)) // 16b pcap header + 2b custom data + len
b.Grow(16 + extraLen + len(data)) // 16b pcap header + len(metadata) + len(payload)
defer bufferPool.Put(b)
writePktHeader(b, when, len(data)+2)
writePktHeader(b, when, len(data)+extraLen)
// Custom tailscale debugging data
binary.Write(b, binary.LittleEndian, uint16(path))
if meta.DidSNAT {
binary.Write(b, binary.LittleEndian, uint8(meta.OriginalSrc.Addr().BitLen()/8))
b.Write(meta.OriginalSrc.Addr().AsSlice())
} else {
binary.Write(b, binary.LittleEndian, uint8(0)) // SNAT addr len == 0
}
if meta.DidDNAT {
binary.Write(b, binary.LittleEndian, uint8(meta.OriginalDst.Addr().BitLen()/8))
b.Write(meta.OriginalDst.Addr().AsSlice())
} else {
binary.Write(b, binary.LittleEndian, uint8(0)) // DNAT addr len == 0
}
b.Write(data)
s.mu.Lock()