Проектная лаборатория

Собственный BitTorrent

0 / 19этапов пройдено

Этап 14 · Magnet-ссылки

Отправка рукопожатия расширений

Русский перевод заданий CodeCrafters. Примеры подготовлены для Go. Выбор языка меняет команды и результаты, но не текст задания.

На этом этапе вы отправите список расширений, поддерживаемых вашим клиентом.

Идентификаторы расширений и рукопожатие

Каждый пир хранит соответствие между именами расширений и идентификаторами. Одному имени расширения у разных пиров могут соответствовать разные идентификаторы, но для конкретного пира идентификатор остаётся постоянным.

Для общения с другими пирами через расширение метаданных ваш пир должен знать идентификатор, используемый удалённым пиром для этого расширения. Имя расширения метаданных — ut_metadata. Чтобы узнать идентификатор, нужно отправить сообщение рукопожатия расширений и дождаться соответствующего ответного сообщения пира.

Сообщение рукопожатия расширений содержит такой словарь:

{
  "m": {
    "ut_metadata": 16,
    ... (other extension names and IDs)
  }
}

В этом примере 16 — идентификатор расширения метаданных, используемый пиром. Это лишь пример: можно выбрать любое значение идентификатора.

Программа должна отправить сообщение рукопожатия расширений вскоре после получения сообщения битового поля. Общая последовательность:

  • Установить TCP-соединение с пиром.
  • Отправить сообщение базового рукопожатия.
  • Получить сообщение базового рукопожатия.
  • Отправить сообщение битового поля (в этом задании можно пропустить).
  • Получить сообщение битового поля.
  • Если пир поддерживает расширения (судя по зарезервированному биту базового рукопожатия):
    • Отправить сообщение рукопожатия расширений.
    • Получить сообщение рукопожатия расширений.

Обратите внимание: сообщение рукопожатия расширений отправляется только тогда, когда удалённый пир поддерживает расширения, о чём сообщает зарезервированный бит базового рукопожатия. Так сохраняется обратная совместимость с пирами без поддержки расширений.

На этом этапе мы реализуем отправку сообщения рукопожатия расширений. Получение реализуем на следующем этапе.

Формат рукопожатия расширений

Сообщения расширений следуют стандартному формату сообщений BitTorrent:

  • Префикс длины сообщения (4 байта).
  • Идентификатор сообщения (1 байт).
    • Для всех сообщений, реализованных расширениями, равен 20.
  • Полезная нагрузка (переменный размер).

Структура полезной нагрузки:

  • Идентификатор сообщения расширения (1 байт).
    • Для рукопожатия расширений равен 0.
  • Словарь bencode (переменный размер).
    • Содержит ключ "m", значением которого является другой словарь.
    • Внутренний словарь сопоставляет имена поддерживаемых расширений соответствующим идентификаторам сообщений.
    • Например, {"ut_metadata": 1, "ut_pex": 2} означает, что пир поддерживает расширения "ut_metadata" и "ut_pex" с идентификаторами 1 и 2 соответственно.

Нас интересует имя "ut_metadata", соответствующее расширению метаданных.

Тесты

Тестирующая система запустит вашу программу следующим образом:

$ ./your_program.sh magnet_handshake <magnet-link>

Ожидаемый вывод:

Peer ID: 0102030405060708090a0b0c0d0e0f1011121314

Вывод совпадает с предыдущим этапом. Дополнительно тестирующая система проверит, что:

  • Получено сообщение рукопожатия расширений.
  • Оно содержит словарь вида {"m": {"ut_metadata": <PICK YOUR ID>}}.
  • Идентификатор для ut_metadata находится в диапазоне от 1 до 255: он должен представляться 8-битным беззнаковым целым числом, отличным от 0.

Примечания

  • Программа должна отправлять рукопожатие расширений только если пир поддерживает расширения.
    • Чтобы это определить, проверьте зарезервированные байты сообщения базового рукопожатия.
  • Сообщение рукопожатия расширений описано в разделе о рукопожатии документации протокола расширений.

Проверка в вашей IDE

Нужны Node.js, Git, Go 1.24+ для тестеров и инструменты выбранного языка. Тестеры загружаются и запускаются локально; отдельным проектам нужны дополнительные системные зависимости.

Настройка проекта и IDE

1. Создайте проект один раз

node '/opt/graphlms/tools/project-lab/cli.mjs' init bittorrent ./my-bittorrent --language go

2. Откройте папку в IDE

cd ./my-bittorrent

Реализуйте требования этапа в созданном проекте.

Запустите из папки проекта

node '/opt/graphlms/tools/project-lab/cli.mjs' submit --stage xi4

Запускайте submit из папки проекта. Это локальные проверки, а не сертификаты или результаты аккаунта CodeCrafters.

Результат проверки

go / ЛОКАЛЬНО

Подключение к локальной проверке…

Здесь появится результат

Запустите submit в терминале. Страница обновляет результаты каждые 8 секунд.

GraphLMS — инженерная лаборатория роста