feat(compression): implement transparent LZ4 chunk compression with V1 backwards compatibility
This commit is contained in:
+13
-4
@@ -86,6 +86,7 @@ pub struct SanctumFile {
|
||||
meta: SanctumMetaData,
|
||||
// (chunk_index, decrypted_payload, is_dirty)
|
||||
cached_chunk: Option<(u32, Vec<u8>, bool)>,
|
||||
format_version: u32,
|
||||
}
|
||||
|
||||
impl Debug for SanctumFile {
|
||||
@@ -94,6 +95,7 @@ impl Debug for SanctumFile {
|
||||
.field("node_id", &self.node_id)
|
||||
.field("file_size", &self.file_size)
|
||||
.field("cursor", &self.cursor)
|
||||
.field("format_version", &self.format_version)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -103,6 +105,7 @@ impl SanctumFile {
|
||||
node: NodeRecord,
|
||||
db: Database,
|
||||
dek: Arc<Zeroizing<[u8; 32]>>,
|
||||
format_version: u32,
|
||||
) -> Self {
|
||||
let meta = SanctumMetaData {
|
||||
is_dir: node.is_dir,
|
||||
@@ -119,14 +122,16 @@ impl SanctumFile {
|
||||
dek,
|
||||
meta,
|
||||
cached_chunk: None,
|
||||
format_version,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Schreibt den aktuell im RAM gehaltenen Chunk verschlüsselt in die SQLite-Datenbank zurück.
|
||||
fn flush_cached_chunk(&mut self) -> Result<(), FsError> {
|
||||
if let Some((idx, ref data, true)) = self.cached_chunk {
|
||||
let (ciphertext, nonce, tag) =
|
||||
encrypt_chunk(&self.dek, self.node_id, idx, data).map_err(|e| {
|
||||
encrypt_chunk(&self.dek, self.node_id, idx, data, self.format_version).map_err(|e| {
|
||||
error!("Verschlüsselungsfehler beim Chunk-Flush: {e}");
|
||||
FsError::GeneralFailure
|
||||
})?;
|
||||
@@ -166,6 +171,7 @@ impl SanctumFile {
|
||||
&record.ciphertext,
|
||||
&record.nonce,
|
||||
&record.tag,
|
||||
self.format_version,
|
||||
)
|
||||
.map_err(|e| {
|
||||
error!("AEAD-Entschlüsselungsfehler bei Chunk #{chunk_index}: {e}");
|
||||
@@ -339,13 +345,15 @@ impl DavFile for SanctumFile {
|
||||
pub struct SanctumFs {
|
||||
db: Database,
|
||||
dek: Arc<Zeroizing<[u8; 32]>>,
|
||||
format_version: u32,
|
||||
}
|
||||
|
||||
impl SanctumFs {
|
||||
pub fn new(db: Database, dek: Zeroizing<[u8; 32]>) -> Self {
|
||||
pub fn new(db: Database, dek: Zeroizing<[u8; 32]>, format_version: u32) -> Self {
|
||||
Self {
|
||||
db,
|
||||
dek: Arc::new(dek),
|
||||
format_version,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +440,7 @@ impl DavFileSystem for SanctumFs {
|
||||
}
|
||||
};
|
||||
|
||||
let file = SanctumFile::new(node, self.db.clone(), self.dek.clone());
|
||||
let file = SanctumFile::new(node, self.db.clone(), self.dek.clone(), self.format_version);
|
||||
Ok(Box::new(file) as Box<dyn DavFile>)
|
||||
})
|
||||
}
|
||||
@@ -678,11 +686,12 @@ impl DavFileSystem for SanctumFs {
|
||||
&record.ciphertext,
|
||||
&record.nonce,
|
||||
&record.tag,
|
||||
self.format_version,
|
||||
)
|
||||
.map_err(|_| FsError::GeneralFailure)?;
|
||||
|
||||
let (new_ct, new_nonce, new_tag) =
|
||||
encrypt_chunk(&self.dek, dest_node.id, idx, &plaintext)
|
||||
encrypt_chunk(&self.dek, dest_node.id, idx, &plaintext, self.format_version)
|
||||
.map_err(|_| FsError::GeneralFailure)?;
|
||||
|
||||
self.db
|
||||
|
||||
Reference in New Issue
Block a user