| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 
							- /* <!-- copyright */
 
- /*
 
-  * aria2 - The high speed download utility
 
-  *
 
-  * Copyright (C) 2006 Tatsuhiro Tsujikawa
 
-  *
 
-  * This program is free software; you can redistribute it and/or modify
 
-  * it under the terms of the GNU General Public License as published by
 
-  * the Free Software Foundation; either version 2 of the License, or
 
-  * (at your option) any later version.
 
-  *
 
-  * This program is distributed in the hope that it will be useful,
 
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
-  * GNU General Public License for more details.
 
-  *
 
-  * You should have received a copy of the GNU General Public License
 
-  * along with this program; if not, write to the Free Software
 
-  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-  *
 
-  * In addition, as a special exception, the copyright holders give
 
-  * permission to link the code of portions of this program with the
 
-  * OpenSSL library under certain conditions as described in each
 
-  * individual source file, and distribute linked combinations
 
-  * including the two.
 
-  * You must obey the GNU General Public License in all respects
 
-  * for all of the code used other than OpenSSL.  If you modify
 
-  * file(s) with this exception, you may extend this exception to your
 
-  * version of the file(s), but you are not obligated to do so.  If you
 
-  * do not wish to do so, delete this exception statement from your
 
-  * version.  If you delete this exception statement from all source
 
-  * files in the program, then also delete it here.
 
-  */
 
- /* copyright --> */
 
- #include "DefaultBtAnnounce.h"
 
- #include "BtRegistry.h"
 
- #include "LogFactory.h"
 
- #include "Logger.h"
 
- #include "MetaFileUtil.h"
 
- #include "Dictionary.h"
 
- #include "List.h"
 
- #include "Data.h"
 
- #include "DelegatingPeerListProcessor.h"
 
- #include "Util.h"
 
- #include "prefs.h"
 
- #include "DlAbortEx.h"
 
- #include "message.h"
 
- #include "SimpleRandomizer.h"
 
- #include "BtContext.h"
 
- #include "PieceStorage.h"
 
- #include "BtRuntime.h"
 
- #include "PeerStorage.h"
 
- #include "Peer.h"
 
- #include "Option.h"
 
- #include "StringFormat.h"
 
- #include "A2STR.h"
 
- namespace aria2 {
 
- DefaultBtAnnounce::DefaultBtAnnounce(const BtContextHandle& btContext,
 
- 				     const Option* option):
 
-   btContext(btContext),
 
-   trackers(0),
 
-   interval(DEFAULT_ANNOUNCE_INTERVAL),
 
-   minInterval(DEFAULT_ANNOUNCE_INTERVAL),
 
-   complete(0),
 
-   incomplete(0),
 
-   announceList(btContext->getAnnounceTiers()),
 
-   option(option),
 
-   logger(LogFactory::getInstance()),
 
-   _randomizer(SimpleRandomizer::getInstance()),
 
-   btRuntime(BT_RUNTIME(btContext)),
 
-   pieceStorage(PIECE_STORAGE(btContext)),
 
-   peerStorage(PEER_STORAGE(btContext))
 
- {
 
-   prevAnnounceTime.setTimeInSec(0);
 
-   generateKey();
 
- }
 
- DefaultBtAnnounce::~DefaultBtAnnounce() {
 
- }
 
- void DefaultBtAnnounce::generateKey()
 
- {
 
-   key = Util::randomAlpha(8, _randomizer);
 
- }
 
- bool DefaultBtAnnounce::isDefaultAnnounceReady() {
 
-   return (trackers == 0 && prevAnnounceTime.elapsed(minInterval) &&
 
- 	  !announceList.allTiersFailed());
 
- }
 
- bool DefaultBtAnnounce::isStoppedAnnounceReady() {
 
-   return (trackers == 0 &&
 
- 	  btRuntime->isHalt() &&
 
- 	  announceList.countStoppedAllowedTier());
 
- }
 
- bool DefaultBtAnnounce::isCompletedAnnounceReady() {
 
-   return (trackers == 0 &&
 
- 	  pieceStorage->allDownloadFinished() &&
 
- 	  announceList.countCompletedAllowedTier());
 
- }
 
- bool DefaultBtAnnounce::isAnnounceReady() {
 
-   return
 
-     isStoppedAnnounceReady() ||
 
-     isCompletedAnnounceReady() ||
 
-     isDefaultAnnounceReady();
 
- }
 
- std::string DefaultBtAnnounce::getAnnounceUrl() {
 
-   if(isStoppedAnnounceReady()) {
 
-     if(!announceList.currentTierAcceptsStoppedEvent()) {
 
-       announceList.moveToStoppedAllowedTier();
 
-     }
 
-     announceList.setEvent(AnnounceTier::STOPPED);
 
-   } else if(isCompletedAnnounceReady()) {
 
-     if(!announceList.currentTierAcceptsCompletedEvent()) {
 
-       announceList.moveToCompletedAllowedTier();
 
-     }
 
-     announceList.setEvent(AnnounceTier::COMPLETED);
 
-   } else if(isDefaultAnnounceReady()) {
 
-     // If download completed before "started" event is sent to a tracker,
 
-     // we change the event to something else to prevent us from
 
-     // sending "completed" event.
 
-     if(pieceStorage->allDownloadFinished() &&
 
-        announceList.getEvent() == AnnounceTier::STARTED) {
 
-       announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION);
 
-     }
 
-   } else {
 
-     return A2STR::NIL;
 
-   }
 
-   unsigned int numWant = 50;
 
-   if(!btRuntime->lessThanEqMinPeer() || btRuntime->isHalt()) {
 
-     numWant = 0;
 
-   }
 
-   TransferStat stat = peerStorage->calculateStat();
 
-   uint64_t left = pieceStorage->getTotalLength()-pieceStorage->getCompletedLength();
 
-   if(left < 0) {
 
-     left = 0;
 
-   }
 
-   std::string url = announceList.getAnnounce()+"?"+
 
-     "info_hash="+Util::torrentUrlencode(btContext->getInfoHash(),
 
- 					btContext->getInfoHashLength())+"&"+
 
-     "peer_id="+Util::torrentUrlencode(btContext->getPeerId(), 20)+"&"+
 
-     "uploaded="+Util::uitos(stat.getSessionUploadLength())+"&"+
 
-     "downloaded="+Util::uitos(stat.getSessionDownloadLength())+"&"+
 
-     "left="+Util::uitos(left)+"&"+
 
-     "compact=1"+"&"+
 
-     "key="+key+"&"+
 
-     "numwant="+Util::uitos(numWant)+"&"+
 
-     "no_peer_id=1";
 
-   if(btRuntime->getListenPort() > 0) {
 
-     url += std::string("&")+"port="+Util::uitos(btRuntime->getListenPort());
 
-   }
 
-   std::string event = announceList.getEventString();
 
-   if(!event.empty()) {
 
-     url += std::string("&")+"event="+event;
 
-   }
 
-   if(!trackerId.empty()) {
 
-     url += std::string("&")+"trackerid="+Util::torrentUrlencode(trackerId);
 
-   }
 
-   if(option->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
 
-     url += "&requirecrypto=1";
 
-   } else {
 
-     url += "&supportcrypto=1";
 
-   }
 
-   return url;
 
- }
 
- void DefaultBtAnnounce::announceStart() {
 
-   trackers++;
 
- }
 
- void DefaultBtAnnounce::announceSuccess() {
 
-   trackers = 0;
 
-   announceList.announceSuccess();
 
- }
 
- void DefaultBtAnnounce::announceFailure() {
 
-   trackers = 0;
 
-   announceList.announceFailure();
 
- }
 
- bool DefaultBtAnnounce::isAllAnnounceFailed() {
 
-   return announceList.allTiersFailed();
 
- }
 
- void DefaultBtAnnounce::resetAnnounce() {
 
-   prevAnnounceTime.reset();
 
-   announceList.resetTier();
 
- }
 
- void
 
- DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
 
- 					   size_t trackerResponseLength)
 
- {
 
-   SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
 
- 							trackerResponseLength));
 
-   const Dictionary* response = dynamic_cast<const Dictionary*>(entry.get());
 
-   if(!response) {
 
-     throw DlAbortEx(MSG_NULL_TRACKER_RESPONSE);
 
-   }
 
-   const Data* failureReasonData = dynamic_cast<const Data*>(response->get("failure reason"));
 
-   if(failureReasonData) {
 
-     throw DlAbortEx
 
-       (StringFormat(EX_TRACKER_FAILURE,
 
- 		    failureReasonData->toString().c_str()).str());
 
-   }
 
-   const Data* warningMessageData = dynamic_cast<const Data*>(response->get("warning message"));
 
-   if(warningMessageData) {
 
-     logger->warn(MSG_TRACKER_WARNING_MESSAGE,
 
- 		 warningMessageData->toString().c_str());
 
-   }
 
-   const Data* trackerIdData = dynamic_cast<const Data*>(response->get("tracker id"));
 
-   if(trackerIdData) {
 
-     trackerId = trackerIdData->toString();
 
-     logger->debug("Tracker ID:%s", trackerId.c_str());
 
-   }
 
-   const Data* intervalData = dynamic_cast<const Data*>(response->get("interval"));
 
-   if(intervalData) {
 
-     time_t t = intervalData->toInt();
 
-     if(t > 0) {
 
-       interval = intervalData->toInt();
 
-       logger->debug("Interval:%d", interval);
 
-     }
 
-   }
 
-   const Data* minIntervalData = dynamic_cast<const Data*>(response->get("min interval"));
 
-   if(minIntervalData) {
 
-     time_t t = minIntervalData->toInt();
 
-     if(t > 0) {
 
-       minInterval = minIntervalData->toInt();
 
-       logger->debug("Min interval:%d", minInterval);
 
-     }
 
-   }
 
-   if(minInterval > interval) {
 
-     minInterval = interval;
 
-   }
 
-   const Data* completeData = dynamic_cast<const Data*>(response->get("complete"));
 
-   if(completeData) {
 
-     complete = completeData->toInt();
 
-     logger->debug("Complete:%d", complete);
 
-   }
 
-   const Data* incompleteData = dynamic_cast<const Data*>(response->get("incomplete"));
 
-   if(incompleteData) {
 
-     incomplete = incompleteData->toInt();
 
-     logger->debug("Incomplete:%d", incomplete);
 
-   }
 
-   const MetaEntry* peersEntry = response->get("peers");
 
-   if(peersEntry &&
 
-      !btRuntime->isHalt() &&
 
-      btRuntime->lessThanMinPeer()) {
 
-     DelegatingPeerListProcessor proc;
 
-     std::deque<SharedHandle<Peer> > peers;
 
-     proc.extractPeer(peers, peersEntry);
 
-     peerStorage->addPeer(peers);
 
-   }
 
-   if(!peersEntry) {
 
-     logger->info(MSG_NO_PEER_LIST_RECEIVED);
 
-   }
 
- }
 
- bool DefaultBtAnnounce::noMoreAnnounce() {
 
-   return (trackers == 0 &&
 
- 	  btRuntime->isHalt() &&
 
- 	  !announceList.countStoppedAllowedTier());
 
- }
 
- void DefaultBtAnnounce::shuffleAnnounce() {
 
-   announceList.shuffle();
 
- }
 
- void DefaultBtAnnounce::setRandomizer(const RandomizerHandle& randomizer)
 
- {
 
-   _randomizer = randomizer;
 
- }
 
- void DefaultBtAnnounce::setBtRuntime(const BtRuntimeHandle& btRuntime)
 
- {
 
-   this->btRuntime = btRuntime;
 
- }
 
- BtRuntimeHandle DefaultBtAnnounce::getBtRuntime() const
 
- {
 
-   return btRuntime;
 
- }
 
- void DefaultBtAnnounce::setPieceStorage(const PieceStorageHandle& pieceStorage)
 
- {
 
-   this->pieceStorage = pieceStorage;
 
- }
 
- PieceStorageHandle DefaultBtAnnounce::getPieceStorage() const
 
- {
 
-   return pieceStorage;
 
- }
 
- void DefaultBtAnnounce::setPeerStorage(const PeerStorageHandle& peerStorage)
 
- {
 
-   this->peerStorage = peerStorage;
 
- }
 
- PeerStorageHandle DefaultBtAnnounce::getPeerStorage() const
 
- {
 
-   return peerStorage;
 
- }
 
- } // namespace aria2
 
 
  |