Skip to content

Commit

Permalink
Properly reply to announce request
Browse files Browse the repository at this point in the history
  • Loading branch information
glassez committed Mar 9, 2018
1 parent e22946e commit dfddda5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 22 deletions.
56 changes: 34 additions & 22 deletions src/base/bittorrent/tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void Tracker::respondToAnnounceRequest()
}
bool ok = false;
annonceReq.peer.port = queryParams.value("port").toInt(&ok);
if (!ok || annonceReq.peer.port < 1 || annonceReq.peer.port > 65535) {
if (!ok || (annonceReq.peer.port < 0) || (annonceReq.peer.port > 65535)) {
qDebug("Tracker: Invalid port number (%d)", annonceReq.peer.port);
status(103, "Missing port");
return;
Expand Down Expand Up @@ -216,50 +216,62 @@ void Tracker::respondToAnnounceRequest()
// 7. TODO: support "compact" extension

// Done parsing, now let's reply
if (m_torrents.contains(annonceReq.infoHash)) {
if (annonceReq.event == "stopped") {
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
m_torrents[annonceReq.infoHash].remove(annonceReq.peer.uid());
return;
}
if (annonceReq.event == "stopped") {
unregisterPeer(annonceReq);
}
else {
registerPeer(annonceReq);
replyWithPeerList(annonceReq);
}
}

void Tracker::registerPeer(const TrackerAnnounceRequest &annonceReq)
{
if (annonceReq.peer.port == 0) return;

if (!m_torrents.contains(annonceReq.infoHash)) {
// Unknown torrent
if (m_torrents.size() == MAX_TORRENTS) {
// Reached max size, remove a random torrent
m_torrents.erase(m_torrents.begin());
}
}

// Register the user
PeerList peers = m_torrents.value(annonceReq.infoHash);
if (peers.size() == MAX_PEERS_PER_TORRENT) {
// Too many peers, remove a random one
peers.erase(peers.begin());
PeerList &peers = m_torrents[annonceReq.infoHash];
if (!peers.contains(annonceReq.peer.uid())) {
// Unknown peer
if (peers.size() == MAX_PEERS_PER_TORRENT) {
// Too many peers, remove a random one
peers.erase(peers.begin());
}
}
peers[annonceReq.peer.uid()] = annonceReq.peer;
m_torrents[annonceReq.infoHash] = peers;
}

void Tracker::unregisterPeer(const TrackerAnnounceRequest &annonceReq)
{
if (annonceReq.peer.port == 0) return;

// Reply
replyWithPeerList(annonceReq);
if (m_torrents[annonceReq.infoHash].remove(annonceReq.peer.uid()) > 0)
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
}

void Tracker::replyWithPeerList(const TrackerAnnounceRequest &annonceReq)
{
// Prepare the entry for bencoding
libtorrent::entry::dictionary_type replyDict;
replyDict["interval"] = libtorrent::entry(ANNOUNCE_INTERVAL);
QList<Peer> peers = m_torrents.value(annonceReq.infoHash).values();

libtorrent::entry::list_type peerList;
foreach (const Peer &p, peers) {
//if (p != annonce_req.peer)
for (const Peer &p : m_torrents.value(annonceReq.infoHash))
peerList.push_back(p.toEntry(annonceReq.noPeerId));
}
replyDict["peers"] = libtorrent::entry(peerList);
libtorrent::entry replyEntry(replyDict);

const libtorrent::entry replyEntry(replyDict);
// bencode
std::vector<char> buf;
libtorrent::bencode(std::back_inserter(buf), replyEntry);
QByteArray reply(&buf[0], static_cast<int>(buf.size()));
QByteArray reply;
libtorrent::bencode(std::back_inserter(reply), replyEntry);
qDebug("Tracker: reply with the following bencoded data:\n %s", reply.constData());

// HTTP reply
Expand Down
2 changes: 2 additions & 0 deletions src/base/bittorrent/tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ namespace BitTorrent

private:
void respondToAnnounceRequest();
void registerPeer(const TrackerAnnounceRequest &annonceReq);
void unregisterPeer(const TrackerAnnounceRequest &annonceReq);
void replyWithPeerList(const TrackerAnnounceRequest &annonceReq);

Http::Server *m_server;
Expand Down

0 comments on commit dfddda5

Please sign in to comment.