1 /* 2 * Bittorrent Client using Qt and libtorrent. 3 * Copyright (C) 2019 Mike Tzou (Chocobo1) 4 * Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru> 5 * Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * In addition, as a special exception, the copyright holders give permission to 22 * link this program with the OpenSSL project's "OpenSSL" library (or with 23 * modified versions of it that use the same license as the "OpenSSL" library), 24 * and distribute the linked executables. You must obey the GNU General Public 25 * License in all respects for all of the code used other than "OpenSSL". If you 26 * modify file(s), you may extend this exception to your version of the file(s), 27 * but you are not obligated to do so. If you do not wish to do so, delete this 28 * exception statement from your version. 29 */ 30 31 #pragma once 32 33 #include <string> 34 35 #include <libtorrent/entry.hpp> 36 37 #include <QHash> 38 #include <QObject> 39 #include <QSet> 40 41 #include "base/bittorrent/infohash.h" 42 #include "base/http/irequesthandler.h" 43 #include "base/http/responsebuilder.h" 44 45 namespace Http 46 { 47 class Server; 48 } 49 50 namespace BitTorrent 51 { 52 struct Peer 53 { 54 QByteArray peerId; 55 ushort port = 0; // self-claimed by peer, might not be the same as socket port 56 bool isSeeder = false; 57 58 // caching precomputed values 59 lt::entry::string_type address; 60 lt::entry::string_type endpoint; 61 62 QByteArray uniqueID() const; 63 }; 64 65 bool operator==(const Peer &left, const Peer &right); 66 bool operator!=(const Peer &left, const Peer &right); 67 uint qHash(const Peer &key, uint seed); 68 69 // *Basic* Bittorrent tracker implementation 70 // [BEP-3] The BitTorrent Protocol Specification 71 // also see: https://wiki.theory.org/index.php/BitTorrentSpecification#Tracker_HTTP.2FHTTPS_Protocol 72 class Tracker final : public QObject, public Http::IRequestHandler, private Http::ResponseBuilder 73 { 74 Q_OBJECT Q_DISABLE_COPY(Tracker)75 Q_DISABLE_COPY(Tracker) 76 77 struct TrackerAnnounceRequest; 78 79 struct TorrentStats 80 { 81 qint64 seeders = 0; 82 QSet<Peer> peers; 83 84 void setPeer(const Peer &peer); 85 bool removePeer(const Peer &peer); 86 }; 87 88 public: 89 explicit Tracker(QObject *parent = nullptr); 90 91 bool start(); 92 93 private: 94 Http::Response processRequest(const Http::Request &request, const Http::Environment &env) override; 95 void processAnnounceRequest(); 96 97 void registerPeer(const TrackerAnnounceRequest &announceReq); 98 void unregisterPeer(const TrackerAnnounceRequest &announceReq); 99 void prepareAnnounceResponse(const TrackerAnnounceRequest &announceReq); 100 101 Http::Server *m_server; 102 Http::Request m_request; 103 Http::Environment m_env; 104 105 QHash<TorrentID, TorrentStats> m_torrents; 106 }; 107 } 108