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}
pull/1/head
Tatsuhiro Tsujikawa 2008-02-28 17:40:47 +00:00
parent a1458a1642
commit 3698b46805
7 changed files with 108 additions and 7 deletions

View File

@ -1,3 +1,17 @@
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}
2008-02-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Add a file descriptor which connected to fast peer(latency<1500) to

View File

@ -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());
}

View File

@ -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());

View File

@ -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);

View File

@ -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());
}

View File

@ -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.
@ -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<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.

View File

@ -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