Предупреждение - Устарело - Не поддерживается - Используйте SAMv3
Ниже описана версия 2 простого клиентского протокола для взаимодействия с I2P.
SAM V2 был представлен в релизе I2P 0.6.1.31. Значительные отличия от SAM V1 отмечены “***”. Альтернативы: SAM V1 , SAM V3 , BOB .
Изменения версии 2
SAM V2 был введен в релизе I2P 0.6.1.31. По сравнению с версией 1, SAM v2 предоставляет способ управления несколькими сокетами на одном I2P destination параллельно, то есть клиенту не нужно ждать успешной отправки данных через один сокет перед отправкой данных через другой сокет. Все данные проходят через один и тот же сокет клиент<–>SAM. Для множественных сокетов смотрите SAMv3 .
Изменения I2P 0.9.14
Сообщаемая версия остается “2.0”.
- DEST GENERATE теперь поддерживает параметр SIGNATURE_TYPE.
- Параметр MIN в HELLO VERSION теперь является необязательным.
- Параметры MIN и MAX в HELLO VERSION теперь поддерживают однозначные версии, такие как “3”.
Протокол версии 2
Клиентское приложение взаимодействует с мостом SAM, который обрабатывает всю функциональность I2P (используя streaming lib для виртуальных потоков или I2CP напрямую для асинхронных сообщений).
Вся коммуникация между клиентом и SAM bridge происходит в незашифрованном и неаутентифицированном виде через единственный TCP сокет. Доступ к SAM bridge должен быть защищен с помощью брандмауэров или другими средствами (возможно, bridge может иметь списки контроля доступа для IP-адресов, от которых принимаются соединения).
Все эти SAM сообщения отправляются в одной строке в виде обычного ASCII, завершаясь символом новой строки (\n). Форматирование, показанное ниже, предназначено лишь для удобочитаемости, и хотя первые два слова в каждом сообщении должны оставаться в своём определённом порядке, порядок пар ключ=значение может изменяться (например, “ONE TWO A=B C=D” или “ONE TWO C=D A=B” являются одинаково корректными конструкциями). Кроме того, протокол чувствителен к регистру.
SAM сообщения интерпретируются в UTF-8. Пары Ключ=значение должны быть разделены одним пробелом. Значения могут быть заключены в двойные кавычки, если они содержат пробелы, например key=“long value text”. Механизм экранирования отсутствует.
Связь может принимать три различные формы:
- Виртуальные потоки
- Датаграммы с возможностью ответа (сообщения с полем FROM)
- Анонимные датаграммы (необработанные анонимные сообщения)
Рукопожатие SAM соединения
Никакое SAM-взаимодействие не может происходить до тех пор, пока клиент и мост не согласуют версию протокола, что выполняется отправкой клиентом сообщения HELLO и отправкой мостом ответа HELLO REPLY:
HELLO VERSION MIN=$min MAX=$max
и
*** HELLO REPLY RESULT=$result VERSION=2.0
Начиная с I2P 0.9.14, параметр MIN является необязательным. Параметр MAX должен быть указан и быть больше или равен “2” и меньше “3” для использования версии 2.
Значение RESULT может быть одним из:
OKNOVERSION
SAM-сессии
SAM сессия создается клиентом путем открытия сокета к SAM мосту, выполнения рукопожатия и отправки сообщения SESSION CREATE, и сессия завершается при отключении сокета.
Каждый I2P Destination может использоваться только для одной SAM-сессии одновременно и может использовать только одну из этих форм (сообщения, полученные через другие формы, отбрасываются).
Сообщение SESSION CREATE, отправляемое клиентом мосту, выглядит следующим образом:
SESSION CREATE
STYLE={STREAM,DATAGRAM,RAW}
DESTINATION={$name,TRANSIENT}
[DIRECTION={BOTH,RECEIVE,CREATE}]
[option=value]*
DESTINATION указывает, какое назначение должно использоваться для отправки и получения сообщений/потоков. Если задано $name, мост SAM просматривает своё локальное хранилище (файл sam.keys) для поиска связанного назначения (и приватного ключа). Если не существует ассоциации, соответствующей этому имени, создаётся новая. Если назначение указано как TRANSIENT, всегда создаётся новое.
Обратите внимание, что DESTINATION является идентификатором, а не данными в кодировке Base 64. Для указания Destination необходимо использовать SAM V3 .
DIRECTION может быть указан только для STREAM сессий, сообщая мосту, что клиент будет либо создавать, либо принимать потоки, либо и то, и другое. Если это не указано, будет предполагаться BOTH. Попытка создать исходящий поток при DIRECTION=RECEIVE должна привести к ошибке, а входящие потоки при DIRECTION=CREATE будут игнорироваться.
Дополнительные указанные параметры должны передаваться в конфигурацию I2P-сессии, если они не обрабатываются SAM bridge (например, “tunnels.depthInbound=0”). Эти параметры описаны ниже.
SAM мост сам по себе уже должен быть настроен с указанием того, через какой router он должен взаимодействовать по I2P (хотя при необходимости может быть способ переопределить это, например i2cp.tcp.host=localhost и i2cp.tcp.port=7654).
После получения сообщения создания сессии, SAM мост ответит сообщением статуса сессии следующим образом:
SESSION STATUS
RESULT=$result
DESTINATION={$name,TRANSIENT}
[MESSAGE=...]
Значение RESULT может быть одним из следующих:
OKDUPLICATED_DESTI2P_ERRORINVALID_KEY
Если это не OK, MESSAGE должно содержать понятную для человека информацию о том, почему сессия не может быть создана.
Обратите внимание, что не выдается предупреждение, если $name не найден и вместо этого создается временное назначение. Обратите внимание, что фактическое временное назначение в формате base 64 не выводится в ответе; это $name или TRANSIENT, как указано в SESSION CREATE. Если вам нужны эти функции, вы должны использовать SAM V3 .
Виртуальные потоки SAM
Виртуальные потоки гарантированно отправляются надежно и в порядке очередности, с уведомлениями об успехе или неудаче, как только они становятся доступными.
После установления сессии с STYLE=STREAM, как клиент, так и SAM мост могут асинхронно отправлять различные сообщения туда и обратно для управления потоками, как указано ниже:
STREAM CONNECT
ID=$id
DESTINATION=$destination
Это устанавливает новое виртуальное соединение от локального получателя к указанному узлу, помечая его уникальным ID в области сессии. Уникальный ID представляет собой ASCII число по основанию 10 от 1 до (2^31-1).
$destination представляет собой base 64 кодировку Destination , которая составляет 516 или более символов base 64 (387 или более байт в двоичном формате), в зависимости от типа подписи.
SAM bridge отвечает на это сообщением о статусе потока:
STREAM STATUS
RESULT=$result
ID=$id
[MESSAGE=...]
Значение RESULT может быть одним из:
OKCANT_REACH_PEERI2P_ERRORINVALID_KEYTIMEOUT
Если RESULT равен OK, указанное назначение активно и авторизовало соединение; если соединение было невозможно (таймаут и т.д.), RESULT будет содержать соответствующее значение ошибки (сопровождаемое необязательным человеко-читаемым MESSAGE).
На принимающей стороне SAM bridge просто уведомляет клиента следующим образом:
STREAM CONNECTED
DESTINATION=$destination
ID=$id
Это сообщает клиенту, что указанное назначение создало с ним виртуальное соединение. Следующий поток данных будет отмечен данным уникальным ID, который представляет собой ASCII целое число в десятичной системе счисления от -1 до -(2^31-1).
$destination - это base64-представление Destination , которое содержит 516 или более символов base64 (387 или более байт в двоичном формате), в зависимости от типа подписи.
Когда клиент хочет отправить данные через виртуальное соединение, он делает это следующим образом:
STREAM SEND
ID=$id
SIZE=$numBytes\n[$numBytes of data]
Это запрашивает у SAM bridge добавить указанные данные в буфер, отправляемый узлу через виртуальное соединение. Размер отправки $numBytes указывает, сколько 8-битных байт включено после символа новой строки, что может быть от 1 до 32768 (32КБ).
*** SAM мост немедленно отвечает:
*** STREAM SEND
*** ID=$id
*** RESULT=$result
*** STATE=$bufferState
*** где $bufferState может быть:
BUFFER_FULL- буфер SAM содержит 32 КБ или более данных для отправки, и последующие запросы SEND будут завершаться неудачейREADY- буфер SAM не заполнен, и следующий запрос SEND гарантированно будет успешным
*** и $result является одним из:
OK- данные успешно буферизованыFAILED- буфер заполнен, данные не буферизованы
*** Если SAM bridge ответил с BUFFER_FULL, он отправит другое сообщение, как только его буфер снова станет доступным:
*** STREAM READY_TO_SEND ID=$id
*** Когда результат OK, SAM bridge затем будет делать всё возможное для доставки сообщения максимально быстро и эффективно, возможно буферизуя несколько SEND сообщений вместе. Если возникает ошибка при доставке данных или если удаленная сторона закрывает соединение, SAM bridge сообщит клиенту:
STREAM CLOSED
RESULT=$result
ID=$id
[MESSAGE=...]
Значение RESULT может быть одним из:
OKCANT_REACH_PEERI2P_ERRORPEER_NOT_FOUNDTIMEOUT
Если соединение было корректно закрыто другим узлом, $result устанавливается в OK. Если $result не равно OK, MESSAGE может содержать описательное сообщение, такое как “peer unreachable” и т.д. Когда клиент хочет закрыть соединение, он отправляет SAM мосту сообщение о закрытии:
STREAM CLOSE
ID=$id
Затем bridge очищает то, что необходимо, и отбрасывает этот ID - больше никаких сообщений не может быть отправлено или получено через него.
Для другой стороны коммуникации, когда узел отправил некоторые данные и они доступны для клиента, мост SAM незамедлительно доставит их:
STREAM RECEIVED
ID=$id
SIZE=$numBytes\n[$numBytes of data]
*** Однако с SAM версии 2.0 клиент должен сначала сообщить SAM bridge, сколько входящих данных разрешено для всей сессии, отправив сообщение:
*** STREAM RECEIVE
*** ID=$id
*** LIMIT=$limit\n
*** где $limit может быть:
NONE- SAM мост будет продолжать прослушивание и доставлять входящие данные (такое же поведение, как в версии 1.0)- целое число (меньше 2^64) - количество принятых байт, после которого SAM мост прекратит прослушивание входящего потока. Когда клиент готов принять больше байт из потока, он должен снова отправить такое сообщение с большим значением $limit.
*** Клиент должен отправлять такие сообщения STREAM RECEIVE после того, как соединение с узлом установлено, т.е. после того, как клиент получил “STREAM CONNECTED” или “STREAM STATUS RESULT=OK” от SAM моста.
Все потоки неявно закрываются при разрыве соединения между SAM мостом и клиентом.
SAM Repliable Datagrams
Хотя I2P изначально не содержит адрес FROM, для удобства использования предоставляется дополнительный уровень в виде repliable datagrams - неупорядоченных и ненадежных сообщений размером до 31744 байт, которые включают адрес FROM (оставляя до 1КБ для материала заголовка). Этот адрес FROM аутентифицируется внутренне SAMv3 (используя ключ подписи destination для проверки источника) и включает защиту от повторных атак.
Минимальный размер составляет 1. Для обеспечения наилучшей надежности доставки рекомендуемый максимальный размер составляет приблизительно 11 КБ.
После установления SAM-сессии со STYLE=DATAGRAM клиент может отправить SAM-мосту:
DATAGRAM SEND
DESTINATION=$destination
SIZE=$numBytes\n[$numBytes of data]
Когда датаграмма поступает, мост доставляет её клиенту через:
DATAGRAM RECEIVED
DESTINATION=$destination
SIZE=$numBytes\n[$numBytes of data]
$destination — это base 64 представление Destination , которое содержит 516 или более символов base 64 (387 или более байт в двоичном формате), в зависимости от типа подписи.
SAM bridge никогда не предоставляет клиенту заголовки аутентификации или другие поля, только данные, которые предоставил отправитель. Это продолжается до тех пор, пока сессия не будет закрыта (когда клиент разрывает соединение).
SAM анонимные датаграммы
Выжимая максимум из пропускной способности I2P, SAM позволяет клиентам отправлять и получать анонимные датаграммы, оставляя аутентификацию и информацию об ответах на усмотрение самих клиентов. Эти датаграммы являются ненадежными и неупорядоченными, и могут достигать 32768 байт.
Минимальный размер составляет 1. Для наилучшей надёжности доставки рекомендуемый максимальный размер составляет приблизительно 11 КБ.
После установки SAM-сессии с STYLE=RAW, клиент может отправить SAM-мосту:
RAW SEND
DESTINATION=$destination
SIZE=$numBytes\n[$numBytes of data]
$destination — это base 64 представление Destination , которое состоит из 516 или более символов base 64 (387 или более байт в двоичном формате), в зависимости от типа подписи.
Когда поступает необработанная датаграмма, мост доставляет её клиенту через:
RAW RECEIVED
SIZE=$numBytes\n[$numBytes of data]
Функциональность утилиты SAM
Следующее сообщение может использоваться клиентом для запроса разрешения имен к мосту SAM:
NAMING LOOKUP
NAME=$name
на что отвечает
NAMING REPLY
RESULT=$result
NAME=$name
[VALUE=$destination]
[MESSAGE=$message]
Значение RESULT может быть одним из:
OKINVALID_KEYKEY_NOT_FOUND
Если NAME=ME, то ответ будет содержать назначение, используемое текущей сессией (полезно, если вы используете TRANSIENT). Если $result не равен OK, MESSAGE может передавать описательное сообщение, например “bad format” и т.д.
$destination - это base 64 представление Destination , которое содержит 516 или более символов base 64 (387 или более байт в двоичном виде), в зависимости от типа подписи.
Публичные и приватные base64 ключи могут быть созданы с помощью следующего сообщения:
DEST GENERATE
что отвечается
DEST REPLY
PUB=$destination
PRIV=$privkey
Начиная с I2P 0.9.14, поддерживается дополнительный параметр SIGNATURE_TYPE. Значение SIGNATURE_TYPE может быть любым именем (например, ECDSA_SHA256_P256, регистр не учитывается) или числом (например, 1), которое поддерживается Key Certificates . По умолчанию используется DSA_SHA1.
$destination — это base 64 представление Destination , которое содержит 516 или более символов base 64 (387 или более байт в двоичном формате), в зависимости от типа подписи.
$privkey представляет собой base 64 кодировку конкатенации Destination , за которой следует Private Key , а затем Signing Private Key , что составляет 884 или более символов base 64 (663 или более байт в двоичном формате), в зависимости от типа подписи.
Значения RESULT
Это значения, которые может содержать поле RESULT, и их значение:
| Значение | Описание |
|---|---|
OK | Операция выполнена успешно |
CANT_REACH_PEER | Узел существует, но недоступен |
DUPLICATED_DEST | Указанный Destination уже используется |
I2P_ERROR | Общая ошибка I2P (например, разрыв I2CP соединения и т.д.) |
INVALID_KEY | Указанный ключ недействителен (неверный формат и т.д.) |
KEY_NOT_FOUND | Система именования не может разрешить указанное имя |
PEER_NOT_FOUND | Узел не найден в сети |
TIMEOUT | Тайм-аут при ожидании события (например, ответа узла) |
Опции Tunnel, I2CP и Streaming
Эти опции могут быть переданы как пары имя=значение в конце строки SAM SESSION CREATE.
Все сессии могут включать опции I2CP, такие как длины tunnel . Сессии STREAM могут включать опции библиотеки Streaming . Смотрите эти справочники для названий опций и значений по умолчанию.
Примечания по Base 64
Кодирование Base 64 должно использовать стандартный алфавит Base 64 для I2P “A-Z, a-z, 0-9, -, ~”.
Реализации клиентских библиотек
Клиентские библиотеки доступны для C, C++, C#, Perl и Python. Они находятся в директории apps/sam/ в исходном пакете I2P. Некоторые могут быть устаревшими и не обновлены для поддержки SAMv2.
Настройка SAM по умолчанию
Порт SAM по умолчанию — 7656. SAM не включен по умолчанию в I2P Router; его необходимо запустить вручную или настроить на автоматический запуск на странице настройки клиентов в консоли роутера или в файле clients.config.