openrtc-file-transfer
Optional native companion for the TypeScript openrtc-file-transfer package.
It implements the same version-1 named-channel wire format over any protected
bidirectional byte stream. The crate does not own OpenRTC lifecycle, peer
selection, filesystem policy, persistent queues, history, or UI.
Applications open an authenticated OpenRTC peer stream, then pass it to
send_path or receive_to_directory. Receivers enforce bounded headers and
file sizes, sanitize filenames, write with create_new, verify optional SHA-256
digests incrementally, and acknowledge only after the destination is flushed.
Resume is explicit and fail-closed: an offset is accepted only when the named
destination already exists at exactly that length; any declared digest includes
and verifies the existing prefix before appended bytes are acknowledged.
Incoming resume bytes are staged separately, so interruption or integrity
failure never deletes or modifies the receiver's existing destination.
For runtime-wide directional speed limits, clone one
flow_control::BulkFlowController across every bulk executor. Configure optional
upload/download bytes-per-second rates and pass a BodyFlow with an authenticated
peer scheduling key to send_path_with_flow or receive_to_directory_with_flow.
The stream helpers bound body and hashing buffers to 64 KiB even when callers
prefer larger chunks. Admission, headers and acknowledgements bypass body pacing.
Start transport I/O deadlines after each pacing wait, rather than wrapping the
whole transfer in a short timeout. Dropping an acquire future cancels its queued
slice; live rate updates wake waiting work. Applications still own durable byte
accounting, quota grants, cross-runtime execution ownership and delivery receipts.
The routed codec also understands negotiated OFT2 Waiting (kind 0x08):
transfer ID, big-endian u64 checkpointed offset and u32 lease milliseconds
(1–60,000). RECEIVER_WAIT_METADATA_KEY is openrtc.receive-wait; an immutable
offer must contain value 1 before a receiver may issue waiting frames. A wait
is neither an offset ACK nor a completion receipt. Native protocol executors
must implement authenticated-peer/active-window matching, bounded deadline
renewal and cancellation before advertising this capability. Codec support by
itself does not enable receiver pacing or alter the legacy raw-stream helpers.
The shared routed codec supports CapabilitiesRequest (OFT2 0x09) and
Capabilities (0x0a). Requests carry an optional immutable header after a
big-endian u32 length; an empty request has zero length. Responses carry a
closed version-1 JSON document after a u32 length, bounded to4096 bytes, with
version, durableResume, completionReceipt, extensions,
receiveAvailable, and maxFileBytes (0..=9,007,199,254,740,991). A header probe
is bounded by the configured header-byte ceiling and the safe-integer size
ceiling, independently of current receive body limits. This permits protected
product receipt lookup after body admission changes.
RequiredTransferCapabilities and FileTransferHeader::with_required_capabilities
encode required features under immutable openrtc.required-capabilities.v1
metadata. TransferCapabilities::require checks receiver availability, size and
features before body acceptance. Extension names are bounded, sorted and distinct;
unknown fields, invalid flags/versions and malformed metadata fail closed.
The legacy stream helpers reject required-feature metadata before opening the
source or creating a destination. Their explicit bounded streaming limits remain
separate from routed negotiation.
Native routed executors must probe, bind replies to the authenticated peer and transfer ID, enforce requirements before allocating a sink, and retrieve an exact durable product receipt before applying current body limits. They must verify required receipt persistence before success and require durable checkpoints for advertised resume. The codec is not a queue, destination/ACL owner or receipt store; support must not be advertised before the consumer implements and qualifies those behaviors. See the TypeScript companion for the shared wire contract and callback-based executor.