46 lines
4.7 KiB
C
46 lines
4.7 KiB
C
/* dm_mailbox_media — durable задания суперузла: размещение на M, доставка
|
||
* метаданных получателю и освобождение назначений по DELETE_ACK/EXPIRED либо подтверждённому TTL.
|
||
* Жизненный цикл принадлежит dm_mailbox, control принимает dm_media. Все API в uasync.
|
||
* Координатор хранится в dm_media_jobs/dm_media_holders SQLite ядра; таймер — только триггер повторов.
|
||
* Таймер 1с обрабатывает до 8 задач, retry_at через 5с; выбранный M сохраняется до STORE.
|
||
* Выбор M: storage=yes в общей группе A/B, достижимый узел по node_id, кроме A/B и прежних назначений.
|
||
* S может одновременно быть M: local control проходит тот же обработчик без router-соединения к себе.
|
||
* SQLite и группы принадлежат ядру; instance должен пережить owner. Входные тела заимствованы до возврата.
|
||
* Из C++ этот внутренний C API включать внутри extern "C".
|
||
*/
|
||
#ifndef DM_MAILBOX_MEDIA_H
|
||
#define DM_MAILBOX_MEDIA_H
|
||
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
struct UTUN_INSTANCE;
|
||
struct dm_mb_media;
|
||
|
||
/* Создать таблицы/owner/таймер; inst с живыми SQLite/ua обязателен. Owner либо NULL при ошибке.
|
||
* Повторы задач после restart начинаются сразу. Единственным owner управляет dm_mailbox. */
|
||
struct dm_mb_media* dm_mailbox_media_create(struct UTUN_INSTANCE* inst);
|
||
/* Отменить таймер и освободить owner, сохранив задания/назначения в БД. NULL допустим. */
|
||
void dm_mailbox_media_destroy(struct dm_mb_media* media);
|
||
/* Вызвать в транзакции PUT после проверки роли S, получателя и подписи полного msg/len.
|
||
* 0=не file либо зарегистрирован точный SHA256 полного body для UUID, -1=ошибка/конфликт. Не отправляет STORE.
|
||
* media обязателен для file; commit/rollback принадлежит вызывающему. */
|
||
int dm_mailbox_media_register(struct dm_mb_media* media, uint64_t group, uint64_t recipient,
|
||
const uint8_t* msg, size_t len);
|
||
/* После проверки router-подписи и размера команды в dm_media: group/source — доверенные поля router.
|
||
* body заимствован на время вызова; RECEIPT=152, STORED=24, DELETE_ACK/EXPIRED=16, REJECT=17 байт.
|
||
* RECEIPT имеет формат dm_media.h; STORED=[UUID:16][expires:8], ACK/EXPIRED=[UUID:16], REJECT=[UUID:16][reason:1].
|
||
* STORED/REJECT/ACK относятся к сохранённому назначению M; RECEIPT проверяется отдельно подписью B.
|
||
* EXPIRED/REJECT атомарно освобождают назначение и сбрасывают текущий holder; ошибка откатывает оба изменения.
|
||
* Таймер завершает stored-назначение по expires даже при offline B/потерянном EXPIRED, также после restart.
|
||
* После квитанции повторяется DELETE до 16 неосвобождённым M за проход cleanup.
|
||
* Тело удаляется только при отсутствии неосвобождённых назначений; ошибка сканирования откладывает очистку.
|
||
* Для неподтверждённого STORE повтор запрашивает результат из custody/tombstone M; квитанция B не отменяется. */
|
||
void dm_mailbox_media_recv(struct dm_mb_media* media, uint64_t group, uint64_t source,
|
||
uint8_t cmd, const uint8_t* body, size_t len);
|
||
/* Проверить 152-байтовую квитанцию и попытаться отправить доступным S общей группы.
|
||
* За один вызов выбирается до 64 подходящих S на группу, включая локальный S; A/B исключаются.
|
||
* Это попытка отправки; durable повтор обеспечивает квитанция в dm_files/dm_media_jobs, а не сам вызов. */
|
||
void dm_mailbox_media_receipt(struct UTUN_INSTANCE* inst, const uint8_t* receipt);
|
||
|
||
#endif
|