https://gitlab.synchro.net/main/sbbs/-/commit/a8843ffb8b199017665b83fd
Modified Files:
src/sbbs3/zmodem.c
Log Message:
zmodem: don't retransmit the ZFILE at a receiver's opening ZRINIT
A ZMODEM receiver announces itself with a ZRINIT unprompted, and the
sender then sends a ZRQINIT of its own before the first file, drawing a
second ZRINIT. That second one arrives after the ZFILE has already gone
out, and the loop waiting for the ZFILE's answer accepted only ZACK, so a ZRINIT counted as a failed attempt and the whole ZFILE frame was sent
again. The receiver answered both copies, leaving a second ZRPOS on the back-channel that the sender then read mid-stream and treated as a
retransmit request, restarting the file from the beginning and taking two rounds of error recovery to settle. Sending four files to lrzsz cost a
round trip, a duplicate frame and an error in the receiver's log every
session; under load the stale ZRPOS cost seconds.
Absorb one such ZRINIT per ZFILE attempt and keep waiting for the real
answer instead, which is what lrzsz's sender does in the same spot. A
second ZRINIT still retransmits, so a receiver that genuinely missed the
ZFILE recovers as before.
The stale ZRPOS was previously consumed by the 1-second receive-buffer
purge removed in 36c17d6b1e (2026-08-21), which is why the cost was only
the wasted round trip until now. Verified with the sender and receiver
pinned to one CPU, which reproduced the restart in 2 runs of 3 before the change and 0 of 12 after; a 256 MiB send to lrzsz stays at 204 MB/s, and
error recovery under injected bit-flips still completes byte-identical.
Visible in a protocol dump sent by Uwe Ohse, who reported the purge stall.
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net