summaryrefslogtreecommitdiff
path: root/src/TrackerWatcherCommand.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-03-26 17:12:52 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-03-26 17:20:27 +0900
commitd64089632e82a2548752c7a6baaa68365a795a74 (patch)
tree57fc7b85a8c1290975d58fa4761b04a7695bf7e3 /src/TrackerWatcherCommand.cc
parentc81b1321122e8509b55c94c0cbca0d8d6d319f0c (diff)
parenta7cd943a06b1a5ff4515b57060b84037f8d01f9f (diff)
Merge branch 'master' into random-webseeding
Diffstat (limited to 'src/TrackerWatcherCommand.cc')
-rw-r--r--src/TrackerWatcherCommand.cc219
1 files changed, 119 insertions, 100 deletions
diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc
index 2826ec54..2e6f4f31 100644
--- a/src/TrackerWatcherCommand.cc
+++ b/src/TrackerWatcherCommand.cc
@@ -71,21 +71,15 @@
namespace aria2 {
HTTPAnnRequest::HTTPAnnRequest(std::unique_ptr<RequestGroup> rg)
- : rg_{std::move(rg)}
-{}
-
-HTTPAnnRequest::~HTTPAnnRequest()
-{}
-
-bool HTTPAnnRequest::stopped() const
+ : rg_{std::move(rg)}
{
- return rg_->getNumCommand() == 0;
}
-bool HTTPAnnRequest::success() const
-{
- return rg_->downloadFinished();
-}
+HTTPAnnRequest::~HTTPAnnRequest() {}
+
+bool HTTPAnnRequest::stopped() const { return rg_->getNumCommand() == 0; }
+
+bool HTTPAnnRequest::success() const { return rg_->downloadFinished(); }
void HTTPAnnRequest::stop(DownloadEngine* e)
{
@@ -101,43 +95,51 @@ bool HTTPAnnRequest::issue(DownloadEngine* e)
e->setNoWait(true);
A2_LOG_DEBUG("added tracker request command");
return true;
- } catch(RecoverableException& ex) {
+ }
+ catch (RecoverableException& ex) {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, ex);
return false;
}
}
-bool HTTPAnnRequest::processResponse
-(const std::shared_ptr<BtAnnounce>& btAnnounce)
+bool HTTPAnnRequest::processResponse(
+ const std::shared_ptr<BtAnnounce>& btAnnounce)
{
try {
std::stringstream strm;
unsigned char data[2048];
rg_->getPieceStorage()->getDiskAdaptor()->openFile();
- while(1) {
- ssize_t dataLength = rg_->getPieceStorage()->
- getDiskAdaptor()->readData(data, sizeof(data), strm.tellp());
- if(dataLength == 0) {
+ while (1) {
+ ssize_t dataLength = rg_->getPieceStorage()->getDiskAdaptor()->readData(
+ data, sizeof(data), strm.tellp());
+ if (dataLength == 0) {
break;
}
strm.write(reinterpret_cast<const char*>(data), dataLength);
}
std::string res = strm.str();
- btAnnounce->processAnnounceResponse
- (reinterpret_cast<const unsigned char*>(res.c_str()), res.size());
+ btAnnounce->processAnnounceResponse(
+ reinterpret_cast<const unsigned char*>(res.c_str()), res.size());
return true;
- } catch(RecoverableException& e) {
- A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
+ }
+ catch (RecoverableException& e) {
+ const auto& dctx = rg_->getDownloadContext();
+ const auto& fe = dctx->getFirstFileEntry();
+ auto uris = fe->getUris();
+
+ A2_LOG_ERROR_EX(fmt("GID#%s - Tracker request %s failed",
+ GroupId::toHex(rg_->getGID()).c_str(), uris[0].c_str()),
+ e);
return false;
}
}
UDPAnnRequest::UDPAnnRequest(const std::shared_ptr<UDPTrackerRequest>& req)
- : req_(req)
-{}
+ : req_(req)
+{
+}
-UDPAnnRequest::~UDPAnnRequest()
-{}
+UDPAnnRequest::~UDPAnnRequest() {}
bool UDPAnnRequest::stopped() const
{
@@ -147,47 +149,50 @@ bool UDPAnnRequest::stopped() const
bool UDPAnnRequest::success() const
{
return req_ && req_->state == UDPT_STA_COMPLETE &&
- req_->error == UDPT_ERR_SUCCESS;
+ req_->error == UDPT_ERR_SUCCESS;
}
void UDPAnnRequest::stop(DownloadEngine* e)
{
- if(req_) {
+ if (req_) {
req_.reset();
}
}
bool UDPAnnRequest::issue(DownloadEngine* e)
{
- if(req_) {
+ if (req_) {
e->addCommand(make_unique<NameResolveCommand>(e->newCUID(), e, req_));
e->setNoWait(true);
return true;
- } else {
+ }
+ else {
return false;
}
}
-bool UDPAnnRequest::processResponse
-(const std::shared_ptr<BtAnnounce>& btAnnounce)
+bool UDPAnnRequest::processResponse(
+ const std::shared_ptr<BtAnnounce>& btAnnounce)
{
- if(req_) {
+ if (req_) {
btAnnounce->processUDPTrackerResponse(req_);
return true;
- } else {
+ }
+ else {
return false;
}
}
-TrackerWatcherCommand::TrackerWatcherCommand
-(cuid_t cuid, RequestGroup* requestGroup, DownloadEngine* e)
- : Command(cuid),
- requestGroup_(requestGroup),
- e_(e),
- udpTrackerClient_(e_->getBtRegistry()->getUDPTrackerClient())
+TrackerWatcherCommand::TrackerWatcherCommand(cuid_t cuid,
+ RequestGroup* requestGroup,
+ DownloadEngine* e)
+ : Command(cuid),
+ requestGroup_(requestGroup),
+ e_(e),
+ udpTrackerClient_(e_->getBtRegistry()->getUDPTrackerClient())
{
requestGroup_->increaseNumCommand();
- if(udpTrackerClient_) {
+ if (udpTrackerClient_) {
udpTrackerClient_->increaseWatchers();
}
}
@@ -195,78 +200,90 @@ TrackerWatcherCommand::TrackerWatcherCommand
TrackerWatcherCommand::~TrackerWatcherCommand()
{
requestGroup_->decreaseNumCommand();
- if(udpTrackerClient_) {
+ if (udpTrackerClient_) {
udpTrackerClient_->decreaseWatchers();
}
}
-bool TrackerWatcherCommand::execute() {
- if(requestGroup_->isForceHaltRequested()) {
- if(!trackerRequest_) {
+bool TrackerWatcherCommand::execute()
+{
+ if (requestGroup_->isForceHaltRequested()) {
+ if (!trackerRequest_) {
return true;
- } else if(trackerRequest_->stopped() ||
- trackerRequest_->success()) {
+ }
+ else if (trackerRequest_->stopped() || trackerRequest_->success()) {
return true;
- } else {
+ }
+ else {
trackerRequest_->stop(e_);
e_->setRefreshInterval(std::chrono::milliseconds(0));
e_->addCommand(std::unique_ptr<Command>(this));
return false;
}
}
- if(btAnnounce_->noMoreAnnounce()) {
+ if (btAnnounce_->noMoreAnnounce()) {
A2_LOG_DEBUG("no more announce");
return true;
}
- if(!trackerRequest_) {
+ if (!trackerRequest_) {
trackerRequest_ = createAnnounce(e_);
- if(trackerRequest_) {
+ if (trackerRequest_) {
trackerRequest_->issue(e_);
+ A2_LOG_DEBUG("tracker request created");
}
- } else if(trackerRequest_->stopped()) {
+ }
+ else if (trackerRequest_->stopped()) {
// We really want to make sure that tracker request has finished
// by checking getNumCommand() == 0. Because we reset
// trackerRequestGroup_, if it is still used in other Command, we
// will get Segmentation fault.
- if(trackerRequest_->success()) {
- if(trackerRequest_->processResponse(btAnnounce_)) {
+ if (trackerRequest_->success()) {
+ if (trackerRequest_->processResponse(btAnnounce_)) {
btAnnounce_->announceSuccess();
btAnnounce_->resetAnnounce();
addConnection();
- } else {
+ }
+ else {
btAnnounce_->announceFailure();
- if(btAnnounce_->isAllAnnounceFailed()) {
+ if (btAnnounce_->isAllAnnounceFailed()) {
btAnnounce_->resetAnnounce();
}
}
trackerRequest_.reset();
- } else {
+ }
+ else {
// handle errors here
btAnnounce_->announceFailure(); // inside it, trackers = 0.
trackerRequest_.reset();
- if(btAnnounce_->isAllAnnounceFailed()) {
+ if (btAnnounce_->isAllAnnounceFailed()) {
btAnnounce_->resetAnnounce();
}
}
}
+
+ if (!trackerRequest_ && btAnnounce_->noMoreAnnounce()) {
+ A2_LOG_DEBUG("no more announce");
+ return true;
+ }
+
e_->addCommand(std::unique_ptr<Command>(this));
return false;
}
void TrackerWatcherCommand::addConnection()
{
- while(!btRuntime_->isHalt() && btRuntime_->lessThanMinPeers()) {
- if(!peerStorage_->isPeerAvailable()) {
+ while (!btRuntime_->isHalt() && btRuntime_->lessThanMinPeers()) {
+ if (!peerStorage_->isPeerAvailable()) {
break;
}
cuid_t ncuid = e_->newCUID();
std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
// sanity check
- if(!peer) {
+ if (!peer) {
break;
}
- auto command = make_unique<PeerInitiateConnectionCommand>
- (ncuid, requestGroup_, peer, e_, btRuntime_);
+ auto command = make_unique<PeerInitiateConnectionCommand>(
+ ncuid, requestGroup_, peer, e_, btRuntime_);
command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_);
e_->addCommand(std::move(command));
@@ -278,32 +295,34 @@ void TrackerWatcherCommand::addConnection()
std::unique_ptr<AnnRequest>
TrackerWatcherCommand::createAnnounce(DownloadEngine* e)
{
- while(!btAnnounce_->isAllAnnounceFailed() &&
- btAnnounce_->isAnnounceReady()) {
+ while (!btAnnounce_->isAllAnnounceFailed() &&
+ btAnnounce_->isAnnounceReady()) {
std::string uri = btAnnounce_->getAnnounceUrl();
uri_split_result res;
memset(&res, 0, sizeof(res));
- if(uri_split(&res, uri.c_str()) == 0) {
+ if (uri_split(&res, uri.c_str()) == 0) {
// Without UDP tracker support, send it to normal tracker flow
// and make it fail.
std::unique_ptr<AnnRequest> treq;
- if(udpTrackerClient_ &&
- uri::getFieldString(res, USR_SCHEME, uri.c_str()) == "udp") {
+ if (udpTrackerClient_ &&
+ uri::getFieldString(res, USR_SCHEME, uri.c_str()) == "udp") {
uint16_t localPort;
- localPort = e->getBtRegistry()->getUdpPort();
- treq = createUDPAnnRequest
- (uri::getFieldString(res, USR_HOST, uri.c_str()), res.port,
- localPort);
- } else {
+ localPort = e->getBtRegistry()->getTcpPort();
+ treq =
+ createUDPAnnRequest(uri::getFieldString(res, USR_HOST, uri.c_str()),
+ res.port, localPort);
+ }
+ else {
treq = createHTTPAnnRequest(btAnnounce_->getAnnounceUrl());
}
btAnnounce_->announceStart(); // inside it, trackers++.
return treq;
- } else {
+ }
+ else {
btAnnounce_->announceFailure();
}
}
- if(btAnnounce_->isAllAnnounceFailed()) {
+ if (btAnnounce_->isAllAnnounceFailed()) {
btAnnounce_->resetAnnounce();
}
return nullptr;
@@ -311,27 +330,28 @@ TrackerWatcherCommand::createAnnounce(DownloadEngine* e)
std::unique_ptr<AnnRequest>
TrackerWatcherCommand::createUDPAnnRequest(const std::string& host,
- uint16_t port,
- uint16_t localPort)
+ uint16_t port, uint16_t localPort)
{
- return make_unique<UDPAnnRequest>
- (btAnnounce_->createUDPTrackerRequest(host, port, localPort));
+ auto req = btAnnounce_->createUDPTrackerRequest(host, port, localPort);
+ req->user_data = this;
+
+ return make_unique<UDPAnnRequest>(std::move(req));
}
namespace {
-bool backupTrackerIsAvailable
-(const std::shared_ptr<DownloadContext>& context)
+bool backupTrackerIsAvailable(const std::shared_ptr<DownloadContext>& context)
{
auto torrentAttrs = bittorrent::getTorrentAttrs(context);
- if(torrentAttrs->announceList.size() >= 2) {
+ if (torrentAttrs->announceList.size() >= 2) {
return true;
}
- if(torrentAttrs->announceList.empty()) {
+ if (torrentAttrs->announceList.empty()) {
return false;
}
- if(torrentAttrs->announceList[0].size() >= 2) {
+ if (torrentAttrs->announceList[0].size() >= 2) {
return true;
- } else {
+ }
+ else {
return false;
}
}
@@ -344,9 +364,10 @@ TrackerWatcherCommand::createHTTPAnnRequest(const std::string& uri)
uris.push_back(uri);
auto option = util::copy(getOption());
auto rg = make_unique<RequestGroup>(GroupId::create(), option);
- if(backupTrackerIsAvailable(requestGroup_->getDownloadContext())) {
+ if (backupTrackerIsAvailable(requestGroup_->getDownloadContext())) {
A2_LOG_DEBUG("This is multi-tracker announce.");
- } else {
+ }
+ else {
A2_LOG_DEBUG("This is single-tracker announce.");
}
rg->setNumConcurrentCommand(1);
@@ -363,10 +384,8 @@ TrackerWatcherCommand::createHTTPAnnRequest(const std::string& uri)
option->get(PREF_BT_TRACKER_CONNECT_TIMEOUT));
option->put(PREF_REUSE_URI, A2_V_FALSE);
option->put(PREF_SELECT_LEAST_USED_HOST, A2_V_FALSE);
- auto dctx = std::make_shared<DownloadContext>
- (option->getAsInt(PREF_PIECE_LENGTH),
- 0,
- "[tracker.announce]");
+ auto dctx = std::make_shared<DownloadContext>(
+ option->getAsInt(PREF_PIECE_LENGTH), 0, "[tracker.announce]");
dctx->getFileEntries().front()->setUris(uris);
rg->setDownloadContext(dctx);
auto dwf = std::make_shared<ByteArrayDiskWriterFactory>();
@@ -383,26 +402,26 @@ TrackerWatcherCommand::createHTTPAnnRequest(const std::string& uri)
return make_unique<HTTPAnnRequest>(std::move(rg));
}
-void TrackerWatcherCommand::setBtRuntime
-(const std::shared_ptr<BtRuntime>& btRuntime)
+void TrackerWatcherCommand::setBtRuntime(
+ const std::shared_ptr<BtRuntime>& btRuntime)
{
btRuntime_ = btRuntime;
}
-void TrackerWatcherCommand::setPeerStorage
-(const std::shared_ptr<PeerStorage>& peerStorage)
+void TrackerWatcherCommand::setPeerStorage(
+ const std::shared_ptr<PeerStorage>& peerStorage)
{
peerStorage_ = peerStorage;
}
-void TrackerWatcherCommand::setPieceStorage
-(const std::shared_ptr<PieceStorage>& pieceStorage)
+void TrackerWatcherCommand::setPieceStorage(
+ const std::shared_ptr<PieceStorage>& pieceStorage)
{
pieceStorage_ = pieceStorage;
}
-void TrackerWatcherCommand::setBtAnnounce
-(const std::shared_ptr<BtAnnounce>& btAnnounce)
+void TrackerWatcherCommand::setBtAnnounce(
+ const std::shared_ptr<BtAnnounce>& btAnnounce)
{
btAnnounce_ = btAnnounce;
}