Stream a file or a whole directory tree to a peer, with integrity, backpressure, pause/resume/cancel, idle-timeout and crash-safe writes. More...
#include "librats/util/rats_export.h"#include "librats/node/peer_network.h"#include "librats/peer/peer.h"#include "librats/core/bytes.h"#include "librats/peer/peer_id.h"#include "librats/util/fs.h"#include "librats/crypto/sha256.h"#include <atomic>#include <chrono>#include <condition_variable>#include <cstdint>#include <functional>#include <memory>#include <mutex>#include <queue>#include <string>#include <thread>#include <unordered_map>#include <vector>Go to the source code of this file.
Classes | |
| class | librats::FileTransfer |
| struct | librats::FileTransfer::Config |
| struct | librats::FileTransfer::FileEntry |
| One file inside a transfer (a single-file transfer has exactly one). More... | |
| struct | librats::FileTransfer::Offer |
| Delivered to the offer callback so the app can accept() or reject(). More... | |
| struct | librats::FileTransfer::Progress |
| Snapshot passed to the progress callback (both directions). More... | |
| struct | librats::FileTransfer::Stats |
| Aggregate counters. More... | |
Namespaces | |
| namespace | librats |
Stream a file or a whole directory tree to a peer, with integrity, backpressure, pause/resume/cancel, idle-timeout and crash-safe writes.
Push model: the sender offers a file/directory; the receiver accepts (choosing a destination) or rejects; the sender streams the data; the receiver verifies a whole-file SHA-256 before moving each temp file into place. All control + data ride on MessageType::FileChunk as compact binary opcodes (no JSON), implemented on the Node/Subsystem plugin model.
Continuing an interrupted transfer: accept_resume() takes the partial file the app kept from an earlier attempt and asks the sender to start at its length, which rides along on the RESPONSE. A sender that does not understand the request streams from zero and the receiver quietly starts over, so the feature degrades to the old behaviour against an older peer instead of failing.
Integrity: every file ends with its SHA-256, verified end-to-end before the temp file is moved into place; a mismatch (or a disk-write failure) fails the whole transfer. In transit the Noise session already AEAD-authenticates every byte, so no redundant per-chunk checksum rides the wire.
Backpressure: the sender keeps at most window_bytes un-acked; the receiver acks cumulative progress at least twice per window, so the sender never stalls.
Safety: temp file names are derived from the sender's PeerId + the transfer id (never the peer's self-declared name) — the id alone is only unique per sender, so two peers' first transfers would otherwise share a temp file. Every peer-supplied relative path in a directory manifest is validated against path traversal before use, and a manifest file count is checked against the payload size before it is used to size an allocation.
Threading: a worker pool runs the blocking send loop (one transfer per worker); receiving + all control handling run on the reactor thread; a maintenance thread reaps idle/timed-out transfers. A finished transfer is erased as it completes, so there is no retention window. Each transfer has its own mutex+condvar; the maps are guarded by mutex_.
Wire (MessageType::FileChunk payload, big-endian): OFFER [1][id:u64][flags:u8][total:u64][name_len:u16][name][file_count:u32] { [path_len:u16][path][size:u64] } × file_count RESPONSE [2][id:u64][accept:u8]{[start_offset:u64]} (offset: resume request) CHUNK [3][id:u64][file_index:u32][offset:u64][data] FILE_END [4][id:u64][file_index:u32][sha256:32] PROGRESS [5][id:u64][received:u64] (cumulative across all files) COMPLETE [6][id:u64][ok:u8] CANCEL [7][id:u64] PAUSE [8][id:u64] RESUME [9][id:u64]
Definition in file file_transfer.h.