DHT. Как реализовать безтрекерный обмен файлами?

Здравствуйте.

Почитал мануал по DHT протоколу.

Меня интересует реализация безтрекерного (trackerless) файлообмена.

Правильно ли я понимаю Алгоритм BEP-5?

1. Делаем запрос в router.utorrent.com: 6881 - получаем стартовый список нод. Насколько я понял инфохэши мы не запрашиваем, т.к. в данном случае единого трекера нет.

import bencode
import random
import socket


my_id = ''.join([chr(random.randint(0, 255)) for _ in range(20)])
ping_query = {'y': 'q',
          't': '0f',
          'q': 'find_node',
          'a': {'id': my_id}}
ping_query_bencoded = bencode.bencode(ping_query)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(ping_query_bencoded,
     (socket.gethostbyname('router.bittorrent.com'), 6881))
r = s.recvfrom(1024)
ping_response = bencode.bdecode(r[0])
print(ping_response)


2. Записываем ноды в routing table.

nodes = [
              ["<host>", <port>], 
              ["<host>", <port>]
              ]


3. Используя routing table, обзваниваем ноды на предмет поиска инфохэша файла (get_peers) или анонсируем свой инфохэш (announce_peer)

В какую таблицу мы складируем инфохэши от собственных и полученных файлов?

Запрос 'ping' делаем только в router.utorrent.com: 6881 или по всем нодам из routing table?

Запрос 'ping' в данном случае делаем 1 раз в n секунд - показываем, что наша нода жива?

Заранее спасибо за ответы.
  • Вопрос задан
  • 1333 просмотра
Решения вопроса 1
@ivan386
ID для узла выбирается уже не случайно https://www.bittorrent.org/beps/bep_0042.html
Но если не предполагается анонса и приёма запросов то ID можно выбрать любой. Не все клиенты реализовали этот BEP.

1. router.utorrent.com: 6881 - используется только для первичного получения списка узлов командой find_node. Она не требует info_hash а только id узла и target которые могут быть одинаковы так как мы ищем свою позицию в сети.

В дальнейшем router.utorrent.com: 6881 не должен использоваться больше никак.

2. routing table должен содержать значения для каждого узла: id, ip(v4 или v6), port, время последнего ответа.

Её периодически нужно сохранять на диск и при следующем старте пытаться загрузиться уже с неё.

3. Из таблицы выбираются ближайшие по id узлы к target или info_hash. И к ним соответственно отправляются find_node или get_peers.

announce_peer возможен только после get_peers так как нужен токен для анонса который в ответе на get_peers.

find_node используется для нахождения ближайших к своему id узлов. Также периодически можно искать случайные id для пополнения routing table.

В какую таблицу мы складируем инфохэши от собственных и полученных файлов?


Соответственно нужна отдельная таблица в которой по info_hash будет храниться список пиров.

Запрос 'ping' делаем только в router.utorrent.com: 6881 или по всем нодам из routing table?


Ни в коем случае. Работа с ним закончена на первом этапе.

Ping нужно отсылать только на узлы из routing table с которыми длительное время не было связи. До тех пор пока узлы не ответят на ping их нельзя отдавать другим узлам на их запросы. Соответственно и узлы полученные от другого узла нельзя отдавать дальше до проверки их состояния.

Другие узлы также будут проверять этот пингуя или опрашивая его.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы