0

Im using the bencodeNET trying to send a find_node query and receive an answer using a bootstrapping node. it seems like the request works well and I do get a response on wireshark and c#. the problem is when decoding (using bencoding ofc) I get unreadable and unusable dictionary code:

IPAddress[] ipAddresses = Dns.GetHostAddresses("router.bittorrent.com");
var endpoint = new IPEndPoint(ipAddresses[0], 6881);

// Create a new bencoded dictionary for the query
BDictionary query = new BDictionary();
query["t"] = new BString("aa"); // transaction ID
query["y"] = new BString("q"); // query type
query["q"] = new BString("find_node"); // query name
// Add additional parameters to the query
BDictionary argsDict = new BDictionary();
argsDict["id"] = new BString(id); // target node ID
Console.WriteLine(BMethods.BytesToId(Encoding.ASCII.GetBytes(argsDict["id"].ToString())) + "penis");
argsDict["target"] = new BString(id); // target ID
query["a"] = argsDict;

Console.WriteLine(argsDict.Get<BString>("id")+"here");
var parser = new BencodeParser(Encoding.GetEncoding("ISO-8859-1"));
// Encode the query as a byte array
var queryBytes = query.EncodeAsBytes();
// Create a new socket

UdpClient udpServer = new UdpClient(11000);

udpServer.Send(queryBytes, queryBytes.Length, endpoint); // reply back
var data = udpServer.Receive(ref endpoint); // listen on port 11000
Console.WriteLine(Encoding.GetEncoding("ISO-8859-1").GetString(data));
BDictionary response = parser.Parse<BDictionary>(data);
foreach (KeyValuePair<BString, IBObject> i in response)
{
    if(i.Value is BDictionary)
    {
        BDictionary b = (BDictionary)i.Value;
        foreach (KeyValuePair<BString, IBObject> j in b)
        {

            Console.WriteLine(j.Key + ": " + BMethods.BytesToId(BMethods.ConvertHexToByte((((BString)j.Value).ToString()))));

        }
        continue;
    }
    Console.WriteLine(i.Key + ": " + ((i.Value).ToString()));
}

id is a random 20 byte array if you're wondering the response output usually looks something like this:

ip: ?Z?w*o id: 2oNisQÿJì)Iº«òûaF|Ag nodes: I??"2/IªLO!d?å?Y3?/lYA??cwIov0ahrth_EqU½?G??▌Ä?÷0ï%(I¼A?ÿ?¡9I?òµ??°O0?~x,B?ªO];'?UDz½??cUP¿}ïWLx?;K=&o¼âC}ÑWAº3{àO\AOé81Ñ B-F¥)ú21?c_ìvyêo?AMe6lcp\g?èöUɰ_6OrEu[?)??']km?èU¡(á t: aa y: r

with obviously id and nodes being completely unreadable and unusable.

anyone wondering how a proper response should look like its in BEP 5

now with id I could get around this by just taking the bytes and turning the bytes to hex. the problem is the nodes key which holds a lot more information than just a sha-1 id (that being ip and port).

Edit: forgot to add sometimes the response dictionary doesn't contain a "nodes" key at all despite Wireshark showing it should

raz
  • 29
  • 7

2 Answers2

0

This is normal because bencoding is foremost a binary format which just sometimes happens to be human-readable. Bencode "strings" really are byte[], BEP52 clarifies this. The examples in BEP5 use values that just happen to be in the ascii range to improve readability.

the8472
  • 40,999
  • 5
  • 70
  • 122
  • Cool thanks is there any solutions to this? Or should I just manually sort this spacific key? Something I forgot to add but will add right now sometimes the response dictionary doesn't contain a node key at all despite Wireshark returning it – raz Jan 23 '23 at 17:20
  • there shouldn't be any sorting necessary on the receiving side. and if it shows up in wireshark but not in your code then maybe it's an issue with the bdecode library. maybe write some test-cases that takes raw inputs (from your packet captures) and tries to decode them without going through the network, that should make things more reproducable. – the8472 Jan 23 '23 at 17:34
  • I'll try monotorrent implementation for bencoding maybe. bencodeNET seemed fairly popular but it might not be used for dht rather it's used for things like torrent files but I haven't done any research on them – raz Jan 23 '23 at 17:40
  • Alright I solved it going to write the solution – raz Jan 23 '23 at 19:11
  • Also this is a question to my response, ipv6 and ipv4 don't exist in the same dht correct? Edit: no according to bep – raz Jan 23 '23 at 19:34
0

I don't have the code with me right now but I'll add it later. Essentially "nodes" key as written in bep 5 is composed of 20 bytes of the id, 4 bytes of the IP, and 2 bytes of the port. Using this information you can use this mess of a dump and composed it into a byte array which you can turn into a list of nodes with the information above

raz
  • 29
  • 7