From e6e017756096d53417622c0a4048d1dfb4340f49 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 31 Mar 2006 13:58:22 +0000 Subject: [PATCH] * src/PeerInteractionCommand.cc (checkInactiveConnection): New function (detectMessageFlooding): Updated. (checkLongTimePeerChoking): Updated. (getNewPieceAndSendInterest): Added debug log. * src/PeerInteractionCommand.h: New function checkInactiveConnection() * src/TorrentMan.cc (deleteOldErrorPeers): Updated. (getPeer): Updated. * src/TorrentMan.h: Added MAX_PEER_ERROR. * src/PeerAbstractCommand.cc (onAbort): Increment error counter. * src/PeerListenCommand.cc (execute): Close connection if incoming peer is localhost. * src/main.cc (main): Updated PREF_PEER_CONNECTION_TIMEOUT to 60. * src/PendingMessage.cc (processMessage): Not to send piece message if peer is not interested in the pieces localhost has. * src/Peer.cc (shouldChoke): Updated. * src/SendMessageQueue.cc (cancelAllRequest): Fixed. --- ChangeLog | 26 ++++++++++++++++++++++++++ TODO | 5 ++--- src/BitfieldMan.h | 3 +++ src/Peer.cc | 8 ++++++++ src/Peer.h | 2 ++ src/PeerAbstractCommand.cc | 6 +++++- src/PeerInteractionCommand.cc | 17 +++++++++++++++-- src/PeerInteractionCommand.h | 1 + src/PeerListenCommand.cc | 5 ++++- src/PendingMessage.cc | 4 +++- src/SendMessageQueue.cc | 2 +- src/TorrentMan.cc | 4 ++-- src/TorrentMan.h | 1 + src/main.cc | 2 +- 14 files changed, 74 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f1643b6..77dcdee8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2006-03-31 Tatsuhiro Tsujikawa + + * src/PeerInteractionCommand.cc (checkInactiveConnection): New function + (detectMessageFlooding): Updated. + (checkLongTimePeerChoking): Updated. + (getNewPieceAndSendInterest): Added debug log. + * src/PeerInteractionCommand.h: New function checkInactiveConnection() + + * src/TorrentMan.cc (deleteOldErrorPeers): Updated. + (getPeer): Updated. + * src/TorrentMan.h: Added MAX_PEER_ERROR. + + * src/PeerAbstractCommand.cc (onAbort): Increment error counter. + + * src/PeerListenCommand.cc (execute): Close connection if incoming peer + is localhost. + + * src/main.cc (main): Updated PREF_PEER_CONNECTION_TIMEOUT to 60. + + * src/PendingMessage.cc (processMessage): Not to send piece message + if peer is not interested in the pieces localhost has. + + * src/Peer.cc (shouldChoke): Updated. + + * src/SendMessageQueue.cc (cancelAllRequest): Fixed. + 2006-03-28 Tatsuhiro Tsujikawa Added new class SendMessageQueue that includes PendingMessages and diff --git a/TODO b/TODO index 2f344b4d..8e7fed30 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,5 @@ * Add port range command-line option * Add max peers command-line option * Distinguish seeder from leecher -* time out for connecting peers -* ignore incoming connection from localhost. -* do not connect to localhost +* file selection in multi-file mode +* try to use ftruncate to allocate file. \ No newline at end of file diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h index ec8dcafc..3f8165ae 100644 --- a/src/BitfieldMan.h +++ b/src/BitfieldMan.h @@ -87,6 +87,9 @@ public: void clearAllBit(); void setAllBit(); + + void addFilter(long long int offset, long long int length); + void clearFilter(); }; #endif // _D_BITFIELD_MAN_H_ diff --git a/src/Peer.cc b/src/Peer.cc index fca917d3..f9b8fbe5 100644 --- a/src/Peer.cc +++ b/src/Peer.cc @@ -40,6 +40,10 @@ bool Peer::shouldChoke() const { if(peerDownload <= pieceLength*10) { return false; } + // we are always optimistic. + if(amInterested && peerInterested) { + return false; + } if(amChocking) { return !(peerDownload+pieceLength*5 < peerUpload); } else { @@ -50,3 +54,7 @@ bool Peer::shouldChoke() const { bool Peer::hasPiece(int index) const { return bitfield->isBitSet(index); } + +bool Peer::isSeeder() const { + return bitfield->isAllBitSet(); +} diff --git a/src/Peer.h b/src/Peer.h index 98f5ef59..41b323ac 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -111,6 +111,8 @@ public: bool hasPiece(int index) const; + bool isSeeder() const; + static Peer* nullPeer; }; diff --git a/src/PeerAbstractCommand.cc b/src/PeerAbstractCommand.cc index 269d4411..384ae0e7 100644 --- a/src/PeerAbstractCommand.cc +++ b/src/PeerAbstractCommand.cc @@ -125,7 +125,11 @@ bool PeerAbstractCommand::prepareForRetry(int wait) { } void PeerAbstractCommand::onAbort(Exception* ex) { - peer->error = 1; + if(peer->isSeeder()) { + peer->error++; + } else { + peer->error += MAX_PEER_ERROR; + } peer->tryCount = 0; peer->cuid = 0; peer->amChocking = true; diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index b1021df6..a5569dbb 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -107,6 +107,7 @@ bool PeerInteractionCommand::executeInternal() { case WIRED: detectMessageFlooding(); checkLongTimePeerChoking(); + checkInactiveConnection(); syncPiece(); decideChoking(); for(int i = 0; i < 10; i++) { @@ -128,6 +129,16 @@ bool PeerInteractionCommand::executeInternal() { return false; } +void PeerInteractionCommand::checkInactiveConnection() { + if((!peer->amInterested && !peer->peerInterested && + e->torrentMan->connections >= MAX_PEER_LIST_SIZE) || + (!peer->amInterested && e->torrentMan->connections >= MAX_PEER_LIST_SIZE && + e->torrentMan->isEndGame())) { + throw new DlAbortEx("marked as inactive connection."); + } + +} + void PeerInteractionCommand::detectMessageFlooding() { struct timeval now; gettimeofday(&now, NULL); @@ -135,7 +146,7 @@ void PeerInteractionCommand::detectMessageFlooding() { freqCheckPoint = now; } else { if(Util::difftv(now, freqCheckPoint) >= 5*1000000) { - if(chokeUnchokeCount*1.0/(Util::difftv(now, freqCheckPoint)/1000000) >= 0.3 + if(chokeUnchokeCount*1.0/(Util::difftv(now, freqCheckPoint)/1000000) >= 0.4 || haveCount*1.0/(Util::difftv(now, freqCheckPoint)/1000000) >= 20.0) { throw new DlAbortEx("flooding detected."); } else { @@ -159,7 +170,7 @@ void PeerInteractionCommand::checkLongTimePeerChoking() { } } else { if(peer->amInterested && peer->peerChoking) { - if(Util::difftv(now, chokeCheckPoint) >= 5*60*1000000) { + if(Util::difftv(now, chokeCheckPoint) >= 3*60*1000000) { throw new DlAbortEx("too long choking"); } } else { @@ -325,6 +336,7 @@ Piece PeerInteractionCommand::getNewPieceAndSendInterest() { PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection); sendMessageQueue->addPendingMessage(pendingMessage); } else { + e->logger->debug("CUID#%d - starting download for piece #%d", cuid, piece.getIndex()); e->logger->debug("CUID#%d - try to send interested", cuid); PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection); sendMessageQueue->addPendingMessage(pendingMessage); @@ -404,6 +416,7 @@ void PeerInteractionCommand::beforeSocketCheck() { e->torrentMan->unadvertisePiece(cuid); detectMessageFlooding(); checkLongTimePeerChoking(); + checkInactiveConnection(); PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid); if(indexes.size() >= 20) { diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h index 48c5246d..3950c6ba 100644 --- a/src/PeerInteractionCommand.h +++ b/src/PeerInteractionCommand.h @@ -42,6 +42,7 @@ private: void receiveMessage(); void detectMessageFlooding(); void checkLongTimePeerChoking(); + void checkInactiveConnection(); void syncPiece(); void detectTimeoutAndDuplicateBlock(); void decideChoking(); diff --git a/src/PeerListenCommand.cc b/src/PeerListenCommand.cc index 79ee2a87..eb666b70 100644 --- a/src/PeerListenCommand.cc +++ b/src/PeerListenCommand.cc @@ -61,7 +61,10 @@ bool PeerListenCommand::execute() { peerSocket = socket->acceptConnection(); pair peerInfo; peerSocket->getPeerInfo(peerInfo); - if(e->torrentMan->connections < MAX_PEERS) { + pair localInfo; + peerSocket->getAddrInfo(localInfo); + if(peerInfo.first != localInfo.first && + e->torrentMan->connections < MAX_PEERS) { Peer* peer = new Peer(peerInfo.first, peerInfo.second, e->torrentMan->pieceLength, e->torrentMan->totalSize); diff --git a/src/PendingMessage.cc b/src/PendingMessage.cc index ba1c5ab9..f478fa3a 100644 --- a/src/PendingMessage.cc +++ b/src/PendingMessage.cc @@ -57,11 +57,13 @@ bool PendingMessage::processMessage() { } break; case PeerMessage::PIECE: - if(!peerConnection->getPeer()->amChocking) { + if((!peerConnection->getPeer()->amChocking && + peerConnection->getPeer()->peerInterested) || inProgress) { if(!inProgress) { peerConnection->sendPieceHeader(index, begin, length); peerConnection->getPeer()->addPeerDownload(length); } + inProgress = false; int writtenLength = peerConnection->sendPieceData(pieceDataOffset, leftPieceDataLength); if(writtenLength != leftPieceDataLength) { inProgress = true; diff --git a/src/SendMessageQueue.cc b/src/SendMessageQueue.cc index e03c9571..69e44b25 100644 --- a/src/SendMessageQueue.cc +++ b/src/SendMessageQueue.cc @@ -110,7 +110,7 @@ void SendMessageQueue::cancelAllRequest() { void SendMessageQueue::cancelAllRequest(Piece& piece) { deletePendingRequestMessage(); - requestSlotMan->deleteAllRequestSlot(Piece::nullPiece); + requestSlotMan->deleteAllRequestSlot(piece); } int SendMessageQueue::countPendingMessage() const { diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index 1cd89d97..0630c434 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -109,7 +109,7 @@ int TorrentMan::deleteOldErrorPeers(int maxNum) { int counter = 0; for(Peers::iterator itr = peers.begin(); itr != peers.end();) { Peer* p = *itr; - if(p->error != 0 && p->cuid == 0) { + if(p->error >= MAX_PEER_ERROR && p->cuid == 0) { delete p; itr = peers.erase(itr); counter++; @@ -126,7 +126,7 @@ int TorrentMan::deleteOldErrorPeers(int maxNum) { Peer* TorrentMan::getPeer() const { for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); itr++) { Peer* p = *itr; - if(p->cuid == 0 && p->error == 0) { + if(p->cuid == 0 && p->error < MAX_PEER_ERROR) { return p; } } diff --git a/src/TorrentMan.h b/src/TorrentMan.h index 4e47525c..d8be9d69 100644 --- a/src/TorrentMan.h +++ b/src/TorrentMan.h @@ -49,6 +49,7 @@ using namespace std; #define MAX_PEER_LIST_SIZE 250 #define END_GAME_PIECE_NUM 20 +#define MAX_PEER_ERROR 5 class FileEntry { public: diff --git a/src/main.cc b/src/main.cc index e3493809..645c1768 100644 --- a/src/main.cc +++ b/src/main.cc @@ -242,7 +242,7 @@ int main(int argc, char* argv[]) { Option* op = new Option(); op->put(PREF_RETRY_WAIT, "5"); op->put(PREF_TIMEOUT, "60"); - op->put(PREF_PEER_CONNECTION_TIMEOUT, "30"); + op->put(PREF_PEER_CONNECTION_TIMEOUT, "60"); op->put(PREF_MIN_SEGMENT_SIZE, "1048576");// 1M op->put(PREF_MAX_TRIES, "5"); op->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);