Re: DHT specification questions
[email protected] Thu, 14 Aug 2008 15:00:57 +0000 (UTC)
| Newsgroups | gmane.network.gnutella.devel |
|---|---|
| Organization | Home, Grenoble, France |
| Message-ID | <[email protected]> |
Hello Mike! Quoting Michael Green <[email protected]> from ml.gnutella.dev-forum: :So this is with Mojito running alongside gtk-gnutella? How's it :performing so far and did you run into any "compatibility" issues? I'm :in the midst of revamping the aged Cultiv8r core since I have time again :so I'd like to know what I can focus on adding vs. keeping it on a :backburner. Mojito is a "brand name" and I happen to dislike it. I prefer to call it the Gnutella DHT. Yes, I have followed the (incomplete but better than nothing) specifications from LimeWire's web site, basically to know what the packet format is. Once I had the "language" to let two nodes speak together, I used the Kademlia specifications to implement the DHT code. I confess I had no problems at all once I have understood that all the values serialized in the DHT messages are in BIG ENDIAN (even the port number, contrary to Gnutella's usage). Then gtk-gnutella "instantly" joined the DHT. I put "instantly" into quotes because it actually took a looong time for gtk-gnutella to receive a DHT PONG back in answer to the DHT PING it sent. Seeding is done by looking for Gnutella pongs containing the GGEP "DHT" extension. Once one of the hosts answers, you get a hold on a valid Kademlia host and then you can follow the boostrap procedure: look for your own ID, then look for IDs in the k-buckets that are further and further away, at which point your routing table is bootstrapped and you are part of the structure. Hourly k-bucket refreshes generate 2 MiB of incoming UDP traffic. Other than that, the average traffic is about 1 KiB/s in and out, because the node constantly receives FIND_NODE and FIND_VALUE requests, and of course STORE messages. FIND_NODE_RESPONSE messages and VALUE messages are the bulkier to send back. STORE_ACKs are uselessly bulky but since most nodes send a STORE with only 1 DHT value, they remain small enough. I have not yet managed to reverse-engineer the format of the data published by LimeWire. Contrary to what is said in the specs, they seem to use specific data types: "ALOC" for alt-locs and "PROX" for push-proxies. Also the value payloads start with 0xC3 and contain what looks like valid GGEP. Here's a sample "ALOC v0.1" value payload: ----------------- Value payload: Offset 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 0 c3 09 63 6c 69 65 6e 74 2d 69 64 50 e7 4d 6f 26 ..client-idP.Mo& 16 95 0d 9e d5 a1 2e c0 2f de e2 0f 00 0a 66 69 72 ......./.....fir 32 65 77 61 6c 6c 65 64 41 00 06 6c 65 6e 67 74 68 ewalledA..length 48 43 da cf 3b 04 70 6f 72 74 42 58 e9 83 74 6c 73 C..;.portBX..tls 64 40 @ ----------------- (65 bytes). And here's a sample "PROX v0.0" value payload: ----------------- Value payload: Offset 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 0 c3 09 63 6c 69 65 6e 74 2d 69 64 50 bf fa 62 65 ..client-idP..be 16 c8 88 06 76 9c eb 08 79 a0 12 ec 00 08 66 65 61 ...v...y.....fea 32 74 75 72 65 73 41 00 0b 66 77 74 2d 76 65 72 73 turesA..fwt-vers 48 69 6f 6e 41 01 04 70 6f 72 74 42 82 3f 07 70 72 ionA..portB.?.pr 64 6f 78 69 65 73 55 06 4c 61 4a 76 6d 5f 06 61 59 oxiesU.LaJvm_.aY 80 1d 29 7a 0a 06 4c 7d bc bd ae 79 83 74 6c 73 41 .)z..L}...y.tlsA 96 e0 . ----------------- (97 bytes). Once again, we can see LimeWire being creative and using long identifiers where shorter ones would have been better. Bandwidth is cheap. I need to continue reverse engineering to determine what exactly gets stored under each GGEP key, but that should be easy now. Good luck, implementing the DHT was fun, although it's not a lightweight task: I evaluate my efforts to 2 man.months (normalized to 8 hours a day, 20 days a month). Cheers, Raphael