/* */ #include "ActivePeerConnectionCommand.h" #include "PeerInitiateConnectionCommand.h" #include "message.h" #include "DownloadEngine.h" #include "PeerStorage.h" #include "PieceStorage.h" #include "BtRuntime.h" #include "Peer.h" #include "Logger.h" #include "prefs.h" #include "Option.h" #include "BtConstants.h" #include "SocketCore.h" #include "BtAnnounce.h" #include "RequestGroup.h" #include "DownloadContext.h" #include "bittorrent_helper.h" #include "wallclock.h" #include "util.h" #include "RequestGroupMan.h" #include "FileAllocationEntry.h" #include "CheckIntegrityEntry.h" #include "ServerStatMan.h" namespace aria2 { ActivePeerConnectionCommand::ActivePeerConnectionCommand (cuid_t cuid, RequestGroup* requestGroup, DownloadEngine* e, time_t interval) : Command(cuid), _requestGroup(requestGroup), _interval(interval), _e(e), _numNewConnection(5) { _requestGroup->increaseNumCommand(); } ActivePeerConnectionCommand::~ActivePeerConnectionCommand() { _requestGroup->decreaseNumCommand(); } bool ActivePeerConnectionCommand::execute() { if(_btRuntime->isHalt()) { return true; } if(_checkPoint.difference(global::wallclock) >= _interval) { _checkPoint = global::wallclock; TransferStat tstat = _requestGroup->calculateStat(); const unsigned int maxDownloadLimit = _requestGroup->getMaxDownloadSpeedLimit(); const unsigned int maxUploadLimit = _requestGroup->getMaxUploadSpeedLimit(); unsigned int thresholdSpeed; if(_requestGroup->getDownloadContext()-> getAttribute(bittorrent::BITTORRENT).containsKey(bittorrent::METADATA)) { thresholdSpeed = _requestGroup->getOption()->getAsInt(PREF_BT_REQUEST_PEER_SPEED_LIMIT); } else { thresholdSpeed = 0; } if(maxDownloadLimit > 0) { thresholdSpeed = std::min(maxDownloadLimit, thresholdSpeed); } if(// for seeder state (_pieceStorage->downloadFinished() && _btRuntime->lessThanMaxPeers() && (maxUploadLimit == 0 || tstat.getUploadSpeed() < maxUploadLimit*0.8)) || // for leecher state (!_pieceStorage->downloadFinished() && (tstat.getDownloadSpeed() < thresholdSpeed || _btRuntime->lessThanMinPeers()))) { unsigned int numConnection = 0; if(_pieceStorage->downloadFinished()) { if(_btRuntime->getMaxPeers() > _btRuntime->getConnections()) { numConnection = std::min(_numNewConnection, _btRuntime->getMaxPeers()-_btRuntime->getConnections()); } } else { numConnection = _numNewConnection; } for(unsigned int numAdd = numConnection; numAdd > 0 && _peerStorage->isPeerAvailable(); --numAdd) { SharedHandle peer = _peerStorage->getUnusedPeer(); connectToPeer(peer); } if(_btRuntime->getConnections() == 0 && !_pieceStorage->downloadFinished()) { _btAnnounce->overrideMinInterval(BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL); } } } _e->addCommand(this); return false; } void ActivePeerConnectionCommand::connectToPeer(const SharedHandle& peer) { if(peer.isNull()) { return; } peer->usedBy(_e->newCUID()); PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer, _e, _btRuntime); command->setPeerStorage(_peerStorage); command->setPieceStorage(_pieceStorage); _e->addCommand(command); if(getLogger()->info()) { getLogger()->info(MSG_CONNECTING_TO_PEER, util::itos(getCuid()).c_str(), peer->getIPAddress().c_str()); } } void ActivePeerConnectionCommand::setBtRuntime (const SharedHandle& btRuntime) { _btRuntime = btRuntime; } void ActivePeerConnectionCommand::setPieceStorage (const SharedHandle& pieceStorage) { _pieceStorage = pieceStorage; } void ActivePeerConnectionCommand::setPeerStorage (const SharedHandle& peerStorage) { _peerStorage = peerStorage; } void ActivePeerConnectionCommand::setBtAnnounce (const SharedHandle& btAnnounce) { _btAnnounce = btAnnounce; } } // namespace aria2