2009-07-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Disconnect seeder if client is also in seed state.
	* src/BtBitfieldMessage.cc
	* src/BtHaveAllMessage.cc
	* src/BtHaveMessage.cc
	* src/message.h
	* test/BtBitfieldMessageTest.cc
	* test/BtHaveAllMessageTest.cc
	* test/BtHaveMessageTest.cc
	* test/MockPieceStorage.h
pull/1/head
Tatsuhiro Tsujikawa 2009-07-06 15:22:06 +00:00
parent db84b1b652
commit 5f966f6327
9 changed files with 145 additions and 7 deletions

View File

@ -1,3 +1,15 @@
2009-07-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Disconnect seeder if client is also in seed state.
* src/BtBitfieldMessage.cc
* src/BtHaveAllMessage.cc
* src/BtHaveMessage.cc
* src/message.h
* test/BtBitfieldMessageTest.cc
* test/BtHaveAllMessageTest.cc
* test/BtHaveMessageTest.cc
* test/MockPieceStorage.h
2009-07-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Keep CreateRequestCommand in queue when no segment is available so

View File

@ -73,6 +73,9 @@ BtBitfieldMessage::create(const unsigned char* data, size_t dataLength)
void BtBitfieldMessage::doReceivedAction() {
pieceStorage->updatePieceStats(bitfield, bitfieldLength, peer->getBitfield());
peer->setBitfield(bitfield, bitfieldLength);
if(peer->isSeeder() && pieceStorage->downloadFinished()) {
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
}
}
const unsigned char* BtBitfieldMessage::getMessage() {

View File

@ -37,6 +37,7 @@
#include "Peer.h"
#include "StringFormat.h"
#include "PieceStorage.h"
#include "message.h"
namespace aria2 {
@ -59,6 +60,9 @@ void BtHaveAllMessage::doReceivedAction()
peer->getBitfieldLength());
peer->setAllBitfield();
pieceStorage->addPieceStats(peer->getBitfield(), peer->getBitfieldLength());
if(peer->isSeeder() && pieceStorage->downloadFinished()) {
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
}
}
} // namespace aria2

View File

@ -35,6 +35,8 @@
#include "BtHaveMessage.h"
#include "Peer.h"
#include "PieceStorage.h"
#include "message.h"
#include "DlAbortEx.h"
namespace aria2 {
@ -50,6 +52,9 @@ void BtHaveMessage::doReceivedAction()
{
peer->updateBitfield(getIndex(), 1);
pieceStorage->addPieceStats(getIndex());
if(peer->isSeeder() && pieceStorage->downloadFinished()) {
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
}
}
} // namespace aria2

View File

@ -172,6 +172,7 @@
" file. Skipping.")
#define MSG_GID_NOT_PROVIDED "GID is not provided."
#define MSG_CANNOT_PARSE_XML_RPC_REQUEST "Failed to parse xml-rpc request."
#define MSG_GOOD_BYE_SEEDER "Client is in seed state: Good Bye Seeder;)"
#define EX_TIME_OUT _("Timeout.")
#define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")

View File

@ -1,10 +1,14 @@
#include "BtBitfieldMessage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "PeerMessageUtil.h"
#include "Util.h"
#include "Peer.h"
#include "MockPieceStorage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "DlAbortEx.h"
namespace aria2 {
@ -14,6 +18,7 @@ class BtBitfieldMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreate);
CPPUNIT_TEST(testGetMessage);
CPPUNIT_TEST(testDoReceivedAction);
CPPUNIT_TEST(testDoReceivedAction_goodByeSeeder);
CPPUNIT_TEST(testToString);
CPPUNIT_TEST_SUITE_END();
private:
@ -25,6 +30,7 @@ public:
void testCreate();
void testGetMessage();
void testDoReceivedAction();
void testDoReceivedAction_goodByeSeeder();
void testToString();
};
@ -87,6 +93,41 @@ void BtBitfieldMessageTest::testDoReceivedAction() {
peer->getBitfieldLength()));
}
void BtBitfieldMessageTest::testDoReceivedAction_goodByeSeeder()
{
SharedHandle<Peer> peer(new Peer("ip", 6000));
peer->allocateSessionResource(1024, 1024);
BtBitfieldMessage msg;
msg.setPeer(peer);
SharedHandle<MockPieceStorage> pieceStorage(new MockPieceStorage());
msg.setPieceStorage(pieceStorage);
unsigned char bitfield[] = { 0x00 };
msg.setBitfield(bitfield, sizeof(bitfield));
// peer is not seeder and client have not completed download
msg.doReceivedAction();
pieceStorage->setDownloadFinished(true);
// client completed download, but peer is not seeder
msg.doReceivedAction();
pieceStorage->setDownloadFinished(false);
bitfield[0] = 0x80;
msg.setBitfield(bitfield, sizeof(bitfield));
// peer is seeder, but client have not completed download
msg.doReceivedAction();
pieceStorage->setDownloadFinished(true);
try {
msg.doReceivedAction();
CPPUNIT_FAIL("exception must be thrown.");
} catch(DlAbortEx& e) {
// success
}
}
void BtBitfieldMessageTest::testToString() {
BtBitfieldMessage msg;
unsigned char bitfield[] = { 0xff, 0xff };

View File

@ -1,9 +1,13 @@
#include "BtHaveAllMessage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "PeerMessageUtil.h"
#include "Peer.h"
#include "MockPieceStorage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "DlAbortEx.h"
namespace aria2 {
@ -13,6 +17,7 @@ class BtHaveAllMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreate);
CPPUNIT_TEST(testGetMessage);
CPPUNIT_TEST(testDoReceivedAction);
CPPUNIT_TEST(testDoReceivedAction_goodByeSeeder);
CPPUNIT_TEST_SUITE_END();
private:
@ -23,6 +28,7 @@ public:
void testCreate();
void testGetMessage();
void testDoReceivedAction();
void testDoReceivedAction_goodByeSeeder();
};
@ -80,4 +86,24 @@ void BtHaveAllMessageTest::testDoReceivedAction() {
} catch(...) {}
}
void BtHaveAllMessageTest::testDoReceivedAction_goodByeSeeder()
{
BtHaveAllMessage msg;
SharedHandle<Peer> peer(new Peer("ip", 6000));
peer->allocateSessionResource(1024, 1024);
peer->setFastExtensionEnabled(true);
msg.setPeer(peer);
SharedHandle<MockPieceStorage> pieceStorage(new MockPieceStorage());
msg.setPieceStorage(pieceStorage);
pieceStorage->setDownloadFinished(true);
try {
msg.doReceivedAction();
CPPUNIT_FAIL("exception must be thrown.");
} catch(DlAbortEx& e) {
// success
}
}
} // namespace aria2

View File

@ -1,9 +1,13 @@
#include "BtHaveMessage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "PeerMessageUtil.h"
#include "Peer.h"
#include "MockPieceStorage.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
#include "DlAbortEx.h"
namespace aria2 {
@ -13,6 +17,7 @@ class BtHaveMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreate);
CPPUNIT_TEST(testGetMessage);
CPPUNIT_TEST(testDoReceivedAction);
CPPUNIT_TEST(testDoReceivedAction_goodByeSeeder);
CPPUNIT_TEST(testToString);
CPPUNIT_TEST_SUITE_END();
private:
@ -24,6 +29,7 @@ public:
void testCreate();
void testGetMessage();
void testDoReceivedAction();
void testDoReceivedAction_goodByeSeeder();
void testToString();
};
@ -80,6 +86,39 @@ void BtHaveMessageTest::testDoReceivedAction() {
CPPUNIT_ASSERT(peer->hasPiece(msg.getIndex()));
}
void BtHaveMessageTest::testDoReceivedAction_goodByeSeeder()
{
SharedHandle<Peer> peer(new Peer("ip", 6000));
peer->allocateSessionResource(1024, 2*1024);
BtHaveMessage msg;
msg.setIndex(0);
msg.setPeer(peer);
SharedHandle<MockPieceStorage> pieceStorage(new MockPieceStorage());
msg.setPieceStorage(pieceStorage);
// peer is not seeder and client have not completed download
msg.doReceivedAction();
pieceStorage->setDownloadFinished(true);
// client have completed download but, peer is not seeder
msg.doReceivedAction();
msg.setIndex(1);
pieceStorage->setDownloadFinished(false);
// peer is a seeder but client have not completed download
msg.doReceivedAction();
pieceStorage->setDownloadFinished(true);
try {
msg.doReceivedAction();
CPPUNIT_FAIL("exception must be thrown.");
} catch(DlAbortEx& e) {
// success
}
}
void BtHaveMessageTest::testToString() {
BtHaveMessage msg;

View File

@ -23,6 +23,7 @@ private:
SharedHandle<DiskAdaptor> diskAdaptor;
std::deque<size_t> pieceLengthList;
std::deque<SharedHandle<Piece> > inFlightPieces;
bool _downloadFinished;
bool _allDownloadFinished;
public:
MockPieceStorage():totalLength(0),
@ -32,6 +33,7 @@ public:
bitfieldMan(0),
selectiveDownloadingMode(false),
endGame(false),
_downloadFinished(false),
_allDownloadFinished(false) {}
virtual ~MockPieceStorage() {}
@ -133,7 +135,12 @@ public:
virtual void clearFileFilter() {}
virtual bool downloadFinished() {
return false;
return _downloadFinished;
}
void setDownloadFinished(bool f)
{
_downloadFinished = f;
}
virtual bool allDownloadFinished() {