/* */ #ifndef _D_PEER_H_ #define _D_PEER_H_ #include "common.h" #include #include #include #include #include "SharedHandle.h" #include "TimeA2.h" #include "BtConstants.h" #include "PeerStat.h" #include "a2functional.h" #include "Command.h" namespace aria2 { class PeerSessionResource; class BtMessageDispatcher; class Peer { public: std::string ipaddr; // TCP port of the other end of communication. If _incoming is // true, then this port is not a port the peer is listening to and // we cannot connect to it. uint16_t port; private: std::string id; cuid_t _cuid; unsigned char _peerId[PEER_ID_LENGTH]; Time _firstContactTime; Time _badConditionStartTime; bool _seeder; PeerSessionResource* _res; // If true, port is assumed not to be a listening port. bool _incoming; // If true, this peer is from local network. bool _localPeer; // Before calling updateSeeder(), make sure that // allocateSessionResource() is called and _res is created. // Otherwise assertion fails. void updateSeeder(); public: Peer(std::string ipaddr, uint16_t port, bool incoming = false); ~Peer(); bool operator==(const Peer& p) { return id == p.id; } bool operator!=(const Peer& p) { return !(*this == p); } void resetStatus(); void usedBy(cuid_t cuid); cuid_t usedBy() const { return _cuid; } bool unused() const { return _cuid == 0; } // Returns true iff _res != 0. bool isActive() const { return _res != 0; } void setPeerId(const unsigned char* peerId); const unsigned char* getPeerId() const { return _peerId; } bool isSeeder() const { return _seeder; } const std::string& getID() const { return id; } void startBadCondition(); bool isGood() const; void allocateSessionResource(size_t pieceLength, uint64_t totalLength); void releaseSessionResource(); const Time& getFirstContactTime() const { return _firstContactTime; } void setFirstContactTime(const Time& time); const Time& getBadConditionStartTime() const { return _badConditionStartTime; } // Before calling following member functions, make sure that // allocateSessionResource() is called and _res is created. // Otherwise assertion fails. // localhost is choking this peer bool amChoking() const; void amChoking(bool b) const; // localhost is interested in this peer bool amInterested() const; void amInterested(bool b) const; // this peer is choking localhost bool peerChoking() const; void peerChoking(bool b) const; // this peer is interested in localhost bool peerInterested() const; void peerInterested(bool b); // this peer should be choked bool chokingRequired() const; void chokingRequired(bool b); // this peer is eligible for unchoking optionally. bool optUnchoking() const; void optUnchoking(bool b); // this peer is snubbing. bool snubbing() const; void snubbing(bool b); void updateUploadLength(size_t bytes); void updateDownloadLength(size_t bytes); /** * Returns the transfer rate from localhost to remote host. */ unsigned int calculateUploadSpeed(); /** * Returns the transfer rate from remote host to localhost. */ unsigned int calculateDownloadSpeed(); /** * Returns the number of bytes uploaded to the remote host. */ uint64_t getSessionUploadLength() const; /** * Returns the number of bytes downloaded from the remote host. */ uint64_t getSessionDownloadLength() const; void setBitfield(const unsigned char* bitfield, size_t bitfieldLength); const unsigned char* getBitfield() const; size_t getBitfieldLength() const; void setAllBitfield(); /** * operation = 1: set index-th bit to 1 * operation = 0: set index-th bit to 0 */ void updateBitfield(size_t index, int operation); void setFastExtensionEnabled(bool enabled); bool isFastExtensionEnabled() const; void addPeerAllowedIndex(size_t index); bool isInPeerAllowedIndexSet(size_t index) const; size_t countPeerAllowedIndexSet() const; const std::vector& getPeerAllowedIndexSet() const; void addAmAllowedIndex(size_t index); bool isInAmAllowedIndexSet(size_t index) const; void setExtendedMessagingEnabled(bool enabled); bool isExtendedMessagingEnabled() const; void setDHTEnabled(bool enabled); bool isDHTEnabled() const; bool shouldBeChoking() const; bool hasPiece(size_t index) const; uint8_t getExtensionMessageID(const std::string& name) const; std::string getExtensionName(uint8_t id) const; void setExtension(const std::string& name, uint8_t id); const Time& getLastDownloadUpdate() const; const Time& getLastAmUnchoking() const; uint64_t getCompletedLength() const; bool isIncomingPeer() const { return _incoming; } void setIncomingPeer(bool incoming); bool isLocalPeer() const { return _localPeer; } void setLocalPeer(bool flag) { _localPeer = flag; } void setBtMessageDispatcher(const WeakHandle& dpt); size_t countOutstandingUpload() const; }; template size_t countSeeder(InputIterator first, InputIterator last) { return std::count_if(first, last, mem_fun_sh(&Peer::isSeeder)); } } // namespace aria2 #endif // _D_PEER_H_