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