Exemple #1
0
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);
}