Expand description
Entropy reconciliation channel.
The entropy module ships a snapshot of the local datastore to a
peer reconciliation engine (and vice versa) over a TCP
connection. Each chunk of the snapshot is encrypted with
AES-128-CBC using a pre-shared key and IV loaded from the
conf-configured recon_key.pem and recon_iv.pem files. The
key and IV used here are independent from the per-peer
AES session key established during the DNODE handshake; the
entropy channel uses its own pre-shared material.
§Layout
utilholds the on-disk key/IV loaders and validated wrappers.senddrives the client side: connect, write the negotiation header, stream the snapshot.receivedrives the server side: bind, accept, replay the plaintext into aSnapshotSink.- The top-level
EntropyConfiggathers the operator-visible knobs.
§Wire format
The reference engine’s reconciliation protocol consists of two
sub-protocols (a file-stream snd path and a per-record rcv
path) that are not inverses of each other. The Rust port uses a
single, length-prefixed framing that subsumes the snd shape
and is symmetric across sender and receiver. See
docs/parity.md for the precise
divergence list.
Negotiation header (20 bytes, big-endian u32 fields):
magic = 0x64640001
command = 1 (SEND: data flowing sender -> receiver)
header_size = N (size in bytes of the snapshot header below)
buffer_size = M (max plaintext bytes per chunk)
cipher_size = C (max ciphertext bytes per chunk)
Snapshot header (header_size bytes, big-endian u32 fields then
zero-padded):
total_len = L (total plaintext length in bytes)
encrypt_flag = 0|1 (1 if chunks are AES-128-CBC encrypted)
<header_size - 8 bytes of zero padding>
Chunks (repeated until L plaintext bytes have been delivered):
u32 BE chunk_len
<chunk_len bytes of payload>
When encrypt_flag is set each payload is the AES-128-CBC
ciphertext of the matching plaintext chunk, PKCS#7-padded to a
16-byte boundary; the receiver strips the padding before
delivering bytes to its sink.§Example
use std::path::PathBuf;
use dynomite::entropy::{EntropyConfig, EntropyReceiver, EntropySender};
let cfg = EntropyConfig {
key_file: PathBuf::from("/etc/dynomite/recon_key.pem"),
iv_file: PathBuf::from("/etc/dynomite/recon_iv.pem"),
listen_addr: "127.0.0.1:8105".parse().unwrap(),
send_addr: None,
peer_endpoint: "127.0.0.1:8105".parse().unwrap(),
buffer_size: 16 * 1024,
header_size: 1024,
encrypt: true,
};
drop(cfg);Re-exports§
pub use crate::entropy::receive::EntropyReceiver;pub use crate::entropy::send::EntropySender;pub use crate::entropy::send::RedisLocalSnapshot;pub use crate::entropy::util::EntropyIv;pub use crate::entropy::util::EntropyKey;pub use crate::entropy::util::EntropyMaterial;pub use crate::entropy::util::ENTROPY_IV_LEN;pub use crate::entropy::util::ENTROPY_KEY_LEN;
Modules§
- driver
- Periodic entropy reconciliation driver.
- receive
- Entropy receiver.
- send
- Entropy sender.
- util
- Pre-shared key and IV loading for the entropy reconciliation channel.
Structs§
- Entropy
Config - Operator-facing configuration for the entropy worker.
- Negotiation
Header - Negotiation header that opens every entropy connection.
- Snapshot
Header - Per-snapshot header carried inside the variable-sized header region declared by the negotiation step.
Enums§
- Entropy
Error - Errors raised by the entropy module.
Constants§
- DEFAULT_
BUFFER_ SIZE - Default plaintext chunk size, in bytes. Matches the reference
engine’s
BUFFER_SIZE(16 KiB). - DEFAULT_
CIPHER_ SIZE - Default ciphertext chunk capacity, in bytes. The reference engine reserves an extra 1 KiB above the plaintext buffer to hold cipher overhead; we mirror that headroom, which is far more than PKCS#7 needs.
- DEFAULT_
HEADER_ SIZE - Default snapshot header size, in bytes. Matches the reference
engine’s
MAX_HEADER_SIZE. - ENTROPY_
COMMAND_ SEND - Negotiation command: sender pushes a snapshot to the receiver.
- ENTROPY_
MAGIC - Magic word that opens every entropy negotiation header.
- MAX_
BUFFER_ SIZE - Hard ceiling on the negotiated
buffer_size, in bytes (5 MiB). - MAX_
CIPHER_ SIZE - Hard ceiling on the negotiated
cipher_size, in bytes (5 MiB). - MAX_
HEADER_ SIZE - Hard ceiling on the negotiated
header_size, in bytes. - MAX_
SNAPSHOT_ SIZE - Hard ceiling on a single snapshot’s plaintext size, in bytes (4 GiB).
- SAFE_
PREALLOC - Cap the receiver’s pre-allocation hint to avoid a malicious or
malformed
total_lentriggering an oversized allocation up front. Real RDB snapshots stream chunk-by-chunk; the receiver reallocates as plaintext arrives if the snapshot is genuinely larger than the hint.
Traits§
- Snapshot
Sink - Receiver-side hook that consumes the decrypted snapshot.
- Snapshot
Source - Snapshot byte source.
Functions§
- boxed_
sink - Box a
SnapshotSinkinto theBoxedSnapshotSinkalias expected byEntropyReceiver::run. - boxed_
source - Box a
SnapshotSourceinto theBoxedSnapshotSourcealias expected byEntropySender::run.
Type Aliases§
- Boxed
Snapshot Sink - Boxed
SnapshotSinkhanded toEntropyReceiver. - Boxed
Snapshot Source - Boxed
SnapshotSourcehanded toEntropySender. - Entropy
Result - Convenience type alias.