File indexing completed on 2024-06-02 05:05:34

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "tracker.h"
0007 
0008 #include <QRandomGenerator>
0009 #include <QUrl>
0010 
0011 #include "httptracker.h"
0012 #include "udptracker.h"
0013 #include <net/addressresolver.h>
0014 #include <torrent/globals.h>
0015 #include <torrent/server.h>
0016 #include <util/functions.h>
0017 #include <util/log.h>
0018 
0019 namespace bt
0020 {
0021 static QString custom_ip;
0022 static QString custom_ip_resolved;
0023 
0024 const Uint32 INITIAL_WAIT_TIME = 30;
0025 const Uint32 LONGER_WAIT_TIME = 300;
0026 const Uint32 FINAL_WAIT_TIME = 1800;
0027 
0028 Tracker::Tracker(const QUrl &url, TrackerDataSource *tds, const PeerID &id, int tier)
0029     : TrackerInterface(url)
0030     , tier(tier)
0031     , peer_id(id)
0032     , tds(tds)
0033 {
0034     key = QRandomGenerator::global()->generate();
0035     connect(&reannounce_timer, &QTimer::timeout, this, &Tracker::manualUpdate);
0036     reannounce_timer.setSingleShot(true);
0037     bytes_downloaded_at_start = bytes_uploaded_at_start = 0;
0038 }
0039 
0040 Tracker::~Tracker()
0041 {
0042 }
0043 
0044 void Tracker::setCustomIP(const QString &ip)
0045 {
0046     if (custom_ip == ip)
0047         return;
0048 
0049     Out(SYS_TRK | LOG_NOTICE) << "Setting custom ip to " << ip << endl;
0050     custom_ip = ip;
0051     custom_ip_resolved = QString();
0052     if (ip.isNull())
0053         return;
0054 
0055     if (custom_ip.endsWith(QLatin1String(".i2p"))) {
0056         custom_ip_resolved = custom_ip;
0057     } else {
0058         net::Address addr;
0059         if (addr.setAddress(ip))
0060             custom_ip_resolved = custom_ip;
0061         else
0062             custom_ip_resolved = net::AddressResolver::resolve(custom_ip, 7777).toString();
0063     }
0064 }
0065 
0066 QString Tracker::getCustomIP()
0067 {
0068     return custom_ip_resolved;
0069 }
0070 
0071 void Tracker::timedDelete(int ms)
0072 {
0073     QTimer::singleShot(ms, this, &Tracker::deleteLater);
0074     connect(this, &Tracker::stopDone, this, &Tracker::deleteLater);
0075 }
0076 
0077 void Tracker::failed(const QString &err)
0078 {
0079     error = err;
0080     status = TRACKER_ERROR;
0081     requestFailed(err);
0082 }
0083 
0084 void Tracker::handleFailure()
0085 {
0086     if (failureCount() > 5) {
0087         // we failed to contact the tracker 5 times in a row, so try again in
0088         // 30 minutes
0089         setInterval(FINAL_WAIT_TIME);
0090         reannounce_timer.start(FINAL_WAIT_TIME * 1000);
0091         request_time = QDateTime::currentDateTime();
0092     } else if (failureCount() > 2) {
0093         // we failed to contact the only tracker 3 times in a row, so try again in
0094         // a minute or 5, no need for hammering every 30 seconds
0095         setInterval(LONGER_WAIT_TIME);
0096         reannounce_timer.start(LONGER_WAIT_TIME * 1000);
0097         request_time = QDateTime::currentDateTime();
0098     } else {
0099         // lets not hammer and wait 30 seconds
0100         setInterval(INITIAL_WAIT_TIME);
0101         reannounce_timer.start(INITIAL_WAIT_TIME * 1000);
0102         request_time = QDateTime::currentDateTime();
0103     }
0104 }
0105 
0106 void Tracker::resetTrackerStats()
0107 {
0108     bytes_downloaded_at_start = tds->bytesDownloaded();
0109     bytes_uploaded_at_start = tds->bytesUploaded();
0110 }
0111 
0112 Uint64 Tracker::bytesDownloaded() const
0113 {
0114     Uint64 bd = tds->bytesDownloaded();
0115     if (bd > bytes_downloaded_at_start)
0116         return bd - bytes_downloaded_at_start;
0117     else
0118         return 0;
0119 }
0120 
0121 Uint64 Tracker::bytesUploaded() const
0122 {
0123     Uint64 bu = tds->bytesUploaded();
0124     if (bu > bytes_uploaded_at_start)
0125         return bu - bytes_uploaded_at_start;
0126     else
0127         return 0;
0128 }
0129 
0130 }
0131 
0132 #include "moc_tracker.cpp"