mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-10 23:07:59 +00:00
Merge pull request #9953 from Chocobo1/announce
Use ip parameter from tracker request if provided
This commit is contained in:
commit
eb957bb790
@ -60,7 +60,7 @@ bool Peer::operator==(const Peer &other) const
|
|||||||
|
|
||||||
QString Peer::uid() const
|
QString Peer::uid() const
|
||||||
{
|
{
|
||||||
return ip + ':' + QString::number(port);
|
return ip.toString() + ':' + QString::number(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
libtorrent::entry Peer::toEntry(bool noPeerId) const
|
libtorrent::entry Peer::toEntry(bool noPeerId) const
|
||||||
@ -68,7 +68,7 @@ libtorrent::entry Peer::toEntry(bool noPeerId) const
|
|||||||
libtorrent::entry::dictionary_type peerMap;
|
libtorrent::entry::dictionary_type peerMap;
|
||||||
if (!noPeerId)
|
if (!noPeerId)
|
||||||
peerMap["id"] = libtorrent::entry(peerId.toStdString());
|
peerMap["id"] = libtorrent::entry(peerId.toStdString());
|
||||||
peerMap["ip"] = libtorrent::entry(ip.toStdString());
|
peerMap["ip"] = libtorrent::entry(ip.toString().toStdString());
|
||||||
peerMap["port"] = libtorrent::entry(port);
|
peerMap["port"] = libtorrent::entry(port);
|
||||||
|
|
||||||
return libtorrent::entry(peerMap);
|
return libtorrent::entry(peerMap);
|
||||||
@ -145,10 +145,12 @@ void Tracker::respondToAnnounceRequest()
|
|||||||
queryParams[paramName] = paramValue;
|
queryParams[paramName] = paramValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackerAnnounceRequest annonceReq;
|
TrackerAnnounceRequest announceReq;
|
||||||
|
|
||||||
// IP
|
// IP
|
||||||
annonceReq.peer.ip = m_env.clientAddress.toString();
|
// Use the "ip" parameter provided from tracker request first, then fall back to client IP if invalid
|
||||||
|
const QHostAddress paramIP {QString::fromLatin1(queryParams.value("ip"))};
|
||||||
|
announceReq.peer.ip = paramIP.isNull() ? m_env.clientAddress : paramIP;
|
||||||
|
|
||||||
// 1. Get info_hash
|
// 1. Get info_hash
|
||||||
if (!queryParams.contains("info_hash")) {
|
if (!queryParams.contains("info_hash")) {
|
||||||
@ -156,7 +158,7 @@ void Tracker::respondToAnnounceRequest()
|
|||||||
status(101, "Missing info_hash");
|
status(101, "Missing info_hash");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
annonceReq.infoHash = queryParams.value("info_hash");
|
announceReq.infoHash = queryParams.value("info_hash");
|
||||||
// info_hash cannot be longer than 20 bytes
|
// info_hash cannot be longer than 20 bytes
|
||||||
/*if (annonce_req.info_hash.toLatin1().length() > 20) {
|
/*if (annonce_req.info_hash.toLatin1().length() > 20) {
|
||||||
qDebug("Tracker: Info_hash is not 20 byte long: %s (%d)", qUtf8Printable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length());
|
qDebug("Tracker: Info_hash is not 20 byte long: %s (%d)", qUtf8Printable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length());
|
||||||
@ -170,7 +172,7 @@ void Tracker::respondToAnnounceRequest()
|
|||||||
status(102, "Missing peer_id");
|
status(102, "Missing peer_id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
annonceReq.peer.peerId = queryParams.value("peer_id");
|
announceReq.peer.peerId = queryParams.value("peer_id");
|
||||||
// peer_id cannot be longer than 20 bytes
|
// peer_id cannot be longer than 20 bytes
|
||||||
/*if (annonce_req.peer.peer_id.length() > 20) {
|
/*if (annonce_req.peer.peer_id.length() > 20) {
|
||||||
qDebug("Tracker: peer_id is not 20 byte long: %s", qUtf8Printable(annonce_req.peer.peer_id));
|
qDebug("Tracker: peer_id is not 20 byte long: %s", qUtf8Printable(annonce_req.peer.peer_id));
|
||||||
@ -185,52 +187,52 @@ void Tracker::respondToAnnounceRequest()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
annonceReq.peer.port = queryParams.value("port").toInt(&ok);
|
announceReq.peer.port = queryParams.value("port").toInt(&ok);
|
||||||
if (!ok || (annonceReq.peer.port < 0) || (annonceReq.peer.port > 65535)) {
|
if (!ok || (announceReq.peer.port < 0) || (announceReq.peer.port > 65535)) {
|
||||||
qDebug("Tracker: Invalid port number (%d)", annonceReq.peer.port);
|
qDebug("Tracker: Invalid port number (%d)", announceReq.peer.port);
|
||||||
status(103, "Missing port");
|
status(103, "Missing port");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Get event
|
// 4. Get event
|
||||||
annonceReq.event = "";
|
announceReq.event = "";
|
||||||
if (queryParams.contains("event")) {
|
if (queryParams.contains("event")) {
|
||||||
annonceReq.event = queryParams.value("event");
|
announceReq.event = queryParams.value("event");
|
||||||
qDebug("Tracker: event is %s", qUtf8Printable(annonceReq.event));
|
qDebug("Tracker: event is %s", qUtf8Printable(announceReq.event));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Get numwant
|
// 5. Get numwant
|
||||||
annonceReq.numwant = 50;
|
announceReq.numwant = 50;
|
||||||
if (queryParams.contains("numwant")) {
|
if (queryParams.contains("numwant")) {
|
||||||
int tmp = queryParams.value("numwant").toInt();
|
int tmp = queryParams.value("numwant").toInt();
|
||||||
if (tmp > 0) {
|
if (tmp > 0) {
|
||||||
qDebug("Tracker: numwant = %d", tmp);
|
qDebug("Tracker: numwant = %d", tmp);
|
||||||
annonceReq.numwant = tmp;
|
announceReq.numwant = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. no_peer_id (extension)
|
// 6. no_peer_id (extension)
|
||||||
annonceReq.noPeerId = false;
|
announceReq.noPeerId = false;
|
||||||
if (queryParams.contains("no_peer_id"))
|
if (queryParams.contains("no_peer_id"))
|
||||||
annonceReq.noPeerId = true;
|
announceReq.noPeerId = true;
|
||||||
|
|
||||||
// 7. TODO: support "compact" extension
|
// 7. TODO: support "compact" extension
|
||||||
|
|
||||||
// Done parsing, now let's reply
|
// Done parsing, now let's reply
|
||||||
if (annonceReq.event == "stopped") {
|
if (announceReq.event == "stopped") {
|
||||||
unregisterPeer(annonceReq);
|
unregisterPeer(announceReq);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
registerPeer(annonceReq);
|
registerPeer(announceReq);
|
||||||
replyWithPeerList(annonceReq);
|
replyWithPeerList(announceReq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tracker::registerPeer(const TrackerAnnounceRequest &annonceReq)
|
void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
if (annonceReq.peer.port == 0) return;
|
if (announceReq.peer.port == 0) return;
|
||||||
|
|
||||||
if (!m_torrents.contains(annonceReq.infoHash)) {
|
if (!m_torrents.contains(announceReq.infoHash)) {
|
||||||
// Unknown torrent
|
// Unknown torrent
|
||||||
if (m_torrents.size() == MAX_TORRENTS) {
|
if (m_torrents.size() == MAX_TORRENTS) {
|
||||||
// Reached max size, remove a random torrent
|
// Reached max size, remove a random torrent
|
||||||
@ -239,34 +241,34 @@ void Tracker::registerPeer(const TrackerAnnounceRequest &annonceReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register the user
|
// Register the user
|
||||||
PeerList &peers = m_torrents[annonceReq.infoHash];
|
PeerList &peers = m_torrents[announceReq.infoHash];
|
||||||
if (!peers.contains(annonceReq.peer.uid())) {
|
if (!peers.contains(announceReq.peer.uid())) {
|
||||||
// Unknown peer
|
// Unknown peer
|
||||||
if (peers.size() == MAX_PEERS_PER_TORRENT) {
|
if (peers.size() == MAX_PEERS_PER_TORRENT) {
|
||||||
// Too many peers, remove a random one
|
// Too many peers, remove a random one
|
||||||
peers.erase(peers.begin());
|
peers.erase(peers.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peers[annonceReq.peer.uid()] = annonceReq.peer;
|
peers[announceReq.peer.uid()] = announceReq.peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tracker::unregisterPeer(const TrackerAnnounceRequest &annonceReq)
|
void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
if (annonceReq.peer.port == 0) return;
|
if (announceReq.peer.port == 0) return;
|
||||||
|
|
||||||
if (m_torrents[annonceReq.infoHash].remove(annonceReq.peer.uid()) > 0)
|
if (m_torrents[announceReq.infoHash].remove(announceReq.peer.uid()) > 0)
|
||||||
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
|
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tracker::replyWithPeerList(const TrackerAnnounceRequest &annonceReq)
|
void Tracker::replyWithPeerList(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
// Prepare the entry for bencoding
|
// Prepare the entry for bencoding
|
||||||
libtorrent::entry::dictionary_type replyDict;
|
libtorrent::entry::dictionary_type replyDict;
|
||||||
replyDict["interval"] = libtorrent::entry(ANNOUNCE_INTERVAL);
|
replyDict["interval"] = libtorrent::entry(ANNOUNCE_INTERVAL);
|
||||||
|
|
||||||
libtorrent::entry::list_type peerList;
|
libtorrent::entry::list_type peerList;
|
||||||
for (const Peer &p : m_torrents.value(annonceReq.infoHash))
|
for (const Peer &p : m_torrents.value(announceReq.infoHash))
|
||||||
peerList.push_back(p.toEntry(annonceReq.noPeerId));
|
peerList.push_back(p.toEntry(announceReq.noPeerId));
|
||||||
replyDict["peers"] = libtorrent::entry(peerList);
|
replyDict["peers"] = libtorrent::entry(peerList);
|
||||||
|
|
||||||
const libtorrent::entry replyEntry(replyDict);
|
const libtorrent::entry replyEntry(replyDict);
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
|
||||||
#include "base/http/irequesthandler.h"
|
#include "base/http/irequesthandler.h"
|
||||||
#include "base/http/responsebuilder.h"
|
#include "base/http/responsebuilder.h"
|
||||||
@ -51,7 +52,7 @@ namespace BitTorrent
|
|||||||
{
|
{
|
||||||
struct Peer
|
struct Peer
|
||||||
{
|
{
|
||||||
QString ip;
|
QHostAddress ip;
|
||||||
QByteArray peerId;
|
QByteArray peerId;
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
@ -90,9 +91,9 @@ namespace BitTorrent
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void respondToAnnounceRequest();
|
void respondToAnnounceRequest();
|
||||||
void registerPeer(const TrackerAnnounceRequest &annonceReq);
|
void registerPeer(const TrackerAnnounceRequest &announceReq);
|
||||||
void unregisterPeer(const TrackerAnnounceRequest &annonceReq);
|
void unregisterPeer(const TrackerAnnounceRequest &announceReq);
|
||||||
void replyWithPeerList(const TrackerAnnounceRequest &annonceReq);
|
void replyWithPeerList(const TrackerAnnounceRequest &announceReq);
|
||||||
|
|
||||||
Http::Server *m_server;
|
Http::Server *m_server;
|
||||||
TorrentList m_torrents;
|
TorrentList m_torrents;
|
||||||
|
Loading…
Reference in New Issue
Block a user