/* */ #include "ActivePeerConnectionCommand.h" #include "PeerInitiateConnectionCommand.h" #include "CUIDCounter.h" #include "message.h" #include "DownloadEngine.h" #include "BtContext.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" namespace aria2 { ActivePeerConnectionCommand::ActivePeerConnectionCommand(int cuid, RequestGroup* requestGroup, DownloadEngine* e, const BtContextHandle& btContext, time_t interval) :Command(cuid), BtContextAwareCommand(btContext), RequestGroupAware(requestGroup), interval(interval), e(e), _thresholdSpeed(e->option->getAsInt(PREF_BT_REQUEST_PEER_SPEED_LIMIT)), _maxUploadSpeedLimit(e->option->getAsInt(PREF_MAX_UPLOAD_LIMIT)), _numNewConnection(5) { unsigned int maxDownloadSpeed = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT); if(maxDownloadSpeed > 0) { _thresholdSpeed = std::min(maxDownloadSpeed, _thresholdSpeed); } } ActivePeerConnectionCommand::~ActivePeerConnectionCommand() {} bool ActivePeerConnectionCommand::execute() { if(btRuntime->isHalt()) { return true; } if(checkPoint.elapsed(interval)) { checkPoint.reset(); TransferStat tstat = _requestGroup->calculateStat(); if(// for seeder state (pieceStorage->downloadFinished() && btRuntime->lessThanMaxPeers() && (_maxUploadSpeedLimit == 0 || tstat.getUploadSpeed() < _maxUploadSpeedLimit*0.8)) || // for leecher state (!pieceStorage->downloadFinished() && (tstat.getDownloadSpeed() < _thresholdSpeed || btRuntime->lessThanMinPeers()))) { unsigned int numConnection = pieceStorage->downloadFinished() ? std::min(_numNewConnection, BtRuntime::MAX_PEERS-btRuntime->getConnections()) : _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(CUIDCounterSingletonHolder::instance()->newID()); PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer, e, btContext); e->commands.push_back(command); logger->info(MSG_CONNECTING_TO_PEER, cuid, peer->ipaddr.c_str()); } } // namespace aria2