Files
utun2/src/chat/chat_attachment.h
T

91 lines
7.3 KiB
C

/* chat_attachment — вложения канала с шифрованием и ручной выдачей ключа автором.
* send готовит контейнер и публикует сообщение; downloaded/want запускают получение ключа и расшифровку.
* Автор отвечает на запрос через decide. Ключи и очередь доставки сохраняются в локальной БД.
* Все вызовы, кроме identity, — uasync. init после media_async; quiesce до остановки workers, destroy после них.
* Обмен ключами подписан и зашифрован; для доставки нужен живой маршрут обеих сторон.
* Ответы REQUEST_ACK/GRANT/DENY/RESULT_ACK атомарно меняют ключ, запрос и outbox собственной транзакцией.
* Внешняя транзакция для ответов запрещена. GRANT/DENY подтверждаются только после проверенного commit;
* повтор с тем же результатом допустим, конфликтующий ключ/решение отклоняется. Отказ SQL сохраняет прежнее состояние.
* Незавершённый rollback отключает модуль и запрашивает остановку ядра владельцем вне callback. */
#ifndef CHAT_ATTACHMENT_H
#define CHAT_ATTACHMENT_H
#include "../media_async/attachment.h"
#include "../media_async/encrypted_file.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UTUN_INSTANCE;
// ── Жизненный цикл модуля ──
// Подключить таблицы, router-сервис и обработку сохранённых задач; 0/-1.
int chat_attachment_init(struct UTUN_INSTANCE* inst);
// Запретить новые подготовки и остановить таймер; запущенные workers завершаются отдельно.
void chat_attachment_quiesce(struct UTUN_INSTANCE* inst);
// После завершения workers убрать незавершённые подготовки и отключить router-сервис.
void chat_attachment_destroy(struct UTUN_INSTANCE* inst);
// ── Отправка и учёт вложений ──
/* Асинхронно отправить подготовленный файл; channel — десятичный ID, reply — 32 байта ID ответа либо нули.
* Аргументы копируются. 0 — задача принята, source передан задаче и будет удалён даже при ошибке подготовки.
* -1 — отказ до принятия, source остаётся у вызывающего, события MSG_SUBMITTED здесь нет.
* Ключ/UUID/метаданные фиксируются собственной SQL-транзакцией до передачи source и запуска worker.
* Внешняя транзакция запрещена и остаётся нетронутой при отказе. Ошибка rollback с открытой транзакцией
* запрещает новые задачи модуля и запрашивает остановку ядра; уничтожение выполняет владелец вне callback.
* Ненулевой request возвращается в единственном CHAT_EVT_MSG_SUBMITTED; отказ media_async_submit может
* дать его синхронно, до возврата 0. Commit не усиливает установленную ядром политику SQLite synchronous. */
/* type проверяется encrypted_file_validate_type до выделения задачи, генерации UUID/ключа и записи в БД. */
int chat_attachment_send(struct UTUN_INSTANCE* inst, const char* channel, const char* source,
const struct attachment_info* info, const char* type, const uint8_t reply[32], uint64_t request);
// Прочитать UUID из канонического base64-префикса тела медиа; 0/-1. Подпись проверяет вызывающий.
int chat_attachment_identity(const char* body, size_t length, uint8_t id[16]);
// Связать авторский ключ с ID сообщения и SHA256 контейнера до публикации; 0/-1. Массивы копируются в БД.
int chat_attachment_bind(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t id[16],
const uint8_t message[32], const uint8_t hash[32]);
// Учесть проверенное db_sync сообщение и сохранить метаданные контейнера; 0/-1. Обычные сообщения игнорируются.
int chat_attachment_observe(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message[32],
uint64_t author, const char* json, size_t length);
// ── Получение файла и выдача доступа ──
// После проверенной загрузки: сохранить состояние, запросить ключ либо расшифровать.
void chat_attachment_downloaded(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message[32]);
// Ручная загрузка на storage-узле также означает запрос пользовательского доступа.
void chat_attachment_want(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message[32]);
/* Сохранить решение автора по ожидающему запросу peer: approve!=0 — выдать ключ, 0 — отказать.
* 0 — собственная транзакция решения+outbox завершена, затем послано одно уведомление изменения;
* -1 — ошибка/нет прав или ожидающего запроса, прежнее состояние сохранено. Доставка идёт позже.
* Внешняя транзакция отклоняется без изменений; проверка прав выполняется внутри собственной.
* Открытая после отказа rollback транзакция требует остановки/закрытия БД владельцем после poll. */
int chat_attachment_decide(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message[32], uint64_t peer, int approve);
// ── Команда интерфейса ──
struct chat_attachment_decision {
struct UTUN_INSTANCE* inst;
char channel[32];
uint8_t message[32];
uint64_t peer;
int approve;
};
// arg — u_malloc/u_calloc chat_attachment_decision, освобождается здесь; успех уже уведомлён decide, ошибка — событие с success=0.
void chat_attachment_decision_trampoline(void* arg);
// ── Локальное удаление канала ──
// Канал удаляется локально: отменить очереди, стереть ключи и частные копии.
void chat_attachment_delete_channel(struct UTUN_INSTANCE* inst, const char* channel);
#ifdef __cplusplus
}
#endif
#endif