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 "util/rats_export.h"#include "node/peer_network.h"#include "peer/peer.h"#include "core/bytes.h"#include "peer/peer_id.h"#include "util/fs.h"#include "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.
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] 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.