/* */ #include "PeerAbstractCommand.h" #include "DlAbortEx.h" #include "DlRetryEx.h" #include "Util.h" #include "message.h" #include "prefs.h" PeerAbstractCommand::PeerAbstractCommand(int cuid, const PeerHandle& peer, TorrentDownloadEngine* e, const SocketHandle& s) :Command(cuid), e(e), socket(s), peer(peer), checkSocketIsReadable(false), checkSocketIsWritable(false), uploadLimitCheck(false), uploadLimit(0) { setReadCheckSocket(socket); timeout = e->option->getAsInt(PREF_TIMEOUT); e->torrentMan->connections++; } PeerAbstractCommand::~PeerAbstractCommand() { disableReadCheckSocket(); disableWriteCheckSocket(); e->torrentMan->connections--; } bool PeerAbstractCommand::execute() { if(e->torrentMan->isHalt()) { return true; } try { if(uploadLimitCheck && (uploadLimit == 0 || e->getUploadSpeed() <= uploadLimit*1024) || checkSocketIsReadable && readCheckTarget->isReadable(0) || checkSocketIsWritable && writeCheckTarget->isWritable(0)) { checkPoint.reset(); } if(checkPoint.elapsed(timeout)) { throw new DlRetryEx(EX_TIME_OUT); } return executeInternal(); } catch(Exception* err) { logger->error(MSG_DOWNLOAD_ABORTED, err, cuid); onAbort(err); delete(err); return prepareForNextPeer(0); } } // TODO this method removed when PeerBalancerCommand is implemented bool PeerAbstractCommand::prepareForNextPeer(int wait) { return true; } bool PeerAbstractCommand::prepareForRetry(int wait) { return true; } void PeerAbstractCommand::onAbort(Exception* ex) { if(peer->isSeeder()) { peer->error++; } else { peer->error += MAX_PEER_ERROR; } peer->resetStatus(); logger->debug("CUID#%d - Peer %s:%d banned.", cuid, peer->ipaddr.c_str(), peer->port); } void PeerAbstractCommand::disableReadCheckSocket() { if(checkSocketIsReadable) { e->deleteSocketForReadCheck(readCheckTarget, getUuid()); checkSocketIsReadable = false; readCheckTarget = SocketHandle(); } } void PeerAbstractCommand::setReadCheckSocket(const SocketHandle& socket) { if(!socket->isOpen()) { disableReadCheckSocket(); } else { if(checkSocketIsReadable) { if(readCheckTarget != socket) { e->deleteSocketForReadCheck(readCheckTarget, getUuid()); e->addSocketForReadCheck(socket, getUuid()); readCheckTarget = socket; } } else { e->addSocketForReadCheck(socket, getUuid()); checkSocketIsReadable = true; readCheckTarget = socket; } } } void PeerAbstractCommand::disableWriteCheckSocket() { if(checkSocketIsWritable) { e->deleteSocketForWriteCheck(writeCheckTarget, getUuid()); checkSocketIsWritable = false; writeCheckTarget = SocketHandle(); } } void PeerAbstractCommand::setWriteCheckSocket(const SocketHandle& socket) { if(!socket->isOpen()) { disableWriteCheckSocket(); } else { if(checkSocketIsWritable) { if(writeCheckTarget != socket) { e->deleteSocketForWriteCheck(writeCheckTarget, getUuid()); e->addSocketForWriteCheck(socket, getUuid()); writeCheckTarget = socket; } } else { e->addSocketForWriteCheck(socket, getUuid()); checkSocketIsWritable = true; writeCheckTarget = socket; } } } void PeerAbstractCommand::setUploadLimit(int uploadLimit) { this->uploadLimit = uploadLimit; } void PeerAbstractCommand::setUploadLimitCheck(bool check) { this->uploadLimitCheck = check; }