# Потоки **Поток** представляет из себя канал обмена _событиями_ в определённой конфигурации. _Узлы_ должны обрабатывать _события_ единообразно, вне зависимости от того, через какой _поток_ они передаются. ## Stream ID Каждый _поток_ имеет пару собственных уникальных идентификаторов: "Stream ID", "SID". Они используются для определения принадлежности _события_ к существующим _потокам_. Для увеличения энтропии, с целью исключения анализа траффика, SID представляет из себя нефиксированное значение, уникальное для каждого _события_. Каждый из двух _узлов_ в _соединении_ имеет собственный SID. Допустим, что есть два _узла_: `pc`, который подключается, и `ps`, к которому подключается `pc`. Тогда пусть SID, используемый _узлом_ `pc` будет называться `sidc`, а `ps` - `sids`. Для того, чтобы установить новое _соединение_, _узлы_ должны проделать следующее: 1. `pc` генерирует стартовое значение `sidc` и отправляет его _узлу_ `ps` вместе с алгоритмами симметричного шифрования и хэширования для обработки `sids`, а также симметричный ключ соответствующего алгоритму размера. 2. `ps` принимает данные и отвечает _узлу_ `pc` стартовым значением `sids`, алгоритмами шифрования и хэширования `sidc`, а также симметричный ключ соответствующего алгоритму размера. При этом, `ps` должен иметь единую конфигурацию алгоритмов симметричного шифрования, хэш-функции и используемый ключ для обработки SID всех _потоков_. Перед использованием в отправляемом _событии_, _узел_ должен обработать прежнее значение SID, а именно: зашифровать его с использованием избранного при установке _соединения_ алгоритма симметричного шифрования и ключа, а затем вычислить хэш. Если размер выходных данных хэш-функции больше размера SID, то эти данные поблочно XOR'ятся сами с собой. В реализации это может выглядеть вот так: ```C // size_t arr_sz: размер вывода хэш-функции // char *arr: вывод хэш-функции // uint32_t sid: прежний SID sid = *(uint32_t*)arr; for (size_t i = 1; i < arr_sz / 4; ++i) sid = sid ^ ((uint32_t*)arr)[i]; ``` Если любой из _узлов_ обнаруживает ложное значение SID в полученном _событии_, то он обязан разорвать _соединение_.