File indexing completed on 2024-06-02 05:05:14
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "dhtpeersource.h" 0007 #include "announcetask.h" 0008 #include "dht.h" 0009 #include <QHostAddress> 0010 #include <interfaces/torrentinterface.h> 0011 #include <torrent/globals.h> 0012 #include <torrent/server.h> 0013 #include <util/functions.h> 0014 #include <util/log.h> 0015 0016 using namespace bt; 0017 0018 namespace dht 0019 { 0020 DHTPeerSource::DHTPeerSource(DHTBase &dh_table, const bt::SHA1Hash &info_hash, const QString &torrent_name) 0021 : dh_table(dh_table) 0022 , curr_task(nullptr) 0023 , info_hash(info_hash) 0024 , torrent_name(torrent_name) 0025 { 0026 connect(&timer, &QTimer::timeout, this, &DHTPeerSource::onTimeout); 0027 connect(&dh_table, &DHTBase::started, this, &DHTPeerSource::manualUpdate); 0028 connect(&dh_table, &DHTBase::stopped, this, &DHTPeerSource::dhtStopped); 0029 started = false; 0030 timer.setSingleShot(true); 0031 request_interval = 5 * 60 * 1000; 0032 } 0033 0034 DHTPeerSource::~DHTPeerSource() 0035 { 0036 if (curr_task) 0037 curr_task->kill(); 0038 } 0039 0040 void DHTPeerSource::start() 0041 { 0042 started = true; 0043 if (dh_table.isRunning()) 0044 doRequest(); 0045 } 0046 0047 void DHTPeerSource::dhtStopped() 0048 { 0049 stop(nullptr); 0050 curr_task = nullptr; 0051 } 0052 0053 void DHTPeerSource::stop(bt::WaitJob *) 0054 { 0055 started = false; 0056 if (curr_task) { 0057 curr_task->kill(); 0058 timer.stop(); 0059 } 0060 } 0061 0062 void DHTPeerSource::manualUpdate() 0063 { 0064 if (dh_table.isRunning() && started) 0065 doRequest(); 0066 } 0067 0068 bool DHTPeerSource::doRequest() 0069 { 0070 if (!dh_table.isRunning()) 0071 return false; 0072 0073 if (curr_task) 0074 return true; 0075 0076 Uint16 port = ServerInterface::getPort(); 0077 curr_task = dh_table.announce(info_hash, port); 0078 if (curr_task) { 0079 for (const bt::DHTNode &n : std::as_const(nodes)) 0080 curr_task->addDHTNode(n.ip, n.port); 0081 0082 connect(curr_task, &AnnounceTask::dataReady, this, &DHTPeerSource::onDataReady); 0083 connect(curr_task, &AnnounceTask::finished, this, &DHTPeerSource::onFinished); 0084 return true; 0085 } 0086 0087 return false; 0088 } 0089 0090 void DHTPeerSource::onFinished(Task *t) 0091 { 0092 if (curr_task == t) { 0093 onDataReady(curr_task); 0094 curr_task = nullptr; 0095 timer.start(request_interval); 0096 } 0097 } 0098 0099 void DHTPeerSource::onDataReady(Task *t) 0100 { 0101 if (curr_task == t) { 0102 Uint32 cnt = 0; 0103 DBItem item; 0104 while (curr_task->takeItem(item)) { 0105 const net::Address &addr = item.getAddress(); 0106 /* Out(SYS_DHT|LOG_NOTICE) << 0107 QString("DHT: Got potential peer %1 for torrent %2") 0108 .arg(addr.toString()).arg(tor->getStats().torrent_name) << endl;*/ 0109 addPeer(addr, false); 0110 cnt++; 0111 } 0112 0113 if (cnt) { 0114 Out(SYS_DHT | LOG_NOTICE) << QString("DHT: Got %1 potential peers for torrent %2").arg(cnt).arg(torrent_name) << endl; 0115 peersReady(this); 0116 } 0117 } 0118 } 0119 0120 void DHTPeerSource::onTimeout() 0121 { 0122 if (dh_table.isRunning() && started) 0123 doRequest(); 0124 } 0125 0126 void DHTPeerSource::addDHTNode(const bt::DHTNode &node) 0127 { 0128 nodes.append(node); 0129 } 0130 0131 void DHTPeerSource::setRequestInterval(Uint32 interval) 0132 { 0133 request_interval = interval; 0134 } 0135 0136 }