diff --git a/examples/ktcli/ktcli.h b/examples/ktcli/ktcli.h index 6627e2d..7de75e8 100644 --- a/examples/ktcli/ktcli.h +++ b/examples/ktcli/ktcli.h @@ -1,68 +1,68 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KTCLI_H #define KTCLI_H #include #include #include #include #include #include class QUrl; typedef boost::scoped_ptr TorrentControlPtr; class KTCLI : public QCoreApplication,public bt::QueueManagerInterface { Q_OBJECT public: KTCLI(int argc, char** argv); - virtual ~KTCLI(); + ~KTCLI() override; /// Start downloading bool start(); private: QString tempDir(); bool load(const QUrl &url); bool loadFromFile(const QString & path); bool loadFromDir(const QString & path); - virtual bool notify(QObject* obj, QEvent* ev); - virtual bool alreadyLoaded(const bt::SHA1Hash& ih) const; - virtual void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk); + bool notify(QObject* obj, QEvent* ev) override; + bool alreadyLoaded(const bt::SHA1Hash& ih) const override; + void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk) override; public Q_SLOTS: void update(); void finished(bt::TorrentInterface* tor); void shutdown(); private: QCommandLineParser parser; QTimer timer; TorrentControlPtr tc; int updates; }; #endif // KTCLI_H diff --git a/src/bcodec/bencoder.h b/src/bcodec/bencoder.h index 57d3c4a..409e70f 100644 --- a/src/bcodec/bencoder.h +++ b/src/bcodec/bencoder.h @@ -1,187 +1,187 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTBENCODER_H #define BTBENCODER_H #include #include class QIODevice; namespace bt { class File; /** * @author Joris Guisson * * Interface for classes which wish to receive the output from a BEncoder. */ class KTORRENT_EXPORT BEncoderOutput { public: virtual ~BEncoderOutput() {} /** * Write a string of characters. * @param str The string * @param len The length of the string */ virtual void write(const char* str,Uint32 len) = 0; }; /** * Writes the output of a bencoder to a file */ class KTORRENT_EXPORT BEncoderFileOutput : public BEncoderOutput { File* fptr; public: BEncoderFileOutput(File* fptr); - void write(const char* str,Uint32 len); + void write(const char* str,Uint32 len) override; }; /** * Write the output of a BEncoder to a QByteArray */ class KTORRENT_EXPORT BEncoderBufferOutput : public BEncoderOutput { QByteArray & data; Uint32 ptr; public: BEncoderBufferOutput(QByteArray & data); - void write(const char* str,Uint32 len); + void write(const char* str,Uint32 len) override; }; class KTORRENT_EXPORT BEncoderIODeviceOutput : public BEncoderOutput { QIODevice* dev; public: BEncoderIODeviceOutput(QIODevice* dev); - void write(const char* str,Uint32 len); + void write(const char* str,Uint32 len) override; }; /** * @author Joris Guisson * @brief Helper class to b-encode stuff. * * This class b-encodes data. For more details about b-encoding, see * the BitTorrent protocol docs. The data gets written to a BEncoderOutput * thing. */ class KTORRENT_EXPORT BEncoder { BEncoderOutput* out; bool del; public: /** * Constructor, output gets written to a file. * @param fptr The File to write to */ BEncoder(File* fptr); /** * Constructor, output gets written to a BEncoderOutput object. * @param out The BEncoderOutput */ BEncoder(BEncoderOutput* out); /** * Constructor, output gets written to a QIODevice object. * @param dev The QIODevice */ BEncoder(QIODevice* dev); virtual ~BEncoder(); /** * Begin a dictionary.Should have a corresponding end call. */ void beginDict(); /** * Begin a list. Should have a corresponding end call. */ void beginList(); template void write(const QByteArray& key,T val) { write(key); write(val); } /** * Write a boolean (is encoded as an intà * @param val */ void write(bool val); /** * Write a float * @param val */ void write(float val); /** * Write an int * @param val */ void write(Uint32 val); /** * Write an int64 * @param val */ void write(Uint64 val); private: /** * Write a string * @param str */ void write(const char* str); public: /** * Write a QByteArray * @param data */ void write(const QByteArray & data); /** * Write a data array * @param data * @param size of data */ void write(const Uint8* data,Uint32 size); /** * End a beginDict or beginList call. */ void end(); }; } #endif diff --git a/src/bcodec/bnode.h b/src/bcodec/bnode.h index 216b519..8d36c40 100644 --- a/src/bcodec/bnode.h +++ b/src/bcodec/bnode.h @@ -1,232 +1,232 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTBNODE_H #define BTBNODE_H #include #include #include #include #include #include "value.h" namespace bt { class BListNode; /** * @author Joris Guisson * @brief Base class for a node in a b-encoded piece of data * * There are 3 possible pieces of data in b-encoded piece of data. * This is the base class for all those 3 things. */ class KTORRENT_EXPORT BNode { public: enum Type { VALUE,DICT,LIST }; /** * Constructor, sets the Type, and the offset into * the data. * @param type Type of node * @param off The offset into the data */ BNode(Type type,Uint32 off); virtual ~BNode(); /// Get the type of node Type getType() const {return type;} /// Get the offset in the bytearray where this node starts. Uint32 getOffset() const {return off;} /// Get the length this node takes up in the bytearray. Uint32 getLength() const {return len;} /// Set the length void setLength(Uint32 l) {len = l;} /// Print some debugging info virtual void printDebugInfo() = 0; private: Type type; Uint32 off,len; }; /** * @author Joris Guisson * @brief Represents a value (string,bytearray or int) in bencoded data * * @todo Use QVariant */ class KTORRENT_EXPORT BValueNode : public BNode { Value value; public: BValueNode(const Value & v,Uint32 off); - virtual ~BValueNode(); + ~BValueNode() override; const Value & data() const {return value;} - void printDebugInfo(); + void printDebugInfo() override; }; /** * @author Joris Guisson * @brief Represents a dictionary in bencoded data * */ class KTORRENT_EXPORT BDictNode : public BNode { struct DictEntry { QByteArray key; BNode* node; }; QList children; public: BDictNode(Uint32 off); - virtual ~BDictNode(); + ~BDictNode() override; /// Get a list of keys QList keys() const; /** * Insert a BNode in the dictionary. * @param key The key * @param node The node */ void insert(const QByteArray & key,BNode* node); /** * Get a BNode. * @param key The key * @return The node or 0 if there is no node with has key @a key */ BNode* getData(const QByteArray & key); /** * Get a BListNode. * @param key The key * @return The node or 0 if there is no list node with has key @a key */ BListNode* getList(const QByteArray& key); /** * Get a BDictNode. * @param key The key * @return The node or 0 if there is no dict node with has key @a key */ BDictNode* getDict(const QByteArray& key); /** * Get a BValueNode. * @param key The key * @return The node or 0 if there is no value node with has key @a key */ BValueNode* getValue(const QByteArray& key); /// Same as getValue, except directly returns an int, if something goes wrong, an error will be thrown int getInt(const QByteArray& key); /// Same as getValue, except directly returns a qint64, if something goes wrong, an error will be thrown qint64 getInt64(const QByteArray& key); /// Same as getValue, except directly returns a QString, if something goes wrong, an error will be thrown QString getString(const QByteArray& key,QTextCodec* tc); /// Same as getValue, except directly returns an QByteArray, if something goes wrong, an error will be thrown QByteArray getByteArray(const QByteArray& key); - void printDebugInfo(); + void printDebugInfo() override; }; /** * @author Joris Guisson * @brief Represents a list in bencoded data * */ class KTORRENT_EXPORT BListNode : public BNode { QList children; public: BListNode(Uint32 off); - virtual ~BListNode(); + ~BListNode() override; /** * Append a node to the list. * @param node The node */ void append(BNode* node); - void printDebugInfo(); + void printDebugInfo() override; /// Get the number of nodes in the list. Uint32 getNumChildren() const {return children.count();} /** * Get a node from the list * @param idx The index * @return The node or 0 if idx is out of bounds */ BNode* getChild(Uint32 idx) {return children.at(idx);} /** * Get a BListNode. * @param idx The index * @return The node or 0 if the index is out of bounds or the element * at postion @a idx isn't a BListNode. */ BListNode* getList(Uint32 idx); /** * Get a BDictNode. * @param idx The index * @return The node or 0 if the index is out of bounds or the element * at postion @a idx isn't a BDictNode. */ BDictNode* getDict(Uint32 idx); /** * Get a BValueNode. * @param idx The index * @return The node or 0 if the index is out of bounds or the element * at postion @a idx isn't a BValueNode. */ BValueNode* getValue(Uint32 idx); /// Same as getValue, except directly returns an int, if something goes wrong, an error will be thrown int getInt(Uint32 idx); /// Same as getValue, except directly returns a qint64, if something goes wrong, an error will be thrown qint64 getInt64(Uint32 idx); /// Same as getValue, except directly returns a QString, if something goes wrong, an error will be thrown QString getString(Uint32 idx,QTextCodec* tc); /// Same as getValue, except directly returns an QByteArray, if something goes wrong, an error will be thrown QByteArray getByteArray(Uint32 idx); }; } #endif diff --git a/src/datachecker/datachecker.h b/src/datachecker/datachecker.h index c3c3d23..aa0d2d4 100644 --- a/src/datachecker/datachecker.h +++ b/src/datachecker/datachecker.h @@ -1,95 +1,95 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTDATACHECKER_H #define BTDATACHECKER_H #include #include #include class QString; namespace bt { class Torrent; /** * @author Joris Guisson * * Checks which data is downloaded, given a torrent and a file or directory containing * files of the torrent. */ class KTORRENT_EXPORT DataChecker : public QObject { Q_OBJECT public: DataChecker(bt::Uint32 from, bt::Uint32 to); - virtual ~DataChecker(); + ~DataChecker() override; /** * Check to see which chunks have been downloaded of a torrent, and which chunks fail. * The corresponding bitsets should be filled with this information. * If anything goes wrong and Error should be thrown. * @param path path to the file or dir (this needs to end with the name suggestion of the torrent) * @param tor The torrent * @param dnddir DND dir, optional argument if we know this * @param current_status Current status of the torrent */ virtual void check(const QString & path,const Torrent & tor,const QString & dnddir,const BitSet & current_status) = 0; /** * Get the BitSet representing all the downloaded chunks and which is the result of the data check. */ const BitSet & getResult() const {return result;} /// Stop an ongoing check void stop() {need_to_stop = true;} Q_SIGNALS: /** * Emitted when a chunk has been proccessed. * @param num The number processed * @param total The total number of pieces to process */ void progress(quint32 num,quint32 total); /** * Emitted when a failed or dowloaded chunk is found. * @param num_failed The number of failed chunks * @param num_found The number of found chunks * @param num_downloaded Number of downloaded chunks * @param num_not_downloaded Number of not downloaded chunks */ void status(quint32 num_failed,quint32 num_found,quint32 num_downloaded,quint32 num_not_downloaded); protected: BitSet result; Uint32 failed,found,downloaded,not_downloaded; bool need_to_stop; bt::Uint32 from; bt::Uint32 to; }; } #endif diff --git a/src/datachecker/datacheckerjob.h b/src/datachecker/datacheckerjob.h index 11a2438..bf885d3 100644 --- a/src/datachecker/datacheckerjob.h +++ b/src/datachecker/datacheckerjob.h @@ -1,74 +1,74 @@ /*************************************************************************** * Copyright (C) 2009 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_DATACHECKERJOB_H #define BT_DATACHECKERJOB_H #include #include namespace bt { class DataCheckerThread; /// Job which runs a DataChecker class KTORRENT_EXPORT DataCheckerJob : public bt::Job, public Resource { Q_OBJECT public: DataCheckerJob(bool auto_import,TorrentControl* tc, bt::Uint32 from, bt::Uint32 to); - virtual ~DataCheckerJob(); + ~DataCheckerJob() override; - virtual void start(); - virtual void kill(bool quietly = true); - virtual TorrentStatus torrentStatus() const {return CHECKING_DATA;} + void start() override; + void kill(bool quietly = true) override; + TorrentStatus torrentStatus() const override {return CHECKING_DATA;} /// Is this an automatic import bool isAutoImport() const {return auto_import;} /// Was the job stopped bool isStopped() const {return killed;} /// Get the first chunk the datacheck was started from bt::Uint32 firstChunk() const {return from;} /// Get the last chunk of the datacheck bt::Uint32 lastChunk() const {return to;} private Q_SLOTS: void threadFinished(); void progress(quint32 num, quint32 total); void status(quint32 num_failed, quint32 num_found, quint32 num_downloaded, quint32 num_not_downloaded); private: - virtual void acquired(); + void acquired() override; private: DataCheckerThread* dcheck_thread; bool killed; bool auto_import; bool started; bt::Uint32 from; bt::Uint32 to; }; } #endif // BT_DATACHECKERJOB_H diff --git a/src/datachecker/datacheckerthread.h b/src/datachecker/datacheckerthread.h index c0a5bb6..23464cc 100644 --- a/src/datachecker/datacheckerthread.h +++ b/src/datachecker/datacheckerthread.h @@ -1,64 +1,64 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTDATACHECKERTHREAD_H #define BTDATACHECKERTHREAD_H #include #include #include namespace bt { class Torrent; class DataChecker; /** @author Joris Guisson Thread which runs the data check. */ class KTORRENT_EXPORT DataCheckerThread : public QThread { DataChecker* dc; QString path; const Torrent & tor; QString dnddir; bool running; QString error; BitSet status; public: DataCheckerThread(DataChecker* dc,const BitSet & status,const QString & path,const Torrent & tor,const QString & dnddir); - virtual ~DataCheckerThread(); + ~DataCheckerThread() override; - virtual void run(); + void run() override; /// Get the data checker DataChecker* getDataChecker() {return dc;} /// Are we still running bool isRunning() const {return running;} /// Get the error (if any occurred) QString getError() const {return error;} }; } #endif diff --git a/src/datachecker/multidatachecker.h b/src/datachecker/multidatachecker.h index d6bcada..0d9e64f 100644 --- a/src/datachecker/multidatachecker.h +++ b/src/datachecker/multidatachecker.h @@ -1,55 +1,55 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTMULTIDATACHECKER_H #define BTMULTIDATACHECKER_H #include #include #include #include "datachecker.h" namespace bt { /** @author Joris Guisson */ class KTORRENT_EXPORT MultiDataChecker : public DataChecker { public: MultiDataChecker(bt::Uint32 from, bt::Uint32 to); - virtual ~MultiDataChecker(); + ~MultiDataChecker() override; - virtual void check(const QString& path, const Torrent& tor,const QString & dnddir,const BitSet & current_status); + void check(const QString& path, const Torrent& tor,const QString & dnddir,const BitSet & current_status) override; private: bool loadChunk(Uint32 ci,Uint32 cs,const Torrent & to); File::Ptr open(const Torrent & tor,Uint32 idx); void closePastFiles(Uint32 min_idx); private: QString cache; QString dnd_dir; Uint8* buf; QMap files; }; } #endif diff --git a/src/datachecker/singledatachecker.h b/src/datachecker/singledatachecker.h index 4c3191d..395b9bf 100644 --- a/src/datachecker/singledatachecker.h +++ b/src/datachecker/singledatachecker.h @@ -1,44 +1,44 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTSINGLEDATACHECKER_H #define BTSINGLEDATACHECKER_H #include "datachecker.h" namespace bt { /** * @author Joris Guisson * * Data checker for single file torrents. */ class KTORRENT_EXPORT SingleDataChecker : public DataChecker { public: SingleDataChecker(bt::Uint32 from, bt::Uint32 to); - virtual ~SingleDataChecker(); + ~SingleDataChecker() override; - virtual void check(const QString& path, const Torrent& tor,const QString & dnddir,const BitSet & current_status); + void check(const QString& path, const Torrent& tor,const QString & dnddir,const BitSet & current_status) override; }; } #endif diff --git a/src/dht/announcereq.h b/src/dht/announcereq.h index e9ce44f..890c541 100644 --- a/src/dht/announcereq.h +++ b/src/dht/announcereq.h @@ -1,56 +1,56 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_ANNOUNCEREQ_H #define DHT_ANNOUNCEREQ_H #include "getpeersreq.h" namespace dht { /** * Announce request in the DHT protocol */ class KTORRENT_EXPORT AnnounceReq : public GetPeersReq { public: AnnounceReq(); AnnounceReq(const Key & id,const Key & info_hash,bt::Uint16 port,const Key & token); - virtual ~AnnounceReq(); + ~AnnounceReq() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; const Key & getToken() const {return token;} bt::Uint16 getPort() const {return port;} typedef QSharedPointer Ptr; private: bt::Uint16 port; Key token; }; } #endif // DHT_ANNOUNCEREQ_H diff --git a/src/dht/announcersp.h b/src/dht/announcersp.h index 3fe5752..f988d4b 100644 --- a/src/dht/announcersp.h +++ b/src/dht/announcersp.h @@ -1,48 +1,48 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_ANNOUNCERSP_H #define DHT_ANNOUNCERSP_H #include "rpcmsg.h" namespace dht { /** * Announce response message */ class KTORRENT_EXPORT AnnounceRsp : public RPCMsg { public: AnnounceRsp(); AnnounceRsp(const QByteArray & mtid,const Key & id); - virtual ~AnnounceRsp(); + ~AnnounceRsp() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; typedef QSharedPointer Ptr; }; } #endif // DHT_ANNOUNCERSP_H diff --git a/src/dht/announcetask.h b/src/dht/announcetask.h index 92ad0fd..e8ed3d6 100644 --- a/src/dht/announcetask.h +++ b/src/dht/announcetask.h @@ -1,86 +1,86 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTANNOUNCETASK_H #define DHTANNOUNCETASK_H #include "kbucket.h" #include "task.h" namespace dht { class Database; class KBucketEntryAndToken : public KBucketEntry { Key token; public: KBucketEntryAndToken() {} KBucketEntryAndToken(const KBucketEntry & e, const Key & token) : KBucketEntry(e), token(token) {} - virtual ~KBucketEntryAndToken() {} + ~KBucketEntryAndToken() override {} const Key & getToken() const { return token; } }; /** @author Joris Guisson */ class AnnounceTask : public Task { public: AnnounceTask(Database* db, RPCServer* rpc, Node* node, const dht::Key & info_hash, bt::Uint16 port, QObject* parent); - virtual ~AnnounceTask(); + ~AnnounceTask() override; - virtual void callFinished(RPCCall* c, RPCMsg::Ptr rsp); - virtual void callTimeout(RPCCall* c); - virtual void update(); + void callFinished(RPCCall* c, RPCMsg::Ptr rsp) override; + void callTimeout(RPCCall* c) override; + void update() override; /** * Take one item from the returned values. * Returns false if there is no item to take. * @param item The item * @return false if no item to take, true else */ bool takeItem(DBItem & item); private: void handleNodes(const QByteArray & nodes, int ip_version); private: dht::Key info_hash; bt::Uint16 port; std::set answered; // nodes which have answered with values KBucketEntrySet answered_visited; // nodes which have answered with values which have been visited Database* db; DBItemList returned_items; }; } #endif diff --git a/src/dht/dht.h b/src/dht/dht.h index 40dfee4..30a41e3 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h @@ -1,139 +1,139 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTDHT_H #define DHTDHT_H #include #include #include #include #include #include "key.h" #include "dhtbase.h" #include "rpcmsg.h" namespace net { class AddressResolver; } namespace bt { class SHA1Hash; } namespace dht { class Node; class RPCServer; class Database; class TaskManager; class Task; class AnnounceTask; class NodeLookup; class KBucket; class ErrMsg; class PingReq; class FindNodeReq; class GetPeersReq; class AnnounceReq; /** @author Joris Guisson */ class DHT : public DHTBase { Q_OBJECT public: DHT(); - virtual ~DHT(); + ~DHT() override; void ping(const PingReq & r); void findNode(const FindNodeReq & r); void response(const RPCMsg & r); void getPeers(const GetPeersReq & r); void announce(const AnnounceReq & r); void error(const ErrMsg & r); void timeout(RPCMsg::Ptr r); /** * A Peer has received a PORT message, and uses this function to alert the DHT of it. * @param ip The IP of the peer * @param port The port in the PORT message */ - void portReceived(const QString & ip,bt::Uint16 port); + void portReceived(const QString & ip,bt::Uint16 port) override; /** * Do an announce on the DHT network * @param info_hash The info_hash * @param port The port * @return The task which handles this */ - AnnounceTask* announce(const bt::SHA1Hash & info_hash,bt::Uint16 port); + AnnounceTask* announce(const bt::SHA1Hash & info_hash,bt::Uint16 port) override; /** * Refresh a bucket using a find node task. * @param id The id * @param bucket The bucket to refresh */ NodeLookup* refreshBucket(const dht::Key & id,KBucket & bucket); /** * Do a NodeLookup. * @param id The id of the key to search */ NodeLookup* findNode(const dht::Key & id); /// Do a findNode for our node id NodeLookup* findOwnNode(); /// See if it is possible to start a task bool canStartTask() const; - void start(const QString & table,const QString & key_file,bt::Uint16 port); - void stop(); - void addDHTNode(const QString & host,bt::Uint16 hport); + void start(const QString & table,const QString & key_file,bt::Uint16 port) override; + void stop() override; + void addDHTNode(const QString & host,bt::Uint16 hport) override; - virtual QMap getClosestGoodNodes(int maxNodes); + QMap getClosestGoodNodes(int maxNodes) override; /// Bootstrap from well-known nodes void bootstrap(); private Q_SLOTS: - void update(); + void update() override; void onResolverResults(net::AddressResolver* ar); void ownNodeLookupFinished(Task* t); void expireDatabaseItems(); private: Node* node; RPCServer* srv; Database* db; TaskManager* tman; QTimer expire_timer; QString table_file; QTimer update_timer; NodeLookup* our_node_lookup; }; } #endif diff --git a/src/dht/dhtbase.h b/src/dht/dhtbase.h index 7b52b04..fa38c2f 100644 --- a/src/dht/dhtbase.h +++ b/src/dht/dhtbase.h @@ -1,130 +1,130 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTDHTBASE_H #define DHTDHTBASE_H #include #include #include class QString; namespace bt { class SHA1Hash; } namespace dht { class AnnounceTask; struct Stats { /// number of peers in the routing table bt::Uint32 num_peers; /// Number of running tasks bt::Uint32 num_tasks; }; /** * @author Joris Guisson * * Interface for DHT class, this is to keep other things separate from the inner workings * of the DHT. */ class DHTBase : public QObject { Q_OBJECT public: DHTBase(); - virtual ~DHTBase(); + ~DHTBase() override; /** * Start the DHT * @param table File where the save table is located * @param key_file Where our DHT key is stored * @param port The port to use */ virtual void start(const QString & table,const QString & key_file,bt::Uint16 port) = 0; /** * Stop the DHT */ virtual void stop() = 0; /** * Update the DHT */ virtual void update() = 0; /** * A Peer has received a PORT message, and uses this function to alert the DHT of it. * @param ip The IP of the peer * @param port The port in the PORT message */ virtual void portReceived(const QString & ip,bt::Uint16 port) = 0; /** * Do an announce on the DHT network * @param info_hash The info_hash * @param port The port * @return The task which handles this */ virtual AnnounceTask* announce(const bt::SHA1Hash & info_hash,bt::Uint16 port) = 0; /** * See if the DHT is running. */ bool isRunning() const {return running;} /// Get the DHT port bt::Uint16 getPort() const {return port;} /// Get statistics about the DHT const dht::Stats & getStats() const {return stats;} /** * Add a DHT node. This node shall be pinged immediately. * @param host The hostname or ip * @param hport The port of the host */ virtual void addDHTNode(const QString & host,bt::Uint16 hport) = 0; /** * Returns maxNodes number of nodes * that are closest to ourselves and are good. * @param maxNodes maximum nr of nodes in QMap to return. */ virtual QMap getClosestGoodNodes(int maxNodes) = 0; Q_SIGNALS: void started(); void stopped(); protected: bool running; bt::Uint16 port; dht::Stats stats; }; } #endif diff --git a/src/dht/dhtpeersource.h b/src/dht/dhtpeersource.h index a2c46f3..6f0b99f 100644 --- a/src/dht/dhtpeersource.h +++ b/src/dht/dhtpeersource.h @@ -1,79 +1,79 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTDHTPEERSOURCE_H #define DHTDHTPEERSOURCE_H #include #include #include "task.h" namespace bt { class WaitJob; struct DHTNode; } namespace dht { class DHTBase; class AnnounceTask; /** @author Joris Guisson */ class KTORRENT_EXPORT DHTPeerSource : public bt::PeerSource { Q_OBJECT public: DHTPeerSource(DHTBase & dh_table,const bt::SHA1Hash & info_hash,const QString & torrent_name); - virtual ~DHTPeerSource(); + ~DHTPeerSource() override; - virtual void start(); - virtual void stop(bt::WaitJob* wjob = 0); - virtual void manualUpdate(); + void start() override; + void stop(bt::WaitJob* wjob = 0) override; + void manualUpdate() override; void addDHTNode(const bt::DHTNode & node); void setRequestInterval(bt::Uint32 interval); private Q_SLOTS: void onTimeout(); bool doRequest(); void onDataReady(Task* t); void onFinished(Task* t); void dhtStopped(); private: DHTBase & dh_table; AnnounceTask* curr_task; bt::SHA1Hash info_hash; QTimer timer; bool started; QList nodes; QString torrent_name; bt::Uint32 request_interval; }; } #endif diff --git a/src/dht/errmsg.h b/src/dht/errmsg.h index 54cece3..d4787d5 100644 --- a/src/dht/errmsg.h +++ b/src/dht/errmsg.h @@ -1,53 +1,53 @@ /*************************************************************************** * Copyright (C) 2012 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_ERRMSG_H #define DHT_ERRMSG_H #include "rpcmsg.h" namespace dht { /** * Error message in the DHT protocol */ class KTORRENT_EXPORT ErrMsg : public RPCMsg { public: ErrMsg(); ErrMsg(const QByteArray& mtid, const dht::Key& id, const QString& msg); - virtual ~ErrMsg(); + ~ErrMsg() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; /// Get the error message const QString & message() const {return msg;} typedef QSharedPointer Ptr; private: QString msg; }; } #endif // DHT_ERRMSG_H diff --git a/src/dht/findnodereq.h b/src/dht/findnodereq.h index 276213a..7a5b8a3 100644 --- a/src/dht/findnodereq.h +++ b/src/dht/findnodereq.h @@ -1,56 +1,56 @@ /*************************************************************************** * Copyright (C) 2012 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_FINDNODEREQ_H #define DHT_FINDNODEREQ_H #include #include "rpcmsg.h" namespace dht { /** * FindNode request in the DHT protocol */ class KTORRENT_EXPORT FindNodeReq : public RPCMsg { public: FindNodeReq(); FindNodeReq(const Key & id, const Key & target); - virtual ~FindNodeReq(); + ~FindNodeReq() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; const Key & getTarget() const {return target;} bool wants(int ip_version) const; typedef QSharedPointer Ptr; private: Key target; QStringList want; }; } #endif // DHT_FINDNODEREQ_H diff --git a/src/dht/findnodersp.h b/src/dht/findnodersp.h index 2789752..f4ab790 100644 --- a/src/dht/findnodersp.h +++ b/src/dht/findnodersp.h @@ -1,53 +1,53 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_FINDNODERSP_H #define DHT_FINDNODERSP_H #include "rpcmsg.h" #include "packednodecontainer.h" namespace dht { /** * FindNode response message for DHT */ class KTORRENT_EXPORT FindNodeRsp : public RPCMsg, public PackedNodeContainer { public: FindNodeRsp(); FindNodeRsp(const QByteArray & mtid, const Key & id); - virtual ~FindNodeRsp(); + ~FindNodeRsp() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; typedef QSharedPointer Ptr; }; } #endif // DHT_FINDNODERSP_H diff --git a/src/dht/getpeersreq.h b/src/dht/getpeersreq.h index aa5fc52..05b0573 100644 --- a/src/dht/getpeersreq.h +++ b/src/dht/getpeersreq.h @@ -1,57 +1,57 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_GETPEERSREQ_H #define DHT_GETPEERSREQ_H #include #include "rpcmsg.h" namespace dht { /** * GetPeers request in the DHT protocol */ class KTORRENT_EXPORT GetPeersReq : public RPCMsg { public: GetPeersReq(); GetPeersReq(const Key & id,const Key & info_hash); - virtual ~GetPeersReq(); + ~GetPeersReq() override; const Key & getInfoHash() const {return info_hash;} bool wants(int ip_version) const; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; typedef QSharedPointer Ptr; protected: Key info_hash; QStringList want; }; } #endif // DHT_GETPEERSREQ_H diff --git a/src/dht/getpeersrsp.h b/src/dht/getpeersrsp.h index 0d8e0a4..51a4efa 100644 --- a/src/dht/getpeersrsp.h +++ b/src/dht/getpeersrsp.h @@ -1,60 +1,60 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_GETPEERSRSP_H #define DHT_GETPEERSRSP_H #include "rpcmsg.h" #include "packednodecontainer.h" namespace dht { /** * GetPeers response message */ class KTORRENT_EXPORT GetPeersRsp : public RPCMsg, public PackedNodeContainer { public: GetPeersRsp(); GetPeersRsp(const QByteArray & mtid, const Key & id, const Key & token); GetPeersRsp(const QByteArray & mtid, const Key & id, const DBItemList & values, const Key & token); - virtual ~GetPeersRsp(); + ~GetPeersRsp() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; - virtual void parse(bt::BDictNode* dict); + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; + void parse(bt::BDictNode* dict) override; const DBItemList & getItemList() const {return items;} const Key & getToken() const {return token;} bool containsNodes() const {return nodes.size() > 0 || nodes6.size() > 0;} bool containsValues() const {return nodes.size() == 0;} typedef QSharedPointer Ptr; private: Key token; DBItemList items; }; } #endif // DHT_GETPEERSRSP_H diff --git a/src/dht/kbucket.h b/src/dht/kbucket.h index 18f734b..e87c990 100644 --- a/src/dht/kbucket.h +++ b/src/dht/kbucket.h @@ -1,158 +1,158 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTKBUCKET_H #define DHTKBUCKET_H #include #include #include #include #include "key.h" #include "rpccall.h" #include "kbucketentry.h" namespace bt { class BEncoder; } namespace dht { class RPCServerInterface; class KClosestNodesSearch; class Task; const bt::Uint32 K = 20; const bt::Uint32 BUCKET_MAGIC_NUMBER = 0xB0C4B0C4; const bt::Uint32 BUCKET_REFRESH_INTERVAL = 15 * 60 * 1000; /** * @author Joris Guisson * * A KBucket is just a list of KBucketEntry objects. * The list is sorted by time last seen : * The first element is the least recently seen, the last * the most recently seen. */ class KBucket : public RPCCallListener { Q_OBJECT public: KBucket(RPCServerInterface* srv, const Key & our_id); KBucket(const dht::Key & min_key, const dht::Key & max_key, RPCServerInterface* srv, const Key & our_id); - virtual ~KBucket(); + ~KBucket() override; typedef QSharedPointer Ptr; /// Get the min key const dht::Key & minKey() const {return min_key;} /// Get the max key const dht::Key & maxKey() const {return max_key;} /// Does the key k lies in in the range of this bucket bool keyInRange(const dht::Key & k) const; /// Are we allowed to split bool splitAllowed() const; class UnableToSplit {}; /** * Split the bucket in two new buckets, each containing half the range of the original one. * @return A pair of KBucket's * @throw UnableToSplit if something goes wrong */ std::pair split() throw (UnableToSplit); /** * Inserts an entry into the bucket. * @param entry The entry to insert * @return true If the bucket needs to be split, false otherwise */ bool insert(const KBucketEntry & entry); /// Get the least recently seen node const KBucketEntry & leastRecentlySeen() const {return entries[0];} /// Get the number of entries bt::Uint32 getNumEntries() const {return entries.count();} /// See if this bucket contains an entry bool contains(const KBucketEntry & entry) const; /** * Find the K closest entries to a key and store them in the KClosestNodesSearch * object. * @param kns The object to storre the search results */ void findKClosestNodes(KClosestNodesSearch & kns); /** * A peer failed to respond * @param addr Address of the peer */ bool onTimeout(const net::Address & addr); /// Check if the bucket needs to be refreshed bool needsToBeRefreshed() const; /// save the bucket to a file void save(bt::BEncoder & enc); /// Load the bucket from a file void load(bt::BDictNode* dict); /// Update the refresh timer of the bucket void updateRefreshTimer(); /// Set the refresh task void setRefreshTask(Task* t); private: - virtual void onResponse(RPCCall* c, RPCMsg::Ptr rsp); - virtual void onTimeout(RPCCall* c); + void onResponse(RPCCall* c, RPCMsg::Ptr rsp) override; + void onTimeout(RPCCall* c) override; void pingQuestionable(const KBucketEntry & replacement_entry); bool replaceBadEntry(const KBucketEntry & entry); private Q_SLOTS: void onFinished(Task* t); private: dht::Key min_key, max_key; QList entries, pending_entries; RPCServerInterface* srv; Key our_id; QMap pending_entries_busy_pinging; mutable bt::TimeStamp last_modified; Task* refresh_task; }; } template inline uint qHash(const T & e) { return e.hash(); } #endif diff --git a/src/dht/key.h b/src/dht/key.h index f0a3919..12bc1de 100644 --- a/src/dht/key.h +++ b/src/dht/key.h @@ -1,169 +1,169 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTKEY_H #define DHTKEY_H #include #include #include namespace dht { /** * @author Joris Guisson * @brief Key in the distributed hash table * * Key's in the distributed hash table are just SHA-1 hashes. * Key provides all necesarry operators to be used as a value. */ class KTORRENT_EXPORT Key : public bt::SHA1Hash { public: /** * Constructor, sets key to 0. */ Key(); /** * Copy constructor. Seeing that Key doesn't add any data * we just pass a SHA1Hash, Key's are automatically covered by this * @param k Hash to copy */ Key(const bt::SHA1Hash & k); /** * Make a key out of a bytearray * @param ba The QByteArray */ Key(const QByteArray & ba); /** * Make a key out of a 20 byte array. * @param d The array */ Key(const bt::Uint8* d); /// Destructor. - virtual ~Key(); + ~Key() override; /** * Create a random key. * @return A random Key */ static Key random(); /// Get the minimum key (all zeros) static Key min(); /// Get the maximum key (all FF) static Key max(); /** * Equality operator. * @param other The key to compare * @return true if this key is equal to other */ bool operator == (const Key & other) const; /** * Inequality operator. * @param other The key to compare * @return true if this key is not equal to other */ bool operator != (const Key & other) const; /** * Smaller then operator. * @param other The key to compare * @return rue if this key is smaller then other */ bool operator < (const Key & other) const; /** * Smaller then or equal operator. * @param other The key to compare * @return rue if this key is smaller then or equal to other */ bool operator <= (const Key & other) const; /** * Greater then operator. * @param other The key to compare * @return rue if this key is greater then other */ bool operator > (const Key & other) const; /** * Greater then or equal operator. * @param other The key to compare * @return rue if this key is greater then or equal to other */ bool operator >= (const Key & other) const; /** * Divide by a number operator */ Key operator / (int value) const; /** * Addition for keys * @param a The first key * @param b The second key */ friend KTORRENT_EXPORT Key operator + (const Key & a, const Key & b); /** * Subtraction for keys * @param a The first key * @param b The second key */ friend KTORRENT_EXPORT Key operator - (const Key & a, const Key & b); /** * Addition for key and a value * @param a The key * @param b The value */ friend KTORRENT_EXPORT Key operator + (const Key & a, bt::Uint8 value); /** * The distance of two keys is the keys xor together. * @param a The first key * @param b The second key * @return a xor b */ static Key distance(const Key & a, const Key & b); /** * Calculate the middle between two keys. * @param a The first key * @param b The second key * @return The middle */ static Key mid(const Key & a, const Key & b); }; } #endif diff --git a/src/dht/node.h b/src/dht/node.h index f01c289..cefb0ff 100644 --- a/src/dht/node.h +++ b/src/dht/node.h @@ -1,103 +1,103 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTNODE_H #define DHTNODE_H #include #include "key.h" #include "kbucket.h" using bt::Uint8; namespace dht { class DHT; class RPCMsg; class RPCServer; class KClosestNodesSearch; const bt::Uint32 WANT_IPV4 = 1; const bt::Uint32 WANT_IPV6 = 2; const bt::Uint32 WANT_BOTH = WANT_IPV4 | WANT_IPV6; /** * @author Joris Guisson * * A Node represents us in the kademlia network. It contains * our id and 160 KBucket's. * A KBucketEntry is in node i, when the difference between our id and * the KBucketEntry's id is between 2 to the power i and 2 to the power i+1. */ class Node : public QObject { Q_OBJECT public: Node(RPCServer* srv, const QString & key_file); - virtual ~Node(); + ~Node() override; /** * An RPC message was received, the node must now update * the right bucket. * @param dh_table The DHT * @param msg The message * @param srv The RPCServer to send a ping if necessary */ void received(DHT* dh_table, const RPCMsg & msg); /// Get our own ID const dht::Key & getOurID() const {return our_id;} /** * Find the K closest entries to a key and store them in the KClosestNodesSearch * object. * @param kns The object to storre the search results * @param want Which protocol(s) are wanted */ void findKClosestNodes(KClosestNodesSearch & kns, bt::Uint32 want); /** * Increase the failed queries count of the bucket entry we sent the message to */ void onTimeout(RPCMsg::Ptr msg); /// Check if a buckets needs to be refreshed, and refresh if necesarry void refreshBuckets(DHT* dh_table); /// Save the routing table to a file void saveTable(const QString & file); /// Load the routing table from a file void loadTable(const QString & file); /// Get the number of entries in the routing table bt::Uint32 getNumEntriesInRoutingTable() const {return num_entries;} private: class Private; Private* d; dht::Key our_id; bt::Uint32 num_entries; }; } #endif diff --git a/src/dht/nodelookup.h b/src/dht/nodelookup.h index e8db2c0..fcf5c4d 100644 --- a/src/dht/nodelookup.h +++ b/src/dht/nodelookup.h @@ -1,56 +1,56 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTNODELOOKUP_H #define DHTNODELOOKUP_H #include "key.h" #include "task.h" namespace dht { class Node; class RPCServer; /** * @author Joris Guisson * * Task to do a node lookup. */ class NodeLookup : public Task { public: NodeLookup(const dht::Key & node_id,RPCServer* rpc,Node* node,QObject* parent); - virtual ~NodeLookup(); + ~NodeLookup() override; - virtual void update(); - virtual void callFinished(RPCCall* c, RPCMsg::Ptr rsp); - virtual void callTimeout(RPCCall* c); + void update() override; + void callFinished(RPCCall* c, RPCMsg::Ptr rsp) override; + void callTimeout(RPCCall* c) override; private: void handleNodes(const QByteArray & nodes, int ip_version); private: dht::Key node_id; bt::Uint32 num_nodes_rsp; }; } #endif diff --git a/src/dht/pingreq.h b/src/dht/pingreq.h index dfb8683..20d82bd 100644 --- a/src/dht/pingreq.h +++ b/src/dht/pingreq.h @@ -1,48 +1,48 @@ /*************************************************************************** * Copyright (C) 2012 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_PINGREQ_H #define DHT_PINGREQ_H #include "rpcmsg.h" namespace dht { /** * Ping request message in the DHT protocol */ class KTORRENT_EXPORT PingReq : public RPCMsg { public: PingReq(); PingReq(const Key & id); - virtual ~PingReq(); + ~PingReq() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; typedef QSharedPointer Ptr; }; } #endif // DHT_PINGREQ_H diff --git a/src/dht/pingrsp.h b/src/dht/pingrsp.h index f8d0b5d..f3aa2a8 100644 --- a/src/dht/pingrsp.h +++ b/src/dht/pingrsp.h @@ -1,48 +1,48 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHT_PINGRSP_H #define DHT_PINGRSP_H #include "rpcmsg.h" namespace dht { /** * Ping response message in the DHT protocol */ class KTORRENT_EXPORT PingRsp : public RPCMsg { public: PingRsp(); PingRsp(const QByteArray & mtid, const Key & id); - virtual ~PingRsp(); + ~PingRsp() override; - virtual void apply(DHT* dh_table); - virtual void print(); - virtual void encode(QByteArray & arr) const; + void apply(DHT* dh_table) override; + void print() override; + void encode(QByteArray & arr) const override; typedef QSharedPointer Ptr; }; } #endif // DHT_PINGRSP_H diff --git a/src/dht/rpccall.h b/src/dht/rpccall.h index 8fce8e8..f57d8d5 100644 --- a/src/dht/rpccall.h +++ b/src/dht/rpccall.h @@ -1,107 +1,107 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTRPCCALL_H #define DHTRPCCALL_H #include #include "key.h" #include "rpcmsg.h" namespace dht { class RPCCall; /** * Class which objects should derive from, if they want to know the result of a call. */ class RPCCallListener : public QObject { Q_OBJECT public: RPCCallListener(QObject* parent); - virtual ~RPCCallListener(); + ~RPCCallListener() override; public Q_SLOTS: /** * A response was received. * @param c The call * @param rsp The response */ virtual void onResponse(RPCCall* c, RPCMsg::Ptr rsp) = 0; /** * The call has timed out. * @param c The call */ virtual void onTimeout(RPCCall* c) = 0; }; /** * @author Joris Guisson */ class RPCCall : public QObject { Q_OBJECT public: RPCCall(RPCMsg::Ptr msg, bool queued); - virtual ~RPCCall(); + ~RPCCall() override; /** * Called when a queued call gets started. Starts the timeout timer. */ void start(); /** * Called by the server if a response is received. * @param rsp */ void response(RPCMsg::Ptr rsp); /** * Add a listener for this call * @param cl The listener */ void addListener(RPCCallListener* cl); /// Get the message type Method getMsgMethod() const; /// Get the request sent const RPCMsg::Ptr getRequest() const {return msg;} /// Get the request sent RPCMsg::Ptr getRequest() {return msg;} private Q_SLOTS: void onTimeout(); Q_SIGNALS: void response(RPCCall* c, RPCMsg::Ptr rsp); void timeout(RPCCall* c); private: RPCMsg::Ptr msg; QTimer timer; bool queued; }; } #endif diff --git a/src/dht/rpcserver.cpp b/src/dht/rpcserver.cpp index f9b003a..801a495 100644 --- a/src/dht/rpcserver.cpp +++ b/src/dht/rpcserver.cpp @@ -1,318 +1,318 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "rpcserver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rpccall.h" #include "rpcmsg.h" #include "kbucket.h" #include "node.h" #include "dht.h" #include "pingreq.h" #include "rpcmsgfactory.h" using namespace bt; namespace dht { class RPCServer::Private : public net::ServerSocket::DataHandler, public RPCMethodResolver { public: Private(RPCServer* p, DHT* dh_table, Uint16 port) : p(p), dh_table(dh_table), next_mtid(0), port(port) {} - ~Private() + ~Private() override { bt::Globals::instance().getPortList().removePort(port, net::UDP); calls.setAutoDelete(true); calls.clear(); qDeleteAll(call_queue); call_queue.clear(); } void reset() { sockets.clear(); } void listen(const QString & ip) { net::Address addr(ip, port); net::ServerSocket::Ptr sock(new net::ServerSocket(this)); if (!sock->bind(addr)) { Out(SYS_DHT | LOG_IMPORTANT) << "DHT: Failed to bind to " << addr.toString() << endl; } else { Out(SYS_DHT | LOG_NOTICE) << "DHT: Bound to " << addr.toString() << endl; sockets.append(sock); sock->setReadNotificationsEnabled(true); } } - virtual void dataReceived(bt::Buffer::Ptr ptr, const net::Address& addr) + void dataReceived(bt::Buffer::Ptr ptr, const net::Address& addr) override { try { // read and decode the packet BDecoder bdec(ptr->get(), ptr->size(), false); boost::scoped_ptr n(bdec.decode()); if (!n || n->getType() != BNode::DICT) return; // try to make a RPCMsg of it RPCMsg::Ptr msg = factory.build((BDictNode*)n.get(), this); if (msg) { if (addr.ipVersion() == 6 && addr.isIPv4Mapped()) msg->setOrigin(addr.convertIPv4Mapped()); else msg->setOrigin(addr); msg->apply(dh_table); // erase an existing call if (msg->getType() == RSP_MSG && calls.contains(msg->getMTID())) { // delete the call, but first notify it off the response RPCCall* c = calls.find(msg->getMTID()); c->response(msg); calls.erase(msg->getMTID()); c->deleteLater(); doQueuedCalls(); } } } catch (bt::Error & err) { Out(SYS_DHT | LOG_DEBUG) << "Error happened during parsing : " << err.toString() << endl; } } - virtual void readyToWrite(net::ServerSocket* sock) + void readyToWrite(net::ServerSocket* sock) override { Q_UNUSED(sock); } - virtual Method findMethod(const QByteArray& mtid) + Method findMethod(const QByteArray& mtid) override { const RPCCall* call = calls.find(mtid); if (call) return call->getMsgMethod(); else return dht::NONE; } void send(const net::Address & addr, const QByteArray & msg) { foreach(net::ServerSocket::Ptr sock, sockets) { if (sock->sendTo((const bt::Uint8*)msg.data(), msg.size(), addr) == msg.size()) break; } } void doQueuedCalls() { while (call_queue.count() > 0 && calls.count() < 256) { RPCCall* c = call_queue.first(); call_queue.removeFirst(); while (calls.contains(QByteArray(1, next_mtid))) next_mtid++; RPCMsg::Ptr msg = c->getRequest(); QByteArray mtid(1, next_mtid); msg->setMTID(mtid); next_mtid++; sendMsg(msg); calls.insert(msg->getMTID(), c); c->start(); } } RPCCall* doCall(RPCMsg::Ptr msg) { Uint8 start = next_mtid; QByteArray mtid(1, start); while (calls.contains(mtid)) { mtid[0] = ++next_mtid; if (next_mtid == start) // if this happens we cannot do any calls { // so queue the call RPCCall* c = new RPCCall(msg, true); call_queue.append(c); Out(SYS_DHT | LOG_NOTICE) << "Queueing RPC call, no slots available at the moment" << endl; return c; } } msg->setMTID(mtid); sendMsg(msg); RPCCall* c = new RPCCall(msg, false); calls.insert(mtid, c); return c; } void sendMsg(RPCMsg::Ptr msg) { QByteArray data; msg->encode(data); send(msg->getDestination(), data); // PrintRawData(data); } void timedOut(const QByteArray & mtid) { // delete the call RPCCall* c = calls.find(mtid); if (c) { dh_table->timeout(c->getRequest()); calls.erase(mtid); c->deleteLater(); } doQueuedCalls(); } RPCServer* p; QList sockets; DHT* dh_table; bt::PtrMap calls; QList call_queue; bt::Uint8 next_mtid; bt::Uint16 port; RPCMsgFactory factory; }; RPCServer::RPCServer(DHT* dh_table, Uint16 port, QObject *parent) : QObject(parent), d(new Private(this, dh_table, port)) { } RPCServer::~RPCServer() { delete d; } void RPCServer::start() { d->reset(); QStringList ips = NetworkInterfaceIPAddresses(NetworkInterface()); foreach(const QString & addr, ips) { d->listen(addr); } if (d->sockets.count() == 0) { // Try all addresses if the previous listen calls all failed d->listen(QHostAddress(QHostAddress::AnyIPv6).toString()); d->listen(QHostAddress(QHostAddress::Any).toString()); } if (d->sockets.count() > 0) bt::Globals::instance().getPortList().addNewPort(d->port, net::UDP, true); } void RPCServer::stop() { bt::Globals::instance().getPortList().removePort(d->port, net::UDP); d->reset(); } #if 0 static void PrintRawData(const QByteArray & data) { QString tmp; for (int i = 0;i < data.size();i++) { char c = QChar(data[i]).toLatin1(); if (!QChar(data[i]).isPrint() || c == 0) tmp += '#'; else tmp += c; } Out(SYS_DHT | LOG_DEBUG) << tmp << endl; } #endif RPCCall* RPCServer::doCall(RPCMsg::Ptr msg) { RPCCall* c = d->doCall(msg); if (c) connect(c, &RPCCall::timeout, this, &RPCServer::callTimeout); return c; } void RPCServer::sendMsg(RPCMsg::Ptr msg) { d->sendMsg(msg); } void RPCServer::sendMsg(const dht::RPCMsg& msg) { QByteArray data; msg.encode(data); d->send(msg.getDestination(), data); } void RPCServer::callTimeout(RPCCall* call) { d->timedOut(call->getRequest()->getMTID()); } void RPCServer::ping(const dht::Key & our_id, const net::Address & addr) { RPCMsg::Ptr pr(new PingReq(our_id)); pr->setOrigin(addr); doCall(pr); } Uint32 RPCServer::getNumActiveRPCCalls() const { return d->calls.count(); } } diff --git a/src/dht/rpcserver.h b/src/dht/rpcserver.h index 7d910e4..7b8fc85 100644 --- a/src/dht/rpcserver.h +++ b/src/dht/rpcserver.h @@ -1,98 +1,98 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTRPCSERVER_H #define DHTRPCSERVER_H #include #include #include #include #include #include #include using bt::Uint32; using bt::Uint16; using bt::Uint8; namespace dht { class Key; class DHT; /** * @author Joris Guisson * * Class to handle incoming and outgoing RPC messages. */ class RPCServer : public QObject, public RPCServerInterface { Q_OBJECT public: RPCServer(DHT* dh_table, Uint16 port, QObject *parent = 0); - virtual ~RPCServer(); + ~RPCServer() override; /// Start the server void start(); /// Stop the server void stop(); /** * Do a RPC call. * @param msg The message to send * @return The call object */ - virtual RPCCall* doCall(RPCMsg::Ptr msg); + RPCCall* doCall(RPCMsg::Ptr msg) override; /** * Send a message, this only sends the message, it does not keep any call * information. This should be used for replies. * @param msg The message to send */ void sendMsg(RPCMsg::Ptr msg); /** * Send a message, this only sends the message, it does not keep any call * information. This should be used for replies. * @param msg The message to send */ void sendMsg(const RPCMsg & msg); /** * Ping a node, we don't care about the MTID. * @param addr The address */ void ping(const dht::Key & our_id, const net::Address & addr); /// Get the number of active calls Uint32 getNumActiveRPCCalls() const; private Q_SLOTS: void callTimeout(RPCCall* call); private: class Private; Private* d; }; } #endif diff --git a/src/dht/task.h b/src/dht/task.h index fd7fbff..d625b41 100644 --- a/src/dht/task.h +++ b/src/dht/task.h @@ -1,167 +1,167 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTTASK_H #define DHTTASK_H #include "rpccall.h" #include "rpcserver.h" #include "kbucket.h" namespace net { class AddressResolver; } namespace dht { class Node; class Task; class KClosestNodesSearch; const bt::Uint32 MAX_CONCURRENT_REQS = 16; /** * @author Joris Guisson * * Performs a task on K nodes provided by a KClosestNodesSearch. * This is a base class for all tasks. */ class Task : public RPCCallListener { Q_OBJECT public: /** * Create a task. * @param rpc The RPC server to do RPC calls * @param node The node * @param parent The parent object */ Task(RPCServer* rpc, Node* node, QObject* parent); - virtual ~Task(); + ~Task() override; /** * This will copy the results from the KClosestNodesSearch * object into the todo list. And call update if the task is not queued. * @param kns The KClosestNodesSearch object * @param queued Is the task queued */ void start(const KClosestNodesSearch & kns, bool queued); /** * Start the task, to be used when a task is queued. */ void start(); /// Decrements the outstanding_reqs - virtual void onResponse(RPCCall* c, RPCMsg::Ptr rsp); + void onResponse(RPCCall* c, RPCMsg::Ptr rsp) override; /// Decrements the outstanding_reqs - virtual void onTimeout(RPCCall* c); + void onTimeout(RPCCall* c) override; /** * Will continue the task, this will be called every time we have * rpc slots available for this task. Should be implemented by derived classes. */ virtual void update() = 0; /** * A call is finished and a response was received. * @param c The call * @param rsp The response */ virtual void callFinished(RPCCall* c, RPCMsg::Ptr rsp) = 0; /** * A call timedout * @param c The call */ virtual void callTimeout(RPCCall* c) = 0; /** * Do a call to the rpc server, increments the outstanding_reqs variable. * @param req THe request to send * @return true if call was made, false if not */ bool rpcCall(RPCMsg::Ptr req); /// See if we can do a request bool canDoRequest() const {return outstanding_reqs < MAX_CONCURRENT_REQS;} /// Is the task finished bool isFinished() const {return task_finished;} /// Get the number of outstanding requests bt::Uint32 getNumOutstandingRequests() const {return outstanding_reqs;} bool isQueued() const {return queued;} /** * Tell listeners data is ready. */ void emitDataReady(); /// Kills the task void kill(); /** * Add a node to the todo list * @param ip The ip or hostname of the node * @param port The port */ void addDHTNode(const QString & ip, bt::Uint16 port); Q_SIGNALS: /** * The task is finsihed. * @param t The Task */ void finished(Task* t); /** * Called by the task when data is ready. * Can be overrided if wanted. * @param t The Task */ void dataReady(Task* t); protected: void done(); protected Q_SLOTS: void onResolverResults(net::AddressResolver* res); protected: dht::KBucketEntrySet visited; // nodes visited dht::KBucketEntrySet todo; // nodes todo Node* node; private: RPCServer* rpc; bt::Uint32 outstanding_reqs; bool task_finished; bool queued; }; } #endif diff --git a/src/dht/taskmanager.h b/src/dht/taskmanager.h index 90997f2..d86c9ff 100644 --- a/src/dht/taskmanager.h +++ b/src/dht/taskmanager.h @@ -1,67 +1,67 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DHTTASKMANAGER_H #define DHTTASKMANAGER_H #include #include #include #include "task.h" namespace dht { class DHT; /** * @author Joris Guisson * * Manages all dht tasks. */ class TaskManager : public QObject { Q_OBJECT public: TaskManager(const DHT* dh_table); - virtual ~TaskManager(); + ~TaskManager() override; /** * Add a task to manage. * @param task */ void addTask(Task* task); /// Get the number of running tasks bt::Uint32 getNumTasks() const {return num_active;} /// Get the number of queued tasks bt::Uint32 getNumQueuedTasks() const {return queued.count();} private Q_SLOTS: void taskFinished(Task* task); private: const DHT* dh_table; QList > queued; bt::Uint32 num_active; }; } #endif diff --git a/src/dht/tests/rpcmsgtest.cpp b/src/dht/tests/rpcmsgtest.cpp index 87e5eb7..4941532 100644 --- a/src/dht/tests/rpcmsgtest.cpp +++ b/src/dht/tests/rpcmsgtest.cpp @@ -1,216 +1,216 @@ /*************************************************************************** * Copyright (C) 2012 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include class RPCMsgTest : public QObject, public dht::RPCMethodResolver { Q_OBJECT private: - virtual dht::Method findMethod(const QByteArray& mtid) + dht::Method findMethod(const QByteArray& mtid) override { Q_UNUSED(mtid); return current_method; } private Q_SLOTS: void initTestCase() { bt::InitLog("rpcmsgtest.log", false, true); } void cleanupTestCase() { } void testErrMsg() { const char* msg = "d1:eli201e23:A Generic Error Ocurrede1:t2:aa1:y1:ee"; try { bt::BDecoder dec(QByteArray(msg), false); QScopedPointer dict(dec.decodeDict()); dht::RPCMsg::Ptr msg = factory.build(dict.data(), 0); QVERIFY(msg->getType() == dht::ERR_MSG); dht::ErrMsg::Ptr err = msg.dynamicCast(); QVERIFY(err); QVERIFY(err->message() == "A Generic Error Ocurred"); QVERIFY(err->getMTID() == QByteArray("aa")); } catch (bt::Error & e) { QFAIL(e.toString().toLocal8Bit().data()); } } void testWrongErrMsg() { const char* msg[] = {"d1:t2:aa1:y1:ee", "d1:eli201e1:t2:aa1:y1:ee", 0}; int idx = 0; while (msg[idx]) { bt::BDecoder dec(QByteArray(msg[idx]), false); QScopedPointer dict(dec.decodeDict()); try { dht::RPCMsg::Ptr msg = factory.build(dict.data(), this); QFAIL("No exception thrown"); } catch (bt::Error & ) { // OK } idx++; } } void testPing() { const char* msg[] = {"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe", "d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re", 0}; current_method = dht::PING; int idx = 0; while (msg[idx]) { bt::BDecoder dec(QByteArray(msg[idx]), false); QScopedPointer dict(dec.decodeDict()); try { dht::RPCMsg::Ptr msg = factory.build(dict.data(), this); QVERIFY(msg); QVERIFY(msg->getMTID() == QByteArray("aa")); QVERIFY(msg->getMethod() == dht::PING); } catch (bt::Error & e) { QFAIL(e.toString().toLocal8Bit().data()); } idx++; } } void testFindNode() { const char* msg[] = { "d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe", "d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re", 0 }; current_method = dht::FIND_NODE; int idx = 0; while (msg[idx]) { bt::BDecoder dec(QByteArray(msg[idx]), false); QScopedPointer dict(dec.decodeDict()); try { dht::RPCMsg::Ptr msg = factory.build(dict.data(), this); QVERIFY(msg); QVERIFY(msg->getMTID() == QByteArray("aa")); QVERIFY(msg->getMethod() == dht::FIND_NODE); } catch (bt::Error & e) { QFAIL(e.toString().toLocal8Bit().data()); } idx++; } } void testGetPeers() { const char* msg[] = { "d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe", "d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re", "d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re", 0 }; current_method = dht::GET_PEERS; int idx = 0; while (msg[idx]) { bt::BDecoder dec(QByteArray(msg[idx]), false); QScopedPointer dict(dec.decodeDict()); try { dht::RPCMsg::Ptr msg = factory.build(dict.data(), this); QVERIFY(msg); QVERIFY(msg->getMTID() == QByteArray("aa")); QVERIFY(msg->getMethod() == dht::GET_PEERS); } catch (bt::Error & e) { QFAIL(e.toString().toLocal8Bit().data()); } idx++; } } void testAnnounce() { const char* msg[] = { "d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe", "d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re", 0 }; current_method = dht::ANNOUNCE_PEER; int idx = 0; while (msg[idx]) { bt::BDecoder dec(QByteArray(msg[idx]), false); QScopedPointer dict(dec.decodeDict()); try { dht::RPCMsg::Ptr msg = factory.build(dict.data(), this); QVERIFY(msg); QVERIFY(msg->getMTID() == QByteArray("aa")); QVERIFY(msg->getMethod() == dht::ANNOUNCE_PEER); } catch (bt::Error & e) { QFAIL(e.toString().toLocal8Bit().data()); } idx++; } } private: dht::RPCMsgFactory factory; dht::Method current_method; }; QTEST_MAIN(RPCMsgTest) #include "rpcmsgtest.moc" diff --git a/src/diskio/cachefile.h b/src/diskio/cachefile.h index f27b1b7..e9c1a62 100644 --- a/src/diskio/cachefile.h +++ b/src/diskio/cachefile.h @@ -1,159 +1,159 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTCACHEFILE_H #define BTCACHEFILE_H #include #include #include #include #include namespace bt { class PreallocationThread; /** * Interface which classes must implement to be able to map something from a CacheFile * It will also be used to notify when things get unmapped or remapped */ class MMappeable { public: virtual ~MMappeable() {} /** * When a CacheFile is closed, this will be called on all existing mappings. */ virtual void unmapped() = 0; }; /** @author Joris Guisson Used by Single and MultiFileCache to write to disk. */ class CacheFile : public QObject { Q_OBJECT public: CacheFile(); - virtual ~CacheFile(); + ~CacheFile() override; enum Mode { READ,WRITE,RW }; /** * Open the file. * @param path Path of the file * @param size Max size of the file * @throw Error when something goes wrong */ void open(const QString & path,Uint64 size); /// Change the path of the file void changePath(const QString & npath); /** * Map a part of the file into memory, will expand the file * if it is to small, but will not go past the limit set in open. * @param thing The thing that wishes to map the mmapping * @param off Offset into the file * @param size Size of the region to map * @param mode How the region will be mapped * @return A ptr to the mmaped region, or 0 if something goes wrong */ void* map(MMappeable* thing,Uint64 off,Uint32 size,Mode mode); /** * Unmap a previously mapped region. * @param ptr Ptr to the region * @param size Size of the region */ void unmap(void* ptr,Uint32 size); /** * Close the file, everything will be unmapped. * @param to_be_reopened Indicates if the close is temporarely (i.e. it will be reopened) */ void close(); /** * Read from the file. * @param buf Buffer to store data * @param size Size to read * @param off Offset to read from in file */ void read(Uint8* buf,Uint32 size,Uint64 off); /** * Write to the file. * @param buf Buffer to write * @param size Size to read * @param off Offset to read from in file */ void write(const Uint8* buf,Uint32 size,Uint64 off); /** * Preallocate disk space */ void preallocate(PreallocationThread* prealloc); /// Get the number of bytes this cache file is taking up Uint64 diskUsage(); typedef QSharedPointer Ptr; private: void growFile(Uint64 to_write); void closeTemporary(); void openFile(Mode mode); void unmapAll(); bool allocateBytes(bt::Uint64 off,bt::Uint64 size); private Q_SLOTS: void aboutToClose(); private: QFile* fptr; bool read_only; Uint64 max_size,file_size; QString path; struct Entry { MMappeable* thing; void* ptr; Uint32 size; Uint64 offset; Uint32 diff; Mode mode; }; QMap mappings; // mappings where offset wasn't a multiple of 4K mutable QMutex mutex; bool manual_close; }; } #endif diff --git a/src/diskio/chunkmanager.h b/src/diskio/chunkmanager.h index 598aa31..68d9669 100644 --- a/src/diskio/chunkmanager.h +++ b/src/diskio/chunkmanager.h @@ -1,365 +1,365 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTCHUNKMANAGER_H #define BTCHUNKMANAGER_H #include #include #include #include #include #include #include #include #include "chunk.h" class QStringList; namespace bt { class TorrentFile; class PreallocationThread; class TorrentFileInterface; class CacheFactory; class Job; struct NewChunkHeader { unsigned int index; // the Chunks index unsigned int deprecated; // offset in cache file }; /** * @author Joris Guisson * * Manages all Chunk's and the cache file, where all the chunk's are stored. * It also manages a separate index file, where the position of each piece * in the cache file is stored. * * The chunks are stored in the cache file in the correct order. Eliminating * the need for a file reconstruction algorithm for single files. */ class KTORRENT_EXPORT ChunkManager : public QObject { Q_OBJECT public: ChunkManager(Torrent& tor, const QString& tmpdir, const QString& datadir, bool custom_output_name, CacheFactory* fac); - virtual ~ChunkManager(); + ~ChunkManager() override; /// Get the torrent const Torrent& getTorrent() const { return tor; } /// Get the data dir QString getDataDir() const; /// Get the actual output path QString getOutputPath() const; void changeOutputPath(const QString& output_path); /// Remove obsolete chunks void checkMemoryUsage(); /** * Change the data dir. * @param data_dir */ void changeDataDir(const QString& data_dir); /** * Move the data files of the torrent. * @param ndir The new directory */ Job* moveDataFiles(const QString& ndir); /** * A move of data files has finished * @param job The job doing the move */ void moveDataFilesFinished(Job* job); /** * Move some data files to a new location * @param files Map of files and their new location */ Job* moveDataFiles(const QMap & files); /** * A move of data files with the map has finished * @param files Map of files and their new location * @param job The job doing the move */ void moveDataFilesFinished(const QMap & files, Job* job); /** * Loads the index file. * @throw Error When it can be loaded */ void loadIndexFile(); /** * Create the cache file, and index files. * @param check_priority Check if priority of chunk matches that of files * @throw Error When it can be created */ void createFiles(bool check_priority = false); /** * Test all files and see if they are not missing. * If so put them in a list */ bool hasMissingFiles(QStringList& sl); /** * Prepare diskspace preallocation * @param prealloc The thread going to do the preallocation */ void preparePreallocation(PreallocationThread* prealloc); /** * Open the necessary files when the download gets started. */ void start(); /** * Closes files when the download gets stopped. */ void stop(); /** * Get's the i'th Chunk. * @param i The Chunk's index * @return The Chunk, or 0 when i is out of bounds */ Chunk* getChunk(unsigned int i); /** * Reset a chunk as if it were never downloaded. * @param i The chunk */ void resetChunk(unsigned int i); /** * Mark a chunk as downloaded. * @param i The Chunk's index */ void chunkDownloaded(unsigned int i); /** * Calculates the number of bytes left for the tracker. Does include * excluded chunks (this should be used for the tracker). * @return The number of bytes to download + the number of bytes excluded */ Uint64 bytesLeft() const; /** * Calculates the number of bytes left to download. */ Uint64 bytesLeftToDownload() const; /** * Calculates the number of bytes which have been excluded. * @return The number of bytes excluded */ Uint64 bytesExcluded() const; /** * Calculates the number of chunks left to download. * Does not include excluded chunks. * @return The number of chunks to download */ Uint32 chunksLeft() const; /** * Check if we have all chunks, this is not the same as * chunksLeft() == 0, it does not look at excluded chunks. * @return true if all chunks have been downloaded */ bool haveAllChunks() const; /** * Get the number of chunks which have been excluded. * @return The number of excluded chunks */ Uint32 chunksExcluded() const; /** * Get the number of downloaded chunks * @return */ Uint32 chunksDownloaded() const; /** * Get the number of only seed chunks. */ Uint32 onlySeedChunks() const; /** * Get a BitSet of the status of all Chunks */ const BitSet& getBitSet() const { return bitset; } /** * Get the excluded bitset */ const BitSet& getExcludedBitSet() const { return excluded_chunks; } /** * Get the only seed bitset. */ const BitSet& getOnlySeedBitSet() const { return only_seed_chunks; } /// Get the number of chunks into the file. Uint32 getNumChunks() const { return tor.getNumChunks(); } /// Print memory usage to log file void debugPrintMemUsage(); /** * Make sure that a range will get priority over other chunks. * @param from First chunk in range * @param to Last chunk in range */ void prioritise(Uint32 from, Uint32 to, Priority priority); /** * Make sure that a range will not be downloaded. * @param from First chunk in range * @param to Last chunk in range */ void exclude(Uint32 from, Uint32 to); /** * Make sure that a range will be downloaded. * Does the opposite of exclude. * @param from First chunk in range * @param to Last chunk in range */ void include(Uint32 from, Uint32 to); /** * Data has been checked, and these chunks are OK. * The ChunkManager will update it's internal structures * @param ok_chunks The ok_chunks * @param from First chunk of the check * @param to Last chunk of the check */ void dataChecked(const BitSet& ok_chunks, Uint32 from, Uint32 to); /// Test if the torrent has existing files, only works the first time a torrent is loaded bool hasExistingFiles() const; /// Mark all existing files as downloaded void markExistingFilesAsDownloaded(); /// Recreates missing files void recreateMissingFiles(); /// Set missing files as do not download void dndMissingFiles(); /// Delete all data files Job* deleteDataFiles(); /// Are all not deselected chunks downloaded. bool completed() const; /// Set the preview sizes for audio and video files static void setPreviewSizes(Uint32 audio, Uint32 video); /// Get the current disk usage of all the files in this torrent Uint64 diskUsage(); /// Get the size in chunks of the preview range of a file of the torrent Uint32 previewChunkRangeSize(const TorrentFile& tf) const; /// Get the size in chunks of the preview range for a single file torrent Uint32 previewChunkRangeSize() const; /// The download priority of a file has changed void downloadPriorityChanged(TorrentFile* tf, Priority newpriority, Priority oldpriority); /// Is the storage mounted ? bool isStorageMounted(QStringList& missing); Q_SIGNALS: /** * Emitted when a range of chunks has been excluded * @param from First chunk in range * @param to Last chunk in range */ void excluded(Uint32 from, Uint32 to); /** * Emitted when a range of chunks has been included back. * @param from First chunk in range * @param to Last chunk in range */ void included(Uint32 from, Uint32 to); /** * Emitted when chunks get excluded or included, so * that the statistics can be updated. */ void updateStats(); /** * A corrupted chunk has been found during uploading. * @param chunk The chunk */ void corrupted(Uint32 chunk); private: static Uint32 preview_size_audio; static Uint32 preview_size_video; class Private; Private* d; Torrent& tor; BitSet bitset; BitSet excluded_chunks; BitSet only_seed_chunks; }; } #endif diff --git a/src/diskio/deletedatafilesjob.h b/src/diskio/deletedatafilesjob.h index 8f96389..fbd46d3 100644 --- a/src/diskio/deletedatafilesjob.h +++ b/src/diskio/deletedatafilesjob.h @@ -1,90 +1,90 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTDELETEDATAFILESJOB_H #define BTDELETEDATAFILESJOB_H #include #include #include #include namespace bt { /** * @author Joris Guisson * KIO::Job to delete all the files of a torrent. */ class DeleteDataFilesJob : public Job { Q_OBJECT public: /** * @param base Base directory, the data files are in */ DeleteDataFilesJob(const QString & base); - virtual ~DeleteDataFilesJob(); + ~DeleteDataFilesJob() override; /** * Add a file to delete * @param file File */ void addFile(const QString & file); /** * Check all directories in fpath and delete them if they are empty. * The base path passed in the constructor, will be prepended to fpath. * @param fpath The file path */ void addEmptyDirectoryCheck(const QString & fpath); /// Start the job - virtual void start(); + void start() override; /// Kill the job - virtual void kill(bool quietly); + void kill(bool quietly) override; private Q_SLOTS: void onDeleteJobDone(KJob* j); private: struct DirTree { QString name; bt::PtrMap subdirs; DirTree(const QString & name); ~DirTree(); void insert(const QString & fpath); void doDeleteOnEmpty(const QString & base); }; private: QList files; QString base; DirTree* directory_tree; KIO::Job* active_job; }; } #endif diff --git a/src/diskio/movedatafilesjob.h b/src/diskio/movedatafilesjob.h index 8c32c14..e916566 100644 --- a/src/diskio/movedatafilesjob.h +++ b/src/diskio/movedatafilesjob.h @@ -1,88 +1,88 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTMOVEDATAFILESJOB_H #define BTMOVEDATAFILESJOB_H #include #include namespace bt { class TorrentFileInterface; /** * @author Joris Guisson * KIO::Job to move all the files of a torrent. */ class MoveDataFilesJob : public Job, public Resource { Q_OBJECT public: MoveDataFilesJob(); /** Constructor with a file map. @param fmap Map of files and their destinations */ MoveDataFilesJob(const QMap & fmap); - virtual ~MoveDataFilesJob(); + ~MoveDataFilesJob() override; /** * Add a move to the todo list. * @param src File to move * @param dst Where to move it to */ void addMove(const QString & src,const QString & dst); - virtual void start(); - virtual void kill(bool quietly = true); + void start() override; + void kill(bool quietly = true) override; /// Get the file map (could be empty) const QMap & fileMap() const {return file_map;} private Q_SLOTS: void onJobDone(KJob* j); void onCanceled(KJob* j); void onRecoveryJobDone(KJob* j); void onTransferred(KJob *job, KJob::Unit unit, qulonglong amount); void onSpeed(KJob* job, unsigned long speed); private: void recover(bool delete_active); void startMoving(); - virtual void acquired(); + void acquired() override; private: bool err; KIO::Job* active_job; QString active_src,active_dst; QMap todo; QMap success; int running_recovery_jobs; QMap file_map; bt::Uint64 bytes_moved; bt::Uint64 total_bytes; bt::Uint64 bytes_moved_current_file; }; } #endif diff --git a/src/diskio/multifilecache.h b/src/diskio/multifilecache.h index 5050939..89f4f7a 100644 --- a/src/diskio/multifilecache.h +++ b/src/diskio/multifilecache.h @@ -1,84 +1,84 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTMULTIFILECACHE_H #define BTMULTIFILECACHE_H #include #include "cache.h" #include "cachefile.h" #include "dndfile.h" namespace bt { /** * @author Joris Guisson * @brief Cache for multi file torrents * * This class manages a multi file torrent cache. Everything gets stored in the * correct files immediately. */ class KTORRENT_EXPORT MultiFileCache : public Cache { public: MultiFileCache(Torrent& tor, const QString & tmpdir, const QString & datadir, bool custom_output_name); - virtual ~MultiFileCache(); + ~MultiFileCache() override; - virtual void changeTmpDir(const QString& ndir); - virtual void create(); - virtual PieceData::Ptr loadPiece(Chunk* c, Uint32 off, Uint32 length); - virtual PieceData::Ptr preparePiece(Chunk* c, Uint32 off, Uint32 length); - virtual void savePiece(PieceData::Ptr piece); - virtual void close(); - virtual void open(); - virtual Job* moveDataFiles(const QString & ndir); - virtual void moveDataFilesFinished(Job* job); - virtual Job* moveDataFiles(const QMap & files); - virtual void moveDataFilesFinished(const QMap & files, Job* job); - virtual QString getOutputPath() const; - virtual void changeOutputPath(const QString & outputpath); - virtual void preparePreallocation(PreallocationThread* prealloc); - virtual bool hasMissingFiles(QStringList & sl); - virtual Job* deleteDataFiles(); - virtual Uint64 diskUsage(); - virtual void loadFileMap(); - virtual void saveFileMap(); - virtual bool getMountPoints(QSet& mps); + void changeTmpDir(const QString& ndir) override; + void create() override; + PieceData::Ptr loadPiece(Chunk* c, Uint32 off, Uint32 length) override; + PieceData::Ptr preparePiece(Chunk* c, Uint32 off, Uint32 length) override; + void savePiece(PieceData::Ptr piece) override; + void close() override; + void open() override; + Job* moveDataFiles(const QString & ndir) override; + void moveDataFilesFinished(Job* job) override; + Job* moveDataFiles(const QMap & files) override; + void moveDataFilesFinished(const QMap & files, Job* job) override; + QString getOutputPath() const override; + void changeOutputPath(const QString & outputpath) override; + void preparePreallocation(PreallocationThread* prealloc) override; + bool hasMissingFiles(QStringList & sl) override; + Job* deleteDataFiles() override; + Uint64 diskUsage() override; + void loadFileMap() override; + void saveFileMap() override; + bool getMountPoints(QSet& mps) override; private: void touch(TorrentFile & tf); - virtual void downloadStatusChanged(TorrentFile*, bool); + void downloadStatusChanged(TorrentFile*, bool) override; void saveFirstAndLastChunk(TorrentFile* tf, const QString & src_file, const QString & dst_file); void recreateFile(TorrentFile* tf, const QString & dnd_file, const QString & output_file); PieceData::Ptr createPiece(Chunk* c, Uint32 off, Uint32 length, bool read_only); void calculateOffsetAndLength(Uint32 piece_off, Uint32 piece_len, Uint64 file_off, Uint32 chunk_off, Uint32 chunk_len, Uint64 & off, Uint32 & len); private: QString cache_dir, output_dir; QMap files; QMap dnd_files; QString new_output_dir; bool opened; }; } #endif diff --git a/src/diskio/piecedata.h b/src/diskio/piecedata.h index 820ad30..2b9b8c1 100644 --- a/src/diskio/piecedata.h +++ b/src/diskio/piecedata.h @@ -1,155 +1,155 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPIECEDATA_H #define BTPIECEDATA_H #include #include #include #ifndef Q_WS_WIN #include #endif #include namespace bt { class File; class Chunk; class SHA1Hash; class SHA1HashGen; /** Class which holds the data of a piece of a chunk. It has a reference counter. */ class KTORRENT_EXPORT PieceData : public QSharedData, public MMappeable { public: PieceData(Chunk* chunk, Uint32 off, Uint32 len, Uint8* ptr, CacheFile::Ptr cache_file, bool read_only); - virtual ~PieceData(); + ~PieceData() override; /// Unload the piece void unload(); /// Is it a mapped into memory bool mapped() const {return cache_file != 0;} /// Is this writeable bool writeable() const {return !read_only;} /// Get the offset of the piece in the chunk Uint32 offset() const {return off;} /// Get the length of the piece Uint32 length() const {return len;} /// Get a pointer to the data Uint8* data() {return ptr;} /// Check if the data pointer is OK bool ok() const {return ptr != 0;} /// Set the data pointer void setData(Uint8* p) {ptr = p;} /// Get the parent chunk of the piece Chunk* parentChunk() {return chunk;} /** Write data into the PieceData. This function should always be used for writing into a PieceData object, as it protects against bus errors. @param buf The buffer to write @param size Size of the buffer @param off Offset to write @return The number of bytes written @throw BusError When writing results in a SIGBUS */ Uint32 write(const Uint8* buf, Uint32 buf_size, Uint32 off = 0); /** Read data from the PieceData. This function should always be used for reading from a PieceData object, as it protects against bus errors. @param buf The buffer to read into @param to_read Amount of bytes to read @param off Offset in the PieceData to start reading from @return The number of bytes read @throw BusError When reading results in a SIGBUS */ Uint32 read(Uint8* buf, Uint32 to_read, Uint32 off = 0); /** Save PieceData to a File. This function protects against bus errors. @param file The file to write to @param size Size to write @param off Offset in PieceData to write from @return The number of bytes written @throw BusError When writing results in a SIGBUS */ Uint32 writeToFile(File & file, Uint32 size, Uint32 off = 0); /** Read PieceData from a File. This function protects against bus errors. @param file The file to read from @param size Size to read @param off Offset in PieceData to write into @return The number of bytes read @throw BusError When reading results in a SIGBUS */ Uint32 readFromFile(File & file, Uint32 size, Uint32 off = 0); /** Update a SHA1HashGen with this PieceData. This function protects against bus errors. @param hg The SHA1HashGen to update @throw BusError When reading results in a SIGBUS */ void updateHash(SHA1HashGen & hg); /** Generate a SHA1Hash of this PieceData. This function protects against bus errors. @return The SHA1 hash @throw BusError When reading results in a SIGBUS */ SHA1Hash generateHash() const; typedef QExplicitlySharedDataPointer Ptr; /// Is the piece in use by somebody else then the cache bool inUse() const {return ref > 1;} private: - virtual void unmapped(); + void unmapped() override; private: Chunk* chunk; Uint32 off; Uint32 len; Uint8* ptr; CacheFile::Ptr cache_file; bool read_only; }; } #endif diff --git a/src/diskio/preallocationjob.h b/src/diskio/preallocationjob.h index e5d7e8a..016abae 100644 --- a/src/diskio/preallocationjob.h +++ b/src/diskio/preallocationjob.h @@ -1,52 +1,52 @@ /*************************************************************************** * Copyright (C) 2009 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_PREALLOCATIONJOB_H #define BT_PREALLOCATIONJOB_H #include namespace bt { class PreallocationThread; class ChunkManager; class KTORRENT_EXPORT PreallocationJob : public bt::Job { Q_OBJECT public: PreallocationJob(ChunkManager* cman,TorrentControl* tc); - virtual ~PreallocationJob(); + ~PreallocationJob() override; - virtual void start(); - virtual void kill(bool quietly = true); - virtual TorrentStatus torrentStatus() const {return ALLOCATING_DISKSPACE;} + void start() override; + void kill(bool quietly = true) override; + TorrentStatus torrentStatus() const override {return ALLOCATING_DISKSPACE;} private Q_SLOTS: void finished(); private: ChunkManager* cman; PreallocationThread* prealloc_thread; }; } #endif // BT_PREALLOCATIONJOB_H diff --git a/src/diskio/preallocationthread.h b/src/diskio/preallocationthread.h index 1e2d41e..d82f297 100644 --- a/src/diskio/preallocationthread.h +++ b/src/diskio/preallocationthread.h @@ -1,99 +1,99 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPREALLOCATIONTHREAD_H #define BTPREALLOCATIONTHREAD_H #include #include #include #include #include #include "cachefile.h" #include "ktorrent_export.h" namespace bt { /** * @author Joris Guisson * * Thread to preallocate diskspace */ class KTORRENT_EXPORT PreallocationThread : public QThread { public: PreallocationThread(); - virtual ~PreallocationThread(); + ~PreallocationThread() override; /// Add a CacheFile to preallocate void add(CacheFile::Ptr cache_file); - virtual void run(); + void run() override; /** * Stop the thread. */ void stop(); /** * Set an error message, also calls stop * @param msg The message */ void setErrorMsg(const QString & msg); /// See if the thread has been stopped bool isStopped() const; /// Did an error occur during the preallocation ? bool errorHappened() const; /// Get the error_msg const QString & errorMessage() const {return error_msg;} /// nb Number of bytes have been written void written(Uint64 nb); /// Get the number of bytes written Uint64 bytesWritten(); /// Allocation was aborted, so the next time the torrent is started it needs to be started again void setNotFinished(); /// See if the allocation hasn't completed yet bool isNotFinished() const; /// See if the thread was done bool isDone() const; private: bool expand(const QString & path, Uint64 max_size); private: QList todo; bool stopped, not_finished, done; QString error_msg; Uint64 bytes_written; mutable QMutex mutex; }; } #endif diff --git a/src/diskio/singlefilecache.h b/src/diskio/singlefilecache.h index f84c16c..9d55e33 100644 --- a/src/diskio/singlefilecache.h +++ b/src/diskio/singlefilecache.h @@ -1,75 +1,75 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTSINGLEFILECACHE_H #define BTSINGLEFILECACHE_H #include "cache.h" namespace bt { class CacheFile; /** * @author Joris Guisson * @brief Cache for single file torrents * * This class implements Cache for a single file torrent */ class KTORRENT_EXPORT SingleFileCache : public Cache { public: SingleFileCache(Torrent& tor,const QString & tmpdir,const QString & datadir); - virtual ~SingleFileCache(); + ~SingleFileCache() override; - virtual PieceData::Ptr loadPiece(Chunk* c,Uint32 off,Uint32 length); - virtual PieceData::Ptr preparePiece(Chunk* c,Uint32 off,Uint32 length); - virtual void savePiece(PieceData::Ptr piece); - virtual void create(); - virtual void close(); - virtual void open(); - virtual void changeTmpDir(const QString & ndir); + PieceData::Ptr loadPiece(Chunk* c,Uint32 off,Uint32 length) override; + PieceData::Ptr preparePiece(Chunk* c,Uint32 off,Uint32 length) override; + void savePiece(PieceData::Ptr piece) override; + void create() override; + void close() override; + void open() override; + void changeTmpDir(const QString & ndir) override; using Cache::moveDataFiles; - virtual Job* moveDataFiles(const QString & ndir); + Job* moveDataFiles(const QString & ndir) override; using Cache::moveDataFilesFinished; - virtual void moveDataFilesFinished(Job* job); - virtual void changeOutputPath(const QString& outputpath); - virtual QString getOutputPath() const {return output_file;} - virtual void preparePreallocation(PreallocationThread* prealloc); - virtual bool hasMissingFiles(QStringList & sl); - virtual Job* deleteDataFiles(); - virtual Uint64 diskUsage(); - virtual void loadFileMap(); - virtual void saveFileMap(); - virtual bool getMountPoints(QSet& mps); + void moveDataFilesFinished(Job* job) override; + void changeOutputPath(const QString& outputpath) override; + QString getOutputPath() const override {return output_file;} + void preparePreallocation(PreallocationThread* prealloc) override; + bool hasMissingFiles(QStringList & sl) override; + Job* deleteDataFiles() override; + Uint64 diskUsage() override; + void loadFileMap() override; + void saveFileMap() override; + bool getMountPoints(QSet& mps) override; private: PieceData::Ptr createPiece(Chunk* c,Uint64 off,Uint32 length,bool read_only); private: QString cache_file; QString output_file; QString move_data_files_dst; CacheFile::Ptr fd; }; } #endif diff --git a/src/download/chunkdownload.h b/src/download/chunkdownload.h index 39fbd79..438f28d 100644 --- a/src/download/chunkdownload.h +++ b/src/download/chunkdownload.h @@ -1,234 +1,234 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTCHUNKDOWNLOAD_H #define BTCHUNKDOWNLOAD_H #include #include #include #include #include #include #include #include #include namespace bt { class File; class Chunk; class Piece; class Peer; class Request; class PieceDownloader; struct ChunkDownloadHeader { Uint32 index; Uint32 num_bits; Uint32 buffered; }; struct PieceHeader { Uint32 piece; Uint32 size; Uint32 mapped; }; class DownloadStatus { public: DownloadStatus(); ~DownloadStatus(); void add(Uint32 p); void remove(Uint32 p); bool contains(Uint32 p); void clear(); void timeout() {timeouts++;} Uint32 numTimeouts() const {return timeouts;} typedef QSet::iterator iterator; iterator begin() {return status.begin();} iterator end() {return status.end();} private: Uint32 timeouts; QSet status; }; /** * @author Joris Guisson * @brief Handles the download off one Chunk off a Peer * * This class handles the download of one Chunk. */ class KTORRENT_EXPORT ChunkDownload : public QObject,public ChunkDownloadInterface { Q_OBJECT public: /** * Constructor, set the chunk and the PeerManager. * @param chunk The Chunk */ ChunkDownload(Chunk* chunk); - virtual ~ChunkDownload(); + ~ChunkDownload() override; /// Get the chunk Chunk* getChunk() {return chunk;} /// Get the total number of pieces Uint32 getTotalPieces() const {return num;} /// Get the number of pieces downloaded Uint32 getPiecesDownloaded() const {return num_downloaded;} /// Get the number of bytes downloaded. Uint32 bytesDownloaded() const; /// Get the index of the chunk Uint32 getChunkIndex() const; /// Get the PeerID of the current peer QString getPieceDownloaderName() const; /// Get the download speed Uint32 getDownloadSpeed() const; /// Get download stats - void getStats(Stats & s); + void getStats(Stats & s) override; /// See if a chunkdownload is idle (i.e. has no downloaders) bool isIdle() const {return pdown.count() == 0;} /** * A Piece has arived. * @param p The Piece * @param ok Whether or not the piece was needed * @return true If Chunk is complete */ bool piece(const Piece & p,bool & ok); /** * Assign the downloader to download from. * @param pd The downloader * @return true if the peer was asigned, false if not */ bool assign(PieceDownloader* pd); /** * Release a downloader * @param pd The downloader */ void release(PieceDownloader* pd); /** * A PieceDownloader has been killed. We need to remove it. * @param pd The PieceDownloader */ void killed(PieceDownloader* pd); /** * Save to a File * @param file The File */ void save(File & file); /** * Load from a File * @param file The File * @param hdr Header for the chunk * @param update_hash Whether or not to update the hash */ bool load(File & file,ChunkDownloadHeader & hdr,bool update_hash = true); /** * Cancel all requests. */ void cancelAll(); /** * When a Chunk is downloaded, this function checks if all * pieces are delivered by the same peer and if so returns it. * @return The PieceDownloader or 0 if there is no only peer */ PieceDownloader* getOnlyDownloader(); /// See if a PieceDownloader is assigned to this chunk bool containsPeer(PieceDownloader *pd) {return pdown.contains(pd);} /// See if the download is choked (i.e. all downloaders are choked) bool isChoked() const; /// Release all PD's and clear the requested chunks void releaseAllPDs(); /// Send requests to peers void update(); /// See if this CD hasn't been active in the last update bool needsToBeUpdated() const {return timer.getElapsedSinceUpdate() > 60 * 1000;} /// Get the SHA1 hash of the downloaded chunk SHA1Hash getHash() const {return hash_gen.get();} /// Get the number of downloaders Uint32 getNumDownloaders() const {return pdown.count();} private Q_SLOTS: void onTimeout(const bt::Request & r); void onRejected(const bt::Request & r); private: void notDownloaded(const Request & r,bool reject); void updateHash(); void sendRequests(); bool sendRequest(PieceDownloader* pd); void sendCancels(PieceDownloader* pd); void endgameCancel(const Piece & p); Uint32 bestPiece(PieceDownloader* pd); private: BitSet pieces; Chunk* chunk; Uint32 num; Uint32 num_downloaded; Uint32 last_size; Timer timer; QList pdown; PtrMap dstatus; QSet piece_providers; PieceData::Ptr* piece_data; SHA1HashGen hash_gen; Uint32 num_pieces_in_hash; friend File & operator << (File & out,const ChunkDownload & cd); friend File & operator >> (File & in,ChunkDownload & cd); }; } #endif diff --git a/src/download/chunkselector.h b/src/download/chunkselector.h index 8f42f43..ca98010 100644 --- a/src/download/chunkselector.h +++ b/src/download/chunkselector.h @@ -1,87 +1,87 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTCHUNKSELECTOR_H #define BTCHUNKSELECTOR_H #include #include #include namespace bt { class BitSet; class ChunkManager; class Downloader; class PeerManager; class PieceDownloader; /** * @author Joris Guisson * * Selects which Chunks to download. */ class ChunkSelector : public ChunkSelectorInterface { std::list chunks; Timer sort_timer; public: ChunkSelector(); - virtual ~ChunkSelector(); + ~ChunkSelector() override; - virtual void init(ChunkManager* cman, Downloader* downer, PeerManager* pman); + void init(ChunkManager* cman, Downloader* downer, PeerManager* pman) override; /** * Select which chunk to download for a PieceDownloader. * @param pd The PieceDownloader * @param chunk Index of chunk gets stored here * @return true upon succes, false otherwise */ - bool select(PieceDownloader* pd,Uint32 & chunk); + bool select(PieceDownloader* pd,Uint32 & chunk) override; /** * Data has been checked, and these chunks are OK. * @param ok_chunks The ok_chunks */ - void dataChecked(const bt::BitSet& ok_chunks, bt::Uint32 from, bt::Uint32 to); + void dataChecked(const bt::BitSet& ok_chunks, bt::Uint32 from, bt::Uint32 to) override; /** * A range of chunks has been reincluded. * @param from The first chunk * @param to The last chunk */ - void reincluded(Uint32 from, Uint32 to); + void reincluded(Uint32 from, Uint32 to) override; /** * Reinsert a chunk. * @param chunk The chunk */ - void reinsert(Uint32 chunk); + void reinsert(Uint32 chunk) override; - virtual bool selectRange(Uint32 & from,Uint32 & to,Uint32 max_len); + bool selectRange(Uint32 & from,Uint32 & to,Uint32 max_len) override; protected: Uint32 leastPeers(const std::list & lp,Uint32 alternative,Uint32 max_peers_per_chunk); }; } #endif diff --git a/src/download/downloader.h b/src/download/downloader.h index 8e99971..a284958 100644 --- a/src/download/downloader.h +++ b/src/download/downloader.h @@ -1,316 +1,316 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTDOWNLOADER_H #define BTDOWNLOADER_H #include #include #include #include #include "download/webseed.h" #include "download/chunkdownload.h" #include "peer/peermanager.h" class QUrl; namespace bt { class BitSet; class Torrent; class ChunkManager; class PeerManager; class Peer; class Chunk; class Piece; class ChunkSelectorInterface; class PieceDownloader; class MonitorInterface; class WebSeedChunkDownload; typedef PtrMap::iterator CurChunkItr; typedef PtrMap::const_iterator CurChunkCItr; #define CURRENT_CHUNK_MAGIC 0xABCDEF00 struct CurrentChunksHeader { Uint32 magic; // CURRENT_CHUNK_MAGIC Uint32 major; Uint32 minor; Uint32 num_chunks; }; /** * @author Joris Guisson * @brief Manages the downloading * * This class manages the downloading of the file. It should * regurarly be updated. */ class KTORRENT_EXPORT Downloader : public QObject,public PieceHandler { Q_OBJECT public: /** * Constructor. * @param tor The Torrent * @param pman The PeerManager * @param cman The ChunkManager */ Downloader(Torrent & tor,PeerManager & pman,ChunkManager & cman); - virtual ~Downloader(); + ~Downloader() override; /** * Set the group ID's of the webseed (for speed limits) * @param up Upload group id * @param down Download group id */ void setGroupIDs(Uint32 up,Uint32 down); /// Get the number of webseeds Uint32 getNumWebSeeds() const {return webseeds.count();} /// Get a webseed const WebSeed* getWebSeed(Uint32 i) const {return i < (Uint32)webseeds.count() ? webseeds[i] : 0;} /// Get a webseed WebSeed* getWebSeed(Uint32 i) {return i < (Uint32)webseeds.count() ? webseeds[i] : 0;} /// Add a webseed WebSeed* addWebSeed(const QUrl &url); /// Remove a webseed bool removeWebSeed(const QUrl &url); /// Remove all webseeds void removeAllWebSeeds(); /// Save the user created webseeds void saveWebSeeds(const QString & file); /// Add the user created webseeds void loadWebSeeds(const QString & file); /// Get the number of bytes we have downloaded Uint64 bytesDownloaded() const {return bytes_downloaded + curr_chunks_downloaded;} /// Get the current dowload rate Uint32 downloadRate() const; /// Get the number of chunks we are dowloading Uint32 numActiveDownloads() const {return current_chunks.count() + active_webseed_downloads;} /// See if the download is finished. bool isFinished() const; /** * Clear all downloads. Deletes all active downloads. */ void clearDownloads(); /** * Pause the download */ void pause(); CurChunkCItr beginDownloads() const {return current_chunks.begin();} CurChunkCItr endDownloads() const {return current_chunks.end();} /** * Get a download for a chunk * @param chunk The chunk * @return The ChunkDownload, or 0 if no download is found */ ChunkDownload* download(Uint32 chunk); /** * Get a download for a chunk (const version) * @param chunk The chunk * @return The ChunkDownload, or 0 if no download is found */ const ChunkDownload* download(Uint32 chunk) const; /** * See if we are downloading a Chunk * @param chunk ID of Chunk * @return true if we are, false if not */ bool downloading(Uint32 chunk) const; /** * Can we download a chunk from a webseed. * @param chunk ID of Chunk * @return true if we can */ bool canDownloadFromWebSeed(Uint32 chunk) const; /** * Get the number of downloaders assigned to a chunk * @param chunk ID of Chunk * @return the number of downloaders for that chunk */ Uint32 numDownloadersForChunk(Uint32 chunk) const; /// Are we in endgame mode bool endgameMode() const; /** * Save the current downloads. * @param file The file to save to */ void saveDownloads(const QString & file); /** * Load the current downloads. * @param file The file to load from */ void loadDownloads(const QString & file); /** * Get the number of bytes already downloaded in the current_chunks file. * @param file The path of the current_chunks file * @return The bytes already downloading */ Uint32 getDownloadedBytesOfCurrentChunksFile(const QString & file); /** * A corrupted chunk has been detected, make sure we redownload it. * @param chunk The chunk */ void corrupted(Uint32 chunk); /// Set the ChunkSelector, 0 means KT will reset to the default selector void setChunkSelector(ChunkSelectorInterface* csel); /** * We got a new connection. * @param peer The PieceDownloader */ void addPieceDownloader(PieceDownloader* peer); /** * Remove a piece downloader. * @param peer The PieceDownloader */ void removePieceDownloader(PieceDownloader* peer); /// Enable or disable the use of webseeds static void setUseWebSeeds(bool on); public Q_SLOTS: /** * Update the downloader. */ void update(); /** * Set the TorrentMonitor. * @param tmo */ void setMonitor(MonitorInterface* tmo); /** * Data has been checked, and these chunks are OK. * @param ok_chunks The ok_chunks * @param from First chunk of the check * @param to Last chunk of the check */ void dataChecked(const BitSet & ok_chunks, bt::Uint32 from, bt::Uint32 to); /** * Recalculate the number of bytes downloaded. */ void recalcDownloaded(); private Q_SLOTS: - virtual void pieceReceived(const bt::Piece & p); + void pieceReceived(const bt::Piece & p) override; bool finished(ChunkDownload* c); /** * Kill all ChunkDownload's which have been excluded. * @param from First chunk of range * @param to Last chunk of range */ void onExcluded(Uint32 from,Uint32 to); /** * Make sure chunk selector is back OK, when chunks are included back again. * @param from First chunk * @param to Last chunk */ void onIncluded(Uint32 from,Uint32 to); /** * A WebSeed has finished a Chunk * @param c The chunk */ void onChunkReady(Chunk* c); void chunkDownloadStarted(WebSeedChunkDownload* cd,Uint32 chunk); void chunkDownloadFinished(WebSeedChunkDownload* cd,Uint32 chunk); Q_SIGNALS: /** * An error occurred while we we're writing or reading from disk. * @param msg Message */ void ioError(const QString & msg); /** * Emitted when a chunk has been downloaded. * @param chunk The chunk */ void chunkDownloaded(Uint32 chunk); private: bool downloadFrom(PieceDownloader* pd); void downloadFrom(WebSeed* ws); void normalUpdate(); bool findDownloadForPD(PieceDownloader* pd); ChunkDownload* selectCD(PieceDownloader* pd,Uint32 num); ChunkDownload* selectWorst(PieceDownloader* pd); private: Torrent & tor; PeerManager & pman; ChunkManager & cman; Uint64 bytes_downloaded; Uint64 curr_chunks_downloaded; Uint64 unnecessary_data; PtrMap current_chunks; QList piece_downloaders; MonitorInterface* tmon; ChunkSelectorInterface* chunk_selector; QList webseeds; PtrMap webseeds_chunks; Uint32 active_webseed_downloads; bool webseeds_on; Uint32 webseed_range_size; bool webseed_endgame_mode; static bool use_webseeds; }; } #endif diff --git a/src/download/httpconnection.h b/src/download/httpconnection.h index 3cfc60c..9633649 100644 --- a/src/download/httpconnection.h +++ b/src/download/httpconnection.h @@ -1,172 +1,172 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTHTTPCONNECTION_H #define BTHTTPCONNECTION_H #include #include #include #include #include class QUrl; namespace bt { /** @author Joris Guisson HTTP connection for webseeding. We do not use KIO here, because we want to be able to apply the maximum upload and download rate to webseeds; */ class HttpConnection : public QObject, public net::SocketReader, public net::StreamSocketListener { Q_OBJECT public: HttpConnection(); - virtual ~HttpConnection(); + ~HttpConnection() override; /// Get the last http response code int responseCode() const {return response_code;} /// Is this connection redirected bool isRedirected() const {return redirected;} /// Get the redirected url QUrl redirectedUrl() const {return redirected_url;} /** * Set the group ID's of the socket * @param up Upload group id * @param down Download group id */ void setGroupIDs(Uint32 up,Uint32 down); /** * Connect to a webseed * @param url Url of the webseeder */ void connectTo(const QUrl &url); /** * Connect to a proxy. * @param proxy The HTTP proxy to use (null means don't use any) * @param proxy_port The port of the HTTP proxy */ void connectToProxy(const QString & proxy,Uint16 proxy_port); /// Check if the connection is OK bool ok() const; /// See if we are connected bool connected() const; /// Has the connection been closed bool closed() const; /// Ready to do another request bool ready() const; /** * Do a HTTP GET request * @param path The path of the file * @param query The query string for the url * @param start Offset into file * @param len Length of data to download */ bool get(const QString & host,const QString & path,const QString & query,bt::Uint64 start,bt::Uint64 len); - virtual void onDataReady(Uint8* buf,Uint32 size); - virtual void connectFinished(bool succeeded); - virtual void dataSent(); + void onDataReady(Uint8* buf,Uint32 size) override; + void connectFinished(bool succeeded) override; + void dataSent() override; /** * Get some part of the * @param data Bytearray to copy the data into * @return true if data was filled in */ bool getData(QByteArray & data); /// Get the current download rate int getDownloadRate() const; /// Get the status string const QString getStatusString() const; private Q_SLOTS: void hostResolved(net::AddressResolver* ar); void connectTimeout(); void replyTimeout(); Q_SIGNALS: void startReplyTimer(int timeout); void stopReplyTimer(); void stopConnectTimer(); private: enum State { IDLE,RESOLVING,CONNECTING,ACTIVE,ERROR,CLOSED }; struct HttpGet { QString host; QString path; QString query; bt::Uint64 start; bt::Uint64 len; bt::Uint64 data_received; QByteArray buffer; QByteArray piece_data; bool response_header_received; bool request_sent; QString failure_reason; bool redirected; QUrl redirected_to; bt::Uint64 content_length; int response_code; HttpGet(const QString & host,const QString & path,const QString & query,bt::Uint64 start,bt::Uint64 len,bool using_proxy); virtual ~HttpGet(); bool onDataReady(Uint8* buf,Uint32 size); bool finished() const {return data_received >= len;} }; net::StreamSocket* sock; State state; mutable QMutex mutex; HttpGet* request; bool using_proxy; QString status; QTimer connect_timer; QTimer reply_timer; Uint32 up_gid,down_gid; bool close_when_finished; bool redirected; QUrl redirected_url; int response_code; }; } #endif diff --git a/src/download/streamingchunkselector.h b/src/download/streamingchunkselector.h index 2e3207c..b6f710c 100644 --- a/src/download/streamingchunkselector.h +++ b/src/download/streamingchunkselector.h @@ -1,79 +1,79 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_STREAMINGCHUNKSELECTOR_H #define BT_STREAMINGCHUNKSELECTOR_H #include #include #include namespace bt { /** ChunkSelector which supports streaming mode. It has a range of chunks which are to be downloaded sequentially. And it has a cursor, to support jumping around in the stream. */ class KTORRENT_EXPORT StreamingChunkSelector : public bt::ChunkSelector { public: StreamingChunkSelector(); - virtual ~StreamingChunkSelector(); + ~StreamingChunkSelector() override; - virtual void init(ChunkManager* cman, Downloader* downer, PeerManager* pman); - virtual bool select(bt::PieceDownloader* pd, bt::Uint32& chunk); - virtual void dataChecked(const bt::BitSet& ok_chunks, Uint32 from, Uint32 to); - virtual void reincluded(bt::Uint32 from, bt::Uint32 to); - virtual void reinsert(bt::Uint32 chunk); - virtual bool selectRange(bt::Uint32& from, bt::Uint32& to, bt::Uint32 max_len); + void init(ChunkManager* cman, Downloader* downer, PeerManager* pman) override; + bool select(bt::PieceDownloader* pd, bt::Uint32& chunk) override; + void dataChecked(const bt::BitSet& ok_chunks, Uint32 from, Uint32 to) override; + void reincluded(bt::Uint32 from, bt::Uint32 to) override; + void reinsert(bt::Uint32 chunk) override; + bool selectRange(bt::Uint32& from, bt::Uint32& to, bt::Uint32 max_len) override; /// Get the critical window size in chunks Uint32 criticialWindowSize() const {return critical_window_size;} /** Set the range to be downloaded sequentially. The cursor will be initialized to the first of the range. @param from Start of range @param to End of range */ void setSequentialRange(bt::Uint32 from, bt::Uint32 to); /// Set the cursor location void setCursor(bt::Uint32 chunk); private: void updateRange(); void initRange(); bool selectFromPreview(bt::PieceDownloader* pd, bt::Uint32& chunk); private: bt::Uint32 range_start; bt::Uint32 range_end; bt::Uint32 cursor; bt::Uint32 critical_window_size; std::list range; std::set preview_chunks; }; } #endif // BT_STREAMINGCHUNKSELECTOR_H diff --git a/src/download/tests/streamingchunkselectortest.cpp b/src/download/tests/streamingchunkselectortest.cpp index 27708f5..6edc615 100644 --- a/src/download/tests/streamingchunkselectortest.cpp +++ b/src/download/tests/streamingchunkselectortest.cpp @@ -1,173 +1,173 @@ #ifndef QT_GUI_LIB #define QT_GUI_LIB #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "testlib/dummytorrentcreator.h" using namespace bt; const bt::Uint64 TEST_FILE_SIZE = 15 * 1024 * 1024; class DummyDownloader : public PieceDownloader { public: - virtual ~DummyDownloader() {} - - virtual bool canAddRequest() const {return true;} - virtual void cancel(const bt::Request&) {} - virtual void cancelAll() {} - virtual bool canDownloadChunk() const {return getNumGrabbed() == 0;} - virtual void download(const bt::Request&) {} - virtual void checkTimeouts() {} - virtual Uint32 getDownloadRate() const {return 0;} - virtual QString getName() const {return "foobar";} - virtual bool isChoked() const {return false;} + ~DummyDownloader() override {} + + bool canAddRequest() const override {return true;} + void cancel(const bt::Request&) override {} + void cancelAll() override {} + bool canDownloadChunk() const override {return getNumGrabbed() == 0;} + void download(const bt::Request&) override {} + void checkTimeouts() override {} + Uint32 getDownloadRate() const override {return 0;} + QString getName() const override {return "foobar";} + bool isChoked() const override {return false;} }; class ExtendedStreamingChunkSelector : public bt::StreamingChunkSelector { public: ExtendedStreamingChunkSelector() {} - virtual ~ExtendedStreamingChunkSelector() {} + ~ExtendedStreamingChunkSelector() override {} void markDownloaded(Uint32 i) { cman->chunkDownloaded(i); } Downloader* downloader() {return downer;} }; class StreamingChunkSelectorTest : public QEventLoop { Q_OBJECT public: StreamingChunkSelectorTest() {} StreamingChunkSelectorTest(QObject* parent) : QEventLoop(parent) {} private Q_SLOTS: void initTestCase() { QLocale::setDefault(QLocale("main")); bt::InitLibKTorrent(); bt::InitLog("streamingchunkselectortest.log", false, true); qsrand(time(0)); } void testSimple() { DummyTorrentCreator creator; bt::TorrentControl tc; QVERIFY(creator.createSingleFileTorrent(TEST_FILE_SIZE, "test.avi")); Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; try { tc.init(0, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); tc.createFiles(); } catch (bt::Error& err) { Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; QFAIL("Torrent load failure"); } ExtendedStreamingChunkSelector* csel = new ExtendedStreamingChunkSelector(); tc.setChunkSelector(csel); QVERIFY(csel != 0); csel->setSequentialRange(0, 50); for (Uint32 i = 0; i < 50; i++) { DummyDownloader dd; Uint32 selected = 0xFFFFFFFF; QVERIFY(csel->select(&dd, selected)); Out(SYS_GEN) << "i = " << i << ", selected = " << selected << endl; QVERIFY(selected == i); csel->markDownloaded(i); } // cleanup tc.setChunkSelector(0); } void testCriticalChunkSpread() { DummyTorrentCreator creator; bt::TorrentControl tc; QVERIFY(creator.createSingleFileTorrent(2 * TEST_FILE_SIZE, "test2.avi")); Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; try { tc.init(0, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); tc.createFiles(); } catch (bt::Error& err) { Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; QFAIL("Torrent load failure"); } ExtendedStreamingChunkSelector* csel = new ExtendedStreamingChunkSelector(); tc.setChunkSelector(csel); QVERIFY(csel != 0); Downloader* downer = csel->downloader(); QVERIFY(downer != 0); // Check that critical chunks are spread over multiple peers csel->setSequentialRange(20, 60); DummyDownloader dd[32]; for (Uint32 i = 0; i < 32; i++) { downer->addPieceDownloader(&dd[i]); } // Check the spread of the downloaders downer->update(); for (Uint32 i = 20; i < csel->criticialWindowSize(); i++) { QVERIFY(downer->downloading(i)); QVERIFY(downer->download(i)->getNumDownloaders() == 32 / csel->criticialWindowSize()); } for (Uint32 i = 0; i < 32; i++) { QVERIFY(dd[i].getNumGrabbed() == 1); } for (Uint32 i = 0; i < 32; i++) { downer->removePieceDownloader(&dd[i]); } // cleanup tc.setChunkSelector(0); } }; QTEST_MAIN(StreamingChunkSelectorTest) #include "streamingchunkselectortest.moc" diff --git a/src/download/webseed.h b/src/download/webseed.h index b58fbb9..0b771a8 100644 --- a/src/download/webseed.h +++ b/src/download/webseed.h @@ -1,224 +1,224 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTWEBSEED_H #define BTWEBSEED_H #include #include #include #include #include #include #include #include namespace bt { class Torrent; class HttpConnection; class ChunkManager; class Chunk; class WebSeedChunkDownload; /** @author Joris Guisson Class which handles downloading from a webseed */ class KTORRENT_EXPORT WebSeed : public QObject,public WebSeedInterface { Q_OBJECT public: WebSeed(const QUrl &url,bool user,const Torrent & tor,ChunkManager & cman); - virtual ~WebSeed(); + ~WebSeed() override; /// Is this webseed busy ? bool busy() const; /// Check if a chunk lies in the current range we are downloading bool inCurrentRange(Uint32 chunk) const {return chunk >= first_chunk && chunk <= last_chunk;} /** * Download a range of chunks * @param first The first chunk * @param last The last chunk */ void download(Uint32 first,Uint32 last); /** * A range has been excluded, if we are fully * downloading in this range, reset. * @param from Start of range * @param to End of range */ void onExcluded(Uint32 from,Uint32 to); /** * Check if the connection has received some data and handle it. * @return The number of bytes downloaded */ Uint32 update(); /** * A chunk has been downloaded. * @param chunk The chunk */ void chunkDownloaded(Uint32 chunk); /** * Cancel the current download and kill the connection */ void cancel(); /// Get the current download rate - Uint32 getDownloadRate() const; + Uint32 getDownloadRate() const override; /** * Set the group ID's of the http connection (for speed limits) * @param up Upload group id * @param down Download group id */ void setGroupIDs(Uint32 up,Uint32 down); /** * Set the proxy to use for all WebSeeds * @param host Hostname or IP address of the proxy * @param port Port number of the proxy */ static void setProxy(const QString & host,bt::Uint16 port); /** * Whether or not to enable or disable the use of a proxy. * When the proxy is disabled, we will use the KDE proxy settings. * @param on On or not */ static void setProxyEnabled(bool on); /// Get the current webseed download WebSeedChunkDownload* currentChunkDownload() {return current;} - virtual void setEnabled(bool on); + void setEnabled(bool on) override; /// Disable the webseed void disable(const QString & reason); /// Get the number of failed attempts Uint32 failedAttempts() const {return num_failures;} public Q_SLOTS: /** * Reset the webseed (kills the connection) */ void reset(); Q_SIGNALS: /** * Emitted when a chunk is downloaded * @param c The chunk */ void chunkReady(Chunk* c); /** * Emitted when a range has been fully downloaded */ void finished(); /** * A ChunkDownload was started * @param cd The ChunkDownloadInterface * @param chunk The chunk which is being started */ void chunkDownloadStarted(WebSeedChunkDownload* cd,Uint32 chunk); /** * A ChunkDownload was finished * @param cd The ChunkDownloadInterface * @param chunk The chunk which is being stopped */ void chunkDownloadFinished(WebSeedChunkDownload* cd,Uint32 chunk); private Q_SLOTS: void redirected(const QUrl &to_url); private: struct Range { Uint32 file; Uint64 off; Uint64 len; }; class AutoDisabled {}; // Exception void fillRangeList(Uint32 chunk); void handleData(const QByteArray & data); void chunkStarted(Uint32 chunk); void chunkStopped(); void connectToServer(); void continueCurChunk(); void readData(); void retryLater(); private: const Torrent & tor; ChunkManager & cman; HttpConnection* conn; QList chunks; Uint32 first_chunk; Uint32 last_chunk; Uint32 cur_chunk; Uint32 bytes_of_cur_chunk; Uint32 num_failures; Uint32 downloaded; WebSeedChunkDownload* current; Uint32 up_gid,down_gid; QList range_queue; QUrl redirected_url; PieceData::Ptr cur_piece; QTimer retry_timer; ConnectionLimit::Token::Ptr token; static QString proxy_host; static Uint16 proxy_port; static bool proxy_enabled; }; class WebSeedChunkDownload : public ChunkDownloadInterface { public: WebSeedChunkDownload(WebSeed* ws,const QString & url,Uint32 index,Uint32 total); - virtual ~WebSeedChunkDownload(); + ~WebSeedChunkDownload() override; - virtual void getStats(Stats & s); + void getStats(Stats & s) override; WebSeed* ws; QString url; Uint32 chunk; Uint32 total_pieces; Uint32 pieces_downloaded; }; } #endif diff --git a/src/interfaces/exitoperation.h b/src/interfaces/exitoperation.h index deacd35..ec0f87b 100644 --- a/src/interfaces/exitoperation.h +++ b/src/interfaces/exitoperation.h @@ -1,68 +1,68 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTEXITOPERATION_H #define BTEXITOPERATION_H #include #include #include namespace bt { /** * @author Joris Guisson * * Object to derive from for operations which need to be performed at exit. * The operation should emit the operationFinished signal when they are done. * * ExitOperation's can be used in combination with a WaitJob, to wait for a certain amount of time * to give several ExitOperation's the time time to finish up. */ class KTORRENT_EXPORT ExitOperation : public QObject { Q_OBJECT public: ExitOperation(); - virtual ~ExitOperation(); + ~ExitOperation() override; /// whether or not we can do a deleteLater on the job after it has finished. virtual bool deleteAllowed() const {return true;} Q_SIGNALS: void operationFinished(ExitOperation* opt); }; /** * Exit operation which waits for a KIO::Job */ class ExitJobOperation : public ExitOperation { Q_OBJECT public: ExitJobOperation(KJob* j); - virtual ~ExitJobOperation(); + ~ExitJobOperation() override; - virtual bool deleteAllowed() const {return true;} + bool deleteAllowed() const override {return true;} private Q_SLOTS: virtual void onResult(KJob* j); }; } #endif diff --git a/src/interfaces/peersource.h b/src/interfaces/peersource.h index c6f34ae..68cd08f 100644 --- a/src/interfaces/peersource.h +++ b/src/interfaces/peersource.h @@ -1,110 +1,110 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPEERSOURCE_H #define BTPEERSOURCE_H #include #include #include #include #include namespace bt { class WaitJob; /** * @author Joris Guisson * * This class is the base class for all classes who which to provide potential peers * for torrents. PeerSources should work independently and should emit a signal when they * have peers ready. */ class KTORRENT_EXPORT PeerSource : public QObject { Q_OBJECT public: PeerSource(); - virtual ~PeerSource(); + ~PeerSource() override; /** * Take the first peer from the list. The item * is removed from the list. * @param addr The address of the peer * @param local Is this is a peer on the local network * @return true If there was one available, false if not */ bool takePeer(net::Address & addr, bool & local); /** * Add a peer to the list of peers. * @param addr The address of the peer * @param port The port * @param local Whether or not the peer is on the local network */ void addPeer(const net::Address & addr,bool local = false); public Q_SLOTS: /** * Start gathering peers. */ virtual void start() = 0; /** * Stop gathering peers. */ virtual void stop(bt::WaitJob* wjob = 0) = 0; /** * The torrent has finished downloading. * This is optional and should be used by HTTP and UDP tracker sources * to notify the tracker. */ virtual void completed(); /** * PeerSources wanting to implement a manual update, should implement this. */ virtual void manualUpdate(); /** * The source is about to be destroyed. Subclasses can override this * to clean up some things. */ virtual void aboutToBeDestroyed(); Q_SIGNALS: /** * This signal should be emitted when a new batch of peers is ready. * @param ps The PeerSource */ void peersReady(PeerSource* ps); private: /// List to keep the potential peers in. QList > peers; }; } #endif diff --git a/src/interfaces/piecedownloader.h b/src/interfaces/piecedownloader.h index 1848ac2..371f87d 100644 --- a/src/interfaces/piecedownloader.h +++ b/src/interfaces/piecedownloader.h @@ -1,148 +1,148 @@ /*************************************************************************** * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPIECEDOWNLOADER_H #define BTPIECEDOWNLOADER_H #include #include #include namespace bt { class Piece; class Request; /** * Interface for all things which want to download pieces from something. * @author Joris Guisson */ class KTORRENT_EXPORT PieceDownloader : public QObject { Q_OBJECT public: PieceDownloader(); - virtual ~PieceDownloader(); + ~PieceDownloader() override; /** * Grab the Peer, indicates how many ChunkDownload's * are using this PeerDownloader. * @return The number of times this PeerDownloader was grabbed */ int grab(); /** * When a ChunkDownload is ready with this PeerDownloader, * it will release it, so that others can use it. */ void release(); /// Get the number of times this PeerDownloader was grabbed. int getNumGrabbed() const {return grabbed;} /** * Send a Request. * @param req The Request */ virtual void download(const bt::Request & req) = 0; /** * Cancel a Request. * @param req The Request */ virtual void cancel(const bt::Request & req) = 0; /** * Cancel all Requests */ virtual void cancelAll() = 0; /** * Get the name of the PieceDownloader * This is something which can be shown in the GUI. * For a regular PeerDownloader, this should be the client and version. * For a webseed this should be the URL */ virtual QString getName() const = 0; /** * Get the current download rate. * @return The download rate in bytes/sec */ virtual bt::Uint32 getDownloadRate() const = 0; /** * See if the PieceDownloader is choked, can be overwritten by subclasses. * @return Whether or not the PieceDownloader is choked */ virtual bool isChoked() const {return false;} /** * Whether or not we can add another request. */ virtual bool canAddRequest() const = 0; /** * Whether or not we can download another chunk from this. */ virtual bool canDownloadChunk() const = 0; /// See if this PieceDownloader has nearly finished a chunk bool isNearlyDone() const {return getNumGrabbed() == 1 && nearly_done;} /// Set the nearly done status of the PeerDownloader void setNearlyDone(bool nd) {nearly_done = nd;} /** * See if the PieceDownloader has a Chunk. * By default this returns true, but it can be * overridden by subclasses. * @param idx The Chunk's index */ virtual bool hasChunk(bt::Uint32 /*idx*/) const {return true;} /** * Check if requests have timedout */ virtual void checkTimeouts() = 0; Q_SIGNALS: /** * Emitted when a request takes longer then 60 seconds to download. * The sender of the request will have to request it again. This does not apply for * unsent requests. Their timestamps will be updated when they get transmitted. * @param r The request */ void timedout(const bt::Request & r); /** * A request was rejected. * @param req The Request */ void rejected(const bt::Request & req); private: int grabbed; bool nearly_done; }; } #endif diff --git a/src/interfaces/serverinterface.h b/src/interfaces/serverinterface.h index 3a991ec..5acf75e 100644 --- a/src/interfaces/serverinterface.h +++ b/src/interfaces/serverinterface.h @@ -1,128 +1,128 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_SERVERINTERFACE_H #define BT_SERVERINTERFACE_H #include #include #include #include #include namespace bt { class SHA1Hash; class PeerManager; /** Base class for all servers which accept connections. */ class KTORRENT_EXPORT ServerInterface : public QObject { Q_OBJECT public: ServerInterface(QObject* parent = 0); - virtual ~ServerInterface(); + ~ServerInterface() override; /** * Change the port. * @param port The new port */ virtual bool changePort(Uint16 port) = 0; /// Set the port to use static void setPort(Uint16 p) {port = p;} /// Get the port in use static Uint16 getPort() {return port;} /** * Add a PeerManager. * @param pman The PeerManager */ static void addPeerManager(PeerManager* pman); /** * Remove a PeerManager. * @param pman The PeerManager */ static void removePeerManager(PeerManager* pman); /** * Find the PeerManager given the info_hash of it's torrent. * @param hash The info_hash * @return The PeerManager or 0 if one can't be found */ static PeerManager* findPeerManager(const SHA1Hash & hash); /** * Find the info_hash based on the skey hash. The skey hash is a hash * of 'req2' followed by the info_hash. This function finds the info_hash * which matches the skey hash. * @param skey HASH('req2',info_hash) * @param info_hash which matches * @return true If one was found */ static bool findInfoHash(const SHA1Hash & skey,SHA1Hash & info_hash); /** * Enable encryption. * @param allow_unencrypted Allow unencrypted connections (if encryption fails) */ static void enableEncryption(bool allow_unencrypted); /** * Disable encrypted authentication. */ static void disableEncryption(); static bool isEncryptionEnabled() {return encryption;} static bool unencryptedConnectionsAllowed() {return allow_unencrypted;} /** Get a list of potential IP addresses to bind to */ static QStringList bindAddresses(); static void setUtpEnabled(bool on,bool only_use_utp); static bool isUtpEnabled() {return utp_enabled;} static bool onlyUseUtp() {return only_use_utp;} static void setPrimaryTransportProtocol(TransportProtocol proto); static TransportProtocol primaryTransportProtocol() {return primary_transport_protocol;} protected: void newConnection(mse::EncryptedPacketSocket::Ptr sock); protected: static Uint16 port; static QList peer_managers; static bool encryption; static bool allow_unencrypted; static bool utp_enabled; static bool only_use_utp; static TransportProtocol primary_transport_protocol; }; } #endif // BT_SERVERINTERFACE_H diff --git a/src/interfaces/torrentfileinterface.h b/src/interfaces/torrentfileinterface.h index ab0ec86..1fdbc1d 100644 --- a/src/interfaces/torrentfileinterface.h +++ b/src/interfaces/torrentfileinterface.h @@ -1,172 +1,172 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTORRENTFILEINTERFACE_H #define BTTORRENTFILEINTERFACE_H #include #include #include #include class QTextCodec; namespace bt { /** * @author Joris Guisson * @brief Interface for a file in a multifile torrent * * This class is the interface for a file in a multifile torrent. */ class KTORRENT_EXPORT TorrentFileInterface : public QObject { Q_OBJECT public: /** * Constructor, set the path and size. * @param index The index of the file in the torrent * @param path The path * @param size The size */ TorrentFileInterface(Uint32 index,const QString & path,Uint64 size); - virtual ~TorrentFileInterface(); + ~TorrentFileInterface() override; enum FileType { UNKNOWN, AUDIO, VIDEO, NORMAL }; /// Get the index of the file Uint32 getIndex() const {return index;} /// Get the path of the file QString getPath() const {return path;} /// Get the path of a file on disk QString getPathOnDisk() const {return path_on_disk;} /// Get the mount point of the file on disk QString getMountPoint() const; /// Set the mount point void setMountPoint(const QString & path) {mount_point = path;} /** * Set the actual path of the file on disk. * @param p The path */ void setPathOnDisk(const QString & p) {path_on_disk = p;} /// Get user modified path (if isn't changed, the normal path is returned) QString getUserModifiedPath() const {return user_modified_path.isEmpty() ? path : user_modified_path;} /// Set the user modified path void setUserModifiedPath(const QString & p) {user_modified_path = p;} /// Get the size of the file Uint64 getSize() const {return size;} /// Get the index of the first chunk in which this file lies Uint32 getFirstChunk() const {return first_chunk;} /// Get the last chunk of the file Uint32 getLastChunk() const {return last_chunk;} /// Get the offset at which the file starts in the first chunk Uint64 getFirstChunkOffset() const {return first_chunk_off;} /// Get how many bytes the files takes up of the last chunk Uint64 getLastChunkSize() const {return last_chunk_size;} /// See if the TorrentFile is null. bool isNull() const {return path.isNull();} /// Set whether we have to not download this file virtual void setDoNotDownload(bool dnd) = 0; /// Whether or not we have to not download this file virtual bool doNotDownload() const = 0; /// Checks if this file is multimedial virtual bool isMultimedia() const = 0; /// Gets the current priority of the torrent virtual Priority getPriority() const {return priority;} /// Sets the priority of the torrent virtual void setPriority(Priority newpriority = NORMAL_PRIORITY) = 0; /// Wheather to emit signal when dl status changes or not. virtual void setEmitDownloadStatusChanged(bool show) = 0; /// Emits signal dlStatusChanged. Use it only with FileSelectDialog! virtual void emitDownloadStatusChanged() = 0; /// Did this file exist before the torrent was loaded by KT bool isPreExistingFile() const {return preexisting;} /// Set whether this file is preexisting void setPreExisting(bool pe) {preexisting = pe;} /// Get the % of the file which is downloaded float getDownloadPercentage() const; /// See if preview is available bool isPreviewAvailable() const {return preview;} /// Set the unencoded path void setUnencodedPath(const QList up); /// Change the text codec void changeTextCodec(QTextCodec* codec); /// Is this a video bool isVideo() const {return filetype == VIDEO;} /// Is this an audio file bool isAudio() const {return filetype == AUDIO;} protected: Uint32 index; Uint32 first_chunk; Uint32 last_chunk; Uint32 num_chunks_downloaded; Uint64 size; Uint64 first_chunk_off; Uint64 last_chunk_size; bool preexisting; bool emit_status_changed; bool preview; mutable FileType filetype; Priority priority; QString path; QString path_on_disk; QString user_modified_path; mutable QString mount_point; QList unencoded_path; }; } #endif diff --git a/src/interfaces/torrentinterface.h b/src/interfaces/torrentinterface.h index cf55f49..a50ea4c 100644 --- a/src/interfaces/torrentinterface.h +++ b/src/interfaces/torrentinterface.h @@ -1,571 +1,571 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTORRENTINTERFACE_H #define BTTORRENTINTERFACE_H #include #include #include #include #include #include #include #include #ifdef ERROR #undef ERROR #endif namespace bt { class Job; class BitSet; class SHA1Hash; class WaitJob; class PeerID; class MonitorInterface; class TorrentFileInterface; class PeerSource; class SHA1Hash; class WebSeedInterface; class JobQueue; class ChunkSelectorInterface; enum TorrentStartResponse { START_OK, USER_CANCELED, NOT_ENOUGH_DISKSPACE, MAX_SHARE_RATIO_REACHED, BUSY_WITH_JOB, QM_LIMITS_REACHED // Max seeds or downloads reached }; enum AutoStopReason { MAX_RATIO_REACHED, MAX_SEED_TIME_REACHED }; struct DHTNode { QString ip; bt::Uint16 port; }; enum TorrentFeature { DHT_FEATURE, UT_PEX_FEATURE // µTorrent peer exchange }; /** * @author Joris Guisson * @brief Interface for an object which controls one torrent * * This class is the interface for an object which controls the * up- and download of one torrent. */ class KTORRENT_EXPORT TorrentInterface : public QObject { Q_OBJECT public: TorrentInterface(); - virtual ~TorrentInterface(); + ~TorrentInterface() override; /// Set the URL which the torrent was loaded from void setLoadUrl(const QUrl &u) {url = u;} /// Get the URL which the torrent was loaded from QUrl loadUrl() const {return url;} /** * Update the object, should be called periodically. */ virtual void update() = 0; /** * Pause the torrent. */ virtual void pause() = 0; /** * Unpause the torrent. */ virtual void unpause() = 0; /** * Start the download of the torrent. */ virtual void start() = 0; /** * Stop the download, closes all connections. * @param wjob WaitJob, used when KT is shutting down, * so that we can wait for all stopped events to reach the tracker */ virtual void stop(bt::WaitJob* wjob = 0) = 0; /** * Update the tracker, this should normally handled internally. * We leave it public so that the user can do a manual announce. */ virtual void updateTracker() = 0; /** * Scrape all or one tracker (private torrents) */ virtual void scrapeTracker() = 0; /// Get the torrent's statistics const TorrentStats & getStats() const {return stats;} /** * Checks if torrent is multimedial and chunks needed for preview are downloaded * This only works for single file torrents * @return true if it is **/ virtual bool readyForPreview() const = 0; /// See if this is a single file torrent and a multimedia files virtual bool isMultimedia() const = 0; /** * Get the torX directory of this torrent. Temporary stuff like the index * file get stored there. */ virtual QString getTorDir() const = 0; /// Get the data directory of this torrent virtual QString getDataDir() const = 0; /** * Get the download running time of this torrent in seconds * @return Uint32 - time in seconds */ virtual Uint32 getRunningTimeDL() const = 0; /** * Get the upload running time of this torrent in seconds * @return Uint32 - time in seconds */ virtual Uint32 getRunningTimeUL() const = 0; /** * Change to a new torX dir. If this fails * we will fall back on the old directory. * @param new_dir The new directory * @return true upon succes */ virtual bool changeTorDir(const QString & new_dir) = 0; enum ChangeOutputFlags { MOVE_FILES = 1,FULL_PATH = 2 }; /** * Change to a new data dir. If this fails * we will fall back on the old directory. * @param new_dir The new directory * @param flags The OR of ChangeOutputFlags * @return true upon succes */ virtual bool changeOutputDir(const QString& new_dir,int flags) = 0; /** * Roll back the previous changeDataDir call. * Does nothing if there was no previous changeDataDir call. */ virtual void rollback() = 0; /** * Get a BitSet of the status of all Chunks */ virtual const bt::BitSet & downloadedChunksBitSet() const = 0; /** * Get a BitSet of the availability of all Chunks */ virtual const bt::BitSet & availableChunksBitSet() const = 0; /** * Get a BitSet of the excluded Chunks */ virtual const bt::BitSet & excludedChunksBitSet() const = 0; /** * Get a bitset of only seed chunks */ virtual const bt::BitSet & onlySeedChunksBitSet() const = 0; /// Set the monitor virtual void setMonitor(MonitorInterface* tmo) = 0; /// Get the number of files in a multifile torrent (0 if we do not have a multifile torrent) virtual Uint32 getNumFiles() const = 0; /** * Get the index'th file of a multifile torrent * @param index The index * @return The TorrentFileInterface (isNull() will be true in case of error) */ virtual TorrentFileInterface & getTorrentFile(Uint32 index) = 0; /** * Const version of the previous one. * @param index The index of the file * @return The TorrentFileInterface (isNull() will be true in case of error) */ virtual const TorrentFileInterface & getTorrentFile(Uint32 index) const = 0; /** * Move a torrent file to a new location. * @param files Map of files and their new location * @return true upon success */ virtual bool moveTorrentFiles(const QMap & files) = 0; /** Create a TorrentFileStream object. If the torrent is destroyed this object must also be destroyed. @param index Index of the file (in case of a single file torrent, this does not matter) @param streaming_mode Set to true if this needs to be streamed (note that only one streaming_mode per torrent is allowed) @param parent Parent of the TorrentFileStream @return A TorrentFileStream or 0 if index is not valid */ virtual TorrentFileStream::Ptr createTorrentFileStream(bt::Uint32 index,bool streaming_mode,QObject* parent) = 0; ///Get a pointer to TrackersList object virtual TrackersList* getTrackersList() = 0; ///Get a pointer to TrackersList object virtual const TrackersList* getTrackersList() const = 0; ///Get the torrent queue number. Zero if not in queue virtual int getPriority() const = 0; ///Set the torrent queue number. virtual void setPriority(int p) = 0; /// Set the max share ratio virtual void setMaxShareRatio(float ratio) = 0; /// Get the max share ratio virtual float getMaxShareRatio() const = 0; /// Set the max seed time in hours (0 is no limit) virtual void setMaxSeedTime(float hours) = 0; /// Get the max seed time virtual float getMaxSeedTime() const = 0; /// Get the comments virtual QString getComments() const = 0; /// Update the status virtual void updateStatus() = 0; ///Is manual announce allowed? virtual bool announceAllowed() = 0; /** * Returns estimated time left for finishing download. Returned value is in seconds. * Uses TimeEstimator class to calculate this value. */ virtual int getETA() = 0; /** * Verify the correctness of all data. If from and to are not a valid range, the * entire torrent will be checked. * @param auto_import Is this an automatic import * @param from Chunk to start from * @param to Chunk to end with */ virtual Job* startDataCheck(bool auto_import, bt::Uint32 from, bt::Uint32 to) = 0; /** * Is storage mounted for this torrent * @param missing Filled with missing mount points (if any) * @return true if there are any missing, false otherwise **/ virtual bool isStorageMounted(QStringList & missing) = 0; /** * Test all files and see if they are not missing. * If so put them in a list */ virtual bool hasMissingFiles(QStringList & sl) = 0; /** * Recreate missing files. */ virtual void recreateMissingFiles() = 0; /** * Mark missing files as do not download. */ virtual void dndMissingFiles() = 0; /// Get the number of initial DHT nodes virtual Uint32 getNumDHTNodes() const = 0; /// Get a DHT node virtual const DHTNode & getDHTNode(Uint32 i) const = 0; /** Delete the data files of the torrent, * they will be lost permanently */ virtual void deleteDataFiles() = 0; ///Checks if a seeding torrent has reached its maximum share ratio virtual bool overMaxRatio() = 0; /// Checks if a seeding torrent has reached it's max seed timery / will be ret virtual bool overMaxSeedTime() = 0; /// Handle an error virtual void handleError(const QString & err) = 0; /// Get the info_hash. virtual const bt::SHA1Hash & getInfoHash() const = 0; /** * Add a new PeerSource * @param ps */ virtual void addPeerSource(PeerSource* ps) = 0; /** * Remove a nPeerSource * @param ps */ virtual void removePeerSource(PeerSource* ps) = 0; /// Is a feature enabled virtual bool isFeatureEnabled(TorrentFeature tf) = 0; /// Disable or enable a feature virtual void setFeatureEnabled(TorrentFeature tf,bool on) = 0; /// Get our PeerID virtual const bt::PeerID & getOwnPeerID() const = 0; /// Set the traffic limits for this torrent virtual void setTrafficLimits(Uint32 up,Uint32 down) = 0; /// Get the traffic limits virtual void getTrafficLimits(Uint32 & up,Uint32 & down) = 0; /// Set the assured speeds virtual void setAssuredSpeeds(Uint32 up,Uint32 down) = 0; /// Get the assured speeds virtual void getAssuredSpeeds(Uint32 & up,Uint32 & down) = 0; /// Check if there is enough diskspace available for this torrent virtual bool checkDiskSpace(bool emit_sig = true) = 0; /// Get the text codec used in the torrent virtual const QTextCodec* getTextCodec() const = 0; /// Set the text codec virtual void changeTextCodec(QTextCodec* tc) = 0; /// Get the number of webseeds virtual Uint32 getNumWebSeeds() const = 0; /// Get a webseed (returns 0 if index is invalid) virtual const WebSeedInterface* getWebSeed(Uint32 i) const = 0; /// Get a webseed (returns 0 if index is invalid) virtual WebSeedInterface* getWebSeed(Uint32 i) = 0; /// Add a webseed (return false, if there is already a webseed with the same url) virtual bool addWebSeed(const QUrl &url) = 0; /// Remove a webseed (only user created ones can be removed) virtual bool removeWebSeed(const QUrl &url) = 0; /// Mark all existing files as downloaded ( virtual void markExistingFilesAsDownloaded() = 0; /// Set the user modified file or toplevel directory name virtual void setUserModifiedFileName(const QString & n) {user_modified_name = n;} /// Gets the user modified file or toplevel directory name QString getUserModifiedFileName() const {return user_modified_name.isEmpty() ? stats.torrent_name : user_modified_name;} /// Set the displayed name virtual void setDisplayName(const QString & n) = 0; /// Gets the displayed name QString getDisplayName() const {return display_name.isEmpty() ? stats.torrent_name : display_name;} /// Set whether the QM can start a torrent. virtual void setAllowedToStart(bool on) = 0; /** * Can the torrent be started by the QM. * @return True if it can, false otherwise */ bool isAllowedToStart() const {return stats.qm_can_start;} /** * Set whether the torrent is queued or not */ virtual void setQueued(bool queued) = 0; /// Get the JobQueue of the torrent virtual const JobQueue* getJobQueue() const = 0; /// Set the ChunkSelector to use (0 resets to the default ChunkSelector) virtual void setChunkSelector(ChunkSelectorInterface* csel) = 0; /// After some network down time, the network is back up virtual void networkUp() = 0; /** * Get the move upon completion directory. * @param dir the directory an empty url disables this feature */ virtual void setMoveWhenCompletedDir(const QString &dir) = 0; /** * Get the move upon completion directory. */ virtual QString getMoveWhenCompletedDir() const = 0; /** * Enable or disable superseeding mode, does nothing if the torrent is not finished. */ virtual void setSuperSeeding(bool on) = 0; typedef QSharedPointer Ptr; typedef QPointer WPtr; Q_SIGNALS: /** * Emitted when we have finished downloading. * @param me The object who emitted the signal */ void finished(bt::TorrentInterface* me); /** * Emitted when a Torrent download is stopped by error * @param me The object who emitted the signal * @param msg Error message */ void stoppedByError(bt::TorrentInterface* me, QString msg); /** * Emitted when maximum share ratio for this torrent is changed * @param me The object which emitted the signal. */ void maxRatioChanged(bt::TorrentInterface* me); /** * Emitted then torrent is stopped from seeding by KTorrent. * Happens when torrent has reached maximum share ratio and maybe we'll add something more... * @param me The object which emitted the signal. * @param reason The reason why it was aut stopped */ void seedingAutoStopped(bt::TorrentInterface* me,bt::AutoStopReason reason); /** * Emitted just before the torrent is started, this should be used to do some * checks on the files in the cache. * @param me The torrent which emitted the signal * @param ret The return value */ void aboutToBeStarted(bt::TorrentInterface* me,bool & ret); /** * Emitted when missing files have been marked as dnd. * The intention of this signal is to update the GUI. * @param me The torrent which emitted the signal */ void missingFilesMarkedDND(bt::TorrentInterface* me); /** * A corrupted chunk has been found during upload. * @param me The torrent which emitted the signal */ void corruptedDataFound(bt::TorrentInterface* me); /** * Disk is running out of space. * @param me The torrent which emitted the signal * @param toStop should this torrent be stopped or not */ void diskSpaceLow(bt::TorrentInterface* me, bool toStop); /** * Torrent has been stopped * @param me The torrent which emitted the signal */ void torrentStopped(bt::TorrentInterface* me); /** * Signal emitted when the torrent needs a data check * @param me The torrent * */ void needDataCheck(bt::TorrentInterface* me); /** * Emitted whenever the status of the torrent changes. * @param me the torrent */ void statusChanged(bt::TorrentInterface* me); /** * Emitted when a chunk is downloaded. * @param me The torrent * @param chunk The chunk */ void chunkDownloaded(bt::TorrentInterface* me,bt::Uint32 chunk); /** * Emitted when the torrent thinks the QM should update the queue */ void updateQueue(); /** * Emitted when all running jobs are done. * @param me the torrent */ void runningJobsDone(bt::TorrentInterface* me); protected: TorrentStats stats; QString user_modified_name; QString display_name; QUrl url; }; } #endif diff --git a/src/magnet/magnetdownloader.h b/src/magnet/magnetdownloader.h index f21b140..a63b724 100644 --- a/src/magnet/magnetdownloader.h +++ b/src/magnet/magnetdownloader.h @@ -1,110 +1,110 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_MAGNETDOWNLOADER_H #define BT_MAGNETDOWNLOADER_H #include #include #include #include #include #include "magnetlink.h" namespace dht { class DHTPeerSource; } namespace bt { class Peer; class PeerManager; /** Class which tries to download the metadata associated to a MagnetLink It basically has a Tracker (optional), a DHTPeerSource and a PeerManager. With these it tries to find peers, connect to them and download the metadata. */ class KTORRENT_EXPORT MagnetDownloader : public QObject, public TrackerDataSource { Q_OBJECT public: MagnetDownloader(const MagnetLink & mlink,QObject* parent); - virtual ~MagnetDownloader(); + ~MagnetDownloader() override; /** Update the MagnetDownloader */ void update(); /// Is the magnet download running bool running() const; /// How many peers are we connected to Uint32 numPeers() const; /// Get the MagnetLink const MagnetLink & magnetLink() const {return mlink;} public Q_SLOTS: /** Start the MagnetDownloader, this will enable DHT. */ void start(); /** Stop the MagnetDownloader */ void stop(); Q_SIGNALS: /** Emitted when downloading the metadata was succesfull. */ void foundMetadata(bt::MagnetDownloader* self,const QByteArray & metadata); private Q_SLOTS: void onNewPeer(Peer* p); void onMetadataDownloaded(const QByteArray & data); void onTorrentDownloaded(KJob*); void dhtStarted(); void dhtStopped(); private: - virtual Uint64 bytesDownloaded() const; - virtual Uint64 bytesUploaded() const; - virtual Uint64 bytesLeft() const; - virtual const SHA1Hash & infoHash() const; - virtual bool isPartialSeed() const; + Uint64 bytesDownloaded() const override; + Uint64 bytesUploaded() const override; + Uint64 bytesLeft() const override; + const SHA1Hash & infoHash() const override; + bool isPartialSeed() const override; private: MagnetLink mlink; QList trackers; PeerManager* pman; dht::DHTPeerSource* dht_ps; QByteArray metadata; Torrent tor; bool found; }; } #endif // BT_MAGNETDOWNLOADER_H diff --git a/src/magnet/tests/magnetlinktest.cpp b/src/magnet/tests/magnetlinktest.cpp index dfc0486..fd6c9d6 100644 --- a/src/magnet/tests/magnetlinktest.cpp +++ b/src/magnet/tests/magnetlinktest.cpp @@ -1,57 +1,57 @@ #include #include #include #include class MagnetLinkTest : public QObject { Q_OBJECT public: MagnetLinkTest() {} - ~MagnetLinkTest() {} + ~MagnetLinkTest() override {} private Q_SLOTS: void init() { } void testParsing() { QString data = QString("magnet:?xt=urn:btih:fe377e017ef52efa83251231b5b991ffae0e77ae&dn=Indie+Top+50+-+Best+of+Indie") +"&tr=http%3A%2F%2Fdenis.stalker.h3q.com%3A6969%2Fannounce" +"&to=http%3A%2F%2Ftorrents.thepiratebay.org%2F5156308%2FIndie_Top_50_-_Best_of_Indie.5156308.TPB.torrent"; bt::MagnetLink mlink(data); QVERIFY(mlink.isValid()); QCOMPARE(mlink.displayName(),QString("Indie Top 50 - Best of Indie")); QCOMPARE(mlink.torrent(),QString("http://torrents.thepiratebay.org/5156308/Indie_Top_50_-_Best_of_Indie.5156308.TPB.torrent")); QCOMPARE(mlink.trackers()[0],QUrl("http://denis.stalker.h3q.com:6969/announce")); bt::Uint8 hash[] = { 0xfe, 0x37, 0x7e, 0x01, 0x7e, 0xf5, 0x2e, 0xfa, 0x83, 0x25, 0x12, 0x31, 0xb5, 0xb9, 0x91, 0xff, 0xae, 0x0e, 0x77, 0xae }; QCOMPARE(mlink.infoHash(),bt::SHA1Hash(hash)); } void testInvalidUrl() { QStringList invalid; invalid << "dinges:"; invalid << "magnet:?xt=dinges"; invalid << "magnet:?xt=urn:btih:fe377e017ef52ef"; invalid << "magnet:?xt=urn:btih:fe377e017ef52efa83251231b5b991ffae0e77--"; foreach (const QString & data,invalid) { bt::MagnetLink mlink(data); QVERIFY(!mlink.isValid()); } } }; QTEST_MAIN(MagnetLinkTest) #include "magnetlinktest.moc" diff --git a/src/mse/encryptedauthenticate.h b/src/mse/encryptedauthenticate.h index 19fe36c..e2c24e9 100644 --- a/src/mse/encryptedauthenticate.h +++ b/src/mse/encryptedauthenticate.h @@ -1,87 +1,87 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef MSEENCRYPTEDAUTHENTICATE_H #define MSEENCRYPTEDAUTHENTICATE_H #include #include #include #include "bigint.h" namespace mse { class RC4Encryptor; const Uint32 MAX_EA_BUF_SIZE = 622 + 512; /** * @author Joris Guisson * * Encrypted version of the Authenticate class */ class EncryptedAuthenticate : public bt::Authenticate { Q_OBJECT public: EncryptedAuthenticate(const net::Address & addr, bt::TransportProtocol proto, const bt::SHA1Hash& info_hash, const bt::PeerID& peer_id, bt::PeerConnector::WPtr pcon); - virtual ~EncryptedAuthenticate(); + ~EncryptedAuthenticate() override; private Q_SLOTS: - virtual void connected(); - virtual void onReadyRead(); + void connected() override; + void onReadyRead() override; private: void handleYB(); void handleCryptoSelect(); void findVC(); void handlePadD(); private: enum State { NOT_CONNECTED, SENT_YA, GOT_YB, FOUND_VC, WAIT_FOR_PAD_D, NORMAL_HANDSHAKE }; BigInt xa,ya,s,skey,yb; State state; RC4Encryptor* our_rc4; Uint8 buf[MAX_EA_BUF_SIZE]; Uint32 buf_size; Uint32 vc_off; Uint32 dec_bytes; bt::SHA1Hash enc,dec; Uint32 crypto_select; Uint16 pad_D_len; Uint32 end_of_crypto_handshake; }; } #endif diff --git a/src/mse/encryptedpacketsocket.h b/src/mse/encryptedpacketsocket.h index a8959e8..f16e982 100644 --- a/src/mse/encryptedpacketsocket.h +++ b/src/mse/encryptedpacketsocket.h @@ -1,164 +1,164 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef MSESTREAMSOCKET_H #define MSESTREAMSOCKET_H #include #include #include class QString; using bt::Uint8; using bt::Uint16; using bt::Uint32; namespace bt { class SHA1Hash; } namespace mse { class RC4Encryptor; /** * @author Joris Guisson * * Wrapper around a TCP socket which handles RC4 encryption. */ class KTORRENT_EXPORT EncryptedPacketSocket : public net::PacketSocket { public: EncryptedPacketSocket(int ip_version); EncryptedPacketSocket(int fd,int ip_version); EncryptedPacketSocket(net::SocketDevice* sock); - virtual ~EncryptedPacketSocket(); + ~EncryptedPacketSocket() override; /** * Send a chunk of data. (Does not encrypt the data) * @param data The data * @param len The length * @return Number of bytes written */ Uint32 sendData(const Uint8* data,Uint32 len); /** * Reads data from the peer. * @param buf The buffer to store the data * @param len The maximum number of bytes to read * @return The number of bytes read */ Uint32 readData(Uint8* buf,Uint32 len); /// Get the number of bytes available to read. Uint32 bytesAvailable() const; /// Are we using encryption bool encrypted() const {return enc != 0;} /** * Initialize the RC4 encryption algorithm. * @param dkey * @param ekey */ void initCrypt(const bt::SHA1Hash & dkey,const bt::SHA1Hash & ekey); /// Set the encryptor void setRC4Encryptor(RC4Encryptor* enc); /// Disables encryption. All data will be sent over as plain text. void disableCrypt(); /// Close the socket void close(); /// Connect the socket to a remote host bool connectTo(const QString & ip,Uint16 port); /// Connect the socket to a remote host bool connectTo(const net::Address & addr); /// Get the IP address of the remote peer QString getRemoteIPAddress() const; /// Get the port of the remote peer bt::Uint16 getRemotePort() const; /// Get the full address net::Address getRemoteAddress() const; /** * Reinsert data, this is needed when we read to much during the crypto handshake. * This data will be the first to read out. The data will be copied to a temporary buffer * which will be destroyed when the reinserted data has been read. */ void reinsert(const Uint8* d,Uint32 size); /// see if the socket is still OK bool ok() const; /// Start monitoring of this socket by the monitor thread void startMonitoring(net::SocketReader* rdr); /// Stop monitoring this socket void stopMonitoring(); /// Is this socket connecting to a remote host bool connecting() const; /// See if a connect was success full bool connectSuccesFull() const; /** * Set the TOS byte for new sockets. * @param t TOS value */ static void setTOS(Uint8 t) {tos = t;} /** * Set the remote address of the socket. Used by Socks to set the actual * address of the connection. * @param addr The address */ void setRemoteAddress(const net::Address & addr); typedef QSharedPointer Ptr; private: - virtual void preProcess(bt::Packet::Ptr packet); - virtual void postProcess(Uint8* data, Uint32 size); + void preProcess(bt::Packet::Ptr packet) override; + void postProcess(Uint8* data, Uint32 size) override; private: RC4Encryptor* enc; Uint8* reinserted_data; Uint32 reinserted_data_size; Uint32 reinserted_data_read; bool monitored; static Uint8 tos; }; } #endif diff --git a/src/mse/encryptedserverauthenticate.h b/src/mse/encryptedserverauthenticate.h index 7ed99d3..912a820 100644 --- a/src/mse/encryptedserverauthenticate.h +++ b/src/mse/encryptedserverauthenticate.h @@ -1,80 +1,80 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef MSEENCRYPTEDSERVERAUTHENTICATE_H #define MSEENCRYPTEDSERVERAUTHENTICATE_H #include #include #include "bigint.h" namespace mse { class RC4Encryptor; const Uint32 MAX_SEA_BUF_SIZE = 608 + 20 + 20 + 8 + 4 + 2 + 512 + 2 + 68; /** @author Joris Guisson */ class EncryptedServerAuthenticate : public bt::ServerAuthenticate { Q_OBJECT public: EncryptedServerAuthenticate(mse::EncryptedPacketSocket::Ptr sock); - virtual ~EncryptedServerAuthenticate(); + ~EncryptedServerAuthenticate() override; private Q_SLOTS: - virtual void onReadyRead(); + void onReadyRead() override; private: void handleYA(); void sendYB(); void findReq1(); void calculateSKey(); void processVC(); void handlePadC(); void handleIA(); private: enum State { WAITING_FOR_YA, WAITING_FOR_REQ1, FOUND_REQ1, FOUND_INFO_HASH, WAIT_FOR_PAD_C, WAIT_FOR_IA, NON_ENCRYPTED_HANDSHAKE }; BigInt xb,yb,s,ya; bt::SHA1Hash skey,info_hash; State state; Uint8 buf[MAX_SEA_BUF_SIZE]; Uint32 buf_size; Uint32 req1_off; Uint32 crypto_provide,crypto_select; Uint16 pad_C_len; Uint16 ia_len; RC4Encryptor* our_rc4; }; } #endif diff --git a/src/net/addressresolver.h b/src/net/addressresolver.h index 68a23ff..9f6fb1c 100644 --- a/src/net/addressresolver.h +++ b/src/net/addressresolver.h @@ -1,93 +1,93 @@ /*************************************************************************** * Copyright (C) 2011 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NET_ADDRESSRESOLVER_H #define NET_ADDRESSRESOLVER_H #include #include #include namespace net { /** * Resolves hostnames into net::Address objects. * This class will clean itself up, after it is done using deleteLater. **/ class KTORRENT_EXPORT AddressResolver : public QObject { Q_OBJECT public: /** * Constructor, initializer the lookup. * @param host Hostname * @param port Port number * @param parent Parent * @param slot Slot of parent to connect to **/ AddressResolver(const QString & host, bt::Uint16 port, QObject* parent, const char* slot); - virtual ~AddressResolver(); + ~AddressResolver() override; /// Dit the resolver succeed ? bool succeeded() const {return succesfull;} /// Get the resulting address const net::Address & address() const {return result;} /** * Convenience method to resolve a hostname. * @param host Hostname * @param port Port number * @param parent Parent * @param slot Slot of parent to connect to * @return void **/ static void resolve(const QString & host, bt::Uint16 port, QObject* parent, const char* slot); /** * Synchronous resolve * @param host Hostname * @param port Port number * @return :Address **/ static net::Address resolve(const QString & host, bt::Uint16 port); Q_SIGNALS: /** * Emitted when hostname lookup succeeded * @param ar This AddressResolver **/ void resolved(net::AddressResolver* ar); private Q_SLOTS: void hostResolved(const QHostInfo & res); private: int lookup_id; net::Address result; bool succesfull; bool ongoing; }; } #endif // NET_ADDRESSRESOLVER_H diff --git a/src/net/downloadthread.h b/src/net/downloadthread.h index 65fbd9b..5fb253d 100644 --- a/src/net/downloadthread.h +++ b/src/net/downloadthread.h @@ -1,66 +1,66 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETDOWNLOADTHREAD_H #define NETDOWNLOADTHREAD_H #include #include #include namespace net { /** * @author Joris Guisson * * Thread which processes incoming data */ class DownloadThread : public NetworkThread { public: DownloadThread(SocketMonitor* sm); - virtual ~DownloadThread(); + ~DownloadThread() override; /// Wake up the download thread void wakeUp(); /// Set the download cap static void setCap(bt::Uint32 cap) {dcap = cap;} /// Get the download cap static Uint32 cap() {return dcap;} /// Set the sleep time when using download caps static void setSleepTime(bt::Uint32 stime); private: - virtual void update(); - virtual bool doGroup(SocketGroup* g,Uint32 & allowance,bt::TimeStamp now); + void update() override; + bool doGroup(SocketGroup* g,Uint32 & allowance,bt::TimeStamp now) override; int waitForSocketReady(); private: WakeUpPipe::Ptr wake_up; static bt::Uint32 dcap; static bt::Uint32 sleep_time; }; } #endif diff --git a/src/net/networkthread.h b/src/net/networkthread.h index f471c2d..b5de486 100644 --- a/src/net/networkthread.h +++ b/src/net/networkthread.h @@ -1,121 +1,121 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETNETWORKTHREAD_H #define NETNETWORKTHREAD_H #include #include #include #include #include using bt::Uint32; namespace net { class SocketMonitor; /** @author Joris Guisson Base class for the 2 networking threads. Handles the socket groups. */ class NetworkThread : public QThread, public Poll { protected: SocketMonitor* sm; bool running; bt::PtrMap groups; bt::TimeStamp prev_run_time; public: NetworkThread(SocketMonitor* sm); - virtual ~NetworkThread(); + ~NetworkThread() override; /** * Add a new group with a given limit * @param gid The group ID (cannot be 0, 0 is the default group) * @param limit The limit in bytes per sec * @param assured_rate The assured rate for this group in bytes per second */ void addGroup(Uint32 gid,Uint32 limit,Uint32 assured_rate); /** * Remove a group * @param gid The group ID */ void removeGroup(Uint32 gid); /** * Set the limit for a group * @param gid The group ID * @param limit The limit */ void setGroupLimit(Uint32 gid,Uint32 limit); /** * Set the assured rate for a group * @param gid The group ID * @param as The assured rate */ void setGroupAssuredRate(Uint32 gid,Uint32 as); /** * The main function of the thread */ - void run(); + void run() override; /** * Subclasses must implement this function */ virtual void update() = 0; /** * Do one SocketGroup * @param g The group * @param allowance The groups allowance * @param now The current time * @return true if the group can go again */ virtual bool doGroup(SocketGroup* g,Uint32 & allowance,bt::TimeStamp now) = 0; /// Stop before the next update void stop() {running = false;} /// Is the thread running bool isRunning() const {return running;} protected: /** * Go over all groups and do them * @param num_ready The number of ready sockets * @param now The current time * @param limit The global limit in bytes per sec */ void doGroups(Uint32 num_ready,bt::TimeStamp now,bt::Uint32 limit); private: Uint32 doGroupsLimited(Uint32 num_ready,bt::TimeStamp now,Uint32 & allowance); }; } #endif diff --git a/src/net/packetsocket.h b/src/net/packetsocket.h index 579b1e4..4ebc851 100644 --- a/src/net/packetsocket.h +++ b/src/net/packetsocket.h @@ -1,103 +1,103 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETBUFFEREDSOCKET_H #define NETBUFFEREDSOCKET_H #include #include #include #include #include #include namespace net { using bt::Uint8; using bt::Uint32; /** * @author Joris Guisson * * Extends the TrafficShapedSocket with outbound bittorrent * packet queues. */ class PacketSocket : public TrafficShapedSocket { public: PacketSocket(SocketDevice* sock); PacketSocket(int fd,int ip_version); PacketSocket(bool tcp,int ip_version); - virtual ~PacketSocket(); + ~PacketSocket() override; /** * Add a packet to send * @param packet The Packet to send **/ void addPacket(bt::Packet::Ptr packet); - virtual Uint32 write(Uint32 max, bt::TimeStamp now); - virtual bool bytesReadyToWrite() const; + Uint32 write(Uint32 max, bt::TimeStamp now) override; + bool bytesReadyToWrite() const override; /// Get the number of data bytes uploaded Uint32 dataBytesUploaded(); /** * Clear all pieces we are not in the progress of sending. * @param reject Whether or not to send a reject */ void clearPieces(bool reject); /** * Do not send a piece which matches this request. * But only if we are not already sending the piece. * @param req The request * @param reject Whether we can send a reject instead */ void doNotSendPiece(const bt::Request& req, bool reject); /// Get the number of pending piece uploads Uint32 numPendingPieceUploads() const; protected: /** * Preprocess the packet data, before it is sent. Default implementation does nothing. * @param packet The packet **/ virtual void preProcess(bt::Packet::Ptr packet); private: bt::Packet::Ptr selectPacket(); protected: std::deque control_packets; std::deque data_packets; //NOTE: revert back to lists because of erase() calls? bt::Packet::Ptr curr_packet; Uint32 ctrl_packets_sent; Uint32 uploaded_data_bytes; }; } #endif diff --git a/src/net/reverseresolver.h b/src/net/reverseresolver.h index fb72aaa..36216e8 100644 --- a/src/net/reverseresolver.h +++ b/src/net/reverseresolver.h @@ -1,103 +1,103 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NET_REVERSERESOLVER_H #define NET_REVERSERESOLVER_H #include #include #include #include #include #include namespace net { class ReverseResolverThread; /** Resolve an IP address into a hostname This should be threated as fire and forget objects, when using them asynchronously. The worker thread will delete them, when they are done. */ class ReverseResolver : public QObject { Q_OBJECT public: ReverseResolver(QObject* parent = 0); - virtual ~ReverseResolver(); + ~ReverseResolver() override; /** Resolve an ip address asynchronously, uses the worker thread Connecting to the resolved signal should be done with Qt::QueuedConnection, seeing that it will be emitted from the worker thread. @param addr The address */ void resolveAsync(const net::Address & addr); /** Resolve an ip address synchronously. */ QString resolve(const net::Address & addr); /** Run the actual resolve and emit the signal when done */ void run(); /// Shutdown the worker thread static void shutdown(); Q_SIGNALS: /// Emitted when the resolution is complete void resolved(const QString & host); private: static ReverseResolverThread* worker; net::Address addr_to_resolve; }; class ReverseResolverThread : public QThread { Q_OBJECT public: ReverseResolverThread(); - virtual ~ReverseResolverThread(); + ~ReverseResolverThread() override; /// Add a ReverseResolver to the todo list void add(ReverseResolver* rr); /// Run the thread - virtual void run(); + void run() override; /// Stop the thread void stop(); private: QMutex mutex; QWaitCondition more_data; QList todo_list; bool stopped; }; } #endif // NET_REVERSERESOLVER_H diff --git a/src/net/serversocket.h b/src/net/serversocket.h index 2158eb7..7fb0bd3 100644 --- a/src/net/serversocket.h +++ b/src/net/serversocket.h @@ -1,165 +1,165 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NET_SERVERSOCKET_H #define NET_SERVERSOCKET_H #include #include #include #include #include namespace net { class Address; /** Convenience class to create and bind a server socket. Internally it combines a QSocketNotifier and a net::Socket. */ class KTORRENT_EXPORT ServerSocket : public QObject { Q_OBJECT public: typedef QSharedPointer Ptr; /** Interface class to handle new connections from a ServerSocket. */ class KTORRENT_EXPORT ConnectionHandler { public: virtual ~ConnectionHandler() {} /** A new connection has been accepted @param fd The filedescriptor of the connection @param addr The address of the connection */ virtual void newConnection(int fd,const net::Address & addr) = 0; }; /** Interface class to handle data from a ServerSocket */ class KTORRENT_EXPORT DataHandler { public: virtual ~DataHandler() {} /** An UDP packet was received @param data The packet @param addr The address from which it was received */ virtual void dataReceived(bt::Buffer::Ptr buffer,const net::Address & addr) = 0; /** Socket has become writeable @param sock The socket */ virtual void readyToWrite(net::ServerSocket* sock) = 0; }; /** Create a TCP server socket @param chandler The connection handler */ ServerSocket(ConnectionHandler* chandler); /** Create an UDP server socket @param dhandler The data handler */ ServerSocket(DataHandler* dhandler); - virtual ~ServerSocket(); + ~ServerSocket() override; /** Bind the socket to an IP and port @param ip The IP address @param port The port number @return true upon success, false otherwise */ bool bind(const QString & ip,bt::Uint16 port); /** Bind the socket to an address @param addr The address @return true upon success, false otherwise */ bool bind(const net::Address & addr); /** Method to send data with the socket. Only use this when the socket is a UDP socket. It will fail for TCP server sockets. @param data The data to send @param addr The address to send to @return The number of bytes sent */ int sendTo(const QByteArray & data,const net::Address & addr); /** Method to send data with the socket. Only use this when the socket is a UDP socket. It will fail for TCP server sockets. @param buf The data to send @param size The size of the data @param addr The address to send to @return The number of bytes sent */ int sendTo(const bt::Uint8* buf,int size,const net::Address & addr); /** Enable write notifications. @param on On or not */ void setWriteNotificationsEnabled(bool on); /** Enable read notifications. @param on On or not */ void setReadNotificationsEnabled(bool on); /** Set the TOS byte of the socket @param type_of_service Value to set @return true upon success, false otherwise */ bool setTOS(unsigned char type_of_service); private Q_SLOTS: void readyToAccept(int fd); void readyToRead(int fd); void readyToWrite(int fd); private: class Private; Private* d; }; } #endif // NET_SERVERSOCKET_H diff --git a/src/net/socket.h b/src/net/socket.h index bdf768d..7f95e6a 100644 --- a/src/net/socket.h +++ b/src/net/socket.h @@ -1,87 +1,87 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETSOCKET_H #define NETSOCKET_H #include #include #include #include "address.h" namespace net { const int SEND_FAILURE = 0; const int SEND_WOULD_BLOCK = -1; /** @author Joris Guisson */ class KTORRENT_EXPORT Socket : public SocketDevice { public: explicit Socket(int fd,int ip_version); explicit Socket(bool tcp,int ip_version); - virtual ~Socket(); + ~Socket() override; - virtual void setBlocking(bool on); - virtual bool connectTo(const Address & addr); - virtual bool connectSuccesFull(); - virtual void close(); - virtual Uint32 bytesAvailable() const; - virtual int send(const bt::Uint8* buf,int len); - virtual int recv(bt::Uint8* buf,int max_len); - virtual bool ok() const {return m_fd >= 0;} - virtual int fd() const {return m_fd;} - virtual bool setTOS(unsigned char type_of_service); - virtual const Address & getPeerName() const {return addr;} - virtual Address getSockName() const; + void setBlocking(bool on) override; + bool connectTo(const Address & addr) override; + bool connectSuccesFull() override; + void close() override; + Uint32 bytesAvailable() const override; + int send(const bt::Uint8* buf,int len) override; + int recv(bt::Uint8* buf,int max_len) override; + bool ok() const override {return m_fd >= 0;} + int fd() const override {return m_fd;} + bool setTOS(unsigned char type_of_service) override; + const Address & getPeerName() const override {return addr;} + Address getSockName() const override; - virtual void reset(); - virtual void prepare(Poll* p,Poll::Mode mode); - virtual bool ready(const Poll* p,Poll::Mode mode) const; + void reset() override; + void prepare(Poll* p,Poll::Mode mode) override; + bool ready(const Poll* p,Poll::Mode mode) const override; bool bind(const QString & ip,Uint16 port,bool also_listen); bool bind(const Address & addr,bool also_listen); int accept(Address & a); int sendTo(const bt::Uint8* buf,int size,const Address & addr); int recvFrom(bt::Uint8* buf,int max_size,Address & addr); bool isIPv4() const {return m_ip_version == 4;} bool isIPv6() const {return m_ip_version == 6;} /// Take the filedescriptor from the socket int take(); typedef QSharedPointer Ptr; private: void cacheAddress(); private: int m_fd; int m_ip_version; int r_poll_index; int w_poll_index; }; } #endif diff --git a/src/net/socks.h b/src/net/socks.h index f6f5921..56de1e8 100644 --- a/src/net/socks.h +++ b/src/net/socks.h @@ -1,123 +1,123 @@ /*************************************************************************** * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETSOCKS_H #define NETSOCKS_H #include #include #include #include namespace net { /** * @author Joris Guisson * * Class which handles the SOCKSv5 protocol */ class KTORRENT_EXPORT Socks : public QObject { Q_OBJECT public: enum State { IDLE, CONNECTING_TO_SERVER, CONNECTING_TO_HOST, CONNECTED, FAILED }; enum SetupState { NONE, AUTH_REQUEST_SENT, USERNAME_AND_PASSWORD_SENT, CONNECT_REQUEST_SENT }; Socks(mse::EncryptedPacketSocket::Ptr sock,const Address & dest); - virtual ~Socks(); + ~Socks() override; /// Setup a socks connection, return the current state State setup(); /** * The socket is ready to write (used to determine if we are connected to the server) * @return The current state */ State onReadyToWrite(); /** * There is data available on the socked * @return The current state */ State onReadyToRead(); /// Is socks enabled static bool enabled() {return socks_enabled;} /// Enable or disable socks static void setSocksEnabled(bool on) {socks_enabled = on;} /// Set the socks server address static void setSocksServerAddress(const QString & host,bt::Uint16 port); /// Set the socks version (4 or 5) static void setSocksVersion(int version) {socks_version = version;} /** * Set the SOCKSv5 Username and password * @param username The username * @param password The password */ static void setSocksAuthentication(const QString & username,const QString & password); private: State sendAuthRequest(); void sendConnectRequest(); void sendUsernamePassword(); State handleAuthReply(); State handleUsernamePasswordReply(); State handleConnectReply(); private Q_SLOTS: void resolved(net::AddressResolver* ar); private: mse::EncryptedPacketSocket::Ptr sock; Address dest; State state; SetupState internal_state; int version; static net::Address socks_server_addr; static bool socks_server_addr_resolved; static QString socks_server_host; static bt::Uint16 socks_server_port; static bool socks_enabled; static int socks_version; static QString socks_username; static QString socks_password; }; } #endif diff --git a/src/net/streamsocket.h b/src/net/streamsocket.h index 6729a33..36b7983 100644 --- a/src/net/streamsocket.h +++ b/src/net/streamsocket.h @@ -1,72 +1,72 @@ /*************************************************************************** * Copyright (C) 2011 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NET_STREAMSOCKET_H #define NET_STREAMSOCKET_H #include #include namespace net { class StreamSocketListener { public: virtual ~StreamSocketListener() {} /** * Called when a StreamSocket gets connected. */ virtual void connectFinished(bool succeeded) = 0; /** * Called when all data has been sent. */ virtual void dataSent() = 0; }; /** * TrafficShapedSocket which provides a simple buffer as outbound data queue. * And a callback interface (StreamSocketListener) for notification of events. */ class StreamSocket : public net::TrafficShapedSocket { public: StreamSocket(bool tcp, int ip_version, StreamSocketListener* listener); - virtual ~StreamSocket(); + ~StreamSocket() override; - virtual bool bytesReadyToWrite() const; - virtual bt::Uint32 write(bt::Uint32 max, bt::TimeStamp now); + bool bytesReadyToWrite() const override; + bt::Uint32 write(bt::Uint32 max, bt::TimeStamp now) override; /** * Add data to send * @param data The QByteArray */ void addData(const QByteArray & data); private: StreamSocketListener* listener; QByteArray buffer; }; } #endif // NET_STREAMSOCKET_H diff --git a/src/net/uploadthread.h b/src/net/uploadthread.h index 876e6e3..52a4ee4 100644 --- a/src/net/uploadthread.h +++ b/src/net/uploadthread.h @@ -1,66 +1,66 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef NETUPLOADTHREAD_H #define NETUPLOADTHREAD_H #include #include #include #include namespace net { class SocketMonitor; /** @author Joris Guisson */ class UploadThread : public NetworkThread { static bt::Uint32 ucap; static bt::Uint32 sleep_time; WakeUpPipe::Ptr wake_up; public: UploadThread(SocketMonitor* sm); - virtual ~UploadThread(); + ~UploadThread() override; /// Wake up thread, data is ready to be sent void signalDataReady(); /// Set the upload cap static void setCap(bt::Uint32 uc) {ucap = uc;} /// Get the upload cap static Uint32 cap() {return ucap;} /// Set the sleep time when using upload caps static void setSleepTime(bt::Uint32 stime); private: - virtual void update(); - virtual bool doGroup(SocketGroup* g,Uint32 & allowance,bt::TimeStamp now); + void update() override; + bool doGroup(SocketGroup* g,Uint32 & allowance,bt::TimeStamp now) override; int waitForSocketsReady(); }; } #endif diff --git a/src/net/wakeuppipe.h b/src/net/wakeuppipe.h index 2839c12..6587673 100644 --- a/src/net/wakeuppipe.h +++ b/src/net/wakeuppipe.h @@ -1,64 +1,64 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KTWAKEUPPIPE_H #define KTWAKEUPPIPE_H #include #include #include #include namespace net { /** A WakeUpPipe's purpose is to wakeup a select or poll call. It works by using a pipe One end needs to be part of the poll or select, and the other end will send dummy data to it. Waking up the select or poll call. */ class KTORRENT_EXPORT WakeUpPipe : public bt::Pipe, public PollClient { public: WakeUpPipe(); - virtual ~WakeUpPipe(); + ~WakeUpPipe() override; /// Wake up the other socket virtual void wakeUp(); /// Read all the dummy data - virtual void handleData(); + void handleData() override; - virtual int fd() const {return readerSocket();} + int fd() const override {return readerSocket();} - virtual void reset(); + void reset() override; /// Have we been woken up bool wokenUp() const {return woken_up;} typedef QSharedPointer Ptr; protected: mutable QMutex mutex; bool woken_up; }; } #endif diff --git a/src/peer/authenticate.h b/src/peer/authenticate.h index f88d585..348c0d4 100644 --- a/src/peer/authenticate.h +++ b/src/peer/authenticate.h @@ -1,92 +1,92 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTAUTHENTICATE_H #define BTAUTHENTICATE_H #include #include #include #include "authenticatebase.h" namespace net { class Socks; } namespace bt { /** * @author Joris Guisson * @brief Authenicate a peer * * After we connect to a peer, * we need to authenticate the peer. This class handles this. */ class Authenticate : public AuthenticateBase { Q_OBJECT public: /** * Connect to a remote host first and authenicate it. * @param addr Address to connect to * @param proto Transport protocol to use * @param info_hash Info hash * @param peer_id Peer ID * @param pman PeerManager */ Authenticate(const net::Address & addr,TransportProtocol proto, const SHA1Hash & info_hash,const PeerID & peer_id, PeerConnector::WPtr pcon); - virtual ~Authenticate(); + ~Authenticate() override; const PeerID & getPeerID() const {return peer_id;} /// See if the authentication is succesfull bool isSuccesfull() const {return succes;} public Q_SLOTS: /// Stop the authentication void stop(); protected Q_SLOTS: - virtual void onReadyWrite(); - virtual void onReadyRead(); + void onReadyWrite() override; + void onReadyRead() override; protected: - void onFinish(bool succes); - void handshakeReceived(bool full); + void onFinish(bool succes) override; + void handshakeReceived(bool full) override; virtual void connected(); protected: SHA1Hash info_hash; PeerID our_peer_id,peer_id; net::Address addr; bool succes; PeerConnector::WPtr pcon; net::Socks* socks; }; } #endif diff --git a/src/peer/authenticatebase.h b/src/peer/authenticatebase.h index e17c9c1..31d8085 100644 --- a/src/peer/authenticatebase.h +++ b/src/peer/authenticatebase.h @@ -1,116 +1,116 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTAUTHENTICATEBASE_H #define BTAUTHENTICATEBASE_H #include #include #include #include namespace bt { class SHA1Hash; class PeerID; /** * @author Joris Guisson * * Base class for authentication classes. This class just groups * some common stuff between Authenticate and ServerAuthentciate. * It has a socket, handles the timing out, provides a function to send * the handshake. */ class AuthenticateBase : public QObject { Q_OBJECT public: AuthenticateBase(); AuthenticateBase(mse::EncryptedPacketSocket::Ptr s); - virtual ~AuthenticateBase(); + ~AuthenticateBase() override; /// Set whether this is a local peer void setLocal(bool loc) {local = loc;} /// Is this a local peer bool isLocal() const {return local;} /// See if the authentication is finished bool isFinished() const {return finished;} /// Flags indicating which extensions are supported Uint32 supportedExtensions() const {return ext_support;} /// get the socket mse::EncryptedPacketSocket::Ptr getSocket() const {return sock;} /// We can read from the socket virtual void onReadyRead(); /// We can write to the socket (used to detect a succesfull connection) virtual void onReadyWrite(); protected: /** * Send a handshake * @param info_hash The info_hash to include * @param our_peer_id Our PeerID */ void sendHandshake(const SHA1Hash & info_hash,const PeerID & our_peer_id); /** * Authentication finished. * @param succes Succes or not */ virtual void onFinish(bool succes) = 0; /** * The other side send a handshake. The first 20 bytes * of the handshake will already have been checked. * @param full Indicates whether we have a full handshake * if this is not full, we should just send our own */ virtual void handshakeReceived(bool full) = 0; /** * Fill in the handshake in a buffer. */ void makeHandshake(bt::Uint8* buf,const SHA1Hash & info_hash,const PeerID & our_peer_id); protected Q_SLOTS: void onTimeout(); void onError(int err); protected: mse::EncryptedPacketSocket::Ptr sock; QTimer timer; bool finished; Uint8 handshake[68]; Uint32 bytes_of_handshake_received; Uint32 ext_support; bool local; }; } #endif diff --git a/src/peer/authenticationmonitor.h b/src/peer/authenticationmonitor.h index 016fc47..045cabe 100644 --- a/src/peer/authenticationmonitor.h +++ b/src/peer/authenticationmonitor.h @@ -1,84 +1,84 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTAUTHENTICATIONMONITOR_H #define BTAUTHENTICATIONMONITOR_H #include #include #include #include namespace bt { class AuthenticateBase; /** @author Joris Guisson Monitors ongoing authentication attempts. This class is a singleton. */ class KTORRENT_EXPORT AuthenticationMonitor : public net::Poll { std::list auths; static AuthenticationMonitor self; AuthenticationMonitor(); public: - virtual ~AuthenticationMonitor(); + ~AuthenticationMonitor() override; /** * Add a new AuthenticateBase object. * @param s */ void add(AuthenticateBase* s); /** * Remove an AuthenticateBase object * @param s */ void remove(AuthenticateBase* s); /** * Check all AuthenticateBase objects. */ void update(); /** * Clear all AuthenticateBase objects, also delets them */ void clear(); /** * Shutdown the authentication manager */ void shutdown(); static AuthenticationMonitor & instance() {return self;} private: void handleData(); }; } #endif diff --git a/src/peer/badpeerslist.h b/src/peer/badpeerslist.h index 3a4bff2..e5371bd 100644 --- a/src/peer/badpeerslist.h +++ b/src/peer/badpeerslist.h @@ -1,50 +1,50 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTBADPEERSLIST_H #define BTBADPEERSLIST_H #include #include namespace bt { /** Blocklist to keep track of bad peers. */ class BadPeersList : public BlockListInterface { public: BadPeersList(); - virtual ~BadPeersList(); + ~BadPeersList() override; - virtual bool blocked(const net::Address & addr) const; + bool blocked(const net::Address & addr) const override; /// Add a bad peer to the list void addBadPeer(const QString & ip); private: QStringList bad_peers; }; } #endif diff --git a/src/peer/packetreader.h b/src/peer/packetreader.h index fcd3f4a..fec7c86 100644 --- a/src/peer/packetreader.h +++ b/src/peer/packetreader.h @@ -1,85 +1,85 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPACKETREADER_H #define BTPACKETREADER_H #include #include #include #include #include namespace bt { class PeerInterface; struct IncomingPacket { QScopedArrayPointer data; Uint32 size; Uint32 read; IncomingPacket(Uint32 size); typedef QSharedPointer Ptr; }; /** * Chops up the raw byte stream from a socket into bittorrent packets * @author Joris Guisson */ class KTORRENT_EXPORT PacketReader : public net::SocketReader { public: PacketReader(Uint32 max_packet_size); - virtual ~PacketReader(); + ~PacketReader() override; /** * Push packets to Peer (runs in main thread) * @param peer The PeerInterface which will handle the packet */ void update(PeerInterface & peer); /// Did an error occur bool ok() const {return !error;} - virtual void onDataReady(Uint8* buf, Uint32 size); + void onDataReady(Uint8* buf, Uint32 size) override; private: Uint32 newPacket(Uint8* buf, Uint32 size); Uint32 readPacket(Uint8* buf, Uint32 size); IncomingPacket::Ptr dequeuePacket(); private: bool error; #ifndef DO_NOT_USE_DEQUE std::deque packet_queue; #else QList packet_queue; #endif QMutex mutex; Uint8 len[4]; int len_received; Uint32 max_packet_size; }; } #endif diff --git a/src/peer/peer.h b/src/peer/peer.h index 2a9452b..20511b8 100644 --- a/src/peer/peer.h +++ b/src/peer/peer.h @@ -1,369 +1,369 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPEER_H #define BTPEER_H #include #include #include #include #include #include #include #include "peerid.h" #include "peerprotocolextension.h" #include "connectionlimit.h" namespace net { class Address; } namespace bt { class Peer; class Piece; class PacketReader; class PeerDownloader; class PeerUploader; class PeerManager; class BitSet; /** * @author Joris Guisson * @brief Manages the connection with a peer * * This class manages a connection with a peer in the P2P network. * It provides functions for sending packets. Packets it receives * get relayed to the outside world using a bunch of signals. */ class KTORRENT_EXPORT Peer : public QObject, public PeerInterface { Q_OBJECT public: /** * Constructor, set the socket. * The socket is already opened. * @param sock The socket * @param peer_id The Peer's BitTorrent ID * @param num_chunks The number of chunks in the file * @param chunk_size Size of each chunk * @param support Which extensions the peer supports * @param local Whether or not it is a local peer * @param token ConnectionLimit token * @param pman The PeerManager */ Peer(mse::EncryptedPacketSocket::Ptr sock, const PeerID & peer_id, Uint32 num_chunks, Uint32 chunk_size, Uint32 support, bool local, ConnectionLimit::Token::Ptr token, PeerManager* pman); - virtual ~Peer(); + ~Peer() override; /// Get the peer's unique ID. Uint32 getID() const {return id;} /// Get the IP address of the Peer. QString getIPAddresss() const; /// Get the port of the Peer Uint16 getPort() const; /// Get the address of the peer net::Address getAddress() const; /// See if the peer is stalled. bool isStalled() const; /// Are we being snubbed by the Peer bool isSnubbed() const; /// Get the upload rate in bytes per sec Uint32 getUploadRate() const; /// Get the download rate in bytes per sec Uint32 getDownloadRate() const; /// Update the up- and down- speed and handle incoming packets void update(); /// Pause the peer connection void pause(); /// Unpause the peer connection void unpause(); /// Get the PeerDownloader. PeerDownloader* getPeerDownloader() const {return downloader;} /// Get the PeerUploader. PeerUploader* getPeerUploader() const {return uploader;} /// Get the PeerManager PeerManager* getPeerManager() {return pman;} /** * Send a chunk of data. * @param data The data * @param len The length * @param proto Indicates whether the packed is data or a protocol message * @return Number of bytes written */ Uint32 sendData(const Uint8* data,Uint32 len); /** * Reads data from the peer. * @param buf The buffer to store the data * @param len The maximum number of bytes to read * @return The number of bytes read */ Uint32 readData(Uint8* buf,Uint32 len); /// Get the number of bytes available to read. Uint32 bytesAvailable() const; /** * Close the peers connection. */ void closeConnection(); /** * Kill the Peer. */ - void kill(); + void kill() override; /// Get the time in milliseconds since the last time a piece was received. Uint32 getTimeSinceLastPiece() const; /// Get the time the peer connection was established. const QTime & getConnectTime() const {return connect_time;} /** * Get the percentual amount of data available from peer. */ float percentAvailable() const; /// Set the ACA score void setACAScore(double s); - virtual bt::Uint32 averageDownloadSpeed() const; + bt::Uint32 averageDownloadSpeed() const override; /// Choke the peer void choke(); /** * Emit the port packet signal. */ void emitPortPacket(); /** * Emit the pex signal */ void emitPex(const QByteArray & data); /// Disable or enable pex void setPexEnabled(bool on); /** * Emit the metadataDownloaded signal */ void emitMetadataDownloaded(const QByteArray & data); /// Send an extended protocol handshake void sendExtProtHandshake(Uint16 port,Uint32 metadata_size,bool partial_seed); /** * Set the peer's group IDs for traffic * @param up_gid The upload gid * @param down_gid The download gid */ void setGroupIDs(Uint32 up_gid,Uint32 down_gid); /// Enable or disable hostname resolving static void setResolveHostnames(bool on); /// Check if the peer has wanted chunks bool hasWantedChunks(const BitSet & wanted_chunks) const; /** * Send a choke packet. */ void sendChoke(); /** * Send an unchoke packet. */ void sendUnchoke(); /** * Sends an unchoke message but doesn't update the am_choked field so KT still thinks * it is choked (and will not upload to it), this is to punish snubbers. */ void sendEvilUnchoke(); /** * Send an interested packet. */ void sendInterested(); /** * Send a not interested packet. */ void sendNotInterested(); /** * Send a request for data. * @param req The Request */ void sendRequest(const Request & r); /** * Cancel a request. * @param req The Request */ void sendCancel(const Request & r); /** * Send a reject for a request * @param req The Request */ void sendReject(const Request & r); /** * Send a have packet. * @param index */ void sendHave(Uint32 index); /** * Send an allowed fast packet * @param index */ void sendAllowedFast(Uint32 index); /** * Send a chunk of data. * @param index Index of chunk * @param begin Offset into chunk * @param len Length of data * @param ch The Chunk * @return true If we satisfy the request, false otherwise */ bool sendChunk(Uint32 index,Uint32 begin,Uint32 len,Chunk * ch); /** * Send a BitSet. The BitSet indicates which chunks we have. * @param bs The BitSet */ void sendBitSet(const BitSet & bs); /** * Send a port message * @param port The port */ void sendPort(Uint16 port); /// Send a have all message void sendHaveAll(); /// Send a have none message void sendHaveNone(); /** * Send a suggest piece packet * @param index Index of the chunk */ void sendSuggestPiece(Uint32 index); /// Send an extended protocol message void sendExtProtMsg(Uint8 id,const QByteArray & data); /** * Clear all pending piece uploads we are not in the progress of sending. */ void clearPendingPieceUploads(); - virtual void chunkAllowed(Uint32 chunk); - virtual void handlePacket(const bt::Uint8* packet, bt::Uint32 size); + void chunkAllowed(Uint32 chunk) override; + void handlePacket(const bt::Uint8* packet, bt::Uint32 size) override; typedef QSharedPointer Ptr; typedef QWeakPointer WPtr; private Q_SLOTS: void resolved(const QString & hinfo); private: void handleChoke(Uint32 len); void handleUnchoke(Uint32 len); void handleInterested(Uint32 len); void handleNotInterested(Uint32 len); void handleHave(const Uint8* packet,Uint32 len); void handleHaveAll(Uint32 len); void handleHaveNone(Uint32 len); void handleBitField(const Uint8* packet,Uint32 len); void handleRequest(const Uint8* packet,Uint32 len); void handlePiece(const Uint8* packet,Uint32 len); void handleCancel(const Uint8* packet,Uint32 len); void handleReject(const Uint8* packet,Uint32 len); void handlePort(const Uint8* packet,Uint32 len); void handleExtendedPacket(const Uint8* packet,Uint32 size); void handleExtendedHandshake(const Uint8* packet,Uint32 size); Q_SIGNALS: /** * Emitted when metadata has been downloaded from the Peer */ void metadataDownloaded(const QByteArray & data); private: mse::EncryptedPacketSocket::Ptr sock; ConnectionLimit::Token::Ptr token; Timer stalled_timer; Uint32 id; Timer snub_timer; PacketReader* preader; PeerDownloader* downloader; PeerUploader* uploader; QTime connect_time; bool pex_allowed; PeerManager* pman; PtrMap extensions; Uint32 ut_pex_id; Uint64 bytes_downloaded_since_unchoke; static bool resolve_hostname; friend class PeerDownloader; }; } #endif diff --git a/src/peer/peerconnector.h b/src/peer/peerconnector.h index 0450dba..290bdf4 100644 --- a/src/peer/peerconnector.h +++ b/src/peer/peerconnector.h @@ -1,90 +1,90 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_PEERCONNECTOR_H #define BT_PEERCONNECTOR_H #include #include #include #include #include #include "connectionlimit.h" #if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0)) template uint qHash(const QSharedPointer &ptr) { return qHash(ptr.data()); } #endif namespace bt { class Authenticate; class PeerManager; /** Class which connects to a peer. */ class KTORRENT_EXPORT PeerConnector : public Resource { public: enum Method { TCP_WITH_ENCRYPTION, TCP_WITHOUT_ENCRYPTION, UTP_WITH_ENCRYPTION, UTP_WITHOUT_ENCRYPTION }; PeerConnector(const net::Address & addr,bool local,PeerManager* pman, ConnectionLimit::Token::Ptr token); - virtual ~PeerConnector(); + ~PeerConnector() override; /// Called when an authentication attempt is finished void authenticationFinished(bt::Authenticate* auth, bool ok); /// Start connecting void start(); /** * Set the maximum number of active PeerConnectors allowed */ static void setMaxActive(Uint32 mc); typedef QSharedPointer Ptr; typedef QWeakPointer WPtr; /// Set a weak pointer to this object void setWeakPointer(WPtr ptr); private: - virtual void acquired(); + void acquired() override; private: class Private; Private* d; }; } #endif // BT_PEERCONNECTOR_H diff --git a/src/peer/peerdownloader.h b/src/peer/peerdownloader.h index 519b841..6799c72 100644 --- a/src/peer/peerdownloader.h +++ b/src/peer/peerdownloader.h @@ -1,203 +1,203 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPEERDOWNLOADER_H #define BTPEERDOWNLOADER_H #include #include #include #include namespace bt { class Peer; class Request; class Piece; /** * Request with a timestamp. */ struct TimeStampedRequest { Request req; TimeStamp time_stamp; TimeStampedRequest(); /** * Constructor, set the request and calculate the timestamp. * @param r The Request */ TimeStampedRequest(const Request & r); /** * Copy constructor, copy the request and the timestamp * @param r The Request */ TimeStampedRequest(const TimeStampedRequest & t); /// Destructor ~TimeStampedRequest(); /// Smaller then operator, uses timestamps to compare bool operator < (const TimeStampedRequest & t) const { return time_stamp < t.time_stamp; } /** * Equality operator, compares requests only. * @param r The Request * @return true if equal */ bool operator == (const Request & r); /** * Equality operator, compares requests only. * @param r The Request * @return true if equal */ bool operator == (const TimeStampedRequest & r); /** * Assignment operator. * @param r The Request to copy * @return *this */ TimeStampedRequest & operator = (const Request & r); /** * Assignment operator. * @param r The TimeStampedRequest to copy * @return *this */ TimeStampedRequest & operator = (const TimeStampedRequest & r); }; /** * @author Joris Guisson * @brief Class which downloads pieces from a Peer * * This class downloads Piece's from a Peer. */ class PeerDownloader : public PieceDownloader { Q_OBJECT public: /** * Constructor, set the Peer * @param peer The Peer * @param chunk_size Size of a chunk in bytes */ PeerDownloader(Peer* peer,Uint32 chunk_size); - virtual ~PeerDownloader(); + ~PeerDownloader() override; /// See if we can add a request to the wait_queue - virtual bool canAddRequest() const; - virtual bool canDownloadChunk() const; + bool canAddRequest() const override; + bool canDownloadChunk() const override; /// Get the number of active requests Uint32 getNumRequests() const; /// Is the Peer choked. - virtual bool isChoked() const; + bool isChoked() const override; /// Is NULL (is the Peer set) bool isNull() const {return peer == 0;} /** * See if the Peer has a Chunk * @param idx The Chunk's index */ - virtual bool hasChunk(Uint32 idx) const; + bool hasChunk(Uint32 idx) const override; /// Get the Peer const Peer* getPeer() const {return peer;} /** * Check for timed out requests. */ - void checkTimeouts(); + void checkTimeouts() override; /// Get the maximum number of chunk downloads Uint32 getMaxChunkDownloads() const; /** * The peer has been choked, all pending requests are rejected. * (except for allowed fast ones) */ void choked(); - virtual QString getName() const; - virtual Uint32 getDownloadRate() const; + QString getName() const override; + Uint32 getDownloadRate() const override; /** * Called when a piece has arrived. * @param p The Piece */ void piece(const Piece & p); public Q_SLOTS: /** * Send a Request. Note that the DownloadCap * may not allow this. (In which case it will * be stored temporarely in the unsent_reqs list) * @param req The Request */ - virtual void download(const Request & req); + void download(const Request & req) override; /** * Cancel a Request. * @param req The Request */ - virtual void cancel(const Request & req); + void cancel(const Request & req) override; /** * Cancel all Requests */ - virtual void cancelAll(); + void cancelAll() override; /** * Handles a rejected request. * @param req */ void onRejected(const Request & req); /** * Send requests and manage wait queue */ void update(); private Q_SLOTS: void peerDestroyed(); private: Peer* peer; QList reqs; QList wait_queue; Uint32 max_wait_queue_size; Uint32 chunk_size; }; } #endif diff --git a/src/peer/peermanager.h b/src/peer/peermanager.h index c6b8fee..aed326b 100644 --- a/src/peer/peermanager.h +++ b/src/peer/peermanager.h @@ -1,292 +1,292 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPEERMANAGER_H #define BTPEERMANAGER_H #include #include #include #include #include #include namespace KNetwork { class KResolverResults; } namespace bt { class PeerID; class Piece; class Torrent; class Authenticate; class ChunkCounter; class PieceDownloader; class ConnectionLimit; using KNetwork::KResolverResults; const Uint32 MAX_SIMULTANIOUS_AUTHS = 20; /// Base class for handling pieces class KTORRENT_EXPORT PieceHandler { public: virtual ~PieceHandler() {} virtual void pieceReceived(const Piece & p) = 0; }; /** * @author Joris Guisson * @brief Manages all the Peers * * This class manages all Peer objects. * It can also open connections to other peers. */ class KTORRENT_EXPORT PeerManager : public QObject { Q_OBJECT public: /** * Constructor. * @param tor The Torrent */ PeerManager(Torrent & tor); - virtual ~PeerManager(); + ~PeerManager() override; /// Get the connection limits static ConnectionLimit & connectionLimits(); /** * Check for new connections, update down and upload speed of each Peer. * Initiate new connections. */ void update(); /** * Pause the peer connections */ void pause(); /** * Unpause the peer connections */ void unpause(); /** * Get a list of all peers. * @return A QList of Peer's */ QList getPeers() const; /** * Find a Peer based on it's ID * @param peer_id The ID * @return A Peer or 0, if nothing could be found */ Peer::Ptr findPeer(Uint32 peer_id); /** * Find a Peer based on it's PieceDownloader * @param pd The PieceDownloader * @return The matching Peer or 0 if none can be found */ Peer::Ptr findPeer(PieceDownloader* pd); void setWantedChunks(const BitSet & bs); /** * Close all Peer connections. */ void closeAllConnections(); /** * Start listening to incoming requests. * @param superseed Set to true to get superseeding */ void start(bool superseed); /** * Stop listening to incoming requests. */ void stop(); /** * Kill all peers who appear to be stale */ void killStalePeers(); /// Get the number of connected peers Uint32 getNumConnectedPeers() const; /// Get the number of connected seeders Uint32 getNumConnectedSeeders() const; /// Get the number of connected leechers Uint32 getNumConnectedLeechers() const; /// Get the number of pending peers we are attempting to connect to Uint32 getNumPending() const; /// Is the peer manager started bool isStarted() const; /// Get the Torrent const Torrent & getTorrent() const; /// Get the combined upload rate of all peers in bytes per sec Uint32 uploadRate() const; /** * A new connection is ready for this PeerManager. * @param sock The socket * @param peer_id The Peer's ID * @param support What extensions the peer supports */ void newConnection(mse::EncryptedPacketSocket::Ptr sock, const PeerID & peer_id, Uint32 support); /** * Add a potential peer * @param addr The peers' address * @param local Is it a peer on the local network * @return void **/ void addPotentialPeer(const net::Address & addr, bool local); /** * Kills all connections to seeders. * This is used when torrent download gets finished * and we should drop all connections to seeders */ void killSeeders(); /** * Kills all peers that are not interested for a long time. * This should be used when torrent is seeding ONLY. */ void killUninterested(); /// Get a BitSet of all available chunks const BitSet & getAvailableChunksBitSet() const; /// Get the chunk counter. ChunkCounter & getChunkCounter(); /// Are we connected to a Peer given it's PeerID ? bool connectedTo(const PeerID & peer_id); /** * A peer has authenticated. * @param auth The Authenticate object * @param pcon The PeerConnector * @param ok Whether or not the attempt was succesfull * @param token The ConnectionLimit::Token */ void peerAuthenticated(Authenticate* auth, PeerConnector::WPtr pcon, bool ok, ConnectionLimit::Token::Ptr token); /** * Save the IP's and port numbers of all peers. */ void savePeerList(const QString & file); /** * Load the peer list again and add them to the potential peers */ void loadPeerList(const QString & file); class PeerVisitor { public: virtual ~PeerVisitor() {} /// Called for each Peer virtual void visit(const Peer::Ptr p) = 0; }; /// Visit all peers void visit(PeerVisitor & visitor); /// Is PEX eanbled bool isPexEnabled() const; /// Enable or disable PEX void setPexEnabled(bool on); /// Set the group IDs of each peer void setGroupIDs(Uint32 up, Uint32 down); /// Have message received by a peer void have(Peer* p, Uint32 index); /// Bitset received by a peer void bitSetReceived(Peer* p, const BitSet & bs); /// Rerun the choker void rerunChoker(); /// Does the choker need to run again bool chokerNeedsToRun() const; /// A PEX message was received void pex(const QByteArray & arr); /// A port packet was received void portPacketReceived(const QString & ip, Uint16 port); /// A Piece was received void pieceReceived(const Piece & p); /// Set the piece handler void setPieceHandler(PieceHandler* ph); /// Enable or disable super seeding void setSuperSeeding(bool on, const BitSet & chunks); /// Send a have message to all peers void sendHave(Uint32 index); /// Set if we are a partial seed or not void setPartialSeed(bool partial_seed); /// Are we a partial seed bool isPartialSeed() const; public Q_SLOTS: /** * A PeerSource, has new potential peers. * @param ps The PeerSource */ void peerSourceReady(PeerSource* ps); Q_SIGNALS: void newPeer(Peer* p); void peerKilled(Peer* p); private: class Private; Private* d; }; } #endif diff --git a/src/peer/serverauthenticate.h b/src/peer/serverauthenticate.h index 41f4996..fcdd1a3 100644 --- a/src/peer/serverauthenticate.h +++ b/src/peer/serverauthenticate.h @@ -1,66 +1,66 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTSERVERAUTHENTICATE_H #define BTSERVERAUTHENTICATE_H #include "authenticatebase.h" namespace bt { /** * @author Joris Guisson * * Handles the authentication of incoming connections on the Server. * Once the authentication is finished, the socket gets handed over * to the right PeerManager. */ class ServerAuthenticate : public AuthenticateBase { Q_OBJECT public: ServerAuthenticate(mse::EncryptedPacketSocket::Ptr sock); - virtual ~ServerAuthenticate(); + ~ServerAuthenticate() override; static bool isFirewalled(); static void setFirewalled(bool Firewalled); protected: - void onFinish(bool succes); - void handshakeReceived(bool full); + void onFinish(bool succes) override; + void handshakeReceived(bool full) override; private: static bool s_firewalled; }; } inline bool bt::ServerAuthenticate::isFirewalled() { return s_firewalled; } inline void bt::ServerAuthenticate::setFirewalled(bool Firewalled) { s_firewalled = Firewalled; } #endif diff --git a/src/peer/tests/accessmanagertest.cpp b/src/peer/tests/accessmanagertest.cpp index a2d6ca8..2f3b815 100644 --- a/src/peer/tests/accessmanagertest.cpp +++ b/src/peer/tests/accessmanagertest.cpp @@ -1,96 +1,96 @@ /*************************************************************************** * Copyright (C) 2012 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include class TestBlockList : public bt::BlockListInterface { public: TestBlockList() { } - virtual ~TestBlockList() + ~TestBlockList() override { } - virtual bool blocked(const net::Address& addr) const + bool blocked(const net::Address& addr) const override { return addr.toString() == "8.8.8.8"; } }; class AccessManagerTest : public QObject { Q_OBJECT public: private Q_SLOTS: void initTestCase() { bt::InitLog("accessmanagertest.log"); } void cleanupTestCase() { } void testCustomIP() { bt::Tracker::setCustomIP("123.123.123.123"); bt::Server::setPort(7777); QVERIFY(!bt::AccessManager::instance().allowed(net::Address("123.123.123.123", 7777))); QVERIFY(bt::AccessManager::instance().allowed(net::Address("123.123.123.123", 7776))); } void testExternalAddress() { bt::Server::setPort(7777); bt::AccessManager::instance().addExternalIP("12.12.12.12"); QVERIFY(!bt::AccessManager::instance().allowed(net::Address("12.12.12.12", 7777))); QVERIFY(bt::AccessManager::instance().allowed(net::Address("12.12.12.12", 7776))); } void testBlockList() { bt::AccessManager::instance().addBlockList(new TestBlockList()); QVERIFY(!bt::AccessManager::instance().allowed(net::Address("8.8.8.8", 7777))); QVERIFY(bt::AccessManager::instance().allowed(net::Address("8.8.8.9", 7776))); } private: }; QTEST_MAIN(AccessManagerTest) #include "accessmanagertest.moc" diff --git a/src/peer/tests/packetreadertest.cpp b/src/peer/tests/packetreadertest.cpp index 09d66f0..87638f7 100644 --- a/src/peer/tests/packetreadertest.cpp +++ b/src/peer/tests/packetreadertest.cpp @@ -1,173 +1,173 @@ /*************************************************************************** * Copyright (C) 2012 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include class PacketReaderTest : public QObject, public bt::PeerInterface { Q_OBJECT public: PacketReaderTest(QObject* parent = 0) : QObject(parent), bt::PeerInterface(bt::PeerID(), 100) {} - virtual void chunkAllowed(bt::Uint32 chunk) + void chunkAllowed(bt::Uint32 chunk) override { Q_UNUSED(chunk); } - virtual void handlePacket(const bt::Uint8* packet, bt::Uint32 size) + void handlePacket(const bt::Uint8* packet, bt::Uint32 size) override { received_packet.reset(new bt::Uint8[size]); memcpy(received_packet.data(), packet, size); received_packet_size = size; } bool check(const bt::Uint8* packet, bt::Uint32 size) { return received_packet_size == size && memcmp(packet, received_packet.data(), size) == 0; } - virtual bt::Uint32 averageDownloadSpeed() const + bt::Uint32 averageDownloadSpeed() const override { return 0; } - virtual void kill() + void kill() override { } void reset() { received_packet_size = 0; received_packet.reset(); } private Q_SLOTS: void initTestCase() { bt::InitLog("packetreadertest.log"); } void cleanupTestCase() { } void testOnePacket() { reset(); bt::Uint8 data[] = {0, 0, 0, 10, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE}; bt::PacketReader pr(1024); pr.onDataReady(data, 14); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(check(data + 4, 10)); } void testMultiplePackets() { reset(); bt::Uint8 data[] = {0, 0, 0, 10, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE}; bt::Uint8 data2[] = {0, 0, 0, 10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; bt::PacketReader pr(1024); pr.onDataReady(data, 14); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(check(data + 4, 10)); pr.onDataReady(data2, 14); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(check(data2 + 4, 10)); } void testChunked() { reset(); bt::Uint8 data[] = {0, 0, 0, 10, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE}; bt::PacketReader pr(1024); pr.onDataReady(data, 7); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(received_packet_size == 0); pr.onDataReady(data + 7, 7); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(check(data + 4, 10)); } void testIncompleteLength() { reset(); bt::Uint8 data[] = {0, 0, 0, 10, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE}; bt::PacketReader pr(1024); pr.onDataReady(data, 3); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(received_packet_size == 0); pr.onDataReady(data + 3, 11); QVERIFY(pr.ok()); pr.update(*this); QVERIFY(check(data + 4, 10)); } void testLengthToLarge() { reset(); bt::Uint8 data[] = {0, 0, 0, 10, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE}; bt::PacketReader pr(7); pr.onDataReady(data, 14); QVERIFY(!pr.ok()); pr.update(*this); QVERIFY(received_packet_size == 0); } void testUnicodeLiteral() { QString a = QString("%1Torrent").arg(QChar(0x00B5)); QVERIFY(a == QStringLiteral("µTorrent")); } private: QScopedArrayPointer received_packet; bt::Uint32 received_packet_size; }; QTEST_MAIN(PacketReaderTest) #include "packetreadertest.moc" diff --git a/src/peer/tests/superseedtest.cpp b/src/peer/tests/superseedtest.cpp index c29fcf7..699bd79 100644 --- a/src/peer/tests/superseedtest.cpp +++ b/src/peer/tests/superseedtest.cpp @@ -1,247 +1,247 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include using namespace bt; #define NUM_CHUNKS 10 #define INVALID_CHUNK 0xFFFFFFFF static int peer_cnt = 0; class DummyPeer : public PeerInterface { public: DummyPeer() : PeerInterface(PeerID(),NUM_CHUNKS) { QString name = QStringLiteral("%1").arg(peer_cnt++); if (name.size() < 20) name = name.leftJustified(20, QLatin1Char(' ')); peer_id = PeerID(name.toLatin1().constData()); allowed_chunk = INVALID_CHUNK; allow_called = false; } - virtual ~DummyPeer() + ~DummyPeer() override {} void reset() { pieces.setAll(false); allowed_chunk = INVALID_CHUNK; } void have(Uint32 chunk) { pieces.set(chunk,true); } void haveAll() { pieces.setAll(true); } - virtual void kill() + void kill() override { killed = true; } - virtual Uint32 averageDownloadSpeed() const {return 0;} + Uint32 averageDownloadSpeed() const override {return 0;} - virtual void chunkAllowed(Uint32 chunk) + void chunkAllowed(Uint32 chunk) override { allowed_chunk = chunk; allow_called = true; } - virtual void handlePacket(const bt::Uint8* packet, Uint32 size) + void handlePacket(const bt::Uint8* packet, Uint32 size) override { Q_UNUSED(packet); Q_UNUSED(size); } Uint32 allowed_chunk; bool allow_called; }; class SuperSeedTest : public QObject { Q_OBJECT public: SuperSeedTest(QObject* parent = 0) : QObject(parent) {} bool allowCalled(PeerInterface* peer) { return ((DummyPeer*)peer)->allow_called && ((DummyPeer*)peer)->allowed_chunk != INVALID_CHUNK; } private Q_SLOTS: void initTestCase() { bt::InitLog("superseedtest.log"); allow_called = false; qsrand(time(0)); } void cleanupTestCase() { } void testSuperSeeding() { Out(SYS_GEN|LOG_DEBUG) << "testSuperSeeding" << endl; SuperSeeder ss(NUM_CHUNKS); // First test, all tree should get a chunk for (int i = 0;i < 3;i++) { DummyPeer* p = &peer[i]; ss.peerAdded(p); QVERIFY(allowCalled(p)); p->allow_called = false; } ss.dump(); DummyPeer* uploader = &peer[0]; DummyPeer* downloader = &peer[1]; DummyPeer* next = &peer[2]; // Simulate normal superseeding operation for (int i = 0;i < 4;i++) { Out(SYS_GEN|LOG_DEBUG) << "======================================" << endl; Uint32 prev_chunk = uploader->allowed_chunk; // Now simulate b downloaded the first chunk from a Uint32 chunk = prev_chunk; Out(SYS_GEN|LOG_DEBUG) << "uploader = " << uploader->getPeerID().toString() << endl; Out(SYS_GEN|LOG_DEBUG) << "downloader = " << downloader->getPeerID().toString() << endl; Out(SYS_GEN|LOG_DEBUG) << "chunk = " << chunk << endl; if (uploader->allowed_chunk == downloader->allowed_chunk) { uploader->have(chunk); downloader->have(chunk); ss.have(downloader,chunk); Out(SYS_GEN|LOG_DEBUG) << "prev_chunk = " << chunk << ", uploader->allowed_chunk = " << uploader->allowed_chunk << endl; QVERIFY(uploader->allowed_chunk != prev_chunk && uploader->allowed_chunk != INVALID_CHUNK); QVERIFY(allowCalled(uploader)); uploader->allow_called = false; QVERIFY(!allowCalled(downloader)); } else { uploader->have(chunk); downloader->have(chunk); ss.have(downloader,chunk); Out(SYS_GEN|LOG_DEBUG) << "prev_chunk = " << chunk << ", uploader->allowed_chunk = " << uploader->allowed_chunk << endl; QVERIFY(uploader->allowed_chunk != prev_chunk && uploader->allowed_chunk != INVALID_CHUNK); QVERIFY(allowCalled(uploader)); // allow should be called again on the uploader uploader->allow_called = false; } // Cycle through peers DummyPeer* n = uploader; uploader = downloader; downloader = next; next = n; ss.dump(); } } #if 0 void testSeed() { Out(SYS_GEN|LOG_DEBUG) << "testSeed" << endl; SuperSeeder ss(NUM_CHUNKS,this); for (int i = 0;i < 4;i++) peer[i].reset(); // First test, all tree should get a chunk for (int i = 0;i < 3;i++) { DummyPeer* p = &peer[i]; ss.peerAdded(p); QVERIFY(allowCalled(p)); QVERIFY(p->allowed_chunk != INVALID_CHUNK); target.clear(); } ss.dump(); // Now simulate a seed sending a have all message peer[3].haveAll(); ss.haveAll(&peer[3]); QVERIFY(allow_called == false); target.clear(); // Continue superseeding DummyPeer* uploader = &peer[0]; DummyPeer* downloader = &peer[1]; DummyPeer* next = &peer[2]; for (int i = 0;i < 4;i++) { Out(SYS_GEN|LOG_DEBUG) << "======================================" << endl; Uint32 prev_chunk = uploader->allowed_chunk; // Now simulate b downloaded the first chunk from a Uint32 chunk = prev_chunk; Out(SYS_GEN|LOG_DEBUG) << "uploader = " << uploader->getPeerID().toString() << endl; Out(SYS_GEN|LOG_DEBUG) << "downloader = " << downloader->getPeerID().toString() << endl; Out(SYS_GEN|LOG_DEBUG) << "chunk = " << chunk << endl; uploader->have(chunk); downloader->have(chunk); ss.have(downloader,chunk); QVERIFY(allowCalled(uploader)); // allow should be called again on the uploader Out(SYS_GEN|LOG_DEBUG) << "prev_chunk = " << chunk << ", uploader->allowed_chunk = " << uploader->allowed_chunk << endl; QVERIFY(uploader->allowed_chunk != prev_chunk && uploader->allowed_chunk != INVALID_CHUNK); target.clear(); // Cycle through peers DummyPeer* n = uploader; uploader = downloader; downloader = next; next = n; ss.dump(); } } #endif private: DummyPeer peer[4]; bool allow_called; }; QTEST_MAIN(SuperSeedTest) #include "superseedtest.moc" diff --git a/src/peer/utmetadata.h b/src/peer/utmetadata.h index f8585f3..3c9f304 100644 --- a/src/peer/utmetadata.h +++ b/src/peer/utmetadata.h @@ -1,68 +1,68 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_UTMETADATA_H #define BT_UTMETADATA_H #include namespace bt { class MetadataDownload; class BDictNode; class Peer; class Torrent; /** Handles ut_metadata extension */ class KTORRENT_EXPORT UTMetaData : public PeerProtocolExtension { public: UTMetaData(const Torrent & tor,bt::Uint32 id,Peer* peer); - virtual ~UTMetaData(); + ~UTMetaData() override; /** Handle a metadata packet */ - void handlePacket(const bt::Uint8* packet, Uint32 size); + void handlePacket(const bt::Uint8* packet, Uint32 size) override; /** Set the reported metadata size */ void setReportedMetadataSize(Uint32 metadata_size); private: void request(BDictNode* dict); void reject(BDictNode* dict); void data(BDictNode* dict,const QByteArray & piece_data); void sendReject(int piece); void sendData(int piece,int total_size,const QByteArray & data); void startDownload(); private: const Torrent & tor; Uint32 reported_metadata_size; MetadataDownload* download; }; } #endif // BT_UTMETADATA_H diff --git a/src/peer/utpex.h b/src/peer/utpex.h index 32b6545..09d6f72 100644 --- a/src/peer/utpex.h +++ b/src/peer/utpex.h @@ -1,84 +1,84 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTUTPEX_H #define BTUTPEX_H #include #include #include #include #include #include "peerprotocolextension.h" namespace bt { class Peer; class BEncoder; /** * @author Joris Guisson * * Class which handles µTorrent's peer exchange */ class KTORRENT_EXPORT UTPex : public PeerProtocolExtension, public PeerManager::PeerVisitor { public: UTPex(Peer* peer,Uint32 id); - virtual ~UTPex(); + ~UTPex() override; /** * Handle a PEX packet * @param packet The packet * @param size The size of the packet */ - void handlePacket(const Uint8* packet,Uint32 size); + void handlePacket(const Uint8* packet,Uint32 size) override; /// Do we need to update PEX (should happen every minute) - bool needsUpdate() const; + bool needsUpdate() const override; /// Send a new PEX packet to the Peer - void update(); + void update() override; /// Change the ID used in the extended packets void changeID(Uint32 nid) {id = nid;} /// Globally disable or enabled PEX static void setEnabled(bool on) {pex_enabled = on;} /// Is PEX enabled globally static bool isEnabled() {return pex_enabled;} private: void encode(BEncoder & enc,const std::map & ps); void encodeFlags(BEncoder & enc,const std::map & flags); - virtual void visit(const bt::Peer::Ptr p); + void visit(const bt::Peer::Ptr p) override; private: std::map peers; TimeStamp last_updated; static bool pex_enabled; std::map added; std::map flags; std::map npeers; }; } #endif diff --git a/src/torrent/advancedchokealgorithm.h b/src/torrent/advancedchokealgorithm.h index 567660e..28d7e65 100644 --- a/src/torrent/advancedchokealgorithm.h +++ b/src/torrent/advancedchokealgorithm.h @@ -1,55 +1,55 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTADVANCEDCHOKEALGORITHM_H #define BTADVANCEDCHOKEALGORITHM_H #include #include "choker.h" namespace bt { struct TorrentStats; /** @author Joris Guisson */ class AdvancedChokeAlgorithm : public ChokeAlgorithm { public: AdvancedChokeAlgorithm(); - virtual ~AdvancedChokeAlgorithm(); + ~AdvancedChokeAlgorithm() override; - virtual void doChokingLeechingState(PeerManager & pman, ChunkManager & cman, const TorrentStats & stats); - virtual void doChokingSeedingState(PeerManager & pman, ChunkManager & cman, const TorrentStats & stats); + void doChokingLeechingState(PeerManager & pman, ChunkManager & cman, const TorrentStats & stats) override; + void doChokingSeedingState(PeerManager & pman, ChunkManager & cman, const TorrentStats & stats) override; private: bool calcACAScore(Peer::Ptr p, ChunkManager & cman, const TorrentStats & stats); Peer::Ptr updateOptimisticPeer(PeerManager & pman, const QList & ppl); void doUnchoking(QList & ppl, Peer::Ptr poup); private: TimeStamp last_opt_sel_time; // last time we updated the optimistic unchoked peer }; } #endif diff --git a/src/torrent/job.h b/src/torrent/job.h index 500c483..85ec9fb 100644 --- a/src/torrent/job.h +++ b/src/torrent/job.h @@ -1,75 +1,75 @@ /*************************************************************************** * Copyright (C) 2009 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_JOB_H #define BT_JOB_H #include #include #include "torrentstats.h" class KJobTrackerInterface; namespace bt { class TorrentControl; /** A Job is a KIO::Job which runs on a torrent */ class KTORRENT_EXPORT Job : public KIO::Job { Q_OBJECT public: Job(bool stop_torrent,TorrentControl* tc); - virtual ~Job(); + ~Job() override; /// Do we need to stop the torrent when the job is running bool stopTorrent() const {return stop_torrent;} - virtual void start(); + void start() override; virtual void kill(bool quietly=true); /// Return the status of the torrent during the job (default implementation returns INVALID_STATUS) virtual TorrentStatus torrentStatus() const; /// Get the torrent associated with this job TorrentControl* torrent() {return tc;} /// Set the torrent associated with this job void setTorrent(TorrentControl* t) {tc = t;} /// Set the job tracker static void setJobTracker(KJobTrackerInterface* trk); protected: /// Register the job with the tracker void registerWithTracker(); private: TorrentControl* tc; bool stop_torrent; static KJobTrackerInterface* tracker; }; } #endif // BT_JOB_H diff --git a/src/torrent/jobqueue.h b/src/torrent/jobqueue.h index f1a7c2f..6ef13e8 100644 --- a/src/torrent/jobqueue.h +++ b/src/torrent/jobqueue.h @@ -1,68 +1,68 @@ /*************************************************************************** * Copyright (C) 2009 by * * Joris Guisson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_JOBQUEUE_H #define BT_JOBQUEUE_H #include #include #include namespace bt { class Job; /** A job queue handles all jobs running on a torrent in a sequential order */ class KTORRENT_EXPORT JobQueue : public QObject { Q_OBJECT public: JobQueue(TorrentControl* parent); - virtual ~JobQueue(); + ~JobQueue() override; /// Are there running jobs bool runningJobs() const; /// Start the next job void startNextJob(); /// Enqueue a job void enqueue(Job* job); /// Get the current job Job* currentJob(); /// Kill all jobs void killAll(); private Q_SLOTS: void jobDone(KJob* job); private: QList queue; TorrentControl* tc; bool restart; }; } #endif // BT_JOBQUEUE_H diff --git a/src/torrent/peersourcemanager.h b/src/torrent/peersourcemanager.h index 00919a0..88f8168 100644 --- a/src/torrent/peersourcemanager.h +++ b/src/torrent/peersourcemanager.h @@ -1,95 +1,95 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTPEERSOURCEMANAGER_H #define BTPEERSOURCEMANAGER_H #include #include #include #include #include namespace dht { class DHTPeerSource; } namespace bt { class Torrent; class TorrentControl; class PeerSource; /** * @author Joris Guisson * * This class manages all PeerSources. */ class PeerSourceManager : public TrackerManager { Q_OBJECT QList additional; dht::DHTPeerSource* m_dht; public: PeerSourceManager(TorrentControl* tor,PeerManager* pman); - virtual ~PeerSourceManager(); + ~PeerSourceManager() override; /** * Add a PeerSource, the difference between PeerSource and Tracker * is that only one Tracker can be used at the same time, * PeerSource can always be used. * @param ps The PeerSource */ void addPeerSource(PeerSource* ps); /** * Remove a Tracker or PeerSource. * @param ps */ void removePeerSource(PeerSource* ps); /** * See if the PeerSourceManager has been started */ bool isStarted() const {return started;} - virtual void start(); - virtual void stop(WaitJob* wjob = 0); - virtual void completed(); - virtual void manualUpdate(); + void start() override; + void stop(WaitJob* wjob = 0) override; + void completed() override; + void manualUpdate() override; ///Adds DHT as PeerSource for this torrent void addDHT(); ///Removes DHT from PeerSourceManager for this torrent. void removeDHT(); ///Checks if DHT is enabled bool dhtStarted(); }; } #endif diff --git a/src/torrent/server.cpp b/src/torrent/server.cpp index 84661e9..1928fd2 100644 --- a/src/torrent/server.cpp +++ b/src/torrent/server.cpp @@ -1,123 +1,123 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "server.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "globals.h" #include "torrent.h" #include namespace bt { typedef QSharedPointer ServerSocketPtr; class Server::Private : public net::ServerSocket::ConnectionHandler { public: Private(Server* p) : p(p) { } - ~Private() + ~Private() override { } void reset() { sockets.clear(); } - virtual void newConnection(int fd,const net::Address & addr) + void newConnection(int fd,const net::Address & addr) override { mse::EncryptedPacketSocket::Ptr s(new mse::EncryptedPacketSocket(fd,addr.ipVersion())); p->newConnection(s); } void add(const QString & ip,bt::Uint16 port) { ServerSocketPtr sock(new net::ServerSocket(this)); if (sock->bind(ip,port)) { sockets.append(sock); } } Server* p; QList sockets; }; Server::Server() : d(new Private(this)) { } Server::~Server() { Globals::instance().getPortList().removePort(port,net::TCP); delete d; } bool Server::changePort(Uint16 p) { if (d->sockets.count() > 0 && p == port) return true; Globals::instance().getPortList().removePort(port,net::TCP); d->reset(); QStringList possible = bindAddresses(); foreach (const QString & addr,possible) { d->add(addr,p); } if (d->sockets.count() == 0) { // Try any addresses if previous binds failed d->add(QHostAddress(QHostAddress::AnyIPv6).toString(),p); d->add(QHostAddress(QHostAddress::Any).toString(),p); } if (d->sockets.count()) { Globals::instance().getPortList().addNewPort(p,net::TCP,true); return true; } else return false; } } diff --git a/src/torrent/server.h b/src/torrent/server.h index 45503f5..21c9539 100644 --- a/src/torrent/server.h +++ b/src/torrent/server.h @@ -1,60 +1,60 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTSERVER_H #define BTSERVER_H #include #include #include #include #include "globals.h" namespace bt { class PeerManager; /** * @author Joris Guisson * * Class which listens for incoming connections. * Handles authentication and then hands of the new * connections to a PeerManager. * * All PeerManager's should register with this class when they * are created and should unregister when they are destroyed. */ class KTORRENT_EXPORT Server : public ServerInterface { Q_OBJECT public: Server(); - virtual ~Server(); + ~Server() override; - virtual bool changePort(Uint16 port); + bool changePort(Uint16 port) override; private: class Private; Private* d; }; } #endif diff --git a/src/torrent/tests/torrentfilestreammultitest.cpp b/src/torrent/tests/torrentfilestreammultitest.cpp index bb0c802..3eba5ad 100644 --- a/src/torrent/tests/torrentfilestreammultitest.cpp +++ b/src/torrent/tests/torrentfilestreammultitest.cpp @@ -1,170 +1,170 @@ #ifndef QT_GUI_LIB #define QT_GUI_LIB #endif #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace bt; const bt::Uint32 TEST_FILE_SIZE = 5 * 1024 * 1024; bt::Uint64 RandomSize(bt::Uint64 min_size, bt::Uint64 max_size) { bt::Uint64 r = max_size - min_size; return min_size + qrand() % r; } class TorrentFileStreamMultiTest : public QEventLoop, public bt::QueueManagerInterface { Q_OBJECT public: TorrentFileStreamMultiTest(QObject* parent = 0) : QEventLoop(parent) { } - virtual bool alreadyLoaded(const bt::SHA1Hash& ih) const + bool alreadyLoaded(const bt::SHA1Hash& ih) const override { Q_UNUSED(ih); return false; } - virtual void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk) + void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk) override { Q_UNUSED(ih); Q_UNUSED(trk); } private Q_SLOTS: void initTestCase() { QLocale::setDefault(QLocale("main")); bt::InitLog("torrentfilestreammultitest.log", false, false); files["aaa.avi"] = RandomSize(TEST_FILE_SIZE / 2, TEST_FILE_SIZE); files["bbb.avi"] = RandomSize(TEST_FILE_SIZE / 2, TEST_FILE_SIZE); files["ccc.avi"] = RandomSize(TEST_FILE_SIZE / 2, TEST_FILE_SIZE); QVERIFY(creator.createMultiFileTorrent(files, "movies")); Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; try { tc.init(this, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); tc.createFiles(); QVERIFY(tc.hasExistingFiles()); tc.startDataCheck(false, 0, tc.getStats().total_chunks); do { processEvents(AllEvents, 1000); } while (tc.getStats().status == bt::CHECKING_DATA); QVERIFY(tc.getStats().completed); } catch (bt::Error& err) { Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; QFAIL("Torrent load failure"); } qsrand(time(0)); } void cleanupTestCase() { } void testSimple() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testSimple() " << endl; // Simple test read each file and check if they are the same on disk for (bt::Uint32 i = 0; i < tc.getNumFiles(); i++) { Out(SYS_GEN | LOG_DEBUG) << "Doing file " << i << endl; bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(i, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); QVERIFY(stream->size() == (qint64)tc.getTorrentFile(i).getSize()); QByteArray tmp(stream->size(), 0); qint64 written = 0; while (written < stream->size()) { qint64 ret = stream->read(tmp.data(), stream->size()); Out(SYS_GEN | LOG_DEBUG) << "Returned " << ret << endl; QVERIFY(ret == stream->size()); written += ret; // Load the file and check if the data is the same QFile fptr(stream->path()); QVERIFY(fptr.open(QIODevice::ReadOnly)); QByteArray tmp2(stream->size(), 0); QVERIFY(fptr.read(tmp2.data(), stream->size()) == stream->size()); QVERIFY(tmp == tmp2); } stream->close(); } Out(SYS_GEN | LOG_DEBUG) << "End: testSimple() " << endl; } void testSeek() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testSeek() " << endl; // In each file take a couple of random samples and compare them with the actual file for (bt::Uint32 i = 0; i < tc.getNumFiles(); i++) { bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(i, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); QVERIFY(stream->size() == (qint64)tc.getTorrentFile(i).getSize()); QFile fptr(stream->path()); QVERIFY(fptr.open(QIODevice::ReadOnly)); for (bt::Uint32 j = 0; j < 10; j++) { qint64 off = qrand() % (stream->size() - 256); QVERIFY(stream->seek(off)); QVERIFY(fptr.seek(off)); QByteArray sdata(256, 0); QVERIFY(stream->read(sdata.data(), 256) == 256); QByteArray fdata(256, 0); QVERIFY(fptr.read(fdata.data(), 256) == 256); QVERIFY(sdata == fdata); } stream->close(); } Out(SYS_GEN | LOG_DEBUG) << "End: testSeek() " << endl; } private: DummyTorrentCreator creator; bt::TorrentControl tc; QMap files; }; QTEST_MAIN(TorrentFileStreamMultiTest) #include "torrentfilestreammultitest.moc" diff --git a/src/torrent/tests/torrentfilestreamtest.cpp b/src/torrent/tests/torrentfilestreamtest.cpp index 6e18a72..c7a68da 100644 --- a/src/torrent/tests/torrentfilestreamtest.cpp +++ b/src/torrent/tests/torrentfilestreamtest.cpp @@ -1,282 +1,282 @@ #ifndef QT_GUI_LIB #define QT_GUI_LIB #endif #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace bt; const bt::Uint32 TEST_FILE_SIZE = 5 * 1024 * 1024; class TorrentFileStreamTest : public QEventLoop, public bt::QueueManagerInterface { Q_OBJECT public: TorrentFileStreamTest(QObject* parent = 0) : QEventLoop(parent) { } - virtual bool alreadyLoaded(const bt::SHA1Hash& ih) const + bool alreadyLoaded(const bt::SHA1Hash& ih) const override { Q_UNUSED(ih); return false; } - virtual void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk) + void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk) override { Q_UNUSED(ih); Q_UNUSED(trk); } private Q_SLOTS: void initTestCase() { QLocale::setDefault(QLocale("main")); bt::InitLog("torrentfilestreamtest.log", false, false); QVERIFY(creator.createSingleFileTorrent(TEST_FILE_SIZE, "test.avi")); QVERIFY(creator2.createSingleFileTorrent(TEST_FILE_SIZE, "test2.avi")); Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; Out(SYS_GEN | LOG_DEBUG) << "Created " << creator2.torrentPath() << endl; try { tc.init(this, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); tc.createFiles(); QVERIFY(tc.hasExistingFiles()); tc.startDataCheck(false, 0, tc.getStats().total_chunks); do { processEvents(AllEvents, 1000); } while (tc.getStats().status == bt::CHECKING_DATA); QVERIFY(tc.getStats().completed); incomplete_tc.init(this, bt::LoadFile(creator2.torrentPath()), creator2.tempPath() + "tor0", creator2.tempPath() + "data/"); incomplete_tc.createFiles(); } catch (bt::Error& err) { Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; QFAIL("Torrent load failure"); } qsrand(time(0)); } void cleanupTestCase() { } void testSimple() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testSimple() " << endl; bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); // Simple test read per chunk and verify if it works QByteArray tmp(tc.getStats().chunk_size, 0); bt::Uint64 written = 0; bt::Uint32 idx = 0; while (written < TEST_FILE_SIZE) { qint64 ret = stream->read(tmp.data(), tc.getStats().chunk_size); QVERIFY(ret == tc.getStats().chunk_size); written += tc.getStats().chunk_size; // Verify the hash bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(), tmp.size()); QVERIFY(hash == tc.getTorrent().getHash(idx)); idx++; } stream->close(); Out(SYS_GEN | LOG_DEBUG) << "End: testSimple() " << endl; } void testSeek() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testSeek() " << endl; bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); // Simple test read per chunk and seek somewhat bt::Uint32 chunk_size = tc.getStats().chunk_size; QByteArray tmp(chunk_size, 0); bt::Uint64 written = 0; bt::Uint32 idx = 0; while (written < TEST_FILE_SIZE) { // Chunk size of last chunk can be smaller if (idx == tc.getStats().total_chunks - 1) { chunk_size = tc.getStats().chunk_size % tc.getStats().total_bytes; if (chunk_size == 0) chunk_size = tc.getStats().chunk_size; } // Lets read in two times, first at the back and then at the front qint64 split = qrand() % chunk_size; while (split == 0) split = qrand() % chunk_size; QVERIFY(stream->seek(idx * tc.getStats().chunk_size + split)); qint64 ret = stream->read(tmp.data() + split, chunk_size - split); QVERIFY(ret == (chunk_size - split)); written += ret; QVERIFY(stream->seek(idx * tc.getStats().chunk_size)); ret = stream->read(tmp.data(), split); QVERIFY(ret == split); written += ret; // Verify the hash bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(), tmp.size()); QVERIFY(hash == tc.getTorrent().getHash(idx)); idx++; } stream->close(); Out(SYS_GEN | LOG_DEBUG) << "End: testSeek() " << endl; } void testRandomAccess() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testRandomAccess() " << endl; bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); // Read an area of around 5 chunks in at a random location // And verify the 3 middle chunks qint64 range_size = tc.getStats().chunk_size * 5; qint64 off = ((qrand() % 100) / 100.0) * (tc.getStats().total_bytes - range_size); QVERIFY(stream->seek(off)); Out(SYS_GEN | LOG_DEBUG) << "Reading random range" << endl; Out(SYS_GEN | LOG_DEBUG) << "range_size = " << range_size << endl; Out(SYS_GEN | LOG_DEBUG) << "off = " << off << endl; QByteArray range(range_size, 0); qint64 bytes_read = 0; while (bytes_read < range_size) { qint64 ret = stream->read(range.data() + bytes_read, range_size - bytes_read); Out(SYS_GEN | LOG_DEBUG) << "ret = " << ret << endl; Out(SYS_GEN | LOG_DEBUG) << "read = " << bytes_read << endl; QVERIFY(ret > 0); bytes_read += ret; } { QFile fptr(stream->path()); QVERIFY(fptr.open(QIODevice::ReadOnly)); QByteArray tmp(range_size, 0); fptr.seek(off); QVERIFY(fptr.read(tmp.data(), range_size) == range_size); QVERIFY(tmp == range); } QVERIFY(bytes_read == range_size); // Calculate the offset of the first chunk in range qint64 chunk_idx = off / tc.getStats().chunk_size; if (off % tc.getStats().chunk_size != 0) chunk_idx++; qint64 chunk_off = chunk_idx * tc.getStats().chunk_size - off; Out(SYS_GEN | LOG_DEBUG) << "chunk_idx = " << chunk_idx << endl; Out(SYS_GEN | LOG_DEBUG) << "chunk_off = " << chunk_off << endl; // Verify the hashes for (int i = 0; i < 3; i++) { bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)range.data() + chunk_off, tc.getStats().chunk_size); Out(SYS_GEN | LOG_DEBUG) << "chash = " << hash.toString() << endl; Out(SYS_GEN | LOG_DEBUG) << "whash = " << tc.getTorrent().getHash(chunk_idx).toString() << endl; QVERIFY(hash == tc.getTorrent().getHash(chunk_idx)); chunk_idx++; chunk_off += tc.getStats().chunk_size; } stream->close(); Out(SYS_GEN | LOG_DEBUG) << "End: testRandomAccess() " << endl; } void testMultiSeek() { Out(SYS_GEN | LOG_DEBUG) << "Begin: testMultiSeek() " << endl; bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0, false, this); QVERIFY(stream); QVERIFY(!stream->open(QIODevice::ReadWrite)); QVERIFY(stream->open(QIODevice::ReadOnly)); QFile fptr(stream->path()); QVERIFY(fptr.open(QIODevice::ReadOnly)); for (int i = 0; i < 20; i++) { qint64 off = qrand() % (TEST_FILE_SIZE - 100); // Seek to a random location QVERIFY(stream->seek(off)); QByteArray tmp(100, 0); QVERIFY(stream->read(tmp.data(), 100) == 100); // Verify those QByteArray tmp2(100, 0); fptr.seek(off); QVERIFY(fptr.read(tmp2.data(), 100) == 100); QVERIFY(tmp == tmp2); } stream->close(); Out(SYS_GEN | LOG_DEBUG) << "End: testMultiSeek() " << endl; } void testStreamingCreate() { bt::TorrentFileStream::Ptr a = tc.createTorrentFileStream(0, true, this); QVERIFY(a); bt::TorrentFileStream::Ptr b = tc.createTorrentFileStream(0, true, this); QVERIFY(!b); a.clear(); b = tc.createTorrentFileStream(0, true, this); QVERIFY(b); } void testSeekToUndownloadedSection() { bt::TorrentFileStream::Ptr a = incomplete_tc.createTorrentFileStream(0, true, this); QVERIFY(incomplete_tc.getStats().completed == false); QVERIFY(a->seek(TEST_FILE_SIZE / 2)); QVERIFY(a->bytesAvailable() == 0); } private: DummyTorrentCreator creator; DummyTorrentCreator creator2; bt::TorrentControl tc; bt::TorrentControl incomplete_tc; }; QTEST_MAIN(TorrentFileStreamTest) #include "torrentfilestreamtest.moc" diff --git a/src/torrent/torrentcontrol.h b/src/torrent/torrentcontrol.h index 972f32c..4b5116d 100644 --- a/src/torrent/torrentcontrol.h +++ b/src/torrent/torrentcontrol.h @@ -1,352 +1,352 @@ /*************************************************************************** * Copyright (C) 2005 by * * Joris Guisson * * Ivan Vasic * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTORRENTCONTROL_H #define BTTORRENTCONTROL_H #include #include #include #include #include #include #include #include #include "torrent.h" #include "globals.h" class QStringList; class QString; class KJob; namespace bt { class StatsFile; class Choker; class PeerSourceManager; class ChunkManager; class PeerManager; class Downloader; class Uploader; class Peer; class BitSet; class QueueManagerInterface; class TimeEstimator; class WaitJob; class MonitorInterface; class ChunkSelectorFactoryInterface; class CacheFactory; class JobQueue; class DataCheckerJob; /** * @author Joris Guisson * @brief Controls just about everything * * This is the interface which any user gets to deal with. * This class controls the uploading, downloading, choking, * updating the tracker and chunk management. */ class KTORRENT_EXPORT TorrentControl : public TorrentInterface, public FilePriorityListener { Q_OBJECT public: TorrentControl(); - virtual ~TorrentControl(); + ~TorrentControl() override; /// Get the Torrent. const Torrent & getTorrent() const {return *tor;} /** * Initialize the TorrentControl. * @param qman The QueueManager * @param data The data of the torrent * @param tmpdir The directory to store temporary data * @param datadir The directory to store the actual file(s) * (only used the first time we load a torrent) * @throw Error when something goes wrong */ void init(QueueManagerInterface* qman, const QByteArray & data, const QString & tmpdir, const QString & datadir); /// Tell the TorrentControl obj to preallocate diskspace in the next update void setPreallocateDiskSpace(bool pa) {prealloc = pa;} /// Test if the torrent has existing files, only works the first time a torrent is loaded bool hasExistingFiles() const; - virtual const BitSet & downloadedChunksBitSet() const; - virtual const BitSet & availableChunksBitSet() const; - virtual const BitSet & excludedChunksBitSet() const; - virtual const BitSet & onlySeedChunksBitSet() const; - virtual bool changeTorDir(const QString & new_dir); - virtual bool changeOutputDir(const QString& new_dir,int flags); - virtual void rollback(); - virtual void setDisplayName(const QString & n); - virtual TrackersList* getTrackersList(); - virtual const TrackersList* getTrackersList() const; - virtual QString getDataDir() const {return outputdir;} - virtual QString getTorDir() const {return tordir;} - virtual void setMonitor(MonitorInterface* tmo); - virtual Uint32 getRunningTimeDL() const; - virtual Uint32 getRunningTimeUL() const; - virtual Uint32 getNumFiles() const; - virtual TorrentFileInterface & getTorrentFile(Uint32 index); - virtual const TorrentFileInterface & getTorrentFile(Uint32 index) const; - virtual bool moveTorrentFiles(const QMap & files); - virtual void recreateMissingFiles(); - virtual void dndMissingFiles(); - virtual TorrentFileStream::Ptr createTorrentFileStream(bt::Uint32 index,bool streaming_mode,QObject* parent); - virtual void addPeerSource(PeerSource* ps); - virtual void removePeerSource(PeerSource* ps); - virtual const QTextCodec* getTextCodec() const; - virtual void changeTextCodec(QTextCodec* tc); - virtual Uint32 getNumWebSeeds() const; - virtual const WebSeedInterface* getWebSeed(Uint32 i) const; - virtual WebSeedInterface* getWebSeed(Uint32 i); - virtual bool addWebSeed(const QUrl &url); - virtual bool removeWebSeed(const QUrl &url); - virtual bool readyForPreview() const; - virtual bool isMultimedia() const; - virtual void markExistingFilesAsDownloaded(); - virtual int getPriority() const { return istats.priority; } - virtual void setPriority(int p); - virtual bool overMaxRatio(); - virtual void setMaxShareRatio(float ratio); - virtual float getMaxShareRatio() const { return stats.max_share_ratio; } - virtual bool overMaxSeedTime(); - virtual void setMaxSeedTime(float hours); - virtual float getMaxSeedTime() const {return stats.max_seed_time;} - virtual void setAllowedToStart(bool on); - virtual void setQueued(bool queued); - virtual void setChunkSelector(ChunkSelectorInterface* csel); - virtual void networkUp(); - virtual bool announceAllowed(); - virtual Job* startDataCheck(bool auto_import, bt::Uint32 from, bt::Uint32 to); - virtual bool hasMissingFiles(QStringList & sl); - virtual bool isStorageMounted(QStringList& missing); - virtual Uint32 getNumDHTNodes() const; - virtual const DHTNode & getDHTNode(Uint32 i) const; - virtual void deleteDataFiles(); - virtual const bt::PeerID & getOwnPeerID() const; - virtual QString getComments() const; - virtual const JobQueue* getJobQueue() const {return job_queue;} - virtual bool isFeatureEnabled(TorrentFeature tf); - virtual void setFeatureEnabled(TorrentFeature tf,bool on); - virtual bool checkDiskSpace(bool emit_sig = true); - virtual void setTrafficLimits(Uint32 up,Uint32 down); - virtual void getTrafficLimits(Uint32 & up,Uint32 & down); - virtual void setAssuredSpeeds(Uint32 up,Uint32 down); - virtual void getAssuredSpeeds(Uint32 & up,Uint32 & down); - virtual const SHA1Hash & getInfoHash() const; - virtual void setUserModifiedFileName(const QString & n); - virtual int getETA(); - virtual void setMoveWhenCompletedDir(const QString &dir) {completed_dir = dir; saveStats();} - virtual QString getMoveWhenCompletedDir() const {return completed_dir;} - virtual void setSuperSeeding(bool on); + const BitSet & downloadedChunksBitSet() const override; + const BitSet & availableChunksBitSet() const override; + const BitSet & excludedChunksBitSet() const override; + const BitSet & onlySeedChunksBitSet() const override; + bool changeTorDir(const QString & new_dir) override; + bool changeOutputDir(const QString& new_dir,int flags) override; + void rollback() override; + void setDisplayName(const QString & n) override; + TrackersList* getTrackersList() override; + const TrackersList* getTrackersList() const override; + QString getDataDir() const override {return outputdir;} + QString getTorDir() const override {return tordir;} + void setMonitor(MonitorInterface* tmo) override; + Uint32 getRunningTimeDL() const override; + Uint32 getRunningTimeUL() const override; + Uint32 getNumFiles() const override; + TorrentFileInterface & getTorrentFile(Uint32 index) override; + const TorrentFileInterface & getTorrentFile(Uint32 index) const override; + bool moveTorrentFiles(const QMap & files) override; + void recreateMissingFiles() override; + void dndMissingFiles() override; + TorrentFileStream::Ptr createTorrentFileStream(bt::Uint32 index,bool streaming_mode,QObject* parent) override; + void addPeerSource(PeerSource* ps) override; + void removePeerSource(PeerSource* ps) override; + const QTextCodec* getTextCodec() const override; + void changeTextCodec(QTextCodec* tc) override; + Uint32 getNumWebSeeds() const override; + const WebSeedInterface* getWebSeed(Uint32 i) const override; + WebSeedInterface* getWebSeed(Uint32 i) override; + bool addWebSeed(const QUrl &url) override; + bool removeWebSeed(const QUrl &url) override; + bool readyForPreview() const override; + bool isMultimedia() const override; + void markExistingFilesAsDownloaded() override; + int getPriority() const override { return istats.priority; } + void setPriority(int p) override; + bool overMaxRatio() override; + void setMaxShareRatio(float ratio) override; + float getMaxShareRatio() const override { return stats.max_share_ratio; } + bool overMaxSeedTime() override; + void setMaxSeedTime(float hours) override; + float getMaxSeedTime() const override {return stats.max_seed_time;} + void setAllowedToStart(bool on) override; + void setQueued(bool queued) override; + void setChunkSelector(ChunkSelectorInterface* csel) override; + void networkUp() override; + bool announceAllowed() override; + Job* startDataCheck(bool auto_import, bt::Uint32 from, bt::Uint32 to) override; + bool hasMissingFiles(QStringList & sl) override; + bool isStorageMounted(QStringList& missing) override; + Uint32 getNumDHTNodes() const override; + const DHTNode & getDHTNode(Uint32 i) const override; + void deleteDataFiles() override; + const bt::PeerID & getOwnPeerID() const override; + QString getComments() const override; + const JobQueue* getJobQueue() const override {return job_queue;} + bool isFeatureEnabled(TorrentFeature tf) override; + void setFeatureEnabled(TorrentFeature tf,bool on) override; + bool checkDiskSpace(bool emit_sig = true) override; + void setTrafficLimits(Uint32 up,Uint32 down) override; + void getTrafficLimits(Uint32 & up,Uint32 & down) override; + void setAssuredSpeeds(Uint32 up,Uint32 down) override; + void getAssuredSpeeds(Uint32 & up,Uint32 & down) override; + const SHA1Hash & getInfoHash() const override; + void setUserModifiedFileName(const QString & n) override; + int getETA() override; + void setMoveWhenCompletedDir(const QString &dir) override {completed_dir = dir; saveStats();} + QString getMoveWhenCompletedDir() const override {return completed_dir;} + void setSuperSeeding(bool on) override; /// Create all the necessary files void createFiles(); /// Get the PeerManager const PeerManager * getPeerMgr() const; /** * Set a custom chunk selector factory (needs to be done for init is called) * Note: TorrentControl does not take ownership */ void setChunkSelectorFactory(ChunkSelectorFactoryInterface* csfi); /// Set a custom Cache factory void setCacheFactory(CacheFactory* cf); public Q_SLOTS: /** * Update the object, should be called periodically. */ - void update(); + void update() override; /** * Pause the torrent. */ - void pause(); + void pause() override; /** * Unpause the torrent. */ - void unpause(); + void unpause() override; /** * Start the download of the torrent. */ - void start(); + void start() override; /** * Stop the download, closes all connections. * @param wjob WaitJob to wait at exit for the completion of stopped requests */ - void stop(WaitJob* wjob = 0); + void stop(WaitJob* wjob = 0) override; /** * Update the tracker, this should normally handled internally. * We leave it public so that the user can do a manual announce. */ - void updateTracker(); + void updateTracker() override; /** * Scrape the tracker. * */ - void scrapeTracker(); + void scrapeTracker() override; /** * A scrape has finished on the tracker. * */ void trackerScrapeDone(); /** * Enable or disable data check upon completion * @param on */ static void setDataCheckWhenCompleted(bool on) {completed_datacheck = on;} /** * Set the minimum amount of diskspace in MB. When there is less then this free, torrents will be stopped. * @param m */ static void setMinimumDiskSpace(Uint32 m) {min_diskspace = m;} protected: /// Called when a data check is finished by DataCheckerJob void afterDataCheck(DataCheckerJob* job,const BitSet & result); void beforeDataCheck(); void preallocFinished(const QString & error,bool completed); void allJobsDone(); bool preallocate(); private Q_SLOTS: void onNewPeer(Peer* p); void onPeerRemoved(Peer* p); void doChoking(); void onIOError(const QString & msg); /// Update the stats of the torrent. void updateStats(); void corrupted(Uint32 chunk); void moveDataFilesFinished(KJob* j); void moveDataFilesWithMapFinished(KJob* j); void downloaded(Uint32 chunk); void moveToCompletedDir(); void emitFinished(); private: void updateTracker(const QString & ev,bool last_succes = true); - void updateStatus(); + void updateStatus() override; void saveStats(); void loadStats(); void loadOutputDir(); void loadEncoding(); void getSeederInfo(Uint32 & total,Uint32 & connected_to) const; void getLeecherInfo(Uint32 & total,Uint32 & connected_to) const; void continueStart(); - virtual void handleError(const QString & err); + void handleError(const QString & err) override; void initInternal(QueueManagerInterface* qman,const QString & tmpdir,const QString & ddir); void checkExisting(QueueManagerInterface* qman); void setupDirs(const QString & tmpdir,const QString & ddir); void setupStats(); void setupData(); void setUploadProps(Uint32 limit,Uint32 rate); void setDownloadProps(Uint32 limit,Uint32 rate); - virtual void downloadPriorityChanged(TorrentFile* tf, Priority newpriority, Priority oldpriority); + void downloadPriorityChanged(TorrentFile* tf, Priority newpriority, Priority oldpriority) override; void updateRunningTimes(); Q_SIGNALS: void dataCheckFinished(); private: JobQueue* job_queue; Torrent* tor; PeerSourceManager* psman; ChunkManager* cman; PeerManager* pman; Downloader* downloader; Uploader* uploader; Choker* choke; TimeEstimator* m_eta; MonitorInterface* tmon; CacheFactory* cache_factory; QString move_data_files_destination_path; Timer choker_update_timer; Timer stats_save_timer; Timer stalled_timer; Timer wanted_update_timer; QString tordir; QString old_tordir; QString outputdir; QString error_msg; QString completed_dir; bool prealloc; TimeStamp last_diskspace_check; bool loading_stats; struct InternalStats { QDateTime time_started_dl; QDateTime time_started_ul; Uint32 running_time_dl; Uint32 running_time_ul; Uint64 prev_bytes_dl; Uint64 prev_bytes_ul; Uint64 session_bytes_uploaded; bool io_error; bool custom_output_name; Uint16 port; int priority; bool dht_on; bool diskspace_warning_emitted; }; Uint32 upload_gid; // group ID for upload Uint32 upload_limit; Uint32 download_gid; // group ID for download Uint32 download_limit; Uint32 assured_download_speed; Uint32 assured_upload_speed; InternalStats istats; StatsFile* stats_file; TorrentFileStream::WPtr stream; static bool completed_datacheck; static Uint32 min_diskspace; friend class DataCheckerJob; friend class PreallocationJob; friend class JobQueue; }; } #endif diff --git a/src/torrent/torrentcreator.h b/src/torrent/torrentcreator.h index b25096f..8a7feb0 100644 --- a/src/torrent/torrentcreator.h +++ b/src/torrent/torrentcreator.h @@ -1,119 +1,119 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTORRENTCREATOR_H #define BTTORRENTCREATOR_H #include #include #include #include #include "torrent.h" namespace bt { class BEncoder; class TorrentControl; /** * @author Joris Guisson * @brief Class to generate torrent files * * This class generates torrent files. * It also allows to create a TorrentControl object, so * that we immediately can start to share the torrent. */ class KTORRENT_EXPORT TorrentCreator : public QThread { Q_OBJECT // input values QString target; QStringList trackers; QList webseeds; int chunk_size; QString name,comments; // calculated values Uint32 num_chunks; Uint64 last_size; QList files; QList hashes; // Uint32 cur_chunk; bool priv; Uint64 tot_size; bool decentralized; bool stopped; public: /** * Constructor. * @param target The file or directory to make a torrent of * @param trackers A list of tracker urls * @param webseeds A list of webseed urls * @param chunk_size The size of each chunk * @param name The name suggestion * @param comments The comments field of the torrent * @param priv Private torrent or not */ TorrentCreator(const QString & target,const QStringList & trackers,const QList & webseeds, Uint32 chunk_size,const QString & name, const QString & comments,bool priv,bool decentralized); - virtual ~TorrentCreator(); + ~TorrentCreator() override; /// Get the number of chunks Uint32 getNumChunks() const {return num_chunks;} Uint32 getCurrentChunk() const {return cur_chunk;} /** * Save the torrent file. * @param url Filename * @throw Error if something goes wrong */ void saveTorrent(const QString & url); /** * Make a TorrentControl object for this torrent. * This will also create the files : * data_dir/index * data_dir/torrent * data_dir/cache (symlink to target) * @param data_dir The data directory * @throw Error if something goes wrong * @return The newly created object */ TorrentControl* makeTC(const QString & data_dir); /// Stop the thread void stop() {stopped = true;} private: void saveInfo(BEncoder & enc); void saveFile(BEncoder & enc,const TorrentFile & file); void savePieces(BEncoder & enc); void buildFileList(const QString & dir); bool calcHashSingle(); bool calcHashMulti(); - virtual void run(); + void run() override; bool calculateHash(); }; } #endif diff --git a/src/torrent/torrentfile.h b/src/torrent/torrentfile.h index 1d79b91..edbf064 100644 --- a/src/torrent/torrentfile.h +++ b/src/torrent/torrentfile.h @@ -1,139 +1,139 @@ /*************************************************************************** * Copyright (C) 2005 by * * Joris Guisson * * Ivan Vasic * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTORRENTFILE_H #define BTTORRENTFILE_H #include #include #include namespace bt { class ChunkManager; class Torrent; /** * @author Joris Guisson * * File in a multi file torrent. Keeps track of the path of the file, * it's size, offset into the cache and between which chunks it lies. */ class KTORRENT_EXPORT TorrentFile : public TorrentFileInterface { Q_OBJECT Torrent* tor; Uint64 cache_offset; Priority priority; Priority old_priority; bool missing; public: /** * Default constructor. Creates a null TorrentFile. */ TorrentFile(Torrent* tor = 0); /** * Constructor. * @param index Index number of the file * @param path Path of the file * @param off Offset into the torrent * (i.e. how many bytes were all the previous files in the torrent combined) * @param size Size of the file * @param chunk_size Size of each chunk */ TorrentFile(Torrent* tor,Uint32 index,const QString & path,Uint64 off,Uint64 size,Uint64 chunk_size); /** * Copy constructor. * @param tf The TorrentFile to copy */ TorrentFile(const TorrentFile & tf); - virtual ~TorrentFile(); + ~TorrentFile() override; /// Get the offset into the torrent Uint64 getCacheOffset() const {return cache_offset;} /// Get the offset at which the file starts in the first chunk Uint64 getFirstChunkOffset() const {return first_chunk_off;} /// Get how many bytes the files takes up of the last chunk Uint64 getLastChunkSize() const {return last_chunk_size;} /// Check if this file doesn't have to be downloaded - bool doNotDownload() const {return (priority == EXCLUDED);} + bool doNotDownload() const override {return (priority == EXCLUDED);} /// Set whether we have to not download this file - void setDoNotDownload(bool dnd); + void setDoNotDownload(bool dnd) override; /// Checks if this file is multimedial - bool isMultimedia() const; + bool isMultimedia() const override; /// Gets the priority of the file - Priority getPriority() const {return priority;} + Priority getPriority() const override {return priority;} /// Sets the priority of the file - void setPriority(Priority newpriority = NORMAL_PRIORITY); + void setPriority(Priority newpriority = NORMAL_PRIORITY) override; /// Get the previous priority value Priority getOldPriority() const {return old_priority;} /// emits signal. - void emitDownloadStatusChanged(); + void emitDownloadStatusChanged() override; - void setEmitDownloadStatusChanged(bool show) { emit_status_changed = show; } + void setEmitDownloadStatusChanged(bool show) override { emit_status_changed = show; } /** * Assignment operator * @param tf The file to copy * @return *this */ TorrentFile & operator = (const TorrentFile & tf); /// See if the file is missing bool isMissing() const {return missing;} /// Set the file to be missing or not void setMissing(bool m) {missing = m;} /** * Calculate the offset of a chunk in the file * @param cindex Index of chunk * @param chunk_size Size of each chunk */ Uint64 fileOffset(Uint32 cindex,Uint64 chunk_size) const; static TorrentFile null; /** * Update the number of downloaded chunks for this file. * @param cman The ChunkManager */ void updateNumDownloadedChunks(ChunkManager & cman); }; } #endif diff --git a/src/torrent/torrentfilestream.h b/src/torrent/torrentfilestream.h index ac68b0a..f35417b 100644 --- a/src/torrent/torrentfilestream.h +++ b/src/torrent/torrentfilestream.h @@ -1,105 +1,105 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_TORRENTFILESTREAM_H #define BT_TORRENTFILESTREAM_H #include #include #include #include #include namespace bt { class ChunkManager; class TorrentControl; class TorrentInterface; class BitSet; /** QIODevice which streams a file of a torrent or the whole torrent (for single file torrents) This object should not be manually constructed. */ class KTORRENT_EXPORT TorrentFileStream : public QIODevice { Q_OBJECT public: TorrentFileStream(TorrentControl* tc,ChunkManager* cman,bool streaming_mode,QObject* parent); TorrentFileStream(TorrentControl* tc,Uint32 file_index,ChunkManager* cman,bool streaming_mode,QObject* parent); - virtual ~TorrentFileStream(); + ~TorrentFileStream() override; /// Open the device (only readonly access will be allowed) - virtual bool open(QIODevice::OpenMode mode); + bool open(QIODevice::OpenMode mode) override; /// Close the device - virtual void close(); + void close() override; /// Get the current stream position - virtual qint64 pos() const; + qint64 pos() const override; /// Get the total size - virtual qint64 size() const; + qint64 size() const override; /// Seek, will fail if attempting to seek to a point which is not downloaded yet - virtual bool seek(qint64 pos); + bool seek(qint64 pos) override; /// Are we at the end of the file - virtual bool atEnd() const; + bool atEnd() const override; /// Reset the stream - virtual bool reset(); + bool reset() override; /// How many bytes are there available - virtual qint64 bytesAvailable() const; + qint64 bytesAvailable() const override; /// The stream is not sequential - virtual bool isSequential() const {return false;} + bool isSequential() const override {return false;} /// Get the path of the file QString path() const; /// Get a BitSet of all the chunks of this TorrentFileStream const BitSet & chunksBitSet() const; /// Get the current chunk relative to the first chunk of the file Uint32 currentChunk() const; typedef QSharedPointer Ptr; typedef QWeakPointer WPtr; protected: - virtual qint64 writeData(const char* data, qint64 len); - virtual qint64 readData(char* data, qint64 maxlen); + qint64 writeData(const char* data, qint64 len) override; + qint64 readData(char* data, qint64 maxlen) override; void emitReadChannelFinished(); private Q_SLOTS: void chunkDownloaded(bt::TorrentInterface* tc, bt::Uint32 chunk); private: class Private; Private* d; }; } #endif // BT_TORRENTFILESTREAM_H diff --git a/src/torrent/uploader.h b/src/torrent/uploader.h index 48baae6..cecd249 100644 --- a/src/torrent/uploader.h +++ b/src/torrent/uploader.h @@ -1,75 +1,75 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTUPLOADER_H #define BTUPLOADER_H #include #include "globals.h" namespace bt { class Peer; class ChunkManager; /** * @author Joris Guisson * * Class which manages the uploading of data. It has a PeerUploader for * each Peer. */ class Uploader : public QObject, public PeerManager::PeerVisitor { Q_OBJECT public: /** * Constructor, sets the ChunkManager. * @param cman The ChunkManager */ Uploader(ChunkManager & cman,PeerManager & pman); - virtual ~Uploader(); + ~Uploader() override; /// Get the number of bytes uploaded. Uint64 bytesUploaded() const {return uploaded;} /// Get the upload rate of all Peers combined. Uint32 uploadRate() const; /// Set the number of bytes which have been uploaded. void setBytesUploaded(Uint64 b) {uploaded = b;} public Q_SLOTS: /** * Update every PeerUploader. */ void update(); private: - virtual void visit(const bt::Peer::Ptr p); + void visit(const bt::Peer::Ptr p) override; private: ChunkManager & cman; PeerManager & pman; Uint64 uploaded; }; } #endif diff --git a/src/tracker/httptracker.h b/src/tracker/httptracker.h index 8290825..923270e 100644 --- a/src/tracker/httptracker.h +++ b/src/tracker/httptracker.h @@ -1,98 +1,98 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTHTTPTRACKER_H #define BTHTTPTRACKER_H #include #include #include "tracker.h" class KJob; namespace KIO { class MetaData; } namespace bt { /** * @author Joris Guisson * @brief Communicates with the tracker * * This class uses the HTTP protocol to communicate with the tracker. */ class KTORRENT_EXPORT HTTPTracker : public Tracker { Q_OBJECT public: HTTPTracker(const QUrl &url,TrackerDataSource* tds,const PeerID & id,int tier); - virtual ~HTTPTracker(); + ~HTTPTracker() override; - virtual void start(); - virtual void stop(WaitJob* wjob = 0); - virtual void completed(); - virtual Uint32 failureCount() const {return failures;} - virtual void scrape(); + void start() override; + void stop(WaitJob* wjob = 0) override; + void completed() override; + Uint32 failureCount() const override {return failures;} + void scrape() override; static void setProxy(const QString & proxy,const bt::Uint16 proxy_port); static void setProxyEnabled(bool on); static void setUseQHttp(bool on); private Q_SLOTS: void onKIOAnnounceResult(KJob* j); #ifdef HAVE_HTTPANNOUNEJOB void onQHttpAnnounceResult(KJob* j); #endif void onScrapeResult(KJob* j); void emitInvalidURLFailure(); void onTimeout(); - virtual void manualUpdate(); + void manualUpdate() override; private: void doRequest(WaitJob* wjob = 0); bool updateData(const QByteArray & data); void setupMetaData(KIO::MetaData & md); void doAnnounceQueue(); void doAnnounce(const QUrl &u); void onAnnounceResult(const QUrl &url,const QByteArray & data,KJob* j); private: KJob* active_job; QList announce_queue; QString event; QTimer timer; QString error; Uint32 failures; bool supports_partial_seed_extension; static bool proxy_on; static QString proxy; static Uint16 proxy_port; static bool use_qhttp; }; } #endif diff --git a/src/tracker/kioannouncejob.h b/src/tracker/kioannouncejob.h index eec1098..46f8e4f 100644 --- a/src/tracker/kioannouncejob.h +++ b/src/tracker/kioannouncejob.h @@ -1,59 +1,59 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_KIOANNOUNCEJOB_H #define BT_KIOANNOUNCEJOB_H #include #include #include namespace bt { class KTORRENT_EXPORT KIOAnnounceJob : public KIO::Job { Q_OBJECT public: KIOAnnounceJob(const QUrl & url,const KIO::MetaData & md); - virtual ~KIOAnnounceJob(); + ~KIOAnnounceJob() override; /// Get the announce url QUrl announceUrl() const {return url;} /// Get the reply data const QByteArray & replyData() const {return reply_data;} - virtual bool doKill(); + bool doKill() override; private Q_SLOTS: void data(KIO::Job* j,const QByteArray & data); void finished(KJob* j); private: QUrl url; QByteArray reply_data; KIO::TransferJob* get_job; }; } #endif // BT_KIOANNOUNCEJOB_H diff --git a/src/tracker/tracker.h b/src/tracker/tracker.h index a0dc604..f5d8ea3 100644 --- a/src/tracker/tracker.h +++ b/src/tracker/tracker.h @@ -1,151 +1,151 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTTRACKER_H #define BTTRACKER_H #include #include #include #include #include #include #include class QUrl; namespace bt { /** Interface used by the Tracker to obtain the data it needs to know when announcing. */ class KTORRENT_EXPORT TrackerDataSource { public: virtual ~TrackerDataSource() {} virtual Uint64 bytesDownloaded() const = 0; virtual Uint64 bytesUploaded() const = 0; virtual Uint64 bytesLeft() const = 0; virtual const SHA1Hash & infoHash() const = 0; virtual bool isPartialSeed() const = 0; }; /** * Base class for all tracker classes. */ class KTORRENT_EXPORT Tracker : public PeerSource,public TrackerInterface { Q_OBJECT public: Tracker(const QUrl &url,TrackerDataSource* tds,const PeerID & id,int tier); - virtual ~Tracker(); + ~Tracker() override; /** * Set the custom IP * @param str */ static void setCustomIP(const QString & str); /// get the tracker url QUrl trackerURL() const {return url;} /** * Delete the tracker in ms milliseconds, or when the stopDone signal is emitted. * @param ms Number of ms to wait */ void timedDelete(int ms); /** * Get the number of failed attempts to reach a tracker. * @return The number of failed attempts */ virtual Uint32 failureCount() const = 0; /** * Do a tracker scrape to get more accurate stats about a torrent. * Does nothing if the tracker does not support this. */ virtual void scrape() = 0; /// Get the trackers tier int getTier() const {return tier;} /// Get the custom ip to use, null if none is set static QString getCustomIP(); /// Handle a failure void handleFailure(); protected: /// Reset the tracker stats void resetTrackerStats(); /// Calculates the bytes downloaded to send with the request Uint64 bytesDownloaded() const; /// Calculates the bytes uploaded to send with the request Uint64 bytesUploaded() const; /// Emit the failure signal, and set the error void failed(const QString & err); public Q_SLOTS: - virtual void manualUpdate() = 0; + void manualUpdate() override = 0; Q_SIGNALS: /** * Emitted when an error happens. * @param failure_reason The reason why we couldn't reach the tracker */ void requestFailed(const QString & failure_reason); /** * Emitted when a stop is done. */ void stopDone(); /** * Emitted when a request to the tracker succeeded */ void requestOK(); /** * A request to the tracker has been started. */ void requestPending(); /** * Emitted when a scrape has finished * */ void scrapeDone(); protected: int tier; PeerID peer_id; TrackerDataSource* tds; Uint32 key; QTimer reannounce_timer; Uint64 bytes_downloaded_at_start; Uint64 bytes_uploaded_at_start; }; } #endif diff --git a/src/tracker/trackermanager.h b/src/tracker/trackermanager.h index b9c6530..be33b64 100644 --- a/src/tracker/trackermanager.h +++ b/src/tracker/trackermanager.h @@ -1,138 +1,138 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_TRACKERMANAGER_H #define BT_TRACKERMANAGER_H #include #include #include #include #include #include #include namespace bt { class TorrentControl; class WaitJob; class PeerManager; /** * Manages all trackers */ class KTORRENT_EXPORT TrackerManager : public QObject,public bt::TrackersList,public TrackerDataSource { Q_OBJECT public: TrackerManager(TorrentControl* tor,PeerManager* pman); - virtual ~TrackerManager(); + ~TrackerManager() override; - virtual TrackerInterface* getCurrentTracker() const; - virtual void setCurrentTracker(TrackerInterface* t); - virtual void setCurrentTracker(const QUrl &url); - virtual QList getTrackers(); - virtual TrackerInterface* addTracker(const QUrl &url, bool custom = true,int tier = 1); - virtual bool removeTracker(TrackerInterface* t); - virtual bool removeTracker(const QUrl &url); - virtual bool canRemoveTracker(TrackerInterface* t); - virtual void restoreDefault(); - virtual void setTrackerEnabled(const QUrl &url,bool on); - virtual bool noTrackersReachable() const; + TrackerInterface* getCurrentTracker() const override; + void setCurrentTracker(TrackerInterface* t) override; + void setCurrentTracker(const QUrl &url) override; + QList getTrackers() override; + TrackerInterface* addTracker(const QUrl &url, bool custom = true,int tier = 1) override; + bool removeTracker(TrackerInterface* t) override; + bool removeTracker(const QUrl &url) override; + bool canRemoveTracker(TrackerInterface* t) override; + void restoreDefault() override; + void setTrackerEnabled(const QUrl &url,bool on) override; + bool noTrackersReachable() const override; /// Get the number of seeders Uint32 getNumSeeders() const; /// Get the number of leechers Uint32 getNumLeechers() const; /** * Start gathering peers */ virtual void start(); /** * Stop gathering peers * @param wjob WaitJob to wait at exit for the completion of stopped events to the trackers */ virtual void stop(WaitJob* wjob = 0); /** * Notify peersources and trackrs that the download is complete. */ virtual void completed(); /** * Do a manual update on all peer sources and trackers. */ virtual void manualUpdate(); /** * Do a scrape on the current tracker * */ virtual void scrape(); protected: void saveCustomURLs(); void loadCustomURLs(); void saveTrackerStatus(); void loadTrackerStatus(); void addTracker(Tracker* trk); void switchTracker(Tracker* trk); Tracker* selectTracker(); - virtual Uint64 bytesDownloaded() const; - virtual Uint64 bytesUploaded() const; - virtual Uint64 bytesLeft() const; - virtual const SHA1Hash & infoHash() const; - virtual bool isPartialSeed() const; + Uint64 bytesDownloaded() const override; + Uint64 bytesUploaded() const override; + Uint64 bytesLeft() const override; + const SHA1Hash & infoHash() const override; + bool isPartialSeed() const override; private Q_SLOTS: /** * The an error happened contacting the tracker. * @param err The error */ void onTrackerError(const QString & err); /** * Tracker update was OK. * @param */ void onTrackerOK(); /** * Update the current tracker manually */ void updateCurrentManually(); protected: TorrentControl* tor; PtrMap trackers; bool no_save_custom_trackers; PeerManager* pman; Tracker* curr; QList custom_trackers; bool started; }; } #endif // BT_TRACKERMANAGER_H diff --git a/src/tracker/udptracker.h b/src/tracker/udptracker.h index 6c67ac1..9b5ee6e 100644 --- a/src/tracker/udptracker.h +++ b/src/tracker/udptracker.h @@ -1,109 +1,109 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTUDPTRACKER_H #define BTUDPTRACKER_H #include #include #include #include #include "tracker.h" namespace net { class AddressResolver; } namespace bt { class UDPTrackerSocket; /** * @author Joris Guisson * @brief Communicates with an UDP tracker * * This class is able to communicate with an UDP tracker. * This is an implementation of the protocol described in * http://xbtt.sourceforge.net/udp_tracker_protocol.html */ class UDPTracker : public Tracker { Q_OBJECT public: UDPTracker(const QUrl &url,TrackerDataSource* tds,const PeerID & id,int tier); - virtual ~UDPTracker(); + ~UDPTracker() override; - virtual void start(); - virtual void stop(WaitJob* wjob = 0); - virtual void completed(); - virtual Uint32 failureCount() const {return failures;} - virtual void scrape(); + void start() override; + void stop(WaitJob* wjob = 0) override; + void completed() override; + Uint32 failureCount() const override {return failures;} + void scrape() override; private Q_SLOTS: void onConnTimeout(); void connectReceived(Int32 tid,Int64 connection_id); void announceReceived(Int32 tid,const Uint8* buf,Uint32 size); void scrapeReceived(Int32 tid,const Uint8* buf,Uint32 size); void onError(Int32 tid,const QString & error_string); void onResolverResults(net::AddressResolver* ar); - virtual void manualUpdate(); + void manualUpdate() override; private: void sendConnect(); void sendAnnounce(); void sendScrape(); bool doRequest(); enum Event { NONE = 0, COMPLETED = 1, STARTED = 2, STOPPED = 3 }; enum Todo { NOTHING = 0, SCRAPE_REQUEST = 1, ANNOUNCE_REQUEST = 2 }; private: net::Address address; Int64 connection_id; Int32 transaction_id; Int32 scrape_transaction_id; Uint32 data_read; int failures; bool resolved; Uint32 todo; Event event; QTimer conn_timer; static UDPTrackerSocket* socket; static Uint32 num_instances; }; } #endif diff --git a/src/tracker/udptrackersocket.cpp b/src/tracker/udptrackersocket.cpp index 17b63e4..ab32968 100644 --- a/src/tracker/udptrackersocket.cpp +++ b/src/tracker/udptrackersocket.cpp @@ -1,284 +1,284 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "udptrackersocket.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ERROR #undef ERROR #endif namespace bt { Uint16 UDPTrackerSocket::port = 4444; class UDPTrackerSocket::Private : public net::ServerSocket::DataHandler { public: Private(UDPTrackerSocket* p) : p(p) { } - ~Private() + ~Private() override { } void listen(const QString & ip,Uint16 port) { net::ServerSocket::Ptr sock(new net::ServerSocket(this)); if (sock->bind(ip,port)) sockets.append(sock); } bool send(const Uint8* buf,int size,const net::Address & addr) { foreach (net::ServerSocket::Ptr sock,sockets) if (sock->sendTo(buf,size,addr) == size) return true; return false; } - virtual void dataReceived(bt::Buffer::Ptr buffer, const net::Address& addr) + void dataReceived(bt::Buffer::Ptr buffer, const net::Address& addr) override { Q_UNUSED(addr); if (buffer->size() < 4) return; Uint32 type = ReadUint32(buffer->get(),0); switch (type) { case CONNECT: p->handleConnect(buffer); break; case ANNOUNCE: p->handleAnnounce(buffer); break; case ERROR: p->handleError(buffer); break; case SCRAPE: p->handleScrape(buffer); break; } } - virtual void readyToWrite(net::ServerSocket* sock) + void readyToWrite(net::ServerSocket* sock) override { Q_UNUSED(sock); } QList sockets; QMap transactions; UDPTrackerSocket* p; }; UDPTrackerSocket::UDPTrackerSocket() : d(new Private(this)) { if (port == 0) port = 4444; QStringList ips = NetworkInterfaceIPAddresses(NetworkInterface()); foreach (const QString & ip,ips) d->listen(ip,port); if (d->sockets.count() == 0) { // Try all addresses if the previous listen calls all failed d->listen(QHostAddress(QHostAddress::AnyIPv6).toString(),port); d->listen(QHostAddress(QHostAddress::Any).toString(),port); } if (d->sockets.count() == 0) { Out(SYS_TRK|LOG_IMPORTANT) << QString("Cannot bind to udp port %1").arg(port) << endl; } else { Globals::instance().getPortList().addNewPort(port,net::UDP,true); } } UDPTrackerSocket::~UDPTrackerSocket() { Globals::instance().getPortList().removePort(port,net::UDP); delete d; } void UDPTrackerSocket::sendConnect(Int32 tid,const net::Address & addr) { Int64 cid = 0x41727101980LL; Uint8 buf[16]; WriteInt64(buf,0,cid); WriteInt32(buf,8,CONNECT); WriteInt32(buf,12,tid); d->send(buf,16,addr); d->transactions.insert(tid,CONNECT); } void UDPTrackerSocket::sendAnnounce(Int32 tid,const Uint8* data,const net::Address & addr) { d->send(data,98,addr); d->transactions.insert(tid,ANNOUNCE); } void UDPTrackerSocket::sendScrape(Int32 tid, const bt::Uint8* data, const net::Address& addr) { d->send(data,36,addr); d->transactions.insert(tid,SCRAPE); } void UDPTrackerSocket::cancelTransaction(Int32 tid) { d->transactions.remove(tid); } void UDPTrackerSocket::handleConnect(bt::Buffer::Ptr buf) { if (buf->size() < 12) return; // Read the transaction_id and check it Int32 tid = ReadInt32(buf->get(),4); QMap::iterator i = d->transactions.find(tid); // if we can't find the transaction, just return if (i == d->transactions.end()) return; // check whether the transaction is a CONNECT if (i.value() != CONNECT) { d->transactions.erase(i); error(tid,QString()); return; } // everything ok, emit signal d->transactions.erase(i); connectReceived(tid,ReadInt64(buf->get(),8)); } void UDPTrackerSocket::handleAnnounce(bt::Buffer::Ptr buf) { if (buf->size() < 4) return; // Read the transaction_id and check it Int32 tid = ReadInt32(buf->get(),4); QMap::iterator i = d->transactions.find(tid); // if we can't find the transaction, just return if (i == d->transactions.end() || buf->size() < 20) return; // check whether the transaction is a ANNOUNCE if (i.value() != ANNOUNCE) { d->transactions.erase(i); error(tid,QString()); return; } // everything ok, emit signal d->transactions.erase(i); announceReceived(tid,buf->get(), buf->size()); } void UDPTrackerSocket::handleError(bt::Buffer::Ptr buf) { if (buf->size() < 4) return; // Read the transaction_id and check it Int32 tid = ReadInt32(buf->get(),4); QMap::iterator it = d->transactions.find(tid); // if we can't find the transaction, just return if (it == d->transactions.end()) return; // extract error message d->transactions.erase(it); QString msg; for (Uint32 i = 8;i < buf->size();i++) msg += (char)buf->get()[i]; // emit signal error(tid,msg); } void UDPTrackerSocket::handleScrape(bt::Buffer::Ptr buf) { if (buf->size() < 4) return; // Read the transaction_id and check it Int32 tid = ReadInt32((Uint8*)buf.data(),4); QMap::iterator i = d->transactions.find(tid); // if we can't find the transaction, just return if (i == d->transactions.end()) return; // check whether the transaction is a SCRAPE if (i.value() != SCRAPE) { d->transactions.erase(i); error(tid,QString()); return; } // everything ok, emit signal d->transactions.erase(i); scrapeReceived(tid,buf->get(),buf->size()); } Int32 UDPTrackerSocket::newTransactionID() { Int32 transaction_id = rand() * time(0); while (d->transactions.contains(transaction_id)) transaction_id++; return transaction_id; } void UDPTrackerSocket::setPort(Uint16 p) { port = p; } Uint16 UDPTrackerSocket::getPort() { return port; } } diff --git a/src/tracker/udptrackersocket.h b/src/tracker/udptrackersocket.h index f547bef..bdd2cef 100644 --- a/src/tracker/udptrackersocket.h +++ b/src/tracker/udptrackersocket.h @@ -1,157 +1,157 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTUDPTRACKERSOCKET_H #define BTUDPTRACKERSOCKET_H #include #include #include #include #include #ifdef ERROR #undef ERROR #endif namespace net { class Address; } namespace bt { /** * @author Joris Guisson * * Class which handles communication with one or more UDP trackers. */ class KTORRENT_EXPORT UDPTrackerSocket : public QObject { Q_OBJECT public: UDPTrackerSocket(); - virtual ~UDPTrackerSocket(); + ~UDPTrackerSocket() override; enum Action { CONNECT = 0, ANNOUNCE = 1, SCRAPE = 2, ERROR = 3 }; /** * Send a connect message. As a response to this, the connectReceived * signal will be emitted, classes recieving this signal should check if * the transaction_id is the same. * @param tid The transaction_id * @param addr The address to send to */ void sendConnect(Int32 tid,const net::Address & addr); /** * Send an announce message. As a response to this, the announceReceived * signal will be emitted, classes recieving this signal should check if * the transaction_id is the same. * @param tid The transaction_id * @param data The data to send (connect input structure, in UDP Tracker specifaction) * @param addr The address to send to */ void sendAnnounce(Int32 tid,const Uint8* data,const net::Address & addr); /** * Send a scrape message. As a response to this, the scrapeReceived * signal will be emitted, classes recieving this signal should check if * the transaction_id is the same. * @param tid The transaction_id * @param data The data to send (connect input structure, in UDP Tracker specifaction) * @param addr The address to send to */ void sendScrape(Int32 tid,const Uint8* data,const net::Address & addr); /** * If a transaction times out, this should be used to cancel it. * @param tid */ void cancelTransaction(Int32 tid); /** * Compute a free transaction_id. * @return A free transaction_id */ Int32 newTransactionID(); /** * Set the port ot use. * @param p The port */ static void setPort(Uint16 p); /// Get the port in use. static Uint16 getPort(); Q_SIGNALS: /** * Emitted when a connect message is received. * @param tid The transaction_id * @param connection_id The connection_id returned */ void connectReceived(Int32 tid,Int64 connection_id); /** * Emitted when an announce message is received. * @param tid The transaction_id * @param buf The data * @param size The data size */ void announceReceived(Int32 tid,const Uint8* buf,Uint32 size); /** * Emitted when a scrape message is received. * @param tid The transaction_id * @param buf The data * @param size The data size */ void scrapeReceived(Int32 tid,const Uint8* buf,Uint32 size); /** * Signal emitted, when an error occurs during a transaction. * @param tid The transaction_id * @param error_string Potential error string */ void error(Int32 tid,const QString & error_string); private: void handleConnect(bt::Buffer::Ptr buf); void handleAnnounce(bt::Buffer::Ptr buf); void handleError(bt::Buffer::Ptr buf); void handleScrape(bt::Buffer::Ptr buf); private: class Private; Private* d; static Uint16 port; }; } #endif diff --git a/src/upnp/upnpdescriptionparser.cpp b/src/upnp/upnpdescriptionparser.cpp index f9b6e40..c0b0ca8 100644 --- a/src/upnp/upnpdescriptionparser.cpp +++ b/src/upnp/upnpdescriptionparser.cpp @@ -1,238 +1,238 @@ /*************************************************************************** * Copyright (C) 2005-2007 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "upnpdescriptionparser.h" #include #include #include #include #include "upnprouter.h" using namespace bt; namespace bt { class XMLContentHandler : public QXmlDefaultHandler { enum Status { TOPLEVEL,ROOT,DEVICE,SERVICE,FIELD,OTHER }; QString tmp; UPnPRouter* router; UPnPService curr_service; QStack status_stack; public: XMLContentHandler(UPnPRouter* router); - virtual ~XMLContentHandler(); + ~XMLContentHandler() override; - bool startDocument(); - bool endDocument(); + bool startDocument() override; + bool endDocument() override; bool startElement(const QString &, const QString & localName, const QString &, - const QXmlAttributes & atts); - bool endElement(const QString & , const QString & localName, const QString & ); - bool characters(const QString & ch); + const QXmlAttributes & atts) override; + bool endElement(const QString & , const QString & localName, const QString & ) override; + bool characters(const QString & ch) override; bool interestingDeviceField(const QString & name); bool interestingServiceField(const QString & name); }; UPnPDescriptionParser::UPnPDescriptionParser() {} UPnPDescriptionParser::~UPnPDescriptionParser() {} bool UPnPDescriptionParser::parse(const QString & file,UPnPRouter* router) { bool ret = true; QFile fptr(file); if (!fptr.open(QIODevice::ReadOnly)) return false; QXmlInputSource input(&fptr); XMLContentHandler chandler(router); QXmlSimpleReader reader; reader.setContentHandler(&chandler); ret = reader.parse(&input,false); if (!ret) { Out(SYS_PNP|LOG_IMPORTANT) << "Error parsing XML" << endl; return false; } return true; } bool UPnPDescriptionParser::parse(const QByteArray & data,UPnPRouter* router) { bool ret = true; QXmlInputSource input; input.setData(data); XMLContentHandler chandler(router); QXmlSimpleReader reader; reader.setContentHandler(&chandler); ret = reader.parse(&input,false); if (!ret) { Out(SYS_PNP|LOG_IMPORTANT) << "Error parsing XML" << endl; return false; } return true; } ///////////////////////////////////////////////////////////////////////////////// XMLContentHandler::XMLContentHandler(UPnPRouter* router) : router(router) {} XMLContentHandler::~XMLContentHandler() {} bool XMLContentHandler::startDocument() { status_stack.push(TOPLEVEL); return true; } bool XMLContentHandler::endDocument() { status_stack.pop(); return true; } bool XMLContentHandler::interestingDeviceField(const QString & name) { return name == "friendlyName" || name == "manufacturer" || name == "modelDescription" || name == "modelName" || name == "modelNumber"; } bool XMLContentHandler::interestingServiceField(const QString & name) { return name == "serviceType" || name == "serviceId" || name == "SCPDURL" || name == "controlURL" || name == "eventSubURL"; } bool XMLContentHandler::startElement(const QString &, const QString & localName, const QString &, const QXmlAttributes & ) { tmp = ""; switch (status_stack.top()) { case TOPLEVEL: // from toplevel we can only go to root if (localName == "root") status_stack.push(ROOT); else return false; break; case ROOT: // from the root we can go to device or specVersion // we are not interested in the specVersion if (localName == "device") status_stack.push(DEVICE); else status_stack.push(OTHER); break; case DEVICE: // see if it is a field we are interested in if (interestingDeviceField(localName)) status_stack.push(FIELD); else status_stack.push(OTHER); break; case SERVICE: if (interestingServiceField(localName)) status_stack.push(FIELD); else status_stack.push(OTHER); break; case OTHER: if (localName == "service") status_stack.push(SERVICE); else if (localName == "device") status_stack.push(DEVICE); else status_stack.push(OTHER); break; case FIELD: break; } return true; } bool XMLContentHandler::endElement(const QString & , const QString & localName, const QString & ) { switch (status_stack.top()) { case FIELD: // we have a field so set it status_stack.pop(); if (status_stack.top() == DEVICE) { // if we are in a device router->getDescription().setProperty(localName,tmp); } else if (status_stack.top() == SERVICE) { // set a property of a service curr_service.setProperty(localName,tmp); } break; case SERVICE: // add the service router->addService(curr_service); curr_service.clear(); // pop the stack status_stack.pop(); break; default: status_stack.pop(); break; } // reset tmp tmp = ""; return true; } bool XMLContentHandler::characters(const QString & ch) { if (ch.length() > 0) { tmp += ch; } return true; } } diff --git a/src/upnp/upnpmcastsocket.h b/src/upnp/upnpmcastsocket.h index 5f01b9a..4e6f563 100644 --- a/src/upnp/upnpmcastsocket.h +++ b/src/upnp/upnpmcastsocket.h @@ -1,90 +1,90 @@ /*************************************************************************** * Copyright (C) 2005-2007 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KTUPNPMCASTSOCKET_H #define KTUPNPMCASTSOCKET_H #include #include #include #include #include #include "upnprouter.h" using bt::Uint32; namespace bt { class UPnPRouter; /** * @author Joris Guisson * * Socket used to discover UPnP devices. This class will keep track * of all discovered devices. */ class KTORRENT_EXPORT UPnPMCastSocket : public QUdpSocket { Q_OBJECT public: UPnPMCastSocket(bool verbose = false); - virtual ~UPnPMCastSocket(); + ~UPnPMCastSocket() override; /// Get the number of routers discovered Uint32 getNumDevicesDiscovered() const; /// Find a router using it's server name UPnPRouter* findDevice(const QString & name); /// Save all routers to a file (for convenience at startup) void saveRouters(const QString & file); /// Load all routers from a file void loadRouters(const QString & file); /// Set verbose mode void setVerbose(bool v); public Q_SLOTS: /** * Try to discover a UPnP device on the network. * A signal will be emitted when a device is found. */ void discover(); private Q_SLOTS: void onReadyRead(); void error(QAbstractSocket::SocketError err); void onXmlFileDownloaded(UPnPRouter* r,bool success); Q_SIGNALS: /** * Emitted when a router or internet gateway device is detected. * @param router The router */ void discovered(bt::UPnPRouter* router); private: class UPnPMCastSocketPrivate; UPnPMCastSocketPrivate* d; }; } #endif diff --git a/src/upnp/upnprouter.h b/src/upnp/upnprouter.h index d45acf6..aebe63c 100644 --- a/src/upnp/upnprouter.h +++ b/src/upnp/upnprouter.h @@ -1,213 +1,213 @@ /*************************************************************************** * Copyright (C) 2005-2007 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KTUPNPROUTER_H #define KTUPNPROUTER_H #include #include #include #include class KJob; namespace bt { class HTTPRequest; class WaitJob; /** * Structure describing a UPnP service found in an xml file. */ struct KTORRENT_EXPORT UPnPService { QString serviceid; QString servicetype; QString controlurl; QString eventsuburl; QString scpdurl; UPnPService(); UPnPService(const UPnPService & s); /** * Set a property of the service. * @param name Name of the property (matches to variable names) * @param value Value of the property */ void setProperty(const QString & name,const QString & value); /** * Set all strings to empty. */ void clear(); /** * Assignment operator * @param s The service to copy * @return *this */ UPnPService & operator = (const UPnPService & s); }; /** * Struct to hold the description of a device */ struct KTORRENT_EXPORT UPnPDeviceDescription { QString friendlyName; QString manufacturer; QString modelDescription; QString modelName; QString modelNumber; /** * Set a property of the description * @param name Name of the property (matches to variable names) * @param value Value of the property */ void setProperty(const QString & name,const QString & value); }; /** * @author Joris Guisson * * Class representing a UPnP enabled router. This class is also used to communicate * with the router. */ class KTORRENT_EXPORT UPnPRouter : public QObject { Q_OBJECT public: /** * Construct a router. * @param server The name of the router * @param location The location of it's xml description file * @param verbose Print lots of debug info */ UPnPRouter(const QString & server,const QUrl &location,bool verbose = false); - virtual ~UPnPRouter(); + ~UPnPRouter() override; /// Disable or enable verbose logging void setVerbose(bool v); /// Get the name of the server QString getServer() const; /// Get the location of it's xml description QUrl getLocation() const; /// Get the device description UPnPDeviceDescription & getDescription(); /// Get the device description (const version) const UPnPDeviceDescription & getDescription() const; /// Get the current error (null string if there is none) QString getError() const; /// Get the router's external IP QString getExternalIP() const; /** * Download the XML File of the router. */ void downloadXMLFile(); /** * Add a service to the router. * @param s The service */ void addService(const UPnPService & s); #if 0 /** * See if a port is forwarded * @param port The Port */ void isPortForwarded(const net::Port & port); #endif /** * Forward a local port * @param port The local port to forward */ void forward(const net::Port & port); /** * Undo forwarding * @param port The port * @param waitjob When this is set the jobs needs to be added to the waitjob, * so we can wait for their completeion at exit */ void undoForward(const net::Port & port,bt::WaitJob* waitjob = 0); /** In order to iterate over all forwardings, the visitor pattern must be used. */ class Visitor { public: virtual ~Visitor() {} /** Called for each forwarding. @param port The Port @param pending When set to true, the forwarding is not completed yet @param service The UPnPService this forwarding is for */ virtual void forwarding(const net::Port & port, bool pending, const UPnPService* service) = 0; }; /** Visit all forwardings @param visitor The Visitor */ void visit(Visitor* visitor) const; private Q_SLOTS: void forwardResult(HTTPRequest* r); void undoForwardResult(HTTPRequest* r); void getExternalIPResult(HTTPRequest* r); void downloadFinished(KJob* j); Q_SIGNALS: /** * Internal state has changed, a forwarding succeeded or failed, or an undo forwarding succeeded or failed. */ void stateChanged(); /** * Signal which indicates that the XML was downloaded successfully or not. * @param r The router which emitted the signal * @param success Whether or not it succeeded */ void xmlFileDownloaded(UPnPRouter* r,bool success); private: class UPnPRouterPrivate; UPnPRouterPrivate* d; }; } #endif diff --git a/src/util/autorotatelogjob.h b/src/util/autorotatelogjob.h index f460660..c1de976 100644 --- a/src/util/autorotatelogjob.h +++ b/src/util/autorotatelogjob.h @@ -1,60 +1,60 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTAUTOROTATELOGJOB_H #define BTAUTOROTATELOGJOB_H #include #include namespace bt { class Log; /** @author Joris Guisson Job which handles the rotation of the log file. This Job must do several move jobs which must be done sequentially. */ class AutoRotateLogJob : public KIO::Job { Q_OBJECT public: AutoRotateLogJob(const QString & file,Log* lg); - virtual ~AutoRotateLogJob(); + ~AutoRotateLogJob() override; virtual void kill(bool quietly=true); private Q_SLOTS: void moveJobDone(KJob*); void compressJobDone(KJob*); private: void update(); private: QString file; int cnt; Log* lg; }; } #endif diff --git a/src/util/compressfilejob.h b/src/util/compressfilejob.h index 7b9f6a2..d396eda 100644 --- a/src/util/compressfilejob.h +++ b/src/util/compressfilejob.h @@ -1,74 +1,74 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTCOMPRESSFILEJOB_H #define BTCOMPRESSFILEJOB_H #include #include #include namespace bt { class KTORRENT_EXPORT CompressThread : public QThread { public: CompressThread(const QString & file); - virtual ~CompressThread(); + ~CompressThread() override; /// Run the compression thread - virtual void run(); + void run() override; /// Cancel the thread, things should be cleaned up properly void cancel(); /// Get the error which happened (0 means no error) int error() const {return err;} private: QString file; bool canceled; int err; }; /** Compress a file using gzip and remove it when completed successfully. */ class KTORRENT_EXPORT CompressFileJob : public KIO::Job { Q_OBJECT public: CompressFileJob(const QString & file); - virtual ~CompressFileJob(); + ~CompressFileJob() override; - virtual void start(); + void start() override; virtual void kill(bool quietly=true); private Q_SLOTS: void compressThreadFinished(); private: QString file; CompressThread* compress_thread; }; } #endif diff --git a/src/util/decompressfilejob.h b/src/util/decompressfilejob.h index 49f94c0..66e859c 100644 --- a/src/util/decompressfilejob.h +++ b/src/util/decompressfilejob.h @@ -1,79 +1,79 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DECOMPRESSFILEJOB_H #define DECOMPRESSFILEJOB_H #include #include #include namespace bt { /** * Thread which decompresses a single file */ class KTORRENT_EXPORT DecompressThread : public QThread { public: DecompressThread(const QString & file,const QString & dest_file); - virtual ~DecompressThread(); + ~DecompressThread() override; /// Run the decompression thread - virtual void run(); + void run() override; /// Cancel the thread, things should be cleaned up properly void cancel(); /// Get the error which happened (0 means no error) int error() const {return err;} private: QString file; QString dest_file; bool canceled; int err; }; /** Decompress a file and remove it when completed successfully. */ class KTORRENT_EXPORT DecompressFileJob : public KIO::Job { Q_OBJECT public: DecompressFileJob(const QString & file,const QString & dest); - virtual ~DecompressFileJob(); + ~DecompressFileJob() override; - virtual void start(); + void start() override; virtual void kill(bool quietly=true); private Q_SLOTS: void decompressThreadFinished(); private: QString file; QString dest; DecompressThread* decompress_thread; }; } #endif // DECOMPRESSFILEJOB_H diff --git a/src/util/extractfilejob.cpp b/src/util/extractfilejob.cpp index 48f7f52..cbbc05e 100644 --- a/src/util/extractfilejob.cpp +++ b/src/util/extractfilejob.cpp @@ -1,147 +1,147 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "extractfilejob.h" #include #include namespace bt { class ExtractFileThread : public QThread { public: ExtractFileThread(QIODevice* in_dev,QIODevice* out_dev) : in_dev(in_dev),out_dev(out_dev),canceled(false) { } - virtual ~ExtractFileThread() + ~ExtractFileThread() override { delete in_dev; delete out_dev; } - virtual void run() + void run() override { char buf[4096]; qint64 ret = 0; while ((ret = in_dev->read(buf,4096)) != 0 && !canceled) { out_dev->write(buf,ret); } } QIODevice* in_dev; QIODevice* out_dev; bool canceled; }; ExtractFileJob::ExtractFileJob(KArchive* archive, const QString& path, const QString& dest) : archive(archive),path(path),dest(dest),extract_thread(0) { } ExtractFileJob::~ExtractFileJob() { delete archive; } void ExtractFileJob::start() { // first find the file in the archive QStringList path_components = path.split(QLatin1Char('/'), QString::SkipEmptyParts); const KArchiveDirectory* dir = archive->directory(); for (int i = 0;i < path_components.count();i++) { // if we can't find it give back an error QString pc = path_components.at(i); if (!dir->entries().contains(pc)) { setError(KIO::ERR_DOES_NOT_EXIST); emitResult(); return; } const KArchiveEntry* e = dir->entry(pc); if (i < path_components.count() - 1) { // if we are not the last entry in the path, e must be a directory if (!e->isDirectory()) { setError(KIO::ERR_DOES_NOT_EXIST); emitResult(); return; } dir = (const KArchiveDirectory*)e; } else { // last in the path, must be a file if (!e->isFile()) { setError(KIO::ERR_DOES_NOT_EXIST); emitResult(); return; } // create a device to read the file and start a thread to do the reading KArchiveFile* file = (KArchiveFile*)e; QFile* out_dev = new QFile(dest); if (!out_dev->open(QIODevice::WriteOnly)) { delete out_dev; setError(KIO::ERR_CANNOT_OPEN_FOR_WRITING); emitResult(); return; } QIODevice* in_dev = file->createDevice(); extract_thread = new ExtractFileThread(in_dev,out_dev); connect(extract_thread,SIGNAL(finished()),this,SLOT(extractThreadDone()),Qt::QueuedConnection); extract_thread->start(); } } } void ExtractFileJob::kill(bool quietly) { if (extract_thread) { extract_thread->canceled = true; extract_thread->wait(); delete extract_thread; extract_thread = 0; } setError(KIO::ERR_USER_CANCELED); if (!quietly) emitResult(); } void ExtractFileJob::extractThreadDone() { extract_thread->wait(); delete extract_thread; extract_thread = 0; setError(0); emitResult(); } } diff --git a/src/util/extractfilejob.h b/src/util/extractfilejob.h index d54fdd6..f480f3a 100644 --- a/src/util/extractfilejob.h +++ b/src/util/extractfilejob.h @@ -1,57 +1,57 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_EXTRACTFILEJOB_H #define BT_EXTRACTFILEJOB_H #include #include #include namespace bt { class ExtractFileThread; /** Job which extracts a single file out of an archive */ class KTORRENT_EXPORT ExtractFileJob : public KIO::Job { Q_OBJECT public: ExtractFileJob(KArchive* archive,const QString & path,const QString & dest); - virtual ~ExtractFileJob(); + ~ExtractFileJob() override; - virtual void start(); + void start() override; virtual void kill(bool quietly=true); private Q_SLOTS: void extractThreadDone(); private: KArchive* archive; QString path; QString dest; ExtractFileThread* extract_thread; }; } #endif // BT_EXTRACTFILEJOB_H diff --git a/src/util/logsystemmanager.h b/src/util/logsystemmanager.h index 96945a5..822106a 100644 --- a/src/util/logsystemmanager.h +++ b/src/util/logsystemmanager.h @@ -1,72 +1,72 @@ /*************************************************************************** * Copyright (C) 2008 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTLOGSYSTEMMANAGER_H #define BTLOGSYSTEMMANAGER_H #include #include #include #include #include namespace bt { /** Keeps track of all logging system ID's */ class KTORRENT_EXPORT LogSystemManager : public QObject { Q_OBJECT LogSystemManager(); public: - virtual ~LogSystemManager(); + ~LogSystemManager() override; /// Register a system void registerSystem(const QString & name,Uint32 id); /// Unregister a system void unregisterSystem(const QString & name); typedef QMap::iterator iterator; iterator begin() {return systems.begin();} iterator end() {return systems.end();} static LogSystemManager & instance(); /// Get the ID of a system Uint32 systemID(const QString & name); Q_SIGNALS: void registered(const QString & name); void unregisted(const QString & name); private: QMap systems; static QScopedPointer self; }; } #endif diff --git a/src/util/signalcatcher.h b/src/util/signalcatcher.h index 989a020..fabc755 100644 --- a/src/util/signalcatcher.h +++ b/src/util/signalcatcher.h @@ -1,104 +1,104 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BT_SIGNALCATCHER_H #define BT_SIGNALCATCHER_H #ifndef Q_WS_WIN #include #include #include #include #include #include namespace bt { /** Variable used to jump from the SIGBUS handler back to the place which triggered the SIGBUS. */ extern KTORRENT_EXPORT sigjmp_buf sigbus_env; /** * Protects against SIGBUS errors when doing mmapped IO **/ class KTORRENT_EXPORT BusErrorGuard { public: BusErrorGuard(); virtual ~BusErrorGuard(); }; /** Exception throw when a SIGBUS is caught. */ class KTORRENT_EXPORT BusError : public bt::Error { public: BusError(bool write_operation); - virtual ~BusError(); + ~BusError() override; /// Whether or not the SIGBUS was triggered by a write operation bool write_operation; }; /** * Class to handle UNIX signals (not Qt ones) */ class KTORRENT_EXPORT SignalCatcher : public QObject { Q_OBJECT public: SignalCatcher(QObject* parent = 0); - virtual ~SignalCatcher(); + ~SignalCatcher() override; /** * Catch a UNIX signal * @param sig SIGINT, SIGTERM or some other signal * @return true upon success, false otherwise **/ bool catchSignal(int sig); private Q_SLOTS: void handleInput(int fd); private: static void signalHandler(int sig, siginfo_t *siginfo, void *ptr); Q_SIGNALS: /// Emitted when a void triggered(); private: QSocketNotifier* notifier; static int signal_received_pipe[2]; }; } /// Before writing to memory mapped data, call this macro to ensure that SIGBUS signals are caught and properly dealt with #define BUS_ERROR_WPROTECT() BusErrorGuard bus_error_guard; if (sigsetjmp(bt::sigbus_env, 1)) throw bt::BusError(true) /// Before reading from memory mapped data, call this macro to ensure that SIGBUS signals are caught and properly dealt with #define BUS_ERROR_RPROTECT() BusErrorGuard bus_error_guard; if (sigsetjmp(bt::sigbus_env, 1)) throw bt::BusError(false) #endif #endif // BT_SIGNALCATCHER_H diff --git a/src/util/tests/resourcemanagertest.cpp b/src/util/tests/resourcemanagertest.cpp index 93a4b7a..b2a07ee 100644 --- a/src/util/tests/resourcemanagertest.cpp +++ b/src/util/tests/resourcemanagertest.cpp @@ -1,158 +1,158 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include using namespace bt; static bt::Resource* last_acquired = 0; class TestResource : public bt::Resource { public: TestResource(ResourceManager* rman, const QString& group) : Resource(rman,group),acq(false) {} - virtual void acquired() + void acquired() override { Out(SYS_GEN|LOG_DEBUG) << "Resource of " << groupName() << " acquired" << endl; acq = true; last_acquired = this; } bool acq; }; class ResourceManagerTest : public QObject { Q_OBJECT public: private Q_SLOTS: void initTestCase() { bt::InitLog("resourcemanagertest.log"); qsrand(bt::Now()); } void cleanupTestCase() { } void testSingleClass() { Out(SYS_GEN|LOG_DEBUG) << "testSingleClass" << endl; ResourceManager rm(4); QList tr; for (int i = 0;i < 8;i++) { TestResource* r = new TestResource(&rm,"test"); tr.append(r); rm.add(r); // The first 4 should get acquired QVERIFY(r->acq == (i < 4)); } for (int i = 0;i < 4;i++) { delete tr.takeFirst(); QVERIFY(tr.at(3)->acq); // The next availabe one should now be acquired } qDeleteAll(tr); } void testMultiClass() { Out(SYS_GEN|LOG_DEBUG) << "testMultiClass" << endl; ResourceManager rm(4); const char* classes[4] = {"aaa", "bbb", "ccc", "ddd"}; // 4 resources for each class QList tr; for (int i = 0;i < 16;i++) { TestResource* r = new TestResource(&rm,classes[i % 4]); tr.append(r); rm.add(r); // The first 4 should get acquired QVERIFY(r->acq == (i < 4)); } QString last_group; for (int i = 0;i < 12;i++) { Resource* r = tr.takeFirst(); QString g = r->groupName(); delete r; QVERIFY(tr.at(3)->acq); // The next availabe one should now be acquired QVERIFY(g != last_group); last_group = g; } qDeleteAll(tr); } void testFullyRandom() { Out(SYS_GEN|LOG_DEBUG) << "testFullyRandom" << endl; ResourceManager rm(4); const char* classes[4] = {"aaa", "bbb", "ccc", "ddd"}; // A random amount of resources for each class QList tr; Uint32 num_acquired = 0; for (int i = 0;i < 500;i++) { TestResource* r = new TestResource(&rm,classes[rand() % 4]); tr.append(r); rm.add(r); if (r->acq) num_acquired++; } QVERIFY(num_acquired == 4); QString last_acquired_group; for (int i = 0;i < 496;i++) { tr.removeAll((TestResource*)last_acquired); delete last_acquired; QVERIFY(last_acquired); if (last_acquired->groupName() == last_acquired_group) { // This is only possible if there are no other groups which are still pending foreach(TestResource* r,tr) if (!r->acq) QVERIFY(r->groupName() == last_acquired_group); } last_acquired_group = last_acquired->groupName(); } qDeleteAll(tr); } }; QTEST_MAIN(ResourceManagerTest) #include "resourcemanagertest.moc" diff --git a/src/util/waitjob.h b/src/util/waitjob.h index 5ee5983..48dc7e5 100644 --- a/src/util/waitjob.h +++ b/src/util/waitjob.h @@ -1,83 +1,83 @@ /*************************************************************************** * Copyright (C) 2005 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef BTWAITJOB_H #define BTWAITJOB_H #include #include #include #include "constants.h" #include namespace bt { /** * @author Joris Guisson * * Job to wait for a certain amount of time or until one or more ExitOperation's have * finished. */ class KTORRENT_EXPORT WaitJob : public KIO::Job { Q_OBJECT public: WaitJob(Uint32 millis); - virtual ~WaitJob(); + ~WaitJob() override; virtual void kill(bool quietly=true); /** * Add an ExitOperation; * @param op The operation */ void addExitOperation(ExitOperation* op); /** * Add a KIO::Job to wait on; * @param job The job */ void addExitOperation(KIO::Job* job); /** * Execute a WaitJob * @param job The Job */ static void execute(WaitJob* job); /// Are there any ExitOperation's we need to wait for bool needToWait() const {return exit_ops.count() > 0;} private Q_SLOTS: void timerDone(); void operationFinished(ExitOperation* op); private: QList exit_ops; }; KTORRENT_EXPORT void SynchronousWait(Uint32 millis); } #endif diff --git a/src/utp/connection.h b/src/utp/connection.h index 5d46e2c..d1975d3 100644 --- a/src/utp/connection.h +++ b/src/utp/connection.h @@ -1,226 +1,226 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_CONNECTION_H #define UTP_CONNECTION_H #include #include #include #include #include #include #include #include #include #include #include #include namespace utp { class DelayWindow; class LocalWindow; class Transmitter; /** Keeps track of a single UTP connection */ class KTORRENT_EXPORT Connection : public QObject, public Retransmitter { Q_OBJECT public: enum Type { INCOMING, OUTGOING }; /// Thrown when a transmission error occurs, server should kill the connection if it happens class TransmissionError { public: TransmissionError(const char* file, int line); QString location; }; struct Stats { Type type; net::Address remote; ConnectionState state; bt::Uint16 send_connection_id; bt::Uint32 reply_micro; bt::Uint16 recv_connection_id; bt::Uint16 seq_nr; int eof_seq_nr; bt::Uint32 timeout; TimeValue absolute_timeout; int rtt; int rtt_var; bt::Uint32 packet_size; bt::Uint32 last_window_size_transmitted; bt::Uint64 bytes_received; bt::Uint64 bytes_sent; bt::Uint32 packets_received; bt::Uint32 packets_sent; bt::Uint64 bytes_lost; bt::Uint32 packets_lost; bool readable; bool writeable; }; Connection(bt::Uint16 recv_connection_id, Type type, const net::Address & remote, Transmitter* transmitter); - virtual ~Connection(); + ~Connection() override; /// Turn on or off blocking mode void setBlocking(bool on) {blocking = on;} /// Dump connection stats void dumpStats(); /// Start connecting (OUTGOING only) void startConnecting(); /// Get the connection stats const Stats & connectionStats() const {return stats;} /// Handle a single packet ConnectionState handlePacket(const PacketParser & parser, bt::Buffer::Ptr packet); /// Get the remote address const net::Address & remoteAddress() const {return stats.remote;} /// Get the receive connection id bt::Uint16 receiveConnectionID() const {return stats.recv_connection_id;} /// Send some data, returns the amount of bytes sent (or -1 on error) int send(const bt::Uint8* data, bt::Uint32 len); /// Read available data from local window, returns the amount of bytes read int recv(bt::Uint8* buf, bt::Uint32 max_len); /// Get the connection state ConnectionState connectionState() const {return stats.state;} /// Get the type of connection Type connectionType() const {return stats.type;} /// Get the number of bytes available bt::Uint32 bytesAvailable() const; /// Can we write to this socket bool isWriteable() const; /// Wait until the connectTo call fails or succeeds bool waitUntilConnected(); /// Wait until there is data ready or the socket is closed or a timeout occurs bool waitForData(bt::Uint32 timeout = 0); /// Close the socket void close(); /// Reset the connection void reset(); /// Update the RTT time - virtual void updateRTT(const Header* hdr, bt::Uint32 packet_rtt, bt::Uint32 packet_size); + void updateRTT(const Header* hdr, bt::Uint32 packet_rtt, bt::Uint32 packet_size) override; /// Retransmit a packet - virtual void retransmit(PacketBuffer & packet, bt::Uint16 p_seq_nr); + void retransmit(PacketBuffer & packet, bt::Uint16 p_seq_nr) override; /// Is all data sent bool allDataSent() const; /// Get the current timeout - virtual bt::Uint32 currentTimeout() const {return stats.timeout;} + bt::Uint32 currentTimeout() const override {return stats.timeout;} typedef QSharedPointer Ptr; typedef QWeakPointer WPtr; /// Set a weak pointer to self void setWeakPointer(WPtr ptr) {self = ptr;} /// Check if we haven't hit a timeout yet void checkTimeout(const TimeValue & now); private: void sendSYN(); void sendState(); void sendFIN(); void sendReset(); void updateDelayMeasurement(const Header* hdr); void sendStateOrData(); void sendPackets(); void sendPacket(bt::Uint32 type, bt::Uint16 p_ack_nr); void checkIfClosed(); void sendDataPacket(PacketBuffer & packet, bt::Uint16 seq_nr, const TimeValue & now); void startTimer(); void checkState(); bt::Uint32 extensionLength() const; void handleTimeout(); private: Transmitter* transmitter; LocalWindow* local_wnd; RemoteWindow* remote_wnd; bt::CircularBuffer output_buffer; //bt::Timer timer; mutable QMutex mutex; QWaitCondition connected; QWaitCondition data_ready; Stats stats; bool fin_sent; TimeValue last_packet_sent; DelayWindow* delay_window; Connection::WPtr self; bool blocking; friend class UTPServer; }; /** Interface class for transmitting packets and notifying if a connection becomes readable or writeable */ class KTORRENT_EXPORT Transmitter { public: virtual ~Transmitter(); /// Send a packet of a connection virtual bool sendTo(Connection::Ptr conn, const PacketBuffer & packet) = 0; /// Connection has become readable, writeable or both virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable) = 0; /// Called when the connection is closed virtual void closed(Connection::Ptr conn) = 0; }; } #endif // UTP_CONNECTION_H diff --git a/src/utp/pollpipe.h b/src/utp/pollpipe.h index ec73f7c..e985d58 100644 --- a/src/utp/pollpipe.h +++ b/src/utp/pollpipe.h @@ -1,77 +1,77 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_POLLPIPE_H #define UTP_POLLPIPE_H #include #include #include namespace utp { /** Special wake up pipe for UTP polling */ class PollPipe : public net::WakeUpPipe { public: PollPipe(net::Poll::Mode mode); - virtual ~PollPipe(); + ~PollPipe() override; typedef QSharedPointer Ptr; /// Is the pipe being polled bool polling() const {return poll_index >= 0;} /// Prepare the poll void prepare(net::Poll* p, bt::Uint16 conn_id, PollPipe::Ptr self) { QMutexLocker lock(&mutex); conn_ids.set(conn_id, true); if (poll_index < 0) poll_index = p->add(qSharedPointerCast(self)); } /// Are we polling a connection bool polling(bt::Uint16 conn) const { QMutexLocker lock(&mutex); return poll_index >= 0 && conn_ids[conn]; } /// Reset the poll_index - virtual void reset(); + void reset() override; /// Polling mode net::Poll::Mode pollingMode() const {return mode;} private: net::Poll::Mode mode; int poll_index; std::bitset<65536> conn_ids; }; } #endif // UTP_POLLPIPE_H diff --git a/src/utp/tests/connectiontest.cpp b/src/utp/tests/connectiontest.cpp index abad3e7..505266b 100644 --- a/src/utp/tests/connectiontest.cpp +++ b/src/utp/tests/connectiontest.cpp @@ -1,147 +1,147 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include using namespace utp; class ConnectionTest : public QEventLoop,public Transmitter { Q_OBJECT public: ConnectionTest(QObject* parent = 0) : QEventLoop(parent),remote("127.0.0.1",50000) { } - virtual bool sendTo(Connection::Ptr conn, const PacketBuffer & packet) + bool sendTo(Connection::Ptr conn, const PacketBuffer & packet) override { sent_packets.append(packet); Q_UNUSED(conn); return true; } - virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable) + void stateChanged(Connection::Ptr conn, bool readable, bool writeable) override { Q_UNUSED(conn); Q_UNUSED(readable); Q_UNUSED(writeable); } - virtual void closed(Connection::Ptr conn) + void closed(Connection::Ptr conn) override { Q_UNUSED(conn); } bt::Buffer::Ptr buildPacket(bt::Uint32 type,bt::Uint32 recv_conn_id,bt::Uint32 send_conn_id,bt::Uint16 seq_nr,bt::Uint16 ack_nr) { TimeValue tv; bt::Buffer::Ptr packet = pool->get(Header::size()); Header hdr; hdr.version = 1; hdr.type = type; hdr.extension = 0; hdr.connection_id = type == ST_SYN ? recv_conn_id : send_conn_id; hdr.timestamp_microseconds = tv.microseconds; hdr.timestamp_difference_microseconds = 0; hdr.wnd_size = 6666; hdr.seq_nr = seq_nr; hdr.ack_nr = ack_nr; hdr.write(packet->get()); return packet; } public Q_SLOTS: private Q_SLOTS: void initTestCase() { bt::InitLog("connectiontest.log"); pool = bt::BufferPool::Ptr(new bt::BufferPool()); pool->setWeakPointer(pool.toWeakRef()); } void cleanupTestCase() { pool.clear(); } void init() { sent_packets.clear(); } void testConnID() { bt::Uint32 conn_id = 666; Connection conn(conn_id,utp::Connection::INCOMING,remote,this); QVERIFY(conn.connectionStats().recv_connection_id == conn_id); QVERIFY(conn.connectionStats().send_connection_id == conn_id - 1); Connection conn2(conn_id,utp::Connection::OUTGOING,remote,this); QVERIFY(conn2.connectionStats().recv_connection_id == conn_id); QVERIFY(conn2.connectionStats().send_connection_id == conn_id + 1); } void testOutgoingConnectionSetup() { bt::Uint32 conn_id = 666; Connection conn(conn_id,utp::Connection::OUTGOING,remote,this); conn.startConnecting(); const Connection::Stats & s = conn.connectionStats(); QVERIFY(s.state == utp::CS_SYN_SENT); QVERIFY(s.seq_nr == 2); bt::Buffer::Ptr pkt = buildPacket(ST_STATE,conn_id,conn_id + 1,1,1); PacketParser pp(pkt->get(), pkt->size()); QVERIFY(pp.parse()); conn.handlePacket(pp,pkt); QVERIFY(s.state == CS_CONNECTED); QVERIFY(sent_packets.count() == 1); } void testIncomingConnectionSetup() { bt::Uint32 conn_id = 666; Connection conn(conn_id,utp::Connection::INCOMING,remote,this); const Connection::Stats & s = conn.connectionStats(); bt::Buffer::Ptr pkt = buildPacket(ST_SYN,conn_id - 1,conn_id,1,1); PacketParser pp(pkt->get(), pkt->size()); conn.handlePacket(pp,pkt); QVERIFY(s.state == CS_CONNECTED); } private: net::Address remote; QList sent_packets; bt::BufferPool::Ptr pool; }; QTEST_MAIN(ConnectionTest) #include "connectiontest.moc" diff --git a/src/utp/tests/packetlosstest.cpp b/src/utp/tests/packetlosstest.cpp index f2de5ce..3c84d7f 100644 --- a/src/utp/tests/packetlosstest.cpp +++ b/src/utp/tests/packetlosstest.cpp @@ -1,231 +1,231 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #define PACKETS_TO_SEND 20 #define TEST_DATA "This is the packet loss test\n" using namespace utp; using namespace bt; /** Server which simulates packet loss */ class PacketLossServer : public UTPServer { Q_OBJECT public: PacketLossServer(QObject* parent = 0) : UTPServer(parent),packet_loss(false),loss_factor(0.5) { setCreateSockets(false); qsrand(time(0)); } - virtual ~PacketLossServer() + ~PacketLossServer() override {} - virtual void handlePacket(bt::Buffer::Ptr packet, const net::Address& addr) + void handlePacket(bt::Buffer::Ptr packet, const net::Address& addr) override { if (packet_loss) { // pick a random number from 0 to 100 int r = qrand() % 100; if (r <= (int)qRound(100 * loss_factor)) { Out(SYS_UTP|LOG_DEBUG) << "Dropping packet " << endl; return; } } UTPServer::handlePacket(packet,addr); } void setPacketLossSimulation(bool on,float lf) { packet_loss = on; loss_factor = lf; qsrand(time(0)); } private: bool packet_loss; float loss_factor; }; class SendThread : public QThread { Q_OBJECT public: SendThread(Connection::Ptr outgoing,QObject* parent = 0) : QThread(parent),outgoing(outgoing) {} - virtual void run() + void run() override { char test[] = TEST_DATA; int sent = 0; while (sent < PACKETS_TO_SEND && outgoing->connectionState() != CS_CLOSED) { int ret = outgoing->send((const bt::Uint8*)test,strlen(test)); if (ret > 0) { sent++; } msleep(200); } while (!outgoing->allDataSent() && outgoing->connectionState() != CS_CLOSED) sleep(1); Out(SYS_UTP|LOG_DEBUG) << "Transmitted " << sent << " packets " << endl; outgoing->dumpStats(); } Connection::Ptr outgoing; }; class PacketLoss : public QEventLoop { Q_OBJECT public: PacketLoss(QObject* parent = 0) : QEventLoop(parent) { } public Q_SLOTS: void accepted() { incoming = srv.acceptedConnection().toStrongRef(); exit(); } void endEventLoop() { exit(); } private Q_SLOTS: void initTestCase() { bt::InitLog("packetlosstest.log"); port = 50000; while (port < 60000) { if (!srv.changePort(port)) port++; else break; } srv.start(); } void cleanupTestCase() { srv.stop(); } void testConnect() { net::Address addr("127.0.0.1",port); connect(&srv,SIGNAL(accepted()),this,SLOT(accepted()),Qt::QueuedConnection); outgoing = srv.connectTo(addr).toStrongRef(); QVERIFY(outgoing); QTimer::singleShot(5000,this,SLOT(endEventLoop())); // use a 5 second timeout exec(); QVERIFY(incoming); } void testPacketLoss() { bt::Out(SYS_UTP|LOG_DEBUG) << "testPacketLoss" << bt::endl; if (outgoing->connectionState() != CS_CONNECTED || incoming->connectionState() != CS_CONNECTED) { QSKIP("Not Connected",SkipAll); return; } srv.setPacketLossSimulation(true,0.1); // Drop 10 % of all packets SendThread st(outgoing); incoming->setBlocking(true); st.start(); // The thread will start sending a whole bunch of data int received = 0; QString received_data; while (received_data.count(TEST_DATA) < PACKETS_TO_SEND) { bt::Uint32 ba = incoming->bytesAvailable(); if (ba > 0) { QByteArray data(ba,0); int ret = incoming->recv((bt::Uint8*)data.data(),ba); if (ret > 0) { received_data.append(data); received += ret; } } else if (incoming->connectionState() == CS_CLOSED) { Out(SYS_UTP|LOG_DEBUG) << "Connection closed " << endl; break; } else { incoming->waitForData(1000); } } st.wait(); Out(SYS_UTP|LOG_DEBUG) << "Received " << received << " bytes:" << endl; Out(SYS_UTP|LOG_DEBUG) << received_data << endl; incoming->dumpStats(); QVERIFY(incoming->bytesAvailable() == 0); QVERIFY(received_data.count(TEST_DATA) == PACKETS_TO_SEND); QVERIFY(outgoing->allDataSent()); } private: private: Connection::Ptr incoming; Connection::Ptr outgoing; PacketLossServer srv; int port; }; QTEST_MAIN(PacketLoss) #include "packetlosstest.moc" diff --git a/src/utp/tests/remotewindowtest.cpp b/src/utp/tests/remotewindowtest.cpp index 2b0b89f..5b6b9f4 100644 --- a/src/utp/tests/remotewindowtest.cpp +++ b/src/utp/tests/remotewindowtest.cpp @@ -1,359 +1,359 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include using namespace utp; class RemoteWindowTest : public QObject,public utp::Retransmitter { Q_OBJECT public: QSet retransmit_seq_nr; bool update_rtt_called; bool retransmit_ok; RemoteWindowTest(QObject* parent = 0) : QObject(parent),update_rtt_called(false),retransmit_ok(false) { } - virtual void updateRTT(const Header* hdr,bt::Uint32 packet_rtt,bt::Uint32 packet_size) + void updateRTT(const Header* hdr,bt::Uint32 packet_rtt,bt::Uint32 packet_size) override { Q_UNUSED(hdr); Q_UNUSED(packet_rtt); Q_UNUSED(packet_size); update_rtt_called = true; } - virtual void retransmit(PacketBuffer & /*packet*/,bt::Uint16 p_seq_nr) + void retransmit(PacketBuffer & /*packet*/,bt::Uint16 p_seq_nr) override { bt::Out(SYS_UTP|LOG_NOTICE) << "retransmit " << p_seq_nr << bt::endl; retransmit_ok = retransmit_seq_nr.contains(p_seq_nr); } void reset() { retransmit_seq_nr.clear(); update_rtt_called = false; retransmit_ok = false; } - virtual bt::Uint32 currentTimeout() const {return 1000;} + bt::Uint32 currentTimeout() const override {return 1000;} private Q_SLOTS: void initTestCase() { bt::InitLog("remotewindowtest.log"); } void cleanupTestCase() { } void init() { reset(); } void testNormalUsage() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; wnd.addPacket(pkt,1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == 1); wnd.addPacket(pkt,2,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 2); wnd.addPacket(pkt,3,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 3); Header hdr; hdr.ack_nr = 1; hdr.wnd_size = 5000; wnd.packetReceived(&hdr,0,this); QVERIFY(wnd.numUnackedPackets() == 2); QVERIFY(update_rtt_called); reset(); hdr.ack_nr = 2; wnd.packetReceived(&hdr,0,this); QVERIFY(wnd.numUnackedPackets() == 1); QVERIFY(update_rtt_called); reset(); hdr.ack_nr = 3; wnd.packetReceived(&hdr,0,this); QVERIFY(wnd.numUnackedPackets() == 0); QVERIFY(update_rtt_called); } void testMultipleAcks() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; wnd.addPacket(pkt,1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == 1); wnd.addPacket(pkt,2,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 2); wnd.addPacket(pkt,3,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 3); Header hdr; hdr.ack_nr = 3; hdr.wnd_size = 5000; wnd.packetReceived(&hdr,0,this); QVERIFY(wnd.numUnackedPackets() == 0); QVERIFY(update_rtt_called); } void testSelectiveAck() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; wnd.addPacket(pkt,1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == 1); wnd.addPacket(pkt,2,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 2); wnd.addPacket(pkt,3,bt::Now()); QVERIFY(wnd.numUnackedPackets() == 3); // Selectively ack 3 bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack;; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,3); Header hdr; hdr.ack_nr = 0; hdr.wnd_size = 5000; wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 2); QVERIFY(update_rtt_called); reset(); // Ack the rest hdr.ack_nr = 3; hdr.wnd_size = 5000; wnd.packetReceived(&hdr,0,this); QVERIFY(wnd.numUnackedPackets() == 0); QVERIFY(update_rtt_called); } void testRetransmits() { reset(); PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; for (bt::Uint32 i = 0;i < 4;i++) { wnd.addPacket(pkt,i+1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == i + 1); } // Selectively ack the last 3 packets bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack;; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,2); Ack(&sack,3); Ack(&sack,4); Header hdr; hdr.ack_nr = 0; hdr.wnd_size = 5000; retransmit_seq_nr.insert(1); wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 1); QVERIFY(update_rtt_called); QVERIFY(retransmit_ok); } void testMultipleRetransmits() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; for (bt::Uint32 i = 0;i < 4;i++) { wnd.addPacket(pkt,i+1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == i + 1); } // Selectively ack the last 3 packets bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack;; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,2); Ack(&sack,3); Ack(&sack,4); Header hdr; hdr.ack_nr = 0; hdr.wnd_size = 5000; retransmit_seq_nr.insert(1); wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 1); QVERIFY(update_rtt_called); QVERIFY(retransmit_ok); } void testMultipleRetransmits2() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; for (bt::Uint32 i = 0;i < 10;i++) { wnd.addPacket(pkt,i+1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == i + 1); } // Selectively ack the last 3 packets bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack;; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,8); Ack(&sack,9); Ack(&sack,10); Header hdr; hdr.ack_nr = 0; hdr.wnd_size = 5000; for (int i = 1;i < 8;i++) retransmit_seq_nr.insert(i); wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 7); QVERIFY(update_rtt_called); QVERIFY(retransmit_ok); } void testMultipleRetransmits3() { PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; for (bt::Uint32 i = 0;i < 10;i++) { wnd.addPacket(pkt,i+1,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == i + 1); } // Selectively ack 3 random packets bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack;; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,3); Ack(&sack,6); Ack(&sack,10); Header hdr; hdr.ack_nr = 0; hdr.wnd_size = 5000; for (int i = 1;i <= 2;i++) retransmit_seq_nr.insert(i); wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 7); QVERIFY(update_rtt_called); QVERIFY(retransmit_ok); } void testWrapAround() { bt::Out(SYS_UTP|LOG_NOTICE) << "testWrapAround " << bt::endl; reset(); PacketBuffer pkt; pkt.fillDummyData(200); RemoteWindow wnd; bt::Uint16 seq_nr = 65530; for (bt::Uint32 i = 0;i < 10;i++) { wnd.addPacket(pkt,seq_nr + i,bt::Now()); QVERIFY(!wnd.allPacketsAcked()); QVERIFY(wnd.numUnackedPackets() == i + 1); } // Selectively ack 3 random packets bt::Uint8 sack_data[6]; memset(sack_data,0,6); SelectiveAck sack; sack.length = 4; sack.extension = 0; sack.bitmask = sack_data + 2; Ack(&sack,3); Ack(&sack,6); Ack(&sack,10); Header hdr; hdr.ack_nr = seq_nr - 1; hdr.wnd_size = 5000; for (int i = 0;i < 2;i++) retransmit_seq_nr.insert(seq_nr + i); wnd.packetReceived(&hdr,&sack,this); QVERIFY(wnd.numUnackedPackets() == 7); QVERIFY(update_rtt_called); QVERIFY(retransmit_ok); } }; QTEST_MAIN(RemoteWindowTest) #include "remotewindowtest.moc" diff --git a/src/utp/tests/transmittest.cpp b/src/utp/tests/transmittest.cpp index aa0d258..6202807 100644 --- a/src/utp/tests/transmittest.cpp +++ b/src/utp/tests/transmittest.cpp @@ -1,266 +1,266 @@ /*************************************************************************** * Copyright (C) 2010 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #define BYTES_TO_SEND 100*1024*1024 using namespace utp; using namespace bt; static QByteArray Generate(int size) { QByteArray ba(size,0); /* for (int i = 0;i < size;i+=4) { ba[i] = 'A'; ba[i+1] = 'B'; ba[i+2] = 'C'; ba[i+3] = 'D'; } */ for (int i = 0;i < size;i++) { ba[i] = i % 256; } return ba; } /* static void Dump(const bt::Uint8* pkt, bt::Uint32 size,const QString & file) { QFile fptr(file); if (fptr.open(QIODevice::Text|QIODevice::WriteOnly)) { QTextStream out(&fptr); out << "Packet: " << size << ::endl; out << "Hash: " << bt::SHA1Hash::generate(pkt,size).toString() << ::endl; for (bt::Uint32 i = 0;i < size;i+=4) { if (i > 0 && i % 32 == 0) out << ::endl; out << QString("%1%2%3%4 ") .arg(pkt[i],2,16) .arg(pkt[i+1],2,16) .arg(pkt[i+2],2,16) .arg(pkt[i+3],2,16); } out << ::endl << ::endl << ::endl; } } */ class SendThread : public QThread { Q_OBJECT public: SendThread(Connection::Ptr outgoing, UTPServer & srv,QObject* parent = 0) : QThread(parent),outgoing(outgoing),srv(srv) {} - virtual void run() + void run() override { int step = 64*1024; QByteArray data = Generate(step); bt::SHA1HashGen hgen; bt::Int64 sent = 0; int off = 0; net::Poll poller; while (sent < BYTES_TO_SEND && outgoing->connectionState() != CS_CLOSED) { int to_send = step - off; int ret = outgoing->send((const bt::Uint8*)data.data() + off,to_send); if (ret > 0) { hgen.update((const bt::Uint8*)data.data() + off,ret); sent += ret; off += ret; off = off % step; //Out(SYS_UTP|LOG_DEBUG) << "Transmitted " << sent << endl; } else if (ret == 0) { srv.preparePolling(&poller, net::Poll::OUTPUT, outgoing); poller.poll(1000); } else { break; } } sleep(2); Out(SYS_UTP|LOG_DEBUG) << "Transmitted " << sent << endl; outgoing->dumpStats(); outgoing->close(); sent_hash = hgen.get(); } Connection::Ptr outgoing; bt::SHA1Hash sent_hash; UTPServer & srv; }; class TransmitTest : public QEventLoop { Q_OBJECT public: TransmitTest(QObject* parent = 0) : QEventLoop(parent) { } public Q_SLOTS: void accepted() { incoming = srv.acceptedConnection().toStrongRef(); incoming->setBlocking(true); exit(); } void startConnect() { net::Address addr("127.0.0.1",port); outgoing = srv.connectTo(addr); outgoing->setBlocking(true); } void endEventLoop() { exit(); } private Q_SLOTS: void initTestCase() { bt::InitLog("transmittest.log",false,true,false); port = 50000; while (port < 60000) { if (!srv.changePort(port)) port++; else break; } srv.setCreateSockets(false); srv.start(); } void cleanupTestCase() { srv.stop(); } void testConnect() { connect(&srv,SIGNAL(accepted()),this,SLOT(accepted()),Qt::QueuedConnection); QTimer::singleShot(0,this,SLOT(startConnect())); QTimer::singleShot(5000,this,SLOT(endEventLoop())); // use a 5 second timeout exec(); QVERIFY(outgoing); QVERIFY(incoming); QVERIFY(incoming->connectionState() == CS_CONNECTED); if (outgoing->connectionState() != CS_CONNECTED) QVERIFY(outgoing->waitUntilConnected()); QVERIFY(outgoing->connectionState() == CS_CONNECTED); } void testThreaded() { bt::Out(SYS_UTP|LOG_DEBUG) << "testThreaded" << bt::endl; if (outgoing->connectionState() != CS_CONNECTED || incoming->connectionState() != CS_CONNECTED) { QSKIP("Not Connected",SkipAll); return; } bt::SHA1HashGen hgen; SendThread st(outgoing, srv); st.start(); // The thread will start sending a whole bunch of data bt::Int64 received = 0; //int failures = 0; incoming->setBlocking(true); while (received < BYTES_TO_SEND && incoming->connectionState() != CS_CLOSED) { bt::Uint32 ba = incoming->bytesAvailable(); if (ba > 0) { //failures = 0; QByteArray data(ba,0); int to_read = ba;//;qMin(1024,ba); int ret = incoming->recv((bt::Uint8*)data.data(),to_read); QVERIFY(ret == to_read); if (ret > 0) { hgen.update((bt::Uint8*)data.data(),ret); received += ret; //Out(SYS_UTP|LOG_DEBUG) << "Received " << received << endl; } } else if (incoming->connectionState() != CS_CLOSED) { incoming->waitForData(1000); } } st.wait(); Out(SYS_UTP|LOG_DEBUG) << "Received " << received << endl; incoming->dumpStats(); QVERIFY(incoming->bytesAvailable() == 0); QVERIFY(outgoing->allDataSent()); QVERIFY(received >= BYTES_TO_SEND); SHA1Hash rhash = hgen.get(); Out(SYS_UTP|LOG_DEBUG) << "Received data hash: " << rhash.toString() << endl; Out(SYS_UTP|LOG_DEBUG) << "Sent data hash: " << st.sent_hash.toString() << endl; QVERIFY(rhash == st.sent_hash); } private: private: Connection::Ptr incoming; Connection::Ptr outgoing; utp::UTPServer srv; int port; }; QTEST_MAIN(TransmitTest) #include "transmittest.moc" diff --git a/src/utp/utpserver.h b/src/utp/utpserver.h index 8e87de9..2626f7e 100644 --- a/src/utp/utpserver.h +++ b/src/utp/utpserver.h @@ -1,101 +1,101 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_UTPSERVER_H #define UTP_UTPSERVER_H #include #include #include #include #include namespace utp { /** Implements the UTP server. It listens for UTP packets and manages all connections. */ class KTORRENT_EXPORT UTPServer : public bt::ServerInterface, public Transmitter { Q_OBJECT public: UTPServer(QObject* parent = 0); - virtual ~UTPServer(); + ~UTPServer() override; /// Enabled creating sockets (tests need to have this disabled) void setCreateSockets(bool on); - virtual bool changePort(bt::Uint16 port); + bool changePort(bt::Uint16 port) override; /// Send a packet to some host - virtual bool sendTo(Connection::Ptr conn, const PacketBuffer & packet); + bool sendTo(Connection::Ptr conn, const PacketBuffer & packet) override; /// Setup a connection to a remote address Connection::WPtr connectTo(const net::Address & addr); /// Get the last accepted connection (Note: for unittest purposes) Connection::WPtr acceptedConnection(); /// Start the UTP server void start(); /// Stop the UTP server void stop(); /// Prepare the server for polling void preparePolling(net::Poll* p, net::Poll::Mode mode, Connection::Ptr& conn); /// Set the TOS byte void setTOS(bt::Uint8 type_of_service); /// Thread has been started void threadStarted(); /** Handle newly connected sockets, it starts authentication on them. This needs to be called from the main thread. */ void handlePendingConnections(); protected: virtual void handlePacket(bt::Buffer::Ptr buffer, const net::Address & addr); - virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable); - virtual void closed(Connection::Ptr conn); - virtual void customEvent(QEvent* ev); + void stateChanged(Connection::Ptr conn, bool readable, bool writeable) override; + void closed(Connection::Ptr conn) override; + void customEvent(QEvent* ev) override; Q_SIGNALS: void handlePendingConnectionsDelayed(); /// Emitted when a connection is accepted if creating sockets is disabled void accepted(); private Q_SLOTS: void cleanup(); void checkTimeouts(); private: class Private; Private* d; }; } #endif // UTP_UTPSERVER_H diff --git a/src/utp/utpserver_p.h b/src/utp/utpserver_p.h index 82a656c..5e39d92 100644 --- a/src/utp/utpserver_p.h +++ b/src/utp/utpserver_p.h @@ -1,119 +1,119 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_UTPSERVER_P_H #define UTP_UTPSERVER_P_H #include #include #include #include #include #include #include #include #include #include "utpsocket.h" #include "connection.h" #include "pollpipe.h" #include "utpserver.h" #include "outputqueue.h" namespace utp { class UTPServerThread; /** Utility class used by UTPServer to make sure that ServerInterface::newConnection is called from the main thread and not from UTP thread (which is dangerous). */ class MainThreadCall : public QObject { Q_OBJECT public: MainThreadCall(UTPServer* server); - virtual ~MainThreadCall(); + ~MainThreadCall() override; public Q_SLOTS: /** Calls UTPServer::handlePendingConnections, this should be executed in the main thread. */ void handlePendingConnections(); private: UTPServer* server; }; typedef bt::PtrMap::iterator ConItr; struct PollPipePair { PollPipe::Ptr read_pipe; PollPipe::Ptr write_pipe; PollPipePair(); bool testRead(ConItr b, ConItr e); bool testWrite(ConItr b, ConItr e); }; typedef bt::PtrMap::iterator PollPipePairItr; typedef QMap::iterator ConnectionMapItr; class UTPServer::Private : public net::ServerSocket::DataHandler { public: Private(UTPServer* p); - ~Private(); + ~Private() override; bool bind(const net::Address & addr); void syn(const PacketParser & parser, bt::Buffer::Ptr buffer, const net::Address & addr); void reset(const Header* hdr); void wakeUpPollPipes(Connection::Ptr conn, bool readable, bool writeable); Connection::Ptr find(quint16 conn_id); void stop(); - virtual void dataReceived(bt::Buffer::Ptr buffer, const net::Address& addr); - virtual void readyToWrite(net::ServerSocket* sock); + void dataReceived(bt::Buffer::Ptr buffer, const net::Address& addr) override; + void readyToWrite(net::ServerSocket* sock) override; public: UTPServer* p; QList sockets; bool running; QMap connections; UTPServerThread* utp_thread; QMutex mutex; bt::PtrMap poll_pipes; bool create_sockets; bt::Uint8 tos; OutputQueue output_queue; QList pending; QMutex pending_mutex; MainThreadCall* mtc; QList last_accepted; QTimer* timer; }; } #endif diff --git a/src/utp/utpserverthread.h b/src/utp/utpserverthread.h index a82787a..e2d181c 100644 --- a/src/utp/utpserverthread.h +++ b/src/utp/utpserverthread.h @@ -1,46 +1,46 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_UTPSERVERTHREAD_H #define UTP_UTPSERVERTHREAD_H #include #include namespace utp { class UTPServer; class KTORRENT_EXPORT UTPServerThread : public QThread { Q_OBJECT public: UTPServerThread(UTPServer* srv); - virtual ~UTPServerThread(); + ~UTPServerThread() override; - virtual void run(); + void run() override; protected: UTPServer* srv; }; } #endif // UTP_UTPSERVERTHREAD_H diff --git a/src/utp/utpsocket.h b/src/utp/utpsocket.h index 314fd2a..9f6330f 100644 --- a/src/utp/utpsocket.h +++ b/src/utp/utpsocket.h @@ -1,66 +1,66 @@ /*************************************************************************** * Copyright (C) 2009 by Joris Guisson * * joris.guisson@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef UTP_UTPSOCKET_H #define UTP_UTPSOCKET_H #include #include #include #include namespace utp { /** UTPSocket class serves as an interface for the networking code. */ class KTORRENT_EXPORT UTPSocket : public net::SocketDevice { public: UTPSocket(); UTPSocket(Connection::WPtr conn); - virtual ~UTPSocket(); + ~UTPSocket() override; - virtual int fd() const; - virtual bool ok() const; - virtual int send(const bt::Uint8* buf, int len); - virtual int recv(bt::Uint8* buf, int max_len); - virtual void close(); - virtual void setBlocking(bool on); - virtual bt::Uint32 bytesAvailable() const; - virtual bool setTOS(unsigned char type_of_service); - virtual bool connectTo(const net::Address & addr); - virtual bool connectSuccesFull(); - virtual const net::Address & getPeerName() const; - virtual net::Address getSockName() const; - virtual void reset(); - virtual void prepare(net::Poll* p, net::Poll::Mode mode); - virtual bool ready(const net::Poll* p, net::Poll::Mode mode) const; + int fd() const override; + bool ok() const override; + int send(const bt::Uint8* buf, int len) override; + int recv(bt::Uint8* buf, int max_len) override; + void close() override; + void setBlocking(bool on) override; + bt::Uint32 bytesAvailable() const override; + bool setTOS(unsigned char type_of_service) override; + bool connectTo(const net::Address & addr) override; + bool connectSuccesFull() override; + const net::Address & getPeerName() const override; + net::Address getSockName() const override; + void reset() override; + void prepare(net::Poll* p, net::Poll::Mode mode) override; + bool ready(const net::Poll* p, net::Poll::Mode mode) const override; private: Connection::WPtr conn; bool blocking; mutable bool polled_for_reading; mutable bool polled_for_writing; }; } #endif // UTPSOCKET_H