124 lines
8.8 KiB
Markdown
124 lines
8.8 KiB
Markdown
|
# Обзор
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## Терминология
|
|||
|
|
|||
|
Здесь перечислены используемые в данной документации термины, значение которых может быть не очевидно и/или не соответствует тому, которое подразумевается обычно.
|
|||
|
|
|||
|
### Узел
|
|||
|
|
|||
|
Любая машина, способная выполнять коммуникацию по протоколу Stadium. Обычно используется в контексте коммуникации двух машин одного ранга или когда ранг не имеет значения.
|
|||
|
|
|||
|
### Сервер
|
|||
|
|
|||
|
Выполняющий роль сервера _узел_ в многоранговой сети.
|
|||
|
|
|||
|
### Клиент
|
|||
|
|
|||
|
Выполняющий роль клиента _узел_ в многоранговой сети.
|
|||
|
|
|||
|
### Подписанное соединение/сессия
|
|||
|
|
|||
|
Соединение между двумя _узлами_, все _события_ в котором подписаны с помощью оговорённого ассиметричного алгоритма и приватного ключа отправителя.
|
|||
|
|
|||
|
### Шифрованное соединение/сессия
|
|||
|
|
|||
|
Соединение между двумя _узлами_, все _события_ в котором шифруется с помощью оговорённого симметричного алгоритма и ключа. Требует _подписанное соединение_ для установки.
|
|||
|
|
|||
|
### Событие
|
|||
|
|
|||
|
Структура данных, обладающая конкретными семантическими свойствами в зависимости от типа и содержащая дополнительные поля, требуемые для верного отображения и интерпретации самой структуры. Проще говоря - то, чем обмениваются и что обрабатывают _узлы_ во время коммуникации между собой.
|
|||
|
|
|||
|
### Шумовое событие
|
|||
|
|
|||
|
_Событие_ предопределённой категории, имеющее случайно-сгенерированные поля.
|
|||
|
|
|||
|
### LBM
|
|||
|
|
|||
|
Аббревиатура наименования способа форматирования данных, используемого для полезной нагрузки _события_, которая расшифровывается как "Linear Binary Map". Подробнее - в [LBM.md](LBM.md).
|
|||
|
|
|||
|
### Шумовые данные
|
|||
|
|
|||
|
Случайно-сгенерированные данные, помещённые в ячейку полезной нагрузки _события_.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## Пример коммуникации двух узлов
|
|||
|
|
|||
|
Допустим, что у нас есть два неизвестных друг-другу _узла_ - `p1` и `p2`. Тогда полная коммуникация по шагам (от подключения неизвестного для `p2` _узла_ - до "правильного" уничтожения сессии и закрытия соединения) будет выглядеть так: <!--TODO: предстоит переделать, ввиду предстоящих нововведений-->
|
|||
|
|
|||
|
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
|
|||
|
```
|
|||
|
|
|||
|
\* - _стоит уточнить, что в реальных сценариях использования этот публичный ключ должен быть уже известен <!--(см. `TODO`)-->, либо коммуникация должна производиться через транспорт, гарантирующий достоверность передаваемых данных._
|
|||
|
|
|||
|
\*\* - _это может быть публичный ключ подписи `p1`, а может быть и сгенерированный отдельно, в зависимости от сценария использования._
|
|||
|
|
|||
|
\*\*\* - _установка шифрованного соединения полностью опциональна и его отсутствие не накладывает каких-либо ограничений, в рамках этой версии протокола. Формат события в таком соединении см. в [Events.md](Events.md)._
|