2007-08-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

MessageDigestHelper is introduced in order to simplify the use
	of message digest. Removed repeated code.
	The message digest algorithm is now specified by string, like 
"sha1",
	"md5".
	* src/messageDigest.{h, cc}
	* src/MessageDigestHelper.{h, cc}: New class.
	* src/DefaultPieceStorage.cc
	* src/DefaultBtContext.{h, cc}
	(computeFastSet): New function.
	(setInfoHash): Added for unit testing.
	(setNumPieces): Added for unit testing.
	* src/DefaultBtInteractive.cc
	* src/BtPieceMessage.cc
	* src/Peer.cc
	* src/Checksum.h
	* src/message.h
	* src/IteratableChecksumValidator.h
	* src/ChunkChecksumValidator.{h, cc}: Use 
IteratableChecksumValidator
	inside it.
	* src/SegmentMan.{h, cc}
	(checkIntegrity): Removed.
	* src/IteratableChunkChecksumValidator.{h, cc}
	* src/Util.h
	(sha1Sum): Removed.
	(simpleMessageDigest): Removed.
	(fileChecksum): Removed.
	(computeFastSet): Removed.
	* src/ShaVisitor.cc
	* src/ChunkChecksum.h
	* src/DownloadCommand.cc

	Removed messageDigest virtual functions.
	* src/MultiDiskAdaptor.{h, cc}
	* src/DiskAdaptor.h
	* src/ByteArrayDiskWriter.h
	* src/DiskWriter.h
	* src/DiskAdaptorWriter.h
	* src/AbstractSingleDiskAdaptor.{h, cc}
	* src/AbstractDiskWriter.{h, cc}
	
	Fixed comilation error when message digest is disabled.
	* src/MetalinkEntry.{h, cc}
	* src/MetalinkRequestInfo.cc
	
	Removed srandom and random.
	* src/SimpleRandomizer.h

	Added size() virtual function to DiskAdaptor
	* src/MultiDiskAdaptor.h

	Fixed the bug that causes that files are not opened correctly in
	multi-file torrent.
	* src/TorrentRequestInfo.cc
	* src/MultiDiskAdaptor.cc
	
	Added SHA256 support
	* src/messageDigest.cc
	* src/Xml2MetalinkProcessor.cc

	Show supported message digest algorithms
	* src/main.cc

	Updated contact info.
	* src/main.cc
This commit is contained in:
Tatsuhiro Tsujikawa 2007-08-08 14:40:11 +00:00
parent 45f949c713
commit e85f9ccfd6
67 changed files with 1230 additions and 787 deletions

View File

@ -1 +1,2 @@
Tatsuhiro Tsujikawa <tujikawa at users dot sourceforge dot net>
Ross Smith II <aria2spam at netebb dot com> (Windows port)

View File

@ -1,3 +1,70 @@
2007-08-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
MessageDigestHelper is introduced in order to simplify the use
of message digest. Removed repeated code.
The message digest algorithm is now specified by string, like "sha1",
"md5".
* src/messageDigest.{h, cc}
* src/MessageDigestHelper.{h, cc}: New class.
* src/DefaultPieceStorage.cc
* src/DefaultBtContext.{h, cc}
(computeFastSet): New function.
(setInfoHash): Added for unit testing.
(setNumPieces): Added for unit testing.
* src/DefaultBtInteractive.cc
* src/BtPieceMessage.cc
* src/Peer.cc
* src/Checksum.h
* src/message.h
* src/IteratableChecksumValidator.h
* src/ChunkChecksumValidator.{h, cc}: Use IteratableChecksumValidator
inside it.
* src/SegmentMan.{h, cc}
(checkIntegrity): Removed.
* src/IteratableChunkChecksumValidator.{h, cc}
* src/Util.h
(sha1Sum): Removed.
(simpleMessageDigest): Removed.
(fileChecksum): Removed.
(computeFastSet): Removed.
* src/ShaVisitor.cc
* src/ChunkChecksum.h
* src/DownloadCommand.cc
Removed messageDigest virtual functions.
* src/MultiDiskAdaptor.{h, cc}
* src/DiskAdaptor.h
* src/ByteArrayDiskWriter.h
* src/DiskWriter.h
* src/DiskAdaptorWriter.h
* src/AbstractSingleDiskAdaptor.{h, cc}
* src/AbstractDiskWriter.{h, cc}
Fixed comilation error when message digest is disabled.
* src/MetalinkEntry.{h, cc}
* src/MetalinkRequestInfo.cc
Removed srandom and random.
* src/SimpleRandomizer.h
Added size() virtual function to DiskAdaptor
* src/MultiDiskAdaptor.h
Fixed the bug that causes that files are not opened correctly in
multi-file torrent.
* src/TorrentRequestInfo.cc
* src/MultiDiskAdaptor.cc
Added SHA256 support
* src/messageDigest.cc
* src/Xml2MetalinkProcessor.cc
Show supported message digest algorithms
* src/main.cc
Updated contact info.
* src/main.cc
2007-08-02 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Merged Dan's patch:
@ -9,6 +76,10 @@
Updated contact info.
* src/main.cc
Added #ifdef ENABLE_MESSAGE_DIGEST to fix test errors when message
digest is not available.
* src/MetalinkEntry.h
2007-08-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Make a2netcompat.h include a2io.h to fix compilation error:

View File

@ -53,6 +53,12 @@
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the `EVP_DigestInit_ex' function. */
#undef HAVE_EVP_DIGESTINIT_EX
/* Define to 1 if you have the `EVP_sha256' function. */
#undef HAVE_EVP_SHA256
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@ -199,6 +205,9 @@
/* Define to 1 if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define to 1 if you have old openssl. */
#undef HAVE_OLD_LIBSSL
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV

199
configure vendored
View File

@ -5280,7 +5280,7 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5
echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6; }
if test $ac_cv_lib_ssl_SSL_library_init = yes; then
have_openssl=yes
have_openssl=yes; LIBS="-lssl $LIBS"
fi
@ -5342,7 +5342,7 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_main" >&5
echo "${ECHO_T}$ac_cv_lib_crypto_main" >&6; }
if test $ac_cv_lib_crypto_main = yes; then
have_openssl=yes
have_openssl=yes; LIBS="-lcrypto $LIBS"
fi
if test "x$have_openssl" = "xyes"; then
@ -5351,10 +5351,205 @@ cat >>confdefs.h <<\_ACEOF
#define HAVE_LIBSSL 1
_ACEOF
for ac_func in EVP_DigestInit_ex
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval echo '${'$as_ac_var'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
have_digestinit_ex=yes
fi
done
if test "x$have_digestinit_ex" = "x"; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_OLD_LIBSSL 1
_ACEOF
fi
OPENSSL_LIBS="-L$openssl_prefix_lib -lssl -lcrypto"
OPENSSL_CFLAGS="-I$openssl_prefix_include"
for ac_func in EVP_sha256
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval echo '${'$as_ac_var'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
fi
fi

View File

@ -18,17 +18,24 @@ CPPFLAGS_save=$CPPFLAGS
LIBS="-L$openssl_prefix_lib $LIBS"
CPPFLAGS="-I$openssl_prefix_include $CPPFLAGS"
AC_CHECK_LIB([ssl], [SSL_library_init], [have_openssl=yes])
AC_CHECK_LIB([ssl], [SSL_library_init], [have_openssl=yes; LIBS="-lssl $LIBS"])
if test "x$have_openssl" = "xyes"; then
have_openssl=no
AC_CHECK_LIB([crypto], [main], [have_openssl=yes])
AC_CHECK_LIB([crypto], [main], [have_openssl=yes; LIBS="-lcrypto $LIBS"])
if test "x$have_openssl" = "xyes"; then
AC_DEFINE([HAVE_LIBSSL], [1], [Define to 1 if you have openssl.])
dnl check whether EVP_DigestInit_ex exists. Old openssl doesn't have it.
AC_CHECK_FUNCS([EVP_DigestInit_ex], [have_digestinit_ex=yes])
if test "x$have_digestinit_ex" = "x"; then
AC_DEFINE([HAVE_OLD_LIBSSL], [1], [Define to 1 if you have old openssl.])
fi
OPENSSL_LIBS="-L$openssl_prefix_lib -lssl -lcrypto"
OPENSSL_CFLAGS="-I$openssl_prefix_include"
AC_SUBST(OPENSSL_LIBS)
AC_SUBST(OPENSSL_CFLAGS)
dnl search for sha256 support
AC_CHECK_FUNCS([EVP_sha256])
fi
fi

View File

@ -113,36 +113,6 @@ int32_t AbstractDiskWriter::readDataInternal(char* data, int32_t len) {
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 @@ void AbstractDiskWriter::truncate(int64_t length)
ftruncate(fd, length);
}
// TODO the file descriptor fd must be opened before calling this function.
int64_t AbstractDiskWriter::size() const
{
struct stat fileStat;

View File

@ -65,11 +65,6 @@ public:
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);

View File

@ -59,10 +59,6 @@ int32_t AbstractSingleDiskAdaptor::readData(unsigned char* data, int32_t len, in
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();

View File

@ -60,11 +60,13 @@ public:
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;
}

View File

@ -84,6 +84,9 @@ public:
* 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<BtContext> BtContextHandle;

View File

@ -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 @@ string BtPieceMessage::toString() const {
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) {

View File

@ -66,14 +66,6 @@ public:
{
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_

View File

@ -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<Checksum> ChecksumHandle;

View File

@ -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 @@ public:
return _checksumLength;
}
MessageDigestContext::DigestAlgo getAlgo() const
const string& getAlgo() const
{
return _algo;
}

View File

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

View File

@ -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<ChunkChecksumValidator> ChunkChecksumValidatorHandle;
#endif // _D_CHUNK_CHECKSUM_VALIDATOR_H_

View File

@ -40,6 +40,8 @@
#include "DlAbortEx.h"
#include "ShaVisitor.h"
#include "Util.h"
#include "MessageDigestHelper.h"
#include "a2netcompat.h"
#include <libgen.h>
DefaultBtContext::DefaultBtContext():_peerIdPrefix("-aria2-") {}
@ -245,3 +247,39 @@ int32_t DefaultBtContext::getPieceLength() const {
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;
}

View File

@ -107,12 +107,26 @@ private:
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<DefaultBtContext> DefaultBtContextHandle;

View File

@ -96,10 +96,8 @@ void DefaultBtInteractive::addBitfieldMessageToQueue() {
void DefaultBtInteractive::addAllowedFastMessageToQueue() {
if(peer->isFastExtensionEnabled()) {
Integers fastSet = Util::computeFastSet(peer->ipaddr,
btContext->getInfoHash(),
btContext->getNumPieces(),
allowedFastSetSize);
Integers fastSet = btContext->computeFastSet(peer->ipaddr,
allowedFastSetSize);
for(Integers::const_iterator itr = fastSet.begin();
itr != fastSet.end(); itr++) {
dispatcher->addMessageToQueue(messageFactory->createAllowedFastMessage(*itr));

View File

@ -448,10 +448,15 @@ void DefaultPieceStorage::checkIntegrity()
{
logger->notice(MSG_VALIDATING_FILE,
diskAdaptor->getFilePath().c_str());
ChunkChecksumValidator v;
v.setDigestAlgo(DIGEST_ALGO_SHA1);
v.setDiskWriter(new DiskAdaptorWriter(diskAdaptor));
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(bitfieldMan, btContext->getPieceHashes(),
btContext->getPieceLength());
v.validate();
}

View File

@ -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 @@ public:
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;
}

View File

@ -78,12 +78,6 @@ public:
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 @@ public:
virtual int64_t size() const
{
throw new FatalException("DiskAdaptorWriter::size() is not implemented yet.");
return diskAdaptor->size();
}
};

View File

@ -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 @@ public:
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;

View File

@ -118,7 +118,7 @@ bool DownloadCommand::executeInternal() {
_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.

View File

@ -76,6 +76,7 @@ void IteratableChecksumValidator::init()
_bitfield->setAllBit();
_currentOffset = 0;
_ctx = new MessageDigestContext(_checksum->getDigestAlgo());
_ctx = new MessageDigestContext();
_ctx->trySetAlgo(_checksum->getAlgo());
_ctx->digestInit();
}

View File

@ -35,6 +35,7 @@
#include "IteratableChunkChecksumValidator.h"
#include "Util.h"
#include "message.h"
#include "MessageDigestHelper.h"
void IteratableChunkChecksumValidator::validateChunk()
{
@ -65,7 +66,7 @@ string IteratableChunkChecksumValidator::calculateActualChecksum()
{
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

View File

@ -89,6 +89,11 @@ public:
{
return _bitfield->getTotalLength();
}
ChunkChecksumHandle getChunkChecksum()
{
return _chunkChecksum;
}
};
typedef SharedHandle<IteratableChunkChecksumValidator> IteratableChunkChecksumValidatorHandle;

View File

@ -45,7 +45,6 @@ SRCS = Socket.h\
Option.cc Option.h\
Base64.cc Base64.h\
CookieBox.cc CookieBox.h\
messageDigest.h\
LogFactory.cc LogFactory.h\
NullLogger.h\
TimeA2.cc TimeA2.h\
@ -109,7 +108,9 @@ SRCS += ChunkChecksumValidator.cc ChunkChecksumValidator.h\
ChecksumCommand.cc ChecksumCommand.h\
CheckIntegrityCommand.cc CheckIntegrityCommand.h\
CheckIntegrityEntry.cc CheckIntegrityEntry.h\
CheckIntegrityMan.h
CheckIntegrityMan.h\
messageDigest.cc messageDigest.h\
MessageDigestHelper.cc MessageDigestHelper.h
endif # ENABLE_MESSAGE_DIGEST
if ENABLE_BITTORRENT

View File

@ -46,7 +46,9 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_MESSAGE_DIGEST_TRUE@ ChecksumCommand.cc ChecksumCommand.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityCommand.cc CheckIntegrityCommand.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityEntry.cc CheckIntegrityEntry.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityMan.h
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityMan.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ messageDigest.cc messageDigest.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelper.cc MessageDigestHelper.h
@ENABLE_BITTORRENT_TRUE@am__append_2 = MetaEntry.h\
@ENABLE_BITTORRENT_TRUE@ Data.cc Data.h\
@ -219,8 +221,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.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 TimeA2.cc TimeA2.h SharedHandle.h \
CookieBox.cc CookieBox.h LogFactory.cc LogFactory.h \
NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
SpeedCalc.cc SpeedCalc.h PeerStat.h BitfieldMan.cc \
@ -259,9 +261,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
IteratableChecksumValidator.cc IteratableChecksumValidator.h \
ChecksumCommand.cc ChecksumCommand.h CheckIntegrityCommand.cc \
CheckIntegrityCommand.h CheckIntegrityEntry.cc \
CheckIntegrityEntry.h CheckIntegrityMan.h MetaEntry.h Data.cc \
Data.h Dictionary.cc Dictionary.h List.cc List.h \
MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
CheckIntegrityEntry.h CheckIntegrityMan.h messageDigest.cc \
messageDigest.h MessageDigestHelper.cc MessageDigestHelper.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 PeerConnection.cc PeerConnection.h \
PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
@ -338,7 +341,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidator.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ ChecksumCommand.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityCommand.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityEntry.$(OBJEXT)
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityEntry.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ messageDigest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelper.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@am__objects_2 = Data.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.$(OBJEXT) \
@ -676,8 +681,8 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.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 TimeA2.cc TimeA2.h SharedHandle.h \
CookieBox.cc CookieBox.h LogFactory.cc LogFactory.h \
NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
SpeedCalc.cc SpeedCalc.h PeerStat.h BitfieldMan.cc \
@ -902,6 +907,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkRequestInfo.Po@am__quote@
@ -960,6 +966,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localtime_r.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messageDigest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strptime.Po@am__quote@
.c.o:

101
src/MessageDigestHelper.cc Normal file
View File

@ -0,0 +1,101 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "MessageDigestHelper.h"
#include "messageDigest.h"
#include "DlAbortEx.h"
#include "message.h"
#include "DefaultDiskWriter.h"
#include "Util.h"
#include <errno.h>
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);
}

77
src/MessageDigestHelper.h Normal file
View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#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_

View File

@ -39,7 +39,7 @@
MetalinkEntry::MetalinkEntry()
#ifdef ENABLE_MESSAGE_DIGEST
:checksum(0),
chunkChecksum(0)
chunkChecksum(0)
#endif // ENABLE_MESSAGE_DIGEST
{}
@ -84,7 +84,9 @@ public:
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

View File

@ -55,10 +55,9 @@ public:
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 @@ public:
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
}

View File

@ -131,15 +131,19 @@ RequestInfos MetalinkRequestInfo::execute() {
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);

View File

@ -37,7 +37,6 @@
#include "DlAbortEx.h"
#include "message.h"
#include "Util.h"
#include <errno.h>
void MultiDiskAdaptor::resetDiskWriterEntries() {
diskWriterEntries.clear();
@ -169,58 +168,11 @@ int32_t MultiDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t off
return totalReadLength;
}
void MultiDiskAdaptor::hashUpdate(MessageDigestContext& ctx,
const DiskWriterEntryHandle& entry,
int64_t offset, int64_t length)
{
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);
}
}
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();
}
}
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);
}
bool MultiDiskAdaptor::fileExists()
{
if(diskWriterEntries.empty()) {
resetDiskWriterEntries();
}
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->fileExists(getTopDirPath())) {
@ -229,3 +181,14 @@ bool MultiDiskAdaptor::fileExists()
}
return false;
}
// TODO call DiskWriter::openFile() before calling this function.
int64_t MultiDiskAdaptor::size() const
{
int64_t size = 0;
for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
size += (*itr)->size();
}
return size;
}

View File

@ -81,6 +81,11 @@ public:
return File(getFilePath(topDir)).exists();
}
int64_t size() const
{
return diskWriter->size();
}
FileEntryHandle getFileEntry() const {
return fileEntry;
}
@ -115,10 +120,6 @@ private:
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 @@ public:
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;
}

View File

@ -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 @@ Peer::Peer(string ipaddr, int32_t port, int32_t pieceLength, int64_t totalLength
this->bitfield = BitfieldManFactory::getFactoryInstance()->
createBitfieldMan(pieceLength, totalLength);
string idSeed = ipaddr+":"+Util::itos(port);
id = Util::simpleMessageDigest(idSeed);
id = MessageDigestHelper::digestString("sha1", idSeed);
}
/*

View File

@ -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 <errno.h>
@ -54,11 +54,6 @@ SegmentMan::SegmentMan():logger(LogFactory::getInstance()),
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 @@ void SegmentMan::markPieceDone(int64_t length)
}
#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);
bool SegmentMan::isChunkChecksumValidationReady(const ChunkChecksumHandle& chunkChecksum) const {
return !chunkChecksum.isNull() && bitfield && totalSize > 0 &&
chunkChecksum->getEstimatedDataLength() >= totalSize;
}
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_MESSAGE_DIGEST
bool SegmentMan::isChunkChecksumValidationReady() const {
return bitfield && totalSize > 0 &&
((int64_t)pieceHashes.size())*chunkHashLength >= 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 @@ void SegmentMan::tryChunkChecksumValidation(const SegmentHandle& segment)
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 @@ void SegmentMan::tryChunkChecksumValidation(const SegmentHandle& segment)
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;

View File

@ -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 @@ public:
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 @@ public:
}
#ifdef ENABLE_MESSAGE_DIGEST
void checkIntegrity();
void tryChunkChecksumValidation(const SegmentHandle& segment, const ChunkChecksumHandle& chunkChecksum);
void tryChunkChecksumValidation(const SegmentHandle& segment);
bool isChunkChecksumValidationReady() const;
bool isChunkChecksumValidationReady(const ChunkChecksumHandle& chunkChecksum) const;
#endif // ENABLE_MESSAGE_DIGEST
};

View File

@ -35,8 +35,9 @@
#include "ShaVisitor.h"
#include "Util.h"
ShaVisitor::ShaVisitor():
ctx(DIGEST_ALGO_SHA1) {
ShaVisitor::ShaVisitor()
{
ctx.trySetAlgo("sha1");
ctx.digestInit();
}

View File

@ -54,27 +54,22 @@ public:
}
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));

View File

@ -80,7 +80,7 @@ RequestInfos TorrentRequestInfo::execute() {
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 @@ RequestInfos TorrentRequestInfo::execute() {
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 @@ RequestInfos TorrentRequestInfo::execute() {
#endif // ENABLE_MESSAGE_DIGEST
}
} else {
PIECE_STORAGE(btContext)->getDiskAdaptor()->initAndOpenFile();
PIECE_STORAGE(btContext)->getDiskAdaptor()->openFile();
}
}

View File

@ -480,93 +480,6 @@ string Util::getContentDispositionFilename(const string& header) {
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,

View File

@ -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 <string>
#include "FileEntry.h"
#include <utility>
#include <deque>
#include <stdio.h>
#include <ostream>
#define STRTOLL(X) strtoll(X, (char**)NULL, 10);
@ -111,28 +106,10 @@ public:
// 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);
static string toUpper(const string& src);
static string toLower(const string& src);

View File

@ -111,20 +111,36 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
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 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
} 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 @@ ChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xpath,
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 @@ ChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xpath,
}
checksums.push_back(pieceHash);
}
return new ChunkChecksum(algo, checksums, checksumLength);
return new ChunkChecksum(algoString, checksums, checksumLength);
}
#endif // ENABLE_MESSAGE_DIGEST

View File

@ -71,7 +71,6 @@ extern int optind, opterr, optopt;
#ifdef ENABLE_METALINK
#include "MetalinkRequestInfo.h"
#include "Xml2MetalinkProcessor.h"
#endif
#ifdef HAVE_LIBSSL
@ -89,6 +88,9 @@ void showVersion() {
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;
@ -109,7 +111,6 @@ void showVersion() {
cout << endl;
cout << _("Contact Info:") << endl;
cout << "Tatsuhiro Tsujikawa <tujikawa at users dot sourceforge dot net>" << endl;
cout << "Ross Smith II <aria2spam at netebb dot com> (Windows port)" << endl;
cout << endl;
}

View File

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

63
src/messageDigest.cc Normal file
View File

@ -0,0 +1,63 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#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;
}

View File

@ -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 <map>
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
@ -53,14 +51,11 @@ class MessageDigestContext {
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<string, MessageDigestContext::DigestAlgo> DigestAlgoMap;
private:
#ifdef HAVE_LIBSSL
EVP_MD_CTX ctx;
@ -69,17 +64,58 @@ private:
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 @@ public:
#endif // HAVE_LIBGCRYPT
};
typedef SharedHandle<MessageDigestContext> MessageDigestContextHandle;
#endif // ENABLE_SSL
#endif // _D_MESSAGE_DIGEST_H_

View File

@ -17,10 +17,25 @@ private:
static const char* csArray[];// = { "29b0e7878271645fffb7eec7db4a7473a1c00bc1",
// "4df75a661cb7eb2733d9cdaa7f772eae3a4e2976",
// "0a4ea2f7dd7c52ddf2099a444ab2184b4d341bdb" };
public:
void setUp() {
}
ChunkChecksumValidatorHandle
createChunkChecksumValidator(const string& filename, BitfieldMan* bitfield, const ChunkChecksumHandle& chunkChecksum)
{
IteratableChunkChecksumValidatorHandle iv = new IteratableChunkChecksumValidator();
DefaultDiskWriterHandle dw = new DefaultDiskWriter();
dw->openExistingFile(filename);
iv->setDiskWriter(dw);
iv->setBitfield(bitfield);
iv->setChunkChecksum(chunkChecksum);
return new ChunkChecksumValidator(iv);
}
void testValidate();
void testValidate2();
void testValidate3();
@ -30,114 +45,127 @@ public:
CPPUNIT_TEST_SUITE_REGISTRATION( ChunkChecksumValidatorTest );
const char* ChunkChecksumValidatorTest::csArray[] = { "29b0e7878271645fffb7eec7db4a7473a1c00bc1",
"4df75a661cb7eb2733d9cdaa7f772eae3a4e2976",
"0a4ea2f7dd7c52ddf2099a444ab2184b4d341bdb" };
const char* ChunkChecksumValidatorTest::csArray[] =
{ "29b0e7878271645fffb7eec7db4a7473a1c00bc1",
"4df75a661cb7eb2733d9cdaa7f772eae3a4e2976",
"0a4ea2f7dd7c52ddf2099a444ab2184b4d341bdb" };
void ChunkChecksumValidatorTest::testValidate() {
#ifdef ENABLE_MESSAGE_DIGEST
BitfieldMan bitfieldMan(100, 250);
bitfieldMan.setAllBit();
Strings checksums(&csArray[0], &csArray[3]);
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
ChunkChecksumValidator validator;
validator.setDiskWriter(diskWriter);
validator.validate(&bitfieldMan, checksums, 100);
ChunkChecksumValidatorHandle validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isAllBitSet());
checksums[1] = "ffffffffffffffffffffffffffffffffffffffff";
validator.validate(&bitfieldMan, checksums, 100);
validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isBitSet(0));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(1));
CPPUNIT_ASSERT(bitfieldMan.isBitSet(2));
#endif /* ENABLE_MESSAGE_DIGEST */
}
void ChunkChecksumValidatorTest::testValidate2() {
#ifdef ENABLE_MESSAGE_DIGEST
BitfieldMan bitfieldMan(50, 250);
bitfieldMan.setAllBit();
Strings checksums(&csArray[0], &csArray[3]);
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
ChunkChecksumValidator validator;
validator.setDiskWriter(diskWriter);
validator.validate(&bitfieldMan, checksums, 100);
ChunkChecksumValidatorHandle validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isAllBitSet());
checksums[1] = "ffffffffffffffffffffffffffffffffffffffff";
validator.validate(&bitfieldMan, checksums, 100);
validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isBitSet(0));
CPPUNIT_ASSERT(bitfieldMan.isBitSet(1));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(2));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(3));
CPPUNIT_ASSERT(bitfieldMan.isBitSet(4));
#endif /* ENABLE_MESSAGE_DIGEST */
}
void ChunkChecksumValidatorTest::testValidate3() {
#ifdef ENABLE_MESSAGE_DIGEST
BitfieldMan bitfieldMan(50, 250);
bitfieldMan.setAllBit();
Strings checksums;
checksums.push_back("898a81b8e0181280ae2ee1b81e269196d91e869a");
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
ChunkChecksumValidator validator;
validator.setDiskWriter(diskWriter);
validator.validate(&bitfieldMan, checksums, 250);
ChunkChecksumValidatorHandle validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
250));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isAllBitSet());
checksums[0] = "ffffffffffffffffffffffffffffffffffffffff";
validator.validate(&bitfieldMan, checksums, 250);
validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
250));
validator->validate();
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(0));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(1));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(2));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(3));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(4));
#endif /* ENABLE_MESSAGE_DIGEST */
}
void ChunkChecksumValidatorTest::testValidate4() {
#ifdef ENABLE_MESSAGE_DIGEST
BitfieldMan bitfieldMan(70, 250);
bitfieldMan.setAllBit();
Strings checksums(&csArray[0], &csArray[3]);
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
ChunkChecksumValidator validator;
validator.setDiskWriter(diskWriter);
validator.validate(&bitfieldMan, checksums, 100);
ChunkChecksumValidatorHandle validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isAllBitSet());
checksums[1] = "ffffffffffffffffffffffffffffffffffffffff";
validator.validate(&bitfieldMan, checksums, 100);
validator =
createChunkChecksumValidator("chunkChecksumTestFile250.txt",
&bitfieldMan, new ChunkChecksum("sha1",
checksums,
100));
validator->validate();
CPPUNIT_ASSERT(bitfieldMan.isBitSet(0));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(1));
CPPUNIT_ASSERT(!bitfieldMan.isBitSet(2));
CPPUNIT_ASSERT(bitfieldMan.isBitSet(3));
#endif /* ENABLE_MESSAGE_DIGEST */
}

View File

@ -23,6 +23,7 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testGetPieceLength);
CPPUNIT_TEST(testGetInfoHashAsString);
CPPUNIT_TEST(testGetPeerId);
CPPUNIT_TEST(testComputeFastSet);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
@ -43,6 +44,7 @@ public:
void testGetPieceLength();
void testGetInfoHashAsString();
void testGetPeerId();
void testComputeFastSet();
};
@ -224,3 +226,31 @@ void DefaultBtContextTest::testGetPeerId() {
DefaultBtContext btContext;
Util::torrentUrlencode(btContext.getPeerId(), 20);
}
void DefaultBtContextTest::testComputeFastSet()
{
string ipaddr = "192.168.0.1";
unsigned char infoHash[20];
memset(infoHash, 0, sizeof(infoHash));
infoHash[0] = 0xff;
int pieces = 1000;
int fastSetSize = 10;
DefaultBtContext btContext;
btContext.setInfoHash(infoHash);
btContext.setNumPieces(pieces);
Integers fastSet = btContext.computeFastSet(ipaddr, fastSetSize);
//for_each(fastSet.begin(), fastSet.end(), Printer());
//cerr << endl;
int ans1[] = { 686, 459, 278, 200, 404, 834, 64, 203, 760, 950 };
Integers ansSet1(&ans1[0], &ans1[10]);
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet1.begin()));
ipaddr = "10.0.0.1";
fastSet = btContext.computeFastSet(ipaddr, fastSetSize);
int ans2[] = { 568, 188, 466, 452, 550, 662, 109, 226, 398, 11 };
Integers ansSet2(&ans2[0], &ans2[10]);
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
}

View File

@ -55,6 +55,24 @@ public:
}
};
class SortMockBtRequestMessage {
public:
bool operator()(const SharedHandle<MockBtRequestMessage>& a,
const SharedHandle<MockBtRequestMessage>& b) {
if(a->index < b->index) {
return true;
} else if(b->index < a->index) {
return false;
} else if(a->blockIndex < b->blockIndex) {
return true;
} else if(b->blockIndex < a->blockIndex) {
return false;
} else {
return true;
}
}
};
void setUp() {
BtRegistry::clear();
btContext = new MockBtContext();
@ -142,6 +160,8 @@ void DefaultBtRequestFactoryTest::testCreateRequestMessages_onEndGame() {
BtMessages msgs = btRequestFactory->createRequestMessagesOnEndGame(3);
sort(msgs.begin(), msgs.end(), SortMockBtRequestMessage());
CPPUNIT_ASSERT_EQUAL((size_t)3, msgs.size());
BtMessages::iterator itr = msgs.begin();
MockBtRequestMessage* msg = (MockBtRequestMessage*)itr->get();
@ -150,11 +170,11 @@ void DefaultBtRequestFactoryTest::testCreateRequestMessages_onEndGame() {
++itr;
msg = (MockBtRequestMessage*)itr->get();
CPPUNIT_ASSERT_EQUAL(1, msg->index);
CPPUNIT_ASSERT_EQUAL(1, msg->blockIndex);
CPPUNIT_ASSERT_EQUAL(0, msg->blockIndex);
++itr;
msg = (MockBtRequestMessage*)itr->get();
CPPUNIT_ASSERT_EQUAL(1, msg->index);
CPPUNIT_ASSERT_EQUAL(0, msg->blockIndex);
CPPUNIT_ASSERT_EQUAL(1, msg->blockIndex);
}
void DefaultBtRequestFactoryTest::testRemoveTargetPiece() {

View File

@ -1,5 +1,4 @@
#include "DefaultDiskWriter.h"
#include <string>
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
@ -7,7 +6,7 @@ using namespace std;
class DefaultDiskWriterTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DefaultDiskWriterTest);
CPPUNIT_TEST(testMessageDigest);
CPPUNIT_TEST(testSize);
CPPUNIT_TEST_SUITE_END();
private:
@ -15,24 +14,16 @@ public:
void setUp() {
}
void testMessageDigest();
void testSize();
};
CPPUNIT_TEST_SUITE_REGISTRATION( DefaultDiskWriterTest );
void DefaultDiskWriterTest::testMessageDigest() {
#ifdef ENABLE_MESSAGE_DIGEST
void DefaultDiskWriterTest::testSize()
{
DefaultDiskWriter dw;
dw.openExistingFile("4096chunk.txt");
CPPUNIT_ASSERT_EQUAL(string("608cabc0f2fa18c260cafd974516865c772363d5"),
dw.messageDigest(0, 4096, DIGEST_ALGO_SHA1));
CPPUNIT_ASSERT_EQUAL(string("7a4a9ae537ebbbb826b1060e704490ad0f365ead"),
dw.messageDigest(5, 100, DIGEST_ALGO_SHA1));
dw.closeFile();
#endif // ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL((int64_t)4096, dw.size());
}

View File

@ -31,8 +31,13 @@ void FeatureConfigTest::testGetDefaultPort() {
void FeatureConfigTest::testIsSupported() {
CPPUNIT_ASSERT_EQUAL(true,
FeatureConfig::getInstance()->isSupported("http"));
#ifdef ENABLE_SSL
CPPUNIT_ASSERT_EQUAL(true,
FeatureConfig::getInstance()->isSupported("https"));
#else
CPPUNIT_ASSERT_EQUAL(false,
FeatureConfig::getInstance()->isSupported("https"));
#endif // ENABLE_SSL
CPPUNIT_ASSERT_EQUAL(true,
FeatureConfig::getInstance()->isSupported("ftp"));
CPPUNIT_ASSERT_EQUAL(false,
@ -41,11 +46,32 @@ void FeatureConfigTest::testIsSupported() {
void FeatureConfigTest::testGetConfigurationSummary() {
CPPUNIT_ASSERT_EQUAL(string("http: yes\n")
#ifdef ENABLE_SSL
+"https: yes\n"
#else
+"https: no\n"
#endif // ENABLE_SSL
+"ftp: yes\n"
#ifdef ENABLE_BITTORRENT
+"bittorrent: yes\n"
#else
+"bittorrent: no\n"
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
+"metalink: yes\n"
#else
+"metalink: no\n"
#endif // ENABLE_METALINK
#ifdef ENABLE_MESSAGE_DIGEST
+"message digest: yes\n"
+"async dns: yes\n",
#else
+"message digest: no\n"
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_ASYNC_DNS
+"async dns: yes\n"
#else
+"async dns: no\n"
#endif // ENABLE_ASYNC_DNS
,
FeatureConfig::getInstance()->getConfigurationSummary());
}

View File

@ -27,7 +27,8 @@ void IteratableChecksumValidatorTest::testValidate() {
BitfieldMan bitfieldMan(100, 250);
bitfieldMan.setAllBit();
ChecksumHandle checksum = new Checksum("898a81b8e0181280ae2ee1b81e269196d91e869a", DIGEST_ALGO_SHA1);
ChecksumHandle checksum = new Checksum("sha1",
"898a81b8e0181280ae2ee1b81e269196d91e869a");
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
@ -48,7 +49,7 @@ void IteratableChecksumValidatorTest::testValidate2() {
BitfieldMan bitfieldMan(100, 250);
bitfieldMan.setAllBit();
ChecksumHandle checksum = new Checksum("ffffffffffffffffffffffffffffffffffffffff", DIGEST_ALGO_SHA1);
ChecksumHandle checksum = new Checksum("sha1", "ffffffffffffffffffffffffffffffffffffffff");
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");

View File

@ -46,7 +46,7 @@ void IteratableChunkChecksumValidatorTest::testValidate() {
DefaultDiskWriterHandle diskWriter = new DefaultDiskWriter();
diskWriter->openExistingFile("chunkChecksumTestFile250.txt");
ChunkChecksumHandle chunkChecksum = new ChunkChecksum(DIGEST_ALGO_SHA1,
ChunkChecksumHandle chunkChecksum = new ChunkChecksum("sha1",
checksums,
100);
IteratableChunkChecksumValidator validator;
@ -64,7 +64,7 @@ void IteratableChunkChecksumValidatorTest::testValidate() {
CPPUNIT_ASSERT(bitfieldMan.isAllBitSet());
checksums[1] = "ffffffffffffffffffffffffffffffffffffffff";
chunkChecksum = new ChunkChecksum(DIGEST_ALGO_SHA1,
chunkChecksum = new ChunkChecksum("sha1",
checksums,
100);
validator.setChunkChecksum(chunkChecksum);

View File

@ -10,12 +10,7 @@ aria2c_SOURCES = AllTest.cc\
CookieParserTest.cc\
HttpRequestTest.cc\
CookieBoxFactoryTest.cc\
ByteArrayDiskWriterTest.cc\
RequestGroupManTest.cc\
IteratableChecksumValidatorTest.cc\
IteratableChunkChecksumValidatorTest.cc\
PeerTest.cc\
DefaultPeerStorageTest.cc\
RequestFactoryTest.cc\
NetrcAuthResolverTest.cc\
DefaultAuthResolverTest.cc\
@ -32,25 +27,19 @@ aria2c_SOURCES = AllTest.cc\
FileTest.cc\
OptionTest.cc\
Base64Test.cc\
DataTest.cc\
DictionaryTest.cc\
ListTest.cc\
MetaFileUtilTest.cc\
PeerMessageUtilTest.cc\
DefaultDiskWriterTest.cc\
MultiDiskAdaptorTest.cc\
FeatureConfigTest.cc\
ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc\
SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc\
TrackerWatcherCommandTest.cc\
MockPeerStorage.h\
FixedNumberRandomizer.h\
ConsoleFileAllocationMonitorTest.cc\
ChunkChecksumValidatorTest.cc
ConsoleFileAllocationMonitorTest.cc
if ENABLE_MESSAGE_DIGEST
aria2c_SOURCES += ChunkChecksumValidatorTest.cc\
IteratableChecksumValidatorTest.cc\
IteratableChunkChecksumValidatorTest.cc\
MessageDigestHelperTest.cc
endif # ENABLE_MESSAGE_DIGEST
if ENABLE_BITTORRENT
aria2c_SOURCES += BtAllowedFastMessageTest.cc\
BtBitfieldMessageTest.cc\
@ -78,7 +67,22 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
MockBtMessage.h\
MockBtMessageDispatcher.h\
MockBtMessageFactory.h\
ShaVisitorTest.cc
ShaVisitorTest.cc\
DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc\
TrackerWatcherCommandTest.cc\
DefaultPeerStorageTest.cc\
MockPeerStorage.h\
DataTest.cc\
DictionaryTest.cc\
ListTest.cc\
MetaFileUtilTest.cc\
MultiDiskAdaptorTest.cc\
ByteArrayDiskWriterTest.cc\
PeerTest.cc\
PeerMessageUtilTest.cc\
ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc
endif # ENABLE_BITTORRENT
if ENABLE_METALINK

View File

@ -37,7 +37,12 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
check_PROGRAMS = $(am__EXEEXT_1)
@ENABLE_BITTORRENT_TRUE@am__append_1 = BtAllowedFastMessageTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@am__append_1 = ChunkChecksumValidatorTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChunkChecksumValidatorTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelperTest.cc
@ENABLE_BITTORRENT_TRUE@am__append_2 = BtAllowedFastMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ BtCancelMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ BtChokeMessageTest.cc\
@ -63,9 +68,24 @@ check_PROGRAMS = $(am__EXEEXT_1)
@ENABLE_BITTORRENT_TRUE@ MockBtMessage.h\
@ENABLE_BITTORRENT_TRUE@ MockBtMessageDispatcher.h\
@ENABLE_BITTORRENT_TRUE@ MockBtMessageFactory.h\
@ENABLE_BITTORRENT_TRUE@ ShaVisitorTest.cc
@ENABLE_BITTORRENT_TRUE@ ShaVisitorTest.cc\
@ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessorTest.cc\
@ENABLE_BITTORRENT_TRUE@ AnnounceListTest.cc\
@ENABLE_BITTORRENT_TRUE@ TrackerWatcherCommandTest.cc\
@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorageTest.cc\
@ENABLE_BITTORRENT_TRUE@ MockPeerStorage.h\
@ENABLE_BITTORRENT_TRUE@ DataTest.cc\
@ENABLE_BITTORRENT_TRUE@ DictionaryTest.cc\
@ENABLE_BITTORRENT_TRUE@ ListTest.cc\
@ENABLE_BITTORRENT_TRUE@ MetaFileUtilTest.cc\
@ENABLE_BITTORRENT_TRUE@ MultiDiskAdaptorTest.cc\
@ENABLE_BITTORRENT_TRUE@ ByteArrayDiskWriterTest.cc\
@ENABLE_BITTORRENT_TRUE@ PeerTest.cc\
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtilTest.cc\
@ENABLE_BITTORRENT_TRUE@ ShareRatioSeedCriteriaTest.cc\
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.cc
@ENABLE_METALINK_TRUE@am__append_2 = MetalinkerTest.cc\
@ENABLE_METALINK_TRUE@am__append_3 = MetalinkerTest.cc\
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.cc\
@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessorTest.cc
@ -94,24 +114,18 @@ am__aria2c_SOURCES_DIST = AllTest.cc FileUriListParserTest.cc \
StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
UtilTest.cc CookieBoxTest.cc RequestTest.cc \
CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
ByteArrayDiskWriterTest.cc RequestGroupManTest.cc \
IteratableChecksumValidatorTest.cc \
IteratableChunkChecksumValidatorTest.cc PeerTest.cc \
DefaultPeerStorageTest.cc RequestFactoryTest.cc \
RequestGroupManTest.cc RequestFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
GlowFileAllocatorTest.cc NetrcTest.cc SingletonHolderTest.cc \
HttpHeaderTest.cc HttpResponseTest.cc SharedHandleTest.cc \
ChunkedEncodingTest.cc FileTest.cc OptionTest.cc Base64Test.cc \
DataTest.cc DictionaryTest.cc ListTest.cc MetaFileUtilTest.cc \
PeerMessageUtilTest.cc DefaultDiskWriterTest.cc \
MultiDiskAdaptorTest.cc FeatureConfigTest.cc \
ShareRatioSeedCriteriaTest.cc TimeSeedCriteriaTest.cc \
SpeedCalcTest.cc DefaultPeerListProcessorTest.cc \
AnnounceListTest.cc TrackerWatcherCommandTest.cc \
MockPeerStorage.h FixedNumberRandomizer.h \
ConsoleFileAllocationMonitorTest.cc \
ChunkChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \
DefaultDiskWriterTest.cc FeatureConfigTest.cc SpeedCalcTest.cc \
FixedNumberRandomizer.h ConsoleFileAllocationMonitorTest.cc \
ChunkChecksumValidatorTest.cc \
IteratableChecksumValidatorTest.cc \
IteratableChunkChecksumValidatorTest.cc \
MessageDigestHelperTest.cc BtAllowedFastMessageTest.cc \
BtBitfieldMessageTest.cc BtCancelMessageTest.cc \
BtChokeMessageTest.cc BtHandshakeMessageTest.cc \
BtHaveAllMessageTest.cc BtHaveMessageTest.cc \
@ -124,9 +138,20 @@ am__aria2c_SOURCES_DIST = AllTest.cc FileUriListParserTest.cc \
DefaultBtMessageDispatcherTest.cc \
DefaultBtRequestFactoryTest.cc DefaultPieceStorageTest.cc \
MockBtMessage.h MockBtMessageDispatcher.h \
MockBtMessageFactory.h ShaVisitorTest.cc MetalinkerTest.cc \
MetalinkEntryTest.cc Xml2MetalinkProcessorTest.cc
@ENABLE_BITTORRENT_TRUE@am__objects_1 = \
MockBtMessageFactory.h ShaVisitorTest.cc \
DefaultPeerListProcessorTest.cc AnnounceListTest.cc \
TrackerWatcherCommandTest.cc DefaultPeerStorageTest.cc \
MockPeerStorage.h DataTest.cc DictionaryTest.cc ListTest.cc \
MetaFileUtilTest.cc MultiDiskAdaptorTest.cc \
ByteArrayDiskWriterTest.cc PeerTest.cc PeerMessageUtilTest.cc \
ShareRatioSeedCriteriaTest.cc TimeSeedCriteriaTest.cc \
MetalinkerTest.cc MetalinkEntryTest.cc \
Xml2MetalinkProcessorTest.cc
@ENABLE_MESSAGE_DIGEST_TRUE@am__objects_1 = ChunkChecksumValidatorTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChunkChecksumValidatorTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelperTest.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@am__objects_2 = \
@ENABLE_BITTORRENT_TRUE@ BtAllowedFastMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ BtCancelMessageTest.$(OBJEXT) \
@ -150,8 +175,22 @@ am__aria2c_SOURCES_DIST = AllTest.cc FileUriListParserTest.cc \
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageDispatcherTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultBtRequestFactoryTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultPieceStorageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ShaVisitorTest.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_2 = MetalinkerTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ShaVisitorTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessorTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ AnnounceListTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ TrackerWatcherCommandTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DataTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DictionaryTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ListTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MetaFileUtilTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MultiDiskAdaptorTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ByteArrayDiskWriterTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtilTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ShareRatioSeedCriteriaTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = MetalinkerTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessorTest.$(OBJEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) FileUriListParserTest.$(OBJEXT) \
@ -159,12 +198,7 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) FileUriListParserTest.$(OBJEXT) \
HttpHeaderProcessorTest.$(OBJEXT) UtilTest.$(OBJEXT) \
CookieBoxTest.$(OBJEXT) RequestTest.$(OBJEXT) \
CookieParserTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
CookieBoxFactoryTest.$(OBJEXT) \
ByteArrayDiskWriterTest.$(OBJEXT) \
RequestGroupManTest.$(OBJEXT) \
IteratableChecksumValidatorTest.$(OBJEXT) \
IteratableChunkChecksumValidatorTest.$(OBJEXT) \
PeerTest.$(OBJEXT) DefaultPeerStorageTest.$(OBJEXT) \
CookieBoxFactoryTest.$(OBJEXT) RequestGroupManTest.$(OBJEXT) \
RequestFactoryTest.$(OBJEXT) NetrcAuthResolverTest.$(OBJEXT) \
DefaultAuthResolverTest.$(OBJEXT) OptionHandlerTest.$(OBJEXT) \
SegmentManTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
@ -172,18 +206,11 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) FileUriListParserTest.$(OBJEXT) \
SingletonHolderTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
HttpResponseTest.$(OBJEXT) SharedHandleTest.$(OBJEXT) \
ChunkedEncodingTest.$(OBJEXT) FileTest.$(OBJEXT) \
OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) DataTest.$(OBJEXT) \
DictionaryTest.$(OBJEXT) ListTest.$(OBJEXT) \
MetaFileUtilTest.$(OBJEXT) PeerMessageUtilTest.$(OBJEXT) \
DefaultDiskWriterTest.$(OBJEXT) MultiDiskAdaptorTest.$(OBJEXT) \
FeatureConfigTest.$(OBJEXT) \
ShareRatioSeedCriteriaTest.$(OBJEXT) \
TimeSeedCriteriaTest.$(OBJEXT) SpeedCalcTest.$(OBJEXT) \
DefaultPeerListProcessorTest.$(OBJEXT) \
AnnounceListTest.$(OBJEXT) TrackerWatcherCommandTest.$(OBJEXT) \
ConsoleFileAllocationMonitorTest.$(OBJEXT) \
ChunkChecksumValidatorTest.$(OBJEXT) $(am__objects_1) \
$(am__objects_2)
OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) \
DefaultDiskWriterTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \
SpeedCalcTest.$(OBJEXT) \
ConsoleFileAllocationMonitorTest.$(OBJEXT) $(am__objects_1) \
$(am__objects_2) $(am__objects_3)
aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -372,24 +399,15 @@ aria2c_SOURCES = AllTest.cc FileUriListParserTest.cc \
StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
UtilTest.cc CookieBoxTest.cc RequestTest.cc \
CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
ByteArrayDiskWriterTest.cc RequestGroupManTest.cc \
IteratableChecksumValidatorTest.cc \
IteratableChunkChecksumValidatorTest.cc PeerTest.cc \
DefaultPeerStorageTest.cc RequestFactoryTest.cc \
RequestGroupManTest.cc RequestFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
GlowFileAllocatorTest.cc NetrcTest.cc SingletonHolderTest.cc \
HttpHeaderTest.cc HttpResponseTest.cc SharedHandleTest.cc \
ChunkedEncodingTest.cc FileTest.cc OptionTest.cc Base64Test.cc \
DataTest.cc DictionaryTest.cc ListTest.cc MetaFileUtilTest.cc \
PeerMessageUtilTest.cc DefaultDiskWriterTest.cc \
MultiDiskAdaptorTest.cc FeatureConfigTest.cc \
ShareRatioSeedCriteriaTest.cc TimeSeedCriteriaTest.cc \
SpeedCalcTest.cc DefaultPeerListProcessorTest.cc \
AnnounceListTest.cc TrackerWatcherCommandTest.cc \
MockPeerStorage.h FixedNumberRandomizer.h \
ConsoleFileAllocationMonitorTest.cc \
ChunkChecksumValidatorTest.cc $(am__append_1) $(am__append_2)
DefaultDiskWriterTest.cc FeatureConfigTest.cc SpeedCalcTest.cc \
FixedNumberRandomizer.h ConsoleFileAllocationMonitorTest.cc \
$(am__append_1) $(am__append_2) $(am__append_3)
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@ -504,6 +522,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidatorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidatorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelperTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtilTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkerTest.Po@am__quote@

View File

@ -64,17 +64,27 @@ void MetalinkEntryTest::testDropUnsupportedResource() {
MetalinkEntry* entry = createTestEntry();
entry->dropUnsupportedResource();
#if defined ENABLE_SSL && ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL(4, (int)entry->resources.size());
#elif defined ENABLE_SSL || ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL(3, (int)entry->resources.size());
#else
CPPUNIT_ASSERT_EQUAL(2, (int)entry->resources.size());
#endif // ENABLE_MESSAGE_DIGEST
MetalinkResources::const_iterator itr = entry->resources.begin();
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP,
entry->resources.at(0)->type);
(*itr++)->type);
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP,
entry->resources.at(1)->type);
(*itr++)->type);
#ifdef ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_BITTORRENT,
entry->resources.at(2)->type);
(*itr++)->type);
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_SSL
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTPS,
entry->resources.at(3)->type);
(*itr++)->type);
#endif // ENABLE_SSL
}
void MetalinkEntryTest::testReorderResourcesByPreference() {

View File

@ -16,6 +16,7 @@ private:
unsigned char peerId[20];
FileEntries fileEntries;
AnnounceTiers announceTiers;
Integers fastSet;
public:
MockBtContext():totalLength(0),
pieceLength(0),
@ -117,6 +118,16 @@ public:
memcpy(this->peerId, peerId, sizeof(this->peerId));
}
virtual Integers computeFastSet(const string& ipaddr, int32_t fastSetSize)
{
return fastSet;
}
void setFastSet(const Integers& fastSet)
{
this->fastSet = fastSet;
}
};
typedef SharedHandle<MockBtContext> MockBtContextHandle;

View File

@ -9,9 +9,6 @@ class MultiDiskAdaptorTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MultiDiskAdaptorTest);
CPPUNIT_TEST(testWriteData);
CPPUNIT_TEST(testReadData);
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_TEST(testMessageDigest);
#endif // ENABLE_MESSAGE_DIGEST
CPPUNIT_TEST_SUITE_END();
private:
Option* option;
@ -32,9 +29,6 @@ public:
void testWriteData();
void testReadData();
#ifdef ENABLE_MESSAGE_DIGEST
void testMessageDigest();
#endif // ENABLE_MESSAGE_DIGEST
};
@ -137,28 +131,3 @@ void MultiDiskAdaptorTest::testReadData() {
buf[25] = '\0';
CPPUNIT_ASSERT_EQUAL(string("1234567890ABCDEFGHIJKLMNO"), string((char*)buf));
}
#ifdef ENABLE_MESSAGE_DIGEST
void MultiDiskAdaptorTest::testMessageDigest() {
FileEntryHandle entry1(new FileEntry("file1r.txt", 15, 0));
FileEntryHandle entry2(new FileEntry("file2r.txt", 7, 15));
FileEntryHandle entry3(new FileEntry("file3r.txt", 3, 22));
FileEntries entries;
entries.push_back(entry1);
entries.push_back(entry2);
entries.push_back(entry3);
adaptor->setFileEntries(entries);
adaptor->openFile();
string sha1sum = adaptor->messageDigest(0, 25, DIGEST_ALGO_SHA1);
CPPUNIT_ASSERT_EQUAL(string("76495faf71ca63df66dce99547d2c58da7266d9e"), sha1sum);
sha1sum = adaptor->messageDigest(15, 7, DIGEST_ALGO_SHA1);
CPPUNIT_ASSERT_EQUAL(string("737660d816fb23c2d5bc74f62d9b01b852b2aaca"), sha1sum);
sha1sum = adaptor->messageDigest(10, 14, DIGEST_ALGO_SHA1);
CPPUNIT_ASSERT_EQUAL(string("6238bf61dd8df8f77156b2378e9e39cd3939680c"), sha1sum);
adaptor->closeFile();
}
#endif // ENABLE_MESSAGE_DIGEST

View File

@ -2,6 +2,7 @@
#include "ConsoleDownloadEngine.h"
#include "CUIDCounter.h"
#include "prefs.h"
#include "RequestFactory.h"
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
@ -60,6 +61,11 @@ void RequestGroupManTest::testGetInitialCommands()
Option option;
option.put(PREF_SPLIT, "1");
option.put(PREF_TIMEOUT, "10");
RequestFactoryHandle requestFactory = new RequestFactory();
requestFactory->setOption(&option);
RequestFactorySingletonHolder::instance(requestFactory);
RequestGroupMan gm;
RequestGroupHandle rg1 = new RequestGroup("aria2.tar.bz2.metalink",

View File

@ -296,12 +296,18 @@ void RequestTest::testMetalink() {
Request req;
bool v = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!http://aria2.sourceforge.net/download/aria.metalink");
CPPUNIT_ASSERT(v);
#ifdef ENABLE_METALINK
CPPUNIT_ASSERT_EQUAL(string("aria2.sourceforge.net"), req.getHost());
CPPUNIT_ASSERT_EQUAL(string("/download"), req.getDir());
CPPUNIT_ASSERT_EQUAL(string("aria.metalink"), req.getFile());
bool v2 = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!");
CPPUNIT_ASSERT(!v2);
#else
CPPUNIT_ASSERT_EQUAL(string("aria.rednoah.com"), req.getHost());
CPPUNIT_ASSERT_EQUAL(string("/download"), req.getDir());
CPPUNIT_ASSERT_EQUAL(string("aria.tar.bz2"), req.getFile());
#endif // ENABLE_METALINK
}
void RequestTest::testResolveHttpAuthConfig()

View File

@ -22,20 +22,21 @@ class TrackerWatcherCommandTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreateCommand);
CPPUNIT_TEST_SUITE_END();
private:
Option* op;
Option op;
public:
TrackerWatcherCommandTest():op(new Option())
TrackerWatcherCommandTest()
{
op->put(PREF_TRACKER_MAX_TRIES, "10");
RequestFactoryHandle requestFactory = new RequestFactory();
requestFactory->setOption(op);
RequestFactorySingletonHolder::instance(requestFactory);
}
void setUp()
{
CUIDCounterHandle counter = new CUIDCounter();
CUIDCounterSingletonHolder::instance(counter);
op.put(PREF_TRACKER_MAX_TRIES, "10");
RequestFactoryHandle requestFactory = new RequestFactory();
requestFactory->setOption(&op);
RequestFactorySingletonHolder::instance(requestFactory);
}
void testCreateCommand();
@ -53,22 +54,24 @@ void TrackerWatcherCommandTest::testCreateCommand() {
BtRuntimeHandle btRuntime;
BtRegistry::registerBtRuntime(btContext->getInfoHashAsString(), btRuntime);
PieceStorageHandle pieceStorage(new DefaultPieceStorage(btContext, op));
PieceStorageHandle pieceStorage(new DefaultPieceStorage(btContext, &op));
BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),
pieceStorage);
PeerStorageHandle peerStorage(new DefaultPeerStorage(btContext, op));
PeerStorageHandle peerStorage(new DefaultPeerStorage(btContext, &op));
BtRegistry::registerPeerStorage(btContext->getInfoHashAsString(),
peerStorage);
BtAnnounceHandle btAnnounce(new DefaultBtAnnounce(btContext, op));
BtAnnounceHandle btAnnounce(new DefaultBtAnnounce(btContext, &op));
BtRegistry::registerBtAnnounce(btContext->getInfoHashAsString(), btAnnounce);
TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine();
te->option = op;
te->option = &op;
te->_requestGroupMan = new RequestGroupMan();
TrackerWatcherCommand command(1, te, btContext);
RequestFactorySingletonHolder::instance()->createHttpAuthResolver();
CPPUNIT_ASSERT(dynamic_cast<HttpInitiateConnectionCommand*>(command.createCommand()));
//cerr << btAnnounce->getAnnounceUrl() << endl;

View File

@ -15,13 +15,7 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testStartsWith);
// may be moved to other helper class in the future.
CPPUNIT_TEST(testGetContentDispositionFilename);
#ifdef ENABLE_BITTORRENT
CPPUNIT_TEST(testComputeFastSet);
#endif
CPPUNIT_TEST(testRandomAlpha);
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_TEST(testFileChecksum);
#endif
CPPUNIT_TEST(testToUpper);
CPPUNIT_TEST(testToLower);
CPPUNIT_TEST(testUrldecode);
@ -42,15 +36,9 @@ public:
void testEndsWith();
void testReplace();
void testStartsWith();
#ifdef ENABLE_BITTORRENT
void testComputeFastSet();
#endif
// may be moved to other helper class in the future.
void testGetContentDispositionFilename();
void testRandomAlpha();
#ifdef ENABLE_MESSAGE_DIGEST
void testFileChecksum();
#endif
void testToUpper();
void testToLower();
void testUrldecode();
@ -243,55 +231,10 @@ public:
}
};
#ifdef ENABLE_BITTORRENT
void UtilTest::testComputeFastSet() {
string ipaddr = "192.168.0.1";
unsigned char infoHash[20];
memset(infoHash, 0, sizeof(infoHash));
infoHash[0] = 0xff;
int pieces = 1000;
int fastSetSize = 10;
Integers fastSet = Util::computeFastSet(ipaddr, infoHash, pieces, fastSetSize);
//for_each(fastSet.begin(), fastSet.end(), Printer());
//cerr << endl;
int ans1[] = { 686, 459, 278, 200, 404, 834, 64, 203, 760, 950 };
Integers ansSet1(&ans1[0], &ans1[10]);
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet1.begin()));
ipaddr = "10.0.0.1";
fastSet = Util::computeFastSet(ipaddr, infoHash, pieces, fastSetSize);
int ans2[] = { 568, 188, 466, 452, 550, 662, 109, 226, 398, 11 };
Integers ansSet2(&ans2[0], &ans2[10]);
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
}
#endif
void UtilTest::testRandomAlpha() {
CPPUNIT_ASSERT_EQUAL(string("rUopvKRn"), Util::randomAlpha(8));
CPPUNIT_ASSERT_EQUAL((size_t)8, Util::randomAlpha(8).size());
}
#ifdef ENABLE_MESSAGE_DIGEST
void UtilTest::testFileChecksum() {
unsigned char buf[20];
string filename = "4096chunk.txt";
Util::fileChecksum(filename, buf, DIGEST_ALGO_SHA1);
string sha1 = Util::toHex(buf, 20);
CPPUNIT_ASSERT_EQUAL(string("608cabc0f2fa18c260cafd974516865c772363d5"),
sha1);
Util::fileChecksum(filename, buf, DIGEST_ALGO_MD5);
string md5 = Util::toHex(buf, 16);
CPPUNIT_ASSERT_EQUAL(string("82a7348c2e03731109d0cf45a7325b88"),
md5);
}
#endif
void UtilTest::testToUpper() {
string src = "608cabc0f2fa18c260cafd974516865c772363d5";
string upp = "608CABC0F2FA18C260CAFD974516865C772363D5";

View File

@ -28,54 +28,80 @@ CPPUNIT_TEST_SUITE_REGISTRATION( Xml2MetalinkProcessorTest );
void Xml2MetalinkProcessorTest::testParseFile() {
Xml2MetalinkProcessor proc;
try {
MetalinkerHandle metalinker = proc.parseFile("test.xml");
MetalinkerHandle metalinker = proc.parseFile("test.xml");
MetalinkEntries::iterator entryItr = metalinker->entries.begin();
MetalinkEntryHandle entry1 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.2.tar.bz2"), entry1->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)0, entry1->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version);
CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os);
CPPUNIT_ASSERT_EQUAL(string("a96cf3f0266b91d87d5124cf94326422800b627d"),
entry1->checksum->getMessageDigest());
CPPUNIT_ASSERT(DIGEST_ALGO_SHA1 == entry1->checksum->getDigestAlgo());
MetalinkResources::iterator resourceItr1 = entry1->resources.begin();
MetalinkResourceHandle resource1 = *resourceItr1;
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
CPPUNIT_ASSERT_EQUAL(string("jp"), resource1->location);
CPPUNIT_ASSERT_EQUAL(100, resource1->preference);
CPPUNIT_ASSERT_EQUAL(string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
resource1->url);
resourceItr1++;
MetalinkResourceHandle resource2 = *resourceItr1;
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
CPPUNIT_ASSERT_EQUAL(string("us"), resource2->location);
CPPUNIT_ASSERT_EQUAL(100, resource2->preference);
CPPUNIT_ASSERT_EQUAL(string("http://httphost/aria2-0.5.2.tar.bz2"),
resource2->url);
entryItr++;
MetalinkEntryHandle entry2 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.1.tar.bz2"), entry2->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)345689, entry2->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version);
CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os);
MetalinkEntries::iterator entryItr = metalinker->entries.begin();
MetalinkEntryHandle entry1 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.2.tar.bz2"), entry1->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)0, entry1->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version);
CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os);
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
entry2->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL(string("a96cf3f0266b91d87d5124cf94326422800b627d"),
entry1->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL(string("sha1"), entry1->checksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL((int32_t)2, entry2->chunkChecksum->countChecksum());
CPPUNIT_ASSERT_EQUAL((int32_t)262144, entry2->chunkChecksum->getChecksumLength());
CPPUNIT_ASSERT_EQUAL(string("179463a88d79cbf0b1923991708aead914f26142"),
entry2->chunkChecksum->getChecksum(0));
CPPUNIT_ASSERT_EQUAL(string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
entry2->chunkChecksum->getChecksum(1));
MetalinkResources::iterator resourceItr1 = entry1->resources.begin();
MetalinkResourceHandle resource1 = *resourceItr1;
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
CPPUNIT_ASSERT_EQUAL(string("jp"), resource1->location);
CPPUNIT_ASSERT_EQUAL(100, resource1->preference);
CPPUNIT_ASSERT_EQUAL(string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
resource1->url);
resourceItr1++;
MetalinkResourceHandle resource2 = *resourceItr1;
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
CPPUNIT_ASSERT_EQUAL(string("us"), resource2->location);
CPPUNIT_ASSERT_EQUAL(100, resource2->preference);
CPPUNIT_ASSERT_EQUAL(string("http://httphost/aria2-0.5.2.tar.bz2"),
resource2->url);
entryItr++;
MetalinkEntryHandle entry2 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.1.tar.bz2"), entry2->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)345689, entry2->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version);
CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os);
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
entry2->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL((int32_t)2, entry2->chunkChecksum->countChecksum());
CPPUNIT_ASSERT_EQUAL((int32_t)262144, entry2->chunkChecksum->getChecksumLength());
CPPUNIT_ASSERT_EQUAL(string("179463a88d79cbf0b1923991708aead914f26142"),
entry2->chunkChecksum->getChecksum(0));
CPPUNIT_ASSERT_EQUAL(string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
entry2->chunkChecksum->getChecksum(1));
CPPUNIT_ASSERT_EQUAL(string("sha1"), entry2->checksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
entryItr++;
// test case: verification hash is not provided
MetalinkEntryHandle entry3 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("NoVerificationHash"), entry3->getPath());
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT(entry3->checksum.isNull());
CPPUNIT_ASSERT(entry3->chunkChecksum.isNull());
#endif // ENABLE_MESSAGE_DIGEST
entryItr++;
// test case: unsupported verification hash is included
MetalinkEntryHandle entry4 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(string("sha1"),
entry4->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
entry4->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL(string("sha1"),
entry4->chunkChecksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT(DIGEST_ALGO_SHA1 == entry2->checksum->getDigestAlgo());
} catch(Exception* e) {
CPPUNIT_FAIL(e->getMsg());
delete e;

View File

@ -11,8 +11,8 @@
<language>en-US</language>
<os>Linux-x86</os>
<verification>
<hash type="md5">fc4d834e89c18c99b2615d902750948c</hash>
<hash type="sha1">a96cf3f0266b91d87d5124cf94326422800b627d</hash>
<hash type="md5">fc4d834e89c18c99b2615d902750948c</hash>
</verification>
<resources>
<url type="ftp" location="jp" preference="100">ftp://ftphost/aria2-0.5.2.tar.bz2</url>
@ -25,8 +25,8 @@
<language>ja-JP</language>
<os>Linux-m68k</os>
<verification>
<hash type="md5">92296e19c406d77d21bda0bb944eac46</hash>
<hash type="sha1">4c255b0ed130f5ea880f0aa061c3da0487e251cc</hash>
<hash type="md5">92296e19c406d77d21bda0bb944eac46</hash>
<pieces length="262144" type="sha1">
<hash piece="0">179463a88d79cbf0b1923991708aead914f26142</hash>
<hash piece="1">fecf8bc9a1647505fe16746f94e97a477597dbf3</hash>
@ -37,5 +37,27 @@
<url type="http" preference="100">http://httphost/aria2-0.5.1.tar.bz2</url>
</resources>
</file>
<file name="NoVerificationHash">
<resources>
<url type="ftp" preference="100">ftp://host/file</url>
</resources>
</file>
<file name="UnsupportedVerificationHashTypeIncluded">
<verification>
<hash type="notsupported">92296e19c406d77d21bda0bb944eac46</hash>
<hash type="sha1">4c255b0ed130f5ea880f0aa061c3da0487e251cc</hash>
<pieces length="262144" type="notsupported">
<hash piece="0">179463a88d79cbf0b1923991708aead914f26142</hash>
<hash piece="1">fecf8bc9a1647505fe16746f94e97a477597dbf3</hash>
</pieces>
<pieces length="262144" type="sha1">
<hash piece="0">179463a88d79cbf0b1923991708aead914f26142</hash>
<hash piece="1">fecf8bc9a1647505fe16746f94e97a477597dbf3</hash>
</pieces>
</verification>
<resources>
<url type="ftp" preference="100">ftp://host/file</url>
</resources>
</file>
</files>
</metalink>