summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-02-28 17:40:47 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-02-28 17:40:47 +0000
commit3698b4680592accd47df25d904a5e240a2f43f5d (patch)
tree090a1264805576e95077262acdaf5e2bdc1cdb7b /src
parenta1458a1642b6582c0b316e094e5008a10b4963a8 (diff)
2008-02-29 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
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}
Diffstat (limited to 'src')
-rw-r--r--src/BtPieceMessage.cc2
-rw-r--r--src/DownloadCommand.cc24
-rw-r--r--src/DownloadCommand.h6
-rw-r--r--src/MessageDigestHelper.cc35
-rw-r--r--src/MessageDigestHelper.h27
-rw-r--r--src/main.cc7
6 files changed, 94 insertions, 7 deletions
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 <cassert>
@@ -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> peerStat;
+#ifdef ENABLE_MESSAGE_DIGEST
+ MessageDigestContext* _messageDigestContext;
+#endif // ENABLE_MESSAGE_DIGEST
void validatePieceHash(const SharedHandle<Segment>& 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<BinaryStream>& 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 <string>
namespace aria2 {
@@ -44,6 +45,8 @@ namespace aria2 {
class BinaryStream;
class MessageDigestHelper {
+private:
+ static MessageDigestContext* _sha1Ctx;
public:
/**
* Returns message digest in hexadecimal representation.
@@ -59,6 +62,30 @@ public:
}
/**
+ * 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<BinaryStream>& 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<BinaryStream>& bs,
+ int64_t offset, int64_t length);
+
+ /**
* Calculates message digest of file denoted by filename.
* Returns message digest in hexadecimal representation.
* Digest algorithm is specified by algo.
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 <deque>
#include <signal.h>
#include <unistd.h>
@@ -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