filter out magic packets in the middle device to prevent flapping

This commit is contained in:
Owen
2026-08-03 12:14:43 -04:00
parent 6faa3a0273
commit d8714df81f
2 changed files with 202 additions and 38 deletions
+114
View File
@@ -4,9 +4,22 @@ import (
"net/netip"
"testing"
"github.com/fosrl/newt/bind"
"github.com/fosrl/newt/util"
)
// buildIPv4UDPPacket builds a minimal IPv4/UDP packet (no options) carrying payload.
func buildIPv4UDPPacket(payload []byte) []byte {
const ipHeaderLen = 20
const udpHeaderLen = 8
packet := make([]byte, ipHeaderLen+udpHeaderLen+len(payload))
packet[0] = 0x45 // version 4, IHL 5
packet[9] = 17 // protocol: UDP
copy(packet[ipHeaderLen+udpHeaderLen:], payload)
return packet
}
func TestExtractDestIP(t *testing.T) {
tests := []struct {
name string
@@ -88,6 +101,49 @@ func TestGetProtocol(t *testing.T) {
}
}
func TestIsLeakedMagicPacket(t *testing.T) {
request := make([]byte, bind.MagicTestRequestLen)
copy(request, bind.MagicTestRequest)
response := make([]byte, bind.MagicTestResponseLen)
copy(response, bind.MagicTestResponse)
tests := []struct {
name string
packet []byte
want bool
}{
{
name: "magic test request leaked into tunnel",
packet: buildIPv4UDPPacket(request),
want: true,
},
{
name: "magic test response leaked into tunnel",
packet: buildIPv4UDPPacket(response),
want: true,
},
{
name: "ordinary UDP payload",
packet: buildIPv4UDPPacket([]byte("just some ordinary application data")),
want: false,
},
{
name: "too short to be a packet",
packet: []byte{0x45, 0x00},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isLeakedMagicPacket(tt.packet); got != tt.want {
t.Errorf("isLeakedMagicPacket() = %v, want %v", got, tt.want)
}
})
}
}
func BenchmarkExtractDestIP(b *testing.B) {
packet := []byte{
0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
@@ -100,3 +156,61 @@ func BenchmarkExtractDestIP(b *testing.B) {
extractDestIP(packet)
}
}
func TestFilterDownstreamBufsNoDropIsAllocFree(t *testing.T) {
bufs := make([][]byte, 128)
for i := range bufs {
bufs[i] = buildIPv4UDPPacket(make([]byte, 1372))
}
allocs := testing.AllocsPerRun(1000, func() {
out := filterDownstreamBufs(bufs, nil, 0)
if len(out) != len(bufs) {
t.Fatalf("expected no packets dropped, got %d/%d", len(out), len(bufs))
}
})
if allocs != 0 {
t.Errorf("filterDownstreamBufs() with nothing to drop allocated %v times per call, want 0", allocs)
}
}
func TestFilterDownstreamBufsDropsMagicPacket(t *testing.T) {
request := make([]byte, bind.MagicTestRequestLen)
copy(request, bind.MagicTestRequest)
bufs := [][]byte{
buildIPv4UDPPacket([]byte("ordinary payload one")),
buildIPv4UDPPacket(request),
buildIPv4UDPPacket([]byte("ordinary payload two")),
}
out := filterDownstreamBufs(bufs, nil, 0)
if len(out) != 2 {
t.Fatalf("expected 1 packet dropped, got %d remaining", len(out))
}
}
func BenchmarkFilterDownstreamBufsNoDrop(b *testing.B) {
bufs := make([][]byte, 128)
for i := range bufs {
bufs[i] = buildIPv4UDPPacket(make([]byte, 1372))
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
filterDownstreamBufs(bufs, nil, 0)
}
}
func BenchmarkIsLeakedMagicPacket(b *testing.B) {
// A typical ~1400 byte ordinary application payload (the common case on the
// hot path - almost every real packet should look like this).
ordinary := buildIPv4UDPPacket(make([]byte, 1372))
b.ResetTimer()
for i := 0; i < b.N; i++ {
isLeakedMagicPacket(ordinary)
}
}