Reputation: 22601
I've been throwing a little bit of spare time at writing a BitTorrent client, mostly out of curiosity but partly out of a desire to improve my c# skills.
I've been using the theory wiki as my guide. I've built up a library of classes for handling BEncoding, which I'm quite confident in; basically because the sanity check is to regenerate the original .torrent file from my internal representation immediately after parsing, then hash and compare.
The next stage is to get tracker announces working. Here I hit a stumbling block, because trackers reject my requests without terribly useful error messages.
Take, for instance, the latest stack overflow database dump. My code generates the following announce URI:
http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started
The tracker's response to my code:
d14:failure reason32:invalid info hash and/or peer ide
The tracker's response to that string dropped into Chrome's address bar:
d8:completei2e11:external ip13:168.7.249.11110:incompletei0e8:intervali600e5:peerslee
The peer_id is (valid) garbage, but changing it to something sensible (impersonating a widely used client) doesn't change anything.
Like I said, I'm pretty sure I'm pulling the info dictionary out properly and hashing (SHA1) like I should, and the peer id is well formed.
My guess is I'm doing some minor thing stupidly wrong, and would appreciate any help in spotting what it is exactly.
Its kind of hard to guess what code would be pertinent (and there's far to much to just post). However, I'll try and post anything asked for.
EDIT
I wasn't hex encoding the info_hash, which sort of helps.
This is the code that takes the generates URI and try's to fetch a response:
//uri is the above
WebRequest req = WebRequest.Create(uri);
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
Upvotes: 3
Views: 5044
Reputation: 2089
There is a error in the URL %-encoding of the info_hash. The leading zeros in the two last bytes of the info_hash has been removed.
It is: info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C
Should be: info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%0F%0C
When the announce string is dropped into Chrome's address bar it's probably auto-corrected by the browser.
Upvotes: 1
Reputation: 132454
What exactly are you hashing? You should only hash the info
section, not the whole torrent file... So basically, decode the file, reencode the info
section, hash that.
ie. For the torrent posted, all you should be hashing is:
d6:lengthi241671490e4:name20:so-export-2009-07.7z12:piece lengthi262144e6:pieces18440:<lots of binary data>e
Upvotes: 1
Reputation: 16871
This isn't an answer to your problem, but it may help for testing.
There are open-source PHP-based torrent trackers out there. They are incredibly inefficient (I know, I wrote a caching mechanism for one back in the day), but you could set up your own local tracker and modify the PHP code to help debug your client as it communicates with the tracker. Having a local client-server setup would make troubleshooting a lot easier.
Upvotes: 1
Reputation: 217391
MonoTorrent is a BitTorrent implementation that comes with Mono.
In the HTTPTracker class there is a CreateAnnounceString
method.
Maybe you can compare your implementation with how that method is doing it?
(You probably need to hunt down where the AnnounceParameters
instance is created.)
Upvotes: 3