mirror of https://github.com/aria2/aria2
2006-06-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add Time class which represents a specific instant in time and its precision is microseconds. Time checking procedures were rewritten using this object. * src/Time.h: New class. * src/Time.cc: New class. * src/AbstractCommand.h (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (checkPoint): Changed the type to Time. (timeout): New variable. (setTimeout): New function. * src/AbstractCommand.cc (AbstractCommand): Removed the initialization of checkPoint. Added the initialization of timeout. (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (execute): Use checkPoint.reset() and checkPoint.elapsed(). * src/PeerChokeCommand.h (checkPoint): Changed the type to Time. * src/PeerChokeCommand.cc (PeerChokeCommand): Removed the initialization of checkPoint. (execute): Rewritten using Time object. * src/TrackerWatcherCommand.h (checkPoint): Changed the type to Time. * src/TrackerWatcherCommand.cc (TrackerWatcherCommand): Removed the initialization of checkPoint. (execute): Rewritten. * src/ConsoleDownloadEngine.h (cp): Changed the type to Time. (startup): Changed the type to Time. * src/ConsoleDownloadEngine.cc (initStatistics): Use cp.reset(), startup.reset(). (calculateStatistics): Rewritten using Time object. * src/PeerAbstractCommand.h (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (checkPoint): Changed the type to Time. * src/PeerAbstractCommand.cc (PeerAbstractCommand): Removed the initialization of checkPoint. (updateCheckPoint): Removed. (isTimeoutDetected): Removed. (execute): Use checkPoint.reset() and checkPoint.elapsed(). * src/PeerInteractionCommand.cc (PeerInteractionCommand): Removed the initializations of struct timeval variables. * src/PeerInteractionCommand.h (keepAliveCheckPoint): Changed the type to Time. (chokeCheckPoint): Changed the type to Time. (freqCheckPoint): Changed the type to Time. (haveCheckTime): Changed the type to Time. * src/PeerInteractionCommand.cc (executeInternal): Rewritten using Time object. (detectMessageFlooding): Rewritten using Time object. (checkLongTimePeerChoking): Rewritten using Time object. (sendKeepAlive): Rewritten using Time object. (checkHave): Rewritten using Time object. * src/SleepCommand.h (checkPoint): Changed the type to Time. * src/SleepCommand.cc (SleepCommand): Removed the initialization of checkPoint. (execute): Rewritten using Time object. * src/TorrentAutoSaveCommand.h (checkPoint): Changed the type to Time. * src/TorrentAutoSaveCommand.cc (TorrentAutoSaveCommand): Removed the initialization of checkPoint. (execute): Rewritten. * src/DownloadCommand.h (sw): Changed the type to Time. * src/DownloadCommand.cc (DownloadCommand): Removed the initialization of sw. (executeInternal): Rewritten. * src/RequestSlot.h (dispatchedTime): Changed the type to Time. * src/RequestSlot.cc (RequestSlot): Removed the call to setDispatchedTime(). (setDispatchedTime): Rewirtten. (isTimeout): Rewritten. (getLatencyInMillis): Rewritten. * src/TorrentDownloadEngine.h (cp): Changed the type to Time[2]. (startup): Changed the type to Time. * src/TorrentDownloadEngine.cc (initStatistics): Rewritten. (calculateStatistics): Rewritten. * src/DownloadEngine.cc (run): Rewritten. To detect all attempts to connect to the tracker are failed: * src/AbstractCommand.cc (execute): Increment e->segmentMan->errors if a command aborted. * src/SegmentMan.h (errors): New variable. * src/SegmentMan.cc (SegmentMan): Added the initialization of errors. (init): Added the initialization of errors. * src/TrackerWatcherCommand.cc (execute): If e->segmentMan->errors > 0 then assume that the tracker request was failed. To handle snubbed peers: * src/PeerChokeCommand.cc (optUnchokingPeer): Snubbed peers don't get unchoked. (execute): Snubbed peers don't get unchoked. * src/PeerInteraction.h (REQUEST_TIME_OUT): Changed the value from 120 to 60. * src/PeerInteraction.cc (checkRequestSlot): A peer get marked as "snubbed" if it doesn't send back the requested 16k block in 60 seconds. * src/PieceMessage.cc (receivedAction): A peer's snubbed state is cleard if it sends the requested 16k block in 60 seconds. * src/Peer.h (snubbing): New variable. * src/Peer.cc (resetStatus): Added snubbed = false. To fix the bug that causes have message is not sent: * src/PeerInteractionCommand.cc (~PeerInteractionCommand): Removed e->torrentMan->unadvertisePiece(). (FLOODING_CHECK_INTERVAL): New definition(temporal). (detectMessageFlooding): Use FLOODING_CHECK_INTERVAL. * src/TorrentMan.h (HaveEntry): New class. (advertisePiece): Rewritten. (getAdvertisedPieceIndexes): Rewritten. (Haves): Changed the type. (getAdvertisedPieceIndexes): Added an argument. Others: * src/TorrentMan.h (DEFAULT_ANNOUNCE_INTERVAL): Changed the value to 1800. (DEFAULT_ANNOUNCE_MIN_INTERVAL): Changed the value to 1800. * src/TorrentMan.cc (getPeer): Don't check the number of connections here. (setupInternal1): Changed peerId. * src/PeerInteractionCommand.h (KEEP_ALIVE_INTERVAL): New definition. (sendKeepAlive): Use KEEP_ALIVE_INTERVAL. * src/main.cc (main): SA_ONESHOT was replaced with SA_RESETHAND. * src/DownloadEngine.h: Removed unnecessary header includes.pull/1/head
parent
7e36107f45
commit
d380b7b6ab
152
ChangeLog
152
ChangeLog
|
@ -1,3 +1,155 @@
|
||||||
|
2006-06-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
To add Time class which represents a specific instant in time and
|
||||||
|
its precision is microseconds. Time checking procedures were rewritten
|
||||||
|
using this object.
|
||||||
|
|
||||||
|
* src/Time.h: New class.
|
||||||
|
* src/Time.cc: New class.
|
||||||
|
* src/AbstractCommand.h
|
||||||
|
(updateCheckPoint): Removed.
|
||||||
|
(isTimeoutDetected): Removed.
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
(timeout): New variable.
|
||||||
|
(setTimeout): New function.
|
||||||
|
* src/AbstractCommand.cc
|
||||||
|
(AbstractCommand): Removed the initialization of checkPoint.
|
||||||
|
Added the initialization of timeout.
|
||||||
|
(updateCheckPoint): Removed.
|
||||||
|
(isTimeoutDetected): Removed.
|
||||||
|
(execute): Use checkPoint.reset() and checkPoint.elapsed().
|
||||||
|
* src/PeerChokeCommand.h
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
* src/PeerChokeCommand.cc
|
||||||
|
(PeerChokeCommand): Removed the initialization of checkPoint.
|
||||||
|
(execute): Rewritten using Time object.
|
||||||
|
* src/TrackerWatcherCommand.h
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
* src/TrackerWatcherCommand.cc
|
||||||
|
(TrackerWatcherCommand): Removed the initialization of checkPoint.
|
||||||
|
(execute): Rewritten.
|
||||||
|
* src/ConsoleDownloadEngine.h
|
||||||
|
(cp): Changed the type to Time.
|
||||||
|
(startup): Changed the type to Time.
|
||||||
|
* src/ConsoleDownloadEngine.cc
|
||||||
|
(initStatistics): Use cp.reset(), startup.reset().
|
||||||
|
(calculateStatistics): Rewritten using Time object.
|
||||||
|
* src/PeerAbstractCommand.h
|
||||||
|
(updateCheckPoint): Removed.
|
||||||
|
(isTimeoutDetected): Removed.
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
* src/PeerAbstractCommand.cc
|
||||||
|
(PeerAbstractCommand): Removed the initialization of checkPoint.
|
||||||
|
(updateCheckPoint): Removed.
|
||||||
|
(isTimeoutDetected): Removed.
|
||||||
|
(execute): Use checkPoint.reset() and checkPoint.elapsed().
|
||||||
|
* src/PeerInteractionCommand.cc
|
||||||
|
(PeerInteractionCommand): Removed the initializations of struct
|
||||||
|
timeval variables.
|
||||||
|
* src/PeerInteractionCommand.h
|
||||||
|
(keepAliveCheckPoint): Changed the type to Time.
|
||||||
|
(chokeCheckPoint): Changed the type to Time.
|
||||||
|
(freqCheckPoint): Changed the type to Time.
|
||||||
|
(haveCheckTime): Changed the type to Time.
|
||||||
|
* src/PeerInteractionCommand.cc
|
||||||
|
(executeInternal): Rewritten using Time object.
|
||||||
|
(detectMessageFlooding): Rewritten using Time object.
|
||||||
|
(checkLongTimePeerChoking): Rewritten using Time object.
|
||||||
|
(sendKeepAlive): Rewritten using Time object.
|
||||||
|
(checkHave): Rewritten using Time object.
|
||||||
|
* src/SleepCommand.h
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
* src/SleepCommand.cc
|
||||||
|
(SleepCommand): Removed the initialization of checkPoint.
|
||||||
|
(execute): Rewritten using Time object.
|
||||||
|
* src/TorrentAutoSaveCommand.h
|
||||||
|
(checkPoint): Changed the type to Time.
|
||||||
|
* src/TorrentAutoSaveCommand.cc
|
||||||
|
(TorrentAutoSaveCommand): Removed the initialization of checkPoint.
|
||||||
|
(execute): Rewritten.
|
||||||
|
* src/DownloadCommand.h
|
||||||
|
(sw): Changed the type to Time.
|
||||||
|
* src/DownloadCommand.cc
|
||||||
|
(DownloadCommand): Removed the initialization of sw.
|
||||||
|
(executeInternal): Rewritten.
|
||||||
|
* src/RequestSlot.h
|
||||||
|
(dispatchedTime): Changed the type to Time.
|
||||||
|
* src/RequestSlot.cc
|
||||||
|
(RequestSlot): Removed the call to setDispatchedTime().
|
||||||
|
(setDispatchedTime): Rewirtten.
|
||||||
|
(isTimeout): Rewritten.
|
||||||
|
(getLatencyInMillis): Rewritten.
|
||||||
|
* src/TorrentDownloadEngine.h
|
||||||
|
(cp): Changed the type to Time[2].
|
||||||
|
(startup): Changed the type to Time.
|
||||||
|
* src/TorrentDownloadEngine.cc
|
||||||
|
(initStatistics): Rewritten.
|
||||||
|
(calculateStatistics): Rewritten.
|
||||||
|
* src/DownloadEngine.cc
|
||||||
|
(run): Rewritten.
|
||||||
|
|
||||||
|
To detect all attempts to connect to the tracker are failed:
|
||||||
|
|
||||||
|
* src/AbstractCommand.cc
|
||||||
|
(execute): Increment e->segmentMan->errors if a command aborted.
|
||||||
|
* src/SegmentMan.h
|
||||||
|
(errors): New variable.
|
||||||
|
* src/SegmentMan.cc
|
||||||
|
(SegmentMan): Added the initialization of errors.
|
||||||
|
(init): Added the initialization of errors.
|
||||||
|
* src/TrackerWatcherCommand.cc
|
||||||
|
(execute): If e->segmentMan->errors > 0 then assume that the tracker
|
||||||
|
request was failed.
|
||||||
|
|
||||||
|
To handle snubbed peers:
|
||||||
|
|
||||||
|
* src/PeerChokeCommand.cc
|
||||||
|
(optUnchokingPeer): Snubbed peers don't get unchoked.
|
||||||
|
(execute): Snubbed peers don't get unchoked.
|
||||||
|
* src/PeerInteraction.h
|
||||||
|
(REQUEST_TIME_OUT): Changed the value from 120 to 60.
|
||||||
|
* src/PeerInteraction.cc
|
||||||
|
(checkRequestSlot): A peer get marked as "snubbed" if it doesn't send
|
||||||
|
back the requested 16k block in 60 seconds.
|
||||||
|
* src/PieceMessage.cc
|
||||||
|
(receivedAction): A peer's snubbed state is cleard if it sends
|
||||||
|
the requested 16k block in 60 seconds.
|
||||||
|
* src/Peer.h
|
||||||
|
(snubbing): New variable.
|
||||||
|
* src/Peer.cc
|
||||||
|
(resetStatus): Added snubbed = false.
|
||||||
|
|
||||||
|
To fix the bug that causes have message is not sent:
|
||||||
|
|
||||||
|
* src/PeerInteractionCommand.cc
|
||||||
|
(~PeerInteractionCommand): Removed e->torrentMan->unadvertisePiece().
|
||||||
|
(FLOODING_CHECK_INTERVAL): New definition(temporal).
|
||||||
|
(detectMessageFlooding): Use FLOODING_CHECK_INTERVAL.
|
||||||
|
* src/TorrentMan.h
|
||||||
|
(HaveEntry): New class.
|
||||||
|
(advertisePiece): Rewritten.
|
||||||
|
(getAdvertisedPieceIndexes): Rewritten.
|
||||||
|
(Haves): Changed the type.
|
||||||
|
(getAdvertisedPieceIndexes): Added an argument.
|
||||||
|
|
||||||
|
Others:
|
||||||
|
|
||||||
|
* src/TorrentMan.h
|
||||||
|
(DEFAULT_ANNOUNCE_INTERVAL): Changed the value to 1800.
|
||||||
|
(DEFAULT_ANNOUNCE_MIN_INTERVAL): Changed the value to 1800.
|
||||||
|
* src/TorrentMan.cc
|
||||||
|
(getPeer): Don't check the number of connections here.
|
||||||
|
(setupInternal1): Changed peerId.
|
||||||
|
|
||||||
|
* src/PeerInteractionCommand.h
|
||||||
|
(KEEP_ALIVE_INTERVAL): New definition.
|
||||||
|
(sendKeepAlive): Use KEEP_ALIVE_INTERVAL.
|
||||||
|
|
||||||
|
* src/main.cc
|
||||||
|
(main): SA_ONESHOT was replaced with SA_RESETHAND.
|
||||||
|
|
||||||
|
* src/DownloadEngine.h: Removed unnecessary header includes.
|
||||||
|
|
||||||
2006-05-29 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2006-05-29 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
To fix the bug that causes segfaults if a tracker returns a zero-length
|
To fix the bug that causes segfaults if a tracker returns a zero-length
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.59 for aria2c 0.5.0.
|
# Generated by GNU Autoconf 2.59 for aria2c 0.5.1.
|
||||||
#
|
#
|
||||||
# Report bugs to <tujikawa@rednoah.com>.
|
# Report bugs to <tujikawa@rednoah.com>.
|
||||||
#
|
#
|
||||||
|
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='aria2c'
|
PACKAGE_NAME='aria2c'
|
||||||
PACKAGE_TARNAME='aria2c'
|
PACKAGE_TARNAME='aria2c'
|
||||||
PACKAGE_VERSION='0.5.0'
|
PACKAGE_VERSION='0.5.1'
|
||||||
PACKAGE_STRING='aria2c 0.5.0'
|
PACKAGE_STRING='aria2c 0.5.1'
|
||||||
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
|
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
|
||||||
|
|
||||||
ac_unique_file="src/Socket.h"
|
ac_unique_file="src/Socket.h"
|
||||||
|
@ -788,7 +788,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures aria2c 0.5.0 to adapt to many kinds of systems.
|
\`configure' configures aria2c 0.5.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -854,7 +854,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of aria2c 0.5.0:";;
|
short | recursive ) echo "Configuration of aria2c 0.5.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit 0
|
test -n "$ac_init_help" && exit 0
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
aria2c configure 0.5.0
|
aria2c configure 0.5.1
|
||||||
generated by GNU Autoconf 2.59
|
generated by GNU Autoconf 2.59
|
||||||
|
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
@ -1008,7 +1008,7 @@ cat >&5 <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by aria2c $as_me 0.5.0, which was
|
It was created by aria2c $as_me 0.5.1, which was
|
||||||
generated by GNU Autoconf 2.59. Invocation command line was
|
generated by GNU Autoconf 2.59. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -1651,7 +1651,7 @@ fi
|
||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE='aria2c'
|
PACKAGE='aria2c'
|
||||||
VERSION='0.5.0'
|
VERSION='0.5.1'
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
@ -11528,7 +11528,7 @@ _ASBOX
|
||||||
} >&5
|
} >&5
|
||||||
cat >&5 <<_CSEOF
|
cat >&5 <<_CSEOF
|
||||||
|
|
||||||
This file was extended by aria2c $as_me 0.5.0, which was
|
This file was extended by aria2c $as_me 0.5.1, which was
|
||||||
generated by GNU Autoconf 2.59. Invocation command line was
|
generated by GNU Autoconf 2.59. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -11591,7 +11591,7 @@ _ACEOF
|
||||||
|
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF
|
cat >>$CONFIG_STATUS <<_ACEOF
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
aria2c config.status 0.5.0
|
aria2c config.status 0.5.1
|
||||||
configured by $0, generated by GNU Autoconf 2.59,
|
configured by $0, generated by GNU Autoconf 2.59,
|
||||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
#
|
#
|
||||||
AC_PREREQ(2.59)
|
AC_PREREQ(2.59)
|
||||||
AC_INIT(aria2c, 0.5.0, tujikawa@rednoah.com)
|
AC_INIT(aria2c, 0.5.1, tujikawa@rednoah.com)
|
||||||
AM_INIT_AUTOMAKE()
|
AM_INIT_AUTOMAKE()
|
||||||
AM_PATH_CPPUNIT(1.10.2)
|
AM_PATH_CPPUNIT(1.10.2)
|
||||||
AC_CONFIG_SRCDIR([src/Socket.h])
|
AC_CONFIG_SRCDIR([src/Socket.h])
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
# General Public License and is *not* in the public domain.
|
# General Public License and is *not* in the public domain.
|
||||||
|
|
||||||
PACKAGE = aria2c
|
PACKAGE = aria2c
|
||||||
VERSION = 0.5.0
|
VERSION = 0.5.1
|
||||||
|
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "SleepCommand.h"
|
#include "SleepCommand.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, const Socket* s):
|
AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, const Socket* s):
|
||||||
Command(cuid), req(req), e(e), checkSocketIsReadable(false), checkSocketIsWritable(false) {
|
Command(cuid), req(req), e(e), checkSocketIsReadable(false), checkSocketIsWritable(false) {
|
||||||
|
@ -38,8 +37,7 @@ AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, cons
|
||||||
} else {
|
} else {
|
||||||
socket = NULL;
|
socket = NULL;
|
||||||
}
|
}
|
||||||
this->checkPoint.tv_sec = 0;
|
timeout = this->e->option->getAsInt(PREF_TIMEOUT);
|
||||||
this->checkPoint.tv_usec = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractCommand::~AbstractCommand() {
|
AbstractCommand::~AbstractCommand() {
|
||||||
|
@ -50,33 +48,12 @@ AbstractCommand::~AbstractCommand() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCommand::updateCheckPoint() {
|
|
||||||
gettimeofday(&checkPoint, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractCommand::isTimeoutDetected() {
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if(checkPoint.tv_sec == 0 && checkPoint.tv_usec == 0) {
|
|
||||||
checkPoint = now;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
int elapsed = Util::difftvsec(now, checkPoint);
|
|
||||||
if(elapsed >= e->option->getAsInt(PREF_TIMEOUT)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractCommand::execute() {
|
bool AbstractCommand::execute() {
|
||||||
try {
|
try {
|
||||||
if(checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
if(checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||||
checkSocketIsWritable && writeCheckTarget->isWritable(0) ||
|
checkSocketIsWritable && writeCheckTarget->isWritable(0) ||
|
||||||
!checkSocketIsReadable && !checkSocketIsWritable) {
|
!checkSocketIsReadable && !checkSocketIsWritable) {
|
||||||
|
checkPoint.reset();
|
||||||
updateCheckPoint();
|
|
||||||
Segment seg = { 0, 0, 0, false };
|
Segment seg = { 0, 0, 0, false };
|
||||||
if(e->segmentMan->downloadStarted) {
|
if(e->segmentMan->downloadStarted) {
|
||||||
// get segment information in order to set Range header.
|
// get segment information in order to set Range header.
|
||||||
|
@ -88,7 +65,7 @@ bool AbstractCommand::execute() {
|
||||||
}
|
}
|
||||||
return executeInternal(seg);
|
return executeInternal(seg);
|
||||||
} else {
|
} else {
|
||||||
if(isTimeoutDetected()) {
|
if(checkPoint.elapsed(timeout)) {
|
||||||
throw new DlRetryEx(EX_TIME_OUT);
|
throw new DlRetryEx(EX_TIME_OUT);
|
||||||
}
|
}
|
||||||
e->commands.push_back(this);
|
e->commands.push_back(this);
|
||||||
|
@ -99,6 +76,7 @@ bool AbstractCommand::execute() {
|
||||||
onAbort(err);
|
onAbort(err);
|
||||||
delete(err);
|
delete(err);
|
||||||
req->resetUrl();
|
req->resetUrl();
|
||||||
|
e->segmentMan->errors++;
|
||||||
return true;
|
return true;
|
||||||
} catch(DlRetryEx* err) {
|
} catch(DlRetryEx* err) {
|
||||||
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
||||||
|
@ -111,6 +89,7 @@ bool AbstractCommand::execute() {
|
||||||
delete(err);
|
delete(err);
|
||||||
if(isAbort) {
|
if(isAbort) {
|
||||||
logger->error(MSG_MAX_TRY, cuid, req->getTryCount());
|
logger->error(MSG_MAX_TRY, cuid, req->getTryCount());
|
||||||
|
e->segmentMan->errors++;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
||||||
|
|
|
@ -26,13 +26,12 @@
|
||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "SegmentMan.h"
|
#include "SegmentMan.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
|
|
||||||
class AbstractCommand : public Command {
|
class AbstractCommand : public Command {
|
||||||
private:
|
private:
|
||||||
void updateCheckPoint();
|
Time checkPoint;
|
||||||
bool isTimeoutDetected();
|
int timeout;
|
||||||
struct timeval checkPoint;
|
|
||||||
protected:
|
protected:
|
||||||
Request* req;
|
Request* req;
|
||||||
DownloadEngine* e;
|
DownloadEngine* e;
|
||||||
|
@ -44,6 +43,7 @@ protected:
|
||||||
|
|
||||||
void setReadCheckSocket(Socket* socket);
|
void setReadCheckSocket(Socket* socket);
|
||||||
void setWriteCheckSocket(Socket* socket);
|
void setWriteCheckSocket(Socket* socket);
|
||||||
|
void setTimeout(int timeout) { this->timeout = timeout; }
|
||||||
private:
|
private:
|
||||||
bool checkSocketIsReadable;
|
bool checkSocketIsReadable;
|
||||||
bool checkSocketIsWritable;
|
bool checkSocketIsWritable;
|
||||||
|
|
|
@ -40,14 +40,14 @@ void ConsoleDownloadEngine::sendStatistics(long long int currentSize, long long
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDownloadEngine::initStatistics() {
|
void ConsoleDownloadEngine::initStatistics() {
|
||||||
cp.tv_sec = cp.tv_usec = 0;
|
cp.reset();
|
||||||
|
startup.reset();
|
||||||
speed = 0;
|
speed = 0;
|
||||||
psize = 0;
|
psize = 0;
|
||||||
avgSpeed = 0;
|
avgSpeed = 0;
|
||||||
eta = 0;
|
eta = 0;
|
||||||
startupLength = 0;
|
startupLength = 0;
|
||||||
isStartupLengthSet = false;
|
isStartupLengthSet = false;
|
||||||
gettimeofday(&startup, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDownloadEngine::calculateStatistics() {
|
void ConsoleDownloadEngine::calculateStatistics() {
|
||||||
|
@ -56,28 +56,24 @@ void ConsoleDownloadEngine::calculateStatistics() {
|
||||||
startupLength = dlSize;
|
startupLength = dlSize;
|
||||||
isStartupLengthSet = true;
|
isStartupLengthSet = true;
|
||||||
}
|
}
|
||||||
struct timeval now;
|
int elapsed = cp.difference();
|
||||||
gettimeofday(&now, NULL);
|
if(elapsed >= 1) {
|
||||||
if(cp.tv_sec == 0 && cp.tv_usec == 0) {
|
int nspeed = (int)((dlSize-psize)/elapsed);
|
||||||
cp = now;
|
speed = (nspeed+speed)/2;
|
||||||
|
cp.reset();
|
||||||
psize = dlSize;
|
psize = dlSize;
|
||||||
} else {
|
|
||||||
int elapsed = Util::difftvsec(now, cp);
|
|
||||||
if(elapsed >= 1) {
|
|
||||||
int nspeed = (int)((dlSize-psize)/elapsed);
|
|
||||||
speed = (nspeed+speed)/2;
|
|
||||||
cp = now;
|
|
||||||
psize = dlSize;
|
|
||||||
|
|
||||||
avgSpeed = (int)((dlSize-startupLength)/Util::difftvsec(now, startup));
|
int elapsedFromStartup = startup.difference();
|
||||||
if(avgSpeed < 0) {
|
if(elapsedFromStartup > 0) {
|
||||||
avgSpeed = 0;
|
avgSpeed = (int)((dlSize-startupLength)/elapsedFromStartup);
|
||||||
} else if(avgSpeed != 0 && segmentMan->totalSize > 0) {
|
|
||||||
eta = (segmentMan->totalSize-dlSize)/avgSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendStatistics(dlSize, segmentMan->totalSize);
|
|
||||||
}
|
}
|
||||||
|
if(avgSpeed < 0) {
|
||||||
|
avgSpeed = 0;
|
||||||
|
} else if(avgSpeed != 0 && segmentMan->totalSize > 0) {
|
||||||
|
eta = (segmentMan->totalSize-dlSize)/avgSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendStatistics(dlSize, segmentMan->totalSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,15 @@
|
||||||
#define _D_CONSOLE_DOWNLOAD_ENGINE_H_
|
#define _D_CONSOLE_DOWNLOAD_ENGINE_H_
|
||||||
|
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
class ConsoleDownloadEngine : public DownloadEngine {
|
class ConsoleDownloadEngine : public DownloadEngine {
|
||||||
private:
|
private:
|
||||||
struct timeval cp;
|
Time cp;
|
||||||
long long int psize;
|
long long int psize;
|
||||||
int speed;
|
int speed;
|
||||||
// The time when startup
|
// The time when startup
|
||||||
struct timeval startup;
|
Time startup;
|
||||||
// The number of bytes downloaded at startup
|
// The number of bytes downloaded at startup
|
||||||
long long int startupLength;
|
long long int startupLength;
|
||||||
bool isStartupLengthSet;
|
bool isStartupLengthSet;
|
||||||
|
|
|
@ -27,10 +27,7 @@
|
||||||
#include "InitiateConnectionCommandFactory.h"
|
#include "InitiateConnectionCommandFactory.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
DownloadCommand::DownloadCommand(int cuid, Request* req, DownloadEngine* e, const Socket* s):AbstractCommand(cuid, req, e, s), lastSize(0) {
|
DownloadCommand::DownloadCommand(int cuid, Request* req, DownloadEngine* e, const Socket* s):AbstractCommand(cuid, req, e, s), lastSize(0) {}
|
||||||
sw.tv_sec = 0;
|
|
||||||
sw.tv_usec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DownloadCommand::~DownloadCommand() {}
|
DownloadCommand::~DownloadCommand() {}
|
||||||
|
|
||||||
|
@ -54,18 +51,11 @@ bool DownloadCommand::executeInternal(Segment seg) {
|
||||||
seg.ds += bufSize;
|
seg.ds += bufSize;
|
||||||
}
|
}
|
||||||
// calculate downloading speed
|
// calculate downloading speed
|
||||||
struct timeval now;
|
int diff = sw.difference();
|
||||||
gettimeofday(&now, NULL);
|
if(diff >= 1) {
|
||||||
if(sw.tv_sec == 0 && sw.tv_usec == 0) {
|
seg.speed = (int)((seg.ds-lastSize)/(diff*1.0));
|
||||||
sw = now;
|
sw.reset();
|
||||||
lastSize = seg.ds;
|
lastSize = seg.ds;
|
||||||
} else {
|
|
||||||
int diff = Util::difftvsec(now, sw);
|
|
||||||
if(diff >= 1) {
|
|
||||||
seg.speed = (int)((seg.ds-lastSize)/(diff*1.0));
|
|
||||||
sw = now;
|
|
||||||
lastSize = seg.ds;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(e->segmentMan->totalSize != 0 && bufSize == 0) {
|
if(e->segmentMan->totalSize != 0 && bufSize == 0) {
|
||||||
throw new DlRetryEx(EX_GOT_EOF);
|
throw new DlRetryEx(EX_GOT_EOF);
|
||||||
|
|
|
@ -24,14 +24,13 @@
|
||||||
|
|
||||||
#include "AbstractCommand.h"
|
#include "AbstractCommand.h"
|
||||||
#include "TransferEncoding.h"
|
#include "TransferEncoding.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class DownloadCommand : public AbstractCommand {
|
class DownloadCommand : public AbstractCommand {
|
||||||
private:
|
private:
|
||||||
struct timeval sw;
|
Time sw;
|
||||||
long long int lastSize;
|
long long int lastSize;
|
||||||
protected:
|
protected:
|
||||||
bool executeInternal(Segment segment);
|
bool executeInternal(Segment segment);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
|
#include "Time.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -48,15 +49,11 @@ void DownloadEngine::cleanQueue() {
|
||||||
|
|
||||||
void DownloadEngine::run() {
|
void DownloadEngine::run() {
|
||||||
initStatistics();
|
initStatistics();
|
||||||
struct timeval cp;
|
Time cp;
|
||||||
cp.tv_sec = 0;
|
|
||||||
cp.tv_usec = 0;
|
|
||||||
Sockets activeSockets;
|
Sockets activeSockets;
|
||||||
while(!commands.empty()) {
|
while(!commands.empty()) {
|
||||||
struct timeval now;
|
if(cp.elapsed(1)) {
|
||||||
gettimeofday(&now, NULL);
|
cp.reset();
|
||||||
if(Util::difftvsec(now, cp) >= 1) {
|
|
||||||
cp = now;
|
|
||||||
int max = commands.size();
|
int max = commands.size();
|
||||||
for(int i = 0; i < max; i++) {
|
for(int i = 0; i < max; i++) {
|
||||||
Command* com = commands.front();
|
Command* com = commands.front();
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Option.h"
|
#include "Option.h"
|
||||||
#include <sys/time.h>
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
typedef deque<Socket*> Sockets;
|
typedef deque<Socket*> Sockets;
|
||||||
typedef deque<Command*> Commands;
|
typedef deque<Command*> Commands;
|
||||||
|
|
|
@ -101,7 +101,8 @@ SRCS = Socket.cc Socket.h\
|
||||||
AllowedFastMessage.cc AllowedFastMessage.h\
|
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||||
SimplePeerMessage.cc SimplePeerMessage.h\
|
SimplePeerMessage.cc SimplePeerMessage.h\
|
||||||
NullLogger.h
|
NullLogger.h\
|
||||||
|
Time.cc Time.h
|
||||||
noinst_LIBRARIES = libaria2c.a
|
noinst_LIBRARIES = libaria2c.a
|
||||||
libaria2c_a_SOURCES = $(SRCS)
|
libaria2c_a_SOURCES = $(SRCS)
|
||||||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||||
|
|
|
@ -109,7 +109,7 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
|
||||||
PortMessage.$(OBJEXT) HaveAllMessage.$(OBJEXT) \
|
PortMessage.$(OBJEXT) HaveAllMessage.$(OBJEXT) \
|
||||||
HaveNoneMessage.$(OBJEXT) RejectMessage.$(OBJEXT) \
|
HaveNoneMessage.$(OBJEXT) RejectMessage.$(OBJEXT) \
|
||||||
AllowedFastMessage.$(OBJEXT) SuggestPieceMessage.$(OBJEXT) \
|
AllowedFastMessage.$(OBJEXT) SuggestPieceMessage.$(OBJEXT) \
|
||||||
SimplePeerMessage.$(OBJEXT)
|
SimplePeerMessage.$(OBJEXT) Time.$(OBJEXT)
|
||||||
am_libaria2c_a_OBJECTS = $(am__objects_1)
|
am_libaria2c_a_OBJECTS = $(am__objects_1)
|
||||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||||
|
@ -360,7 +360,8 @@ SRCS = Socket.cc Socket.h\
|
||||||
AllowedFastMessage.cc AllowedFastMessage.h\
|
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||||
SimplePeerMessage.cc SimplePeerMessage.h\
|
SimplePeerMessage.cc SimplePeerMessage.h\
|
||||||
NullLogger.h
|
NullLogger.h\
|
||||||
|
Time.cc Time.h
|
||||||
|
|
||||||
noinst_LIBRARIES = libaria2c.a
|
noinst_LIBRARIES = libaria2c.a
|
||||||
libaria2c_a_SOURCES = $(SRCS)
|
libaria2c_a_SOURCES = $(SRCS)
|
||||||
|
@ -525,6 +526,7 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitFirstSegmentSplitter.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitFirstSegmentSplitter.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitSlowestSegmentSplitter.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitSlowestSegmentSplitter.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessage.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessage.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Time.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentAutoSaveCommand.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentAutoSaveCommand.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
|
||||||
|
|
|
@ -59,6 +59,7 @@ void Peer::resetStatus() {
|
||||||
resetDeltaDownload();
|
resetDeltaDownload();
|
||||||
chokingRequired = true;
|
chokingRequired = true;
|
||||||
optUnchoking = false;
|
optUnchoking = false;
|
||||||
|
snubbing = false;
|
||||||
fastExtensionEnabled = false;
|
fastExtensionEnabled = false;
|
||||||
latency = DEFAULT_LATENCY;
|
latency = DEFAULT_LATENCY;
|
||||||
fastSet.clear();
|
fastSet.clear();
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
int cuid;
|
int cuid;
|
||||||
bool chokingRequired;
|
bool chokingRequired;
|
||||||
bool optUnchoking;
|
bool optUnchoking;
|
||||||
|
bool snubbing;
|
||||||
private:
|
private:
|
||||||
char peerId[PEER_ID_LENGTH];
|
char peerId[PEER_ID_LENGTH];
|
||||||
BitfieldMan* bitfield;
|
BitfieldMan* bitfield;
|
||||||
|
@ -65,6 +66,7 @@ public:
|
||||||
peerChoking(true), peerInterested(false),
|
peerChoking(true), peerInterested(false),
|
||||||
tryCount(0), error(0), cuid(0),
|
tryCount(0), error(0), cuid(0),
|
||||||
chokingRequired(true), optUnchoking(false),
|
chokingRequired(true), optUnchoking(false),
|
||||||
|
snubbing(false),
|
||||||
bitfield(NULL),
|
bitfield(NULL),
|
||||||
fastExtensionEnabled(false),
|
fastExtensionEnabled(false),
|
||||||
peerUpload(0), peerDownload(0),
|
peerUpload(0), peerDownload(0),
|
||||||
|
@ -107,8 +109,8 @@ public:
|
||||||
void setAllBitfield();
|
void setAllBitfield();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* operation = 1: set index-th bit 1
|
* operation = 1: set index-th bit to 1
|
||||||
* operation = 0: set index-th bit 0
|
* operation = 0: set index-th bit to 0
|
||||||
*/
|
*/
|
||||||
void updateBitfield(int index, int operation);
|
void updateBitfield(int index, int operation);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, const Socket* s):
|
PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, const Socket* s):
|
||||||
Command(cuid), e(e), peer(peer),
|
Command(cuid), e(e), peer(peer),
|
||||||
|
@ -38,8 +37,6 @@ PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEn
|
||||||
} else {
|
} else {
|
||||||
socket = NULL;
|
socket = NULL;
|
||||||
}
|
}
|
||||||
this->checkPoint.tv_sec = 0;
|
|
||||||
this->checkPoint.tv_usec = 0;
|
|
||||||
timeout = e->option->getAsInt(PREF_TIMEOUT);
|
timeout = e->option->getAsInt(PREF_TIMEOUT);
|
||||||
e->torrentMan->connections++;
|
e->torrentMan->connections++;
|
||||||
}
|
}
|
||||||
|
@ -53,26 +50,6 @@ PeerAbstractCommand::~PeerAbstractCommand() {
|
||||||
e->torrentMan->connections--;
|
e->torrentMan->connections--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerAbstractCommand::updateCheckPoint() {
|
|
||||||
gettimeofday(&checkPoint, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeerAbstractCommand::isTimeoutDetected() {
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if(checkPoint.tv_sec == 0 && checkPoint.tv_usec == 0) {
|
|
||||||
checkPoint = now;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
int elapsed = Util::difftvsec(now, checkPoint);
|
|
||||||
if(elapsed >= timeout) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeerAbstractCommand::execute() {
|
bool PeerAbstractCommand::execute() {
|
||||||
if(e->torrentMan->isHalt()) {
|
if(e->torrentMan->isHalt()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,12 +59,9 @@ bool PeerAbstractCommand::execute() {
|
||||||
e->getUploadSpeed() <= uploadLimit*1024) ||
|
e->getUploadSpeed() <= uploadLimit*1024) ||
|
||||||
checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||||
checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
|
checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
|
||||||
updateCheckPoint();
|
checkPoint.reset();
|
||||||
}
|
}
|
||||||
if(isTimeoutDetected()) {
|
if(checkPoint.elapsed(timeout)) {
|
||||||
// TODO following 2 lines will be deleted.
|
|
||||||
checkPoint.tv_sec = 0;
|
|
||||||
checkPoint.tv_usec = 0;
|
|
||||||
throw new DlRetryEx(EX_TIME_OUT);
|
throw new DlRetryEx(EX_TIME_OUT);
|
||||||
}
|
}
|
||||||
return executeInternal();
|
return executeInternal();
|
||||||
|
|
|
@ -25,13 +25,11 @@
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
#include "TorrentDownloadEngine.h"
|
#include "TorrentDownloadEngine.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
|
|
||||||
class PeerAbstractCommand : public Command {
|
class PeerAbstractCommand : public Command {
|
||||||
private:
|
private:
|
||||||
void updateCheckPoint();
|
Time checkPoint;
|
||||||
bool isTimeoutDetected();
|
|
||||||
struct timeval checkPoint;
|
|
||||||
int timeout;
|
int timeout;
|
||||||
protected:
|
protected:
|
||||||
TorrentDownloadEngine* e;
|
TorrentDownloadEngine* e;
|
||||||
|
|
|
@ -22,10 +22,7 @@
|
||||||
#include "PeerChokeCommand.h"
|
#include "PeerChokeCommand.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
PeerChokeCommand::PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e):Command(cuid), interval(interval), e(e), rotate(0) {
|
PeerChokeCommand::PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e):Command(cuid), interval(interval), e(e), rotate(0) {}
|
||||||
checkPoint.tv_sec = 0;
|
|
||||||
checkPoint.tv_usec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeerChokeCommand::~PeerChokeCommand() {}
|
PeerChokeCommand::~PeerChokeCommand() {}
|
||||||
|
|
||||||
|
@ -41,23 +38,16 @@ void PeerChokeCommand::optUnchokingPeer(Peers& peers) const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
random_shuffle(peers.begin(), peers.end());
|
random_shuffle(peers.begin(), peers.end());
|
||||||
|
int optUnchokCount = 1;
|
||||||
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
||||||
(*itr)->optUnchoking = false;
|
Peers::value_type peer = *itr;
|
||||||
}
|
if(optUnchokCount > 0 && !peer->snubbing) {
|
||||||
Peer* peer = peers.front();
|
optUnchokCount--;
|
||||||
peer->optUnchoking = true;
|
peer->optUnchoking = true;
|
||||||
logger->debug("opt, unchoking %s, delta=%d",
|
logger->debug("opt, unchoking %s, delta=%d",
|
||||||
peer->ipaddr.c_str(), peer->getDeltaUpload());
|
peer->ipaddr.c_str(), peer->getDeltaUpload());
|
||||||
if(e->torrentMan->isEndGame()) {
|
} else {
|
||||||
Peers::iterator itr = peers.begin()+1;
|
peer->optUnchoking = false;
|
||||||
for(; itr != peers.end(); itr++) {
|
|
||||||
Peer* peer = *itr;
|
|
||||||
if(peer->amInterested && peer->peerInterested) {
|
|
||||||
peer->optUnchoking = true;
|
|
||||||
logger->debug("opt, unchoking %s, delta=%d",
|
|
||||||
peer->ipaddr.c_str(), peer->getDeltaUpload());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,10 +86,8 @@ bool PeerChokeCommand::execute() {
|
||||||
if(e->torrentMan->isHalt()) {
|
if(e->torrentMan->isHalt()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
struct timeval now;
|
if(checkPoint.elapsed(interval)) {
|
||||||
gettimeofday(&now, NULL);
|
checkPoint.reset();
|
||||||
if(Util::difftvsec(now, checkPoint) >= interval) {
|
|
||||||
checkPoint = now;
|
|
||||||
Peers peers = e->torrentMan->getActivePeers();
|
Peers peers = e->torrentMan->getActivePeers();
|
||||||
setAllPeerChoked(peers);
|
setAllPeerChoked(peers);
|
||||||
if(e->torrentMan->downloadComplete()) {
|
if(e->torrentMan->downloadComplete()) {
|
||||||
|
@ -107,14 +95,14 @@ bool PeerChokeCommand::execute() {
|
||||||
} else {
|
} else {
|
||||||
orderByUploadRate(peers);
|
orderByUploadRate(peers);
|
||||||
}
|
}
|
||||||
int unchokingCount = peers.size() >= 4 ? 4 : peers.size();
|
int unchokingCount = 4;//peers.size() >= 4 ? 4 : peers.size();
|
||||||
for(Peers::iterator itr = peers.begin(); unchokingCount > 0 && itr != peers.end(); ) {
|
for(Peers::iterator itr = peers.begin(); itr != peers.end() && unchokingCount > 0; ) {
|
||||||
Peer* peer = *itr;
|
Peer* peer = *itr;
|
||||||
if(peer->peerInterested) {
|
if(peer->peerInterested && !peer->snubbing) {
|
||||||
|
unchokingCount--;
|
||||||
peer->chokingRequired = false;
|
peer->chokingRequired = false;
|
||||||
peer->optUnchoking = false;
|
peer->optUnchoking = false;
|
||||||
itr = peers.erase(itr);
|
itr = peers.erase(itr);
|
||||||
unchokingCount--;
|
|
||||||
logger->debug("cat01, unchoking %s, delta=%d", peer->ipaddr.c_str(), peer->getDeltaUpload());
|
logger->debug("cat01, unchoking %s, delta=%d", peer->ipaddr.c_str(), peer->getDeltaUpload());
|
||||||
} else {
|
} else {
|
||||||
itr++;
|
itr++;
|
||||||
|
@ -122,7 +110,7 @@ bool PeerChokeCommand::execute() {
|
||||||
}
|
}
|
||||||
for(Peers::iterator itr = peers.begin(); itr != peers.end(); ) {
|
for(Peers::iterator itr = peers.begin(); itr != peers.end(); ) {
|
||||||
Peer* peer = *itr;
|
Peer* peer = *itr;
|
||||||
if(!peer->peerInterested) {
|
if(!peer->peerInterested && !peer->snubbing) {
|
||||||
peer->chokingRequired = false;
|
peer->chokingRequired = false;
|
||||||
peer->optUnchoking = false;
|
peer->optUnchoking = false;
|
||||||
itr = peers.erase(itr);
|
itr = peers.erase(itr);
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
|
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "TorrentDownloadEngine.h"
|
#include "TorrentDownloadEngine.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
class PeerChokeCommand : public Command {
|
class PeerChokeCommand : public Command {
|
||||||
private:
|
private:
|
||||||
int interval;
|
int interval;
|
||||||
TorrentDownloadEngine* e;
|
TorrentDownloadEngine* e;
|
||||||
int rotate;
|
int rotate;
|
||||||
struct timeval checkPoint;
|
Time checkPoint;
|
||||||
|
|
||||||
void orderByUploadRate(Peers& peers) const;
|
void orderByUploadRate(Peers& peers) const;
|
||||||
void orderByDownloadRate(Peers& peers) const;
|
void orderByDownloadRate(Peers& peers) const;
|
||||||
|
|
|
@ -231,6 +231,7 @@ void PeerInteraction::checkRequestSlot() {
|
||||||
Piece& piece = getDownloadPiece(slot.getIndex());
|
Piece& piece = getDownloadPiece(slot.getIndex());
|
||||||
piece.cancelBlock(slot.getBlockIndex());
|
piece.cancelBlock(slot.getBlockIndex());
|
||||||
itr = requestSlots.erase(itr);
|
itr = requestSlots.erase(itr);
|
||||||
|
peer->snubbing = true;
|
||||||
} else {
|
} else {
|
||||||
Piece piece = getDownloadPiece(slot.getIndex());
|
Piece piece = getDownloadPiece(slot.getIndex());
|
||||||
if(piece.hasBlock(slot.getBlockIndex()) ||
|
if(piece.hasBlock(slot.getBlockIndex()) ||
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "SuggestPieceMessage.h"
|
#include "SuggestPieceMessage.h"
|
||||||
#include "RequestSlot.h"
|
#include "RequestSlot.h"
|
||||||
|
|
||||||
#define REQUEST_TIME_OUT 120
|
#define REQUEST_TIME_OUT 60
|
||||||
#define ALLOWED_FAST_SET_SIZE 10
|
#define ALLOWED_FAST_SET_SIZE 10
|
||||||
|
|
||||||
typedef deque<RequestSlot> RequestSlots;
|
typedef deque<RequestSlot> RequestSlots;
|
||||||
|
|
|
@ -41,12 +41,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
||||||
e->torrentMan, this->peer);
|
e->torrentMan, this->peer);
|
||||||
peerInteraction->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
peerInteraction->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
||||||
setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
||||||
keepAliveCheckPoint.tv_sec = 0;
|
|
||||||
keepAliveCheckPoint.tv_usec = 0;
|
|
||||||
chokeCheckPoint.tv_sec = 0;
|
|
||||||
chokeCheckPoint.tv_usec = 0;
|
|
||||||
freqCheckPoint.tv_sec = 0;
|
|
||||||
freqCheckPoint.tv_usec = 0;
|
|
||||||
chokeUnchokeCount = 0;
|
chokeUnchokeCount = 0;
|
||||||
haveCount = 0;
|
haveCount = 0;
|
||||||
keepAliveCount = 0;
|
keepAliveCount = 0;
|
||||||
|
@ -55,7 +49,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
||||||
|
|
||||||
PeerInteractionCommand::~PeerInteractionCommand() {
|
PeerInteractionCommand::~PeerInteractionCommand() {
|
||||||
delete peerInteraction;
|
delete peerInteraction;
|
||||||
e->torrentMan->unadvertisePiece(cuid);
|
|
||||||
e->torrentMan->deleteActivePeer(this->peer);
|
e->torrentMan->deleteActivePeer(this->peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +82,7 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
peer->ipaddr.c_str(), peer->port,
|
peer->ipaddr.c_str(), peer->port,
|
||||||
handshakeMessage->toString().c_str());
|
handshakeMessage->toString().c_str());
|
||||||
delete handshakeMessage;
|
delete handshakeMessage;
|
||||||
|
haveCheckTime.reset();
|
||||||
peerInteraction->sendBitfield();
|
peerInteraction->sendBitfield();
|
||||||
peerInteraction->sendAllowedFast();
|
peerInteraction->sendAllowedFast();
|
||||||
sequence = WIRED;
|
sequence = WIRED;
|
||||||
|
@ -105,6 +99,7 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
handshakeMessage->toString().c_str());
|
handshakeMessage->toString().c_str());
|
||||||
delete handshakeMessage;
|
delete handshakeMessage;
|
||||||
peerInteraction->sendHandshake();
|
peerInteraction->sendHandshake();
|
||||||
|
haveCheckTime.reset();
|
||||||
peerInteraction->sendBitfield();
|
peerInteraction->sendBitfield();
|
||||||
peerInteraction->sendAllowedFast();
|
peerInteraction->sendAllowedFast();
|
||||||
sequence = WIRED;
|
sequence = WIRED;
|
||||||
|
@ -134,24 +129,19 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FLOODING_CHECK_INTERVAL 5
|
||||||
|
|
||||||
void PeerInteractionCommand::detectMessageFlooding() {
|
void PeerInteractionCommand::detectMessageFlooding() {
|
||||||
struct timeval now;
|
if(freqCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) {
|
||||||
gettimeofday(&now, NULL);
|
if(chokeUnchokeCount*1.0/FLOODING_CHECK_INTERVAL >= 0.4
|
||||||
if(freqCheckPoint.tv_sec == 0 && freqCheckPoint.tv_usec == 0) {
|
//|| haveCount*1.0/elapsed >= 20.0
|
||||||
freqCheckPoint = now;
|
|| keepAliveCount*1.0/FLOODING_CHECK_INTERVAL >= 1.0) {
|
||||||
} else {
|
throw new DlAbortEx("Flooding detected.");
|
||||||
int elapsed = Util::difftvsec(now, freqCheckPoint);
|
} else {
|
||||||
if(elapsed >= 5) {
|
chokeUnchokeCount = 0;
|
||||||
if(chokeUnchokeCount*1.0/elapsed >= 0.4
|
haveCount = 0;
|
||||||
//|| haveCount*1.0/elapsed >= 20.0
|
keepAliveCount = 0;
|
||||||
|| keepAliveCount*1.0/elapsed >= 1.0) {
|
freqCheckPoint.reset();
|
||||||
throw new DlAbortEx("Flooding detected.");
|
|
||||||
} else {
|
|
||||||
chokeUnchokeCount = 0;
|
|
||||||
haveCount = 0;
|
|
||||||
keepAliveCount = 0;
|
|
||||||
freqCheckPoint = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,21 +150,13 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
|
||||||
if(e->torrentMan->downloadComplete()) {
|
if(e->torrentMan->downloadComplete()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct timeval now;
|
if(peer->amInterested && peer->peerChoking) {
|
||||||
gettimeofday(&now, NULL);
|
if(chokeCheckPoint.elapsed(MAX_PEER_CHOKING_INTERVAL)) {
|
||||||
if(chokeCheckPoint.tv_sec == 0 && chokeCheckPoint.tv_usec == 0) {
|
logger->info("CUID#%d - The peer is choking too long.", cuid);
|
||||||
if(peer->amInterested && peer->peerChoking) {
|
peer->snubbing = true;
|
||||||
chokeCheckPoint = now;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(peer->amInterested && peer->peerChoking) {
|
chokeCheckPoint.reset();
|
||||||
if(Util::difftvsec(now, chokeCheckPoint) >= MAX_PEER_CHOKING_INTERVAL) {
|
|
||||||
throw new DlAbortEx("Too long choking.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
chokeCheckPoint.tv_sec = 0;
|
|
||||||
chokeCheckPoint.tv_usec = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,24 +233,19 @@ void PeerInteractionCommand::onAbort(Exception* ex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerInteractionCommand::sendKeepAlive() {
|
void PeerInteractionCommand::sendKeepAlive() {
|
||||||
if(keepAliveCheckPoint.tv_sec == 0 && keepAliveCheckPoint.tv_usec == 0) {
|
if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) {
|
||||||
gettimeofday(&keepAliveCheckPoint, NULL);
|
if(peerInteraction->countMessageInQueue() == 0) {
|
||||||
} else {
|
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
|
||||||
struct timeval now;
|
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if(Util::difftvsec(now, keepAliveCheckPoint) >= 120) {
|
|
||||||
if(peerInteraction->countMessageInQueue() == 0) {
|
|
||||||
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
|
|
||||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
|
||||||
}
|
|
||||||
keepAliveCheckPoint = now;
|
|
||||||
}
|
}
|
||||||
|
keepAliveCheckPoint.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerInteractionCommand::checkHave() {
|
void PeerInteractionCommand::checkHave() {
|
||||||
e->torrentMan->unadvertisePiece(cuid);
|
PieceIndexes indexes =
|
||||||
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
|
e->torrentMan->getAdvertisedPieceIndexes(cuid, haveCheckTime);
|
||||||
|
haveCheckTime.reset();
|
||||||
if(indexes.size() >= 20) {
|
if(indexes.size() >= 20) {
|
||||||
if(peer->isFastExtensionEnabled()) {
|
if(peer->isFastExtensionEnabled()) {
|
||||||
if(e->torrentMan->hasAllPieces()) {
|
if(e->torrentMan->hasAllPieces()) {
|
||||||
|
|
|
@ -25,19 +25,22 @@
|
||||||
#include "PeerAbstractCommand.h"
|
#include "PeerAbstractCommand.h"
|
||||||
#include "PeerConnection.h"
|
#include "PeerConnection.h"
|
||||||
#include "PeerInteraction.h"
|
#include "PeerInteraction.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define MAX_PEER_CHOKING_INTERVAL (3*60)
|
#define MAX_PEER_CHOKING_INTERVAL (1*60)
|
||||||
|
#define KEEP_ALIVE_INTERVAL 120
|
||||||
|
|
||||||
class PeerInteractionCommand : public PeerAbstractCommand {
|
class PeerInteractionCommand : public PeerAbstractCommand {
|
||||||
private:
|
private:
|
||||||
int sequence;
|
int sequence;
|
||||||
PeerInteraction* peerInteraction;
|
PeerInteraction* peerInteraction;
|
||||||
|
|
||||||
struct timeval keepAliveCheckPoint;
|
Time keepAliveCheckPoint;
|
||||||
struct timeval chokeCheckPoint;
|
Time chokeCheckPoint;
|
||||||
struct timeval freqCheckPoint;
|
Time freqCheckPoint;
|
||||||
|
Time haveCheckTime;
|
||||||
int chokeUnchokeCount;
|
int chokeUnchokeCount;
|
||||||
int haveCount;
|
int haveCount;
|
||||||
int keepAliveCount;
|
int keepAliveCount;
|
||||||
|
|
|
@ -59,6 +59,7 @@ void PieceMessage::receivedAction() {
|
||||||
peer->addPeerUpload(blockLength);
|
peer->addPeerUpload(blockLength);
|
||||||
if(!RequestSlot::isNull(slot) &&
|
if(!RequestSlot::isNull(slot) &&
|
||||||
peerInteraction->hasDownloadPiece(slot.getIndex())) {
|
peerInteraction->hasDownloadPiece(slot.getIndex())) {
|
||||||
|
peer->snubbing = false;
|
||||||
//logger->debug("CUID#%d - Latency=%d", cuid, slot.getLatencyInMillis());
|
//logger->debug("CUID#%d - Latency=%d", cuid, slot.getLatencyInMillis());
|
||||||
peer->updateLatency(slot.getLatencyInMillis());
|
peer->updateLatency(slot.getLatencyInMillis());
|
||||||
Piece& piece = peerInteraction->getDownloadPiece(slot.getIndex());
|
Piece& piece = peerInteraction->getDownloadPiece(slot.getIndex());
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
RequestSlot::RequestSlot(int index, int begin, int length, int blockIndex)
|
RequestSlot::RequestSlot(int index, int begin, int length, int blockIndex)
|
||||||
:index(index), begin(begin), length(length), blockIndex(blockIndex) {
|
:index(index), begin(begin), length(length), blockIndex(blockIndex) {}
|
||||||
setDispatchedTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
|
RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
|
||||||
copy(requestSlot);
|
copy(requestSlot);
|
||||||
|
@ -49,17 +47,15 @@ void RequestSlot::copy(const RequestSlot& requestSlot) {
|
||||||
RequestSlot RequestSlot::nullSlot(0, 0, 0, 0);
|
RequestSlot RequestSlot::nullSlot(0, 0, 0, 0);
|
||||||
|
|
||||||
void RequestSlot::setDispatchedTime() {
|
void RequestSlot::setDispatchedTime() {
|
||||||
gettimeofday(&dispatchedTime, NULL);
|
dispatchedTime.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestSlot::isTimeout(int timeoutSec) const {
|
bool RequestSlot::isTimeout(int timeoutSec) const {
|
||||||
return getLatencyInMillis() > timeoutSec*1000;
|
return dispatchedTime.differenceInMillis() > timeoutSec*1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RequestSlot::getLatencyInMillis() const {
|
int RequestSlot::getLatencyInMillis() const {
|
||||||
struct timeval now;
|
return dispatchedTime.differenceInMillis();
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
return Util::difftv(now, dispatchedTime)/1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestSlot::isNull(const RequestSlot& requestSlot) {
|
bool RequestSlot::isNull(const RequestSlot& requestSlot) {
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
#define _D_REQUEST_SLOT_H_
|
#define _D_REQUEST_SLOT_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
|
|
||||||
class RequestSlot {
|
class RequestSlot {
|
||||||
private:
|
private:
|
||||||
struct timeval dispatchedTime;
|
Time dispatchedTime;
|
||||||
int index;
|
int index;
|
||||||
int begin;
|
int begin;
|
||||||
int length;
|
int length;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
SegmentMan::SegmentMan():totalSize(0),
|
SegmentMan::SegmentMan():totalSize(0),
|
||||||
isSplittable(true),
|
isSplittable(true),
|
||||||
downloadStarted(false),
|
downloadStarted(false),
|
||||||
|
errors(0),
|
||||||
dir("."),
|
dir("."),
|
||||||
splitter(NULL),
|
splitter(NULL),
|
||||||
diskWriter(NULL) {
|
diskWriter(NULL) {
|
||||||
|
@ -241,6 +242,7 @@ void SegmentMan::init() {
|
||||||
totalSize = 0;
|
totalSize = 0;
|
||||||
isSplittable = false;
|
isSplittable = false;
|
||||||
downloadStarted = false;
|
downloadStarted = false;
|
||||||
|
errors = 0;
|
||||||
segments.clear();
|
segments.clear();
|
||||||
diskWriter->closeFile();
|
diskWriter->closeFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,11 @@ public:
|
||||||
*/
|
*/
|
||||||
string ufilename;
|
string ufilename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the number of failures(usually, DlAbortEx) in downloads.
|
||||||
|
*/
|
||||||
|
int errors;
|
||||||
|
|
||||||
const Option* option;
|
const Option* option;
|
||||||
SegmentSplitter* splitter;
|
SegmentSplitter* splitter;
|
||||||
DiskWriter* diskWriter;
|
DiskWriter* diskWriter;
|
||||||
|
@ -91,7 +96,7 @@ public:
|
||||||
SegmentMan();
|
SegmentMan();
|
||||||
~SegmentMan();
|
~SegmentMan();
|
||||||
|
|
||||||
// Initializes totalSize, isSplittable, downloadStarted.
|
// Initializes totalSize, isSplittable, downloadStarted, errors.
|
||||||
// Clears command queue. Also, closes diskWriter.
|
// Clears command queue. Also, closes diskWriter.
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
SleepCommand::SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait):
|
SleepCommand::SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait):
|
||||||
Command(cuid), engine(e), nextCommand(nextCommand), wait(wait) {
|
Command(cuid), engine(e), nextCommand(nextCommand), wait(wait) {}
|
||||||
gettimeofday(&checkPoint, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
SleepCommand::~SleepCommand() {
|
SleepCommand::~SleepCommand() {
|
||||||
if(nextCommand != NULL) {
|
if(nextCommand != NULL) {
|
||||||
|
@ -34,9 +32,7 @@ SleepCommand::~SleepCommand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SleepCommand::execute() {
|
bool SleepCommand::execute() {
|
||||||
struct timeval now;
|
if(checkPoint.elapsed(wait)) {
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if(Util::difftvsec(now, checkPoint) >= wait) {
|
|
||||||
engine->commands.push_back(nextCommand);
|
engine->commands.push_back(nextCommand);
|
||||||
nextCommand = NULL;
|
nextCommand = NULL;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -24,14 +24,14 @@
|
||||||
|
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
|
|
||||||
class SleepCommand:public Command {
|
class SleepCommand:public Command {
|
||||||
private:
|
private:
|
||||||
DownloadEngine* engine;
|
DownloadEngine* engine;
|
||||||
Command* nextCommand;
|
Command* nextCommand;
|
||||||
int wait;
|
int wait;
|
||||||
struct timeval checkPoint;
|
Time checkPoint;
|
||||||
public:
|
public:
|
||||||
SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait);
|
SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait);
|
||||||
~SleepCommand();
|
~SleepCommand();
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - a simple utility for downloading files faster
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
#include "Time.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
Time::Time() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
Time::Time(const Time& time) {
|
||||||
|
tv = time.tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
Time::~Time() {}
|
||||||
|
|
||||||
|
Time& Time::operator=(const Time& time) {
|
||||||
|
if(this != &time) {
|
||||||
|
tv = time.tv;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::reset() {
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timeval Time::getCurrentTime() const {
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::elapsed(int sec) const {
|
||||||
|
return Util::difftvsec(getCurrentTime(), tv) >= sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::elapsedInMillis(int millis) const {
|
||||||
|
return Util::difftv(getCurrentTime(), tv)/1000 >= millis;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::isNewer(const Time& time) const {
|
||||||
|
return Util::difftvsec(this->tv, time.tv) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::difference() const {
|
||||||
|
return Util::difftvsec(getCurrentTime(), tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
long long int Time::differenceInMillis() const {
|
||||||
|
return Util::difftv(getCurrentTime(), tv)/1000;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - a simple utility for downloading files faster
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
#ifndef _D_TIME_H_
|
||||||
|
#define _D_TIME_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
class Time {
|
||||||
|
private:
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
struct timeval getCurrentTime() const;
|
||||||
|
public:
|
||||||
|
// The time value is initialized so that it represents the time at which
|
||||||
|
// this object was created.
|
||||||
|
Time();
|
||||||
|
Time(const Time& time);
|
||||||
|
Time& operator=(const Time& time);
|
||||||
|
|
||||||
|
~Time();
|
||||||
|
|
||||||
|
// Makes this object's time value up to date.
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
bool elapsed(int sec) const;
|
||||||
|
|
||||||
|
bool elapsedInMillis(int millis) const;
|
||||||
|
|
||||||
|
int difference() const;
|
||||||
|
long long int differenceInMillis() const;
|
||||||
|
|
||||||
|
// Returns true if this object's time value is zero.
|
||||||
|
bool isZero() const { return tv.tv_sec == 0 && tv.tv_usec == 0; }
|
||||||
|
|
||||||
|
long long int getTimeInMicros() const {
|
||||||
|
return tv.tv_sec*1000*1000+tv.tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long int getTimeInMillis() const {
|
||||||
|
return tv.tv_sec*1000+tv.tv_usec/1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns this object's time value in seconds.
|
||||||
|
int getTime() const {
|
||||||
|
return tv.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNewer(const Time& time) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _D_TIME_H_
|
|
@ -22,21 +22,13 @@
|
||||||
#include "TorrentAutoSaveCommand.h"
|
#include "TorrentAutoSaveCommand.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {
|
TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {}
|
||||||
checkPoint.tv_sec = 0;
|
|
||||||
checkPoint.tv_usec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TorrentAutoSaveCommand::~TorrentAutoSaveCommand() {}
|
TorrentAutoSaveCommand::~TorrentAutoSaveCommand() {}
|
||||||
|
|
||||||
bool TorrentAutoSaveCommand::execute() {
|
bool TorrentAutoSaveCommand::execute() {
|
||||||
if(e->torrentMan->downloadComplete() || e->torrentMan->isHalt()) {
|
if(checkPoint.elapsed(interval) || e->torrentMan->isHalt()) {
|
||||||
return true;
|
checkPoint.reset();
|
||||||
}
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if(Util::difftvsec(now, checkPoint) >= interval) {
|
|
||||||
checkPoint = now;
|
|
||||||
e->torrentMan->save();
|
e->torrentMan->save();
|
||||||
if(e->torrentMan->isHalt()) {
|
if(e->torrentMan->isHalt()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -24,12 +24,13 @@
|
||||||
|
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "TorrentDownloadEngine.h"
|
#include "TorrentDownloadEngine.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
class TorrentAutoSaveCommand : public Command {
|
class TorrentAutoSaveCommand : public Command {
|
||||||
private:
|
private:
|
||||||
TorrentDownloadEngine* e;
|
TorrentDownloadEngine* e;
|
||||||
int interval;
|
int interval;
|
||||||
struct timeval checkPoint;
|
Time checkPoint;
|
||||||
public:
|
public:
|
||||||
TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
||||||
~TorrentAutoSaveCommand();
|
~TorrentAutoSaveCommand();
|
||||||
|
|
|
@ -57,9 +57,9 @@ void TorrentDownloadEngine::initStatistics() {
|
||||||
downloadSpeed = 0;
|
downloadSpeed = 0;
|
||||||
uploadSpeed = 0;
|
uploadSpeed = 0;
|
||||||
lastElapsed = 0;
|
lastElapsed = 0;
|
||||||
gettimeofday(&cp[0], NULL);
|
cp[0].reset();
|
||||||
gettimeofday(&cp[1], NULL);
|
cp[1].reset();
|
||||||
gettimeofday(&startup, NULL);
|
startup.reset();
|
||||||
sessionDownloadLengthArray[0] = 0;
|
sessionDownloadLengthArray[0] = 0;
|
||||||
sessionDownloadLengthArray[1] = 0;
|
sessionDownloadLengthArray[1] = 0;
|
||||||
sessionUploadLengthArray[0] = 0;
|
sessionUploadLengthArray[0] = 0;
|
||||||
|
@ -82,9 +82,7 @@ int TorrentDownloadEngine::calculateSpeed(long long int sessionLength, int elaps
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentDownloadEngine::calculateStatistics() {
|
void TorrentDownloadEngine::calculateStatistics() {
|
||||||
struct timeval now;
|
int elapsed = cp[currentCp].difference();
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
int elapsed = Util::difftvsec(now, cp[currentCp]);
|
|
||||||
|
|
||||||
sessionDownloadLengthArray[0] += torrentMan->getDeltaDownloadLength();
|
sessionDownloadLengthArray[0] += torrentMan->getDeltaDownloadLength();
|
||||||
sessionUploadLengthArray[0] += torrentMan->getDeltaUploadLength();
|
sessionUploadLengthArray[0] += torrentMan->getDeltaUploadLength();
|
||||||
|
@ -111,8 +109,11 @@ void TorrentDownloadEngine::calculateStatistics() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(elapsed-lastElapsed >= 1) {
|
if(elapsed-lastElapsed >= 1) {
|
||||||
avgSpeed = calculateSpeed(sessionDownloadLength,
|
int elapsedFromStartup = startup.difference();
|
||||||
Util::difftvsec(now, startup));
|
if(elapsedFromStartup > 0) {
|
||||||
|
avgSpeed = calculateSpeed(sessionDownloadLength,
|
||||||
|
elapsedFromStartup);
|
||||||
|
}
|
||||||
if(avgSpeed < 0) {
|
if(avgSpeed < 0) {
|
||||||
avgSpeed = 0;
|
avgSpeed = 0;
|
||||||
} else if(avgSpeed != 0) {
|
} else if(avgSpeed != 0) {
|
||||||
|
@ -126,7 +127,7 @@ void TorrentDownloadEngine::calculateStatistics() {
|
||||||
if(elapsed > 15) {
|
if(elapsed > 15) {
|
||||||
sessionDownloadLengthArray[currentCp] = 0;
|
sessionDownloadLengthArray[currentCp] = 0;
|
||||||
sessionUploadLengthArray[currentCp] = 0;
|
sessionUploadLengthArray[currentCp] = 0;
|
||||||
cp[currentCp] = now;
|
cp[currentCp].reset();
|
||||||
lastElapsed = 0;
|
lastElapsed = 0;
|
||||||
currentCp = currentCp ? 0 : 1;
|
currentCp = currentCp ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "TorrentMan.h"
|
#include "TorrentMan.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
class TorrentDownloadEngine : public DownloadEngine {
|
class TorrentDownloadEngine : public DownloadEngine {
|
||||||
private:
|
private:
|
||||||
|
@ -32,7 +33,7 @@ private:
|
||||||
void initStatistics();
|
void initStatistics();
|
||||||
void calculateStatistics();
|
void calculateStatistics();
|
||||||
protected:
|
protected:
|
||||||
struct timeval cp[2];
|
Time cp[2];
|
||||||
long long int sessionDownloadLengthArray[2];
|
long long int sessionDownloadLengthArray[2];
|
||||||
long long int sessionUploadLengthArray[2];
|
long long int sessionUploadLengthArray[2];
|
||||||
int currentCp;
|
int currentCp;
|
||||||
|
@ -43,7 +44,7 @@ protected:
|
||||||
long long int selectedDownloadLengthDiff;
|
long long int selectedDownloadLengthDiff;
|
||||||
long long int selectedTotalLength;
|
long long int selectedTotalLength;
|
||||||
// The time when startup
|
// The time when startup
|
||||||
struct timeval startup;
|
Time startup;
|
||||||
// The number of bytes downloaded since startup
|
// The number of bytes downloaded since startup
|
||||||
long long int sessionDownloadLength;
|
long long int sessionDownloadLength;
|
||||||
// The average speed(bytes per second) since startup
|
// The average speed(bytes per second) since startup
|
||||||
|
|
|
@ -130,9 +130,6 @@ void TorrentMan::deleteOldErrorPeers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Peer* TorrentMan::getPeer() const {
|
Peer* TorrentMan::getPeer() const {
|
||||||
if(connections > MAX_PEER_UPDATE) {
|
|
||||||
return Peer::nullPeer;
|
|
||||||
}
|
|
||||||
for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
||||||
Peer* p = *itr;
|
Peer* p = *itr;
|
||||||
if(p->cuid == 0 && p->error < MAX_PEER_ERROR) {
|
if(p->cuid == 0 && p->error < MAX_PEER_ERROR) {
|
||||||
|
@ -401,8 +398,8 @@ void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, co
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentMan::setupInternal1(const string& metaInfoFile) {
|
void TorrentMan::setupInternal1(const string& metaInfoFile) {
|
||||||
peerId = "-A2****-";
|
peerId = "-aria2-";
|
||||||
for(int i = 0; i < 12; i++) {
|
for(int i = 0; i < 20-(int)peerId.size(); i++) {
|
||||||
peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
|
peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,3 +649,21 @@ void TorrentMan::onDownloadComplete() {
|
||||||
finishSelectiveDownloadingMode();
|
finishSelectiveDownloadingMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentMan::advertisePiece(int cuid, int index) {
|
||||||
|
HaveEntry entry(cuid, index);
|
||||||
|
haves.push_back(entry);
|
||||||
|
};
|
||||||
|
|
||||||
|
PieceIndexes TorrentMan::getAdvertisedPieceIndexes(int myCuid,
|
||||||
|
Time lastCheckTime) const {
|
||||||
|
PieceIndexes indexes;
|
||||||
|
for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
|
||||||
|
const Haves::value_type& have = *itr;
|
||||||
|
if(have.cuid == myCuid || lastCheckTime.isNewer(have.registeredTime)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
indexes.push_back(have.index);
|
||||||
|
}
|
||||||
|
return indexes;
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "FileEntry.h"
|
#include "FileEntry.h"
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
|
#include "Time.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -42,16 +43,26 @@ using namespace std;
|
||||||
|
|
||||||
#define INFO_HASH_LENGTH 20
|
#define INFO_HASH_LENGTH 20
|
||||||
#define PEER_ID_LENGTH 20
|
#define PEER_ID_LENGTH 20
|
||||||
#define DEFAULT_ANNOUNCE_INTERVAL 300
|
#define DEFAULT_ANNOUNCE_INTERVAL 1800
|
||||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 300
|
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 1800
|
||||||
#define MAX_PEERS 55
|
#define MAX_PEERS 55
|
||||||
#define MAX_PEER_UPDATE 15
|
#define MAX_PEER_UPDATE 15
|
||||||
#define MAX_PEER_LIST_SIZE 250
|
#define MAX_PEER_LIST_SIZE 250
|
||||||
#define END_GAME_PIECE_NUM 20
|
#define END_GAME_PIECE_NUM 20
|
||||||
#define MAX_PEER_ERROR 5
|
#define MAX_PEER_ERROR 5
|
||||||
|
|
||||||
|
class HaveEntry {
|
||||||
|
public:
|
||||||
|
int cuid;
|
||||||
|
int index;
|
||||||
|
Time registeredTime;
|
||||||
|
HaveEntry(int cuid, int index):
|
||||||
|
cuid(cuid),
|
||||||
|
index(index) {}
|
||||||
|
};
|
||||||
|
|
||||||
typedef deque<Peer*> Peers;
|
typedef deque<Peer*> Peers;
|
||||||
typedef multimap<int, int> Haves;
|
typedef deque<HaveEntry> Haves;
|
||||||
typedef deque<int> PieceIndexes;
|
typedef deque<int> PieceIndexes;
|
||||||
typedef deque<Piece> Pieces;
|
typedef deque<Piece> Pieces;
|
||||||
|
|
||||||
|
@ -164,26 +175,9 @@ public:
|
||||||
|
|
||||||
string getPieceHash(int index) const;
|
string getPieceHash(int index) const;
|
||||||
|
|
||||||
void advertisePiece(int cuid, int index) {
|
void advertisePiece(int cuid, int index);
|
||||||
Haves::value_type vt(cuid, index);
|
|
||||||
haves.insert(vt);
|
|
||||||
}
|
|
||||||
|
|
||||||
PieceIndexes getAdvertisedPieceIndexes(int myCuid) const {
|
PieceIndexes getAdvertisedPieceIndexes(int myCuid, Time lastCheckTime) const;
|
||||||
PieceIndexes indexes;
|
|
||||||
for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
|
|
||||||
const Haves::value_type& have = *itr;
|
|
||||||
if(have.first == myCuid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
indexes.push_back(have.second);
|
|
||||||
}
|
|
||||||
return indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unadvertisePiece(int cuid) {
|
|
||||||
haves.erase(cuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
long long int getTotalLength() const { return totalLength; }
|
long long int getTotalLength() const { return totalLength; }
|
||||||
void setTotalLength(long long int length) { totalLength = length; }
|
void setTotalLength(long long int length) { totalLength = length; }
|
||||||
|
|
|
@ -26,19 +26,21 @@
|
||||||
TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
|
TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
|
||||||
TorrentDownloadEngine* e,
|
TorrentDownloadEngine* e,
|
||||||
int interval):
|
int interval):
|
||||||
Command(cuid), e(e), interval(interval) {
|
Command(cuid), e(e), interval(interval) {}
|
||||||
checkPoint.tv_sec = 0;
|
|
||||||
checkPoint.tv_usec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
||||||
|
|
||||||
bool TrackerWatcherCommand::execute() {
|
bool TrackerWatcherCommand::execute() {
|
||||||
struct timeval now;
|
if(e->segmentMan->errors > 0) {
|
||||||
gettimeofday(&now, NULL);
|
// we assume the tracker request has failed.
|
||||||
|
e->torrentMan->trackers = 0;
|
||||||
|
e->segmentMan->init();
|
||||||
|
}
|
||||||
if(e->torrentMan->trackers == 0 &&
|
if(e->torrentMan->trackers == 0 &&
|
||||||
(Util::difftvsec(now, checkPoint) >= interval || e->torrentMan->isHalt())) {
|
(e->torrentMan->connections < MAX_PEER_UPDATE ||
|
||||||
checkPoint = now;
|
e->torrentMan->isHalt() ||
|
||||||
|
checkPoint.elapsed(interval))) {
|
||||||
|
checkPoint.reset();
|
||||||
e->torrentMan->req->resetTryCount();
|
e->torrentMan->req->resetTryCount();
|
||||||
int numWant = 50;
|
int numWant = 50;
|
||||||
if(e->torrentMan->connections >= MIN_PEERS || e->torrentMan->isHalt()) {
|
if(e->torrentMan->connections >= MIN_PEERS || e->torrentMan->isHalt()) {
|
||||||
|
@ -90,7 +92,7 @@ bool TrackerWatcherCommand::execute() {
|
||||||
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e);
|
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e);
|
||||||
e->commands.push_back(command);
|
e->commands.push_back(command);
|
||||||
e->torrentMan->trackers++;
|
e->torrentMan->trackers++;
|
||||||
logger->info("CUID#%d - creating new tracker request command #%d", cuid,
|
logger->info("CUID#%d - Creating new tracker request command #%d", cuid,
|
||||||
command->getCuid());
|
command->getCuid());
|
||||||
if(e->torrentMan->isHalt()) {
|
if(e->torrentMan->isHalt()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "TorrentDownloadEngine.h"
|
#include "TorrentDownloadEngine.h"
|
||||||
#include <sys/time.h>
|
#include "Time.h"
|
||||||
|
|
||||||
#define MIN_PEERS 15
|
#define MIN_PEERS 15
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class TrackerWatcherCommand : public Command {
|
||||||
private:
|
private:
|
||||||
TorrentDownloadEngine* e;
|
TorrentDownloadEngine* e;
|
||||||
int interval;
|
int interval;
|
||||||
struct timeval checkPoint;
|
Time checkPoint;
|
||||||
public:
|
public:
|
||||||
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
||||||
~TrackerWatcherCommand();
|
~TrackerWatcherCommand();
|
||||||
|
|
|
@ -647,8 +647,8 @@ int main(int argc, char* argv[]) {
|
||||||
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
|
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
|
||||||
try {
|
try {
|
||||||
//op->put(PREF_MAX_TRIES, "0");
|
//op->put(PREF_MAX_TRIES, "0");
|
||||||
setSignalHander(SIGINT, torrentHandler, SA_ONESHOT);
|
setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
|
||||||
setSignalHander(SIGTERM, torrentHandler, SA_ONESHOT);
|
setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND);
|
||||||
|
|
||||||
Request* req = new Request();
|
Request* req = new Request();
|
||||||
req->isTorrent = true;
|
req->isTorrent = true;
|
||||||
|
|
Loading…
Reference in New Issue