dht find_node нет ответа - PullRequest
       57

dht find_node нет ответа

0 голосов
/ 15 мая 2018

Я пишу dht-сервер и столкнулся с некоторой проблемой.Я отправляю запрос find_node на начальные загрузчики, и они возвращают мне некоторую информацию о компактных узлах (416 байт), которая содержит информацию о 16 узлах, затем я кодирую и сохраняю IP-адрес и порт, продолжаю отправлять find_node запрос к этим узлам, но я не получаю ответ.

Код сервера здесь (получить пакет и начать новый поток, чтобы добавить узлы в список)

public void run() {

    try {
        while (true) {
            byte[] buffer_rcv = new byte[1024];
            DatagramPacket recvPacket = new DatagramPacket(buffer_rcv, buffer_rcv.length);
            socket.receive(recvPacket);
            System.out.println("get!!!");

            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        LinkedList<Node> nodes = BDecode.bdecode_find_node(recvPacket);
                        for (Node n : nodes) {
                            table.add_node(n);
                        }

                        System.out.println("table size" + table.get_all_nodes().size());

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }

            }).start();
            System.out.println("waiting new packet!!!!!!!");
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Я загружаю jbittorrent API отsourceforge и использую его для bdecode

public static LinkedList<Node> bdecode_find_node(DatagramPacket recvPacket) throws IOException {

    byte[]nodes_compact_info = (byte[]) ((Map) new BDecoder().decodeByteArray(recvPacket.getData()).get("r")).get("nodes");

    byte[]node_info = new byte[26];
    byte[]node_id = new byte[20];
    byte[]ip_byte = new byte[4];
    byte[]port_byte = new byte[2];
    int port;


    LinkedList<Node> nodes = new LinkedList<>();
    //System.out.println("nodes_compact_info.length"+nodes_compact_info.length);
    for (int i = 0;i<nodes_compact_info.length/26;i++) { //416 = 16 * 26byte_per_node 
        //0-19 id 20 21 22 23 ip 24 25 port

        node_info = Utils.subArray(nodes_compact_info, i*26, 26);           
        node_id=Utils.subArray(node_info, 0, 20);           
        ip_byte = Utils.subArray(node_info, 20, 4); 

        String ip = "";
        for (int j = 0;j<ip_byte.length;j++) {
            ip+=Utils.byteToUnsignedInt(node_info[j]);
            ip+=".";
        }
        ip = ip.substring(0, ip.length()-1);
        //System.out.println(ip);
        port_byte = Utils.subArray(node_info, 24, 2);
        port = Utils.byteArrayToInt(port_byte);

        nodes.add(new Node(node_id, ip, port, new Date()));         
    }
    return nodes;
}

Наконец я посылаю find_node запрос каждому узлу в списке

public void get_neighbor() {

    ArrayList<Node> nodes = table.get_all_nodes();
    System.out.println("*********get_neighbor!!!");

    for (Node n : nodes) {
        try {

            byte[] find_node_query = BEncode.find_node(this.id, this.id);
            DatagramPacket sendPacket = new DatagramPacket(find_node_query, find_node_query.length,
                    InetAddress.getByName(n.getIp()), n.getPort());
            for (int i = 0;i<5;i++)
                socket.send(sendPacket);
            System.out.println("packet send to " + n.getIp() + ":" + n.getPort());
        } catch (UnknownHostException e1) {
            // TODO Auto-generated catch block
            System.out.println("UnknownHostException" + n.getIp());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("cant send packet");
        }
    }
}

Я застрял там на несколько дней и попробуюмножество способов найти, где что-то пошло не так, помогите мне, пожалуйста.

информация о компактном узле

это возвращается из начальной загрузки и после bdecoding компактная информация об узле

захват

отправка find_node к начальной загрузке

ответ от начальной загрузки

udpпакет в узел

.pcap файл

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Я вижу некоторые проблемы, глядя на эти четыре пакета из файла .pcap

110 48.444854   10.3.157.234    82.221.103.244  BT-DHT  134 
...
113 48.844328   82.221.103.244  10.3.157.234    BT-DHT  528 reply=16 nodes 
114 48.911670   10.3.157.234    47.152.12.43    BT-DHT  134 
115 48.912589   10.3.157.234    181.39.146.92   BT-DHT  134 

Это запрос find_node , отправленный узлу начальной загрузки: router.utorrent.com [82.221.103.244]

Frame 110: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits)
Ethernet II, Src: IntelCor_1d:89:36 (5c:e0:c5:1d:89:36), Dst: Hangzhou_bf:8e:b0 (d4:61:fe:bf:8e:b0)
Internet Protocol Version 4, Src: 10.3.157.234, Dst: 82.221.103.244
User Datagram Protocol, Src Port: 6883, Dst Port: 6881
BitTorrent DHT Protocol
    Transaction ID: 7473
        Key: t
        Value: 7473
    Message type: Request
        Key: y
        Value: q
    Request type: find_node
        Key: q
        Value: find_node
    Request arguments: Dictionary...
        Key: a
        Value: Dictionary...
            id: ef417ba2c490541a8981d7905036c814364750a6
                Key: id
                Value: ef417ba2c490541a8981d7905036c814364750a6
            target: ef417ba2c490541a8981d7905036c814364750a6
                Key: target
                Value: ef417ba2c490541a8981d7905036c814364750a6

Узел отправил id и target с установленным значением: ef417ba2c490541a8981d7905036c814364750a6, поэтому это должно быть его node_id .
Это имеет небольшую проблему, так как ключи в закодированном словаре должны быть отсортированы, но большинство реализаций все равно примут запрос.
d1:t2:ts1:y1:q1:q9:find_node1:ad2:id20:.A....T.....P6..6GP.6:target20:.A....T.....P6..6GP.ee
должно быть:
d1:ad2:id20:.A....T.....P6..6GP.6:target20:.A....T.....P6..6GP.e1:q9:find_node1:t2:ts1:y1:qe


Это ответ от узла начальной загрузки:

Frame 113: 528 bytes on wire (4224 bits), 528 bytes captured (4224 bits)
Ethernet II, Src: Hangzhou_bf:8e:b0 (d4:61:fe:bf:8e:b0), Dst: IntelCor_1d:89:36 (5c:e0:c5:1d:89:36)
Internet Protocol Version 4, Src: 82.221.103.244, Dst: 10.3.157.234
User Datagram Protocol, Src Port: 6881, Dst Port: 6883
BitTorrent DHT Protocol
    ip: def983017ed6
        Key: ip
        Value: def983017ed6
    Response values: Dictionary...
        Key: r
        Value: Dictionary...
            id: ebff36697351ff4aec29cdbaabf2fbe3467cc267
                Key: id
                Value: ebff36697351ff4aec29cdbaabf2fbe3467cc267
            nodes: 16
                Key: nodes
                Value: 16 nodes
                Node 1 (id: 2f980c2befa8ae85856bfabd44fb76137c50e39e, IP/Port: 184.148.185.216:43611)
                Node 2 (id: b527925cd9b0f4610904dd2d75aa8c5aa6c900e3, IP/Port: 201.92.140.89:63505)
                Node 3 (id: 454d423032343241433131303030325858587a63, IP/Port: 119.136.154.198:23493)
                Node 4 (id: 4dbe732bad993048936a71ae2c7be49dc9ab24f9, IP/Port: 27.209.68.82:16001)
                Node 5 (id: 39a36bc7f75c494b90395113ab2fd5833c6d684c, IP/Port: 171.239.30.38:1035)
                Node 6 (id: a5ac55cdfdf231bf35e4e68e3b89b5430f0eedd7, IP/Port: 109.154.41.107:58580)
                Node 7 (id: 8f05d55f2129e53c4a1f87b13199b598c479b0aa, IP/Port: 189.78.63.188:27070)
                Node 8 (id: d1bd0a25de085c18d8c45c60f681f7074b9e0458, IP/Port: 95.81.104.30:27196)
                Node 9 (id: 30f0086f8618d7aa5a53b8ac0e3d5b080351fb9a, IP/Port: 70.118.138.155:26085)
                Node 10 (id: dd4797facea363d908b629ce93183c241f08f478, IP/Port: 189.83.128.160:45381)
                Node 11 (id: 0801a40c0e72581bc76e00262350243fc38d21af, IP/Port: 218.210.40.82:31021)
                Node 12 (id: cacf92f943a69abcc24891919d80953b3e70526d, IP/Port: 120.148.25.109:59348)
                Node 13 (id: 3f3834ab54f4215248f0f47d0d0265317d320b48, IP/Port: 189.62.200.109:49307)
                Node 14 (id: fd81b802855925bee2b2ed89134788babe2328bb, IP/Port: 189.152.39.89:43529)
                Node 15 (id: cef348726b9c1278675db1b1da4b605016aab4f8, IP/Port: 189.163.183.249:49937)
                Node 16 (id: 96f24f9a50ee407836fd124932f69e7d49dcad32, IP/Port: 178.77.35.128:34304)
    Transaction ID: 7473
        Key: t
        Value: 7473
    Message type: Response
        Key: y
        Value: r

Список из 16 узлов.


Это запрос find_node , отправленный первому узлу в списке:
Node 1 (id: 2f980c2befa8ae85856bfabd44fb76137c50e39e, IP/Port: 184.148.185.216:43611)

Frame 114: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits)
Ethernet II, Src: IntelCor_1d:89:36 (5c:e0:c5:1d:89:36), Dst: Hangzhou_bf:8e:b0 (d4:61:fe:bf:8e:b0)
Internet Protocol Version 4, Src: 10.3.157.234, Dst: 47.152.12.43
User Datagram Protocol, Src Port: 6883, Dst Port: 43611
BitTorrent DHT Protocol
    Transaction ID: 6476
        Key: t
        Value: 6476
    Message type: Request
        Key: y
        Value: q
    Request type: find_node
        Key: q
        Value: find_node
    Request arguments: Dictionary...
        Key: a
        Value: Dictionary...
            id: 2f980c2befa8ae85856bfabd44fb7614364750a6
                Key: id
                Value: 2f980c2befa8ae85856bfabd44fb7614364750a6
            target: ef417ba2c490541a8981d7905036c814364750a6
                Key: target
                Value: ef417ba2c490541a8981d7905036c814364750a6

Вот еще вопросы: port и target правильно,
но id не так. Это запрашиваемых узлов id = 2f980c2befa8ae85856bfabd44fb7614364750a6
вместо запрос узлов id = ef417ba2c490541a8981d7905036c814364750a6 в порядке.
Узлы, скорее всего, не будут отвечать на «id похитителей».
IP также неверно, вместо 184.148.185.216 это 47.152.12.43 = 0x2f980c2b, что является четырьмя первыми байтами в запрашиваемых узлах id . Отправка на неправильный IP, конечно, фатальная проблема.
Закодированные ключи не отсортированы.


Это запрос find_node , отправленный второму узлу в списке:
Node 2 (id: b527925cd9b0f4610904dd2d75aa8c5aa6c900e3, IP/Port: 201.92.140.89:63505)

Frame 115: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits)
Ethernet II, Src: IntelCor_1d:89:36 (5c:e0:c5:1d:89:36), Dst: Hangzhou_bf:8e:b0 (d4:61:fe:bf:8e:b0)
Internet Protocol Version 4, Src: 10.3.157.234, Dst: 181.39.146.92
User Datagram Protocol, Src Port: 6883, Dst Port: 63505
BitTorrent DHT Protocol
    Transaction ID: 6f69
        Key: t
        Value: 6f69
    Message type: Request
        Key: y
        Value: q
    Request type: find_node
        Key: q
        Value: find_node
    Request arguments: Dictionary...
        Key: a
        Value: Dictionary...
            id: b527925cd9b0f4610904dd2d75aa8c14364750a6
                Key: id
                Value: b527925cd9b0f4610904dd2d75aa8c14364750a6
            target: ef417ba2c490541a8981d7905036c814364750a6
                Key: target
                Value: ef417ba2c490541a8981d7905036c814364750a6

Имеет те же проблемы, что и первый узел. Все следующие запросы имеют одинаковые проблемы.

0 голосов
/ 20 мая 2018

Я только что нашел.Я фиксирую сокет на порту 6881, но когда я отправляю пакет, порт меняется

Да, это одна проблема.Вы должны связать один UDP-сокет и затем повторно использовать этот сокет.Согласно BEP 45 он также должен быть привязан к определенному адресу.

.pcap файл

Пакет № 2, ответ от начальной загрузкиузел содержит 16 контактов.Первый контакт - id: 0f9c86a1085677f9f1edb519bfc16b626f19fb11, IPv4/Port: 92.255.216.47:29501

Пакет № 18 пытается связаться 47.216.255.92:29501

Таким образом, вы меняете байты при декодировании IP-адреса. Контакты кодируются в порядке сетевых байтов , то есть с прямым порядком байтов.

Для этого вам не нужно использовать обработку строк, InetAddress.getByAddress имеет перегрузку, которая принимает байтовые массивы

...