/* */ #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" namespace aria2 { ActivePeerConnectionCommand::ActivePeerConnectionCommand (int 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.elapsed(interval)) { checkPoint.reset(); 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) { PeerHandle peer = _peerStorage->getUnusedPeer(); connectToPeer(peer); } if(_btRuntime->getConnections() == 0 && !_pieceStorage->downloadFinished()) { _btAnnounce->overrideMinInterval(BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL); } } } e->commands.push_back(this); return false; } void ActivePeerConnectionCommand::connectToPeer(const PeerHandle& 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->commands.push_back(command); logger->info(MSG_CONNECTING_TO_PEER, cuid, peer->ipaddr.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