====== DHT ======
Сами по себе торрент-пиры в сети Yggdrasil в числе узлов DHT друг у друга не появятся (точнее, это очень маловероятно: два клиента с интерфейсами Yggdrasil должны через публичную сеть запустить одни и те же торренты и обменяться альтернативными адресами, либо попасть при обходе миллионов меняющихся участников DHT на живой анонс такого адреса). С другой стороны, препятствий к работе отдельной DHT внутри сети в целом нет. Более того, она уже существует.
===== Теория =====
Как известно, узлы DHT в процессе работы поддерживают актуальность набора кандидатов с разной степенью удалённости координат для отправки через них запросов (на первом шаге). Старые и ставшие недоступными узлы удаляются, новые добавляются в процессе обхода сети при поиске хэшей активных торрентов или случайных идентификаторов, выбранных внутри нужного диапазона координат, который требуется пополнить. Имеющий сколько-то живых произвольных узлов клиент быстро находит через них более близкие и нужные. Откуда они берутся изначально? Либо сохраняются в момент завершения прежней сессии (в надежде, что при следующем включении хоть кто-то ещё будет онлайн; это совсем не гарантируется, если пройдёт неделя, месяц или год), либо получаются с публичных серверов инициализации, прописанных в каждом клиенте или библиотеке и готовых любому выдать актуальный набор свежих узлов.
Очевидно,[citation needed] что добавлять отдельную функцию получения внутрисетевых адресов конкретно для клиентов в Yggdrasil либо в код программ и библиотек, либо на узлы DHT по умолчанию никому из их авторов пока не интересно. Некоторые клиенты (например, Tixati) позволяют указать собственный набор узлов для запуска DHT, так что если вы выписали на бумажку или получили от друга перечень адресов и портов торрент-клиентов на адресах Yggdrassil, их можно туда запихнуть.
Но есть и другой полезный источник: все пиры, с которыми клиент соединяется, записываются в потенциальные узлы DHT. В большинстве клиентов порт для приёма сообщений DHT совпадает с портом для связи с пирами (по UDP) так что достаточно его проверить. В тех, где это не так, клиент во время приветствия при соединении может получить от пира отдельное указание на то, на каком порту работает DHT, и использовать его.
Недавно у пользователей древнейших версий uTorrent переставал работать DHT, как раз из-за того, что такой же древний адрес для инициализации их DHT уходил в офлайн. На «Рутрекере», где адреса трекера много лет заблокированы для дорогих россиян, активно жаловались, что почему-то пиров больше нет. Действительно: трекер не работает, DHT не работает, откуда пиры возьмутся? Починить можно было достаточно просто, добавив в клиент хотя бы один гарантированно популярный торрент с гарантированно рабочим трекером (например, свежий образ Debian или Ubuntu). Трекер выдаёт сотню случайных пиров, у них в большинстве случаев включена работа DHT, можно с их помощью стартовать, добавив в список узлов. Сами файлы никакой роли не играют, их можно даже не качать, главное живых пиров получить.
Тем же методом можно пользоваться и в Yggdrasil. Добавляем в клиент торрент, на котором есть внутрисетевые пиры, с добавленными адресами внутрисетевых трекеров (в надежде, что хотя бы один-то рабочий окажется), получаем с них адреса узлов для старта DHT. Если хотя бы несколько участников будут постоянно держать его в клиенте, любой новозапущенный клиент так может стать участником внутрисетевой DHT.
Осталось выбрать этот //офффициальный// волшебный торрент. Поскольку подойдёт любой, возникает искушение продемонстрировать собственный вкус и застолбить место тем, что тебе лично нравится, или популярно на этой неделе, или иронично комментирует всю эту затею. Нет, всё-таки полезнее будет что-то абстрактное и воспроизводимое, вроде файла нулевого размера с заданным именем и фиксированного размера блока для создаваемого торрента... А впрочем, зачем нам торрент? Хэша достаточно, чтобы получить пиров, которые в обычной ситуации обменяются метаданными. А нам и метаданные не нужны. Просто берём и используем хэш ''0000000000000000000000000000000000000000'' в качестве места встречи клиентов.
Нет, с ним проблемка. В каких-то программах всё работает как надо, но вот libtorrent считает, что такое значение хэша не разрешено (вероятно, потому, что в коде оно используется для других целей, а для реальных данных случайно не получится никогда), так что клиенты на его основе отпадают. Кроме того, мы не одни такие умные (или криворукие), из публичной IPv4 DHT на этот хэш начинают валиться мусорные пиры, которые, похоже, даже не все являются торрент-клиентами. Зачем нам куча бесполезных соединений? Придётся придумать некий Универсальный Уникальный Идентификатор для нашей задачи... А вот и он: ''000000000000000059676764726173696c444854''.
С этого момента любой участник сети с работающим торрент-клиентом может просто добавить волшебную магнитную ссылку и автоматически пополнить внутрисетевую IPv6 DHT. Вуаля!
magnet:?xt=urn:btih:000000000000000059676764726173696c444854&tr=http%3A%2F%2F%5B200%3A1e2f%3Ae608%3Aeb3a%3A2bf%3A1e62%3A87ba%3Ae2f7%5D%3A80%2Fannounce&tr=http%3A%2F%2F%5B21e%3A6565%3A9c87%3Aa49d%3Adafa%3A92c1%3Ab33f%3Af21%5D%3A1337%2Fannounce&tr=udp%3A%2F%2F%5B302%3A68d0%3Af0d5%3Ab88d%3A%3Afdb%5D%3A6969%2Fannounce
{{ :yggdrasil:bittorrent:bittorrent_dht_yggdrasil.png?direct&400 |}}
Любые торренты, анонсируемые в неё прочими участниками, будут доступны и без указания внутрисетевого трекера, с автоматическим поиском пиров, прямо как в привычной публичной сети. Можете в своём клиенте подсмотреть хранящиеся на вашем узле чужие хэши (если он такое позволяет) и добавить для тестовой загрузки любой.
Теоретически, если число участников станет таким большим, что на одном хэше возникнет толкучка, или кто-то специально запустит ботов, замусоривающих списки пиров, или фиктивные узлы DHT вблизи выбранного, можно добавить альтернативы от ''100000000000000059676764726173696c444854'' до ''F00000000000000059676764726173696c444854'' и так далее для следующих битов. Эти же хэши можно добавить в клиент при первом старте для быстрого пополнения списка узлов, хотя на текущий момент число участников таково, что уже первая парочка автоматических поисковых проходов по узлам DHT перебирает и добавляет всех имеющихся.
===== Практика =====
Проверим, что это не выдумка, в разных клиентах, установленных с нуля, со стандартными настройками.
==== Tixati ====
В Tixati панель DHT подробно выводит всё, что творится в клиенте, вдобавок можно максимально подробный журнал вести. Не могу не привести в пример. Кроме того, при помощи файлика ''tixati_local_instance_check.txt'' (см. инструкцию) можно быстро запустить хоть десять портативных клиентов с разными настройками и тестировать, как они друг с другом работают.
* Запускаем программу, после начальных окошек и предупреждений сразу нажимаем на кнопку раздела DHT, а в нём на кнопку Stop.
* В настройках Network — Connections для интерфейса IPv4 выбираем Disabled. Если в системе есть другие сети IPv6, для интерфейса IPv6 выбираем интерфейс или адрес Yggdrasil, чтобы работать только с ним.
* Идём обратно в раздел DHT, нажимаем Start. На вкладке Node Table видим, что DHT для IPv4 отключен, а для IPv6 пытается соединиться с публичными адресами, которые получены с сервера разработчика (о чём написано в Event Log), но через Yggdrasil в глобальную IPv6-сеть не выйти, и это бесполезно.
* Идём в раздел Transfers и добавляем магнитную ссылку, указанную выше. (Полную, с трекерами, конечно. Если вы хотите добавить без трекеров, вы не поняли, как оно работает.) После добавления на вкладке Trackers в свойствах торрента должны появиться какие-то результаты, а на вкладке Peers — подключившиеся-отключившиеся или ждущие метаданных пиры. Столбец с названием клиента добавляется кнопкой Layout — Select Columns — Peers View — Client.
* Опять идём в раздел DHT, видим, что таблицы узлов IPv6 пополняются сначала полученными с трекера пирами, а потом найденными через них. На Port Blocked можно не обращать внимания, это просто догадка на основе успешности соединений. (Ещё видим, что кто-то поленился подкрутить в клиенте случайный идентификатор узла.)
* На вкладке Peer DB наблюдаем, как другие участники анонсируют хэши своих торрентов через наш узел. Пока людей мало, каждый узел видит чуть ли не пол-сети, по мере увеличения числа узлов каждому будут доставаться только всё более и более близкие к его координате хэши.
==== qBittorrent ====
* Запускаем программу, в Tools — Options — Advanced — Network Interface ставим интерфейс Yggdrasil. Если на одном и том же компьютере несколько клиентов одновременно тестируете, можно в настройках libtorrent разрешить несколько соединений с одного IP-адреса, иначе они в тех или иных сочетаниях иногда не желают на одном и том же адресе друг друга видеть.
* В строке состояния видим 0 пиров DHT. В qBittorrent DHT всегда при старте инициализируется путём запроса на общий узел libtorrent, и параллельно, кажется, подмешиваются старые пиры, сохранённые вместе с имеющимися в клиенте торрентами. Нам не доступно ни то, ни другое.
* Добавляем общую магнитную ссылку. На вкладке трекеров видим результаты запроса, на вкладке пиров иногда видим пиров, но qBittorrent очень быстро их стирает при завершении обмена данными (или не показывает вовсе, если данные не передаются).
* В строке состояния циферки узлов DHT начинают расти и выходят на ожидаемое число. Можно пользоваться.
Можно было бы не отключать сеть IPv4, работало бы точно так же, но в этом клиенте вообще нет никаких данных о работе DHT, кроме общего числа узлов, пришлось ориентироваться по нему.
==== BiglyBT ====
В BiglyBT есть отдельная, исторически не совместимая с остальными клиентами реализация DHT. Думаю, её тоже можно запустить с пирами внутри сети, но для этого потребуется постоянно иметь более одного клиента в Yggdrasil и разбираться с отдельным набором настроек. Поэтому мы рассмотрим только общую Mainline DHT, которая подключается соответствующим плагином.
* Запускаем программу, после обновления стандартных плагинов и предложений понаставить новых видим уведомление о том, что в системе обнаружен адрес IPv6 и его работа включена.
* Ставим плагин mlDHT, открыв ссылку ''%%biglybt://install-plugin/mlDHT%%''. Сервера BiglyBT расположены на AWS, подверженном блокировкам, так что в России быстрее будет скачать файл со странички плагинов руками, чтобы не ждать проверки основного и запасного вариантов автоматического обновления.
* Даже если не видим вышеупомянутого уведомления, всё равно идём в Tools — Options — Connection — Advanced Network Settings и проверяем, что IPv6 включен, а интерфейс выбираем Ygdrassil.
* В Tools — Options — Plugins — Mainline DHT проверяем, что IPv6 по умолчанию включен. Можно выбрать Only use Connected Peers to Bootstrap, чтобы он зря не пытался соединиться с публичными узлами.
* View — Mainline DHT (IPv6) открывает панель статистики DHT. Если мы не запускали клиент раньше, там должно быть пусто. Если запускали, то старые пиры могут сами начать слать сообщения на тот же самый порт 49001, который указан по умолчанию (и отличается от случайно выбираемого порта для соединений с пирами в основных настройках). Но в статистике нами добавленных всё равно пока ноль.
* Идём в раздел Library, добавляем волшебную ссылку, закрываем окошко ожидания данных с крутилкой. Если не видим добавленного торрента, ищем на панели кнопку Advanced List, показывающую и загрузки, и раздачи одновременно. В свойствах торрента на вкладке Sources отображается активность трекеров (opentrackr.org добавляется по умолчанию, в настройках плагина Magnet URI Handler это можно убрать). Рядом вкладка с пирами.
* Возвращаемся в статистику DHT, видим, что пиров в таблице теперь не ноль, хранимых данных тоже стало больше, и для иллюстрации расчерчены ёмкости с полосками. Цвет означает наличие или отсутствие отклика, а если догадаетесь навести курсор, увидите в подсказке адрес и прочую информацию для каждого пира. Ещё можно включить нужный уровень отчёта и открыть его через View — Log Views — Mainline DHT Log, там тоже вплоть до каждого сообщения можно отслеживать.
Вообще, для нормальной работы BiglyBT ещё настраивать и настраивать, отключать ненужное (например, встроенные DHT до перезагрузки так и продолжают работать на публичном IPv4 адресе, а вы и не заметили), но для демонстрации сойдёт.
===== Несовместимость с публичным IPv6 =====
Можно заметить, что иногда в таблице появляются адреса IPv6 публичных диапазонов. Ничего страшного тут нет, их автоматически выкинет из-за недоступности. Происходить это может по разным причинам:
* У каких-то пиров в Yggdrasil есть и публичный IPv6-адрес, позволяющий участвовать в глобальной DHT, или они ещё как-то узнают о пирах, которых передают в ответ на запросы.
* Если это не отключено, клиент в фоне получает кандидатов с сервера инициализации.
* Если DHT для адресов IPv4 работает, её участники, имеющие оба типа адресов или получившие анонсы с IPv6-адресами, нам их сообщают вместе с IPv4-адресами.
Ирония в том, что если у вас всё-таки есть работающее глобальное IPv6 соединение вдобавок к виртуальной локалке Yggdrasil, то всё описанное выше работать не будет. Поскольку отдельную реализацию DHT строго для диапазона адресов Yggdrasil вдобавок к двум имеющимся в клиентах пока не делают, при наличии обеих сетей местные адреса клиент станет воспринимать так же, как и все прочие публичные. Сам он их хранить не будет, так как не слишком вероятно, что их идентификаторы совпадут с желаемыми, и более подходящие публичные пиры их вытеснят, а в анонсах другим узлам эти адреса будут расцениваться как нерабочий мусор, поскольку почти все участники глобальной сети не имеют доступа к этому диапазону. Они просто затеряются в толпе глобальных.
По этой причине торрент-клиент придётся использовать либо в режиме связи строго внутри Yggdrasil, либо в режиме публичной сети для IPv4 и Yggdrasil для IPv6, если хочется, чтобы DHT внутри сети работал. (Просто получать пиров с внутрисетевых трекеров, без DHT, конечно, можно будет и не отказываясь от публичной сети IPv6.) Ну, или ждать, когда для 20 странных человек в клиентах сделают отдельную независимую DHT.
~~DISCUSSION~~