/* */ #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(!bittorrent::getTorrentAttrs (requestGroup_->getDownloadContext())->metadata.empty()) { 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