From d0090e556988604787b16b332a544e228d7710e0 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Tue, 14 Apr 2026 16:50:19 -0700 Subject: [PATCH] =?UTF-8?q?Cap=20SMB=20TCP=20burst=20at=204=C3=97MSS=20to?= =?UTF-8?q?=20stay=20under=20NE2000=20RX=20ring=20(#371)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/smb/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/renderer/smb/index.ts b/src/renderer/smb/index.ts index 67c2e79..d0b5d88 100644 --- a/src/renderer/smb/index.ts +++ b/src/renderer/smb/index.ts @@ -142,8 +142,10 @@ export function setupSmbShare(emulator: V86, hostPath: string | null, toolsRoot? } // v86's TCP is stop-and-wait (one MSS, wait for ACK). The link is lossless - // and has no retransmit anyway, so keep a window in flight by sliding the - // ring-buffer view under the original pump(). 8×MSS cap ≈ NE2000 RX ring. + // and has no retransmit anyway, so keep a small window in flight by sliding + // the ring-buffer view under the original pump(). The burst lands in the + // NE2000 RX ring before the guest CPU runs, so the cap is the ring (52–58 + // pages for Win95's driver) — 4×MSS + our ACK ≈ 36 pages, 8 overflowed it. const c = conn as any, sb = c.send_buffer; const mss: number = c.send_chunk_buf?.length ?? 1460; const pump1 = Object.getPrototypeOf(c)?.pump; @@ -152,7 +154,7 @@ export function setupSmbShare(emulator: V86, hostPath: string | null, toolsRoot? c.pump = function () { if (this.pending || !sb.length) return pump1.call(this); const cap = sb.buffer.length, t0 = sb.tail, l0 = sb.length, s0 = this.seq; - const win = Math.max(mss, Math.min(this.winsize || 8192, 8 * mss)); + const win = 4 * mss; let off = hi === undefined ? 0 : Math.max(0, Math.min(hi - s0, l0)); for (; off < l0 && off < win; off += Math.min(mss, l0 - off)) { sb.tail = (t0 + off) % cap; sb.length = l0 - off;