Browse Source

2008-09-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Merged from trunk -r684:691

	Removed wrong comment.
	* src/DefaultPeerStorage.cc

	Moved implementation to SimpleRandomizer.cc from 
SimpleRandomizer.h.
	Added return value of getpid() to argument of srand() to achieve 
more
	randomized value.
	* src/SimpleRandomizer.cc
	* src/SimpleRandomizer.h

	Contact tracker frequently when the number of connections are 0	
and
	download is not finished yet.
	* src/ActivePeerConnectionCommand.cc
	* src/BtAnnounce.h
	* src/DefaultBtAnnounce.cc
	* src/DefaultBtAnnounce.h
	* test/MockBtAnnounce.h
	
	Moved threshold values to UTPexExtensionMessage.
	* src/DefaultBtInteractive.cc
	* src/Peer.cc
	* src/Peer.h
	* src/UTPexExtensionMessage.cc
	* src/UTPexExtensionMessage.h
	* test/UTPexExtensionMessageTest.cc

	Added _incoming member to Peer class and made it true if the 
peer
	initiated connection. Don't add those peer to UTPex message.
	If extended handshake is received, assign _incoming to false.
	* src/DefaultBtInteractive.cc
	* src/HandshakeExtensionMessage.cc
	* src/Peer.cc
	* src/Peer.h
	* src/PeerListenCommand.cc
Tatsuhiro Tsujikawa 17 years ago
parent
commit
f7b6cc766b

+ 38 - 0
ChangeLog

@@ -1,3 +1,41 @@
+2008-09-03  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Merged from trunk -r684:691
+
+	Removed wrong comment.
+	* src/DefaultPeerStorage.cc
+
+	Moved implementation to SimpleRandomizer.cc from SimpleRandomizer.h.
+	Added return value of getpid() to argument of srand() to achieve more
+	randomized value.
+	* src/SimpleRandomizer.cc
+	* src/SimpleRandomizer.h
+
+	Contact tracker frequently when the number of connections are 0	and
+	download is not finished yet.
+	* src/ActivePeerConnectionCommand.cc
+	* src/BtAnnounce.h
+	* src/DefaultBtAnnounce.cc
+	* src/DefaultBtAnnounce.h
+	* test/MockBtAnnounce.h
+	
+	Moved threshold values to UTPexExtensionMessage.
+	* src/DefaultBtInteractive.cc
+	* src/Peer.cc
+	* src/Peer.h
+	* src/UTPexExtensionMessage.cc
+	* src/UTPexExtensionMessage.h
+	* test/UTPexExtensionMessageTest.cc
+
+	Added _incoming member to Peer class and made it true if the peer
+	initiated connection. Don't add those peer to UTPex message.
+	If extended handshake is received, assign _incoming to false.
+	* src/DefaultBtInteractive.cc
+	* src/HandshakeExtensionMessage.cc
+	* src/Peer.cc
+	* src/Peer.h
+	* src/PeerListenCommand.cc
+	
 2008-09-02  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Fixed infinite loop bug in FTP when SIZE command failed.

+ 5 - 0
src/ActivePeerConnectionCommand.cc

@@ -47,6 +47,7 @@
 #include "Option.h"
 #include "BtConstants.h"
 #include "SocketCore.h"
+#include "BtAnnounce.h"
 
 namespace aria2 {
 
@@ -90,6 +91,10 @@ bool ActivePeerConnectionCommand::execute() {
 	PeerHandle peer = peerStorage->getUnusedPeer();
 	connectToPeer(peer);
       }
+      if(btRuntime->getConnections() == 0 &&
+	 !pieceStorage->downloadFinished()) {
+	btAnnounce->overrideMinInterval(BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL);
+      }
     }
   }
   e->commands.push_back(this);

+ 5 - 0
src/BtAnnounce.h

@@ -37,6 +37,7 @@
 
 #include "common.h"
 #include "SharedHandle.h"
+#include "a2time.h"
 #include <string>
 
 namespace aria2 {
@@ -104,6 +105,8 @@ public:
    */
   virtual void shuffleAnnounce() = 0;
 
+  virtual void overrideMinInterval(time_t interval) = 0;
+
   static const std::string FAILURE_REASON;
 
   static const std::string WARNING_MESSAGE;
@@ -119,6 +122,8 @@ public:
   static const std::string INCOMPLETE;
 
   static const std::string PEERS;
+
+  static const unsigned int DEFAULT_ANNOUNCE_INTERVAL = 120;
 };
 
 typedef SharedHandle<BtAnnounce> BtAnnounceHandle;

+ 5 - 0
src/DefaultBtAnnounce.cc

@@ -316,4 +316,9 @@ PeerStorageHandle DefaultBtAnnounce::getPeerStorage() const
   return peerStorage;
 }
 
+void DefaultBtAnnounce::overrideMinInterval(time_t interval)
+{
+  minInterval = interval;
+}
+
 } // namespace aria2

+ 2 - 3
src/DefaultBtAnnounce.h

@@ -67,9 +67,6 @@ private:
   SharedHandle<BtRuntime> btRuntime;
   SharedHandle<PieceStorage> pieceStorage;
   SharedHandle<PeerStorage> peerStorage;
-
-  static const unsigned int DEFAULT_ANNOUNCE_INTERVAL = 120;
-
 public:
   DefaultBtAnnounce(const SharedHandle<BtContext>& btContext,
 		    const Option* option);
@@ -115,6 +112,8 @@ public:
 
   virtual void shuffleAnnounce();
 
+  virtual void overrideMinInterval(time_t interval);
+
   void generateKey();
 
   void setRandomizer(const SharedHandle<Randomizer>& randomizer);

+ 10 - 18
src/DefaultBtInteractive.cc

@@ -392,32 +392,24 @@ void DefaultBtInteractive::checkActiveInteraction()
 
 void DefaultBtInteractive::addPeerExchangeMessage()
 {
-  time_t interval = 60;
-  if(_pexCheckPoint.elapsed(interval)) {
+  if(_pexCheckPoint.elapsed(UTPexExtensionMessage::DEFAULT_INTERVAL)) {
     UTPexExtensionMessageHandle m
       (new UTPexExtensionMessage(peer->getExtensionMessageID("ut_pex")));
     const Peers& peers = peerStorage->getPeers();
     {
-      size_t max = 30;
-      for(Peers::const_iterator i = peers.begin();
-	  i != peers.end() && max; ++i) {
-	const PeerHandle& cpeer = *i;
-	if(peer->ipaddr != cpeer->ipaddr &&
-	   !cpeer->getFirstContactTime().elapsed(interval)) {
-	  m->addFreshPeer(cpeer);
-	  --max;
+      for(std::deque<SharedHandle<Peer> >::const_iterator i =
+	    peers.begin(); i != peers.end() && !m->freshPeersAreFull(); ++i) {
+	if(peer->ipaddr != (*i)->ipaddr) {
+	  m->addFreshPeer(*i);
 	}
       }
     }
     {
-      size_t max = 10;
-      for(Peers::const_reverse_iterator i = peers.rbegin();
-	  i != peers.rend() && max; ++i) {
-	const PeerHandle& cpeer = *i;
-	if(peer->ipaddr != cpeer->ipaddr &&
-	   !cpeer->getBadConditionStartTime().elapsed(interval)) {
-	  m->addDroppedPeer(cpeer);
-	  --max;
+      for(std::deque<SharedHandle<Peer> >::const_reverse_iterator i =
+	    peers.rbegin(); i != peers.rend() && !m->droppedPeersAreFull();
+	  ++i) {
+	if(peer->ipaddr != (*i)->ipaddr) {
+	  m->addDroppedPeer(*i);
 	}
       }
     }

+ 0 - 1
src/DefaultPeerStorage.cc

@@ -217,7 +217,6 @@ void DefaultPeerStorage::deleteUnusedPeer(size_t delSize) {
       itr != peers.rend(); ++itr) {
     const PeerHandle& p = *itr;
     if(p->unused() && delSize > 0) {
-      // Update removedPeerSession******Length
       onErasingPeer(p);
       delSize--;
     } else {

+ 1 - 0
src/HandshakeExtensionMessage.cc

@@ -102,6 +102,7 @@ void HandshakeExtensionMessage::doReceivedAction()
 {
   if(_tcpPort > 0) {
     _peer->port = _tcpPort;
+    _peer->setIncomingPeer(false);
   }
   for(std::map<std::string, uint8_t>::const_iterator itr = _extensions.begin();
       itr != _extensions.end(); ++itr) {

+ 18 - 2
src/Peer.cc

@@ -45,12 +45,13 @@ namespace aria2 {
 
 #define BAD_CONDITION_INTERVAL 10
 
-Peer::Peer(std::string ipaddr, uint16_t port):
+Peer::Peer(std::string ipaddr, uint16_t port, bool incoming):
   ipaddr(ipaddr),
   port(port),
   _badConditionStartTime(0),
   _seeder(false),
-  _res(0)
+  _res(0),
+  _incoming(incoming)
 {
   resetStatus();
   std::string idSeed = ipaddr+":"+Util::uitos(port);
@@ -460,4 +461,19 @@ uint64_t Peer::getCompletedLength() const
   return _res->getCompletedLength();
 }
 
+bool Peer::isIncomingPeer() const
+{
+  return _incoming;
+}
+
+void Peer::setIncomingPeer(bool incoming)
+{
+  _incoming = incoming;
+}
+
+void Peer::setFirstContactTime(const Time& time)
+{
+  _firstContactTime = time;
+}
+
 } // namespace aria2

+ 10 - 1
src/Peer.h

@@ -69,12 +69,15 @@ private:
 
   PeerSessionResource* _res;
 
+  // If true, port is assumed not to be a listening port.
+  bool _incoming;
+
   // Before calling updateSeeder(),  make sure that
   // allocateSessionResource() is called and _res is created.
   // Otherwise assertion fails.
   void updateSeeder();
 public:
-  Peer(std::string ipaddr, uint16_t port);
+  Peer(std::string ipaddr, uint16_t port, bool incoming = false);
 
   ~Peer();
 
@@ -111,6 +114,8 @@ public:
 
   const Time& getFirstContactTime() const;
 
+  void setFirstContactTime(const Time& time);
+
   const Time& getBadConditionStartTime() const;
 
   // Before calling following member functions,  make sure that
@@ -237,6 +242,10 @@ public:
   const Time& getLastAmUnchoking() const;
 
   uint64_t getCompletedLength() const;
+
+  bool isIncomingPeer() const;
+
+  void setIncomingPeer(bool incoming);
 };
 
 typedef SharedHandle<Peer> PeerHandle;

+ 1 - 1
src/PeerListenCommand.cc

@@ -101,7 +101,7 @@ bool PeerListenCommand::execute() {
       // here.
       peerSocket->setBlockingMode();
 
-      PeerHandle peer(new Peer(peerInfo.first, 0));
+      PeerHandle peer(new Peer(peerInfo.first, peerInfo.second, true));
       int32_t cuid = CUIDCounterSingletonHolder::instance()->newID();
       Command* command =
 	new ReceiverMSEHandshakeCommand(cuid, peer, e, peerSocket);

+ 37 - 1
src/SimpleRandomizer.cc

@@ -33,9 +33,45 @@
  */
 /* copyright --> */
 #include "SimpleRandomizer.h"
+#include "a2time.h"
+#include <cstdlib>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace aria2 {
 
-RandomizerHandle SimpleRandomizer::randomizer;
+SharedHandle<Randomizer> SimpleRandomizer::_randomizer;
+
+SharedHandle<Randomizer> SimpleRandomizer::getInstance()
+{
+  if(_randomizer.isNull()) {
+    _randomizer.reset(new SimpleRandomizer());
+  }
+  return _randomizer;
+}
+  
+void SimpleRandomizer::init()
+{
+  srand(time(0)^getpid());
+}
+
+SimpleRandomizer::SimpleRandomizer() {}
+
+SimpleRandomizer::~SimpleRandomizer() {}
+
+long int SimpleRandomizer::getRandomNumber()
+{
+  return rand();
+}
+
+long int SimpleRandomizer::getMaxRandomNumber()
+{
+  return RAND_MAX;
+}
+
+long int SimpleRandomizer::getRandomNumber(long int to)
+{
+  return(int32_t)(((double)to)*getRandomNumber()/(getMaxRandomNumber()+1.0));
+}
 
 } // namespace aria2

+ 9 - 25
src/SimpleRandomizer.h

@@ -36,46 +36,30 @@
 #define _D_SIMPLE_RANDOMIZER_H_
 
 #include "Randomizer.h"
-#include "a2time.h"
-#include <stdlib.h>
 
 namespace aria2 {
 
 class SimpleRandomizer : public Randomizer {
 private:
-  static RandomizerHandle randomizer;
+  static SharedHandle<Randomizer> _randomizer;
 
-  SimpleRandomizer() {}
+  SimpleRandomizer();
 public:
-
-  static RandomizerHandle getInstance() {
-    if(randomizer.isNull()) {
-      randomizer.reset(new SimpleRandomizer());
-    }
-    return randomizer;
-  }
   
-  static void init() {
-    srand(time(0));
-  }
+  static SharedHandle<Randomizer> getInstance();
+  
+  static void init();
 
-  virtual ~SimpleRandomizer() {}
+  virtual ~SimpleRandomizer();
 
-  virtual long int getRandomNumber() {
-    return rand();
-  }
+  virtual long int getRandomNumber();
 
-  virtual long int getMaxRandomNumber() {
-      return RAND_MAX;
-  }
+  virtual long int getMaxRandomNumber();
 
   /**
    * Returns random number in [0, to).
    */
-  virtual long int getRandomNumber(long int to)
-  {
-    return(int32_t)(((double)to)*getRandomNumber()/(getMaxRandomNumber()+1.0));
-  }
+  virtual long int getRandomNumber(long int to);
 };
 
 } // namespace aria2

+ 50 - 5
src/UTPexExtensionMessage.cc

@@ -53,7 +53,10 @@ namespace aria2 {
 const std::string UTPexExtensionMessage::EXTENSION_NAME = "ut_pex";
 
 UTPexExtensionMessage::UTPexExtensionMessage(uint8_t extensionMessageID):
-  _extensionMessageID(extensionMessageID) {}
+  _extensionMessageID(extensionMessageID),
+  _interval(DEFAULT_INTERVAL),
+  _maxFreshPeer(DEFAULT_MAX_FRESH_PEER),
+  _maxDroppedPeer(DEFAULT_MAX_DROPPED_PEER) {}
 
 UTPexExtensionMessage::~UTPexExtensionMessage() {}
 
@@ -96,9 +99,15 @@ void UTPexExtensionMessage::doReceivedAction()
   PEER_STORAGE(_btContext)->addPeer(_freshPeers);
 }
 
-void UTPexExtensionMessage::addFreshPeer(const PeerHandle& peer)
+bool UTPexExtensionMessage::addFreshPeer(const PeerHandle& peer)
 {
-  _freshPeers.push_back(peer);
+  if(!peer->isIncomingPeer() &&
+     !peer->getFirstContactTime().elapsed(_interval)) {
+    _freshPeers.push_back(peer);
+    return true;
+  } else {
+    return false;
+  }
 }
 
 const Peers& UTPexExtensionMessage::getFreshPeers() const
@@ -106,9 +115,20 @@ const Peers& UTPexExtensionMessage::getFreshPeers() const
   return _freshPeers;
 }
 
-void UTPexExtensionMessage::addDroppedPeer(const PeerHandle& peer)
+bool UTPexExtensionMessage::freshPeersAreFull() const
 {
-  _droppedPeers.push_back(peer);
+  return _freshPeers.size() >= _maxFreshPeer;
+}
+
+bool UTPexExtensionMessage::addDroppedPeer(const PeerHandle& peer)
+{
+  if(!peer->isIncomingPeer() &&
+     !peer->getBadConditionStartTime().elapsed(_interval)) {
+    _droppedPeers.push_back(peer);
+    return true;
+  } else {
+    return false;
+  }
 }
 
 const Peers& UTPexExtensionMessage::getDroppedPeers() const
@@ -116,6 +136,31 @@ const Peers& UTPexExtensionMessage::getDroppedPeers() const
   return _droppedPeers;
 }
 
+bool UTPexExtensionMessage::droppedPeersAreFull() const
+{
+  return _droppedPeers.size() >= _maxDroppedPeer;
+}
+
+void UTPexExtensionMessage::setMaxFreshPeer(size_t maxFreshPeer)
+{
+  _maxFreshPeer = maxFreshPeer;
+}
+
+size_t UTPexExtensionMessage::getMaxFreshPeer() const
+{
+  return _maxFreshPeer;
+}
+
+void UTPexExtensionMessage::setMaxDroppedPeer(size_t maxDroppedPeer)
+{
+  _maxDroppedPeer = maxDroppedPeer;
+}
+
+size_t UTPexExtensionMessage::getMaxDroppedPeer() const
+{
+  return _maxDroppedPeer;
+}
+
 void UTPexExtensionMessage::setBtContext(const BtContextHandle& btContext)
 {
   _btContext = btContext;

+ 27 - 2
src/UTPexExtensionMessage.h

@@ -36,6 +36,7 @@
 #define _D_UT_PEX_EXTENSION_MESSAGE_H_
 
 #include "ExtensionMessage.h"
+#include "a2time.h"
 #include <utility>
 #include <deque>
 
@@ -56,6 +57,12 @@ private:
 
   SharedHandle<BtContext> _btContext;
 
+  time_t _interval;
+
+  size_t _maxFreshPeer;
+
+  size_t _maxDroppedPeer;
+
   std::pair<std::string, std::string>
   createCompactPeerListAndFlag(const std::deque<SharedHandle<Peer> >& peers);
 
@@ -82,18 +89,36 @@ public:
 
   virtual void doReceivedAction();
 
-  void addFreshPeer(const SharedHandle<Peer>& peer);
+  bool addFreshPeer(const SharedHandle<Peer>& peer);
 
   const std::deque<SharedHandle<Peer> >& getFreshPeers() const;
+  
+  bool freshPeersAreFull() const;
 
-  void addDroppedPeer(const SharedHandle<Peer>& peer);
+  bool addDroppedPeer(const SharedHandle<Peer>& peer);
 
   const std::deque<SharedHandle<Peer> >& getDroppedPeers() const;
 
+  bool droppedPeersAreFull() const;
+
   void setBtContext(const SharedHandle<BtContext>& btContext);
 
   static UTPexExtensionMessageHandle create(const SharedHandle<BtContext>& btContext,
 					    const unsigned char* data, size_t len);
+
+  void setMaxFreshPeer(size_t maxFreshPeer);
+
+  size_t getMaxFreshPeer() const;
+
+  void setMaxDroppedPeer(size_t maxDroppedPeer);
+
+  size_t getMaxDroppedPeer() const;
+
+  static const time_t DEFAULT_INTERVAL = 60;
+
+  static const size_t DEFAULT_MAX_FRESH_PEER = 30;
+
+  static const size_t DEFAULT_MAX_DROPPED_PEER = 10;
 };
 
 typedef SharedHandle<UTPexExtensionMessage> UTPexExtensionMessageHandle;

+ 2 - 0
test/MockBtAnnounce.h

@@ -56,6 +56,8 @@ public:
     return peerId;
   }
 
+  virtual void overrideMinInterval(time_t interval) {}
+
   void setPeerId(const std::string& peerId) {
     this->peerId = peerId;
   }

+ 74 - 0
test/UTPexExtensionMessageTest.cc

@@ -22,6 +22,10 @@ class UTPexExtensionMessageTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testToString);
   CPPUNIT_TEST(testDoReceivedAction);
   CPPUNIT_TEST(testCreate);
+  CPPUNIT_TEST(testAddFreshPeer);
+  CPPUNIT_TEST(testAddDroppedPeer);
+  CPPUNIT_TEST(testFreshPeersAreFull);
+  CPPUNIT_TEST(testDroppedPeersAreFull);
   CPPUNIT_TEST_SUITE_END();
 private:
   SharedHandle<MockBtContext> _btContext;
@@ -50,6 +54,10 @@ public:
   void testToString();
   void testDoReceivedAction();
   void testCreate();
+  void testAddFreshPeer();
+  void testAddDroppedPeer();
+  void testFreshPeersAreFull();
+  void testDroppedPeersAreFull();
 };
 
 
@@ -77,8 +85,10 @@ void UTPexExtensionMessageTest::testGetBencodedData()
   SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
   msg.addFreshPeer(p2);
   SharedHandle<Peer> p3(new Peer("192.168.0.2", 6882));
+  p3->startBadCondition();
   msg.addDroppedPeer(p3);
   SharedHandle<Peer> p4(new Peer("10.1.1.3", 10000));
+  p4->startBadCondition();
   msg.addDroppedPeer(p4);
 
   unsigned char c1[6];
@@ -110,8 +120,10 @@ void UTPexExtensionMessageTest::testToString()
   SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
   msg.addFreshPeer(p2);
   SharedHandle<Peer> p3(new Peer("192.168.0.2", 6882));
+  p3->startBadCondition();
   msg.addDroppedPeer(p3);
   SharedHandle<Peer> p4(new Peer("10.1.1.3", 10000));
+  p4->startBadCondition();
   msg.addDroppedPeer(p4);
   CPPUNIT_ASSERT_EQUAL(std::string("ut_pex added=2, dropped=2"), msg.toString());
 }
@@ -126,8 +138,10 @@ void UTPexExtensionMessageTest::testDoReceivedAction()
   SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
   msg.addFreshPeer(p2);
   SharedHandle<Peer> p3(new Peer("192.168.0.2", 6882));
+  p3->startBadCondition();
   msg.addDroppedPeer(p3);
   SharedHandle<Peer> p4(new Peer("10.1.1.3", 10000));
+  p4->startBadCondition();
   msg.addDroppedPeer(p4);
   msg.setBtContext(_btContext);
 
@@ -195,4 +209,64 @@ void UTPexExtensionMessageTest::testCreate()
   }    
 }
 
+void UTPexExtensionMessageTest::testAddFreshPeer()
+{
+  UTPexExtensionMessage msg(1);
+  SharedHandle<Peer> p1(new Peer("192.168.0.1", 6881));
+  CPPUNIT_ASSERT(msg.addFreshPeer(p1));
+  SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
+  p2->setFirstContactTime(Time(Time().getTime()-61));
+  CPPUNIT_ASSERT(!msg.addFreshPeer(p2));
+  SharedHandle<Peer> p3(new Peer("10.1.1.3", 9999, true));
+  CPPUNIT_ASSERT(!msg.addFreshPeer(p3));
+}
+
+void UTPexExtensionMessageTest::testAddDroppedPeer()
+{
+  UTPexExtensionMessage msg(1);
+  SharedHandle<Peer> p1(new Peer("192.168.0.1", 6881));
+  CPPUNIT_ASSERT(!msg.addDroppedPeer(p1));
+  SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
+  p2->startBadCondition();
+  CPPUNIT_ASSERT(msg.addFreshPeer(p2));
+  SharedHandle<Peer> p3(new Peer("10.1.1.3", 9999, true));
+  p3->startBadCondition();
+  CPPUNIT_ASSERT(!msg.addDroppedPeer(p3));
+}
+
+void UTPexExtensionMessageTest::testFreshPeersAreFull()
+{
+  UTPexExtensionMessage msg(1);
+  CPPUNIT_ASSERT_EQUAL((size_t)30, msg.getMaxFreshPeer());
+  msg.setMaxFreshPeer(2);
+  SharedHandle<Peer> p1(new Peer("192.168.0.1", 6881));
+  CPPUNIT_ASSERT(msg.addFreshPeer(p1));
+  CPPUNIT_ASSERT(!msg.freshPeersAreFull());
+  SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
+  CPPUNIT_ASSERT(msg.addFreshPeer(p2));
+  CPPUNIT_ASSERT(msg.freshPeersAreFull());
+  SharedHandle<Peer> p3(new Peer("10.1.1.3", 9999));
+  CPPUNIT_ASSERT(msg.addFreshPeer(p3));
+  CPPUNIT_ASSERT(msg.freshPeersAreFull());
+}
+
+void UTPexExtensionMessageTest::testDroppedPeersAreFull()
+{
+  UTPexExtensionMessage msg(1);
+  CPPUNIT_ASSERT_EQUAL((size_t)10, msg.getMaxDroppedPeer());
+  msg.setMaxDroppedPeer(2);
+  SharedHandle<Peer> p1(new Peer("192.168.0.1", 6881));
+  p1->startBadCondition();
+  CPPUNIT_ASSERT(msg.addDroppedPeer(p1));
+  CPPUNIT_ASSERT(!msg.droppedPeersAreFull());
+  SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
+  p2->startBadCondition();
+  CPPUNIT_ASSERT(msg.addDroppedPeer(p2));
+  CPPUNIT_ASSERT(msg.droppedPeersAreFull());
+  SharedHandle<Peer> p3(new Peer("10.1.1.3", 9999));
+  p3->startBadCondition();
+  CPPUNIT_ASSERT(msg.addDroppedPeer(p3));
+  CPPUNIT_ASSERT(msg.droppedPeersAreFull());
+}
+
 } // namespace aria2