PeSIT server restart appends data: recovery point computed with the configured interval, and a fresh request for a known transfer resumes it

Summary

When a PeSIT server transfer is interrupted (gateway process killed during a reception) and the peer restarts it, the file received is corrupt and the transfer is reported DONE. Measured on a real peer restarting on its own after the interruption: 30 408 704 bytes received for a 20 971 520-byte file, wrong checksum, status DONE. Setting disableRestart on the server changes nothing (24 117 248 bytes).

What the wire shows

  1. First CREATE, synchronisation points 1, 2, 3…; the gateway dies at 10 248 192 bytes.
  2. The peer restarts with PI 15 = 1. The gateway answers ACK(WRITE) with PI 18 = 9: transferHandler.StartDataTransfer computes the recovery point as Progress / t.conf.CheckpointSize — the configured interval (1 MiB here) — whereas the interval negotiated with the peer (PI 7) is 36 KiB. The gateway then seeks to 9 MiB; for the peer, point 9 means 331 KiB.
  3. The restart fails; the peer tries again without PI 15 (a fresh request, same transfer id). The gateway finds its interrupted transfer, does no repositioning (not a restart) and appends the whole file after the 9 MiB already there: 9 437 184 + 20 971 520 = 30 408 704.

The in-session restart callback (restartReceived, F.RESYN) has the same defect in another form: checkpointSize = 1 // TODO, so the file is repositioned at the point number in bytes, and the point answered to the peer is that byte offset.

Fix

  • the recovery point and the byte offset use the interval negotiated for the transfer (ServerTransfer.CheckpointSize()), not the configured one; without checkpoints the transfer starts over;
  • a request that is not a restart, for a transfer already known, repositions the file at its beginning;
  • restartReceived uses the negotiated interval and answers the point actually reached.

Test

TestRecoveryPointUsesTheNegotiatedInterval (unit). Measured on the real peer after the fix: the interrupted reception restarted by the peer ends with a bit-identical file (see the merge request).

Related: lib/pesitlib/pesit#51 reported the symptom on the library side; the cause is in the application.

Edited Sep 11, 2026 by Driss Demiray
Assignee Loading
Time tracking Loading