From 928465b7bc638380004b39d6a5c6737f9f30faa0 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 30 Jul 2006 12:58:27 +0000 Subject: [PATCH] 2006-07-30 Tatsuhiro Tsujikawa * src/TorrentMan.h: (advertisePiece): Updated doc. (getAdvertisedPieceIndexes): Updated doc. (removeAdvertisedPiece); New function. * src/TorrentMan.cc (FindElapsedHave): New function object. (removeAdvertisedPiece): New function. * src/HaveEraseCommand.h: New class. * src/HaveEraseCommand.cc: New class. * src/FeatureConfig.h: New class. * src/FeatureConfig.cc: New class. * src/Request.h (defaultPorts): Removed. * src/Request.cc (FeatureConfig.h): Included. (Request): Removed the statements related to defaultPorts. (parseUrl): Removed metalinkEnabled. Use FeatureConfig instead. A default port number is now retrieved from FeatureConfig. * src/main.cc (HaveEraseCommand.h): Included. (showVersion): Added the output of feature list. (main): Added HaveEraseCommand to command queue in BitTorrent downloading. * src/PeerInteractionCommand.h (chokeCheckPoint): Commented out. (periodicExecPoint): New variable. * src/PeerInteractionCommand.cc (executeInternal): Following methods are now called in at least every 0.5 seconds to reduce CPU usage: detectMessageFlooding(), peerInteraction->checkRequestSlot(), checkHave(), sendKeepAlive(). (checkLongTimePeerChoking): Commented out. * src/BitfieldMan.h (getNthBitIndex): Changed the method signature. (getMissingIndexRandomly): Changed the method signature. * src/BitfieldMan.cc (getNthBitIndex): Rewritten (getMissingIndexRandomly): Rewritten. (hasMissingPiece): Rewritten. (getMissingIndex): Refactored. (getMissingUnusedIndex); Refactored. (getMissingIndex): Refactored. --- ChangeLog | 52 ++++++++++++++++++++ src/BitfieldMan.cc | 92 ++++++++++++----------------------- src/BitfieldMan.h | 4 +- src/FeatureConfig.cc | 56 +++++++++++++++++++++ src/FeatureConfig.h | 80 ++++++++++++++++++++++++++++++ src/HaveEraseCommand.cc | 34 +++++++++++++ src/HaveEraseCommand.h | 44 +++++++++++++++++ src/Makefile.am | 10 ++-- src/Makefile.in | 36 ++++++++------ src/PeerInteractionCommand.cc | 16 ++++-- src/PeerInteractionCommand.h | 3 +- src/Request.cc | 18 ++----- src/Request.h | 1 - src/TorrentMan.cc | 31 +++++++++++- src/TorrentMan.h | 6 +++ src/main.cc | 7 +++ test/BitfieldManTest.cc | 73 +++++++++++++++++++++++++++ test/FeatureConfigTest.cc | 42 ++++++++++++++++ test/Makefile.am | 3 +- test/Makefile.in | 6 ++- test/PeerMessageUtilTest.cc | 8 +++ 21 files changed, 514 insertions(+), 108 deletions(-) create mode 100644 src/FeatureConfig.cc create mode 100644 src/FeatureConfig.h create mode 100644 src/HaveEraseCommand.cc create mode 100644 src/HaveEraseCommand.h create mode 100644 test/FeatureConfigTest.cc diff --git a/ChangeLog b/ChangeLog index 04805e29..4f475db1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2006-07-30 Tatsuhiro Tsujikawa + + * src/TorrentMan.h: + (advertisePiece): Updated doc. + (getAdvertisedPieceIndexes): Updated doc. + (removeAdvertisedPiece); New function. + + * src/TorrentMan.cc + (FindElapsedHave): New function object. + (removeAdvertisedPiece): New function. + + * src/HaveEraseCommand.h: New class. + * src/HaveEraseCommand.cc: New class. + + * src/FeatureConfig.h: New class. + * src/FeatureConfig.cc: New class. + + * src/Request.h + (defaultPorts): Removed. + * src/Request.cc + (FeatureConfig.h): Included. + (Request): Removed the statements related to defaultPorts. + (parseUrl): Removed metalinkEnabled. Use FeatureConfig instead. + A default port number is now retrieved from FeatureConfig. + + * src/main.cc + (HaveEraseCommand.h): Included. + (showVersion): Added the output of feature list. + (main): Added HaveEraseCommand to command queue in BitTorrent + downloading. + + * src/PeerInteractionCommand.h + (chokeCheckPoint): Commented out. + (periodicExecPoint): New variable. + * src/PeerInteractionCommand.cc + (executeInternal): Following methods are now called in at least every + 0.5 seconds to reduce CPU usage: + detectMessageFlooding(), peerInteraction->checkRequestSlot(), + checkHave(), sendKeepAlive(). + (checkLongTimePeerChoking): Commented out. + + * src/BitfieldMan.h + (getNthBitIndex): Changed the method signature. + (getMissingIndexRandomly): Changed the method signature. + * src/BitfieldMan.cc + (getNthBitIndex): Rewritten + (getMissingIndexRandomly): Rewritten. + (hasMissingPiece): Rewritten. + (getMissingIndex): Refactored. + (getMissingUnusedIndex); Refactored. + (getMissingIndex): Refactored. + 2006-07-27 Tatsuhiro Tsujikawa * src/PeerMessage.h diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc index 69ded7c2..54519c48 100644 --- a/src/BitfieldMan.cc +++ b/src/BitfieldMan.cc @@ -74,45 +74,36 @@ int BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const { return count; } -int BitfieldMan::getNthBitIndex(const unsigned char* bitfield, int len, int nth) const { +int BitfieldMan::getNthBitIndex(const unsigned char bitfield, int nth) const { int index = -1; - for(int i = 0; i < len && index == -1; i++) { - unsigned char bit = bitfield[i]; - for(int bs = 7; bs >= 0; bs--) { - unsigned char mask = 1 << bs; - if(bit & mask) { - nth--; - if(nth == 0) { - index = i*8+7-bs; - break; - } + for(int bs = 7; bs >= 0; bs--) { + unsigned char mask = 1 << bs; + if(bitfield & mask) { + nth--; + if(nth == 0) { + index = 7-bs; + break; } } } return index; } -int BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const { - int nth = 1+(int)(((double)randMax)*random()/(RAND_MAX+1.0)); +int +BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, + int bitfieldLength) const +{ + int byte = (int)(((double)bitfieldLength)*random()/(RAND_MAX+1.0)); - int count = 0; - int size = sizeof(unsigned int); - for(int i = 0; i < len/size; i++) { - int temp = Util::countBit(*(unsigned int*)&bitfield[i*size]); - if(nth <= count+temp) { - int t = i*size*8+getNthBitIndex(&bitfield[i*size], size, nth-count); - return t; - } else { - count += temp; + for(int i = 0; i < bitfieldLength; i++) { + unsigned char mask = 0xff; + if(bitfield[byte]&mask) { + int index = byte*8+getNthBitIndex(bitfield[byte], 1); + return index; } - } - for(int i = len-len%size; i < len; i++) { - int temp = Util::countBit((unsigned int)bitfield[i]); - if(nth <= count+temp) { - int t = i*8+getNthBitIndex(&bitfield[i], 1, nth-count); - return t; - } else { - count += temp; + byte++; + if(byte == bitfieldLength) { + byte = 0; } } return -1; @@ -122,28 +113,17 @@ bool BitfieldMan::hasMissingPiece(const unsigned char* peerBitfield, int length) if(bitfieldLength != length) { return false; } - unsigned char* tempBitfield = new unsigned char[bitfieldLength]; - for(int i = 0; i < bitfieldLength; i++) { - tempBitfield[i] = peerBitfield[i] & ~bitfield[i]; - if(filterEnabled) { - tempBitfield[i] &= filterBitfield[i]; - } - } bool retval = false; - int size = sizeof(unsigned int); - for(int i = 0; i < length/size; i++) { - if(Util::countBit(*(unsigned int*)&tempBitfield[i*size]) > 0) { + for(int i = 0; i < bitfieldLength; i++) { + unsigned char temp = peerBitfield[i] & ~bitfield[i]; + if(filterEnabled) { + temp &= filterBitfield[i]; + } + if(temp&0xff) { retval = true; break; } } - for(int i = length-length%size; i < length && retval == false; i++) { - if(Util::countBit((unsigned int)tempBitfield[i]) > 0) { - retval = true; - break; - } - } - delete [] tempBitfield; return retval; } @@ -158,11 +138,7 @@ int BitfieldMan::getMissingIndex(const unsigned char* peerBitfield, int length) tempBitfield[i] &= filterBitfield[i]; } } - int max = countSetBit(tempBitfield, bitfieldLength); - int index = -1; - if(max > 0) { - index = getMissingIndexRandomly(tempBitfield, bitfieldLength, max); - } + int index = getMissingIndexRandomly(tempBitfield, bitfieldLength); delete [] tempBitfield; return index; } @@ -178,11 +154,7 @@ int BitfieldMan::getMissingUnusedIndex(const unsigned char* peerBitfield, int le tempBitfield[i] &= filterBitfield[i]; } } - int max = countSetBit(tempBitfield, bitfieldLength); - int index = -1; - if(max > 0) { - index = getMissingIndexRandomly(tempBitfield, bitfieldLength, max); - } + int index = getMissingIndexRandomly(tempBitfield, bitfieldLength); delete [] tempBitfield; return index; } @@ -230,11 +202,7 @@ int BitfieldMan::getMissingIndex() const { tempBitfield[i] &= filterBitfield[i]; } } - int max = countSetBit(tempBitfield, bitfieldLength); - int index = -1; - if(max > 0) { - index = getMissingIndexRandomly(tempBitfield, bitfieldLength, max); - } + int index = getMissingIndexRandomly(tempBitfield, bitfieldLength); delete [] tempBitfield; return index; } diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h index 68fbd6ea..4723c13a 100644 --- a/src/BitfieldMan.h +++ b/src/BitfieldMan.h @@ -38,8 +38,8 @@ private: int blocks; bool filterEnabled; int countSetBit(const unsigned char* bitfield, int len) const; - int getNthBitIndex(const unsigned char* bitfield, int len, int nth) const; - int getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const; + int getNthBitIndex(const unsigned char bit, int nth) const; + int getMissingIndexRandomly(const unsigned char* bitfield, int len) const; bool isBitSetInternal(const unsigned char* bitfield, int index) const; bool setBitInternal(unsigned char* bitfield, int index, bool on); bool setFilterBit(int index); diff --git a/src/FeatureConfig.cc b/src/FeatureConfig.cc new file mode 100644 index 00000000..3f48b6a1 --- /dev/null +++ b/src/FeatureConfig.cc @@ -0,0 +1,56 @@ +/* */ +#include "FeatureConfig.h" + +string FeatureConfig::FEATURE_HTTP = "http"; +string FeatureConfig::FEATURE_HTTPS = "https"; +string FeatureConfig::FEATURE_FTP = "ftp"; +string FeatureConfig::FEATURE_BITTORRENT = "bittorrent"; +string FeatureConfig::FEATURE_METALINK = "metalink"; + +static ProtocolPortMap::value_type defaultPortsArray[] = { + ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTP, 80), + ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTPS, 443), + ProtocolPortMap::value_type(FeatureConfig::FEATURE_FTP, 21), +}; + +ProtocolPortMap FeatureConfig::defaultPorts(&defaultPortsArray[0], + &defaultPortsArray[3]); + +static SupportedFeatureMap::value_type supportedFeaturesArray[] = { + SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTP, true), +#ifdef ENABLE_SSL + SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTPS, true), +#endif // ENABLE_SSL + SupportedFeatureMap::value_type(FeatureConfig::FEATURE_FTP, true), +#ifdef ENABLE_BITTORRENT + SupportedFeatureMap::value_type(FeatureConfig::FEATURE_BITTORRENT, true), +#endif // ENABLE_BITTORRENT +#ifdef ENABLE_METALINK + SupportedFeatureMap::value_type(FeatureConfig::FEATURE_METALINK, true), +#endif // ENABLE_METALINK +}; + +SupportedFeatureMap +FeatureConfig::supportedFeatures(&supportedFeaturesArray[0], + &supportedFeaturesArray[sizeof(supportedFeaturesArray)/sizeof(SupportedFeatureMap::value_type)]); + diff --git a/src/FeatureConfig.h b/src/FeatureConfig.h new file mode 100644 index 00000000..3c048ef3 --- /dev/null +++ b/src/FeatureConfig.h @@ -0,0 +1,80 @@ +/* */ +#ifndef _D_FEATURE_CONFIG_H_ +#define _D_FEATURE_CONFIG_H_ + +#include "common.h" +#include + +typedef map ProtocolPortMap; +typedef map SupportedFeatureMap; + +class FeatureConfig { +private: + static ProtocolPortMap defaultPorts; + static SupportedFeatureMap supportedFeatures; +public: + static string FEATURE_HTTP; + static string FEATURE_HTTPS; + static string FEATURE_FTP; + static string FEATURE_BITTORRENT; + static string FEATURE_METALINK; + + static int getDefaultPort(const string& protocol) { + if(defaultPorts.count(protocol)) { + return defaultPorts[protocol]; + } else { + return 0; + } + } + + static bool isSupported(const string& protocol) { + if(supportedFeatures.count(protocol)) { + return supportedFeatures[protocol]; + } else { + return false; + } + } + + static string getConfigurationSummary() { + string protos[] = { + FEATURE_HTTP, + FEATURE_HTTPS, + FEATURE_FTP, + FEATURE_BITTORRENT, + FEATURE_METALINK + }; + string summary; + for(int i = 0; i < (int)(sizeof(protos)/sizeof(string)); i++) { + summary += protos[i]; + if(isSupported(protos[i])) { + summary += ": yes"; + } else { + summary += ": no"; + } + summary += "\n"; + } + return summary; + } +}; + +#endif // _D_FEATURE_CONFIG_H_ diff --git a/src/HaveEraseCommand.cc b/src/HaveEraseCommand.cc new file mode 100644 index 00000000..f22f474f --- /dev/null +++ b/src/HaveEraseCommand.cc @@ -0,0 +1,34 @@ +/* */ +#include "HaveEraseCommand.h" + +bool HaveEraseCommand::execute() { + if(e->torrentMan->isHalt()) { + return true; + } + if(cp.elapsed(interval)) { + cp.reset(); + e->torrentMan->removeAdvertisedPiece(5); + } + e->commands.push_back(this); + return false; +} diff --git a/src/HaveEraseCommand.h b/src/HaveEraseCommand.h new file mode 100644 index 00000000..023ba495 --- /dev/null +++ b/src/HaveEraseCommand.h @@ -0,0 +1,44 @@ +/* */ +#ifndef _D_HAVE_ERASE_COMMAND_H_ +#define _D_HAVE_ERASE_COMMAND_H_ + +#include "Command.h" +#include "TorrentDownloadEngine.h" + +class HaveEraseCommand : public Command { +private: + TorrentDownloadEngine* e; + Time cp; + int interval; +public: + HaveEraseCommand(int cuid, TorrentDownloadEngine* e, int interval) + :Command(cuid), + e(e), + interval(interval) {} + + virtual ~HaveEraseCommand() {} + + virtual bool execute(); +}; + +#endif // _D_HAVE_ERASE_COMMAND_H_ diff --git a/src/Makefile.am b/src/Makefile.am index 0201a98d..1cfbac55 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,7 +51,8 @@ SRCS = Socket.h\ LogFactory.cc LogFactory.h\ NullLogger.h\ Time.cc Time.h\ - SharedHandle.h + SharedHandle.h\ + FeatureConfig.cc FeatureConfig.h if ENABLE_BITTORRENT SRCS += MetaEntry.h\ @@ -106,7 +107,8 @@ SRCS += MetaEntry.h\ AllowedFastMessage.cc AllowedFastMessage.h\ SuggestPieceMessage.cc SuggestPieceMessage.h\ SimplePeerMessage.cc SimplePeerMessage.h\ - PeerMessageFactory.cc PeerMessageFactory.h + PeerMessageFactory.cc PeerMessageFactory.h\ + HaveEraseCommand.cc HaveEraseCommand.h endif # ENABLE_BITTORRENT if ENABLE_METALINK @@ -121,8 +123,8 @@ noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ -#aria2c_LDFLAGS = -pg +aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg \ No newline at end of file + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg \ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index ddb48dda..12f65d27 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -90,7 +90,8 @@ bin_PROGRAMS = aria2c$(EXEEXT) @ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.cc AllowedFastMessage.h\ @ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\ @ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.cc SimplePeerMessage.h\ -@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.cc PeerMessageFactory.h +@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.cc PeerMessageFactory.h\ +@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.cc HaveEraseCommand.h @ENABLE_METALINK_TRUE@am__append_2 = Metalinker.cc Metalinker.h\ @ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\ @@ -154,12 +155,13 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ AbstractDiskWriter.h File.cc File.h Option.cc Option.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \ - SharedHandle.h MetaEntry.h Data.cc Data.h Dictionary.cc \ - Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \ - MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h TorrentMan.cc \ - TorrentMan.h PeerConnection.cc PeerConnection.h \ - PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \ - PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \ + SharedHandle.h FeatureConfig.cc FeatureConfig.h MetaEntry.h \ + Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \ + MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ + ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \ + PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \ + PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \ + PeerInitiateConnectionCommand.cc \ PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \ PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \ BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \ @@ -188,9 +190,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ RejectMessage.h AllowedFastMessage.cc AllowedFastMessage.h \ SuggestPieceMessage.cc SuggestPieceMessage.h \ SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \ - PeerMessageFactory.h Metalinker.cc Metalinker.h \ - MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \ - MetalinkResource.h MetalinkProcessor.h \ + PeerMessageFactory.h HaveEraseCommand.cc HaveEraseCommand.h \ + Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \ + MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h @ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \ @@ -238,7 +240,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ @ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.$(OBJEXT) \ -@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.$(OBJEXT) +@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.$(OBJEXT) \ +@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.$(OBJEXT) @ENABLE_METALINK_TRUE@am__objects_2 = Metalinker.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \ @@ -266,7 +269,7 @@ am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ PreAllocationDiskWriter.$(OBJEXT) AbstractDiskWriter.$(OBJEXT) \ File.$(OBJEXT) Option.$(OBJEXT) Base64.$(OBJEXT) \ CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) Time.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) + FeatureConfig.$(OBJEXT) $(am__objects_1) $(am__objects_2) am_libaria2c_a_OBJECTS = $(am__objects_3) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -455,17 +458,18 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \ AbstractDiskWriter.h File.cc File.h Option.cc Option.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \ - SharedHandle.h $(am__append_1) $(am__append_2) + SharedHandle.h FeatureConfig.cc FeatureConfig.h \ + $(am__append_1) $(am__append_2) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ -#aria2c_LDFLAGS = -pg +aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg all: all-am @@ -563,6 +567,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DiskAdaptor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpDownloadCommand.Po@am__quote@ @@ -572,6 +577,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelResponseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveAllMessage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveEraseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveNoneMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@ diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index 0d19ce1a..2788026b 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -115,14 +115,18 @@ bool PeerInteractionCommand::executeInternal() { case WIRED: peerInteraction->syncPiece(); decideChoking(); - receiveMessages(); - detectMessageFlooding(); - peerInteraction->checkRequestSlot(); + if(periodicExecPoint.elapsedInMillis(500)) { + periodicExecPoint.reset(); + detectMessageFlooding(); + peerInteraction->checkRequestSlot(); + checkHave(); + sendKeepAlive(); + } + receiveMessages(); + peerInteraction->addRequests(); - checkHave(); peerInteraction->sendMessages(e->getUploadSpeed()); - sendKeepAlive(); break; } if(peerInteraction->countMessageInQueue() > 0) { @@ -152,6 +156,7 @@ void PeerInteractionCommand::detectMessageFlooding() { } } +/* void PeerInteractionCommand::checkLongTimePeerChoking() { if(e->torrentMan->downloadComplete()) { return; @@ -165,6 +170,7 @@ void PeerInteractionCommand::checkLongTimePeerChoking() { chokeCheckPoint.reset(); } } +*/ void PeerInteractionCommand::decideChoking() { if(peer->shouldBeChoking()) { diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h index 037f9029..ff0abb82 100644 --- a/src/PeerInteractionCommand.h +++ b/src/PeerInteractionCommand.h @@ -38,9 +38,10 @@ private: PeerInteraction* peerInteraction; Time keepAliveCheckPoint; - Time chokeCheckPoint; + //Time chokeCheckPoint; Time freqCheckPoint; Time haveCheckTime; + Time periodicExecPoint; int chokeUnchokeCount; int haveCount; int keepAliveCount; diff --git a/src/Request.cc b/src/Request.cc index 93f2a4fb..dede0c22 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -21,14 +21,9 @@ /* copyright --> */ #include "Request.h" #include "Util.h" +#include "FeatureConfig.h" Request::Request():port(0), tryCount(0), isTorrent(false) { - defaultPorts["http"] = 80; -#ifdef ENABLE_SSL - // for SSL - defaultPorts["https"] = 443; -#endif // ENABLE_SSL - defaultPorts["ftp"] = 21; seg.sp = 0; seg.ep = 0; seg.ds = 0; @@ -56,16 +51,11 @@ bool Request::redirectUrl(const string& url) { } bool Request::parseUrl(const string& url) { -#ifdef ENABLE_METALINK - bool metalinkEnabled = true; -#else - bool metalinkEnabled = false; -#endif - string tempUrl; string::size_type sharpIndex = url.find("#"); if(sharpIndex != string::npos) { - if(metalinkEnabled && url.find(METALINK_MARK) == sharpIndex) { + if(FeatureConfig::isSupported(FeatureConfig::FEATURE_METALINK) && + url.find(METALINK_MARK) == sharpIndex) { tempUrl = url.substr(sharpIndex+strlen(METALINK_MARK)); } else { tempUrl = url.substr(0, sharpIndex); @@ -92,7 +82,7 @@ bool Request::parseUrl(const string& url) { if(hp == string::npos) return false; protocol = tempUrl.substr(0, hp); int defPort; - if((defPort = defaultPorts[protocol]) == 0) { + if((defPort = FeatureConfig::getDefaultPort(protocol)) == 0) { return false; } hp += 3; diff --git a/src/Request.h b/src/Request.h index c0fa68ed..5b5b15f1 100644 --- a/src/Request.h +++ b/src/Request.h @@ -57,7 +57,6 @@ private: int port; string dir; string file; - map defaultPorts; int tryCount; int trackerEvent; bool parseUrl(const string& url); diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index a7d0d615..0e97453e 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -660,7 +660,9 @@ void TorrentMan::advertisePiece(int cuid, int index) { PieceIndexes TorrentMan::getAdvertisedPieceIndexes(int myCuid, - const Time& lastCheckTime) const { + const Time& lastCheckTime + ) const +{ PieceIndexes indexes; for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) { const Haves::value_type& have = *itr; @@ -674,3 +676,30 @@ TorrentMan::getAdvertisedPieceIndexes(int myCuid, } return indexes; } + +class FindElapsedHave +{ +private: + int elapsed; +public: + FindElapsedHave(int elapsed):elapsed(elapsed) {} + + bool operator()(const HaveEntry& have) { + if(have.registeredTime.elapsed(elapsed)) { + return true; + } else { + return false; + } + } +}; + +void +TorrentMan::removeAdvertisedPiece(int elapsed) +{ + Haves::iterator itr = find_if(haves.begin(), haves.end(), FindElapsedHave(elapsed)); + if(itr != haves.end()) { + logger->debug("Removed %d have entries.", haves.end()-itr); + haves.erase(itr, haves.end()); + } +} + diff --git a/src/TorrentMan.h b/src/TorrentMan.h index a0112dd5..f9201787 100644 --- a/src/TorrentMan.h +++ b/src/TorrentMan.h @@ -176,9 +176,15 @@ public: string getPieceHash(int index) const; + // Addes piece index to advertise to other commands. They send have message + // based on this information. void advertisePiece(int cuid, int index); + // Returns piece index which is not advertised by the caller command and + // newer than lastCheckTime. PieceIndexes getAdvertisedPieceIndexes(int myCuid, const Time& lastCheckTime) const; + // Removes have entry if specified seconds have elapsed since its registration. + void removeAdvertisedPiece(int elapsed); long long int getTotalLength() const { return totalLength; } void setTotalLength(long long int length) { totalLength = length; } diff --git a/src/main.cc b/src/main.cc index 856c5090..a7bc33f4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -29,6 +29,7 @@ #include "Util.h" #include "InitiateConnectionCommandFactory.h" #include "prefs.h" +#include "FeatureConfig.h" #ifdef ENABLE_BITTORRENT # include "TorrentConsoleDownloadEngine.h" @@ -37,6 +38,7 @@ # include "TorrentAutoSaveCommand.h" # include "TrackerWatcherCommand.h" # include "TrackerUpdateCommand.h" +# include "HaveEraseCommand.h" # include "ByteArrayDiskWriter.h" # include "PeerChokeCommand.h" #endif // ENABLE_BITTORRENT @@ -129,6 +131,9 @@ void showVersion() { cout << PACKAGE << _(" version ") << PACKAGE_VERSION << endl; cout << "Copyright (C) 2006 Tatsuhiro Tsujikawa" << endl; cout << endl; + cout << "**Configuration**" << endl; + cout << FeatureConfig::getConfigurationSummary(); + cout << endl; cout << _("This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" @@ -881,6 +886,8 @@ int main(int argc, char* argv[]) { op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(), 10, te)); + te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(), + te, 10)); te->run(); if(te->torrentMan->downloadComplete()) { diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc index 38f097ea..e8dab885 100644 --- a/test/BitfieldManTest.cc +++ b/test/BitfieldManTest.cc @@ -11,6 +11,7 @@ class BitfieldManTest:public CppUnit::TestFixture { CPPUNIT_TEST(testGetFirstMissingUnusedIndex); CPPUNIT_TEST(testIsAllBitSet); CPPUNIT_TEST(testFilter); + CPPUNIT_TEST(testGetMissingIndex); CPPUNIT_TEST_SUITE_END(); private: @@ -22,6 +23,7 @@ public: void testGetFirstMissingUnusedIndex(); void testIsAllBitSet(); void testFilter(); + void testGetMissingIndex(); }; @@ -136,3 +138,74 @@ void BitfieldManTest::testFilter() { btman2.enableFilter(); CPPUNIT_ASSERT_EQUAL((long long int)31, btman2.getFilteredTotalLength()); } + +void BitfieldManTest::testGetMissingIndex() { + srandom(100); + + BitfieldMan bt1(1024, 1024*256); + + unsigned char bitArray[] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }; + CPPUNIT_ASSERT_EQUAL(80, bt1.getMissingIndex(bitArray, 32)); + + unsigned char bitArray2[] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }; + + CPPUNIT_ASSERT_EQUAL(80, bt1.getMissingIndex(bitArray2, 32)); + + unsigned char bitArray3[] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }; + + CPPUNIT_ASSERT_EQUAL(60, bt1.getMissingIndex(bitArray3, 32)); + + unsigned char bitArray4[] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + CPPUNIT_ASSERT_EQUAL(0, bt1.getMissingIndex(bitArray4, 32)); + + unsigned char bitArray5[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingIndex(bitArray5, 32)); + +} diff --git a/test/FeatureConfigTest.cc b/test/FeatureConfigTest.cc new file mode 100644 index 00000000..a82220a7 --- /dev/null +++ b/test/FeatureConfigTest.cc @@ -0,0 +1,42 @@ +#include "FeatureConfig.h" + +#include + +class FeatureConfigTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(FeatureConfigTest); + CPPUNIT_TEST(testGetDefaultPort); + CPPUNIT_TEST(testIsSupported); + CPPUNIT_TEST(testGetConfigurationSummary); + CPPUNIT_TEST_SUITE_END(); + +public: + void testGetDefaultPort(); + void testIsSupported(); + void testGetConfigurationSummary(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(FeatureConfigTest); + +void FeatureConfigTest::testGetDefaultPort() { + CPPUNIT_ASSERT_EQUAL(80, FeatureConfig::getDefaultPort("http")); + CPPUNIT_ASSERT_EQUAL(443, FeatureConfig::getDefaultPort("https")); + CPPUNIT_ASSERT_EQUAL(21, FeatureConfig::getDefaultPort("ftp")); +} + +void FeatureConfigTest::testIsSupported() { + CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("http")); + CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("https")); + CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("ftp")); + CPPUNIT_ASSERT_EQUAL(false, FeatureConfig::isSupported("ftps")); +} + +void FeatureConfigTest::testGetConfigurationSummary() { + CPPUNIT_ASSERT_EQUAL(string("http: yes\n") + +"https: yes\n" + +"ftp: yes\n" + +"bittorrent: yes\n" + +"metalink: yes\n", + FeatureConfig::getConfigurationSummary()); +} diff --git a/test/Makefile.am b/test/Makefile.am index e8fc2ca8..99486411 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -34,7 +34,8 @@ aria2c_SOURCES = AllTest.cc\ SuggestPieceMessageTest.cc\ Xml2MetalinkProcessorTest.cc\ MetalinkerTest.cc\ - MetalinkEntryTest.cc + MetalinkEntryTest.cc\ + FeatureConfigTest.cc #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_LDFLAGS = ${CPPUNIT_LIBS} diff --git a/test/Makefile.in b/test/Makefile.in index da4b35df..6144249d 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -73,7 +73,7 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \ RejectMessageTest.$(OBJEXT) AllowedFastMessageTest.$(OBJEXT) \ SuggestPieceMessageTest.$(OBJEXT) \ Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \ - MetalinkEntryTest.$(OBJEXT) + MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) aria2c_OBJECTS = $(am_aria2c_OBJECTS) am__DEPENDENCIES_1 = aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1) @@ -255,7 +255,8 @@ aria2c_SOURCES = AllTest.cc\ SuggestPieceMessageTest.cc\ Xml2MetalinkProcessorTest.cc\ MetalinkerTest.cc\ - MetalinkEntryTest.cc + MetalinkEntryTest.cc\ + FeatureConfigTest.cc #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_LDFLAGS = ${CPPUNIT_LIBS} @@ -328,6 +329,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriterTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DictionaryTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfigTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveAllMessageTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessageTest.Po@am__quote@ diff --git a/test/PeerMessageUtilTest.cc b/test/PeerMessageUtilTest.cc index d38a7f20..2b6d4f7e 100644 --- a/test/PeerMessageUtilTest.cc +++ b/test/PeerMessageUtilTest.cc @@ -1,4 +1,12 @@ #include "PeerMessageUtil.h" +#include "UnchokeMessage.h" +#include "InterestedMessage.h" +#include "NotInterestedMessage.h" +#include "HaveMessage.h" +#include "BitfieldMessage.h" +#include "RequestMessage.h" +#include "PieceMessage.h" +#include "CancelMessage.h" #include #include #include