File indexing completed on 2025-01-05 04:37:17

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #ifndef BTPEERINTERFACE_H
0007 #define BTPEERINTERFACE_H
0008 
0009 #include <ktorrent_export.h>
0010 #include <peer/peerid.h>
0011 #include <util/bitset.h>
0012 #include <util/constants.h>
0013 
0014 namespace bt
0015 {
0016 /**
0017  * @author Joris Guisson
0018  * @brief Interface for a Peer
0019  *
0020  * This is the interface for a Peer, it allows other classes to
0021  * get statistics about a Peer, and provides some basic functionality provided by a Peer.
0022  */
0023 class KTORRENT_EXPORT PeerInterface
0024 {
0025 public:
0026     /**
0027         Constructor, initialize the PeerID and the number of chunks
0028         @param peer_id The PeerID
0029         @param num_chunks The number of chunks
0030     */
0031     PeerInterface(const PeerID &peer_id, Uint32 num_chunks);
0032     virtual ~PeerInterface();
0033 
0034     struct Stats {
0035         /// IP address of peer (dotted notation)
0036         QString ip_address;
0037         /// Host name of the peer
0038         QString hostname;
0039         /// The client (Azureus, BitComet, ...)
0040         QString client;
0041         /// Download rate (bytes/s)
0042         bt::Uint32 download_rate;
0043         /// Upload rate (bytes/s)
0044         bt::Uint32 upload_rate;
0045         /// Choked or not
0046         bool choked;
0047         /// Snubbed or not (i.e. we haven't received a piece for a minute)
0048         bool snubbed;
0049         /// Percentage of file which the peer has
0050         float perc_of_file;
0051         /// Does this peer support DHT
0052         bool dht_support;
0053         /// Amount of data uploaded
0054         bt::Uint64 bytes_uploaded;
0055         /// Amount of data downloaded
0056         bt::Uint64 bytes_downloaded;
0057         /// Advanced choke algorithm score
0058         double aca_score;
0059         /// Flag to indicate if this peer has an upload slot
0060         bool has_upload_slot;
0061         /// Is the peer interested
0062         bool interested;
0063         /// Am I interested in the peer
0064         bool am_interested;
0065         /// Whether or not this connection is encrypted
0066         bool encrypted;
0067         /// Number of upload requests queued
0068         bt::Uint32 num_up_requests;
0069         /// Number of outstanding download requests queued
0070         bt::Uint32 num_down_requests;
0071         /// Supports the fast extensions
0072         bool fast_extensions;
0073         /// Is this a peer on the local network
0074         bool local;
0075         /// Whether or not the peer supports the extension protocol
0076         bool extension_protocol;
0077         /// Max number of outstanding requests (reqq in extended protocol handshake)
0078         bt::Uint32 max_request_queue;
0079         /// Time the peer choked us
0080         TimeStamp time_choked;
0081         /// Time the peer unchoked us
0082         TimeStamp time_unchoked;
0083         /// The transport protocol used by the peer
0084         bt::TransportProtocol transport_protocol;
0085         /// Is this a partial seed
0086         bool partial_seed;
0087 
0088         /// Get the address of the peer (hostname if it is valid, IP otherwise)
0089         QString address() const
0090         {
0091             return hostname.isEmpty() ? ip_address : hostname;
0092         }
0093     };
0094 
0095     /// Get the Peer's statistics
0096     const Stats &getStats() const
0097     {
0098         return stats;
0099     }
0100 
0101     /**
0102         Kill the Peer, will ensure the PeerManager closes the connection, and cleans things up.
0103     */
0104     virtual void kill() = 0;
0105 
0106     /// See if the peer has been killed.
0107     bool isKilled() const
0108     {
0109         return killed;
0110     }
0111 
0112     /**
0113         Get the average download speed since the last unchoke in bytes/sec
0114      */
0115     virtual bt::Uint32 averageDownloadSpeed() const = 0;
0116 
0117     /// Get the Peer's BitSet
0118     const BitSet &getBitSet() const
0119     {
0120         return pieces;
0121     }
0122 
0123     /// Get the Peer's ID
0124     const PeerID &getPeerID() const
0125     {
0126         return peer_id;
0127     }
0128 
0129     /// Is the Peer choked
0130     bool isChoked() const
0131     {
0132         return stats.choked;
0133     }
0134 
0135     /// Is the Peer interested
0136     bool isInterested() const
0137     {
0138         return stats.interested;
0139     }
0140 
0141     /// Are we interested in the Peer
0142     bool areWeInterested() const
0143     {
0144         return stats.am_interested;
0145     }
0146 
0147     /// Are we choked for the Peer
0148     bool areWeChoked() const
0149     {
0150         return !stats.has_upload_slot || paused;
0151     }
0152 
0153     /// See if the peer supports DHT
0154     bool isDHTSupported() const
0155     {
0156         return stats.dht_support;
0157     }
0158 
0159     /// Get the time when this Peer choked us
0160     TimeStamp getChokeTime() const
0161     {
0162         return stats.time_choked;
0163     }
0164 
0165     /// Get the time when this Peer unchoked us
0166     TimeStamp getUnchokeTime() const
0167     {
0168         return stats.time_unchoked;
0169     }
0170 
0171     /// See if the peer is a seeder.
0172     bool isSeeder() const
0173     {
0174         return pieces.allOn();
0175     }
0176 
0177     /// Peer is allowed to download chunk (used for superseeding)
0178     virtual void chunkAllowed(bt::Uint32 chunk) = 0;
0179 
0180     /// Handle a received packet
0181     virtual void handlePacket(const bt::Uint8 *packet, bt::Uint32 size) = 0;
0182 
0183 protected:
0184     mutable PeerInterface::Stats stats;
0185     bool paused;
0186     bool killed;
0187     PeerID peer_id;
0188     BitSet pieces;
0189 };
0190 
0191 }
0192 
0193 #endif