91 lines
7.3 KiB
C
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
|