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>
|
||||
|
||||
To fix the bug that causes segfaults if a tracker returns a zero-length
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# 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>.
|
||||
#
|
||||
|
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='aria2c'
|
||||
PACKAGE_TARNAME='aria2c'
|
||||
PACKAGE_VERSION='0.5.0'
|
||||
PACKAGE_STRING='aria2c 0.5.0'
|
||||
PACKAGE_VERSION='0.5.1'
|
||||
PACKAGE_STRING='aria2c 0.5.1'
|
||||
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
|
||||
|
||||
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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
|
@ -854,7 +854,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of aria2c 0.5.0:";;
|
||||
short | recursive ) echo "Configuration of aria2c 0.5.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -994,7 +994,7 @@ fi
|
|||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
aria2c configure 0.5.0
|
||||
aria2c configure 0.5.1
|
||||
generated by GNU Autoconf 2.59
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
@ -1008,7 +1008,7 @@ cat >&5 <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
|
@ -1651,7 +1651,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='aria2c'
|
||||
VERSION='0.5.0'
|
||||
VERSION='0.5.1'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -11528,7 +11528,7 @@ _ASBOX
|
|||
} >&5
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -11591,7 +11591,7 @@ _ACEOF
|
|||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
aria2c config.status 0.5.0
|
||||
aria2c config.status 0.5.1
|
||||
configured by $0, generated by GNU Autoconf 2.59,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
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_PATH_CPPUNIT(1.10.2)
|
||||
AC_CONFIG_SRCDIR([src/Socket.h])
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# General Public License and is *not* in the public domain.
|
||||
|
||||
PACKAGE = aria2c
|
||||
VERSION = 0.5.0
|
||||
VERSION = 0.5.1
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "message.h"
|
||||
#include "SleepCommand.h"
|
||||
#include "prefs.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, const Socket* s):
|
||||
Command(cuid), req(req), e(e), checkSocketIsReadable(false), checkSocketIsWritable(false) {
|
||||
|
@ -38,8 +37,7 @@ AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, cons
|
|||
} else {
|
||||
socket = NULL;
|
||||
}
|
||||
this->checkPoint.tv_sec = 0;
|
||||
this->checkPoint.tv_usec = 0;
|
||||
timeout = this->e->option->getAsInt(PREF_TIMEOUT);
|
||||
}
|
||||
|
||||
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() {
|
||||
try {
|
||||
if(checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||
checkSocketIsWritable && writeCheckTarget->isWritable(0) ||
|
||||
!checkSocketIsReadable && !checkSocketIsWritable) {
|
||||
|
||||
updateCheckPoint();
|
||||
checkPoint.reset();
|
||||
Segment seg = { 0, 0, 0, false };
|
||||
if(e->segmentMan->downloadStarted) {
|
||||
// get segment information in order to set Range header.
|
||||
|
@ -88,7 +65,7 @@ bool AbstractCommand::execute() {
|
|||
}
|
||||
return executeInternal(seg);
|
||||
} else {
|
||||
if(isTimeoutDetected()) {
|
||||
if(checkPoint.elapsed(timeout)) {
|
||||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
e->commands.push_back(this);
|
||||
|
@ -99,6 +76,7 @@ bool AbstractCommand::execute() {
|
|||
onAbort(err);
|
||||
delete(err);
|
||||
req->resetUrl();
|
||||
e->segmentMan->errors++;
|
||||
return true;
|
||||
} catch(DlRetryEx* err) {
|
||||
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
||||
|
@ -111,6 +89,7 @@ bool AbstractCommand::execute() {
|
|||
delete(err);
|
||||
if(isAbort) {
|
||||
logger->error(MSG_MAX_TRY, cuid, req->getTryCount());
|
||||
e->segmentMan->errors++;
|
||||
return true;
|
||||
} else {
|
||||
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
||||
|
|
|
@ -26,13 +26,12 @@
|
|||
#include "Request.h"
|
||||
#include "DownloadEngine.h"
|
||||
#include "SegmentMan.h"
|
||||
#include <sys/time.h>
|
||||
#include "Time.h"
|
||||
|
||||
class AbstractCommand : public Command {
|
||||
private:
|
||||
void updateCheckPoint();
|
||||
bool isTimeoutDetected();
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
int timeout;
|
||||
protected:
|
||||
Request* req;
|
||||
DownloadEngine* e;
|
||||
|
@ -44,6 +43,7 @@ protected:
|
|||
|
||||
void setReadCheckSocket(Socket* socket);
|
||||
void setWriteCheckSocket(Socket* socket);
|
||||
void setTimeout(int timeout) { this->timeout = timeout; }
|
||||
private:
|
||||
bool checkSocketIsReadable;
|
||||
bool checkSocketIsWritable;
|
||||
|
|
|
@ -40,14 +40,14 @@ void ConsoleDownloadEngine::sendStatistics(long long int currentSize, long long
|
|||
}
|
||||
|
||||
void ConsoleDownloadEngine::initStatistics() {
|
||||
cp.tv_sec = cp.tv_usec = 0;
|
||||
cp.reset();
|
||||
startup.reset();
|
||||
speed = 0;
|
||||
psize = 0;
|
||||
avgSpeed = 0;
|
||||
eta = 0;
|
||||
startupLength = 0;
|
||||
isStartupLengthSet = false;
|
||||
gettimeofday(&startup, NULL);
|
||||
}
|
||||
|
||||
void ConsoleDownloadEngine::calculateStatistics() {
|
||||
|
@ -56,28 +56,24 @@ void ConsoleDownloadEngine::calculateStatistics() {
|
|||
startupLength = dlSize;
|
||||
isStartupLengthSet = true;
|
||||
}
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(cp.tv_sec == 0 && cp.tv_usec == 0) {
|
||||
cp = now;
|
||||
int elapsed = cp.difference();
|
||||
if(elapsed >= 1) {
|
||||
int nspeed = (int)((dlSize-psize)/elapsed);
|
||||
speed = (nspeed+speed)/2;
|
||||
cp.reset();
|
||||
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));
|
||||
if(avgSpeed < 0) {
|
||||
avgSpeed = 0;
|
||||
} else if(avgSpeed != 0 && segmentMan->totalSize > 0) {
|
||||
eta = (segmentMan->totalSize-dlSize)/avgSpeed;
|
||||
}
|
||||
|
||||
sendStatistics(dlSize, segmentMan->totalSize);
|
||||
int elapsedFromStartup = startup.difference();
|
||||
if(elapsedFromStartup > 0) {
|
||||
avgSpeed = (int)((dlSize-startupLength)/elapsedFromStartup);
|
||||
}
|
||||
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_
|
||||
|
||||
#include "DownloadEngine.h"
|
||||
#include "Time.h"
|
||||
|
||||
class ConsoleDownloadEngine : public DownloadEngine {
|
||||
private:
|
||||
struct timeval cp;
|
||||
Time cp;
|
||||
long long int psize;
|
||||
int speed;
|
||||
// The time when startup
|
||||
struct timeval startup;
|
||||
Time startup;
|
||||
// The number of bytes downloaded at startup
|
||||
long long int startupLength;
|
||||
bool isStartupLengthSet;
|
||||
|
|
|
@ -27,10 +27,7 @@
|
|||
#include "InitiateConnectionCommandFactory.h"
|
||||
#include "message.h"
|
||||
|
||||
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(int cuid, Request* req, DownloadEngine* e, const Socket* s):AbstractCommand(cuid, req, e, s), lastSize(0) {}
|
||||
|
||||
DownloadCommand::~DownloadCommand() {}
|
||||
|
||||
|
@ -54,18 +51,11 @@ bool DownloadCommand::executeInternal(Segment seg) {
|
|||
seg.ds += bufSize;
|
||||
}
|
||||
// calculate downloading speed
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(sw.tv_sec == 0 && sw.tv_usec == 0) {
|
||||
sw = now;
|
||||
int diff = sw.difference();
|
||||
if(diff >= 1) {
|
||||
seg.speed = (int)((seg.ds-lastSize)/(diff*1.0));
|
||||
sw.reset();
|
||||
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) {
|
||||
throw new DlRetryEx(EX_GOT_EOF);
|
||||
|
|
|
@ -24,14 +24,13 @@
|
|||
|
||||
#include "AbstractCommand.h"
|
||||
#include "TransferEncoding.h"
|
||||
#include <sys/time.h>
|
||||
#include <string>
|
||||
#include "Time.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class DownloadCommand : public AbstractCommand {
|
||||
private:
|
||||
struct timeval sw;
|
||||
Time sw;
|
||||
long long int lastSize;
|
||||
protected:
|
||||
bool executeInternal(Segment segment);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "DownloadEngine.h"
|
||||
#include "Util.h"
|
||||
#include "LogFactory.h"
|
||||
#include "Time.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -48,15 +49,11 @@ void DownloadEngine::cleanQueue() {
|
|||
|
||||
void DownloadEngine::run() {
|
||||
initStatistics();
|
||||
struct timeval cp;
|
||||
cp.tv_sec = 0;
|
||||
cp.tv_usec = 0;
|
||||
Time cp;
|
||||
Sockets activeSockets;
|
||||
while(!commands.empty()) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftvsec(now, cp) >= 1) {
|
||||
cp = now;
|
||||
if(cp.elapsed(1)) {
|
||||
cp.reset();
|
||||
int max = commands.size();
|
||||
for(int i = 0; i < max; i++) {
|
||||
Command* com = commands.front();
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include "common.h"
|
||||
#include "Logger.h"
|
||||
#include "Option.h"
|
||||
#include <sys/time.h>
|
||||
#include <deque>
|
||||
|
||||
typedef deque<Socket*> Sockets;
|
||||
typedef deque<Command*> Commands;
|
||||
|
|
|
@ -101,7 +101,8 @@ SRCS = Socket.cc Socket.h\
|
|||
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||
SimplePeerMessage.cc SimplePeerMessage.h\
|
||||
NullLogger.h
|
||||
NullLogger.h\
|
||||
Time.cc Time.h
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||
|
|
|
@ -109,7 +109,7 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
|
|||
PortMessage.$(OBJEXT) HaveAllMessage.$(OBJEXT) \
|
||||
HaveNoneMessage.$(OBJEXT) RejectMessage.$(OBJEXT) \
|
||||
AllowedFastMessage.$(OBJEXT) SuggestPieceMessage.$(OBJEXT) \
|
||||
SimplePeerMessage.$(OBJEXT)
|
||||
SimplePeerMessage.$(OBJEXT) Time.$(OBJEXT)
|
||||
am_libaria2c_a_OBJECTS = $(am__objects_1)
|
||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
|
@ -360,7 +360,8 @@ SRCS = Socket.cc Socket.h\
|
|||
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||
SimplePeerMessage.cc SimplePeerMessage.h\
|
||||
NullLogger.h
|
||||
NullLogger.h\
|
||||
Time.cc Time.h
|
||||
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
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)/SplitSlowestSegmentSplitter.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)/TorrentConsoleDownloadEngine.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
|
||||
|
|
|
@ -59,6 +59,7 @@ void Peer::resetStatus() {
|
|||
resetDeltaDownload();
|
||||
chokingRequired = true;
|
||||
optUnchoking = false;
|
||||
snubbing = false;
|
||||
fastExtensionEnabled = false;
|
||||
latency = DEFAULT_LATENCY;
|
||||
fastSet.clear();
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
int cuid;
|
||||
bool chokingRequired;
|
||||
bool optUnchoking;
|
||||
bool snubbing;
|
||||
private:
|
||||
char peerId[PEER_ID_LENGTH];
|
||||
BitfieldMan* bitfield;
|
||||
|
@ -65,6 +66,7 @@ public:
|
|||
peerChoking(true), peerInterested(false),
|
||||
tryCount(0), error(0), cuid(0),
|
||||
chokingRequired(true), optUnchoking(false),
|
||||
snubbing(false),
|
||||
bitfield(NULL),
|
||||
fastExtensionEnabled(false),
|
||||
peerUpload(0), peerDownload(0),
|
||||
|
@ -107,8 +109,8 @@ public:
|
|||
void setAllBitfield();
|
||||
|
||||
/**
|
||||
* operation = 1: set index-th bit 1
|
||||
* operation = 0: set index-th bit 0
|
||||
* operation = 1: set index-th bit to 1
|
||||
* operation = 0: set index-th bit to 0
|
||||
*/
|
||||
void updateBitfield(int index, int operation);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "Util.h"
|
||||
#include "message.h"
|
||||
#include "prefs.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, const Socket* s):
|
||||
Command(cuid), e(e), peer(peer),
|
||||
|
@ -38,8 +37,6 @@ PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEn
|
|||
} else {
|
||||
socket = NULL;
|
||||
}
|
||||
this->checkPoint.tv_sec = 0;
|
||||
this->checkPoint.tv_usec = 0;
|
||||
timeout = e->option->getAsInt(PREF_TIMEOUT);
|
||||
e->torrentMan->connections++;
|
||||
}
|
||||
|
@ -53,26 +50,6 @@ PeerAbstractCommand::~PeerAbstractCommand() {
|
|||
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() {
|
||||
if(e->torrentMan->isHalt()) {
|
||||
return true;
|
||||
|
@ -82,12 +59,9 @@ bool PeerAbstractCommand::execute() {
|
|||
e->getUploadSpeed() <= uploadLimit*1024) ||
|
||||
checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||
checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
|
||||
updateCheckPoint();
|
||||
checkPoint.reset();
|
||||
}
|
||||
if(isTimeoutDetected()) {
|
||||
// TODO following 2 lines will be deleted.
|
||||
checkPoint.tv_sec = 0;
|
||||
checkPoint.tv_usec = 0;
|
||||
if(checkPoint.elapsed(timeout)) {
|
||||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
return executeInternal();
|
||||
|
|
|
@ -25,13 +25,11 @@
|
|||
#include "Command.h"
|
||||
#include "Request.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include <sys/time.h>
|
||||
#include "Time.h"
|
||||
|
||||
class PeerAbstractCommand : public Command {
|
||||
private:
|
||||
void updateCheckPoint();
|
||||
bool isTimeoutDetected();
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
int timeout;
|
||||
protected:
|
||||
TorrentDownloadEngine* e;
|
||||
|
|
|
@ -22,10 +22,7 @@
|
|||
#include "PeerChokeCommand.h"
|
||||
#include "Util.h"
|
||||
|
||||
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(int cuid, int interval, TorrentDownloadEngine* e):Command(cuid), interval(interval), e(e), rotate(0) {}
|
||||
|
||||
PeerChokeCommand::~PeerChokeCommand() {}
|
||||
|
||||
|
@ -41,23 +38,16 @@ void PeerChokeCommand::optUnchokingPeer(Peers& peers) const {
|
|||
return;
|
||||
}
|
||||
random_shuffle(peers.begin(), peers.end());
|
||||
int optUnchokCount = 1;
|
||||
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
||||
(*itr)->optUnchoking = false;
|
||||
}
|
||||
Peer* peer = peers.front();
|
||||
peer->optUnchoking = true;
|
||||
logger->debug("opt, unchoking %s, delta=%d",
|
||||
peer->ipaddr.c_str(), peer->getDeltaUpload());
|
||||
if(e->torrentMan->isEndGame()) {
|
||||
Peers::iterator itr = peers.begin()+1;
|
||||
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;
|
||||
}
|
||||
Peers::value_type peer = *itr;
|
||||
if(optUnchokCount > 0 && !peer->snubbing) {
|
||||
optUnchokCount--;
|
||||
peer->optUnchoking = true;
|
||||
logger->debug("opt, unchoking %s, delta=%d",
|
||||
peer->ipaddr.c_str(), peer->getDeltaUpload());
|
||||
} else {
|
||||
peer->optUnchoking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,10 +86,8 @@ bool PeerChokeCommand::execute() {
|
|||
if(e->torrentMan->isHalt()) {
|
||||
return true;
|
||||
}
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftvsec(now, checkPoint) >= interval) {
|
||||
checkPoint = now;
|
||||
if(checkPoint.elapsed(interval)) {
|
||||
checkPoint.reset();
|
||||
Peers peers = e->torrentMan->getActivePeers();
|
||||
setAllPeerChoked(peers);
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
|
@ -107,14 +95,14 @@ bool PeerChokeCommand::execute() {
|
|||
} else {
|
||||
orderByUploadRate(peers);
|
||||
}
|
||||
int unchokingCount = peers.size() >= 4 ? 4 : peers.size();
|
||||
for(Peers::iterator itr = peers.begin(); unchokingCount > 0 && itr != peers.end(); ) {
|
||||
int unchokingCount = 4;//peers.size() >= 4 ? 4 : peers.size();
|
||||
for(Peers::iterator itr = peers.begin(); itr != peers.end() && unchokingCount > 0; ) {
|
||||
Peer* peer = *itr;
|
||||
if(peer->peerInterested) {
|
||||
if(peer->peerInterested && !peer->snubbing) {
|
||||
unchokingCount--;
|
||||
peer->chokingRequired = false;
|
||||
peer->optUnchoking = false;
|
||||
itr = peers.erase(itr);
|
||||
unchokingCount--;
|
||||
logger->debug("cat01, unchoking %s, delta=%d", peer->ipaddr.c_str(), peer->getDeltaUpload());
|
||||
} else {
|
||||
itr++;
|
||||
|
@ -122,7 +110,7 @@ bool PeerChokeCommand::execute() {
|
|||
}
|
||||
for(Peers::iterator itr = peers.begin(); itr != peers.end(); ) {
|
||||
Peer* peer = *itr;
|
||||
if(!peer->peerInterested) {
|
||||
if(!peer->peerInterested && !peer->snubbing) {
|
||||
peer->chokingRequired = false;
|
||||
peer->optUnchoking = false;
|
||||
itr = peers.erase(itr);
|
||||
|
|
|
@ -24,13 +24,14 @@
|
|||
|
||||
#include "Command.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include "Time.h"
|
||||
|
||||
class PeerChokeCommand : public Command {
|
||||
private:
|
||||
int interval;
|
||||
TorrentDownloadEngine* e;
|
||||
int rotate;
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
|
||||
void orderByUploadRate(Peers& peers) const;
|
||||
void orderByDownloadRate(Peers& peers) const;
|
||||
|
|
|
@ -231,6 +231,7 @@ void PeerInteraction::checkRequestSlot() {
|
|||
Piece& piece = getDownloadPiece(slot.getIndex());
|
||||
piece.cancelBlock(slot.getBlockIndex());
|
||||
itr = requestSlots.erase(itr);
|
||||
peer->snubbing = true;
|
||||
} else {
|
||||
Piece piece = getDownloadPiece(slot.getIndex());
|
||||
if(piece.hasBlock(slot.getBlockIndex()) ||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "SuggestPieceMessage.h"
|
||||
#include "RequestSlot.h"
|
||||
|
||||
#define REQUEST_TIME_OUT 120
|
||||
#define REQUEST_TIME_OUT 60
|
||||
#define ALLOWED_FAST_SET_SIZE 10
|
||||
|
||||
typedef deque<RequestSlot> RequestSlots;
|
||||
|
|
|
@ -41,12 +41,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
|||
e->torrentMan, this->peer);
|
||||
peerInteraction->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;
|
||||
haveCount = 0;
|
||||
keepAliveCount = 0;
|
||||
|
@ -55,7 +49,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
|||
|
||||
PeerInteractionCommand::~PeerInteractionCommand() {
|
||||
delete peerInteraction;
|
||||
e->torrentMan->unadvertisePiece(cuid);
|
||||
e->torrentMan->deleteActivePeer(this->peer);
|
||||
}
|
||||
|
||||
|
@ -89,6 +82,7 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
peer->ipaddr.c_str(), peer->port,
|
||||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
haveCheckTime.reset();
|
||||
peerInteraction->sendBitfield();
|
||||
peerInteraction->sendAllowedFast();
|
||||
sequence = WIRED;
|
||||
|
@ -105,6 +99,7 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
peerInteraction->sendHandshake();
|
||||
haveCheckTime.reset();
|
||||
peerInteraction->sendBitfield();
|
||||
peerInteraction->sendAllowedFast();
|
||||
sequence = WIRED;
|
||||
|
@ -134,24 +129,19 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
return false;
|
||||
}
|
||||
|
||||
#define FLOODING_CHECK_INTERVAL 5
|
||||
|
||||
void PeerInteractionCommand::detectMessageFlooding() {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(freqCheckPoint.tv_sec == 0 && freqCheckPoint.tv_usec == 0) {
|
||||
freqCheckPoint = now;
|
||||
} else {
|
||||
int elapsed = Util::difftvsec(now, freqCheckPoint);
|
||||
if(elapsed >= 5) {
|
||||
if(chokeUnchokeCount*1.0/elapsed >= 0.4
|
||||
//|| haveCount*1.0/elapsed >= 20.0
|
||||
|| keepAliveCount*1.0/elapsed >= 1.0) {
|
||||
throw new DlAbortEx("Flooding detected.");
|
||||
} else {
|
||||
chokeUnchokeCount = 0;
|
||||
haveCount = 0;
|
||||
keepAliveCount = 0;
|
||||
freqCheckPoint = now;
|
||||
}
|
||||
if(freqCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) {
|
||||
if(chokeUnchokeCount*1.0/FLOODING_CHECK_INTERVAL >= 0.4
|
||||
//|| haveCount*1.0/elapsed >= 20.0
|
||||
|| keepAliveCount*1.0/FLOODING_CHECK_INTERVAL >= 1.0) {
|
||||
throw new DlAbortEx("Flooding detected.");
|
||||
} else {
|
||||
chokeUnchokeCount = 0;
|
||||
haveCount = 0;
|
||||
keepAliveCount = 0;
|
||||
freqCheckPoint.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,21 +150,13 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
|
|||
if(e->torrentMan->downloadComplete()) {
|
||||
return;
|
||||
}
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(chokeCheckPoint.tv_sec == 0 && chokeCheckPoint.tv_usec == 0) {
|
||||
if(peer->amInterested && peer->peerChoking) {
|
||||
chokeCheckPoint = now;
|
||||
if(peer->amInterested && peer->peerChoking) {
|
||||
if(chokeCheckPoint.elapsed(MAX_PEER_CHOKING_INTERVAL)) {
|
||||
logger->info("CUID#%d - The peer is choking too long.", cuid);
|
||||
peer->snubbing = true;
|
||||
}
|
||||
} else {
|
||||
if(peer->amInterested && peer->peerChoking) {
|
||||
if(Util::difftvsec(now, chokeCheckPoint) >= MAX_PEER_CHOKING_INTERVAL) {
|
||||
throw new DlAbortEx("Too long choking.");
|
||||
}
|
||||
} else {
|
||||
chokeCheckPoint.tv_sec = 0;
|
||||
chokeCheckPoint.tv_usec = 0;
|
||||
}
|
||||
chokeCheckPoint.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,24 +233,19 @@ void PeerInteractionCommand::onAbort(Exception* ex) {
|
|||
}
|
||||
|
||||
void PeerInteractionCommand::sendKeepAlive() {
|
||||
if(keepAliveCheckPoint.tv_sec == 0 && keepAliveCheckPoint.tv_usec == 0) {
|
||||
gettimeofday(&keepAliveCheckPoint, NULL);
|
||||
} else {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftvsec(now, keepAliveCheckPoint) >= 120) {
|
||||
if(peerInteraction->countMessageInQueue() == 0) {
|
||||
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
|
||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||
}
|
||||
keepAliveCheckPoint = now;
|
||||
if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) {
|
||||
if(peerInteraction->countMessageInQueue() == 0) {
|
||||
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
|
||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||
}
|
||||
keepAliveCheckPoint.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::checkHave() {
|
||||
e->torrentMan->unadvertisePiece(cuid);
|
||||
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
|
||||
PieceIndexes indexes =
|
||||
e->torrentMan->getAdvertisedPieceIndexes(cuid, haveCheckTime);
|
||||
haveCheckTime.reset();
|
||||
if(indexes.size() >= 20) {
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
if(e->torrentMan->hasAllPieces()) {
|
||||
|
|
|
@ -25,19 +25,22 @@
|
|||
#include "PeerAbstractCommand.h"
|
||||
#include "PeerConnection.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "Time.h"
|
||||
|
||||
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 {
|
||||
private:
|
||||
int sequence;
|
||||
PeerInteraction* peerInteraction;
|
||||
|
||||
struct timeval keepAliveCheckPoint;
|
||||
struct timeval chokeCheckPoint;
|
||||
struct timeval freqCheckPoint;
|
||||
Time keepAliveCheckPoint;
|
||||
Time chokeCheckPoint;
|
||||
Time freqCheckPoint;
|
||||
Time haveCheckTime;
|
||||
int chokeUnchokeCount;
|
||||
int haveCount;
|
||||
int keepAliveCount;
|
||||
|
|
|
@ -59,6 +59,7 @@ void PieceMessage::receivedAction() {
|
|||
peer->addPeerUpload(blockLength);
|
||||
if(!RequestSlot::isNull(slot) &&
|
||||
peerInteraction->hasDownloadPiece(slot.getIndex())) {
|
||||
peer->snubbing = false;
|
||||
//logger->debug("CUID#%d - Latency=%d", cuid, slot.getLatencyInMillis());
|
||||
peer->updateLatency(slot.getLatencyInMillis());
|
||||
Piece& piece = peerInteraction->getDownloadPiece(slot.getIndex());
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#include "Util.h"
|
||||
|
||||
RequestSlot::RequestSlot(int index, int begin, int length, int blockIndex)
|
||||
:index(index), begin(begin), length(length), blockIndex(blockIndex) {
|
||||
setDispatchedTime();
|
||||
}
|
||||
:index(index), begin(begin), length(length), blockIndex(blockIndex) {}
|
||||
|
||||
RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
|
||||
copy(requestSlot);
|
||||
|
@ -49,17 +47,15 @@ void RequestSlot::copy(const RequestSlot& requestSlot) {
|
|||
RequestSlot RequestSlot::nullSlot(0, 0, 0, 0);
|
||||
|
||||
void RequestSlot::setDispatchedTime() {
|
||||
gettimeofday(&dispatchedTime, NULL);
|
||||
dispatchedTime.reset();
|
||||
}
|
||||
|
||||
bool RequestSlot::isTimeout(int timeoutSec) const {
|
||||
return getLatencyInMillis() > timeoutSec*1000;
|
||||
return dispatchedTime.differenceInMillis() > timeoutSec*1000;
|
||||
}
|
||||
|
||||
int RequestSlot::getLatencyInMillis() const {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
return Util::difftv(now, dispatchedTime)/1000;
|
||||
return dispatchedTime.differenceInMillis();
|
||||
}
|
||||
|
||||
bool RequestSlot::isNull(const RequestSlot& requestSlot) {
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
#define _D_REQUEST_SLOT_H_
|
||||
|
||||
#include "common.h"
|
||||
#include <sys/time.h>
|
||||
#include "Time.h"
|
||||
|
||||
class RequestSlot {
|
||||
private:
|
||||
struct timeval dispatchedTime;
|
||||
Time dispatchedTime;
|
||||
int index;
|
||||
int begin;
|
||||
int length;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
SegmentMan::SegmentMan():totalSize(0),
|
||||
isSplittable(true),
|
||||
downloadStarted(false),
|
||||
errors(0),
|
||||
dir("."),
|
||||
splitter(NULL),
|
||||
diskWriter(NULL) {
|
||||
|
@ -241,6 +242,7 @@ void SegmentMan::init() {
|
|||
totalSize = 0;
|
||||
isSplittable = false;
|
||||
downloadStarted = false;
|
||||
errors = 0;
|
||||
segments.clear();
|
||||
diskWriter->closeFile();
|
||||
}
|
||||
|
|
|
@ -84,6 +84,11 @@ public:
|
|||
*/
|
||||
string ufilename;
|
||||
|
||||
/**
|
||||
* Represents the number of failures(usually, DlAbortEx) in downloads.
|
||||
*/
|
||||
int errors;
|
||||
|
||||
const Option* option;
|
||||
SegmentSplitter* splitter;
|
||||
DiskWriter* diskWriter;
|
||||
|
@ -91,7 +96,7 @@ public:
|
|||
SegmentMan();
|
||||
~SegmentMan();
|
||||
|
||||
// Initializes totalSize, isSplittable, downloadStarted.
|
||||
// Initializes totalSize, isSplittable, downloadStarted, errors.
|
||||
// Clears command queue. Also, closes diskWriter.
|
||||
void init();
|
||||
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#include "Util.h"
|
||||
|
||||
SleepCommand::SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait):
|
||||
Command(cuid), engine(e), nextCommand(nextCommand), wait(wait) {
|
||||
gettimeofday(&checkPoint, NULL);
|
||||
}
|
||||
Command(cuid), engine(e), nextCommand(nextCommand), wait(wait) {}
|
||||
|
||||
SleepCommand::~SleepCommand() {
|
||||
if(nextCommand != NULL) {
|
||||
|
@ -34,9 +32,7 @@ SleepCommand::~SleepCommand() {
|
|||
}
|
||||
|
||||
bool SleepCommand::execute() {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftvsec(now, checkPoint) >= wait) {
|
||||
if(checkPoint.elapsed(wait)) {
|
||||
engine->commands.push_back(nextCommand);
|
||||
nextCommand = NULL;
|
||||
return true;
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
|
||||
#include "DownloadEngine.h"
|
||||
#include "Command.h"
|
||||
#include <sys/time.h>
|
||||
#include "Time.h"
|
||||
|
||||
class SleepCommand:public Command {
|
||||
private:
|
||||
DownloadEngine* engine;
|
||||
Command* nextCommand;
|
||||
int wait;
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
public:
|
||||
SleepCommand(int cuid, DownloadEngine* e, Command* nextCommand, int wait);
|
||||
~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 "Util.h"
|
||||
|
||||
TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {
|
||||
checkPoint.tv_sec = 0;
|
||||
checkPoint.tv_usec = 0;
|
||||
}
|
||||
TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {}
|
||||
|
||||
TorrentAutoSaveCommand::~TorrentAutoSaveCommand() {}
|
||||
|
||||
bool TorrentAutoSaveCommand::execute() {
|
||||
if(e->torrentMan->downloadComplete() || e->torrentMan->isHalt()) {
|
||||
return true;
|
||||
}
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftvsec(now, checkPoint) >= interval) {
|
||||
checkPoint = now;
|
||||
if(checkPoint.elapsed(interval) || e->torrentMan->isHalt()) {
|
||||
checkPoint.reset();
|
||||
e->torrentMan->save();
|
||||
if(e->torrentMan->isHalt()) {
|
||||
return true;
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
|
||||
#include "Command.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include "Time.h"
|
||||
|
||||
class TorrentAutoSaveCommand : public Command {
|
||||
private:
|
||||
TorrentDownloadEngine* e;
|
||||
int interval;
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
public:
|
||||
TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
||||
~TorrentAutoSaveCommand();
|
||||
|
|
|
@ -57,9 +57,9 @@ void TorrentDownloadEngine::initStatistics() {
|
|||
downloadSpeed = 0;
|
||||
uploadSpeed = 0;
|
||||
lastElapsed = 0;
|
||||
gettimeofday(&cp[0], NULL);
|
||||
gettimeofday(&cp[1], NULL);
|
||||
gettimeofday(&startup, NULL);
|
||||
cp[0].reset();
|
||||
cp[1].reset();
|
||||
startup.reset();
|
||||
sessionDownloadLengthArray[0] = 0;
|
||||
sessionDownloadLengthArray[1] = 0;
|
||||
sessionUploadLengthArray[0] = 0;
|
||||
|
@ -82,9 +82,7 @@ int TorrentDownloadEngine::calculateSpeed(long long int sessionLength, int elaps
|
|||
}
|
||||
|
||||
void TorrentDownloadEngine::calculateStatistics() {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
int elapsed = Util::difftvsec(now, cp[currentCp]);
|
||||
int elapsed = cp[currentCp].difference();
|
||||
|
||||
sessionDownloadLengthArray[0] += torrentMan->getDeltaDownloadLength();
|
||||
sessionUploadLengthArray[0] += torrentMan->getDeltaUploadLength();
|
||||
|
@ -111,8 +109,11 @@ void TorrentDownloadEngine::calculateStatistics() {
|
|||
}
|
||||
|
||||
if(elapsed-lastElapsed >= 1) {
|
||||
avgSpeed = calculateSpeed(sessionDownloadLength,
|
||||
Util::difftvsec(now, startup));
|
||||
int elapsedFromStartup = startup.difference();
|
||||
if(elapsedFromStartup > 0) {
|
||||
avgSpeed = calculateSpeed(sessionDownloadLength,
|
||||
elapsedFromStartup);
|
||||
}
|
||||
if(avgSpeed < 0) {
|
||||
avgSpeed = 0;
|
||||
} else if(avgSpeed != 0) {
|
||||
|
@ -126,7 +127,7 @@ void TorrentDownloadEngine::calculateStatistics() {
|
|||
if(elapsed > 15) {
|
||||
sessionDownloadLengthArray[currentCp] = 0;
|
||||
sessionUploadLengthArray[currentCp] = 0;
|
||||
cp[currentCp] = now;
|
||||
cp[currentCp].reset();
|
||||
lastElapsed = 0;
|
||||
currentCp = currentCp ? 0 : 1;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "DownloadEngine.h"
|
||||
#include "TorrentMan.h"
|
||||
#include "Time.h"
|
||||
|
||||
class TorrentDownloadEngine : public DownloadEngine {
|
||||
private:
|
||||
|
@ -32,7 +33,7 @@ private:
|
|||
void initStatistics();
|
||||
void calculateStatistics();
|
||||
protected:
|
||||
struct timeval cp[2];
|
||||
Time cp[2];
|
||||
long long int sessionDownloadLengthArray[2];
|
||||
long long int sessionUploadLengthArray[2];
|
||||
int currentCp;
|
||||
|
@ -43,7 +44,7 @@ protected:
|
|||
long long int selectedDownloadLengthDiff;
|
||||
long long int selectedTotalLength;
|
||||
// The time when startup
|
||||
struct timeval startup;
|
||||
Time startup;
|
||||
// The number of bytes downloaded since startup
|
||||
long long int sessionDownloadLength;
|
||||
// The average speed(bytes per second) since startup
|
||||
|
|
|
@ -130,9 +130,6 @@ void TorrentMan::deleteOldErrorPeers() {
|
|||
}
|
||||
|
||||
Peer* TorrentMan::getPeer() const {
|
||||
if(connections > MAX_PEER_UPDATE) {
|
||||
return Peer::nullPeer;
|
||||
}
|
||||
for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
||||
Peer* p = *itr;
|
||||
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) {
|
||||
peerId = "-A2****-";
|
||||
for(int i = 0; i < 12; i++) {
|
||||
peerId = "-aria2-";
|
||||
for(int i = 0; i < 20-(int)peerId.size(); i++) {
|
||||
peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
|
||||
}
|
||||
|
||||
|
@ -652,3 +649,21 @@ void TorrentMan::onDownloadComplete() {
|
|||
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 "DiskAdaptor.h"
|
||||
#include "Request.h"
|
||||
#include "Time.h"
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
@ -42,16 +43,26 @@ using namespace std;
|
|||
|
||||
#define INFO_HASH_LENGTH 20
|
||||
#define PEER_ID_LENGTH 20
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 300
|
||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 300
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 1800
|
||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 1800
|
||||
#define MAX_PEERS 55
|
||||
#define MAX_PEER_UPDATE 15
|
||||
#define MAX_PEER_LIST_SIZE 250
|
||||
#define END_GAME_PIECE_NUM 20
|
||||
#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 multimap<int, int> Haves;
|
||||
typedef deque<HaveEntry> Haves;
|
||||
typedef deque<int> PieceIndexes;
|
||||
typedef deque<Piece> Pieces;
|
||||
|
||||
|
@ -164,26 +175,9 @@ public:
|
|||
|
||||
string getPieceHash(int index) const;
|
||||
|
||||
void advertisePiece(int cuid, int index) {
|
||||
Haves::value_type vt(cuid, index);
|
||||
haves.insert(vt);
|
||||
}
|
||||
void advertisePiece(int cuid, int index);
|
||||
|
||||
PieceIndexes getAdvertisedPieceIndexes(int myCuid) 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);
|
||||
}
|
||||
PieceIndexes getAdvertisedPieceIndexes(int myCuid, Time lastCheckTime) const;
|
||||
|
||||
long long int getTotalLength() const { return totalLength; }
|
||||
void setTotalLength(long long int length) { totalLength = length; }
|
||||
|
|
|
@ -26,19 +26,21 @@
|
|||
TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
|
||||
TorrentDownloadEngine* e,
|
||||
int interval):
|
||||
Command(cuid), e(e), interval(interval) {
|
||||
checkPoint.tv_sec = 0;
|
||||
checkPoint.tv_usec = 0;
|
||||
}
|
||||
Command(cuid), e(e), interval(interval) {}
|
||||
|
||||
TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
||||
|
||||
bool TrackerWatcherCommand::execute() {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(e->segmentMan->errors > 0) {
|
||||
// we assume the tracker request has failed.
|
||||
e->torrentMan->trackers = 0;
|
||||
e->segmentMan->init();
|
||||
}
|
||||
if(e->torrentMan->trackers == 0 &&
|
||||
(Util::difftvsec(now, checkPoint) >= interval || e->torrentMan->isHalt())) {
|
||||
checkPoint = now;
|
||||
(e->torrentMan->connections < MAX_PEER_UPDATE ||
|
||||
e->torrentMan->isHalt() ||
|
||||
checkPoint.elapsed(interval))) {
|
||||
checkPoint.reset();
|
||||
e->torrentMan->req->resetTryCount();
|
||||
int numWant = 50;
|
||||
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);
|
||||
e->commands.push_back(command);
|
||||
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());
|
||||
if(e->torrentMan->isHalt()) {
|
||||
return true;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "Command.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include <sys/time.h>
|
||||
#include "Time.h"
|
||||
|
||||
#define MIN_PEERS 15
|
||||
|
||||
|
@ -32,7 +32,7 @@ class TrackerWatcherCommand : public Command {
|
|||
private:
|
||||
TorrentDownloadEngine* e;
|
||||
int interval;
|
||||
struct timeval checkPoint;
|
||||
Time checkPoint;
|
||||
public:
|
||||
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
||||
~TrackerWatcherCommand();
|
||||
|
|
|
@ -647,8 +647,8 @@ int main(int argc, char* argv[]) {
|
|||
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
|
||||
try {
|
||||
//op->put(PREF_MAX_TRIES, "0");
|
||||
setSignalHander(SIGINT, torrentHandler, SA_ONESHOT);
|
||||
setSignalHander(SIGTERM, torrentHandler, SA_ONESHOT);
|
||||
setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
|
||||
setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND);
|
||||
|
||||
Request* req = new Request();
|
||||
req->isTorrent = true;
|
||||
|
|
Loading…
Reference in New Issue