stadium-proto/OVERVIEW.md
2023-06-30 00:54:02 +03:00

76 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Спецификация Marafon Protocol (MFP) v1.0
Marafon Protocol это протокол для одноимённого полнофункционального мессенджера, работающего поверх TCP. Основной фокус при работе над оным идёт на:
- Снижение оверхэдов, по сравнению с классическими решениями (Matrix, Discord, WhatsApp, пр.).
- Устойчивость к цензуре.
- Федеративность.
- Поддержка сквозного шифрования.
- Совместимость со всеми мажорными оверлейными сетями (Tor, I2P и yggdrasil).
- Расширяемость.
<!-- TODO: какое шифрование, какие алгоритмы, etc. -->
## Пакеты
Существует три уровня категорий пакетов:
1. **Надкатегория:** Client2Server, Server2Client, Server2Server.
2. **Категория:** Authentication, User, Message, т.д.
3. **Подкатегория:** Login, Create, Delete, т.д.
Надкатегория никак не указывается в пакете и зависит от контекста. Он-же определяет структуру некоторых пакетов, которая может менятся в конкретных случаях. Остальные две занимают по одному байту соответственно.
Пакеты всех категорий, кроме явно оговорённых или принадлежащих к надкатегории Server2Client, содержат идентификатор серверной сессии, являющийся четырёхбайтным числом без знака.
Пакеты всех категорий из надкатегории Client2Server, кроме явно оговорённых, содержат хэш полезной нагрузки, зашифрованный с помощью закрытого ключа подписи клиента.
Данные (AKA "полезная нагрузка") являются расположенными последовательно парами "ключ-значение" и могут быть расположены относительно друг-друга в произвольном порядке. Они следующий формат:
`[2b: key][2b: data length][>0 b: data]`
Исходя из всего вышеописанного, итоговая примерная структура пакета выглядит следующим образом:
`[1b: category][1b: subcategory][4b: server session][>0 b: payload]`
Размер пакета определяется ответом сервера на этапе обмена характеристиками, но не может быть больше, чем 65535 байт. До этого этапа размер пакета составляет 512 байт.
Магическим числом протокола является следующая последовательность байт:
```
HEX: 0x4d 0x61 0x72 0x61 0x66 0x6f 0x6e 0x50
DEC: 77 97 114 97 102 111 110 80
```
Что соответствует строке "MarafonP" в кодировке ASCII.
## Сессии, аутентификация и соединение
После успешной установки защищённого TLS соединения начинается этап обмена характеристиками. Клиент отправляет некоторые метаданные, в числе которых:
- Магическое число: 8 байт
- Версия протокола: 4 байта
- ID серверной сессии: 4 байта (0 если нет; на случай, если соединение надо восстановить, а не создать с нуля)
На что сервер отвечает своим набором метаданных:
- Магическое число: 8 байт
- Интервал обновления: 2 байта (x * 0.01 = интервал в секундах)
<!-- TODO: надо ещё обдумать, какими данными обмениваться клиентосерверу -->
Если при обмене метаданными клиент или сервер обнаруживают несоответствие магических чисел, то они разрывают соединение. Если сервер не поддерживает указанную клиентом версию протокола - он отвечает ошибкой и разрывает соединение. Если при попытке восстановить соединение клиентом, ID серверной сессии не существует в списке недавно-разорванных, то он отвечает ошибкой и разрывает соединение.
При успешной регистрации учётной записи, клиент генерирует пару ключей (открытый-закрытый) в качестве подписи, после чего открытый ключ отправляется серверу и тот сохраняет его.
При успешном входе в учётную запись, сервер генерирует `uint32_t`, являющийся идентификатором серверной сессии. Клиент обязан хранить его и прикреплять к каждому пакету (кроме особо-оговорённых случаев) до момента отключения от сервера.
Если при проверке хэша полезной нагрузки пакета обнаруживается, что подпись неверна - сервер отвечает ошибкой, соединение разрывается, а администратор сервера и владелец учётной записи уведомляются об инцеденте.
Если при проверке ID серверной сессии обнаруживается несоответствие - сервер отвечает ошибкой, соединение разрывается.
Каждые n секунд клиент отправляет запрос на обновление статуса аккаунта. Если спустя указанное на этапе обмена характеристиками время нет ни одного пакета от клиента - сервер разрывает соединение.