Maximum segment size fixes (#25)

* Fixed MSS sent in SYN and SYN-ACK

* Fixed tests
This commit is contained in:
ddirect
2026-01-25 07:37:17 +02:00
committed by GitHub
parent 7edaea1093
commit 91fea9ae58
5 changed files with 11 additions and 6 deletions
+2 -1
View File
@@ -108,8 +108,9 @@ func (ls *StackEthernet) Encapsulate(carrierData []byte, offsetToIP, offsetToFra
// For IP: offsetToIP=14, offsetToFrame=14 // For IP: offsetToIP=14, offsetToFrame=14
// For ARP: offsetToIP=-1, offsetToFrame=14 (but ARP ignores offsetToIP) // For ARP: offsetToIP=-1, offsetToFrame=14 (but ARP ignores offsetToIP)
// Clip carrierData to MTU to prevent writes beyond MTU limit. // Clip carrierData to MTU to prevent writes beyond MTU limit.
offsetToFrame += 14
mtuLimit := offsetToFrame + int(mtu) mtuLimit := offsetToFrame + int(mtu)
h, n, err = ls.handlers.encapsulateAny(carrierData[:mtuLimit], offsetToFrame+14, offsetToFrame+14) h, n, err = ls.handlers.encapsulateAny(carrierData[:mtuLimit], offsetToFrame, offsetToFrame)
if n == 0 { if n == 0 {
return n, err return n, err
} }
+3 -2
View File
@@ -244,11 +244,12 @@ func (h *Handler) Send(b []byte) (int, error) {
} }
} }
offset := uint8(5) offset := uint8(5)
mss := uint16(len(b) - sizeHeaderTCP)
var segment Segment var segment Segment
if h.AwaitingSynSend() { if h.AwaitingSynSend() {
// Handling init syn segment. // Handling init syn segment.
segment = ClientSynSegment(h.bufTx.iss, Size(h.bufRx.Size())) segment = ClientSynSegment(h.bufTx.iss, Size(h.bufRx.Size()))
h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, uint16(len(b))) h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, mss)
offset++ offset++
} else { } else {
var ok bool var ok bool
@@ -266,7 +267,7 @@ func (h *Handler) Send(b []byte) (int, error) {
panic("expected n == available") panic("expected n == available")
} }
} else if segment.Flags == synack { } else if segment.Flags == synack {
h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, uint16(len(b))) h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, mss)
offset++ offset++
} }
} }
+2 -1
View File
@@ -140,7 +140,8 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
func kernelLoop(ctx context.Context, server *StackAsync, clients []StackAsync) { func kernelLoop(ctx context.Context, server *StackAsync, clients []StackAsync) {
const MTU = 1500 const MTU = 1500
buf := make([]byte, MTU) const carrierDataSize = MTU + 14
buf := make([]byte, carrierDataSize)
rng := rand.New(rand.NewSource(1)) // Seed 1 for deterministic but randomized order rng := rand.New(rand.NewSource(1)) // Seed 1 for deterministic but randomized order
order := make([]int, len(clients)) order := make([]int, len(clients))
for i := range order { for i := range order {
+2 -1
View File
@@ -47,7 +47,8 @@ func TestDNS_QueryReceivesAnswer(t *testing.T) {
} }
// Client sends DNS query. // Client sends DNS query.
var buf [MTU]byte const carrierDataSize = MTU + 14
var buf [carrierDataSize]byte
n, err := client.Encapsulate(buf[:], -1, 0) n, err := client.Encapsulate(buf[:], -1, 0)
if err != nil { if err != nil {
t.Fatal("client Encapsulate failed:", err) t.Fatal("client Encapsulate failed:", err)
+2 -1
View File
@@ -217,9 +217,10 @@ func newTCPStacks(t *testing.T, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
} }
func testerFrom(t *testing.T, mtu int) *tester { func testerFrom(t *testing.T, mtu int) *tester {
carrierDataSize := mtu + 14
return &tester{ return &tester{
t: t, t: t,
buf: make([]byte, mtu), buf: make([]byte, carrierDataSize),
} }
} }