diff -uwN aria2-0.11.1+1/src/AbstractDiskWriter.cc aria2-0.11.2.orig/src/AbstractDiskWriter.cc --- aria2-0.11.1+1/src/AbstractDiskWriter.cc 2007-08-03 22:17:04.934625000 -0700 +++ aria2-0.11.2.orig/src/AbstractDiskWriter.cc 2007-08-08 07:40:11.000000000 -0700 @@ -113,36 +113,6 @@ return read(fd, data, len); } -#ifdef ENABLE_MESSAGE_DIGEST -string AbstractDiskWriter::messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) -{ - MessageDigestContext ctx(algo); - ctx.digestInit(); - - int32_t BUFSIZE = 16*1024; - char buf[BUFSIZE]; - for(int64_t i = 0; i < length/BUFSIZE; i++) { - if(BUFSIZE != readData(buf, BUFSIZE, offset)) { - throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno)); - } - ctx.digestUpdate(buf, BUFSIZE); - offset += BUFSIZE; - } - int32_t r = length%BUFSIZE; - if(r > 0) { - if(r != readData(buf, r, offset)) { - throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno)); - } - ctx.digestUpdate(buf, r); - } - unsigned char hashValue[20]; - ctx.digestFinal(hashValue); - - return Util::toHex(hashValue, 20); -} -#endif // ENABLE_MESSAGE_DIGEST - void AbstractDiskWriter::seek(int64_t offset) { if(offset != lseek(fd, offset, SEEK_SET)) { throw new DlAbortEx(EX_FILE_SEEK, filename.c_str(), strerror(errno)); @@ -170,6 +140,7 @@ ftruncate(fd, length); } +// TODO the file descriptor fd must be opened before calling this function. int64_t AbstractDiskWriter::size() const { struct stat fileStat; diff -uwN aria2-0.11.1+1/src/AbstractDiskWriter.h aria2-0.11.2.orig/src/AbstractDiskWriter.h --- aria2-0.11.1+1/src/AbstractDiskWriter.h 2007-05-20 06:51:52.000000000 -0700 +++ aria2-0.11.2.orig/src/AbstractDiskWriter.h 2007-08-08 07:40:11.000000000 -0700 @@ -65,11 +65,6 @@ virtual void openExistingFile(const string& filename, int64_t totalLength = 0); -#ifdef ENABLE_MESSAGE_DIGEST - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo); -#endif // ENABLE_MESSAGE_DIGEST - virtual void writeData(const char* data, int32_t len, int64_t offset); virtual int32_t readData(char* data, int32_t len, int64_t offset); diff -uwN aria2-0.11.1+1/src/AbstractSingleDiskAdaptor.cc aria2-0.11.2.orig/src/AbstractSingleDiskAdaptor.cc --- aria2-0.11.1+1/src/AbstractSingleDiskAdaptor.cc 2007-03-24 08:32:40.000000000 -0700 +++ aria2-0.11.2.orig/src/AbstractSingleDiskAdaptor.cc 2007-08-08 07:40:11.000000000 -0700 @@ -59,10 +59,6 @@ return diskWriter->readData(data, len, offset); } -string AbstractSingleDiskAdaptor::messageDigest(int64_t offset, int64_t length, const MessageDigestContext::DigestAlgo& algo) { - return diskWriter->messageDigest(offset, length, algo); -} - bool AbstractSingleDiskAdaptor::fileExists() { return File(getFilePath()).exists(); diff -uwN aria2-0.11.1+1/src/AbstractSingleDiskAdaptor.h aria2-0.11.2.orig/src/AbstractSingleDiskAdaptor.h --- aria2-0.11.1+1/src/AbstractSingleDiskAdaptor.h 2007-01-25 08:47:29.000000000 -0800 +++ aria2-0.11.2.orig/src/AbstractSingleDiskAdaptor.h 2007-08-08 07:40:11.000000000 -0700 @@ -60,11 +60,13 @@ virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset); - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo); - virtual bool fileExists(); + virtual int64_t size() const + { + return getTotalLength(); + } + void setDiskWriter(const DiskWriterHandle diskWriter) { this->diskWriter = diskWriter; } diff -uwN aria2-0.11.1+1/src/BtContext.h aria2-0.11.2.orig/src/BtContext.h --- aria2-0.11.1+1/src/BtContext.h 2007-01-28 06:18:35.000000000 -0800 +++ aria2-0.11.2.orig/src/BtContext.h 2007-08-08 07:40:11.000000000 -0700 @@ -84,6 +84,9 @@ * Returns the peer id of localhost, 20 byte length */ virtual const unsigned char* getPeerId() = 0; + + virtual Integers computeFastSet(const string& ipaddr, int32_t fastSetSize) = 0; + }; typedef SharedHandle BtContextHandle; diff -uwN aria2-0.11.1+1/src/BtPieceMessage.cc aria2-0.11.2.orig/src/BtPieceMessage.cc --- aria2-0.11.1+1/src/BtPieceMessage.cc 2007-08-03 22:17:05.169000000 -0700 +++ aria2-0.11.2.orig/src/BtPieceMessage.cc 2007-08-08 07:40:11.000000000 -0700 @@ -39,6 +39,8 @@ #include "DlAbortEx.h" #include "BtChokingEvent.h" #include "BtCancelSendingPieceEvent.h" +#include "DiskAdaptorWriter.h" +#include "MessageDigestHelper.h" void BtPieceMessage::setBlock(const unsigned char* block, int32_t blockLength) { delete [] this->block; @@ -190,8 +192,9 @@ bool BtPieceMessage::checkPieceHash(const PieceHandle& piece) { int64_t offset = ((int64_t)piece->getIndex())*btContext->getPieceLength(); - return pieceStorage->getDiskAdaptor()->messageDigest(offset, piece->getLength(), DIGEST_ALGO_SHA1) == - btContext->getPieceHash(piece->getIndex()); + + return MessageDigestHelper::digest("sha1", new DiskAdaptorWriter(pieceStorage->getDiskAdaptor()), offset, piece->getLength()) + == btContext->getPieceHash(piece->getIndex()); } void BtPieceMessage::onNewPiece(const PieceHandle& piece) { diff -uwN aria2-0.11.1+1/src/BtRuntime.h aria2-0.11.2.orig/src/BtRuntime.h --- aria2-0.11.1+1/src/BtRuntime.h 2007-08-03 22:17:05.169000000 -0700 +++ aria2-0.11.2.orig/src/BtRuntime.h 2007-08-09 07:47:47.000000000 -0700 @@ -38,7 +38,7 @@ #include "common.h" #include "SharedHandle.h" -#define MIN_PEERS 15 +#define MIN_PEERS 40 class BtRuntime { private: diff -uwN aria2-0.11.1+1/src/ByteArrayDiskWriter.h aria2-0.11.2.orig/src/ByteArrayDiskWriter.h --- aria2-0.11.1+1/src/ByteArrayDiskWriter.h 2007-08-03 22:17:05.200250000 -0700 +++ aria2-0.11.2.orig/src/ByteArrayDiskWriter.h 2007-08-08 07:40:11.000000000 -0700 @@ -66,14 +66,6 @@ { return buf.str().size(); } - - // not implemented yet -#ifdef ENABLE_MESSAGE_DIGEST - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) { - return ""; - } -#endif // ENABLE_MESSAGE_DIGEST }; #endif // _D_BYTE_ARRAY_DISK_WRITER_H_ diff -uwN aria2-0.11.1+1/src/Checksum.h aria2-0.11.2.orig/src/Checksum.h --- aria2-0.11.1+1/src/Checksum.h 2007-05-31 08:56:20.000000000 -0700 +++ aria2-0.11.2.orig/src/Checksum.h 2007-08-08 07:40:11.000000000 -0700 @@ -36,43 +36,39 @@ #define _D_CHECKSUM_H_ #include "common.h" -#ifdef ENABLE_MESSAGE_DIGEST -#include "messageDigest.h" class Checksum { private: - string md; - MessageDigestContext::DigestAlgo algo; + string _algo; + string _messageDigest; public: - Checksum(const string& md, MessageDigestContext::DigestAlgo algo): - md(md), - algo(algo) {} + // _messageDigest is ascii hexadecimal notation. + Checksum(const string& algo, const string& messageDigest): + _algo(algo), _messageDigest(messageDigest) {} Checksum(): - algo(DIGEST_ALGO_SHA1) {} + _algo("sha1") {} + ~Checksum() {} bool isEmpty() const { - return md.size() == 0; + return _messageDigest.size() == 0; } void setMessageDigest(const string& md) { - this->md = md; + this->_messageDigest = md; } const string& getMessageDigest() const { - return md; + return _messageDigest; } - void setDigestAlgo(MessageDigestContext::DigestAlgo algo) { - this->algo = algo; + void setAlgo(const string& algo) { + this->_algo = algo; } - const MessageDigestContext::DigestAlgo& getDigestAlgo() const { - return algo; + + const string& getAlgo() const { + return _algo; } }; -#else -class Checksum { -}; -#endif // ENABLE_MESSAGE_DIGEST typedef SharedHandle ChecksumHandle; Files aria2-0.11.1+1/src/ChecksumCommand.o and aria2-0.11.2.orig/src/ChecksumCommand.o differ diff -uwN aria2-0.11.1+1/src/ChunkChecksum.h aria2-0.11.2.orig/src/ChunkChecksum.h --- aria2-0.11.1+1/src/ChunkChecksum.h 2007-05-20 06:57:56.000000000 -0700 +++ aria2-0.11.2.orig/src/ChunkChecksum.h 2007-08-08 07:40:11.000000000 -0700 @@ -40,11 +40,11 @@ class ChunkChecksum { private: - MessageDigestContext::DigestAlgo _algo; + string _algo; Strings _checksums; int32_t _checksumLength; public: - ChunkChecksum(const MessageDigestContext::DigestAlgo& algo, + ChunkChecksum(const string& algo, const Strings& checksums, int32_t checksumLength): _algo(algo), @@ -85,7 +85,7 @@ return _checksumLength; } - MessageDigestContext::DigestAlgo getAlgo() const + const string& getAlgo() const { return _algo; } diff -uwN aria2-0.11.1+1/src/ChunkChecksumValidator.cc aria2-0.11.2.orig/src/ChunkChecksumValidator.cc --- aria2-0.11.1+1/src/ChunkChecksumValidator.cc 2007-08-03 22:17:05.215875000 -0700 +++ aria2-0.11.2.orig/src/ChunkChecksumValidator.cc 2007-08-08 07:40:11.000000000 -0700 @@ -33,90 +33,34 @@ */ /* copyright --> */ #include "ChunkChecksumValidator.h" -#include "Util.h" -#include "Exception.h" #include "TimeA2.h" #include "message.h" -#ifdef ENABLE_MESSAGE_DIGEST -void ChunkChecksumValidator::validateSameLengthChecksum(BitfieldMan* bitfieldMan, - int32_t index, - const string& expectedChecksum, - int32_t dataLength, - int32_t checksumLength) +void ChunkChecksumValidator::validate() { - int64_t offset = ((int64_t)index)*checksumLength; - string actualChecksum = diskWriter->messageDigest(offset, dataLength, algo); - if(actualChecksum != expectedChecksum) { - logger->info(EX_INVALID_CHUNK_CHECKSUM, - index, Util::llitos(offset, true).c_str(), - expectedChecksum.c_str(), actualChecksum.c_str()); - bitfieldMan->unsetBit(index); - } -} - -void ChunkChecksumValidator::validateDifferentLengthChecksum(BitfieldMan* bitfieldMan, - int32_t index, - const string& expectedChecksum, - int32_t dataLength, - int32_t checksumLength) -{ - int64_t offset = ((int64_t)index)*checksumLength; - int32_t startIndex; - int32_t endIndex; - Util::indexRange(startIndex, endIndex, offset, - checksumLength, bitfieldMan->getBlockLength()); - if(bitfieldMan->isBitRangeSet(startIndex, endIndex)) { - string actualChecksum = diskWriter->messageDigest(offset, dataLength, algo); - if(expectedChecksum != actualChecksum) { - // wrong checksum - logger->info(EX_INVALID_CHUNK_CHECKSUM, - index, Util::llitos(offset, true).c_str(), - expectedChecksum.c_str(), actualChecksum.c_str()); - bitfieldMan->unsetBitRange(startIndex, endIndex); - } - } -} - -void ChunkChecksumValidator::validate(BitfieldMan* bitfieldMan, - const Strings& checksums, - int32_t checksumLength) -{ - // We assume file is already opened using DiskWriter::open or openExistingFile. - if(((int64_t)checksumLength*checksums.size()) < bitfieldMan->getTotalLength()) { + if(!_validator->canValidate()) { // insufficient checksums. logger->error(MSG_INSUFFICIENT_CHECKSUM, - checksumLength, checksums.size()); + _validator->getChunkChecksum()->getChecksumLength(), + _validator->getChunkChecksum()->countChecksum()); return; } - assert(bitfieldMan->getTotalLength()/checksumLength <= INT32_MAX); - int32_t x = bitfieldMan->getTotalLength()/checksumLength; - int32_t r = bitfieldMan->getTotalLength()%checksumLength; - void (ChunkChecksumValidator::*f)(BitfieldMan*, int32_t, const string&, int32_t, int32_t); - - if(checksumLength == bitfieldMan->getBlockLength()) { - f = &ChunkChecksumValidator::validateSameLengthChecksum; - } else { - f = &ChunkChecksumValidator::validateDifferentLengthChecksum; - } + _validator->init(); + int32_t numChecksum = _validator->getChunkChecksum()->countChecksum(); fileAllocationMonitor->setMinValue(0); - fileAllocationMonitor->setMaxValue(bitfieldMan->getTotalLength()); + fileAllocationMonitor->setMaxValue(numChecksum); fileAllocationMonitor->setCurrentValue(0); fileAllocationMonitor->showProgress(); Time cp; - for(int32_t i = 0; i < x; ++i) { - (this->*f)(bitfieldMan, i, checksums[i], checksumLength, checksumLength); + for(int32_t i = 0; i < numChecksum; ++i) { + _validator->validateChunk(); if(cp.elapsedInMillis(500)) { - fileAllocationMonitor->setCurrentValue(i*checksumLength); + fileAllocationMonitor->setCurrentValue(i+1); fileAllocationMonitor->showProgress(); cp.reset(); } } - if(r) { - (this->*f)(bitfieldMan, x, checksums[x], r, checksumLength); - } - fileAllocationMonitor->setCurrentValue(bitfieldMan->getTotalLength()); + fileAllocationMonitor->setCurrentValue(numChecksum); fileAllocationMonitor->showProgress(); } -#endif // ENABLE_MESSAGE_DIGEST diff -uwN aria2-0.11.1+1/src/ChunkChecksumValidator.h aria2-0.11.2.orig/src/ChunkChecksumValidator.h --- aria2-0.11.1+1/src/ChunkChecksumValidator.h 2007-05-20 06:51:52.000000000 -0700 +++ aria2-0.11.2.orig/src/ChunkChecksumValidator.h 2007-08-08 07:40:11.000000000 -0700 @@ -36,63 +36,33 @@ #define _D_CHUNK_CHECKSUM_VALIDATOR_H_ #include "common.h" -#include "DiskWriter.h" -#include "BitfieldMan.h" -#ifdef ENABLE_MESSAGE_DIGEST -#include "messageDigest.h" -#endif // ENABLE_MESSAGE_DIGEST #include "LogFactory.h" #include "FileAllocationMonitor.h" #include "NullFileAllocationMonitor.h" +#include "IteratableChunkChecksumValidator.h" class ChunkChecksumValidator { -#ifdef ENABLE_MESSAGE_DIGEST -protected: - DiskWriterHandle diskWriter; - - MessageDigestContext::DigestAlgo algo; +private: + IteratableChunkChecksumValidatorHandle _validator; FileAllocationMonitorHandle fileAllocationMonitor; const Logger* logger; - - void validateSameLengthChecksum(BitfieldMan* bitfieldMan, - int32_t index, - const string& expectedChecksum, - int32_t thisLength, - int32_t checksumLength); - - void validateDifferentLengthChecksum(BitfieldMan* bitfieldMan, - int32_t index, - const string& expectedChecksum, - int32_t thisLength, - int32_t checksumLength); public: - ChunkChecksumValidator(): - diskWriter(0), - algo(DIGEST_ALGO_SHA1), + ChunkChecksumValidator(const IteratableChunkChecksumValidatorHandle v): + _validator(v), fileAllocationMonitor(new NullFileAllocationMonitor()), logger(LogFactory::getInstance()) {} ~ChunkChecksumValidator() {} - void validate(BitfieldMan* bitfieldMan, - const Strings& checksums, - int32_t checksumLength); - - void setDiskWriter(const DiskWriterHandle& diskWriter) { - this->diskWriter = diskWriter; - } - - void setDigestAlgo(const MessageDigestContext::DigestAlgo& algo) { - this->algo = algo; - } + void validate(); void setFileAllocationMonitor(const FileAllocationMonitorHandle& monitor) { this->fileAllocationMonitor = monitor; } -#endif // ENABLE_MESSAGE_DIGEST }; +typedef SharedHandle ChunkChecksumValidatorHandle; #endif // _D_CHUNK_CHECKSUM_VALIDATOR_H_ diff -uwN aria2-0.11.1+1/src/DefaultBtContext.cc aria2-0.11.2.orig/src/DefaultBtContext.cc --- aria2-0.11.1+1/src/DefaultBtContext.cc 2007-08-03 22:17:05.309625000 -0700 +++ aria2-0.11.2.orig/src/DefaultBtContext.cc 2007-08-08 07:40:11.000000000 -0700 @@ -40,6 +40,8 @@ #include "DlAbortEx.h" #include "ShaVisitor.h" #include "Util.h" +#include "MessageDigestHelper.h" +#include "a2netcompat.h" #include DefaultBtContext::DefaultBtContext():_peerIdPrefix("-aria2-") {} @@ -245,3 +247,39 @@ int32_t DefaultBtContext::getNumPieces() const { return numPieces; } + +Integers DefaultBtContext::computeFastSet(const string& ipaddr, int32_t fastSetSize) +{ + Integers fastSet; + struct in_addr saddr; + if(inet_aton(ipaddr.c_str(), &saddr) == 0) { + abort(); + } + unsigned char tx[24]; + memcpy(tx, (void*)&saddr.s_addr, 4); + if((tx[0] & 0x80) == 0 || (tx[0] & 0x40) == 0) { + tx[2] = 0x00; + tx[3] = 0x00; + } else { + tx[3] = 0x00; + } + memcpy(tx+4, infoHash, 20); + unsigned char x[20]; + MessageDigestHelper::digest(x, sizeof(x), "sha1", tx, 24); + while((int32_t)fastSet.size() < fastSetSize) { + for(int32_t i = 0; i < 5 && (int32_t)fastSet.size() < fastSetSize; i++) { + int32_t j = i*4; + uint32_t ny; + memcpy(&ny, x+j, 4); + uint32_t y = ntohl(ny); + int32_t index = y%numPieces; + if(find(fastSet.begin(), fastSet.end(), index) == fastSet.end()) { + fastSet.push_back(index); + } + } + unsigned char temp[20]; + MessageDigestHelper::digest(temp, sizeof(temp), "sha1", x, sizeof(x)); + memcpy(x, temp, sizeof(x)); + } + return fastSet; +} diff -uwN aria2-0.11.1+1/src/DefaultBtContext.h aria2-0.11.2.orig/src/DefaultBtContext.h --- aria2-0.11.1+1/src/DefaultBtContext.h 2007-08-03 22:17:05.325250000 -0700 +++ aria2-0.11.2.orig/src/DefaultBtContext.h 2007-08-08 07:40:11.000000000 -0700 @@ -107,12 +107,26 @@ return (const unsigned char*)peerId.c_str(); } + virtual Integers computeFastSet(const string& ipaddr, int32_t fastSetSize); + string generatePeerId() const; void setPeerIdPrefix(const string& peerIdPrefix) { _peerIdPrefix = peerIdPrefix; } + + // for unit test + void setInfoHash(const unsigned char* infoHash) + { + memcpy(this->infoHash, infoHash, sizeof(this->infoHash)); + } + + void setNumPieces(int32_t numPieces) + { + this->numPieces = numPieces; + } + }; typedef SharedHandle DefaultBtContextHandle; diff -uwN aria2-0.11.1+1/src/DefaultBtInteractive.cc aria2-0.11.2.orig/src/DefaultBtInteractive.cc --- aria2-0.11.1+1/src/DefaultBtInteractive.cc 2007-08-03 22:17:05.325250000 -0700 +++ aria2-0.11.2.orig/src/DefaultBtInteractive.cc 2007-08-09 07:47:47.000000000 -0700 @@ -96,9 +96,7 @@ void DefaultBtInteractive::addAllowedFastMessageToQueue() { if(peer->isFastExtensionEnabled()) { - Integers fastSet = Util::computeFastSet(peer->ipaddr, - btContext->getInfoHash(), - btContext->getNumPieces(), + Integers fastSet = btContext->computeFastSet(peer->ipaddr, allowedFastSetSize); for(Integers::const_iterator itr = fastSet.begin(); itr != fastSet.end(); itr++) { @@ -280,7 +278,7 @@ void DefaultBtInteractive::checkActiveInteraction() { int32_t interval = 5*60; - if(inactiveCheckPoint.elapsed(interval) && btRuntime->getConnections() >= MAX_PEERS) { + if(inactiveCheckPoint.elapsed(interval)) { throw new DlAbortEx(EX_DROP_INACTIVE_CONNECTION, interval); } } diff -uwN aria2-0.11.1+1/src/DefaultPieceStorage.cc aria2-0.11.2.orig/src/DefaultPieceStorage.cc --- aria2-0.11.1+1/src/DefaultPieceStorage.cc 2007-08-03 22:17:05.403375000 -0700 +++ aria2-0.11.2.orig/src/DefaultPieceStorage.cc 2007-08-08 07:40:11.000000000 -0700 @@ -448,10 +448,15 @@ { logger->notice(MSG_VALIDATING_FILE, diskAdaptor->getFilePath().c_str()); - ChunkChecksumValidator v; - v.setDigestAlgo(DIGEST_ALGO_SHA1); - v.setDiskWriter(new DiskAdaptorWriter(diskAdaptor)); - v.setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor()); - v.validate(bitfieldMan, btContext->getPieceHashes(), + ChunkChecksumHandle chunkChecksum = new ChunkChecksum("sha1", + btContext->getPieceHashes(), btContext->getPieceLength()); + IteratableChunkChecksumValidatorHandle iv = new IteratableChunkChecksumValidator(); + iv->setDiskWriter(new DiskAdaptorWriter(diskAdaptor)); + iv->setBitfield(bitfieldMan); + iv->setChunkChecksum(chunkChecksum); + + ChunkChecksumValidator v(iv); + v.setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor()); + v.validate(); } diff -uwN aria2-0.11.1+1/src/DiskAdaptor.h aria2-0.11.2.orig/src/DiskAdaptor.h --- aria2-0.11.1+1/src/DiskAdaptor.h 2007-01-28 06:18:35.000000000 -0800 +++ aria2-0.11.2.orig/src/DiskAdaptor.h 2007-08-08 07:40:11.000000000 -0700 @@ -38,9 +38,6 @@ #include "common.h" #include "FileEntry.h" #include "Logger.h" -#ifdef ENABLE_MESSAGE_DIGEST -#include "messageDigest.h" -#endif // ENABLE_MESSAGE_DIGEST class DiskAdaptor { protected: @@ -63,17 +60,14 @@ virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) = 0; -#ifdef ENABLE_MESSAGE_DIGEST - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) = 0; -#endif // ENABLE_MESSAGE_DIGEST - virtual void onDownloadComplete() = 0; virtual bool fileExists() = 0; virtual string getFilePath() = 0; + virtual int64_t size() const = 0; + void setFileEntries(const FileEntries& fileEntries) { this->fileEntries = fileEntries; } Files aria2-0.11.1+1/src/DiskAdaptor.o and aria2-0.11.2.orig/src/DiskAdaptor.o differ diff -uwN aria2-0.11.1+1/src/DiskAdaptorWriter.h aria2-0.11.2.orig/src/DiskAdaptorWriter.h --- aria2-0.11.1+1/src/DiskAdaptorWriter.h 2007-05-20 06:51:52.000000000 -0700 +++ aria2-0.11.2.orig/src/DiskAdaptorWriter.h 2007-08-08 07:40:11.000000000 -0700 @@ -78,12 +78,6 @@ return diskAdaptor->readData((unsigned char*)data, len, position); } - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) - { - return diskAdaptor->messageDigest(offset, length, algo); - } - virtual void truncate(int64_t length) { throw new FatalException("DiskAdaptorWriter::truncate() is not implemented yet."); @@ -91,7 +85,7 @@ virtual int64_t size() const { - throw new FatalException("DiskAdaptorWriter::size() is not implemented yet."); + return diskAdaptor->size(); } }; diff -uwN aria2-0.11.1+1/src/DiskWriter.h aria2-0.11.2.orig/src/DiskWriter.h --- aria2-0.11.1+1/src/DiskWriter.h 2007-08-03 22:17:05.434625000 -0700 +++ aria2-0.11.2.orig/src/DiskWriter.h 2007-08-08 07:40:11.000000000 -0700 @@ -36,9 +36,6 @@ #define _D_DISK_WRITER_H_ #include "common.h" -#ifdef ENABLE_MESSAGE_DIGEST -#include "messageDigest.h" -#endif // ENABLE_MESSAGE_DIGEST using namespace std; @@ -90,10 +87,6 @@ virtual int32_t readData(unsigned char* data, int32_t len, int64_t position) { return readData((char*)data, len, position); } -#ifdef ENABLE_MESSAGE_DIGEST - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) = 0; -#endif // ENABLE_MESSAGE_DIGEST virtual void truncate(int64_t length) = 0; diff -uwN aria2-0.11.1+1/src/DownloadCommand.cc aria2-0.11.2.orig/src/DownloadCommand.cc --- aria2-0.11.1+1/src/DownloadCommand.cc 2007-08-03 22:17:05.450250000 -0700 +++ aria2-0.11.2.orig/src/DownloadCommand.cc 2007-08-08 07:40:11.000000000 -0700 @@ -118,7 +118,7 @@ _requestGroup->getSegmentMan()->completeSegment(cuid, segment); #ifdef ENABLE_MESSAGE_DIGEST if(e->option->get(PREF_REALTIME_CHUNK_CHECKSUM) == V_TRUE) { - _requestGroup->getSegmentMan()->tryChunkChecksumValidation(segment); + _requestGroup->getSegmentMan()->tryChunkChecksumValidation(segment, _requestGroup->getChunkChecksum()); } #endif // ENABLE_MESSAGE_DIGEST // this unit is going to download another segment. diff -uwN aria2-0.11.1+1/src/IteratableChecksumValidator.cc aria2-0.11.2.orig/src/IteratableChecksumValidator.cc --- aria2-0.11.1+1/src/IteratableChecksumValidator.cc 2007-05-31 08:56:20.000000000 -0700 +++ aria2-0.11.2.orig/src/IteratableChecksumValidator.cc 2007-08-08 07:40:11.000000000 -0700 @@ -76,6 +76,7 @@ _bitfield->setAllBit(); _currentOffset = 0; - _ctx = new MessageDigestContext(_checksum->getDigestAlgo()); + _ctx = new MessageDigestContext(); + _ctx->trySetAlgo(_checksum->getAlgo()); _ctx->digestInit(); } diff -uwN aria2-0.11.1+1/src/IteratableChunkChecksumValidator.cc aria2-0.11.2.orig/src/IteratableChunkChecksumValidator.cc --- aria2-0.11.1+1/src/IteratableChunkChecksumValidator.cc 2007-08-03 22:17:05.622125000 -0700 +++ aria2-0.11.2.orig/src/IteratableChunkChecksumValidator.cc 2007-08-08 07:40:11.000000000 -0700 @@ -35,6 +35,7 @@ #include "IteratableChunkChecksumValidator.h" #include "Util.h" #include "message.h" +#include "MessageDigestHelper.h" void IteratableChunkChecksumValidator::validateChunk() { @@ -65,7 +66,7 @@ { int64_t offset = ((int64_t)_currentIndex)*_chunkChecksum->getChecksumLength(); int32_t length = _diskWriter->size() < offset+_chunkChecksum->getChecksumLength() ? _diskWriter->size()-offset : _chunkChecksum->getChecksumLength(); - return _diskWriter->messageDigest(offset, length, _chunkChecksum->getAlgo()); + return MessageDigestHelper::digest(_chunkChecksum->getAlgo(), _diskWriter, offset, length); } bool IteratableChunkChecksumValidator::canValidate() const diff -uwN aria2-0.11.1+1/src/IteratableChunkChecksumValidator.h aria2-0.11.2.orig/src/IteratableChunkChecksumValidator.h --- aria2-0.11.1+1/src/IteratableChunkChecksumValidator.h 2007-06-05 04:37:25.000000000 -0700 +++ aria2-0.11.2.orig/src/IteratableChunkChecksumValidator.h 2007-08-08 07:40:11.000000000 -0700 @@ -89,6 +89,11 @@ { return _bitfield->getTotalLength(); } + + ChunkChecksumHandle getChunkChecksum() + { + return _chunkChecksum; + } }; typedef SharedHandle IteratableChunkChecksumValidatorHandle; diff -uwN aria2-0.11.1+1/src/MessageDigestHelper.cc aria2-0.11.2.orig/src/MessageDigestHelper.cc --- aria2-0.11.1+1/src/MessageDigestHelper.cc 1969-12-31 16:00:00.000000000 -0800 +++ aria2-0.11.2.orig/src/MessageDigestHelper.cc 2007-08-08 07:40:11.000000000 -0700 @@ -0,0 +1,101 @@ +/* */ +#include "MessageDigestHelper.h" +#include "messageDigest.h" +#include "DlAbortEx.h" +#include "message.h" +#include "DefaultDiskWriter.h" +#include "Util.h" +#include + +string MessageDigestHelper::digest(const string& algo, DiskWriterHandle diskWriter, int64_t offset, int64_t length) +{ + MessageDigestContext ctx; + ctx.trySetAlgo(algo); + ctx.digestInit(); + + int32_t BUFSIZE = 4096; + char BUF[BUFSIZE]; + int64_t iteration = length/BUFSIZE; + int32_t tail = length%BUFSIZE; + for(int64_t i = 0; i < iteration; ++i) { + int32_t readLength = diskWriter->readData(BUF, BUFSIZE, offset); + if(readLength != BUFSIZE) { + throw new DlAbortEx(EX_FILE_READ, "n/a", strerror(errno)); + } + ctx.digestUpdate(BUF, readLength); + offset += readLength; + } + if(tail) { + int32_t readLength = diskWriter->readData(BUF, tail, offset); + if(readLength != tail) { + throw new DlAbortEx(EX_FILE_READ, "n/a", strerror(errno)); + } + ctx.digestUpdate(BUF, readLength); + } + string rawMD = ctx.digestFinal(); + return Util::toHex((const unsigned char*)rawMD.c_str(), rawMD.size()); +} + +string MessageDigestHelper::digest(const string& algo, const string& filename) +{ + DiskWriterHandle writer = new DefaultDiskWriter(); + writer->openExistingFile(filename); + return digest(algo, writer); +} + +string MessageDigestHelper::digest(const string& algo, const void* data, int32_t length) +{ + MessageDigestContext ctx; + ctx.trySetAlgo(algo); + ctx.digestInit(); + ctx.digestUpdate(data, length); + string rawMD = ctx.digestFinal(); + return Util::toHex((const unsigned char*)rawMD.c_str(), rawMD.size()); +} + +void MessageDigestHelper::digest(unsigned char* md, int32_t mdLength, + const string& algo, const void* data, int32_t length) +{ + if(mdLength < MessageDigestContext::digestLength(algo)) { + throw new DlAbortEx("Insufficient space for storing message digest: %d required, but only %d is allocated", MessageDigestContext::digestLength(algo), mdLength); + } + MessageDigestContext ctx; + ctx.trySetAlgo(algo); + ctx.digestInit(); + ctx.digestUpdate(data, length); + ctx.digestFinal(md); +} + diff -uwN aria2-0.11.1+1/src/MessageDigestHelper.h aria2-0.11.2.orig/src/MessageDigestHelper.h --- aria2-0.11.1+1/src/MessageDigestHelper.h 1969-12-31 16:00:00.000000000 -0800 +++ aria2-0.11.2.orig/src/MessageDigestHelper.h 2007-08-08 07:40:11.000000000 -0700 @@ -0,0 +1,77 @@ +/* */ +#ifndef _D_MESSAGE_DIGEST_HELPER_H_ +#define _D_MESSAGE_DIGEST_HELPER_H_ + +#include "common.h" +#include "DiskWriter.h" + +class MessageDigestHelper { +public: + /** + * Returns message digest in hexadecimal notation. + * Digest algorithm is specified by algo. + */ + static string digest(const string& algo, DiskWriterHandle diskWriter, int64_t offset, int64_t length); + + /** + * Calculates message digest of file opened by diskWriter. + */ + static string digest(const string& algo, DiskWriterHandle diskWriter) + { + return digest(algo, diskWriter, 0, diskWriter->size()); + } + + /** + * Calculates message digest of file denoted by filename. + */ + static string digest(const string& algo, const string& filename); + + static string digest(const string& algo, const void* data, int32_t length); + + static string digestString(const string& algo, const string& data) + { + return digest(algo, data.c_str(), data.size()); + } + + /** + * Stores *raw* message digest into md. + * Throws exception when mdLength is less than the size of message digest. + */ + static void digest(unsigned char* md, int32_t mdLength, + const string& algo, const void* data, int32_t length); +}; + +#endif // _D_MESSAGE_DIGEST_HELPER_H_ Files aria2-0.11.1+1/src/MetaFileUtil.o and aria2-0.11.2.orig/src/MetaFileUtil.o differ diff -uwN aria2-0.11.1+1/src/MetalinkEntry.cc aria2-0.11.2.orig/src/MetalinkEntry.cc --- aria2-0.11.1+1/src/MetalinkEntry.cc 2007-08-03 22:17:05.700250000 -0700 +++ aria2-0.11.2.orig/src/MetalinkEntry.cc 2007-08-08 07:40:11.000000000 -0700 @@ -84,7 +84,9 @@ switch(res->type) { case MetalinkResource::TYPE_FTP: case MetalinkResource::TYPE_HTTP: +#ifdef ENABLE_SSL case MetalinkResource::TYPE_HTTPS: +#endif // ENABLE_SSL #ifdef ENABLE_BITTORRENT case MetalinkResource::TYPE_BITTORRENT: #endif // ENABLE_BITTORRENT diff -uwN aria2-0.11.1+1/src/MetalinkEntry.h aria2-0.11.2.orig/src/MetalinkEntry.h --- aria2-0.11.1+1/src/MetalinkEntry.h 2007-08-03 22:17:05.715875000 -0700 +++ aria2-0.11.2.orig/src/MetalinkEntry.h 2007-08-08 07:40:11.000000000 -0700 @@ -55,10 +55,9 @@ string version; string language; string os; - ChecksumHandle checksum; -public: MetalinkResources resources; #ifdef ENABLE_MESSAGE_DIGEST + ChecksumHandle checksum; ChunkChecksumHandle chunkChecksum; #endif // ENABLE_MESSAGE_DIGEST public: @@ -72,8 +71,8 @@ this->version = metalinkEntry.version; this->language = metalinkEntry.language; this->os = metalinkEntry.os; - this->checksum = metalinkEntry.checksum; #ifdef ENABLE_MESSAGE_DIGEST + this->checksum = metalinkEntry.checksum; this->chunkChecksum = metalinkEntry.chunkChecksum; #endif // ENABLE_MESSAGE_DIGEST } diff -uwN aria2-0.11.1+1/src/MetalinkRequestInfo.cc aria2-0.11.2.orig/src/MetalinkRequestInfo.cc --- aria2-0.11.1+1/src/MetalinkRequestInfo.cc 2007-08-03 22:17:05.715875000 -0700 +++ aria2-0.11.2.orig/src/MetalinkRequestInfo.cc 2007-08-08 09:01:58.000000000 -0700 @@ -131,15 +131,19 @@ entry->resources.end(), FindBitTorrentUrl()); Strings urls; +#ifdef ENABLE_MESSAGE_DIGEST ChecksumHandle checksum = 0; +#endif // ENABLE_MESSAGE_DIGEST if(itr == entry->resources.end()) { entry->reorderResourcesByPreference(); for_each(entry->resources.begin(), entry->resources.end(), AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT))); +#ifdef ENABLE_MESSAGE_DIGEST // TODO // set checksum checksum = entry->checksum; +#endif // ENABLE_MESSAGE_DIGEST } else { // BitTorrent downloading urls.push_back((*itr)->url); @@ -159,6 +163,8 @@ #endif // ENABLE_MESSAGE_DIGEST groups.push_front(rg); } + // clear PREF_OUT, because PREF_OUT is a filename for metalink file itself. + op->put(PREF_OUT, ""); MultiUrlRequestInfoHandle reqInfo = new MultiUrlRequestInfo(groups, op); nextReqInfos.push_back(reqInfo); } catch(RecoverableException* ex) { diff -uwN aria2-0.11.1+1/src/MultiDiskAdaptor.cc aria2-0.11.2.orig/src/MultiDiskAdaptor.cc --- aria2-0.11.1+1/src/MultiDiskAdaptor.cc 2007-08-03 22:17:05.731500000 -0700 +++ aria2-0.11.2.orig/src/MultiDiskAdaptor.cc 2007-08-08 07:40:11.000000000 -0700 @@ -37,7 +37,6 @@ #include "DlAbortEx.h" #include "message.h" #include "Util.h" -#include void MultiDiskAdaptor::resetDiskWriterEntries() { diskWriterEntries.clear(); @@ -169,63 +168,27 @@ return totalReadLength; } -void MultiDiskAdaptor::hashUpdate(MessageDigestContext& ctx, - const DiskWriterEntryHandle& entry, - int64_t offset, int64_t length) +bool MultiDiskAdaptor::fileExists() { - int32_t BUFSIZE = 16*1024; - unsigned char buf[BUFSIZE]; - for(int64_t i = 0; i < length/BUFSIZE; i++) { - if(BUFSIZE != entry->getDiskWriter()->readData(buf, BUFSIZE, offset)) { - throw new DlAbortEx(EX_FILE_SHA1SUM, "", strerror(errno)); - } - ctx.digestUpdate(buf, BUFSIZE); - offset += BUFSIZE; - } - int32_t r = length%BUFSIZE; - if(r > 0) { - if((int32_t)r != entry->getDiskWriter()->readData(buf, r, offset)) { - throw new DlAbortEx(EX_FILE_SHA1SUM, "", strerror(errno)); - } - ctx.digestUpdate(buf, r); - } + if(diskWriterEntries.empty()) { + resetDiskWriterEntries(); } - -string MultiDiskAdaptor::messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo) { - int64_t fileOffset = offset; - bool reading = false; - int32_t rem = length; - MessageDigestContext ctx(algo); - ctx.digestInit(); - for(DiskWriterEntries::iterator itr = diskWriterEntries.begin(); - itr != diskWriterEntries.end() && rem != 0; itr++) { - if(isInRange(*itr, offset) || reading) { - int32_t readLength = calculateLength((*itr), fileOffset, rem); - hashUpdate(ctx, *itr, fileOffset, readLength); - rem -= readLength; - reading = true; - fileOffset = 0; - } else { - fileOffset -= (*itr)->getFileEntry()->getLength(); - } + itr != diskWriterEntries.end(); itr++) { + if((*itr)->fileExists(getTopDirPath())) { + return true; } - if(!reading) { - throw new DlAbortEx(EX_FILE_OFFSET_OUT_OF_RANGE, Util::llitos(offset, true).c_str()); } - unsigned char hashValue[20]; - ctx.digestFinal(hashValue); - return Util::toHex(hashValue, 20); + return false; } -bool MultiDiskAdaptor::fileExists() +// TODO call DiskWriter::openFile() before calling this function. +int64_t MultiDiskAdaptor::size() const { - for(DiskWriterEntries::iterator itr = diskWriterEntries.begin(); + int64_t size = 0; + for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin(); itr != diskWriterEntries.end(); itr++) { - if((*itr)->fileExists(getTopDirPath())) { - return true; - } + size += (*itr)->size(); } - return false; + return size; } diff -uwN aria2-0.11.1+1/src/MultiDiskAdaptor.h aria2-0.11.2.orig/src/MultiDiskAdaptor.h --- aria2-0.11.1+1/src/MultiDiskAdaptor.h 2007-08-03 22:17:05.731500000 -0700 +++ aria2-0.11.2.orig/src/MultiDiskAdaptor.h 2007-08-08 07:40:11.000000000 -0700 @@ -81,6 +81,11 @@ return File(getFilePath(topDir)).exists(); } + int64_t size() const + { + return diskWriter->size(); + } + FileEntryHandle getFileEntry() const { return fileEntry; } @@ -115,10 +120,6 @@ int64_t fileOffset, int32_t rem) const; - void hashUpdate(MessageDigestContext& ctx, - const DiskWriterEntryHandle& entry, - int64_t offset, int64_t length); - string getTopDirPath() const; public: MultiDiskAdaptor():pieceLength(0), @@ -142,15 +143,14 @@ virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset); - virtual string messageDigest(int64_t offset, int64_t length, - const MessageDigestContext::DigestAlgo& algo); - virtual bool fileExists(); virtual string getFilePath() { return getTopDirPath(); } + virtual int64_t size() const; + void setTopDir(const string& topDir) { this->topDir = topDir; } diff -uwN aria2-0.11.1+1/src/Peer.cc aria2-0.11.2.orig/src/Peer.cc --- aria2-0.11.1+1/src/Peer.cc 2007-08-03 22:17:05.840875000 -0700 +++ aria2-0.11.2.orig/src/Peer.cc 2007-08-08 07:40:11.000000000 -0700 @@ -35,6 +35,7 @@ #include "Peer.h" #include "BitfieldManFactory.h" #include "Util.h" +#include "MessageDigestHelper.h" Peer::Peer(string ipaddr, int32_t port, int32_t pieceLength, int64_t totalLength): ipaddr(ipaddr), @@ -50,7 +51,7 @@ this->bitfield = BitfieldManFactory::getFactoryInstance()-> createBitfieldMan(pieceLength, totalLength); string idSeed = ipaddr+":"+Util::itos(port); - id = Util::simpleMessageDigest(idSeed); + id = MessageDigestHelper::digestString("sha1", idSeed); } /* diff -uwN aria2-0.11.1+1/src/SegmentMan.cc aria2-0.11.2.orig/src/SegmentMan.cc --- aria2-0.11.1+1/src/SegmentMan.cc 2007-08-03 22:17:06.028375000 -0700 +++ aria2-0.11.2.orig/src/SegmentMan.cc 2007-08-08 07:40:11.000000000 -0700 @@ -41,7 +41,7 @@ #include "LogFactory.h" #include "BitfieldManFactory.h" #ifdef ENABLE_MESSAGE_DIGEST -#include "ChunkChecksumValidator.h" +#include "MessageDigestHelper.h" #endif // ENABLE_MESSAGE_DIGEST #include "a2io.h" #include @@ -54,11 +54,6 @@ dir("."), errors(0), diskWriter(0) -#ifdef ENABLE_MESSAGE_DIGEST - , - chunkHashLength(0), - digestAlgo(DIGEST_ALGO_SHA1) -#endif // ENABLE_MESSAGE_DIGEST {} SegmentMan::~SegmentMan() { @@ -474,29 +469,16 @@ } #ifdef ENABLE_MESSAGE_DIGEST -void SegmentMan::checkIntegrity() -{ - logger->notice(MSG_VALIDATING_FILE, - getFilePath().c_str()); - ChunkChecksumValidator v; - v.setDigestAlgo(digestAlgo); - v.setDiskWriter(diskWriter); - v.setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor()); - v.validate(bitfield, pieceHashes, chunkHashLength); -} -#endif // ENABLE_MESSAGE_DIGEST - -#ifdef ENABLE_MESSAGE_DIGEST -bool SegmentMan::isChunkChecksumValidationReady() const { - return bitfield && totalSize > 0 && - ((int64_t)pieceHashes.size())*chunkHashLength >= totalSize; +bool SegmentMan::isChunkChecksumValidationReady(const ChunkChecksumHandle& chunkChecksum) const { + return !chunkChecksum.isNull() && bitfield && totalSize > 0 && + chunkChecksum->getEstimatedDataLength() >= totalSize; } #endif // ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST -void SegmentMan::tryChunkChecksumValidation(const SegmentHandle& segment) +void SegmentMan::tryChunkChecksumValidation(const SegmentHandle& segment, const ChunkChecksumHandle& chunkChecksum) { - if(!isChunkChecksumValidationReady()) { + if(!isChunkChecksumValidationReady(chunkChecksum)) { return; } int32_t hashStartIndex; @@ -504,13 +486,13 @@ Util::indexRange(hashStartIndex, hashEndIndex, segment->getPosition(), segment->writtenLength, - chunkHashLength); - if(!bitfield->isBitSetOffsetRange((int64_t)hashStartIndex*chunkHashLength, - chunkHashLength)) { + chunkChecksum->getChecksumLength()); + if(!bitfield->isBitSetOffsetRange((int64_t)hashStartIndex*chunkChecksum->getChecksumLength(), + chunkChecksum->getChecksumLength())) { ++hashStartIndex; } - if(!bitfield->isBitSetOffsetRange((int64_t)hashEndIndex*chunkHashLength, - chunkHashLength)) { + if(!bitfield->isBitSetOffsetRange((int64_t)hashEndIndex*chunkChecksum->getChecksumLength(), + chunkChecksum->getChecksumLength())) { --hashEndIndex; } logger->debug("hashStartIndex=%d, hashEndIndex=%d", @@ -519,27 +501,27 @@ logger->debug(MSG_NO_CHUNK_CHECKSUM); return; } - int64_t hashOffset = ((int64_t)hashStartIndex)*chunkHashLength; + int64_t hashOffset = ((int64_t)hashStartIndex)*chunkChecksum->getChecksumLength(); int32_t startIndex; int32_t endIndex; Util::indexRange(startIndex, endIndex, hashOffset, - (hashEndIndex-hashStartIndex+1)*chunkHashLength, + (hashEndIndex-hashStartIndex+1)*chunkChecksum->getChecksumLength(), bitfield->getBlockLength()); logger->debug("startIndex=%d, endIndex=%d", startIndex, endIndex); if(bitfield->isBitRangeSet(startIndex, endIndex)) { for(int32_t index = hashStartIndex; index <= hashEndIndex; ++index) { - int64_t offset = ((int64_t)index)*chunkHashLength; + int64_t offset = ((int64_t)index)*chunkChecksum->getChecksumLength(); int32_t dataLength = - offset+chunkHashLength <= totalSize ? chunkHashLength : totalSize-offset; - string actualChecksum = diskWriter->messageDigest(offset, dataLength, digestAlgo); - string expectedChecksum = pieceHashes[index]; - if(expectedChecksum == actualChecksum) { - logger->info(MSG_GOOD_CHUNK_CHECKSUM); + offset+chunkChecksum->getChecksumLength() <= totalSize ? + chunkChecksum->getChecksumLength() : totalSize-offset; + string actualChecksum = MessageDigestHelper::digest(chunkChecksum->getAlgo(), diskWriter, offset, dataLength); + if(chunkChecksum->validateChunk(actualChecksum, index)) { + logger->info(MSG_GOOD_CHUNK_CHECKSUM, actualChecksum.c_str()); } else { logger->info(EX_INVALID_CHUNK_CHECKSUM, index, Util::llitos(offset, true).c_str(), - expectedChecksum.c_str(), actualChecksum.c_str()); + chunkChecksum->getChecksum(index).c_str(), actualChecksum.c_str()); logger->debug("Unset bit from %d to %d(inclusive)", startIndex, endIndex); bitfield->unsetBitRange(startIndex, endIndex); break; diff -uwN aria2-0.11.1+1/src/SegmentMan.h aria2-0.11.2.orig/src/SegmentMan.h --- aria2-0.11.1+1/src/SegmentMan.h 2007-08-03 22:17:06.044000000 -0700 +++ aria2-0.11.2.orig/src/SegmentMan.h 2007-08-08 07:40:11.000000000 -0700 @@ -43,6 +43,9 @@ #include "Request.h" #include "BitfieldMan.h" #include "PeerStat.h" +#ifdef ENABLE_MESSAGE_DIGEST +# include "ChunkChecksum.h" +#endif // ENABLE_MESSAGE_DIGEST using namespace std; @@ -157,12 +160,6 @@ DiskWriterHandle diskWriter; Requests reserved; -#ifdef ENABLE_MESSAGE_DIGEST - Strings pieceHashes; - int32_t chunkHashLength; - MessageDigestContext::DigestAlgo digestAlgo; -#endif // ENABLE_MESSAGE_DIGEST - SegmentMan(); ~SegmentMan(); @@ -300,11 +297,9 @@ } #ifdef ENABLE_MESSAGE_DIGEST - void checkIntegrity(); - - void tryChunkChecksumValidation(const SegmentHandle& segment); + void tryChunkChecksumValidation(const SegmentHandle& segment, const ChunkChecksumHandle& chunkChecksum); - bool isChunkChecksumValidationReady() const; + bool isChunkChecksumValidationReady(const ChunkChecksumHandle& chunkChecksum) const; #endif // ENABLE_MESSAGE_DIGEST }; diff -uwN aria2-0.11.1+1/src/ShaVisitor.cc aria2-0.11.2.orig/src/ShaVisitor.cc --- aria2-0.11.1+1/src/ShaVisitor.cc 2007-01-24 07:55:34.000000000 -0800 +++ aria2-0.11.2.orig/src/ShaVisitor.cc 2007-08-08 07:40:11.000000000 -0700 @@ -35,8 +35,9 @@ #include "ShaVisitor.h" #include "Util.h" -ShaVisitor::ShaVisitor(): - ctx(DIGEST_ALGO_SHA1) { +ShaVisitor::ShaVisitor() +{ + ctx.trySetAlgo("sha1"); ctx.digestInit(); } diff -uwN aria2-0.11.1+1/src/SimpleRandomizer.h aria2-0.11.2.orig/src/SimpleRandomizer.h --- aria2-0.11.1+1/src/SimpleRandomizer.h 2007-08-03 22:17:06.075250000 -0700 +++ aria2-0.11.2.orig/src/SimpleRandomizer.h 2007-08-08 07:40:11.000000000 -0700 @@ -54,27 +54,22 @@ } static void init() { -#ifdef HAVE_SRANDOM - srandom(time(0)); -#else srand(time(0)); -#endif } virtual ~SimpleRandomizer() {} virtual long int getRandomNumber() { -#ifdef HAVE_RANDOM - return random(); -#else return rand(); -#endif } virtual long int getMaxRandomNumber() { return RAND_MAX; } + /** + * Returns random number in [0, to). + */ virtual long int getRandomNumber(long int to) { return(int32_t)(((double)to)*getRandomNumber()/(getMaxRandomNumber()+1.0)); diff -uwN aria2-0.11.1+1/src/TorrentRequestInfo.cc aria2-0.11.2.orig/src/TorrentRequestInfo.cc --- aria2-0.11.1+1/src/TorrentRequestInfo.cc 2007-08-03 22:17:06.169000000 -0700 +++ aria2-0.11.2.orig/src/TorrentRequestInfo.cc 2007-08-08 07:40:11.000000000 -0700 @@ -80,7 +80,7 @@ if(BT_PROGRESS_INFO_FILE(btContext)->exists()) { // load .aria2 file if it exists. BT_PROGRESS_INFO_FILE(btContext)->load(); - PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile(); + PIECE_STORAGE(btContext)->getDiskAdaptor()->openFile(); #ifdef ENABLE_MESSAGE_DIGEST if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) { PIECE_STORAGE(btContext)->checkIntegrity(); @@ -94,7 +94,7 @@ BT_PROGRESS_INFO_FILE(btContext)->getFilename().c_str()); throw new FatalException(EX_DOWNLOAD_ABORTED); } else { - PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile(); + PIECE_STORAGE(btContext)->getDiskAdaptor()->openFile(); #ifdef ENABLE_MESSAGE_DIGEST if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) { PIECE_STORAGE(btContext)->markAllPiecesDone(); @@ -103,7 +103,7 @@ #endif // ENABLE_MESSAGE_DIGEST } } else { - PIECE_STORAGE(btContext)->getDiskAdaptor()->initAndOpenFile(); + PIECE_STORAGE(btContext)->getDiskAdaptor()->openFile(); } } diff -uwN aria2-0.11.1+1/src/Util.cc aria2-0.11.2.orig/src/Util.cc --- aria2-0.11.1+1/src/Util.cc 2007-08-03 22:17:06.215875000 -0700 +++ aria2-0.11.2.orig/src/Util.cc 2007-08-08 07:40:11.000000000 -0700 @@ -480,93 +480,6 @@ return trim(header.substr(filenamesp, filenameep-filenamesp), "\r\n '\""); } -#ifdef ENABLE_MESSAGE_DIGEST -void Util::sha1Sum(unsigned char* digest, const void* data, int32_t dataLength) { - MessageDigestContext ctx(DIGEST_ALGO_SHA1); - ctx.digestInit(); - ctx.digestUpdate(data, dataLength); - ctx.digestFinal(digest); -} - -string Util::simpleMessageDigest(const string& data) { - unsigned char checksum[20]; - sha1Sum(checksum, data.c_str(), data.size()); - return Util::toHex(checksum, sizeof(checksum)); -} - -#endif // ENABLE_MESSAGE_DIGEST - -#ifdef ENABLE_MESSAGE_DIGEST -void Util::fileChecksum(const string& filename, unsigned char* digest, - MessageDigestContext::DigestAlgo algo) { - MessageDigestContext ctx(algo); - ctx.digestInit(); - - int32_t BUFLEN = 4096; - char buf[BUFLEN]; - - int32_t fd; - if((fd = open(filename.c_str(), O_RDWR|O_BINARY, OPEN_MODE)) < 0) { - throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno)); - } - while(1) { - int32_t size = read(fd, buf, BUFLEN); - if(size == -1) { - if(errno == EINTR) { - continue; - } else { - close(fd); - throw new DlAbortEx(EX_FILE_READ, filename.c_str(), strerror(errno)); - } - } else if(size > 0) { - ctx.digestUpdate(buf, size); - } - if(size < BUFLEN) { - break; - } - } - ctx.digestFinal(digest); -} -#endif // ENABLE_MESSAGE_DIGEST - -#ifdef ENABLE_BITTORRENT -Integers Util::computeFastSet(string ipaddr, const unsigned char* infoHash, - int32_t pieces, int32_t fastSetSize) { - Integers fastSet; - struct in_addr saddr; - if(inet_aton(ipaddr.c_str(), &saddr) == 0) { - abort(); - } - unsigned char tx[24]; - memcpy(tx, (void*)&saddr.s_addr, 4); - if((tx[0] & 0x80) == 0 || (tx[0] & 0x40) == 0) { - tx[2] = 0x00; - tx[3] = 0x00; - } else { - tx[3] = 0x00; - } - memcpy(tx+4, infoHash, 20); - unsigned char x[20]; - sha1Sum(x, tx, 24); - while((int32_t)fastSet.size() < fastSetSize) { - for(int32_t i = 0; i < 5 && (int32_t)fastSet.size() < fastSetSize; i++) { - int32_t j = i*4; - uint32_t ny; - memcpy(&ny, x+j, 4); - uint32_t y = ntohl(ny); - int32_t index = y%pieces; - if(find(fastSet.begin(), fastSet.end(), index) == fastSet.end()) { - fastSet.push_back(index); - } - } - unsigned char temp[20]; - sha1Sum(temp, x, 20); - memcpy(x, temp, sizeof(x)); - } - return fastSet; -} -#endif // ENABLE_BITTORRENT - static int32_t nbits[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, diff -uwN aria2-0.11.1+1/src/Util.h aria2-0.11.2.orig/src/Util.h --- aria2-0.11.1+1/src/Util.h 2007-08-03 22:17:06.215875000 -0700 +++ aria2-0.11.2.orig/src/Util.h 2007-08-08 07:40:11.000000000 -0700 @@ -36,15 +36,10 @@ #define _D_UTIL_H_ #include "common.h" -#include "FileEntry.h" #include "a2time.h" -#ifdef ENABLE_MESSAGE_DIGEST -#include "messageDigest.h" -#endif // ENABLE_MESSAGE_DIGEST -#include +#include "FileEntry.h" #include #include -#include #include #define STRTOLL(X) strtoll(X, (char**)NULL, 10); @@ -111,24 +106,6 @@ // this function temporarily put here static string getContentDispositionFilename(const string& header); - // digest must be at least 20 bytes long. -#ifdef ENABLE_MESSAGE_DIGEST - static void sha1Sum(unsigned char* digest, const void* data, int32_t dataLength); - static string simpleMessageDigest(const string& data); -#endif // ENABLE_MESSAGE_DIGEST - - // Before call this method, allocate enough memory to the parameter "digest". - // For sha1, you need 20 bytes. For md5, 16 bytes. -#ifdef ENABLE_MESSAGE_DIGEST - static void fileChecksum(const string& filename, unsigned char* digest, - MessageDigestContext::DigestAlgo algo); -#endif // ENABLE_MESSAGE_DIGEST - -#ifdef ENABLE_BITTORRENT - static Integers computeFastSet(string ipaddr, const unsigned char* infoHash, - int32_t pieces, int32_t fastSetSize); -#endif // ENABLE_BITTORRENT - static int32_t countBit(uint32_t n); static string randomAlpha(int32_t length); diff -uwN aria2-0.11.1+1/src/Xml2MetalinkProcessor.cc aria2-0.11.2.orig/src/Xml2MetalinkProcessor.cc --- aria2-0.11.1+1/src/Xml2MetalinkProcessor.cc 2007-07-07 20:22:37.000000000 -0700 +++ aria2-0.11.2.orig/src/Xml2MetalinkProcessor.cc 2007-08-08 07:40:11.000000000 -0700 @@ -111,20 +111,36 @@ entry->language = Util::trim(xpathContent(xpath+"/m:language")); entry->os = Util::trim(xpathContent(xpath+"/m:os")); #ifdef ENABLE_MESSAGE_DIGEST - string md; - md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]"))); - if(md.size() > 0) { - entry->checksum = new Checksum(); - entry->checksum->setMessageDigest(md); - entry->checksum->setDigestAlgo(DIGEST_ALGO_SHA1); - } else { - md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]"))); - if(md.size() > 0) { - entry->checksum = new Checksum(); - entry->checksum->setMessageDigest(md); - entry->checksum->setDigestAlgo(DIGEST_ALGO_MD5); + xmlXPathObjectPtr hashPathObj = xpathEvaluation(xpath+"/m:verification/m:hash"); + if(hashPathObj) { + xmlNodeSetPtr nodeSet = hashPathObj->nodesetval; + for(int32_t i = 0; i < nodeSet->nodeNr; ++i) { + xmlNodePtr node = nodeSet->nodeTab[i]; + string algo = Util::trim(xmlAttribute(node, "type")); + if(MessageDigestContext::supports(algo)) { + entry->checksum = new Checksum(algo, Util::trim(xmlContent(node))); + break; + } } } + xmlXPathFreeObject(hashPathObj); + + string piecesPath = xpath+"/m:verification/m:pieces"; + xmlXPathObjectPtr pieceHashPathObj = xpathEvaluation(piecesPath); + if(pieceHashPathObj) { + xmlNodeSetPtr nodeSet = pieceHashPathObj->nodesetval; + for(int32_t i = 0; i < nodeSet->nodeNr; ++i) { + xmlNodePtr node = nodeSet->nodeTab[i]; + string algo = Util::trim(xmlAttribute(node, "type")); + if(MessageDigestContext::supports(algo)) { + entry->chunkChecksum = getPieceHash(piecesPath+"[@type=\""+algo+"\"]", + entry->getLength()); + break; + } + } + } + xmlXPathFreeObject(pieceHashPathObj); + /* string piecesPath = xpath+"/m:verification/m:pieces"; string sha1PiecesPath = piecesPath+"[@type=\"sha1\"]"; string md5PiecesPath = piecesPath+"[@type=\"md5\"]"; @@ -133,6 +149,7 @@ } else if(xpathExists(md5PiecesPath)) { entry->chunkChecksum = getPieceHash(md5PiecesPath, entry->getLength()); } + */ #endif // ENABLE_MESSAGE_DIGEST for(int index = 1; 1; index++) { MetalinkResourceHandle resource(getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]")); @@ -159,12 +176,8 @@ int64_t checksumLength = STRTOLL(Util::trim(xmlAttribute(node, "length")).c_str()); string algoString = Util::trim(xmlAttribute(node, "type")); xmlXPathFreeObject(result); - MessageDigestContext::DigestAlgo algo; - if(algoString == "sha1") { - algo = DIGEST_ALGO_SHA1; - } else if(algoString == "md5") { - algo = DIGEST_ALGO_MD5; - } else { + + if(!MessageDigestContext::supports(algoString)) { // unknown checksum type return 0; } @@ -178,7 +191,7 @@ } checksums.push_back(pieceHash); } - return new ChunkChecksum(algo, checksums, checksumLength); + return new ChunkChecksum(algoString, checksums, checksumLength); } #endif // ENABLE_MESSAGE_DIGEST diff -uwN aria2-0.11.1+1/src/main.cc aria2-0.11.2.orig/src/main.cc --- aria2-0.11.1+1/src/main.cc 2007-08-04 23:46:31.701750000 -0700 +++ aria2-0.11.2.orig/src/main.cc 2007-08-09 07:50:08.000000000 -0700 @@ -89,6 +89,9 @@ cout << PACKAGE << _(" version ") << PACKAGE_VERSION << endl; cout << "**Configuration**" << endl; cout << FeatureConfig::getInstance()->getConfigurationSummary(); +#ifdef ENABLE_MESSAGE_DIGEST + cout << "message digest algorithms: " << MessageDigestContext::getSupportedAlgoString() << endl; +#endif // ENABLE_MESSAGE_DIGEST cout << endl; cout << "Copyright (C) 2006, 2007 Tatsuhiro Tsujikawa" << endl; cout << endl; @@ -107,9 +110,8 @@ "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"); cout << endl; - cout << _("Contact Info:\n") << endl; + cout << _("Contact Info:") << endl; cout << "Tatsuhiro Tsujikawa " << endl; - cout << "Ross Smith II (Windows port)" << endl; cout << endl; } @@ -151,7 +153,7 @@ cout << _(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects all URLs.") << endl; cout << _(" --http-user=USER Set HTTP user. This affects all URLs.") << endl; cout << _(" --http-passwd=PASSWD Set HTTP password. This affects all URLs.") << endl; - cout << _(" --http-proxy-user=USER Set HTTP proxy user. This affects all URLs") << endl; + cout << _(" --http-proxy-user=USER Set HTTP proxy user. This affects all URLs.") << endl; cout << _(" --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects all URLs.") << endl; cout << _(" --http-proxy-method=METHOD Set the method to use in proxy request.\n" " METHOD is either 'get' or 'tunnel'.\n" @@ -257,6 +259,13 @@ " encouraged. If --seed-time option is specified\n" " along with this option, seeding ends when at\n" " least one of the conditions is satisfied.") << endl; + cout << _(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID in\n" + " in BitTorrent is 20 byte length. If more than 20\n" + " bytes are specified, only first 20\n" + " bytes are used. If less than 20 bytes are\n" + " specified, the random alphabet characters are\n" + " added to make it's length 20 bytes.\n" + " Default: -aria2-") << endl; #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK cout << _(" -M, --metalink-file=METALINK_FILE The file path to the .metalink file.") << endl; diff -uwN aria2-0.11.1+1/src/message.h aria2-0.11.2.orig/src/message.h --- aria2-0.11.1+1/src/message.h 2007-08-03 22:17:06.403375000 -0700 +++ aria2-0.11.2.orig/src/message.h 2007-08-08 07:40:11.000000000 -0700 @@ -118,7 +118,7 @@ #define MSG_SEEDING_END _("Seeding is over.") #define MSG_SEGMENT_FORWARDING _("CUID#%d cancels segment index=%d. CUID#%d handles it instead.") #define MSG_NO_CHUNK_CHECKSUM _("No chunk to verify.") -#define MSG_GOOD_CHUNK_CHECKSUM _("Good chunk checksum.") +#define MSG_GOOD_CHUNK_CHECKSUM _("Good chunk checksum. hash=%s") #define MSG_LOADING_COOKIE_FAILED _("Failed to load cookies from %s") #define MSG_INCORRECT_NETRC_PERMISSION _(".netrc file %s does not have correct permissions. It should be 600. netrc support disabled.") #define MSG_LOGGING_STARTED _("Logging started.") diff -uwN aria2-0.11.1+1/src/messageDigest.cc aria2-0.11.2.orig/src/messageDigest.cc --- aria2-0.11.1+1/src/messageDigest.cc 1969-12-31 16:00:00.000000000 -0800 +++ aria2-0.11.2.orig/src/messageDigest.cc 2007-08-08 07:40:11.000000000 -0700 @@ -0,0 +1,63 @@ +/* */ +#include "messageDigest.h" + +static MessageDigestContext::DigestAlgoMap::value_type digests[] = { +#ifdef HAVE_LIBSSL + MessageDigestContext::DigestAlgoMap::value_type("md5", EVP_md5()), + MessageDigestContext::DigestAlgoMap::value_type("sha1", EVP_sha1()), +# ifdef HAVE_EVP_SHA256 + MessageDigestContext::DigestAlgoMap::value_type("sha256", EVP_sha256()), +# endif // HAVE_EVP_SHA256 +#elif HAVE_LIBGCRYPT + MessageDigestContext::DigestAlgoMap::value_type("md5", GCRY_MD_MD5), + MessageDigestContext::DigestAlgoMap::value_type("sha1", GCRY_MD_SHA1), + MessageDigestContext::DigestAlgoMap::value_type("sha256", GCRY_MD_SHA256), +#endif // HAVE_LIBGCRYPT +}; + +MessageDigestContext::DigestAlgoMap +MessageDigestContext::digestAlgos(&digests[0], + &digests[sizeof(digests)/sizeof(DigestAlgoMap::value_type)]); + +string MessageDigestContext::digestFinal() +{ + int32_t length = digestLength(algo); + unsigned char* rawMD = new unsigned char[length]; + digestFinal(rawMD); + string rawMDString(&rawMD[0], &rawMD[length]); + delete [] rawMD; + return rawMDString; +} diff -uwN aria2-0.11.1+1/src/messageDigest.h aria2-0.11.2.orig/src/messageDigest.h --- aria2-0.11.1+1/src/messageDigest.h 2007-08-03 22:17:06.419000000 -0700 +++ aria2-0.11.2.orig/src/messageDigest.h 2007-08-08 07:40:11.000000000 -0700 @@ -36,10 +36,8 @@ #define _D_MESSAGE_DIGEST_H_ #include "common.h" - -#ifdef ENABLE_SSL - -#define MAX_MD_LENGTH (16+20) +#include "FatalException.h" +#include #ifdef HAVE_LIBSSL #include @@ -53,14 +51,11 @@ public: #ifdef HAVE_LIBSSL typedef const EVP_MD* DigestAlgo; -# define DIGEST_ALGO_MD5 EVP_md5() -# define DIGEST_ALGO_SHA1 EVP_sha1() #endif // HAVE_LIBSSL #ifdef HAVE_LIBGCRYPT typedef int32_t DigestAlgo; -# define DIGEST_ALGO_MD5 GCRY_MD_MD5 -# define DIGEST_ALGO_SHA1 GCRY_MD_SHA1 #endif // HAVE_LIBGCRYPT + typedef map DigestAlgoMap; private: #ifdef HAVE_LIBSSL EVP_MD_CTX ctx; @@ -69,17 +64,58 @@ gcry_md_hd_t ctx; #endif // HAVE_LIBGCRYPT DigestAlgo algo; + + static DigestAlgoMap digestAlgos; public: - MessageDigestContext(): - algo(DIGEST_ALGO_SHA1) {} - MessageDigestContext(DigestAlgo algo): - algo(algo) {} + MessageDigestContext():algo(getDigestAlgo("sha1")) + {} ~MessageDigestContext() { digestFree(); } + void trySetAlgo(const string& algostring) + { + algo = getDigestAlgo(algostring); + } + + static bool supports(const string& algostring) + { + DigestAlgoMap::const_iterator itr = digestAlgos.find(algostring); + if(itr == digestAlgos.end()) { + return false; + } else { + return true; + } + } + + static DigestAlgo getDigestAlgo(const string& algostring) + { + DigestAlgoMap::const_iterator itr = digestAlgos.find(algostring); + if(itr == digestAlgos.end()) { + throw new FatalException("Digest algorithm %s is not supported.", algostring.c_str()); + } + return (*itr).second; + } + + static string getSupportedAlgoString() + { + string algos; + for(DigestAlgoMap::const_iterator itr = digestAlgos.begin(); + itr != digestAlgos.end(); ++itr) { + algos += (*itr).first+" "; + } + return algos; + } + + static int digestLength(const string& algostring) + { + return digestLength(getDigestAlgo(algostring)); + } + + string digestFinal(); + #if defined(HAVE_OLD_LIBSSL) void digestInit() {EVP_DigestInit(&ctx, algo);} void digestReset() {EVP_DigestInit(&ctx, algo);} @@ -147,5 +183,4 @@ #endif // HAVE_LIBGCRYPT }; typedef SharedHandle MessageDigestContextHandle; -#endif // ENABLE_SSL #endif // _D_MESSAGE_DIGEST_H_