Предупреждение - Устарело - Не поддерживается - Используйте SAMv3
Ниже описана версия 1 простого клиентского протокола для взаимодействия с I2P. Новые альтернативы: SAM V2 , SAM V3 , BOB .
Языковые библиотеки для API SAMv1
- C
- C#
- Perl
- Python
Библиотеки находятся в репозитории исходного кода I2P.
Изменения в I2P 0.9.14
Сообщаемая версия остается “1.0”.
- DEST GENERATE теперь поддерживает параметр SIGNATURE_TYPE.
- Параметр MIN в HELLO VERSION теперь является необязательным.
- Параметры MIN и MAX в HELLO VERSION теперь поддерживают однозначные версии, такие как “3”.
Протокол версии 1
Клиентское приложение взаимодействует с мостом SAM, который обрабатывает всю функциональность I2P (используя библиотеку потоков для виртуальных потоков или 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 Connection Handshake
Никакое SAM-взаимодействие не может происходить до тех пор, пока клиент и мост не согласуют версию протокола, что делается путем отправки клиентом HELLO и отправки мостом HELLO REPLY:
HELLO VERSION MIN=$min MAX=$max
и
HELLO REPLY RESULT=$result VERSION=1.0
Начиная с I2P 0.9.14, параметр MIN является необязательным. Параметр MAX должен быть указан и быть больше или равен “1” и меньше “2” для использования версии 1.
Значение RESULT может быть одним из:
OKNOVERSION
SAM-сессии
SAM-сессия создается клиентом, который открывает сокет к SAM-мосту, выполняет рукопожатие и отправляет сообщение SESSION CREATE, а сессия завершается при отключении сокета.
Каждый I2P Destination может использоваться только для одной SAM-сессии одновременно и может использовать только одну из этих форм (сообщения, полученные через другие формы, отбрасываются).
Сообщение SESSION CREATE, отправляемое клиентом на bridge, выглядит следующим образом:
SESSION CREATE
STYLE={STREAM,DATAGRAM,RAW}
DESTINATION={$name,TRANSIENT}
[DIRECTION={BOTH,RECEIVE,CREATE}]
[option=value]*
DESTINATION указывает, какой destination должен использоваться для отправки и получения сообщений/потоков. Если указано $name, мост SAM просматривает свое локальное хранилище (файл sam.keys) для поиска связанного destination (и приватного ключа). Если не существует ассоциации, соответствующей этому имени, он создает новую. Если destination указан как TRANSIENT, он всегда создает новый.
Обратите внимание, что DESTINATION является идентификатором, а не данными в кодировке Base 64. Для указания Destination необходимо использовать SAM V3 .
DIRECTION может быть указан только для STREAM сессий, указывая мосту, что клиент будет либо создавать, либо принимать потоки, или и то, и другое. Если это не указано, будет предполагаться BOTH. Попытка создать исходящий поток при DIRECTION=RECEIVE должна приводить к ошибке, а входящие потоки при DIRECTION=CREATE будут игнорироваться.
Дополнительные параметры должны передаваться в конфигурацию I2P сессии, если они не обрабатываются SAM bridge (например, “tunnels.depthInbound=0”). Эти параметры описаны ниже.
SAM bridge сам по себе уже должен быть настроен на то, с каким router он должен взаимодействовать через I2P (хотя при необходимости может быть способ переопределить это, например, i2cp.tcp.host=localhost и i2cp.tcp.port=7654).
После получения сообщения создания сеанса, SAM bridge ответит сообщением о статусе сеанса следующим образом:
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 мост должен ответить на это сообщением о статусе потока:
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 целым числом по основанию 10 от -1 до -(2^31-1).
$destination — это base 64 представление Destination , которое состоит из 516 или более символов base 64 (387 или более байт в двоичном виде), в зависимости от типа подписи.
Когда клиент хочет отправить данные по виртуальному соединению, он делает это следующим образом:
STREAM SEND
ID=$id
SIZE=$numBytes\n[$numBytes of data]
Это добавляет указанные данные в буфер, отправляемый узлу через виртуальное соединение. Размер отправки $numBytes указывает, сколько 8-битных байт включено после символа новой строки, что может быть от 1 до 32768 (32КБ).
SAM мост затем сделает всё возможное, чтобы доставить сообщение как можно быстрее и эффективнее, возможно буферизируя несколько SEND сообщений вместе. Если произойдёт ошибка при доставке данных или если удалённая сторона закроет соединение, SAM мост сообщит клиенту:
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 мостом и клиентом.
SAM Repliable Datagrams
Хотя I2P по своей природе не содержит адреса FROM, для удобства использования предоставляется дополнительный уровень в виде repliable datagrams - неупорядоченных и ненадёжных сообщений размером до 31744 байт, которые включают адрес FROM (оставляя до 1КБ для заголовочного материала). Этот адрес FROM внутренне аутентифицируется SAM (используя ключ подписи 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-мост никогда не предоставляет клиенту заголовки аутентификации или другие поля, а только данные, которые предоставил отправитель. Это продолжается до тех пор, пока сессия не будет закрыта (клиентом, разрывающим соединение).
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, такие как длины туннелей . STREAM сессии могут включать опции библиотеки Streaming . См. эти ссылки для получения названий опций и значений по умолчанию.
Заметки о Base 64
Кодирование Base 64 должно использовать стандартный алфавит I2P Base 64 “A-Z, a-z, 0-9, -, ~”.
Реализации клиентских библиотек
Клиентские библиотеки доступны для C, C++, C#, Perl и Python. Они находятся в каталоге apps/sam/ в исходном пакете I2P.
Настройка SAM по умолчанию
Порт SAM по умолчанию — 7656. SAM не включен по умолчанию в I2P Router; его необходимо запустить вручную или настроить автоматический запуск на странице настройки клиентов в консоли роутера или в файле clients.config.