oc-rsync 0.6.4
Wire-compatible with upstream rsync 3.4.4 (protocol 32).
Install
Homebrew:
brew install oferchen/rsync/oc-rsyncBinary: Download the asset for your platform below.
| Platform | Formats |
|---|---|
| Linux (x86_64, aarch64) | .deb, .rpm (with OpenSSL), static musl .tar.gz, *-openssl.tar.gz |
| macOS (x86_64, aarch64) | .tar.gz |
| Windows (x86_64) | .tar.gz, .zip |
Linux static tarballs: *-musl.tar.gz (pure Rust) or *-musl-openssl.tar.gz (OpenSSL-accelerated checksums).
Toolchain variants
Each release ships three Rust-toolchain variants of every binary:
| Suffix | Rust toolchain | Recommended use |
|---|---|---|
| (none) | stable | Default. Use this. |
-beta |
Rust beta | Early adopters validating the next Rust release. |
-nightly |
Rust nightly | Performance experiments and unstable-feature testing. |
The -beta / -nightly suffix denotes the Rust toolchain the artifact was built with - it is not an indicator of oc-rsync's own release maturity (that is set in the release title and README.md).
Highlights
See the v0.6.4 changelog entry for the full, per-category list of changes in this release (258 entries across Added / Fixed / Performance / Changed / Documentation / Testing / CI / Maintenance).
Security
See SECURITY.md for the canonical mitigation roster and docs/design/sec-1-completion-summary-2026-05-22.md for the SEC-1 sub-task (.a-.p) ship state.
Active mitigations
| CVE | Description | Status | Cite |
|---|---|---|---|
| CVE-2026-29518 | Path traversal via symlink race | Fixed | SEC-1.a-q2, SECURITY.md |
| CVE-2026-43619 | Privilege escalation via TOCTOU | Fixed | SEC-1.a-q2, SECURITY.md |
Defense-in-depth. This release ships the SEC-1 *at syscall chain (fstatat, unlinkat, mkdirat, symlinkat, linkat, fchmodat, fchownat, utimensat, renameat) routed through a per-transfer DirSandbox carrier with openat2(RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS) runtime detection. The optional landlock Cargo feature (Linux 5.13+) layers kernel-enforced PathBeneath allowlisting on top; daemons on older kernels run with the *at chain as the sole TOCTOU defense, which is itself sufficient against CVE-2026-29518 / CVE-2026-43619.
Platform support tiers
| Platform | Tier | Notes |
|---|---|---|
| Linux x86_64 / aarch64 | Tier 1 | Full io_uring + splice + vmsplice + Landlock + seccomp. Every required CI cell runs the full nextest workspace. |
| macOS x86_64 / aarch64 | Tier 1 | kqueue + sendfile + clonefile. Every required CI cell runs the full nextest workspace. |
| Windows x86_64 | Tier 2 | IOCP file and socket I/O, TransmitFile, ReFS reflink, CopyFileExW. splice / vmsplice / io_uring are Linux-only and intentionally not implemented; the IOCP receive path is faster than the upstream Cygwin read/write fallback. Required CI cells test the core, engine, and cli crates. See Windows support matrix and the Windows Tier 2 stub inventory. |
Tier 2 is a deliberate choice (no Win32 equivalent for splice / vmsplice / io_uring), not a defect. The IOCP backend matches or beats the upstream Cygwin baseline on the same workload.
Kernel / platform compatibility
| Layer | Minimum | Notes |
|---|---|---|
| io_uring data path | Linux 5.6+ | Runtime-probed; falls back to standard buffered I/O. |
| Provided buffer rings (PBUF_RING) | Linux 5.19+ | Runtime-probed; falls back to standard buffered I/O. |
Landlock LSM (landlock feature) |
Linux 5.13+ | Best-effort ABI downgrade; no-op on older kernels. |
IORING_OP_SEND_ZC (iouring-send-zc feature) |
Linux 6.0+ recommended | Opt-in; default builds use plain IORING_OP_SEND. |
macOS *at chain |
macOS 10.10+ | BSD *at family verified at parity with Linux (SEC-1.k). |
| Windows IOCP | Windows 10 1809+ | NTFS handle-based APIs sidestep path TOCTOU structurally (SEC-1.l). |
Distro packagers: see docs/packaging/landlock-feature-guidance.md for the per-distro --features landlock recommendation, runtime ABI matrix, and build-time dependency notes.
Linux io_uring requirements
oc-rsync uses Linux io_uring for high-throughput I/O on supported kernels. The minimum supported kernel for the io_uring path is Linux 5.6; older kernels (including RHEL 8 / CentOS Stream 8 at 4.18) fall back to standard read(2) / write(2) automatically - no user action required.
For the full performance tier (zero-copy SEND_ZC), Linux 6.0 or newer is required AND the binary must be built with the iouring-send-zc cargo feature enabled. Default release builds advertise --zero-copy but downgrade to non-zero-copy SEND silently on older kernels or builds without the feature.
Full per-opcode kernel-floor matrix: see docs/audit/iouring-opcode-kernel-floor.md.
Supported rsync protocol versions
oc-rsync continues to support protocol versions 28-32 inclusive, matching upstream rsync 2.6.x through 3.4.x. Protocol back-negotiation to 28 is exercised by wire-byte regression tests and a periodic CI matrix against rsync 2.6.9 (built from source). Protocols <= 27 (rsync 2.5.x and earlier) remain unsupported. See docs/design/rp28-k-1-protocol-drop-vs-keep-decision.md for the decision rationale and docs/design/rp28-k-2-execution-record.md for the execution record.
Full changelog: {{PREV_VERSION}}...0.6.4
What's Changed
Full changelog
This release rolls up roughly 1,200 pull requests merged since v0.6.3. See the curated, per-category CHANGELOG for the complete list, or the full commit comparison.
Benchmark Results
oc-rsync vs upstream rsync 3.4.4 on 148.3MB (10000 files).
Highlights
- Overall: oc-rsync is 1.12x faster than upstream on average across transfer modes.
- Sparse Files: 3.45x faster.
- Large File (1GB): 2.04x faster.
- Daemon Push: 1.30x faster.
Local Copy
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.279s | 0.237s | faster 0.85x |
| No-change sync | 0.093s | 0.081s | faster 0.87x |
| Checksum sync | 0.191s | 0.138s | faster 0.72x |
SSH Pull
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.587s | 0.800s | slower 1.36x |
| No-change sync | 0.326s | 0.307s | faster 0.94x |
SSH Push
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.590s | 0.563s | ~same 0.95x |
| No-change sync | 0.348s | 0.339s | ~same 0.97x |
Daemon Pull
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.425s | 1.431s | slower 3.37x |
| No-change sync | 0.211s | 0.166s | faster 0.79x |
Daemon Push
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.408s | 0.347s | faster 0.85x |
| No-change sync | 0.203s | 0.140s | faster 0.69x |
Checksum: OpenSSL vs Pure Rust
| Test | Pure Rust | OpenSSL | Ratio |
|---|---|---|---|
| Initial checksum sync | 0.271s | 0.269s | ~same 0.99x |
| No-change checksum sync | 0.136s | 0.136s | ~same 1.00x |
io_uring vs Standard I/O
| Test | Standard I/O | io_uring | Ratio |
|---|---|---|---|
| Local initial sync | 0.231s | 0.231s | ~same 1.00x |
| Daemon pull initial | 1.439s | 1.429s | ~same 0.99x |
| SSH pull initial | 0.808s | 0.801s | ~same 0.99x |
SSH Transport: upstream vs oc-rsync subprocess vs oc-rsync russh
| Test | Upstream (ssh) | oc-rsync (ssh) | oc-rsync (russh) | oc-sub / upstream | russh / oc-sub |
|---|---|---|---|---|---|
| Initial pull | 0.609s | 0.817s | 0.648s | slower 1.34x | faster 0.79x |
| No-change pull | 0.335s | 0.368s | 0.171s | slower 1.10x | faster 0.47x |
| Initial push | 0.593s | 0.555s | 0.400s | faster 0.94x | faster 0.72x |
| No-change push | 0.344s | 0.340s | 0.184s | ~same 0.99x | faster 0.54x |
Compression
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| zlib initial sync | 0.287s | 0.279s | ~same 0.97x |
| zlib no-change sync | 0.093s | 0.084s | faster 0.90x |
| zstd initial sync | 0.288s | 0.283s | ~same 0.98x |
| zstd no-change sync | 0.093s | 0.085s | faster 0.91x |
Delta Transfer
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Local delta sync | 0.094s | 0.084s | faster 0.89x |
| Local delta checksum sync | 0.194s | 0.145s | faster 0.75x |
Large File (1GB)
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| 1GB file initial sync | 0.500s | 0.580s | slower 1.16x |
| 1GB file no-change sync | 0.045s | 0.004s | faster 0.09x |
| 1GB file delta sync | 1.876s | 0.415s | faster 0.22x |
Many Small Files (100K)
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| 100K files initial sync | 3.038s | 3.127s | ~same 1.03x |
| 100K files no-change sync | 0.588s | 0.775s | slower 1.32x |
Sparse Files
| Test | rsync 3.4.4 | oc-rsync | Ratio |
|---|---|---|---|
| Sparse initial sync | 0.262s | 0.116s | faster 0.44x |
| Sparse no-change sync | 0.047s | 0.006s | faster 0.14x |
Memory Usage (Peak RSS)
| Test | rsync 3.4.4 | oc-rsync | Time Ratio | RSS rsync 3.4.4 | RSS oc-rsync |
|---|---|---|---|---|---|
| Initial sync (10K files) | 0.403s | 0.343s | faster 0.85x | 7.7MB | 45.4MB |
| 1GB file sync | 0.508s | 0.310s | faster 0.61x | 6.9MB | 15.0MB |
| 100K files sync | 2.986s | 3.016s | ~same 1.01x | 7.6MB | 92.5MB |
Summary
Overall: 0.89x average ratio
(best 0.09x, worst 3.37x)
| Mode | Avg Ratio |
|---|---|
| Local Copy | 0.81x |
| SSH Pull | 1.15x |
| SSH Push | 0.96x |
| Daemon Pull | 2.08x |
| Daemon Push | 0.77x |
| Checksum: OpenSSL vs Pure Rust | 0.99x |
| io_uring vs Standard I/O | 0.99x |
| SSH Transport: upstream vs oc-rsync subprocess vs oc-rsync russh | 0.63x |
| Compression | 0.94x |
| Delta Transfer | 0.82x |
| Large File (1GB) | 0.49x |
| Many Small Files (100K) | 1.18x |
| Sparse Files | 0.29x |
| Memory Usage | 0.82x |
Ratio < 1.0 = oc-rsync faster, > 1.0 = upstream faster