Анализ IP-адресов пиров в ответе на уведомление от сервера отслеживания (bitTorrent)

Итак, следующий запрос:

torrent.ubuntu.com:6969/announce?info_hash=%02%21%CA%F9j%A3%CB%94%F0%F5%8DE%8Ex%B0%FC4J%D8%BF&peer_id=ABCDEFGHIJKLMNOPQRST&port=6881&uploaded=0&downloaded=0&left=3353370624&compact=0

приводит к тому, что файл Announce обслуживается. После того, как этот файл будет декодирован, вы получите:

{'peers': '\xb9\x15\xd9\x08\xd8\x05[\xbd_\x15\x1b!', 'interval': 1800, 'complete': 5, 'incomplete': 1}

Я в значительной степени застрял в

'\xb9\x15\xd9\x08\xd8\x05[\xbd_\x15\x1b!'

с compact=1 вы получаете:

'\xbd_\x15\x1b\n\xb9\x15\xd9\x08\xd8\x05'

Если это сетевой порядок (с прямым порядком байтов)?

Из здесь я прочитал:

Обратите внимание, если вы получаете одноранговые узлы в двоичной модели, последние два байта вместе кодируют номер порта (т. е. ‘\x1a\xe1’ = 26 * 256 + 225 = 6881).

Так что, возможно, '\xd8\x05' составляет порт: 216 * 256 + 5 = 55301, а может и нет.

Может кто-нибудь объяснить мне, как разобрать эти шестнадцатеричные числа в адреса ip:port?

Некоторое время гуглил это, не нашел много, поэтому любая помощь будет оценена по достоинству.


person sourlain    schedule 20.07.2015    source источник


Ответы (2)


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

сетевой порядок (с прямым порядком байтов)?

«Сетевой порядок» без дополнительных уточнений обычно имеет обратный порядок байтов.

Может кто-нибудь объяснить мне, как разобрать эти шестнадцатеричные числа в адреса ip:port?

Это не шестнадцатеричные числа. закодированные данные представляют собой необработанные двоичные данные без какой-либо конкретной кодировки. Что бы вы ни использовали для отображения, оно создает шестнадцатеричный вывод.

person the8472    schedule 20.07.2015
comment
Спасибо, что указали мне правильное направление. Я понял, что собираюсь написать свой ответ на Python. - person sourlain; 20.07.2015

Итак, согласно спецификации

одноранговые узлы: (бинарная модель) Вместо использования модели словаря, описанной выше, значением одноранговых узлов может быть строка, состоящая из кратных 6 байтов. Первые 4 байта — это IP-адрес, а последние 2 байта — номер порта. Все в сетевой записи (с обратным порядком байтов).

Это когда для компактного флага установлено значение 1 (Истина), и меня интересует только этот банкомат, поскольку он кажется довольно стандартным.

После синтаксического анализа закодированного файла объявления извлечение ключа «пиры» даст вам кратную 6-байтовую строку.

Эта строка представляет собой двоичные данные с прямым порядком байтов, поэтому для анализа первого адреса мы могли бы (в Python):

decoded = bdecode(announce) # decode the bencoded announce
binary_ip = decoded['peers']
print len(binary_ip) # this will be a multiple of 6 (ie, 12 = 2 ip:port)
offset = 0
ip1 = struct.unpack_from("!i", binary_ip, offset)[0] # ! = network order(big endian); i = int
first_ip = socket.inet_ntoa(struct.pack("!i", ip1)
offset +=4 # save where the first ip ends and the port begins
port1 = struct.unpack_from("!H", binary_ip, offset)[0] # H = unsigned short
offset += 2

Очевидно, вы можете зациклиться на этом, если есть больше одноранговых IP-адресов для чтения.

person sourlain    schedule 20.07.2015