void QTracker::respondToAnnounceRequest() { const QStringMap &gets = m_request.gets; TrackerAnnounceRequest annonce_req; // IP annonce_req.peer.ip = m_env.clientAddress.toString(); // 1. Get info_hash if (!gets.contains("info_hash")) { qDebug("QTracker: Missing info_hash"); status(101, "Missing info_hash"); return; } annonce_req.info_hash = gets.value("info_hash"); // info_hash cannot be longer than 20 bytes /*if (annonce_req.info_hash.toLatin1().length() > 20) { qDebug("QTracker: Info_hash is not 20 byte long: %s (%d)", qPrintable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length()); status(150, "Invalid infohash"); return; }*/ // 2. Get peer ID if (!gets.contains("peer_id")) { qDebug("QTracker: Missing peer_id"); status(102, "Missing peer_id"); return; } annonce_req.peer.peer_id = gets.value("peer_id"); // peer_id cannot be longer than 20 bytes /*if (annonce_req.peer.peer_id.length() > 20) { qDebug("QTracker: peer_id is not 20 byte long: %s", qPrintable(annonce_req.peer.peer_id)); status(151, "Invalid peerid"); return; }*/ // 3. Get port if (!gets.contains("port")) { qDebug("QTracker: Missing port"); status(103, "Missing port"); return; } bool ok = false; annonce_req.peer.port = gets.value("port").toInt(&ok); if (!ok || annonce_req.peer.port < 1 || annonce_req.peer.port > 65535) { qDebug("QTracker: Invalid port number (%d)", annonce_req.peer.port); status(103, "Missing port"); return; } // 4. Get event annonce_req.event = ""; if (gets.contains("event")) { annonce_req.event = gets.value("event"); qDebug("QTracker: event is %s", qPrintable(annonce_req.event)); } // 5. Get numwant annonce_req.numwant = 50; if (gets.contains("numwant")) { int tmp = gets.value("numwant").toInt(); if (tmp > 0) { qDebug("QTracker: numwant = %d", tmp); annonce_req.numwant = tmp; } } // 6. no_peer_id (extension) annonce_req.no_peer_id = false; if (gets.contains("no_peer_id")) annonce_req.no_peer_id = true; // 7. TODO: support "compact" extension // Done parsing, now let's reply if (m_torrents.contains(annonce_req.info_hash)) { if (annonce_req.event == "stopped") { qDebug("QTracker: Peer stopped downloading, deleting it from the list"); m_torrents[annonce_req.info_hash].remove(annonce_req.peer.qhash()); return; } } else { // 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(annonce_req.info_hash); if (peers.size() == MAX_PEERS_PER_TORRENT) { // Too many peers, remove a random one peers.erase(peers.begin()); } peers[annonce_req.peer.qhash()] = annonce_req.peer; m_torrents[annonce_req.info_hash] = peers; // Reply replyWithPeerList(annonce_req); }