From 3698b4680592accd47df25d904a5e240a2f43f5d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 28 Feb 2008 17:40:47 +0000 Subject: [PATCH] 2008-02-29 Tatsuhiro Tsujikawa Create MessageDigestHelper::staticSHA1DigestInit() which uses statically declared sha1 MessageDigestContext. * src/BtPieceMessage.cc: Use staticSHA1DigestInit() to avoid initialization of short-lived MessageDigestContext. * src/MessageDigestHelper.{h, cc} * src/main.cc Now DownloadCommand has a reference to MessageDigestContext to avoid the initialization of MessageDigestContext every time in validating chunk checksum. * src/DownloadCommand.{h, cc} --- ChangeLog | 14 ++++++++++++++ src/BtPieceMessage.cc | 2 +- src/DownloadCommand.cc | 24 +++++++++++++++++++++--- src/DownloadCommand.h | 6 ++++++ src/MessageDigestHelper.cc | 35 ++++++++++++++++++++++++++++++++--- src/MessageDigestHelper.h | 27 +++++++++++++++++++++++++++ src/main.cc | 7 +++++++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea9637da..d041b2bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-02-29 Tatsuhiro Tsujikawa + + Create MessageDigestHelper::staticSHA1DigestInit() which uses + statically declared sha1 MessageDigestContext. + * src/BtPieceMessage.cc: Use staticSHA1DigestInit() to avoid + initialization of short-lived MessageDigestContext. + * src/MessageDigestHelper.{h, cc} + * src/main.cc + + Now DownloadCommand has a reference to MessageDigestContext to avoid + the initialization of MessageDigestContext every time in validating + chunk checksum. + * src/DownloadCommand.{h, cc} + 2008-02-28 Tatsuhiro Tsujikawa Add a file descriptor which connected to fast peer(latency<1500) to diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc index d33c79b0..41d8bb5a 100644 --- a/src/BtPieceMessage.cc +++ b/src/BtPieceMessage.cc @@ -205,7 +205,7 @@ bool BtPieceMessage::checkPieceHash(const PieceHandle& piece) { int64_t offset = ((int64_t)piece->getIndex())*btContext->getPieceLength(); - return MessageDigestHelper::digest("sha1", pieceStorage->getDiskAdaptor(), offset, piece->getLength()) + return MessageDigestHelper::staticSHA1Digest(pieceStorage->getDiskAdaptor(), offset, piece->getLength()) == btContext->getPieceHash(piece->getIndex()); } diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index e28f61b8..e9f0a29a 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -55,7 +55,7 @@ #include "message.h" #include "prefs.h" #ifdef ENABLE_MESSAGE_DIGEST -#include "MessageDigestHelper.h" +# include "MessageDigestHelper.h" #endif // ENABLE_MESSAGE_DIGEST #include @@ -68,8 +68,21 @@ DownloadCommand::DownloadCommand(int cuid, const SocketHandle& s): AbstractCommand(cuid, req, requestGroup, e, s), peerStat(0), +#ifdef ENABLE_MESSAGE_DIGEST + _messageDigestContext(0), +#endif // ENABLE_MESSAGE_DIGEST transferDecoder(0) { +#ifdef ENABLE_MESSAGE_DIGEST + { + std::string algo = _requestGroup->getDownloadContext()->getPieceHashAlgo(); + if(MessageDigestContext::supports(algo)) { + _messageDigestContext = new MessageDigestContext(); + _messageDigestContext->trySetAlgo(algo); + _messageDigestContext->digestInit(); + } + } +#endif // ENABLE_MESSAGE_DIGEST peerStat = _requestGroup->getSegmentMan()->getPeerStat(cuid); if(peerStat.isNull()) { peerStat = new PeerStat(cuid); @@ -81,6 +94,9 @@ DownloadCommand::DownloadCommand(int cuid, DownloadCommand::~DownloadCommand() { assert(peerStat.get()); peerStat->downloadStop(); +#ifdef ENABLE_MESSAGE_DIGEST + delete _messageDigestContext; +#endif // ENABLE_MESSAGE_DIGEST } bool DownloadCommand::executeInternal() { @@ -187,10 +203,12 @@ void DownloadCommand::validatePieceHash(const SegmentHandle& segment) #ifdef ENABLE_MESSAGE_DIGEST std::string expectedPieceHash = _requestGroup->getDownloadContext()->getPieceHash(segment->getIndex()); - if(e->option->get(PREF_REALTIME_CHUNK_CHECKSUM) == V_TRUE && + if(_messageDigestContext && + e->option->get(PREF_REALTIME_CHUNK_CHECKSUM) == V_TRUE && !expectedPieceHash.empty()) { + _messageDigestContext->digestReset(); std::string actualPieceHash = - MessageDigestHelper::digest(_requestGroup->getDownloadContext()->getPieceHashAlgo(), + MessageDigestHelper::digest(_messageDigestContext, _requestGroup->getPieceStorage()->getDiskAdaptor(), segment->getPosition(), segment->getLength()); diff --git a/src/DownloadCommand.h b/src/DownloadCommand.h index 0b7c436b..a8ae9ad1 100644 --- a/src/DownloadCommand.h +++ b/src/DownloadCommand.h @@ -41,6 +41,9 @@ namespace aria2 { class TransferEncoding; class PeerStat; +#ifdef ENABLE_MESSAGE_DIGEST +class MessageDigestContext; +#endif // ENABLE_MESSAGE_DIGEST class DownloadCommand : public AbstractCommand { private: @@ -48,6 +51,9 @@ private: int32_t startupIdleTime; int32_t lowestDownloadSpeedLimit; SharedHandle peerStat; +#ifdef ENABLE_MESSAGE_DIGEST + MessageDigestContext* _messageDigestContext; +#endif // ENABLE_MESSAGE_DIGEST void validatePieceHash(const SharedHandle& segment); diff --git a/src/MessageDigestHelper.cc b/src/MessageDigestHelper.cc index f5d4acce..8d5eab56 100644 --- a/src/MessageDigestHelper.cc +++ b/src/MessageDigestHelper.cc @@ -42,6 +42,29 @@ namespace aria2 { +MessageDigestContext* MessageDigestHelper::_sha1Ctx = 0; + +void MessageDigestHelper::staticSHA1DigestInit() +{ + staticSHA1DigestFree(); + _sha1Ctx = new MessageDigestContext(); + _sha1Ctx->trySetAlgo("sha1"); + _sha1Ctx->digestInit(); +} + +void MessageDigestHelper::staticSHA1DigestFree() +{ + delete _sha1Ctx; +} + +std::string MessageDigestHelper::staticSHA1Digest(const BinaryStreamHandle& bs, + int64_t offset, + int64_t length) +{ + _sha1Ctx->digestReset(); + return digest(_sha1Ctx, bs, offset, length); +} + std::string MessageDigestHelper::digest(const std::string& algo, const BinaryStreamHandle& bs, int64_t offset, @@ -50,7 +73,13 @@ std::string MessageDigestHelper::digest(const std::string& algo, MessageDigestContext ctx; ctx.trySetAlgo(algo); ctx.digestInit(); + return digest(&ctx, bs, offset, length); +} +std::string MessageDigestHelper::digest(MessageDigestContext* ctx, + const SharedHandle& bs, + int64_t offset, int64_t length) +{ int32_t BUFSIZE = 4096; unsigned char BUF[BUFSIZE]; int64_t iteration = length/BUFSIZE; @@ -60,7 +89,7 @@ std::string MessageDigestHelper::digest(const std::string& algo, if(readLength != BUFSIZE) { throw new DlAbortEx(EX_FILE_READ, "n/a", strerror(errno)); } - ctx.digestUpdate(BUF, readLength); + ctx->digestUpdate(BUF, readLength); offset += readLength; } if(tail) { @@ -68,9 +97,9 @@ std::string MessageDigestHelper::digest(const std::string& algo, if(readLength != tail) { throw new DlAbortEx(EX_FILE_READ, "n/a", strerror(errno)); } - ctx.digestUpdate(BUF, readLength); + ctx->digestUpdate(BUF, readLength); } - std::string rawMD = ctx.digestFinal(); + std::string rawMD = ctx->digestFinal(); return Util::toHex((const unsigned char*)rawMD.c_str(), rawMD.size()); } diff --git a/src/MessageDigestHelper.h b/src/MessageDigestHelper.h index d8c30ffd..54cfa028 100644 --- a/src/MessageDigestHelper.h +++ b/src/MessageDigestHelper.h @@ -37,6 +37,7 @@ #include "common.h" #include "SharedHandle.h" +#include "messageDigest.h" #include namespace aria2 { @@ -44,6 +45,8 @@ namespace aria2 { class BinaryStream; class MessageDigestHelper { +private: + static MessageDigestContext* _sha1Ctx; public: /** * Returns message digest in hexadecimal representation. @@ -58,6 +61,30 @@ public: return digest(algo, data.c_str(), data.size()); } + /** + * staticSHA1DigestInit(), staticSHA1DigestFree(), staticSHA1Digest() + * use statically declared MessageDigestContext _sha1Ctx. + */ + /** + * Initializes _sha1Ctx + */ + static void staticSHA1DigestInit(); + + /** + * Frees allocated resources for _sha1Ctx + */ + static void staticSHA1DigestFree(); + + static std::string staticSHA1Digest(const SharedHandle& bs, + int64_t offset, int64_t length); + + /** + * ctx must be initialized or reseted before calling this function. + */ + static std::string digest(MessageDigestContext* ctx, + const SharedHandle& bs, + int64_t offset, int64_t length); + /** * Calculates message digest of file denoted by filename. * Returns message digest in hexadecimal representation. diff --git a/src/main.cc b/src/main.cc index 0afb9b8c..51e71db2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -66,6 +66,9 @@ # include "Metalink2RequestGroup.h" # include "MetalinkEntry.h" #endif // ENABLE_METALINK +#ifdef ENABLE_MESSAGE_DIGEST +# include "MessageDigestHelper.h" +#endif // ENABLE_MESSAGE_DIGEST #include #include #include @@ -273,6 +276,10 @@ int main(int argc, char* argv[]) AuthConfigFactorySingleton::instance(authConfigFactory); CUIDCounterHandle cuidCounter = new CUIDCounter(); CUIDCounterSingletonHolder::instance(cuidCounter); +#ifdef ENABLE_MESSAGE_DIGEST + MessageDigestHelper::staticSHA1DigestInit(); +#endif // ENABLE_MESSAGE_DIGEST + #ifdef SIGPIPE Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0); #endif