From d380b7b6abe016dd0334b18972ce08a4fa92a934 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 12 Jun 2006 16:55:08 +0000 Subject: 2006-06-12 Tatsuhiro Tsujikawa To add Time class which represents a specific instant in time and its precision is microseconds. Time checking procedures were rewritten using this object. * src/Time.h: New class. * src/Time.cc: New class. * src/AbstractCommand.h (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (checkPoint): Changed the type to Time. (timeout): New variable. (setTimeout): New function. * src/AbstractCommand.cc (AbstractCommand): Removed the initialization of checkPoint. Added the initialization of timeout. (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (execute): Use checkPoint.reset() and checkPoint.elapsed(). * src/PeerChokeCommand.h (checkPoint): Changed the type to Time. * src/PeerChokeCommand.cc (PeerChokeCommand): Removed the initialization of checkPoint. (execute): Rewritten using Time object. * src/TrackerWatcherCommand.h (checkPoint): Changed the type to Time. * src/TrackerWatcherCommand.cc (TrackerWatcherCommand): Removed the initialization of checkPoint. (execute): Rewritten. * src/ConsoleDownloadEngine.h (cp): Changed the type to Time. (startup): Changed the type to Time. * src/ConsoleDownloadEngine.cc (initStatistics): Use cp.reset(), startup.reset(). (calculateStatistics): Rewritten using Time object. * src/PeerAbstractCommand.h (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (checkPoint): Changed the type to Time. * src/PeerAbstractCommand.cc (PeerAbstractCommand): Removed the initialization of checkPoint. (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (execute): Use checkPoint.reset() and checkPoint.elapsed(). * src/PeerInteractionCommand.cc (PeerInteractionCommand): Removed the initializations of struct timeval variables. * src/PeerInteractionCommand.h (keepAliveCheckPoint): Changed the type to Time. (chokeCheckPoint): Changed the type to Time. (freqCheckPoint): Changed the type to Time. (haveCheckTime): Changed the type to Time. * src/PeerInteractionCommand.cc (executeInternal): Rewritten using Time object. (detectMessageFlooding): Rewritten using Time object. (checkLongTimePeerChoking): Rewritten using Time object. (sendKeepAlive): Rewritten using Time object. (checkHave): Rewritten using Time object. * src/SleepCommand.h (checkPoint): Changed the type to Time. * src/SleepCommand.cc (SleepCommand): Removed the initialization of checkPoint. (execute): Rewritten using Time object. * src/TorrentAutoSaveCommand.h (checkPoint): Changed the type to Time. * src/TorrentAutoSaveCommand.cc (TorrentAutoSaveCommand): Removed the initialization of checkPoint. (execute): Rewritten. * src/DownloadCommand.h (sw): Changed the type to Time. * src/DownloadCommand.cc (DownloadCommand): Removed the initialization of sw. (executeInternal): Rewritten. * src/RequestSlot.h (dispatchedTime): Changed the type to Time. * src/RequestSlot.cc (RequestSlot): Removed the call to setDispatchedTime(). (setDispatchedTime): Rewirtten. (isTimeout): Rewritten. (getLatencyInMillis): Rewritten. * src/TorrentDownloadEngine.h (cp): Changed the type to Time[2]. (startup): Changed the type to Time. * src/TorrentDownloadEngine.cc (initStatistics): Rewritten. (calculateStatistics): Rewritten. * src/DownloadEngine.cc (run): Rewritten. To detect all attempts to connect to the tracker are failed: * src/AbstractCommand.cc (execute): Increment e->segmentMan->errors if a command aborted. * src/SegmentMan.h (errors): New variable. * src/SegmentMan.cc (SegmentMan): Added the initialization of errors. (init): Added the initialization of errors. * src/TrackerWatcherCommand.cc (execute): If e->segmentMan->errors > 0 then assume that the tracker request was failed. To handle snubbed peers: * src/PeerChokeCommand.cc (optUnchokingPeer): Snubbed peers don't get unchoked. (execute): Snubbed peers don't get unchoked. * src/PeerInteraction.h (REQUEST_TIME_OUT): Changed the value from 120 to 60. * src/PeerInteraction.cc (checkRequestSlot): A peer get marked as "snubbed" if it doesn't send back the requested 16k block in 60 seconds. * src/PieceMessage.cc (receivedAction): A peer's snubbed state is cleard if it sends the requested 16k block in 60 seconds. * src/Peer.h (snubbing): New variable. * src/Peer.cc (resetStatus): Added snubbed = false. To fix the bug that causes have message is not sent: * src/PeerInteractionCommand.cc (~PeerInteractionCommand): Removed e->torrentMan->unadvertisePiece(). (FLOODING_CHECK_INTERVAL): New definition(temporal). (detectMessageFlooding): Use FLOODING_CHECK_INTERVAL. * src/TorrentMan.h (HaveEntry): New class. (advertisePiece): Rewritten. (getAdvertisedPieceIndexes): Rewritten. (Haves): Changed the type. (getAdvertisedPieceIndexes): Added an argument. Others: * src/TorrentMan.h (DEFAULT_ANNOUNCE_INTERVAL): Changed the value to 1800. (DEFAULT_ANNOUNCE_MIN_INTERVAL): Changed the value to 1800. * src/TorrentMan.cc (getPeer): Don't check the number of connections here. (setupInternal1): Changed peerId. * src/PeerInteractionCommand.h (KEEP_ALIVE_INTERVAL): New definition. (sendKeepAlive): Use KEEP_ALIVE_INTERVAL. * src/main.cc (main): SA_ONESHOT was replaced with SA_RESETHAND. * src/DownloadEngine.h: Removed unnecessary header includes. --- src/PeerInteractionCommand.cc | 77 +++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 50 deletions(-) (limited to 'src/PeerInteractionCommand.cc') diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index aafeed58..e6b75b2a 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -41,12 +41,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer, e->torrentMan, this->peer); peerInteraction->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT)); setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT)); - keepAliveCheckPoint.tv_sec = 0; - keepAliveCheckPoint.tv_usec = 0; - chokeCheckPoint.tv_sec = 0; - chokeCheckPoint.tv_usec = 0; - freqCheckPoint.tv_sec = 0; - freqCheckPoint.tv_usec = 0; chokeUnchokeCount = 0; haveCount = 0; keepAliveCount = 0; @@ -55,7 +49,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer, PeerInteractionCommand::~PeerInteractionCommand() { delete peerInteraction; - e->torrentMan->unadvertisePiece(cuid); e->torrentMan->deleteActivePeer(this->peer); } @@ -89,6 +82,7 @@ bool PeerInteractionCommand::executeInternal() { peer->ipaddr.c_str(), peer->port, handshakeMessage->toString().c_str()); delete handshakeMessage; + haveCheckTime.reset(); peerInteraction->sendBitfield(); peerInteraction->sendAllowedFast(); sequence = WIRED; @@ -105,6 +99,7 @@ bool PeerInteractionCommand::executeInternal() { handshakeMessage->toString().c_str()); delete handshakeMessage; peerInteraction->sendHandshake(); + haveCheckTime.reset(); peerInteraction->sendBitfield(); peerInteraction->sendAllowedFast(); sequence = WIRED; @@ -134,24 +129,19 @@ bool PeerInteractionCommand::executeInternal() { return false; } +#define FLOODING_CHECK_INTERVAL 5 + void PeerInteractionCommand::detectMessageFlooding() { - struct timeval now; - gettimeofday(&now, NULL); - if(freqCheckPoint.tv_sec == 0 && freqCheckPoint.tv_usec == 0) { - freqCheckPoint = now; - } else { - int elapsed = Util::difftvsec(now, freqCheckPoint); - if(elapsed >= 5) { - if(chokeUnchokeCount*1.0/elapsed >= 0.4 - //|| haveCount*1.0/elapsed >= 20.0 - || keepAliveCount*1.0/elapsed >= 1.0) { - throw new DlAbortEx("Flooding detected."); - } else { - chokeUnchokeCount = 0; - haveCount = 0; - keepAliveCount = 0; - freqCheckPoint = now; - } + if(freqCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) { + if(chokeUnchokeCount*1.0/FLOODING_CHECK_INTERVAL >= 0.4 + //|| haveCount*1.0/elapsed >= 20.0 + || keepAliveCount*1.0/FLOODING_CHECK_INTERVAL >= 1.0) { + throw new DlAbortEx("Flooding detected."); + } else { + chokeUnchokeCount = 0; + haveCount = 0; + keepAliveCount = 0; + freqCheckPoint.reset(); } } } @@ -160,21 +150,13 @@ void PeerInteractionCommand::checkLongTimePeerChoking() { if(e->torrentMan->downloadComplete()) { return; } - struct timeval now; - gettimeofday(&now, NULL); - if(chokeCheckPoint.tv_sec == 0 && chokeCheckPoint.tv_usec == 0) { - if(peer->amInterested && peer->peerChoking) { - chokeCheckPoint = now; + if(peer->amInterested && peer->peerChoking) { + if(chokeCheckPoint.elapsed(MAX_PEER_CHOKING_INTERVAL)) { + logger->info("CUID#%d - The peer is choking too long.", cuid); + peer->snubbing = true; } } else { - if(peer->amInterested && peer->peerChoking) { - if(Util::difftvsec(now, chokeCheckPoint) >= MAX_PEER_CHOKING_INTERVAL) { - throw new DlAbortEx("Too long choking."); - } - } else { - chokeCheckPoint.tv_sec = 0; - chokeCheckPoint.tv_usec = 0; - } + chokeCheckPoint.reset(); } } @@ -251,24 +233,19 @@ void PeerInteractionCommand::onAbort(Exception* ex) { } void PeerInteractionCommand::sendKeepAlive() { - if(keepAliveCheckPoint.tv_sec == 0 && keepAliveCheckPoint.tv_usec == 0) { - gettimeofday(&keepAliveCheckPoint, NULL); - } else { - struct timeval now; - gettimeofday(&now, NULL); - if(Util::difftvsec(now, keepAliveCheckPoint) >= 120) { - if(peerInteraction->countMessageInQueue() == 0) { - peerInteraction->addMessage(peerInteraction->createKeepAliveMessage()); - peerInteraction->sendMessages(e->getUploadSpeed()); - } - keepAliveCheckPoint = now; + if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) { + if(peerInteraction->countMessageInQueue() == 0) { + peerInteraction->addMessage(peerInteraction->createKeepAliveMessage()); + peerInteraction->sendMessages(e->getUploadSpeed()); } + keepAliveCheckPoint.reset(); } } void PeerInteractionCommand::checkHave() { - e->torrentMan->unadvertisePiece(cuid); - PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid); + PieceIndexes indexes = + e->torrentMan->getAdvertisedPieceIndexes(cuid, haveCheckTime); + haveCheckTime.reset(); if(indexes.size() >= 20) { if(peer->isFastExtensionEnabled()) { if(e->torrentMan->hasAllPieces()) { -- cgit