stadium-proto/Overview.md

6.8 KiB
Raw Blame History

Обзор

Терминология

Здесь перечислены используемые в данной спецификации термины, значение которых может быть не очевидно и/или не соответствует тому, которое подразумевается обычно.

Узел

Любая машина, способная выполнять коммуникацию по протоколу Stadium. Обычно используется в контексте коммуникации двух машин одного ранга или когда ранг не имеет значения.

Сервер

Выполняющий роль сервера узел в многоранговой сети.

Клиент

Выполняющий роль клиента узел в многоранговой сети.

Соединение/поток

Канал обмена событиями между двумя узлами, имеющий свой идентификатор (Stream ID/SID, см. Streams.md) и набор настроек.

Шифрованное соединение/поток

Соединение между двумя узлами, все события в котором шифруются с помощью оговорённого симметричного алгоритма и ключа, а также подписываются с помощью приватного ключа отправителя.

Сессия

То, что устанавливается при создании первого соединения между двумя узлами, с чем ассоциированы конкретные потоки и прочие параметры.

Событие

Структура данных, обладающая конкретными семантическими свойствами в зависимости от типа и содержащая дополнительные поля, требуемые для верного отображения и интерпретации самой структуры. Проще говоря - то, чем обмениваются и что обрабатывают узлы во время коммуникации между собой.

Шумовое событие

Событие предопределённой категории, имеющее случайно-сгенерированные поля.

LBM

Аббревиатура наименования способа форматирования (сериализации) данных, используемого для полезной нагрузки события, которая расшифровывается как "Linear Binary Map". Подробнее - в LBM.md.

Шумовые данные

Случайно-сгенерированные данные, помещённые в специализированную ячейку полезной нагрузки события.

Пример коммуникации двух узлов

Допустим, что у нас есть два неизвестных* друг-другу узла - p1 и p2. Тогда полная коммуникация по шагам (от подключения неизвестного для p2 узла - до "правильного" уничтожения сессии и закрытия соединения) будет выглядеть так:

  1. p1 запрашивает открытое (нешифрованное) рукопожатие с избранными параметрами соединения у p2
  2. p2 отвечает p1 согласием со своей частью параметров
  3. p1 запрашивает публичный ключ подписи у p2
  4. p2 передаёт свой публичный ключ, вместе с используемым алгоритмом
  5. p1 сохраняет полученный публичный ключ и разрывает** соединение и заново устанавливает его, путём отправки p2 запроса шифрованного хэндшейка
  6. p2 отвечает согласием со своей частью параметров подключения
  7. p1 отправляет зашифрованное событие с запросом какого-то объекта
  8. p2 отвечает зашифрованным событием, содержащее статус-код или этот объект
  9. p1 отправляет событие с сообщением о намерении уничтожить сессию и ждёт в течении n времени, по истечению которого может разорвать соединение "насильно"
  10. p2 принимает запрос и прекращает любой параллельный обмен данными
  11. p2 отвечает событием с кодом успешности операции
  12. p2 закрывает соединение

И в виде схемы:

Requesting p2's public key:
[p1] ------[raw handshake request]----> [p2]
[p1] <-----[raw handshake accept]------ [p2]
[p1] ----[request public sign key]----> [p2]
[p1] <-[public key and crypto params]-- [p2]
[p1] ---------[close session]---------> [p2]
[p1] <--------[status code OK]--------- [p2]

Reconnecting in encrypted way and requesting object:
[p1] ---[encrypted handshake request]-> [p2]
[p1] <--[encrypted handshake accept]--- [p2]
[p1] ------[request some object]------> [p2]
[p1] <-[some object data/status code]-- [p2]
[p1] ---------[close session]---------> [p2]
[p1] <--------[status code OK]--------- [p2]

* - стоит уточнить, что в реальных сценариях использования публичный ключ целевого узла скорее всего уже известен, либо коммуникация должна производиться через транспорт, гарантирующий достоверность передаваемых данных. p1 может узнать о существовании таковых, путём отправки события специального типа. В данном примере сей шаг опущен.

** - "разрыв" соединения предполагает обмен между узлами событиями с информацией о завершении сессии; в данном пункте эти шаги опущены, но упомянуты ниже.