wgengine/netstack: clear TCP ECN bits before giving to gvisor

Updates #2642

Change-Id: Ic219442a2656dd9dc99ae1dd91e907fd3d924987
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2022-01-19 14:33:50 -08:00
committed by Brad Fitzpatrick
parent de4696da10
commit c64af5e676
3 changed files with 134 additions and 10 deletions

View File

@@ -6,7 +6,9 @@ package packet
import (
"bytes"
"encoding/hex"
"reflect"
"regexp"
"testing"
"inet.af/netaddr"
@@ -561,3 +563,57 @@ func BenchmarkString(b *testing.B) {
})
}
}
func TestRemoveECNBits(t *testing.T) {
// withECNHex is a TCP SYN packet with ECN bits set in the TCP
// header as captured by Wireshark on macOS against the
// Tailscale interface. In this packet (because it's a SYN
// control packet), the ECN bits are not set in the IP header.
const withECNHex = `45 00 00 40 00 00 40 00
40 06 0c 66 64 7b 65 28 64 7f 00 30 f1 ab 00 16
5a 7a 63 e8 00 00 00 00 b0 c2 ff ff 97 76 00 00
02 04 04 d8 01 03 03 06 01 01 08 0a 03 e1 bd 49
00 00 00 00 04 02 00 00`
// Generated by hand-editing a pcap file in hexl-mode to set
// the TCP flags to just SYN (0x02), then loading that pcap
// file in wireshark to get the expected checksum value, then
// putting that checksum value (0x9836) in the file.
const wantStrippedHex = `45 00 00 40 00 00 40 00
40 06 0c 66 64 7b 65 28 64 7f 00 30 f1 ab 00 16
5a 7a 63 e8 00 00 00 00 b0 02 ff ff 98 36 00 00
02 04 04 d8 01 03 03 06 01 01 08 0a 03 e1 bd 49
00 00 00 00 04 02 00 00`
var p Parsed
pktBuf := bytesOfHex(withECNHex)
p.Decode(pktBuf)
if want := TCPCWR | TCPECNEcho | TCPSyn; p.TCPFlags != want {
t.Fatalf("pre flags = %v; want %v", p.TCPFlags, want)
}
if !p.RemoveECNBits() {
t.Fatal("didn't remove bits")
}
if want := TCPSyn; p.TCPFlags != want {
t.Fatalf("post flags = %v; want %v", p.TCPFlags, want)
}
wantPkt := bytesOfHex(wantStrippedHex)
if !bytes.Equal(pktBuf, wantPkt) {
t.Fatalf("wrong result.\n got: % 2x\nwant: % 2x\n", pktBuf, wantPkt)
}
if p.RemoveECNBits() {
t.Fatal("unexpected true return value on second call")
}
}
var nonHex = regexp.MustCompile(`[^0-9a-fA-F]+`)
func bytesOfHex(s string) []byte {
b, err := hex.DecodeString(nonHex.ReplaceAllString(s, ""))
if err != nil {
panic(err)
}
return b
}