Keep-alive (`STATUS_KEEPALIVE`) may be sent at any point during the transfer. The receiver resets its inactivity timer on receipt. If no data arrives within the receive timeout, the connection is aborted.
Abort (`STATUS_ABORT`) may be sent at any point. On receipt the server cleans up temporary files and exits the child process.
### Protocol Version
`1.1.0` — server and client must match. Mismatch results in `STATUS_ERROR`.
`1.3.0` — server and client must match. Mismatch results in `STATUS_ERROR`.
4.**Config** — runtime parameters (transported over wire, TLS settings excluded)
4.**Config** — runtime parameters (transported over wire, TLS settings excluded). Includes `timeout`, `contimeout`, `quiet`, `backup`, `backup_dir`, `stats`, `max_depth`, `log_file`, `queue_size`.
5.**Queue** — thread-safe bounded queue with condition variables
6.**DirectoryScanner** — recursive BFS traversal with exclude and include pattern support
6.**DirectoryScanner** — recursive BFS traversal with exclude and include pattern support, max-depth enforcement
### Key Algorithms
1.**File scanning** — BFS directory traversal; entries matched against exclude and include patterns
1.**File scanning** — BFS directory traversal; entries matched against exclude and include patterns, max-depth enforced
2.**Chunking** — files accumulated until `chunk_size` threshold, then flushed
3.**Compression** — streaming zstd via `ZSTD_compressStream2` / `ZSTD_decompressStream`
4.**Network protocol** — status-code-driven exchange with metadata packing
5.**Incremental check** — client sends `STATUS_CHECK` + path + size + mtime; server compares against destination
4.**Network protocol** — status-code-driven exchange with metadata packing, keep-alive, and abort support
5.**Incremental check** — client sends `STATUS_CHECK` + path + size + mtime; server compares against destination. Can be batched via `STATUS_CHECK_BATCH` for reduced round-trips.
6.**Bandwidth limiting** — token-bucket algorithm with `nanosleep` throttling on 64 KB write chunks
7.**Metadata restoration** — `chmod()`, `chown()`, `utimensat()` on the receiving side
8.**`--delete`** — sender tracks all sent paths; receiver walks destination tree and removes unlisted files/directories
9.**SSH transport** — `socketpair()` + `fork()` + `execvp("ssh", ...)` with `ControlMaster` and port support
10.**TLS transport** — OpenSSL `SSL_CTX` with TLS 1.2 minimum, optional CA verification, transparent `SSL_read`/`SSL_write` via `io_set_ssl()`
14.**Abort handling** — `SIGINT` sets an abort flag; the next protocol operation sends `STATUS_ABORT` for clean server cleanup
15.**Atomic writes** — files are written to a `.tmp` suffix then atomically renamed via `rename()`, preventing partial files
16.**Backup** — before overwriting, existing files are moved to `--backup-dir` (or same directory with `~` suffix) preserving the original
## Security Features
### Path Traversal Protection
All received file paths are validated by `has_path_traversal()` before any disk operation. Any path containing `..` components is rejected with `STATUS_ERROR`, preventing directory escape attacks.
### TLS Certificate Verification
When `--ca` is provided, the server performs mutual TLS verification (`SSL_VERIFY_PEER` with depth 4). Without `--ca`, TLS is still encrypted but peer certificates are not verified.
### Connection Limits
The server enforces a maximum of 100 concurrent connections (configurable via `max_connections` in `Server`). When the limit is reached, new connections are immediately rejected and closed.
### Abort Handling
If the client receives `SIGINT` (Ctrl+C) during a transfer, it sends `STATUS_ABORT` to the server. The server then cleans up temporary files and exits the child process, preventing incomplete files from remaining on disk.
### Atomic Writes
Received files are written to a temporary path (suffixed with `.tmp`) and then atomically renamed to the final filename via `rename()`. This prevents partial or corrupted files from appearing at the destination if the transfer is interrupted.
## Build Requirements
@@ -223,6 +294,21 @@ Place the `fastsync-server` binary in the remote `$PATH`. The client runs `ssh u
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.