mirror of
https://github.com/soypat/lneto.git
synced 2026-09-07 23:39:04 +00:00
feat(tcp): implement window scaling (RFC 7323)
The window-scale option was parsed for length validation but never applied: the effective receive window was capped at the 16-bit field, which caps throughput at 65535/RTT (about 4MB/s on a 15ms path) no matter how large the receive buffer is. Worse, a receive buffer over 64KiB silently WRAPPED the advertised window on the SYN (uint16 truncation): a 128KiB buffer went on the wire as a near-zero window. Design: scaling lives purely at the wire seam in Handler. The ControlBlock always holds real octet counts; conversion happens on frame read (peer windows shifted up by the peer's offer, never on SYN segments) and frame write (wireWnd: our shift down, SYN never scaled, saturation instead of wrap when the value still does not fit). The local shift derives from the receive buffer size in SetBuffers; every active SYN offers it (a zero shift still lets the peer scale, RFC 7323 §2.5) and a SYN-ACK echoes it only when the peer's SYN carried the option. The ControlBlock's three 2**16 window caps move to the scaled maximum (65535<<14). Tests: on-wire negotiation with asymmetric buffers (shift values, unscaled saturated SYN windows, first scaled advertisement, peer scaling back up); a transfer proving more than 64KiB genuinely in flight without a single ACK, received intact; wire-safety corners (no echo without an offer, saturation not wrap, so the pre-existing 128KiB SYN wrap bug stays pinned). Fuzzers clean: 9.1M TCB execs, 4.9M full-stack HTTP execs, 7.2M TCB actions.
This commit is contained in:
+2
-2
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
var (
|
||||
errDropSegment error = lneto.ErrPacketDrop
|
||||
errWindowTooLarge = errors.New("invalid window size > 2**16")
|
||||
errWindowTooLarge = errors.New("invalid window size > max scaled window")
|
||||
|
||||
errBufferTooSmall error = lneto.ErrShortBuffer
|
||||
errNeedClosedTCBToOpen = errors.New("need closed TCB to call open")
|
||||
@@ -25,7 +25,7 @@ var (
|
||||
errBadSegack = errors.New("seqs:bad segack")
|
||||
errFinwaitExpectedACK = errors.New("seqs:finwait1 expected ACK")
|
||||
|
||||
errWindowOverflow = newRejectErr("wnd > 2**16")
|
||||
errWindowOverflow = newRejectErr("wnd > max scaled window")
|
||||
errSeqNotInWindow = newRejectErr("seq not in snd/rcv.wnd")
|
||||
errZeroWindow = newRejectErr("zero window")
|
||||
errLastNotInWindow = newRejectErr("last not in snd/rcv.wnd")
|
||||
|
||||
Reference in New Issue
Block a user