Account decrypted copies in media quota and protect active containers
This commit is contained in:
1 parent
feb327afc7
commit
5d2522b8de
1 file changed
+39
-2
+39
-2
@@ -34,7 +34,6 @@ void chat_core_submit_media_message(struct UTUN_INSTANCE* inst, struct chat_msg_
|
||||
static void wh_transcribe_done_cb(void* arg, const char* ch_id, const char* text, int err,
|
||||
const uint8_t reply_id[32]);
|
||||
static void chat_media_cache_cleanup_orphans(struct UTUN_INSTANCE* inst);
|
||||
static void chat_media_cache_enforce(struct UTUN_INSTANCE* inst);
|
||||
static void chat_media_cache_reconcile(struct UTUN_INSTANCE* inst);
|
||||
|
||||
/* ─── счётчик объёма медиакеша (сумма файлов, соответствующих сообщениям) ─── */
|
||||
@@ -1514,6 +1513,25 @@ static void chat_media_foreach_media_message(struct chat_core_ctx* cc, const cha
|
||||
|
||||
cb(&f, arg);
|
||||
|
||||
if (cc->attachment_initialized && !strcmp(content_type, ENCRYPTED_ATTACHMENT_TYPE)) {
|
||||
uint8_t crypto_id[16];
|
||||
sqlite3_stmt* local = NULL;
|
||||
if (!chat_attachment_identity(body, dlen, crypto_id) && sqlite3_prepare_v2(cc->db,
|
||||
"SELECT plain_path FROM attachment_keys WHERE channel=? AND crypto_id=? AND ready=1 AND decrypting=0",
|
||||
-1, &local, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_text(local, 1, ch_id, -1, SQLITE_STATIC); sqlite3_bind_blob(local, 2, crypto_id, 16, SQLITE_STATIC);
|
||||
int rc = sqlite3_step(local);
|
||||
if (rc == SQLITE_ROW) {
|
||||
snprintf(f.full_path, sizeof(f.full_path), "%s", sqlite3_column_text(local, 0));
|
||||
size_t prefix = strlen(media_base);
|
||||
if (!strncmp(f.full_path, media_base, prefix) && f.full_path[prefix] == '/') {
|
||||
snprintf(f.rel_path, sizeof(f.rel_path), "%s", f.full_path + prefix + 1); cb(&f, arg);
|
||||
}
|
||||
} else if (rc != SQLITE_DONE) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted cache: scan failed rc=%d ch=%s", rc, ch_id);
|
||||
sqlite3_finalize(local);
|
||||
} else DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted cache: metadata lookup failed ch=%s: %s", ch_id, sqlite3_errmsg(cc->db));
|
||||
}
|
||||
|
||||
u_free(body);
|
||||
media_index_result_free(&result);
|
||||
}
|
||||
@@ -1638,6 +1656,24 @@ static void chat_media_cache_cleanup_orphans(struct UTUN_INSTANCE* inst) {
|
||||
|
||||
struct cache_rel_list rels = {0};
|
||||
chat_media_foreach_media_message(cc, media_base, cache_rel_collect_cb, &rels);
|
||||
/* Ещё не опубликованные контейнеры и их временные файлы принадлежат crypto worker. */
|
||||
if (cc->attachment_initialized) {
|
||||
sqlite3_stmt* active = NULL;
|
||||
if (sqlite3_prepare_v2(cc->db, "SELECT cipher_path FROM attachment_keys", -1, &active, NULL) == SQLITE_OK) {
|
||||
int rc;
|
||||
while ((rc = sqlite3_step(active)) == SQLITE_ROW) {
|
||||
const char* path = (const char*)sqlite3_column_text(active, 0);
|
||||
size_t prefix = strlen(media_base);
|
||||
if (path && !strncmp(path, media_base, prefix) && path[prefix] == '/') {
|
||||
cache_rel_add(&rels, path + prefix + 1);
|
||||
char temporary[1040]; snprintf(temporary, sizeof(temporary), "%s.part", path + prefix + 1);
|
||||
cache_rel_add(&rels, temporary);
|
||||
}
|
||||
}
|
||||
if (rc != SQLITE_DONE) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted cache: active scan failed rc=%d", rc);
|
||||
sqlite3_finalize(active);
|
||||
} else DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted cache: active query failed: %s", sqlite3_errmsg(cc->db));
|
||||
}
|
||||
if (rels.count > 1) qsort(rels.items, (size_t)rels.count, sizeof(char*), cache_str_cmp);
|
||||
|
||||
struct orphan_walk_ctx ow;
|
||||
@@ -1653,10 +1689,11 @@ static void chat_media_cache_cleanup_orphans(struct UTUN_INSTANCE* inst) {
|
||||
u_free(rels.items);
|
||||
}
|
||||
|
||||
static void chat_media_cache_enforce(struct UTUN_INSTANCE* inst) {
|
||||
void chat_media_cache_enforce(struct UTUN_INSTANCE* inst) {
|
||||
struct chat_core_ctx* cc = CC(inst);
|
||||
if (!cc || !cc->initialized || !cc->db || !inst) return;
|
||||
uint64_t limit = inst->config->global.chatserver_storage_total_size;
|
||||
if (cc->attachment_initialized) cc->media_cache_bytes = chat_media_cache_scan_sum(cc);
|
||||
|
||||
if (limit == 0 || cc->media_cache_bytes <= limit) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "%s: cache limit ok bytes=%llu limit=%llu",
|
||||
|
||||
Reference in new issue
Block a user