# Обзор ## Терминология Здесь перечислены используемые в данной документации термины, значение которых может быть не очевидно и/или не соответствует тому, которое подразумевается обычно. ### Узел Любая машина, способная выполнять коммуникацию по протоколу Stadium. Обычно используется в контексте коммуникации двух машин одного ранга или когда ранг не имеет значения. ### Сервер Выполняющий роль сервера _узел_ в многоранговой сети. ### Клиент Выполняющий роль клиента _узел_ в многоранговой сети. ### Подписанное соединение/сессия Соединение между двумя _узлами_, все _события_ в котором подписаны с помощью оговорённого ассиметричного алгоритма и приватного ключа отправителя. ### Шифрованное соединение/сессия Соединение между двумя _узлами_, все _события_ в котором шифруется с помощью оговорённого симметричного алгоритма и ключа. Требует _подписанное соединение_ для установки. ### Событие Структура данных, обладающая конкретными семантическими свойствами в зависимости от типа и содержащая дополнительные поля, требуемые для верного отображения и интерпретации самой структуры. Проще говоря - то, чем обмениваются и что обрабатывают _узлы_ во время коммуникации между собой. ### Шумовое событие _Событие_ предопределённой категории, имеющее случайно-сгенерированные поля. ### LBM Аббревиатура наименования способа форматирования данных, используемого для полезной нагрузки _события_, которая расшифровывается как "Linear Binary Map". Подробнее - в [LBM.md](LBM.md). ### Шумовые данные Случайно-сгенерированные данные, помещённые в ячейку полезной нагрузки _события_. ## Пример коммуникации двух узлов Допустим, что у нас есть два неизвестных друг-другу _узла_ - `p1` и `p2`. Тогда полная коммуникация по шагам (от подключения неизвестного для `p2` _узла_ - до "правильного" уничтожения сессии и закрытия соединения) будет выглядеть так: 1. `p1` подключается с помощью соответствующего транспорта к `p2` 2. `p1` запрашивает рукопожатие с какими-то параметрами подключения 3. `p2` отвечает принятием со своей частью параметров подключения 4. `p1` запрашивает публичный ключ подписи у `p2`\* 5. `p2` отвечает своим публичным ключом и данными об использующемся алгоритме 6. `p1` сохраняет публичный ключ сервера в своём хранилище 7. `p1` отправляет _событие_ с запросом установки публичного ключа сессионной подписи, подписанное с помощью публичного ключа `p2`\*\* 8. `p2` принимает запрос и устанавливает полученный ключ в качестве сессионного для подключения `p1`, если подпись валидна 9. `p2` отвечает _событием_ с кодом успешности операции. С этого момента установлено _подписанное соединение_, т.е. узлы **обязаны** подписывать каждое _событие_ и отклонять любые неподписанные/с ложной подписью 10. `p1` отправляет _событие_ с запросом _шифрованного соединения_, симметричным ключом, зашифрованным с помощью публичного ключа сервера, и используемым алгоритмом шифрования\*\*\* 11. `p2` принимает запрос и устанавливает текущий симметричный ключ сессии 12. `p2` отвечает _событием_ с кодом успешности операции. С этого момента установлено _шифрованное соединение_, т.е. узлы **должны** шифровать _события_ с использованием обозначенного ключа 13. `p1` отправляет зашифрованное _событие_ с запросом какого-то объекта 14. `p2` отвечает зашифрованным _событием_, содержащее этот объект 15. `p1` отправляет _событие_ с сообщением о намерении уничтожить сессию и ждёт в течении n времени, по истечению которого может разорвать соединение "насильно" 16. `p2` принимает запрос и прекращает любой параллельный обмен данными 17. `p2` отвечает _событием_ с кодом успешности операции 18. `p2` закрывает соединение И в виде схемы: ``` Handshake: [p1] --------[transport connect]------> [p2] [p1] --------[handshake request]------> [p2] [p1] <-------[handshake accept]-------- [p2] Get p2's public key: [p1] ----[request public sign key]----> [p2] [p1] <-[public key and crypto params]-- [p2] [p1]: saves p2's public key at local storage Make signed connection: [p1]: sign event [p1] --------[set session sign]-------> [p2] [p2]: check event signature [p2]: associates p1's public key with this connection [p2]: sign event [p1] <--------[status code OK]--------- [p2] [p1]: check event signature Make encrypted connection: [p1]: sign event [p1] ---[set session symmetric key]---> [p2] [p2]: check event signature [p2]: associates symmetric key with this connection [p2]: sign and encrypt event [p1] <--------[status code OK]--------- [p2] [p1]: decrypt and check event signature Request some object: [p1]: sign and encrypt event [p1] ------[request some object]------> [p2] [p2]: decrypt and check event signature [p2]: sign and encrypt event [p1] <-------[some object data]-------- [p2] [p1]: decrypt and check event signature Close session: [p1]: sign and encrypt event [p1] ---------[close session]---------> [p2] [p2]: decrypt and check event signature [p2]: sign and encrypt event [p1] <--------[status code OK]--------- [p2] [p2]: close connection [p1]: decrypt and check event signature ``` \* - _стоит уточнить, что в реальных сценариях использования этот публичный ключ должен быть уже известен , либо коммуникация должна производиться через транспорт, гарантирующий достоверность передаваемых данных._ \*\* - _это может быть публичный ключ подписи `p1`, а может быть и сгенерированный отдельно, в зависимости от сценария использования._ \*\*\* - _установка шифрованного соединения полностью опциональна и его отсутствие не накладывает каких-либо ограничений, в рамках этой версии протокола. Формат события в таком соединении см. в [Events.md](Events.md)._