|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
# DM: доставка сообщений и подготовка медиа |
|
|
|
|
# DM: доставка сообщений и файлов |
|
|
|
|
|
|
|
|
|
Личные беседы принадлежат `src/dm/`. Общие CHAT-группы используются для знакомства, |
|
|
|
|
проверки ролей и маршрутизации; группа не становится идентичностью беседы. |
|
|
|
|
@ -11,7 +11,9 @@
|
|
|
|
|
- Приём после проверки подписи и расшифровки, подтверждение только после commit. |
|
|
|
|
- Доставка с суперузла после возвращения получателя, независимо от отправителя. |
|
|
|
|
- Точное удаление промежуточного сообщения и сохранение квитанции для поздних повторов. |
|
|
|
|
- Шифрование медиа порциями в worker; сетевой жизненный цикл медиа пока не подключён. |
|
|
|
|
- Подготовка, шифрование, проверка и durable публикация медиа в рабочих потоках. |
|
|
|
|
- Прямая передача файлов либо custody на отдельном M, доставка после restart и подтверждённое удаление. |
|
|
|
|
- TTL и квота M; вложения и статусы доставки в Qt и Android. |
|
|
|
|
|
|
|
|
|
## Идентичность и шифрование |
|
|
|
|
|
|
|
|
|
@ -34,6 +36,8 @@ AES-256-CCM: nonce 13 байт, tag 16 байт. Максимальная пор
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Автор подписывает все поля до sig. conv связывает автора с получателем. |
|
|
|
|
Для `ct=file` перед подписью добавляется descriptor `[UUID:16][plaintext_size:8][SHA256(ciphertext):32]`. |
|
|
|
|
В зашифрованном теле находится имя файла; пути хранения строятся только из UUID. |
|
|
|
|
Размер plaintext сообщения ограничен 1024 байтами. seq — положительное int64. |
|
|
|
|
|
|
|
|
|
Медиа ciphertext — последовательность порций с отдельным tag каждой порции. |
|
|
|
|
@ -47,6 +51,9 @@ tags, точный размер и хеш; владелец публикует
|
|
|
|
|
- `dm_core`: беседы, история, outbox и подтверждение получателя. |
|
|
|
|
- `dm_mailbox`: промежуточные сообщения суперузла и квитанции. |
|
|
|
|
- `dm_crypto`: вывод ключей, nonce, CCM и файловые примитивы без БД/сети. |
|
|
|
|
- `dm_media`: файлы endpoint, загрузки и отдельная custody M. |
|
|
|
|
- `dm_mailbox_media`: durable задания S, выбор M и повтор удаления до DELETE_ACK. |
|
|
|
|
- `file_transfer`: подписанная передача байтов, backpressure и отдельный CM handle каждой операции. |
|
|
|
|
|
|
|
|
|
```text |
|
|
|
|
dm_conversations(conv_id, peer_node_id, peer_x25519, peer_ed25519, peer_name, |
|
|
|
|
@ -107,11 +114,12 @@ dm_mail_receipts содержит только служебные квитанц
|
|
|
|
|
диапазонные ACK не поддерживаются: это devel, совместимость не сохраняется. |
|
|
|
|
TTL текстовых сообщений не введён; недельный TTL из pm.txt относится к медиа. |
|
|
|
|
|
|
|
|
|
## Следующая интеграция медиа по pm.txt |
|
|
|
|
## Доставка медиа по pm.txt |
|
|
|
|
|
|
|
|
|
1. Общая передача байтов: явные peer/group/file/size, backpressure и CM handle |
|
|
|
|
на всю активную операцию. Владение handle сохраняется после DOWN/TIMEOUT. |
|
|
|
|
Передавать через собственный svc router; conn_mgr_send использует управляющий сервис CM. |
|
|
|
|
Используется `ETCP_RT_ID_FILE_TRANSFER=0x37`. Один callback читает/отправляет |
|
|
|
|
не более 8 КиБ, продолжение через `call_soon`; inflight ограничен 16 пакетами. |
|
|
|
|
2. Отдельный owner dm_media: подготовка ciphertext, manifest, отправка/скачивание, |
|
|
|
|
временные файлы, TTL и лимит хранения. Каталоги dm_media/ и dm_pending/ вне |
|
|
|
|
группового обхода очистки orphan-файлов; групповые объявления HAVE_BLOCK не используются. |
|
|
|
|
@ -120,10 +128,26 @@ TTL текстовых сообщений не введён; недельный
|
|
|
|
|
4. Текстовая квитанция и квитанция медиа независимы. Получатель подтверждает медиа |
|
|
|
|
после проверки, публикации файла и commit. S хранит задачу удаления у M до DELETE_ACK; |
|
|
|
|
поздний STORED не возрождает завершённую доставку. |
|
|
|
|
5. TTL медиа по умолчанию 7 дней, конфиг на M. Новая custody отклоняется при |
|
|
|
|
5. TTL медиа `dm_media_ttl_sec` по умолчанию 604800 с; квота `dm_media_storage_mb` |
|
|
|
|
по умолчанию 1024 МиБ. Настройки на M. Новая custody отклоняется при |
|
|
|
|
недостатке квоты; уже подтверждённые копии не вытесняются молча раньше срока. |
|
|
|
|
6. Stop снимает новые задачи, ждёт media_async с живыми owner-контекстами, затем |
|
|
|
|
закрывает операции/handles до уничтожения групп. |
|
|
|
|
6. Stop снимает новые задачи и закрывает transfer/CM handles, затем ждёт |
|
|
|
|
media_async с живыми owner-контекстами. Группы уничтожаются после owners. |
|
|
|
|
|
|
|
|
|
Control `ETCP_RT_ID_DM_MEDIA=0x38`: OFFER, STORE, STORED, RECEIPT, DELETE, |
|
|
|
|
DELETE_ACK, EXPIRED, REJECT; точные форматы заданы в `dm_media.h` и реализациях owners. |
|
|
|
|
Подпись router обязательна. Media receipt содержит `DMFILE01`, conv, seq, author, |
|
|
|
|
recipient, UUID и SHA256 полного подписанного сообщения; B подписывает первые 88 байт. |
|
|
|
|
Отдельные таблицы `dm_files`, `dm_custody`, `dm_custody_done`, `dm_media_jobs`, |
|
|
|
|
`dm_media_holders` сохраняют состояния и tombstones. Все выданные grants M |
|
|
|
|
учитываются при удалении; повторный STORE не продлевает TTL. |
|
|
|
|
|
|
|
|
|
Qt и Android получают историю через события ядра: 41 — conv + JSON сообщений, |
|
|
|
|
45 — JSON бесед. Снимки ограничены 200 записями. Отправка вложения вызывает |
|
|
|
|
`dm_send_file` в uasync; длительная обработка выполняется в `media_async`. |
|
|
|
|
Android копирует выбранный URI и сохраняет полученный файл через `Dispatchers.IO`; |
|
|
|
|
Qt сохраняет файл из контекстного меню в отдельном потоке. Фото и видео пока |
|
|
|
|
отправляются как оригинальные файловые вложения, без канального транскодирования. |
|
|
|
|
|
|
|
|
|
## Проверки |
|
|
|
|
|
|
|
|
|
@ -137,5 +161,10 @@ ACK чужого тела, отказ mailbox без роли, точное уд
|
|
|
|
|
Первый сценарий передаёт 40 offline-сообщений (больше порции pump) и перезапускает источник с pending outbox; второй перезапускает |
|
|
|
|
суперузел и доставляет первое сообщение при выключенном источнике. |
|
|
|
|
|
|
|
|
|
Сетевые тесты CM-передачи медиа, media custody/TTL/quota и независимых квитанций |
|
|
|
|
нужно добавить вместе с сетевой интеграцией медиа. |
|
|
|
|
`test_dm_media`: реальные A/B/S/M с раздельными ролями supernode и storage; |
|
|
|
|
прямая передача, custody, restart S/M при выключенном A, точный файл на B, |
|
|
|
|
удаление копии и тела S, поздние STORE/STORED, TTL, отказ по квоте, неверная квитанция, |
|
|
|
|
SQL rollback регистрации, состояния JSON и отмена операции с CM handle. |
|
|
|
|
|
|
|
|
|
`test_dm_worker`: повторное шифрование 8 МиБ не менее 0,5 с и проверка расшифровки; |
|
|
|
|
work выполняется вне uasync, done в его потоке, heartbeat продолжает работать. |
|
|
|
|
|