summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-12-24 06:25:21 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-12-24 06:25:21 +0000
commit9c3e8fbd9c92cc858c2b0f805714e19ce97b7983 (patch)
tree2f53afd601fbe1fff339f17cef5ef37186a1960a /src
parent458cc274628f226b3130240d15a1ae8e562d31b2 (diff)
2006-12-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten a portion of bittorrent implementation: * src/BtMessageValidator.h: New class. * src/BtBitfieldMessageValidator.h: New class. * src/BtHandshakeMessageValidator.h: New class. * src/BtRequestMessageValidator.h: New class. * src/BtSuggestPieceMessageValidator.h: New class. * src/BtAllowedFastMessageValidator.h: New class. * src/BtRejectMessageValidator.h: New class. * src/BtCancelMessageValidator.h: New class. * src/BtPieceMessageValidator.h: New class. * src/BtHaveMessageValidator.h: New class. * src/BtEventListener.h: New class. * src/AbstractBtEventListener.h: New class. * src/BtEvent.h: New class. * src/BtChokingEvent.h: New class. * src/BtChokedEvent.h: New class. * src/BtCancelSendingPieceEvent.h: New class. * src/BtAbortOutstandingRequestEvent.h: New class. * src/Randomizer.h: New class. * src/SimpleRandomizer.h: New class. * src/BtMessage.h: New class. * src/AbstractBtMessage.h: New class. * src/SimpleBtMessage.h: New class. * src/BtHaveMessage.h: New class. * src/BtInterestedMessage.h: New class. * src/BtAllowedFastMessage.h: New class. * src/BtUnchokeMessage.h: New class. * src/BtCancelMessage.h: New class. * src/BtNotInterestedMessage.h: New class. * src/BtChokeMessage.h: New class. * src/BtHaveNoneMessage.h: New class. * src/BtHandshakeMessage.h: New class. * src/BtSuggestPieceMessage.h: New class. * src/BtHaveMessage.h: New class. * src/BtPieceMessage.h: New class. * src/BtHaveAllMessage.h: New class. * src/BtKeepAliveMessage.h: New class. * src/BtPortMessage.h: New class. * src/BtRejectMessage.h: New class. * src/BtBitfieldMessage.h: New class. * src/BtRequestMessage.h: New class. * src/DefaultBtRequestFactory.h: New class. * src/DefaultBtMessageReceiver.h: New class. * src/BtInteractive.h: New class. * src/BtMessageDispatcher.h: New class. * src/DefaultBtMessageDispatcher.h: New class. * src/DefaultBtInteractive.h: New class. * src/BitfieldManFactory.h: New class. * src/HandleRegistry.h: New class. * src/BtMessageFactory.h: New class. * src/BtMessageReceiver.h: New class. * src/DefaultBtMessageFactory.h: New class. * src/PeerObject.h: New class. * src/BtRequestFactory.h: New class.
Diffstat (limited to 'src')
-rw-r--r--src/AbstractBtEventListener.h55
-rw-r--r--src/AbstractBtMessage.h167
-rw-r--r--src/BitfieldMan.cc9
-rw-r--r--src/BitfieldMan.h13
-rw-r--r--src/BitfieldManFactory.cc40
-rw-r--r--src/BitfieldManFactory.h85
-rw-r--r--src/BtAbortOutstandingRequestEvent.h57
-rw-r--r--src/BtAllowedFastMessage.cc89
-rw-r--r--src/BtAllowedFastMessage.h85
-rw-r--r--src/BtAllowedFastMessageValidator.h60
-rw-r--r--src/BtAnnounce.h5
-rw-r--r--src/BtBitfieldMessage.cc95
-rw-r--r--src/BtBitfieldMessage.h98
-rw-r--r--src/BtBitfieldMessageValidator.h61
-rw-r--r--src/BtCancelMessage.cc88
-rw-r--r--src/BtCancelMessage.h93
-rw-r--r--src/BtCancelMessageValidator.h67
-rw-r--r--src/BtCancelSendingPieceEvent.h78
-rw-r--r--src/BtChokeMessage.cc87
-rw-r--r--src/BtChokeMessage.h77
-rw-r--r--src/BtChokedEvent.h45
-rw-r--r--src/BtChokingEvent.h45
-rw-r--r--src/BtContext.h5
-rw-r--r--src/BtEvent.h47
-rw-r--r--src/BtEventListener.h51
-rw-r--r--src/BtHandshakeMessage.cc100
-rw-r--r--src/BtHandshakeMessage.h117
-rw-r--r--src/BtHandshakeMessageValidator.h75
-rw-r--r--src/BtHaveAllMessage.cc81
-rw-r--r--src/BtHaveAllMessage.h73
-rw-r--r--src/BtHaveMessage.cc85
-rw-r--r--src/BtHaveMessage.h81
-rw-r--r--src/BtHaveMessageValidator.h60
-rw-r--r--src/BtHaveNoneMessage.cc80
-rw-r--r--src/BtHaveNoneMessage.h73
-rw-r--r--src/BtInteractive.h66
-rw-r--r--src/BtInterestedMessage.cc85
-rw-r--r--src/BtInterestedMessage.h77
-rw-r--r--src/BtKeepAliveMessage.cc53
-rw-r--r--src/BtKeepAliveMessage.h73
-rw-r--r--src/BtMessage.h72
-rw-r--r--src/BtMessageDispatcher.h82
-rw-r--r--src/BtMessageFactory.cc53
-rw-r--r--src/BtMessageFactory.h91
-rw-r--r--src/BtMessageReceiver.h54
-rw-r--r--src/BtMessageValidator.h52
-rw-r--r--src/BtNotInterestedMessage.cc85
-rw-r--r--src/BtNotInterestedMessage.h77
-rw-r--r--src/BtPieceMessage.cc283
-rw-r--r--src/BtPieceMessage.h154
-rw-r--r--src/BtPieceMessageValidator.h64
-rw-r--r--src/BtPortMessage.cc56
-rw-r--r--src/BtPortMessage.h72
-rw-r--r--src/BtRegistry.cc30
-rw-r--r--src/BtRegistry.h39
-rw-r--r--src/BtRejectMessage.cc101
-rw-r--r--src/BtRejectMessage.h88
-rw-r--r--src/BtRejectMessageValidator.h68
-rw-r--r--src/BtRequestFactory.h72
-rw-r--r--src/BtRequestMessage.cc129
-rw-r--r--src/BtRequestMessage.h117
-rw-r--r--src/BtRequestMessageValidator.h68
-rw-r--r--src/BtSuggestPieceMessage.cc78
-rw-r--r--src/BtSuggestPieceMessage.h81
-rw-r--r--src/BtSuggestPieceMessageValidator.h60
-rw-r--r--src/BtUnchokeMessage.cc85
-rw-r--r--src/BtUnchokeMessage.h76
-rw-r--r--src/DefaultBtAnnounce.cc9
-rw-r--r--src/DefaultBtAnnounce.h7
-rw-r--r--src/DefaultBtContext.cc6
-rw-r--r--src/DefaultBtContext.h10
-rw-r--r--src/DefaultBtInteractive.cc307
-rw-r--r--src/DefaultBtInteractive.h195
-rw-r--r--src/DefaultBtMessageDispatcher.cc214
-rw-r--r--src/DefaultBtMessageDispatcher.h163
-rw-r--r--src/DefaultBtMessageFactory.cc347
-rw-r--r--src/DefaultBtMessageFactory.h131
-rw-r--r--src/DefaultBtMessageReceiver.cc95
-rw-r--r--src/DefaultBtMessageReceiver.h120
-rw-r--r--src/DefaultBtRequestFactory.cc99
-rw-r--r--src/DefaultBtRequestFactory.h125
-rw-r--r--src/DefaultPeerStorage.cc11
-rw-r--r--src/DefaultPeerStorage.h1
-rw-r--r--src/DefaultPieceStorage.cc114
-rw-r--r--src/DefaultPieceStorage.h23
-rw-r--r--src/DownloadEngineFactory.cc18
-rw-r--r--src/HandleRegistry.h73
-rw-r--r--src/Makefile.am56
-rw-r--r--src/Makefile.in185
-rw-r--r--src/Peer.cc51
-rw-r--r--src/Peer.h45
-rw-r--r--src/PeerConnection.cc47
-rw-r--r--src/PeerConnection.h31
-rw-r--r--src/PeerInteraction.cc54
-rw-r--r--src/PeerInteraction.h5
-rw-r--r--src/PeerInteractionCommand.cc269
-rw-r--r--src/PeerInteractionCommand.h33
-rw-r--r--src/PeerMessage.cc1
-rw-r--r--src/PeerMessage.h2
-rw-r--r--src/PeerMessageFactory.cc8
-rw-r--r--src/PeerMessageFactory.h2
-rw-r--r--src/PeerMessageUtil.cc64
-rw-r--r--src/PeerMessageUtil.h56
-rw-r--r--src/PeerObject.h59
-rw-r--r--src/Piece.cc19
-rw-r--r--src/Piece.h25
-rw-r--r--src/PieceMessage.cc38
-rw-r--r--src/PieceMessage.h10
-rw-r--r--src/PieceStorage.h22
-rw-r--r--src/Randomizer.h50
-rw-r--r--src/RequestSlot.cc8
-rw-r--r--src/RequestSlot.h31
-rw-r--r--src/SegmentMan.cc3
-rw-r--r--src/SharedHandle.h14
-rw-r--r--src/SimpleBtMessage.cc64
-rw-r--r--src/SimpleBtMessage.h60
-rw-r--r--src/SimpleRandomizer.cc37
-rw-r--r--src/SimpleRandomizer.h68
-rw-r--r--src/TorrentRequestInfo.cc3
-rw-r--r--src/TrackerUpdateCommand.cc6
-rw-r--r--src/Util.cc36
-rw-r--r--src/Util.h9
-rw-r--r--src/common.h5
-rw-r--r--src/main.cc7
-rw-r--r--src/prefs.h4
125 files changed, 8068 insertions, 555 deletions
diff --git a/src/AbstractBtEventListener.h b/src/AbstractBtEventListener.h
new file mode 100644
index 00000000..4b16f4f6
--- /dev/null
+++ b/src/AbstractBtEventListener.h
@@ -0,0 +1,55 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_ABSTRACT_BT_EVENT_LISTENER_H_
+#define _D_ABSTRACT_BT_EVENT_LISTENER_H_
+
+#include "BtEventListener.h"
+
+class AbstractBtEventListener : public BtEventListener {
+public:
+ virtual ~AbstractBtEventListener() {}
+
+ virtual bool canHandle(const BtEventHandle& event) = 0;
+
+ virtual void handleEventInternal(const BtEventHandle& event) = 0;
+
+ virtual void handleEvent(const BtEventHandle& event) {
+ if(canHandle(event)) {
+ handleEventInternal(event);
+ }
+ }
+};
+
+#endif // _D_ABSTRACT_BT_EVENT_LISTENER_H_
diff --git a/src/AbstractBtMessage.h b/src/AbstractBtMessage.h
new file mode 100644
index 00000000..07902eb8
--- /dev/null
+++ b/src/AbstractBtMessage.h
@@ -0,0 +1,167 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_ABSTRACT_BT_MESSAGE_H_
+#define _D_ABSTRACT_BT_MESSAGE_H_
+
+#include "BtMessage.h"
+#include "Peer.h"
+#include "Piece.h"
+#include "LogFactory.h"
+#include "Logger.h"
+#include "BtEvent.h"
+#include "BtEventListener.h"
+#include "BtContext.h"
+#include "BtRegistry.h"
+
+class AbstractBtMessage : public BtMessage {
+protected:
+ bool sendingInProgress;
+ bool invalidate;
+ bool uploading;
+ int32_t id;
+ int32_t cuid;
+
+ BtContextHandle btContext;
+
+ PieceStorageHandle pieceStorage;
+
+ PeerHandle peer;
+
+ BtMessageValidatorHandle validator;
+ BtEventListeners listeners;
+ const Logger* logger;
+public:
+ AbstractBtMessage():sendingInProgress(false),
+ invalidate(false),
+ uploading(false),
+ id(0),
+ cuid(0),
+ btContext(0),
+ pieceStorage(0),
+ peer(0),
+ validator(0),
+ logger(LogFactory::getInstance())
+
+ {}
+
+ virtual bool isSendingInProgress() {
+ return sendingInProgress;
+ }
+
+ void setSendingInProgress(bool sendingInProgress) {
+ this->sendingInProgress = sendingInProgress;
+ }
+
+ virtual bool isInvalidate() {
+ return invalidate;
+ }
+
+ void setInvalidate(bool invalidate) {
+ this->invalidate = invalidate;
+ }
+
+ virtual bool isUploading() {
+ return uploading;
+ }
+
+ void setUploading(bool uploading) {
+ this->uploading = uploading;
+ }
+
+ virtual int32_t getId() {
+ return id;
+ }
+
+ int32_t getCuid() const {
+ return cuid;
+ }
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+
+ PeerHandle getPeer() const {
+ return peer;
+ }
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ virtual void doReceivedAction() {}
+
+ virtual bool validate(Errors& errors) {
+ if(validator.get()) {
+ return validator->validate(errors);
+ } else {
+ return true;
+ }
+ }
+
+ virtual void onQueued() {}
+
+ virtual void handleEvent(const BtEventHandle& event) {
+ for(BtEventListeners::iterator itr = listeners.begin();
+ itr != listeners.end(); ++itr) {
+ (*itr)->handleEvent(event);
+ }
+ }
+
+ void addEventListener(const BtEventListenerHandle& listener) {
+ listeners.push_back(listener);
+ }
+
+ void setBtMessageValidator(const BtMessageValidatorHandle& validator) {
+ this->validator = validator;
+ }
+
+ BtMessageValidatorHandle getBtMessageValidator() const {
+ return validator;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ this->pieceStorage = PIECE_STORAGE(btContext);
+ }
+
+ BtContextHandle getBtContext() const {
+ return btContext;
+ }
+
+};
+
+typedef SharedHandle<AbstractBtMessage> AbstractBtMessageHandle;
+
+#endif // _D_ABSTRACT_BT_MESSAGE_H_
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc
index 736bc5b8..b29f4db7 100644
--- a/src/BitfieldMan.cc
+++ b/src/BitfieldMan.cc
@@ -38,7 +38,7 @@
BitfieldMan::BitfieldMan(int blockLength, long long int totalLength)
:blockLength(blockLength), totalLength(totalLength), filterBitfield(0),
- filterEnabled(false) {
+ filterEnabled(false), randomizer(0) {
if(blockLength > 0 && totalLength > 0) {
blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0);
bitfieldLength = blocks/8+(blocks%8 ? 1 : 0);
@@ -49,7 +49,7 @@ BitfieldMan::BitfieldMan(int blockLength, long long int totalLength)
}
}
-BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) {
+BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan):randomizer(0) {
blockLength = bitfieldMan.blockLength;
totalLength = bitfieldMan.totalLength;
blocks = bitfieldMan.blocks;
@@ -65,6 +65,7 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) {
} else {
filterBitfield = 0;
}
+ this->randomizer = bitfieldMan.randomizer;
}
BitfieldMan::~BitfieldMan() {
@@ -106,7 +107,9 @@ int
BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield,
int bitfieldLength) const
{
- int byte = (int)(((double)bitfieldLength)*random()/(RAND_MAX+1.0));
+ int byte = (int)(((double)bitfieldLength)*
+ randomizer->getRandomNumber()/
+ (randomizer->getMaxRandomNumber()+1.0));
unsigned char lastMask = 0;
int lastByteLength = totalLength%(blockLength*8);
diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h
index 53758601..43fb81a1 100644
--- a/src/BitfieldMan.h
+++ b/src/BitfieldMan.h
@@ -36,6 +36,7 @@
#define _D_BITFIELD_MAN_H_
#include "common.h"
+#include "Randomizer.h"
#include <deque>
typedef deque<int> BlockIndexes;
@@ -50,6 +51,8 @@ private:
int bitfieldLength;
int blocks;
bool filterEnabled;
+ RandomizerHandle randomizer;
+
int countSetBit(const unsigned char* bitfield, int len) const;
int getNthBitIndex(const unsigned char bit, int nth) const;
int getMissingIndexRandomly(const unsigned char* bitfield, int len) const;
@@ -176,6 +179,8 @@ public:
*/
int countBlock() const;
+ int getMaxIndex() const { return blocks-1; }
+
void setBitfield(const unsigned char* bitfield, int bitfieldLength);
void clearAllBit();
@@ -202,6 +207,14 @@ public:
* affected by filter
*/
long long int getFilteredCompletedLength() const;
+
+ void setRandomizer(const RandomizerHandle& randomizer) {
+ this->randomizer = randomizer;
+ }
+
+ RandomizerHandle getRandomizer() const {
+ return randomizer;
+ }
};
#endif // _D_BITFIELD_MAN_H_
diff --git a/src/BitfieldManFactory.cc b/src/BitfieldManFactory.cc
new file mode 100644
index 00000000..2ee68222
--- /dev/null
+++ b/src/BitfieldManFactory.cc
@@ -0,0 +1,40 @@
+/* <!-- 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 "BitfieldManFactory.h"
+#include "SimpleRandomizer.h"
+
+RandomizerHandle BitfieldManFactory::defaultRandomizer = SimpleRandomizer::getInstance();
+
+BitfieldManFactory::BitfieldManFactory():randomizer(defaultRandomizer) {}
diff --git a/src/BitfieldManFactory.h b/src/BitfieldManFactory.h
new file mode 100644
index 00000000..2e1af096
--- /dev/null
+++ b/src/BitfieldManFactory.h
@@ -0,0 +1,85 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BITFIELD_MAN_FACTORY_H_
+#define _D_BITFIELD_MAN_FACTORY_H_
+
+#include "common.h"
+#include "Randomizer.h"
+#include "BitfieldMan.h"
+
+class BitfieldManFactory;
+
+typedef SharedHandle<BitfieldManFactory> BitfieldManFactoryHandle;
+
+class BitfieldManFactory {
+private:
+ static RandomizerHandle defaultRandomizer;
+ RandomizerHandle randomizer;
+
+ BitfieldManFactory();
+public:
+ ~BitfieldManFactory() {}
+
+ static BitfieldManFactoryHandle getNewFactory() {
+ BitfieldManFactoryHandle factory =
+ BitfieldManFactoryHandle(new BitfieldManFactory());
+ factory->setRandomizer(defaultRandomizer);
+ return factory;
+ }
+
+ BitfieldMan* createBitfieldMan(int blockLength, long long int totalLength) {
+ BitfieldMan* bitfieldMan = new BitfieldMan(blockLength, totalLength);
+ bitfieldMan->setRandomizer(randomizer);
+ return bitfieldMan;
+ }
+
+ static void setDefaultRandomizer(const RandomizerHandle& randomizer) {
+ defaultRandomizer = randomizer;
+ }
+
+ static RandomizerHandle getDefaultRandomizer() {
+ return defaultRandomizer;
+ }
+
+ void setRandomizer(const RandomizerHandle& randomizer) {
+ this->randomizer = randomizer;
+ }
+
+ RandomizerHandle getRandomizer() const {
+ return randomizer;
+ }
+};
+
+#endif // _D_BITFIELD_MAN_FACTORY_H_
diff --git a/src/BtAbortOutstandingRequestEvent.h b/src/BtAbortOutstandingRequestEvent.h
new file mode 100644
index 00000000..6d334bae
--- /dev/null
+++ b/src/BtAbortOutstandingRequestEvent.h
@@ -0,0 +1,57 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_ABORT_OUTSTANDING_REQUEST_EVENT_H_
+#define _D_BT_ABORT_OUTSTANDING_REQUEST_EVENT_H_
+
+#include "BtEvent.h"
+
+class BtAbortOutstandingRequestEvent : public BtEvent {
+private:
+ PieceHandle piece;
+public:
+ BtAbortOutstandingRequestEvent(const PieceHandle& piece):piece(piece) {}
+
+ PieceHandle getPiece() const {
+ return piece;
+ }
+
+ void setPiece(const PieceHandle& piece) {
+ this->piece = piece;
+ }
+};
+
+typedef SharedHandle<BtAbortOutstandingRequestEvent> BtAbortOutstandingRequestEventHandle;
+
+#endif // _D_BT_ABORT_OUTSTANDING_REQUEST_EVENT_H_
diff --git a/src/BtAllowedFastMessage.cc b/src/BtAllowedFastMessage.cc
new file mode 100644
index 00000000..672a499c
--- /dev/null
+++ b/src/BtAllowedFastMessage.cc
@@ -0,0 +1,89 @@
+/* <!-- 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 "BtAllowedFastMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+BtAllowedFastMessageHandle BtAllowedFastMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 5) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "allowed fast", dataLength, 5);
+ }
+ uint32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "allowed fast", ID);
+ }
+ BtAllowedFastMessageHandle message = new BtAllowedFastMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ return message;
+}
+
+void BtAllowedFastMessage::doReceivedAction() {
+ if(!peer->isFastExtensionEnabled()) {
+ throw new DlAbortEx("%s received while fast extension is disabled",
+ toString().c_str());
+ }
+ peer->addPeerAllowedIndex(index);
+}
+
+uint32_t BtAllowedFastMessage::MESSAGE_LENGTH = 9;
+
+const char* BtAllowedFastMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 5, 4bytes
+ * id --- 17, 1byte
+ * piece index --- index, 4bytes
+ * total: 9bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 5, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ }
+ return msg;
+}
+
+uint32_t BtAllowedFastMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+void BtAllowedFastMessage::onSendComplete() {
+ peer->addAmAllowedIndex(index);
+}
+
+string BtAllowedFastMessage::toString() const {
+ return "allowed fast index="+Util::uitos(index);
+}
diff --git a/src/BtAllowedFastMessage.h b/src/BtAllowedFastMessage.h
new file mode 100644
index 00000000..8ace1619
--- /dev/null
+++ b/src/BtAllowedFastMessage.h
@@ -0,0 +1,85 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_ALLOWED_FAST_MESSAGE_H_
+#define _D_BT_ALLOWED_FAST_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtAllowedFastMessage;
+
+typedef SharedHandle<BtAllowedFastMessage> BtAllowedFastMessageHandle;
+
+class BtAllowedFastMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtAllowedFastMessage(uint32_t index = 0)
+ :SimpleBtMessage(),
+ index(index),
+ msg(0) {}
+
+ virtual ~BtAllowedFastMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 17
+ };
+
+ void setIndex(uint32_t index) {
+ this->index = index;
+ }
+ uint32_t getIndex() const { return index; }
+
+ static BtAllowedFastMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ virtual void onSendComplete();
+
+};
+
+#endif // _D_BT_ALLOWED_FAST_MESSAGE_H_
diff --git a/src/BtAllowedFastMessageValidator.h b/src/BtAllowedFastMessageValidator.h
new file mode 100644
index 00000000..b6668239
--- /dev/null
+++ b/src/BtAllowedFastMessageValidator.h
@@ -0,0 +1,60 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_ALLOWED_FAST_MESSAGE_VALIDATOR_H_
+#define _D_BT_ALLOWED_FAST_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtAllowedFastMessage.h"
+
+class BtAllowedFastMessageValidator : public BtMessageValidator {
+private:
+ const BtAllowedFastMessage* message;
+ uint32_t numPiece;
+public:
+ BtAllowedFastMessageValidator(const BtAllowedFastMessage* message,
+ uint32_t numPiece):
+ message(message),
+ numPiece(numPiece) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtAllowedFastMessageValidator> BtAllowedFastMessageValidatorHandle;
+
+#endif // _D_BT_ALLOWED_FAST_MESSAGE_VALIDATOR_H_
diff --git a/src/BtAnnounce.h b/src/BtAnnounce.h
index 3b9e735f..4288a6e4 100644
--- a/src/BtAnnounce.h
+++ b/src/BtAnnounce.h
@@ -99,11 +99,6 @@ public:
* Shuffles the URLs in each announce tier.
*/
virtual void shuffleAnnounce() = 0;
-
- /**
- * Returns the peer id of the client.
- */
- virtual string getPeerId() = 0;
};
typedef SharedHandle<BtAnnounce> BtAnnounceHandle;
diff --git a/src/BtBitfieldMessage.cc b/src/BtBitfieldMessage.cc
new file mode 100644
index 00000000..35d0894d
--- /dev/null
+++ b/src/BtBitfieldMessage.cc
@@ -0,0 +1,95 @@
+/* <!-- 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 "BtBitfieldMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+void BtBitfieldMessage::setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength) {
+ if(this->bitfield == bitfield) {
+ return;
+ }
+ delete [] this->bitfield;
+
+ this->bitfieldLength = bitfieldLength;
+ this->bitfield = new unsigned char[this->bitfieldLength];
+ memcpy(this->bitfield, bitfield, this->bitfieldLength);
+}
+
+BtBitfieldMessageHandle
+BtBitfieldMessage::create(const unsigned char* data, uint32_t dataLength)
+{
+ if(dataLength <= 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "bitfield", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "bitfield", ID);
+ }
+ BtBitfieldMessageHandle message = new BtBitfieldMessage();
+ message->setBitfield((unsigned char*)data+1, dataLength-1);
+ return message;
+}
+
+void BtBitfieldMessage::doReceivedAction() {
+ peer->setBitfield(bitfield, bitfieldLength);
+}
+
+const char* BtBitfieldMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1+bitfieldLength, 4bytes
+ * id --- 5, 1byte
+ * bitfield --- bitfield, len bytes
+ * total: 5+len bytes
+ */
+ msgLength = 5+bitfieldLength;
+ msg = new char[msgLength];
+ PeerMessageUtil::createPeerMessageString(msg, msgLength,
+ 1+bitfieldLength, ID);
+ memcpy(msg+5, bitfield, bitfieldLength);
+ }
+ return msg;
+}
+
+uint32_t BtBitfieldMessage::getMessageLength() {
+ getMessage();
+ return msgLength;
+}
+
+string BtBitfieldMessage::toString() const {
+ return "bitfield "+Util::toHex(bitfield, bitfieldLength);
+}
diff --git a/src/BtBitfieldMessage.h b/src/BtBitfieldMessage.h
new file mode 100644
index 00000000..15bc13aa
--- /dev/null
+++ b/src/BtBitfieldMessage.h
@@ -0,0 +1,98 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_BITFIELD_MESSAGE_H_
+#define _D_BT_BITFIELD_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtBitfieldMessage;
+
+typedef SharedHandle<BtBitfieldMessage> BtBitfieldMessageHandle;
+
+class BtBitfieldMessage : public SimpleBtMessage {
+private:
+ unsigned char* bitfield;
+ uint32_t bitfieldLength;
+ char* msg;
+ int msgLength;
+
+ void init() {
+ bitfield = 0;
+ bitfieldLength = 0;
+ msg = 0;
+ msgLength = 0;
+ }
+public:
+ BtBitfieldMessage():SimpleBtMessage()
+ {
+ init();
+ }
+
+ BtBitfieldMessage(const unsigned char* bitfield,
+ uint32_t bitfieldLength):SimpleBtMessage()
+ {
+ init();
+ setBitfield(bitfield, bitfieldLength);
+ }
+
+ virtual ~BtBitfieldMessage() {
+ delete [] bitfield;
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 5
+ };
+
+ void setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength);
+
+ const unsigned char* getBitfield() const { return bitfield; }
+
+ uint32_t getBitfieldLength() const { return bitfieldLength; }
+
+ static BtBitfieldMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_BITFIELD_MESSAGE_H_
diff --git a/src/BtBitfieldMessageValidator.h b/src/BtBitfieldMessageValidator.h
new file mode 100644
index 00000000..d7a8ddb0
--- /dev/null
+++ b/src/BtBitfieldMessageValidator.h
@@ -0,0 +1,61 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_BITFIELD_MESSAGE_VALIDATOR_H_
+#define _D_BT_BITFIELD_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtBitfieldMessage.h"
+
+class BtBitfieldMessageValidator : public BtMessageValidator {
+private:
+ const BtBitfieldMessage* message;
+ int numPiece;
+public:
+ BtBitfieldMessageValidator(const BtBitfieldMessage* message,
+ int numPiece):
+ message(message),
+ numPiece(numPiece) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkBitfield(message->getBitfield(),
+ message->getBitfieldLength(),
+ numPiece);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtBitfieldMessageValidator> BtBitfieldMessageValidatorHandle;
+#endif // _D_BT_BITFIELD_MESSAGE_VALIDATOR_H_
diff --git a/src/BtCancelMessage.cc b/src/BtCancelMessage.cc
new file mode 100644
index 00000000..ec2f2447
--- /dev/null
+++ b/src/BtCancelMessage.cc
@@ -0,0 +1,88 @@
+/* <!-- 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 "BtCancelMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+BtCancelMessageHandle BtCancelMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 13) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "cancel", dataLength, 13);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "cancel", ID);
+ }
+ BtCancelMessageHandle message = new BtCancelMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ message->setBegin(PeerMessageUtil::getIntParam(data, 5));
+ message->setLength(PeerMessageUtil::getIntParam(data, 9));
+ return message;
+}
+
+void BtCancelMessage::doReceivedAction() {
+ BT_MESSAGE_DISPATCHER(btContext, peer)->doCancelSendingPieceAction(index, begin, length);
+}
+
+uint32_t BtCancelMessage::MESSAGE_LENGTH = 17;
+
+const char* BtCancelMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 13, 4bytes
+ * id --- 8, 1byte
+ * index --- index, 4bytes
+ * begin --- begin, 4bytes
+ * length -- length, 4bytes
+ * total: 17bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 13, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ PeerMessageUtil::setIntParam(&msg[9], begin);
+ PeerMessageUtil::setIntParam(&msg[13], length);
+ }
+ return msg;
+}
+
+uint32_t BtCancelMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtCancelMessage::toString() const {
+ return "cancel index="+Util::uitos(index)+", begin="+Util::uitos(begin)+
+ ", length="+Util::uitos(length);
+}
diff --git a/src/BtCancelMessage.h b/src/BtCancelMessage.h
new file mode 100644
index 00000000..ceee62fb
--- /dev/null
+++ b/src/BtCancelMessage.h
@@ -0,0 +1,93 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CANCEL_MESSAGE_H_
+#define _D_BT_CANCEL_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtCancelMessage;
+
+typedef SharedHandle<BtCancelMessage> BtCancelMessageHandle;
+
+class BtCancelMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ uint32_t begin;
+ uint32_t length;
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtCancelMessage(uint32_t index = 0, uint32_t begin = 0, uint32_t length = 0)
+ :SimpleBtMessage(),
+ index(index),
+ begin(begin),
+ length(length),
+ msg(0) {}
+
+ virtual ~BtCancelMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 8
+ };
+
+ uint32_t getIndex() const { return index; }
+
+ void setIndex(uint32_t index) { this->index = index; }
+
+ uint32_t getBegin() const { return begin; }
+
+ void setBegin(uint32_t begin) { this->begin = begin; }
+
+ uint32_t getLength() const { return length; }
+
+ void setLength(uint32_t length) { this->length = length; }
+
+ static BtCancelMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_CANCEL_MESSAGE_H_
diff --git a/src/BtCancelMessageValidator.h b/src/BtCancelMessageValidator.h
new file mode 100644
index 00000000..af453fa8
--- /dev/null
+++ b/src/BtCancelMessageValidator.h
@@ -0,0 +1,67 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CANCEL_MESSAGE_VALIDATOR_H_
+#define _D_BT_CANCEL_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtCancelMessage.h"
+
+class BtCancelMessageValidator : public BtMessageValidator {
+private:
+ const BtCancelMessage* message;
+ uint32_t numPiece;
+ uint32_t pieceLength;
+public:
+ BtCancelMessageValidator(const BtCancelMessage* message,
+ uint32_t numPiece,
+ uint32_t pieceLength):
+ message(message),
+ numPiece(numPiece),
+ pieceLength(pieceLength) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ PeerMessageUtil::checkBegin(message->getBegin(), pieceLength);
+ PeerMessageUtil::checkLength(message->getLength());
+ PeerMessageUtil::checkRange(message->getBegin(), message->getLength(),
+ pieceLength);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtCancelMessageValidator> BtCancelMessageValidatorHandle;
+
+#endif // _D_BT_CANCEL_MESSAGE_VALIDATOR_H_
diff --git a/src/BtCancelSendingPieceEvent.h b/src/BtCancelSendingPieceEvent.h
new file mode 100644
index 00000000..90dbb936
--- /dev/null
+++ b/src/BtCancelSendingPieceEvent.h
@@ -0,0 +1,78 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CANCEL_SENDING_PIECE_EVENT_H_
+#define _D_BT_CANCEL_SENDING_PIECE_EVENT_H_
+
+#include "BtEvent.h"
+
+class BtCancelSendingPieceEvent : public BtEvent {
+private:
+ uint32_t index;
+ uint32_t begin;
+ uint32_t length;
+public:
+ BtCancelSendingPieceEvent(uint32_t index, uint32_t begin, uint32_t length):
+ index(index), begin(begin), length(length) {}
+
+ virtual ~BtCancelSendingPieceEvent() {}
+
+ void setIndex(uint32_t index) {
+ this->index = index;
+ }
+
+ uint32_t getIndex() const {
+ return index;
+ }
+
+ void setBegin(uint32_t begin) {
+ this->begin = begin;
+ }
+
+ uint32_t getBegin() const {
+ return begin;
+ }
+
+ void setLength(uint32_t length) {
+ this->length = length;
+ }
+
+ uint32_t getLength() const {
+ return length;
+ }
+};
+
+typedef SharedHandle<BtCancelSendingPieceEvent> BtCancelSendingPieceEventHandle;
+
+#endif // _D_BT_CANCEL_SENDING_PIECE_EVENT_H_
diff --git a/src/BtChokeMessage.cc b/src/BtChokeMessage.cc
new file mode 100644
index 00000000..09465511
--- /dev/null
+++ b/src/BtChokeMessage.cc
@@ -0,0 +1,87 @@
+/* <!-- 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 "BtChokeMessage.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+
+BtChokeMessageHandle BtChokeMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "choke", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "choke", ID);
+ }
+ BtChokeMessageHandle chokeMessage = new BtChokeMessage();
+ return chokeMessage;
+}
+
+void BtChokeMessage::doReceivedAction() {
+ peer->peerChoking = true;
+ BT_MESSAGE_DISPATCHER(btContext, peer)->doChokedAction();
+}
+
+bool BtChokeMessage::sendPredicate() const {
+ return !peer->amChoking;
+}
+
+uint32_t BtChokeMessage::MESSAGE_LENGTH = 5;
+
+const char* BtChokeMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 0, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtChokeMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+void BtChokeMessage::onSendComplete() {
+ peer->amChoking = true;
+ BT_MESSAGE_DISPATCHER(btContext, peer)->doChokingAction();
+}
+
+string BtChokeMessage::toString() const {
+ return "choke";
+}
diff --git a/src/BtChokeMessage.h b/src/BtChokeMessage.h
new file mode 100644
index 00000000..b8ee8fee
--- /dev/null
+++ b/src/BtChokeMessage.h
@@ -0,0 +1,77 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CHOKE_MESSAGE_H_
+#define _D_BT_CHOKE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtChokeMessage;
+
+typedef SharedHandle<BtChokeMessage> BtChokeMessageHandle;
+
+class BtChokeMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtChokeMessage():SimpleBtMessage(), msg(0) {}
+
+ virtual ~BtChokeMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 0
+ };
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ static BtChokeMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual bool sendPredicate() const;
+
+ virtual void onSendComplete();
+};
+
+#endif // _D_CHOKE_MESSAGE_H_
diff --git a/src/BtChokedEvent.h b/src/BtChokedEvent.h
new file mode 100644
index 00000000..8fbd293e
--- /dev/null
+++ b/src/BtChokedEvent.h
@@ -0,0 +1,45 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CHOKED_EVENT_H_
+#define _D_BT_CHOKED_EVENT_H_
+
+#include "BtEvent.h"
+
+class BtChokedEvent : public BtEvent {
+};
+
+typedef SharedHandle<BtChokedEvent> BtChokedEventHandle;
+
+#endif // _D_BT_CHOKED_EVENT_H_
diff --git a/src/BtChokingEvent.h b/src/BtChokingEvent.h
new file mode 100644
index 00000000..36d852dd
--- /dev/null
+++ b/src/BtChokingEvent.h
@@ -0,0 +1,45 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CHOKING_EVENT_H_
+#define _D_BT_CHOKING_EVENT_H_
+
+#include "BtEvent.h"
+
+class BtChokingEvent : public BtEvent {
+};
+
+typedef SharedHandle<BtChokingEvent> BtChokingEventHandle;
+
+#endif // _D_BT_CHOKING_EVENT_H_
diff --git a/src/BtContext.h b/src/BtContext.h
index ad05c4f8..7ab6197e 100644
--- a/src/BtContext.h
+++ b/src/BtContext.h
@@ -77,6 +77,11 @@ public:
virtual int getPieceLength() const = 0;
virtual int getNumPieces() const = 0;
+
+ /**
+ * Returns the peer id of localhost, 20 byte length
+ */
+ virtual const unsigned char* getPeerId() = 0;
};
typedef SharedHandle<BtContext> BtContextHandle;
diff --git a/src/BtEvent.h b/src/BtEvent.h
new file mode 100644
index 00000000..fd80729a
--- /dev/null
+++ b/src/BtEvent.h
@@ -0,0 +1,47 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_EVENT_H_
+#define _D_BT_EVENT_H_
+
+#include "common.h"
+
+class BtEvent {
+public:
+ virtual ~BtEvent() {}
+};
+
+typedef SharedHandle<BtEvent> BtEventHandle;
+
+#endif // _D_BT_EVENT_H_
diff --git a/src/BtEventListener.h b/src/BtEventListener.h
new file mode 100644
index 00000000..2d99c910
--- /dev/null
+++ b/src/BtEventListener.h
@@ -0,0 +1,51 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_EVENT_LISTENER_H_
+#define _D_BT_EVENT_LISTENER_H_
+
+#include "common.h"
+#include "BtEvent.h"
+
+class BtEventListener {
+public:
+ virtual ~BtEventListener() {}
+
+ virtual void handleEvent(const BtEventHandle& event) = 0;
+};
+
+typedef SharedHandle<BtEventListener> BtEventListenerHandle;
+typedef deque<BtEventListenerHandle> BtEventListeners;
+
+#endif // _D_BT_EVENT_LISTENER_H_
diff --git a/src/BtHandshakeMessage.cc b/src/BtHandshakeMessage.cc
new file mode 100644
index 00000000..3cedc217
--- /dev/null
+++ b/src/BtHandshakeMessage.cc
@@ -0,0 +1,100 @@
+/* <!-- 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 "BtHandshakeMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+
+const unsigned char* BtHandshakeMessage::BT_PSTR = (const unsigned char*)"BitTorrent protocol";
+
+BtHandshakeMessage::BtHandshakeMessage() {
+ init();
+}
+
+BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash,
+ const unsigned char* peerId)
+{
+ init();
+ memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
+ memcpy(this->peerId, peerId, PEER_ID_LENGTH);
+}
+
+void BtHandshakeMessage::init() {
+ msg = 0;
+ this->pstrlen = 19;
+ pstr = new unsigned char[PSTR_LENGTH];
+ reserved = new unsigned char[RESERVED_LENGTH];
+ infoHash = new unsigned char[INFO_HASH_LENGTH];
+ peerId = new unsigned char[PEER_ID_LENGTH];
+ memcpy(this->pstr, PSTR, PSTR_LENGTH);
+ memset(this->reserved, 0, RESERVED_LENGTH);
+ // fast extension
+ this->reserved[7] |= 0x04;
+}
+
+BtHandshakeMessageHandle BtHandshakeMessage::create(const unsigned char* data, uint32_t dataLength) {
+ BtHandshakeMessageHandle message = new BtHandshakeMessage();
+ message->pstrlen = data[0];
+ memcpy(message->pstr, &data[1], PSTR_LENGTH);
+ memcpy(message->reserved, &data[20], RESERVED_LENGTH);
+ memcpy(message->infoHash, &data[28], INFO_HASH_LENGTH);
+ memcpy(message->peerId, &data[48], PEER_ID_LENGTH);
+ return message;
+}
+
+const char* BtHandshakeMessage::getMessage() {
+ if(!msg) {
+ msg = new char[MESSAGE_LENGTH];
+ msg[0] = pstrlen;
+ memcpy(msg+1, pstr, PSTR_LENGTH);
+ memcpy(msg+20, reserved, RESERVED_LENGTH);
+ memcpy(msg+28, infoHash, INFO_HASH_LENGTH);
+ memcpy(msg+48, peerId, PEER_ID_LENGTH);
+ }
+ return msg;
+}
+
+uint32_t BtHandshakeMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtHandshakeMessage::toString() const {
+ return "handshake peerId="+
+ Util::urlencode(peerId, PEER_ID_LENGTH)+
+ ", reserved="+Util::toHex(reserved, RESERVED_LENGTH);
+}
+
+bool BtHandshakeMessage::isFastExtensionSupported() const {
+ return reserved[7]&0x04;
+}
diff --git a/src/BtHandshakeMessage.h b/src/BtHandshakeMessage.h
new file mode 100644
index 00000000..427343ab
--- /dev/null
+++ b/src/BtHandshakeMessage.h
@@ -0,0 +1,117 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HANDSHAKE_MESSAGE_H_
+#define _D_BT_HANDSHAKE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtHandshakeMessage;
+
+typedef SharedHandle<BtHandshakeMessage> BtHandshakeMessageHandle;
+
+class BtHandshakeMessage : public SimpleBtMessage {
+public:
+ static const uint32_t PSTR_LENGTH = 19;
+ static const unsigned char* BT_PSTR;
+ static const uint32_t RESERVED_LENGTH = 8;
+ static const uint32_t MESSAGE_LENGTH = 68;
+private:
+ uint8_t pstrlen;
+ unsigned char* pstr;
+ unsigned char* reserved;
+ unsigned char* infoHash;
+ unsigned char* peerId;
+ char* msg;
+ void init();
+public:
+ BtHandshakeMessage();
+ /**
+ * infoHash must be 20 byte length.
+ * peerId must be 20 byte length.
+ */
+ BtHandshakeMessage(const unsigned char* infoHash, const unsigned char* peerId);
+
+ static BtHandshakeMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual ~BtHandshakeMessage() {
+ delete [] msg;
+ delete [] pstr;
+ delete [] reserved;
+ delete [] infoHash;
+ delete [] peerId;
+ }
+
+ virtual int32_t getId() const { return INT32_MAX; }
+
+ virtual void doReceivedAction() {};
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ bool isFastExtensionSupported() const;
+
+ uint8_t getPstrlen() const {
+ return pstrlen;
+ }
+
+ const unsigned char* getPstr() const {
+ return pstr;
+ }
+
+ const unsigned char* getReserved() const {
+ return reserved;
+ }
+
+ const unsigned char* getInfoHash() const {
+ return infoHash;
+ }
+
+ void setInfoHash(const unsigned char* infoHash) {
+ memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
+ }
+
+ const unsigned char* getPeerId() const {
+ return peerId;
+ }
+
+ void setPeerId(const unsigned char* peerId) {
+ memcpy(this->peerId, peerId, PEER_ID_LENGTH);
+ }
+};
+
+#endif // _D_HANDSHAKE_MESSAGE_H_
diff --git a/src/BtHandshakeMessageValidator.h b/src/BtHandshakeMessageValidator.h
new file mode 100644
index 00000000..e06d224b
--- /dev/null
+++ b/src/BtHandshakeMessageValidator.h
@@ -0,0 +1,75 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HANDSHAKE_MESSAGE_VALIDATOR_H_
+#define _D_BT_HANDSHAKE_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtHandshakeMessage.h"
+#include "Util.h"
+
+class BtHandshakeMessageValidator : public BtMessageValidator {
+private:
+ const BtHandshakeMessage* message;
+ unsigned char infoHash[20];
+public:
+ BtHandshakeMessageValidator(const BtHandshakeMessage* message,
+ const unsigned char* infoHash):
+ message(message)
+ {
+ memcpy(this->infoHash, infoHash, sizeof(this->infoHash));
+ }
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ if(message->getPstrlen() != 19) {
+ throw new DlAbortEx("invalid handshake pstrlen=%u",
+ message->getPstrlen());
+ }
+ if(memcmp(BtHandshakeMessage::BT_PSTR, message->getPstr(), 19) != 0) {
+ throw new DlAbortEx("invalid handshake pstr=%s",
+ Util::urlencode(message->getPstr(), 19).c_str());
+ }
+ if(memcmp(infoHash, message->getInfoHash(), 20) != 0) {
+ throw new DlAbortEx("invalid handshake info hash: expected:%s, actual:%s",
+ Util::toHex(infoHash, 20).c_str(),
+ Util::toHex(message->getInfoHash(), 20).c_str());
+ }
+ return true;
+ }
+};
+
+typedef SharedHandle<BtHandshakeMessageValidator> BtHandshakeMessageValidatorHandle;
+
+#endif // _D_BT_HANDSHAKE_MESSAGE_VALIDATOR_H_
diff --git a/src/BtHaveAllMessage.cc b/src/BtHaveAllMessage.cc
new file mode 100644
index 00000000..a8d2c671
--- /dev/null
+++ b/src/BtHaveAllMessage.cc
@@ -0,0 +1,81 @@
+/* <!-- 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 "BtHaveAllMessage.h"
+#include "DlAbortEx.h"
+#include "PeerMessageUtil.h"
+
+BtHaveAllMessageHandle BtHaveAllMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have all", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "have all", ID);
+ }
+ BtHaveAllMessageHandle message = new BtHaveAllMessage();
+ return message;
+}
+
+void BtHaveAllMessage::doReceivedAction() {
+ if(!peer->isFastExtensionEnabled()) {
+ throw new DlAbortEx("%s received while fast extension is disabled",
+ toString().c_str());
+ }
+ peer->setAllBitfield();
+}
+
+uint32_t BtHaveAllMessage::MESSAGE_LENGTH = 5;
+
+const char* BtHaveAllMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 14, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtHaveAllMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtHaveAllMessage::toString() const {
+ return "have all";
+}
diff --git a/src/BtHaveAllMessage.h b/src/BtHaveAllMessage.h
new file mode 100644
index 00000000..bce5dc85
--- /dev/null
+++ b/src/BtHaveAllMessage.h
@@ -0,0 +1,73 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HAVE_ALL_MESSAGE_H_
+#define _D_BT_HAVE_ALL_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtHaveAllMessage;
+
+typedef SharedHandle<BtHaveAllMessage> BtHaveAllMessageHandle;
+
+class BtHaveAllMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtHaveAllMessage():msg(0) {}
+
+ virtual ~BtHaveAllMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 14
+ };
+
+ static BtHaveAllMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_HAVE_ALL_MESSAGE_H_
diff --git a/src/BtHaveMessage.cc b/src/BtHaveMessage.cc
new file mode 100644
index 00000000..fdcda7fa
--- /dev/null
+++ b/src/BtHaveMessage.cc
@@ -0,0 +1,85 @@
+/* <!-- 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 "BtHaveMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+BtHaveMessageHandle BtHaveMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 5) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have", dataLength, 5);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "have", ID);
+ }
+ BtHaveMessageHandle message = new BtHaveMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ return message;
+}
+
+void BtHaveMessage::doReceivedAction() {
+ peer->updateBitfield(index, 1);
+}
+
+bool BtHaveMessage::sendPredicate() const {
+ return !peer->hasPiece(index);
+}
+
+uint32_t BtHaveMessage::MESSAGE_LENGTH = 9;
+
+const char* BtHaveMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 5, 4bytes
+ * id --- 4, 1byte
+ * piece index --- index, 4bytes
+ * total: 9bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 5, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ }
+ return msg;
+}
+
+uint32_t BtHaveMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtHaveMessage::toString() const {
+ return "have index="+Util::uitos(index);
+}
diff --git a/src/BtHaveMessage.h b/src/BtHaveMessage.h
new file mode 100644
index 00000000..e0ad84e2
--- /dev/null
+++ b/src/BtHaveMessage.h
@@ -0,0 +1,81 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HAVE_MESSAGE_H_
+#define _D_BT_HAVE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtHaveMessage;
+
+typedef SharedHandle<BtHaveMessage> BtHaveMessageHandle;
+
+class BtHaveMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ char* msg;
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtHaveMessage(uint32_t index = 0):index(index), msg(0) {}
+
+ virtual ~BtHaveMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 4
+ };
+
+ void setIndex(uint32_t index) {
+ this->index = index;
+ }
+
+ uint32_t getIndex() const { return index; }
+
+ static BtHaveMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual bool sendPredicate() const;
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_HAVE_MESSAGE_H_
diff --git a/src/BtHaveMessageValidator.h b/src/BtHaveMessageValidator.h
new file mode 100644
index 00000000..acf2b351
--- /dev/null
+++ b/src/BtHaveMessageValidator.h
@@ -0,0 +1,60 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HAVE_MESSAGE_VALIDATOR_H_
+#define _D_BT_HAVE_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtHaveMessage.h"
+#include "PeerMessageUtil.h"
+
+class BtHaveMessageValidator : public BtMessageValidator {
+private:
+ const BtHaveMessage* message;
+ int numPiece;
+public:
+ BtHaveMessageValidator(const BtHaveMessage* message,
+ int numPiece):
+ message(message),
+ numPiece(numPiece) {}
+
+ virtual bool validate(Errors& errors) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ return true;
+ }
+
+};
+
+#endif // _D_BT_HAVE_MESSAGE_VALIDATOR_H_
diff --git a/src/BtHaveNoneMessage.cc b/src/BtHaveNoneMessage.cc
new file mode 100644
index 00000000..e501f56f
--- /dev/null
+++ b/src/BtHaveNoneMessage.cc
@@ -0,0 +1,80 @@
+/* <!-- 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 "BtHaveNoneMessage.h"
+#include "DlAbortEx.h"
+#include "PeerMessageUtil.h"
+
+BtHaveNoneMessageHandle BtHaveNoneMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have none", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "have none", ID);
+ }
+ BtHaveNoneMessageHandle message = new BtHaveNoneMessage();
+ return message;
+}
+
+void BtHaveNoneMessage::doReceivedAction() {
+ if(!peer->isFastExtensionEnabled()) {
+ throw new DlAbortEx("%s received while fast extension is disabled",
+ toString().c_str());
+ }
+}
+
+uint32_t BtHaveNoneMessage::MESSAGE_LENGTH = 5;
+
+const char* BtHaveNoneMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 15, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtHaveNoneMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtHaveNoneMessage::toString() const {
+ return "have none";
+}
diff --git a/src/BtHaveNoneMessage.h b/src/BtHaveNoneMessage.h
new file mode 100644
index 00000000..ca77d5c5
--- /dev/null
+++ b/src/BtHaveNoneMessage.h
@@ -0,0 +1,73 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_HAVE_NONE_MESSAGE_H_
+#define _D_BT_HAVE_NONE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtHaveNoneMessage;
+
+typedef SharedHandle<BtHaveNoneMessage> BtHaveNoneMessageHandle;
+
+class BtHaveNoneMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtHaveNoneMessage():msg(0) {}
+
+ virtual ~BtHaveNoneMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 15
+ };
+
+ static BtHaveNoneMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_HAVE_NONE_MESSAGE_H_
diff --git a/src/BtInteractive.h b/src/BtInteractive.h
new file mode 100644
index 00000000..8c493bc0
--- /dev/null
+++ b/src/BtInteractive.h
@@ -0,0 +1,66 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_INTERACTIVE_H_
+#define _D_BT_INTERACTIVE_H_
+
+#include "common.h"
+#include "BtMessage.h"
+
+class BtInteractive {
+public:
+ virtual ~BtInteractive() {}
+
+ virtual void initiateHandshake() = 0;
+
+ virtual BtMessageHandle receiveHandshake(bool quickReply = false) = 0;
+
+ virtual BtMessageHandle receiveAndSendHandshake() = 0;
+
+ virtual void doPostHandshakeProcessing() = 0;
+
+ virtual void doInteractionProcessing() = 0;
+
+ virtual void cancelAllPiece() = 0;
+
+ virtual void sendPendingMessage() = 0;
+
+ virtual uint32_t countPendingMessage() = 0;
+
+ virtual bool isSendingMessageInProgress() = 0;
+};
+
+typedef SharedHandle<BtInteractive> BtInteractiveHandle;
+
+#endif // _D_BT_INTERACTIVE_H_
diff --git a/src/BtInterestedMessage.cc b/src/BtInterestedMessage.cc
new file mode 100644
index 00000000..c3680042
--- /dev/null
+++ b/src/BtInterestedMessage.cc
@@ -0,0 +1,85 @@
+/* <!-- 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 "BtInterestedMessage.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+
+BtInterestedMessageHandle BtInterestedMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "interested", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "interested", ID);
+ }
+ BtInterestedMessageHandle message = new BtInterestedMessage();
+ return message;
+}
+
+void BtInterestedMessage::doReceivedAction() {
+ peer->peerInterested = true;
+}
+
+bool BtInterestedMessage::sendPredicate() const {
+ return !peer->amInterested;
+}
+
+uint32_t BtInterestedMessage::MESSAGE_LENGTH = 5;
+
+const char* BtInterestedMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 2, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtInterestedMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+void BtInterestedMessage::onSendComplete() {
+ peer->amInterested = true;
+}
+
+string BtInterestedMessage::toString() const {
+ return "interested";
+}
diff --git a/src/BtInterestedMessage.h b/src/BtInterestedMessage.h
new file mode 100644
index 00000000..3a7b27b7
--- /dev/null
+++ b/src/BtInterestedMessage.h
@@ -0,0 +1,77 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_INTERESTED_MESSAGE_H_
+#define _D_BT_INTERESTED_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtInterestedMessage;
+
+typedef SharedHandle<BtInterestedMessage> BtInterestedMessageHandle;
+
+class BtInterestedMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtInterestedMessage():msg(0) {}
+
+ virtual ~BtInterestedMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 2
+ };
+
+ static BtInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ virtual bool sendPredicate() const;
+
+ virtual void onSendComplete();
+};
+
+#endif // _D_BT_INTERESTED_MESSAGE_H_
diff --git a/src/BtKeepAliveMessage.cc b/src/BtKeepAliveMessage.cc
new file mode 100644
index 00000000..ae9d4a3e
--- /dev/null
+++ b/src/BtKeepAliveMessage.cc
@@ -0,0 +1,53 @@
+/* <!-- 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 "BtKeepAliveMessage.h"
+
+uint32_t BtKeepAliveMessage::MESSAGE_LENGTH = 4;
+
+const char* BtKeepAliveMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 0, 4bytes
+ * total: 4bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ memset(msg, 0, MESSAGE_LENGTH);
+ }
+ return msg;
+}
+
+uint32_t BtKeepAliveMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
diff --git a/src/BtKeepAliveMessage.h b/src/BtKeepAliveMessage.h
new file mode 100644
index 00000000..9044dfe9
--- /dev/null
+++ b/src/BtKeepAliveMessage.h
@@ -0,0 +1,73 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_KEEP_ALIVE_MESSAGE_H_
+#define _D_BT_KEEP_ALIVE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtKeepAliveMessage;
+
+typedef SharedHandle<BtKeepAliveMessage> BtKeepAliveMessageHandle;
+
+class BtKeepAliveMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtKeepAliveMessage():msg(0) {}
+
+ virtual ~BtKeepAliveMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 99
+ };
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction() {}
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const {
+ return "keep alive";
+ }
+};
+
+#endif // _D_BT_KEEP_ALIVE_MESSAGE_H_
diff --git a/src/BtMessage.h b/src/BtMessage.h
new file mode 100644
index 00000000..0a135fec
--- /dev/null
+++ b/src/BtMessage.h
@@ -0,0 +1,72 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_MESSAGE_H_
+#define _D_BT_MESSAGE_H_
+
+#include "common.h"
+#include "Piece.h"
+#include "BtMessageValidator.h"
+#include "BtEvent.h"
+
+class BtMessage {
+public:
+ virtual ~BtMessage() {}
+
+ virtual bool isSendingInProgress() = 0;
+
+ virtual bool isInvalidate() = 0;
+
+ virtual bool isUploading() = 0;
+
+ virtual int32_t getId() = 0;
+
+ virtual void doReceivedAction() = 0;
+
+ virtual void send() = 0;
+
+ virtual bool validate(Errors& errors) = 0;
+
+ virtual void handleEvent(const BtEventHandle& event) = 0;
+
+ virtual void onQueued() = 0;
+
+ virtual string toString() const = 0;
+
+};
+
+typedef SharedHandle<BtMessage> BtMessageHandle;
+typedef deque<BtMessageHandle> BtMessages;
+
+#endif // _D_BT_MESSAGE_H_
diff --git a/src/BtMessageDispatcher.h b/src/BtMessageDispatcher.h
new file mode 100644
index 00000000..7f3ebec2
--- /dev/null
+++ b/src/BtMessageDispatcher.h
@@ -0,0 +1,82 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_MESSAGE_DISPATCHER_H_
+#define _D_BT_MESSAGE_DISPATCHER_H_
+
+#include "common.h"
+#include "Piece.h"
+#include "BtMessage.h"
+#include "RequestSlot.h"
+
+class BtMessageDispatcher {
+public:
+ virtual ~BtMessageDispatcher() {}
+
+ virtual void addMessageToQueue(const BtMessageHandle& btMessage) = 0;
+
+ virtual void addMessageToQueue(const BtMessages& btMessages) = 0;
+
+ virtual void sendMessages() = 0;
+
+ virtual void doCancelSendingPieceAction(uint32_t index, uint32_t begin, uint32_t blockLength) = 0;
+
+ virtual void doCancelSendingPieceAction(const PieceHandle& piece) = 0;
+
+ virtual void doAbortOutstandingRequestAction(const PieceHandle& piece) = 0;
+
+ virtual void doChokedAction() = 0;
+
+ virtual void doChokingAction() = 0;
+
+ virtual void checkRequestSlotAndDoNecessaryThing() = 0;
+
+ virtual bool isSendingInProgress() = 0;
+
+ virtual uint32_t countMessageInQueue() = 0;
+
+ virtual uint32_t countOutstandingRequest() = 0;
+
+ virtual bool isOutstandingRequest(uint32_t index, uint32_t blockIndex) = 0;
+
+ virtual RequestSlot getOutstandingRequest(uint32_t index, uint32_t begin, uint32_t blockLength) = 0;
+
+ virtual void removeOutstandingRequest(const RequestSlot& slot) = 0;
+
+ virtual void addOutstandingRequest(const RequestSlot& slot) = 0;
+};
+
+typedef SharedHandle<BtMessageDispatcher> BtMessageDispatcherHandle;
+
+#endif // _D_BT_MESSAGE_DISPATCHER_H_
diff --git a/src/BtMessageFactory.cc b/src/BtMessageFactory.cc
new file mode 100644
index 00000000..2677c7b0
--- /dev/null
+++ b/src/BtMessageFactory.cc
@@ -0,0 +1,53 @@
+/* <!-- 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 "BtMessageFactory.h"
+#include "DefaultBtMessageFactory.h"
+
+void BtMessageFactory::registerFactory(const string& key,
+ const BtMessageFactoryPrerequisiteHandle& prereq) {
+ prerequisiteMap.erase(key);
+ BtMessageFactoryPrerequisiteMap::value_type p(key, prereq);
+ prerequisiteMap.insert(p);
+}
+
+static BtMessageFactory::BtMessageFactoryHandle getNewFactory(const string& key) {
+ DefaultBtMessageFactoryHandle factory = new DefaultBtMessageFactory();
+ BtMessageFactoryPrerequisiteMap::iterator itr = prerequisiteMap.find(key);
+ if(prerequisiteMap.end() != itr) {
+ // TODO set prerequisite objects to factory here
+ }
+ return factory;
+}
+
diff --git a/src/BtMessageFactory.h b/src/BtMessageFactory.h
new file mode 100644
index 00000000..1dd73afa
--- /dev/null
+++ b/src/BtMessageFactory.h
@@ -0,0 +1,91 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_MESSAGE_FACTORY_H_
+#define _D_BT_MESSAGE_FACTORY_H_
+
+#include "common.h"
+#include "BtMessage.h"
+#include "Piece.h"
+
+class BtMessageFactory {
+public:
+ virtual ~BtMessageFactory() {}
+
+ virtual BtMessageHandle
+ createBtMessage(const unsigned char* msg, uint32_t msgLength) = 0;
+
+ virtual BtMessageHandle
+ createHandshakeMessage(const unsigned char* msg, uint32_t msgLength) = 0;
+
+ virtual BtMessageHandle
+ createHandshakeMessage(const unsigned char* infoHash,
+ const unsigned char* peerId) = 0;
+
+ virtual BtMessageHandle
+ createRequestMessage(const PieceHandle& piece, uint32_t blockIndex) = 0;
+
+ virtual BtMessageHandle
+ createCancelMessage(uint32_t index, uint32_t begin, uint32_t length) = 0;
+
+ virtual BtMessageHandle
+ createPieceMessage(uint32_t index, uint32_t begin, uint32_t length) = 0;
+
+ virtual BtMessageHandle createHaveMessage(uint32_t index) = 0;
+
+ virtual BtMessageHandle createChokeMessage() = 0;
+
+ virtual BtMessageHandle createUnchokeMessage() = 0;
+
+ virtual BtMessageHandle createInterestedMessage() = 0;
+
+ virtual BtMessageHandle createNotInterestedMessage() = 0;
+
+ virtual BtMessageHandle createBitfieldMessage() = 0;
+
+ virtual BtMessageHandle createKeepAliveMessage() = 0;
+
+ virtual BtMessageHandle createHaveAllMessage() = 0;
+
+ virtual BtMessageHandle createHaveNoneMessage() = 0;
+
+ virtual BtMessageHandle
+ createRejectMessage(uint32_t index, uint32_t begin, uint32_t length) = 0;
+
+ virtual BtMessageHandle createAllowedFastMessage(uint32_t index) = 0;
+};
+
+typedef SharedHandle<BtMessageFactory> BtMessageFactoryHandle;
+
+#endif // _D_BT_MESSAGE_FACTORY_H_
diff --git a/src/BtMessageReceiver.h b/src/BtMessageReceiver.h
new file mode 100644
index 00000000..d39a128f
--- /dev/null
+++ b/src/BtMessageReceiver.h
@@ -0,0 +1,54 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_MESSAGE_RECEIVER_H_
+#define _D_BT_MESSAGE_RECEIVER_H_
+
+#include "common.h"
+#include "BtMessage.h"
+
+class BtMessageReceiver {
+public:
+ virtual ~BtMessageReceiver() {}
+
+ virtual BtMessageHandle receiveHandshake(bool quickReply = false) = 0;
+
+ virtual BtMessageHandle receiveAndSendHandshake() = 0;
+
+ virtual BtMessageHandle receiveMessage() = 0;
+};
+
+typedef SharedHandle<BtMessageReceiver> BtMessageReceiverHandle;
+
+#endif // _D_BT_MESSAGE_RECEIVER_H_
diff --git a/src/BtMessageValidator.h b/src/BtMessageValidator.h
new file mode 100644
index 00000000..5298fde4
--- /dev/null
+++ b/src/BtMessageValidator.h
@@ -0,0 +1,52 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_MESSAGE_VALIDATOR_H_
+#define _D_BT_MESSAGE_VALIDATOR_H_
+
+#include "common.h"
+#include "BtMessage.h"
+
+typedef Strings Errors;
+
+class BtMessageValidator {
+public:
+ virtual ~BtMessageValidator() {}
+
+ virtual bool validate(Errors& errors) = 0;
+};
+
+typedef SharedHandle<BtMessageValidator> BtMessageValidatorHandle;
+
+#endif // _D_BT_MESSAGE_VALIDATOR_H_
diff --git a/src/BtNotInterestedMessage.cc b/src/BtNotInterestedMessage.cc
new file mode 100644
index 00000000..4d3fc4eb
--- /dev/null
+++ b/src/BtNotInterestedMessage.cc
@@ -0,0 +1,85 @@
+/* <!-- 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 "BtNotInterestedMessage.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+
+BtNotInterestedMessageHandle BtNotInterestedMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "not interested", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "not interested", ID);
+ }
+ BtNotInterestedMessageHandle message = new BtNotInterestedMessage();
+ return message;
+}
+
+void BtNotInterestedMessage::doReceivedAction() {
+ peer->peerInterested = false;
+}
+
+bool BtNotInterestedMessage::sendPredicate() const {
+ return peer->amInterested;
+}
+
+uint32_t BtNotInterestedMessage::MESSAGE_LENGTH = 5;
+
+const char* BtNotInterestedMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 3, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtNotInterestedMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+void BtNotInterestedMessage::onSendComplete() {
+ peer->amInterested = false;
+}
+
+string BtNotInterestedMessage::toString() const {
+ return "not interested";
+}
diff --git a/src/BtNotInterestedMessage.h b/src/BtNotInterestedMessage.h
new file mode 100644
index 00000000..f7cbee5a
--- /dev/null
+++ b/src/BtNotInterestedMessage.h
@@ -0,0 +1,77 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_NOT_INTERESTED_MESSAGE_H_
+#define _D_BT_NOT_INTERESTED_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtNotInterestedMessage;
+
+typedef SharedHandle<BtNotInterestedMessage> BtNotInterestedMessageHandle;
+
+class BtNotInterestedMessage : public SimpleBtMessage {
+private:
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtNotInterestedMessage():msg(0) {}
+
+ virtual ~BtNotInterestedMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 3
+ };
+
+ static BtNotInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ virtual bool sendPredicate() const;
+
+ virtual void onSendComplete();
+};
+
+#endif // _D_BT_NOT_INTERESTED_MESSAGE_H_
diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc
new file mode 100644
index 00000000..a9bdb758
--- /dev/null
+++ b/src/BtPieceMessage.cc
@@ -0,0 +1,283 @@
+/* <!-- 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 "BtPieceMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "message.h"
+#include "DlAbortEx.h"
+#include "BtChokingEvent.h"
+#include "BtCancelSendingPieceEvent.h"
+
+void BtPieceMessage::setBlock(const unsigned char* block, uint32_t blockLength) {
+ delete [] this->block;
+ this->blockLength = blockLength;
+ this->block = new char[this->blockLength];
+ memcpy(this->block, block, this->blockLength);
+}
+
+BtPieceMessageHandle BtPieceMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength <= 9) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "piece", dataLength, 9);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "piece", ID);
+ }
+ BtPieceMessageHandle message = new BtPieceMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ message->setBegin(PeerMessageUtil::getIntParam(data, 5));
+ message->setBlock(data+9, dataLength-9);
+ return message;
+}
+
+void BtPieceMessage::doReceivedAction() {
+ RequestSlot slot =
+ BT_MESSAGE_DISPATCHER(btContext, peer)->getOutstandingRequest(index,
+ begin,
+ blockLength);
+ peer->updateDownloadLength(blockLength);
+ if(!RequestSlot::isNull(slot)) {
+ peer->snubbing = false;
+ peer->updateLatency(slot.getLatencyInMillis());
+ PieceHandle piece = pieceStorage->getPiece(index);
+ uint64_t offset =
+ ((uint64_t)index)*btContext->getPieceLength()+begin;
+ logger->debug("CUID#%d - Piece received. index=%u, begin=%u, length=%u, offset=%llu, blockIndex=%u",
+ cuid, index, begin, blockLength, offset, slot.getBlockIndex());
+ pieceStorage->getDiskAdaptor()->writeData(block,
+ blockLength,
+ offset);
+ piece->completeBlock(slot.getBlockIndex());
+ BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot);
+ if(piece->pieceComplete()) {
+ if(checkPieceHash(piece)) {
+ onNewPiece(piece);
+ } else {
+ onWrongPiece(piece);
+ }
+ }
+ }
+}
+
+uint32_t BtPieceMessage::MESSAGE_HEADER_LENGTH = 13;
+
+const char* BtPieceMessage::getMessageHeader() {
+ if(!msgHeader) {
+ /**
+ * len --- 9+blockLength, 4bytes
+ * id --- 7, 1byte
+ * index --- index, 4bytes
+ * begin --- begin, 4bytes
+ * total: 13bytes
+ */
+ msgHeader = new char[MESSAGE_HEADER_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msgHeader, MESSAGE_HEADER_LENGTH,
+ 9+blockLength, ID);
+ PeerMessageUtil::setIntParam(&msgHeader[5], index);
+ PeerMessageUtil::setIntParam(&msgHeader[9], begin);
+ }
+ return msgHeader;
+}
+
+uint32_t BtPieceMessage::getMessageHeaderLength() {
+ return MESSAGE_HEADER_LENGTH;
+}
+
+void BtPieceMessage::send() {
+ if(invalidate) {
+ return;
+ }
+ if(!headerSent) {
+ if(!sendingInProgress) {
+ logger->info(MSG_SEND_PEER_MESSAGE,
+ cuid, peer->ipaddr.c_str(), peer->port,
+ toString().c_str());
+ getMessageHeader();
+ leftDataLength = getMessageHeaderLength();
+ sendingInProgress = true;
+ }
+ uint32_t writtenLength
+ = PEER_CONNECTION(btContext, peer)->sendMessage(msgHeader+getMessageHeaderLength()-leftDataLength,
+ leftDataLength);
+ if(writtenLength == leftDataLength) {
+ headerSent = true;
+ leftDataLength = blockLength;
+ } else {
+ leftDataLength -= writtenLength;
+ }
+ }
+ if(headerSent) {
+ sendingInProgress = false;
+ uint64_t pieceDataOffset =
+ ((uint64_t)index)*btContext->getPieceLength()+begin+blockLength-leftDataLength;
+ uint32_t writtenLength =
+ sendPieceData(pieceDataOffset, leftDataLength);
+ peer->updateUploadLength(writtenLength);
+ if(writtenLength < leftDataLength) {
+ sendingInProgress = true;
+ }
+ leftDataLength -= writtenLength;
+ }
+}
+
+uint32_t BtPieceMessage::sendPieceData(uint64_t offset, uint32_t length) const {
+ uint32_t BUF_SIZE = 256;
+ char buf[BUF_SIZE];
+ int32_t iteration = length/BUF_SIZE;
+ uint32_t writtenLength = 0;
+ for(int32_t i = 0; i < iteration; i++) {
+ if(pieceStorage->getDiskAdaptor()->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
+ throw new DlAbortEx("Failed to read data from disk.");
+ }
+ uint32_t ws = PEER_CONNECTION(btContext, peer)->sendMessage(buf, BUF_SIZE);
+ writtenLength += ws;
+ if(ws != BUF_SIZE) {
+ return writtenLength;
+ }
+ }
+
+ int32_t rem = length%BUF_SIZE;
+ if(rem > 0) {
+ if(pieceStorage->getDiskAdaptor()->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
+ throw new DlAbortEx("Failed to read data from disk.");
+ }
+ uint32_t ws = PEER_CONNECTION(btContext, peer)->sendMessage(buf, rem);
+ writtenLength += ws;
+ }
+ return writtenLength;
+}
+
+string BtPieceMessage::toString() const {
+ return "piece index="+Util::uitos(index)+", begin="+Util::uitos(begin)+
+ ", length="+Util::uitos(blockLength);
+}
+
+bool BtPieceMessage::checkPieceHash(const PieceHandle& piece) {
+ uint64_t offset =
+ ((uint64_t)piece->getIndex())*btContext->getPieceLength();
+ return pieceStorage->getDiskAdaptor()->sha1Sum(offset, piece->getLength()) ==
+ btContext->getPieceHash(piece->getIndex());
+}
+
+void BtPieceMessage::onNewPiece(const PieceHandle& piece) {
+ logger->info(MSG_GOT_NEW_PIECE, cuid, piece->getIndex());
+ pieceStorage->completePiece(piece);
+ pieceStorage->advertisePiece(cuid, piece->getIndex());
+}
+
+void BtPieceMessage::onWrongPiece(const PieceHandle& piece) {
+ logger->error(MSG_GOT_WRONG_PIECE, cuid, piece->getIndex());
+ erasePieceOnDisk(piece);
+ piece->clearAllBlock();
+ BT_REQUEST_FACTORY(btContext, peer)->removeTargetPiece(piece);
+}
+
+void BtPieceMessage::erasePieceOnDisk(const PieceHandle& piece) {
+ int32_t BUFSIZE = 4096;
+ char buf[BUFSIZE];
+ memset(buf, 0, BUFSIZE);
+ uint64_t offset =
+ ((uint64_t)piece->getIndex())*btContext->getPieceLength();
+ for(int32_t i = 0; i < piece->getLength()/BUFSIZE; i++) {
+ pieceStorage->getDiskAdaptor()->writeData(buf, BUFSIZE, offset);
+ offset += BUFSIZE;
+ }
+ int32_t r = piece->getLength()%BUFSIZE;
+ if(r > 0) {
+ pieceStorage->getDiskAdaptor()->writeData(buf, r, offset);
+ }
+}
+
+bool BtPieceMessage::BtChokingEventListener::canHandle(const BtEventHandle& event) {
+ BtChokingEvent* intEvent = dynamic_cast<BtChokingEvent*>(event.get());
+ return intEvent != 0;
+}
+
+void BtPieceMessage::BtChokingEventListener::handleEventInternal(const BtEventHandle& event) {
+ message->handleChokingEvent(event);
+}
+
+void BtPieceMessage::handleChokingEvent(const BtEventHandle& event) {
+ if(!invalidate &&
+ !sendingInProgress &&
+ !peer->isInAmAllowedIndexSet(index)) {
+ logger->debug("CUID#%d - Reject piece message in queue because"
+ " the peer has been choked. index=%d, begin=%d, length=%d",
+ cuid,
+ index,
+ begin,
+ blockLength);
+
+ if(peer->isFastExtensionEnabled()) {
+ BtMessageHandle rej =
+ BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index,
+ begin,
+ blockLength);
+ BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(rej);
+ }
+ invalidate = true;
+ }
+}
+
+bool BtPieceMessage::BtCancelSendingPieceEventListener::canHandle(const BtEventHandle& event) {
+ BtCancelSendingPieceEvent* intEvent = dynamic_cast<BtCancelSendingPieceEvent*>(event.get());
+ return intEvent != 0;
+}
+
+void BtPieceMessage::BtCancelSendingPieceEventListener::handleEventInternal(const BtEventHandle& event) {
+ message->handleCancelSendingPieceEvent(event);
+}
+
+void BtPieceMessage::handleCancelSendingPieceEvent(const BtEventHandle& event) {
+ BtCancelSendingPieceEvent* intEvent = (BtCancelSendingPieceEvent*)(event.get());
+ if(!invalidate &&
+ !sendingInProgress &&
+ index == intEvent->getIndex() &&
+ begin == intEvent->getBegin() &&
+ blockLength == intEvent->getLength()) {
+ logger->debug("CUID#%d - Reject piece message in queue because cancel"
+ " message received. index=%d, begin=%d, length=%d",
+ cuid, index, begin, blockLength);
+ if(peer->isFastExtensionEnabled()) {
+ BtMessageHandle rej =
+ BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index,
+ begin,
+ blockLength);
+ BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(rej);
+ }
+ invalidate = true;
+ }
+}
diff --git a/src/BtPieceMessage.h b/src/BtPieceMessage.h
new file mode 100644
index 00000000..d1677369
--- /dev/null
+++ b/src/BtPieceMessage.h
@@ -0,0 +1,154 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_PIECE_MESSAGE_H_
+#define _D_BT_PIECE_MESSAGE_H_
+
+#include "AbstractBtMessage.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
+#include "BtEvent.h"
+#include "AbstractBtEventListener.h"
+
+class BtPieceMessage;
+
+typedef SharedHandle<BtPieceMessage> BtPieceMessageHandle;
+
+class BtPieceMessage : public AbstractBtMessage {
+private:
+ uint32_t index;
+ uint32_t begin;
+ uint32_t blockLength;
+ char* block;
+ uint32_t leftDataLength;
+ bool headerSent;
+ char* msgHeader;
+
+ static uint32_t MESSAGE_HEADER_LENGTH;
+
+ bool checkPieceHash(const PieceHandle& piece);
+
+ void onNewPiece(const PieceHandle& piece);
+
+ void onWrongPiece(const PieceHandle& piece);
+
+ void erasePieceOnDisk(const PieceHandle& piece);
+
+ uint32_t sendPieceData(uint64_t offset, uint32_t length) const;
+
+ class BtChokingEventListener : public AbstractBtEventListener {
+ private:
+ BtPieceMessage* message;
+ public:
+ BtChokingEventListener(BtPieceMessage* message):message(message) {}
+
+ virtual bool canHandle(const BtEventHandle& btEvent);
+
+ virtual void handleEventInternal(const BtEventHandle& btEvent);
+ };
+
+ typedef SharedHandle<BtChokingEventListener> BtChokingEventListenerHandle;
+
+ class BtCancelSendingPieceEventListener : public AbstractBtEventListener {
+ private:
+ BtPieceMessage* message;
+ public:
+ BtCancelSendingPieceEventListener(BtPieceMessage* message):message(message) {}
+
+ virtual bool canHandle(const BtEventHandle& btEvent);
+
+ virtual void handleEventInternal(const BtEventHandle& btEvent);
+ };
+
+ typedef SharedHandle<BtCancelSendingPieceEventListener> BtCancelSendingPieceEventListenerHandle;
+public:
+ BtPieceMessage(uint32_t index = 0, uint32_t begin = 0, uint32_t blockLength = 0)
+ :index(index),
+ begin(begin),
+ blockLength(blockLength),
+ block(0),
+ leftDataLength(0),
+ headerSent(false),
+ msgHeader(0)
+ {
+ uploading = true;
+ addEventListener(new BtChokingEventListener(this));
+ addEventListener(new BtCancelSendingPieceEventListener(this));
+ }
+
+ virtual ~BtPieceMessage() {
+ delete [] msgHeader;
+ delete [] block;
+ }
+
+ enum ID_t {
+ ID = 7
+ };
+
+ uint32_t getIndex() const { return index; }
+
+ void setIndex(uint32_t index) { this->index = index; }
+
+ uint32_t getBegin() const { return begin; }
+
+ void setBegin(uint32_t begin) { this->begin = begin; }
+
+ const char* getBlock() const { return block; }
+
+ void setBlock(const unsigned char* block, uint32_t blockLength);
+
+ uint32_t getBlockLength() const { return blockLength; }
+
+ void setBlockLength(uint32_t blockLength) { this->blockLength = blockLength; }
+
+ static BtPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ const char* getMessageHeader();
+
+ uint32_t getMessageHeaderLength();
+
+ virtual void send();
+
+ virtual string toString() const;
+
+ void handleChokingEvent(const BtEventHandle& event);
+
+ void handleCancelSendingPieceEvent(const BtEventHandle& event);
+};
+
+#endif // _D_BT_PIECE_MESSAGE_H_
diff --git a/src/BtPieceMessageValidator.h b/src/BtPieceMessageValidator.h
new file mode 100644
index 00000000..95e9a3a1
--- /dev/null
+++ b/src/BtPieceMessageValidator.h
@@ -0,0 +1,64 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_PIECE_MESSAGE_VALIDATOR_H_
+#define _D_BT_PIECE_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtPieceMessage.h"
+
+class BtPieceMessageValidator : public BtMessageValidator {
+private:
+ const BtPieceMessage* message;
+ uint32_t numPiece;
+ uint32_t pieceLength;
+public:
+ BtPieceMessageValidator(const BtPieceMessage* message,
+ uint32_t numPiece,
+ uint32_t pieceLength):
+ message(message),
+ numPiece(numPiece),
+ pieceLength(pieceLength) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ PeerMessageUtil::checkBegin(message->getBegin(), pieceLength);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtPieceMessageValidator> BtPieceMessageValidatorHandle;
+
+#endif // _D_BT_PIECE_MESSAGE_VALIDATOR_H_
diff --git a/src/BtPortMessage.cc b/src/BtPortMessage.cc
new file mode 100644
index 00000000..29ffc761
--- /dev/null
+++ b/src/BtPortMessage.cc
@@ -0,0 +1,56 @@
+/* <!-- 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 "BtPortMessage.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+#include "Util.h"
+
+BtPortMessageHandle BtPortMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 3) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "port", dataLength, 3);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "piece", ID);
+ }
+ BtPortMessageHandle message = new BtPortMessage();
+ message->setPort(PeerMessageUtil::getShortIntParam(data, 1));
+ return message;
+}
+
+string BtPortMessage::toString() const {
+ return "port port="+Util::uitos(port);
+}
diff --git a/src/BtPortMessage.h b/src/BtPortMessage.h
new file mode 100644
index 00000000..43f4be34
--- /dev/null
+++ b/src/BtPortMessage.h
@@ -0,0 +1,72 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_PORT_MESSAGE_H_
+#define _D_BT_PORT_MESSAGE_H_
+
+#include "AbstractBtMessage.h"
+
+class BtPortMessage;
+
+typedef SharedHandle<BtPortMessage> BtPortMessageHandle;
+
+class BtPortMessage : public AbstractBtMessage {
+private:
+ uint16_t port;
+public:
+ BtPortMessage(uint16_t port = 0):port(port) {}
+
+ virtual ~BtPortMessage() {}
+
+ enum ID_t {
+ ID = 9
+ };
+
+ uint16_t getPort() const { return port; }
+
+ void setPort(uint16_t port) { this->port = port; }
+
+ virtual int32_t getId() const { return ID; }
+
+ static BtPortMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual void doReceivedAction() {
+ logger->info("DHT is not supported yet.");
+ }
+ virtual void send() {}
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_PORT_MESSAGE_H_
diff --git a/src/BtRegistry.cc b/src/BtRegistry.cc
index cdd9c6e6..e74b86bf 100644
--- a/src/BtRegistry.cc
+++ b/src/BtRegistry.cc
@@ -40,6 +40,7 @@ PieceStorageMap BtRegistry::pieceStorageMap;
BtAnnounceMap BtRegistry::btAnnounceMap;
BtRuntimeMap BtRegistry::btRuntimeMap;
BtProgressInfoFileMap BtRegistry::btProgressInfoFileMap;
+PeerObjectClusterRegistry BtRegistry::peerObjectClusterRegistry;
PeerStorageHandle BtRegistry::getPeerStorage(const string& key) {
PeerStorageMap::iterator itr = peerStorageMap.find(key);
@@ -70,6 +71,7 @@ BtRegistry::getPieceStorage(const string& key) {
bool
BtRegistry::registerPieceStorage(const string& key,
const PieceStorageHandle& pieceStorage) {
+ pieceStorageMap.erase(key);
PieceStorageMap::value_type p(key, pieceStorage);
pair<PieceStorageMap::iterator, bool> retval = pieceStorageMap.insert(p);
return retval.second;
@@ -128,3 +130,31 @@ BtRegistry::registerBtProgressInfoFile(const string& key,
btProgressInfoFileMap.insert(p);
return retval.second;
}
+
+PeerObjectClusterHandle
+BtRegistry::getPeerObjectCluster(const string& key)
+{
+ return peerObjectClusterRegistry.getHandle(key);
+}
+
+void
+BtRegistry::registerPeerObjectCluster(const string& key,
+ const PeerObjectClusterHandle& cluster)
+{
+ peerObjectClusterRegistry.registerHandle(key, cluster);
+}
+
+void
+BtRegistry::unregisterPeerObjectCluster(const string& key)
+{
+ peerObjectClusterRegistry.unregisterHandle(key);
+}
+
+void BtRegistry::clear() {
+ peerStorageMap.clear();
+ pieceStorageMap.clear();
+ btAnnounceMap.clear();
+ btRuntimeMap.clear();
+ btProgressInfoFileMap.clear();
+ peerObjectClusterRegistry.clear();
+}
diff --git a/src/BtRegistry.h b/src/BtRegistry.h
index f8356a23..a04e0c06 100644
--- a/src/BtRegistry.h
+++ b/src/BtRegistry.h
@@ -41,6 +41,8 @@
#include "BtAnnounce.h"
#include "BtRuntime.h"
#include "BtProgressInfoFile.h"
+#include "PeerObject.h"
+#include "HandleRegistry.h"
#include <map>
typedef map<string, PeerStorageHandle> PeerStorageMap;
@@ -49,6 +51,11 @@ typedef map<string, BtAnnounceHandle> BtAnnounceMap;
typedef map<string, BtRuntimeHandle> BtRuntimeMap;
typedef map<string, BtProgressInfoFileHandle> BtProgressInfoFileMap;
+// for BtMessageFactory
+typedef HandleRegistry<string, PeerObject> PeerObjectCluster;
+typedef SharedHandle<PeerObjectCluster> PeerObjectClusterHandle;
+typedef HandleRegistry<string, PeerObjectCluster> PeerObjectClusterRegistry;
+
class BtRegistry {
private:
BtRegistry() {}
@@ -58,6 +65,7 @@ private:
static BtAnnounceMap btAnnounceMap;
static BtRuntimeMap btRuntimeMap;
static BtProgressInfoFileMap btProgressInfoFileMap;
+ static PeerObjectClusterRegistry peerObjectClusterRegistry;
public:
static PeerStorageHandle getPeerStorage(const string& key);
static bool registerPeerStorage(const string& key,
@@ -78,6 +86,19 @@ public:
static BtProgressInfoFileHandle getBtProgressInfoFile(const string& key);
static bool registerBtProgressInfoFile(const string& key,
const BtProgressInfoFileHandle& btProgressInfoFile);
+
+ // for PeerObject
+ static PeerObjectClusterHandle
+ getPeerObjectCluster(const string& key);
+
+ static void
+ registerPeerObjectCluster(const string& key,
+ const PeerObjectClusterHandle& cluster);
+
+ static void
+ unregisterPeerObjectCluster(const string& key);
+
+ static void clear();
};
#define PEER_STORAGE(btContext) \
@@ -95,4 +116,22 @@ BtRegistry::getBtRuntime(btContext->getInfoHashAsString())
#define BT_PROGRESS_INFO_FILE(btContext) \
BtRegistry::getBtProgressInfoFile(btContext->getInfoHashAsString())
+#define PEER_OBJECT_CLUSTER(btContext) \
+BtRegistry::getPeerObjectCluster(btContext->getInfoHashAsString())
+
+#define PEER_OBJECT(btContext, peer) \
+PEER_OBJECT_CLUSTER(btContext)->getHandle(peer->getId())
+
+#define BT_MESSAGE_DISPATCHER(btContext, peer) \
+PEER_OBJECT(btContext, peer)->btMessageDispatcher
+
+#define BT_MESSAGE_FACTORY(btContext, peer) \
+PEER_OBJECT(btContext, peer)->btMessageFactory
+
+#define BT_REQUEST_FACTORY(btContext, peer) \
+PEER_OBJECT(btContext, peer)->btRequestFactory
+
+#define PEER_CONNECTION(btContext, peer) \
+PEER_OBJECT(btContext, peer)->peerConnection
+
#endif // _D_BT_REGISTRY_H_
diff --git a/src/BtRejectMessage.cc b/src/BtRejectMessage.cc
new file mode 100644
index 00000000..e6438c96
--- /dev/null
+++ b/src/BtRejectMessage.cc
@@ -0,0 +1,101 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "BtRejectMessage.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+BtRejectMessageHandle BtRejectMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 13) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "reject", dataLength, 13);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "reject", ID);
+ }
+ BtRejectMessageHandle message = new BtRejectMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ message->setBegin(PeerMessageUtil::getIntParam(data, 5));
+ message->setLength(PeerMessageUtil::getIntParam(data, 9));
+ return message;
+}
+
+void BtRejectMessage::doReceivedAction() {
+ if(!peer->isFastExtensionEnabled()) {
+ throw new DlAbortEx("%s received while fast extension is disabled.",
+ toString().c_str());
+ }
+ // TODO Current implementation does not close a connection even if
+ // a request for this reject message has never sent.
+ RequestSlot slot =
+ BT_MESSAGE_DISPATCHER(btContext, peer)->getOutstandingRequest(index, begin, length);
+ if(RequestSlot::isNull(slot)) {
+ //throw new DlAbortEx("reject recieved, but it is not in the request slots.");
+ } else {
+ BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot);
+ }
+
+}
+
+uint32_t BtRejectMessage::MESSAGE_LENGTH = 17;
+
+const char* BtRejectMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 13, 4bytes
+ * id --- 16, 1byte
+ * index --- index, 4bytes
+ * begin --- begin, 4bytes
+ * length -- length, 4bytes
+ * total: 17bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 13, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ PeerMessageUtil::setIntParam(&msg[9], begin);
+ PeerMessageUtil::setIntParam(&msg[13], length);
+ }
+ return msg;
+}
+
+uint32_t BtRejectMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtRejectMessage::toString() const {
+ return "reject index="+Util::uitos(index)+", begin="+Util::uitos(begin)+
+ ", length="+Util::uitos(length);
+}
diff --git a/src/BtRejectMessage.h b/src/BtRejectMessage.h
new file mode 100644
index 00000000..4e081a6d
--- /dev/null
+++ b/src/BtRejectMessage.h
@@ -0,0 +1,88 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REJECT_MESSAGE_H_
+#define _D_BT_REJECT_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtRejectMessage;
+
+typedef SharedHandle<BtRejectMessage> BtRejectMessageHandle;
+
+class BtRejectMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ uint32_t begin;
+ uint32_t length;
+ char* msg;
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtRejectMessage(uint32_t index = 0, uint32_t begin = 0, uint32_t length = 0)
+ :index(index),
+ begin(begin),
+ length(length),
+ msg(0) {}
+
+ virtual ~BtRejectMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 16
+ };
+
+ uint32_t getIndex() const { return index; }
+ void setIndex(uint32_t index) { this->index = index; }
+
+ uint32_t getBegin() const { return begin; }
+ void setBegin(uint32_t begin) { this->begin = begin; }
+
+ uint32_t getLength() const { return length; }
+ void setLength(uint32_t length) { this->length = length; }
+
+ static BtRejectMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_REJECT_MESSAGE_H_
diff --git a/src/BtRejectMessageValidator.h b/src/BtRejectMessageValidator.h
new file mode 100644
index 00000000..84b814eb
--- /dev/null
+++ b/src/BtRejectMessageValidator.h
@@ -0,0 +1,68 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REJECT_MESSAGE_VALIDATOR_H_
+#define _D_BT_REJECT_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtRejectMessage.h"
+
+class BtRejectMessageValidator : public BtMessageValidator {
+private:
+ const BtRejectMessage* message;
+ uint32_t numPiece;
+ uint32_t pieceLength;
+public:
+ BtRejectMessageValidator(const BtRejectMessage* message,
+ uint32_t numPiece,
+ uint32_t pieceLength):
+ message(message),
+ numPiece(numPiece),
+ pieceLength(pieceLength) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ PeerMessageUtil::checkBegin(message->getBegin(), pieceLength);
+ PeerMessageUtil::checkLength(message->getLength());
+ PeerMessageUtil::checkRange(message->getBegin(),
+ message->getLength(),
+ pieceLength);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtRejectMessageValidator> BtRejectMessageValidatorHandle;
+
+#endif // _D_BT_REJECT_MESSAGE_VALIDATOR_H_
diff --git a/src/BtRequestFactory.h b/src/BtRequestFactory.h
new file mode 100644
index 00000000..f68d0e77
--- /dev/null
+++ b/src/BtRequestFactory.h
@@ -0,0 +1,72 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REQUEST_FACTORY_H_
+#define _D_BT_REQUEST_FACTORY_H_
+
+#include "common.h"
+#include "BtMessage.h"
+#include "Piece.h"
+
+class BtRequestFactory {
+public:
+ virtual ~BtRequestFactory() {}
+
+ virtual void addTargetPiece(const PieceHandle& piece) = 0;
+
+ virtual void removeTargetPiece(const PieceHandle& piece) = 0;
+
+ virtual void removeAllTargetPiece() = 0;
+
+ virtual int countTargetPiece() = 0;
+
+ virtual void removeCompletedPiece() = 0;
+
+ /**
+ * Creates RequestMessage objects associated to the pieces added by
+ * addTargetPiece() and returns them.
+ * The number of objects returned is capped by max.
+ */
+ virtual BtMessages createRequestMessages(int max) = 0;
+
+ /**
+ * Use this method in end game mode.
+ *
+ */
+ virtual BtMessages createRequestMessagesOnEndGame(int max) = 0;
+};
+
+typedef SharedHandle<BtRequestFactory> BtRequestFactoryHandle;
+
+#endif // _D_BT_REQUEST_FACTORY_H_
diff --git a/src/BtRequestMessage.cc b/src/BtRequestMessage.cc
new file mode 100644
index 00000000..6dffaa74
--- /dev/null
+++ b/src/BtRequestMessage.cc
@@ -0,0 +1,129 @@
+/* <!-- 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 "BtRequestMessage.h"
+#include "PeerInteraction.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+#include "BtAbortOutstandingRequestEvent.h"
+
+BtRequestMessageHandle BtRequestMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 13) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "request", dataLength, 13);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "request", ID);
+ }
+ BtRequestMessageHandle message = new BtRequestMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ message->setBegin(PeerMessageUtil::getIntParam(data, 5));
+ message->setLength(PeerMessageUtil::getIntParam(data, 9));
+ return message;
+}
+
+void BtRequestMessage::doReceivedAction() {
+ if(pieceStorage->hasPiece(index) &&
+ (!peer->amChoking ||
+ peer->amChoking && peer->isInAmAllowedIndexSet(index))) {
+ BtMessageHandle msg =
+ BT_MESSAGE_FACTORY(btContext, peer)->createPieceMessage(index,
+ begin,
+ length);
+ BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(msg);
+ } else {
+ if(peer->isFastExtensionEnabled()) {
+ BtMessageHandle msg =
+ BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index,
+ begin,
+ length);
+ BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(msg);
+ }
+ }
+}
+
+uint32_t BtRequestMessage::MESSAGE_LENGTH = 17;
+
+const char* BtRequestMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 13, 4bytes
+ * id --- 6, 1byte
+ * index --- index, 4bytes
+ * begin --- begin, 4bytes
+ * length --- length, 4bytes
+ * total: 17bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 13, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ PeerMessageUtil::setIntParam(&msg[9], begin);
+ PeerMessageUtil::setIntParam(&msg[13], length);
+ }
+ return msg;
+}
+
+uint32_t BtRequestMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtRequestMessage::toString() const {
+ return "request index="+Util::uitos(index)+", begin="+Util::uitos(begin)+
+ ", length="+Util::uitos(length);
+}
+
+void BtRequestMessage::onQueued() {
+ RequestSlot requestSlot(index, begin, length, blockIndex);
+ BT_MESSAGE_DISPATCHER(btContext, peer)->addOutstandingRequest(requestSlot);
+}
+
+bool BtRequestMessage::BtAbortOutstandingRequestEventListener::canHandle(const BtEventHandle& event) {
+ BtAbortOutstandingRequestEvent* intEvent = dynamic_cast<BtAbortOutstandingRequestEvent*>(event.get());
+ return intEvent != 0;
+}
+
+void BtRequestMessage::BtAbortOutstandingRequestEventListener::handleEventInternal(const BtEventHandle& event) {
+ message->handleAbortOutstandingRequestEvent(event);
+}
+
+void BtRequestMessage::handleAbortOutstandingRequestEvent(const BtEventHandle& event) {
+ BtAbortOutstandingRequestEvent* intEvent = (BtAbortOutstandingRequestEvent*)event.get();
+ if(index == intEvent->getPiece()->getIndex() &&
+ !invalidate &&
+ !sendingInProgress) {
+ invalidate = true;
+ }
+}
diff --git a/src/BtRequestMessage.h b/src/BtRequestMessage.h
new file mode 100644
index 00000000..f41b8882
--- /dev/null
+++ b/src/BtRequestMessage.h
@@ -0,0 +1,117 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REQUEST_MESSAGE_H_
+#define _D_BT_REQUEST_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
+#include "AbstractBtEventListener.h"
+
+class BtRequestMessage;
+
+typedef SharedHandle<BtRequestMessage> BtRequestMessageHandle;
+
+class BtRequestMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ uint32_t begin;
+ uint32_t length;
+ uint32_t blockIndex;
+ char* msg;
+
+ static uint32_t MESSAGE_LENGTH;
+
+ class BtAbortOutstandingRequestEventListener : public AbstractBtEventListener {
+ private:
+ BtRequestMessage* message;
+ public:
+ BtAbortOutstandingRequestEventListener(BtRequestMessage* message):message(message) {}
+
+ virtual bool canHandle(const BtEventHandle& event);
+
+ virtual void handleEventInternal(const BtEventHandle& event);
+ };
+
+ typedef SharedHandle<BtAbortOutstandingRequestEventListener> BtAbortOutstandingRequestEventListenerHandle;
+public:
+ BtRequestMessage(uint32_t index = 0,
+ uint32_t begin = 0,
+ uint32_t length = 0,
+ uint32_t blockIndex = 0)
+ :index(index),
+ begin(begin),
+ length(length),
+ blockIndex(blockIndex),
+ msg(0)
+ {
+ addEventListener(new BtAbortOutstandingRequestEventListener(this));
+ }
+
+ virtual ~BtRequestMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 6
+ };
+
+ uint32_t getIndex() const { return index; }
+ void setIndex(uint32_t index) { this->index = index; }
+ uint32_t getBegin() const { return begin; }
+ void setBegin(uint32_t begin) { this->begin = begin; }
+ uint32_t getLength() const { return length; }
+ void setLength(uint32_t length) { this->length = length; }
+ uint32_t getBlockIndex() const { return blockIndex; }
+ void setBlockIndex(uint32_t blockIndex) { this->blockIndex = blockIndex; }
+
+ static BtRequestMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ virtual void onQueued();
+
+ virtual void handleAbortOutstandingRequestEvent(const BtEventHandle& event);
+};
+
+#endif // _D_BT_REQUEST_MESSAGE_H_
diff --git a/src/BtRequestMessageValidator.h b/src/BtRequestMessageValidator.h
new file mode 100644
index 00000000..baa5731a
--- /dev/null
+++ b/src/BtRequestMessageValidator.h
@@ -0,0 +1,68 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REQUEST_MESSAGE_VALIDATOR_H_
+#define _D_BT_REQUEST_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtRequestMessage.h"
+
+class BtRequestMessageValidator : public BtMessageValidator {
+private:
+ const BtRequestMessage* message;
+ uint32_t numPiece;
+ uint32_t pieceLength;
+public:
+ BtRequestMessageValidator(const BtRequestMessage* message,
+ uint32_t numPiece,
+ uint32_t pieceLength):
+ message(message),
+ numPiece(numPiece),
+ pieceLength(pieceLength) {}
+
+ virtual bool validate(Errors& error) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ PeerMessageUtil::checkBegin(message->getBegin(), pieceLength);
+ PeerMessageUtil::checkLength(message->getLength());
+ PeerMessageUtil::checkRange(message->getBegin(),
+ message->getLength(),
+ pieceLength);
+ return true;
+ }
+};
+
+typedef SharedHandle<BtRequestMessageValidator> BtRequestMessageValidatorHandle;
+
+#endif // _D_BT_REQUEST_MESSAGE_VALIDATOR_H_
diff --git a/src/BtSuggestPieceMessage.cc b/src/BtSuggestPieceMessage.cc
new file mode 100644
index 00000000..615fb99c
--- /dev/null
+++ b/src/BtSuggestPieceMessage.cc
@@ -0,0 +1,78 @@
+/* <!-- 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 "BtSuggestPieceMessage.h"
+#include "PeerInteraction.h"
+#include "PeerMessageUtil.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+
+BtSuggestPieceMessageHandle BtSuggestPieceMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 5) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "suggest piece", dataLength, 5);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "suggest piece", ID);
+ }
+ BtSuggestPieceMessageHandle message = new BtSuggestPieceMessage();
+ message->setIndex(PeerMessageUtil::getIntParam(data, 1));
+ return message;
+}
+
+uint32_t BtSuggestPieceMessage::MESSAGE_LENGTH = 9;
+
+const char* BtSuggestPieceMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 5, 4bytes
+ * id --- 13, 1byte
+ * piece index --- index, 4bytes
+ * total: 9bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 5, ID);
+ PeerMessageUtil::setIntParam(&msg[5], index);
+ }
+ return msg;
+}
+
+uint32_t BtSuggestPieceMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+string BtSuggestPieceMessage::toString() const {
+ return "suggest piece index="+Util::uitos(index);
+}
diff --git a/src/BtSuggestPieceMessage.h b/src/BtSuggestPieceMessage.h
new file mode 100644
index 00000000..5143a74a
--- /dev/null
+++ b/src/BtSuggestPieceMessage.h
@@ -0,0 +1,81 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_SUGGEST_PIECE_MESSAGE_H_
+#define _D_BT_SUGGEST_PIECE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtSuggestPieceMessage;
+
+typedef SharedHandle<BtSuggestPieceMessage> BtSuggestPieceMessageHandle;
+
+class BtSuggestPieceMessage : public SimpleBtMessage {
+private:
+ uint32_t index;
+ char* msg;
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtSuggestPieceMessage():index(0), msg(0) {}
+
+ virtual ~BtSuggestPieceMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 13
+ };
+
+ void setIndex(uint32_t index) {
+ this->index = index;
+ }
+
+ uint32_t getIndex() const { return index; }
+
+ static BtSuggestPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction() {
+ // TODO Current implementation ignores this message.
+ }
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+};
+
+#endif // _D_BT_SUGGEST_PIECE_MESSAGE_H_
diff --git a/src/BtSuggestPieceMessageValidator.h b/src/BtSuggestPieceMessageValidator.h
new file mode 100644
index 00000000..293b3c71
--- /dev/null
+++ b/src/BtSuggestPieceMessageValidator.h
@@ -0,0 +1,60 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_SUGGEST_PIECE_MESSAGE_VALIDATOR_H_
+#define _D_BT_SUGGEST_PIECE_MESSAGE_VALIDATOR_H_
+
+#include "BtMessageValidator.h"
+#include "BtSuggestPieceMessage.h"
+
+class BtSuggestPieceMessageValidator : public BtMessageValidator {
+private:
+ const BtSuggestPieceMessage* message;
+ int numPiece;
+public:
+ BtSuggestPieceMessageValidator(const BtSuggestPieceMessage* message,
+ int numPiece):
+ message(message),
+ numPiece(numPiece) {}
+
+ virtual bool validate(Errors& errors) {
+ // TODO
+ PeerMessageUtil::checkIndex(message->getIndex(), numPiece);
+ return true;
+ }
+
+};
+
+typedef SharedHandle<BtSuggestPieceMessageValidator> BtSuggestPieceMessageValidatorHandle;
+#endif // _D_BT_SUGGEST_PIECE_MESSAGE_VALIDATOR_H_
diff --git a/src/BtUnchokeMessage.cc b/src/BtUnchokeMessage.cc
new file mode 100644
index 00000000..e96d9d96
--- /dev/null
+++ b/src/BtUnchokeMessage.cc
@@ -0,0 +1,85 @@
+/* <!-- 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 "BtUnchokeMessage.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+
+BtUnchokeMessageHandle BtUnchokeMessage::create(const unsigned char* data, uint32_t dataLength) {
+ if(dataLength != 1) {
+ throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "unchoke", dataLength, 1);
+ }
+ int32_t id = PeerMessageUtil::getId(data);
+ if(id != ID) {
+ throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
+ id, "unchoke", ID);
+ }
+ BtUnchokeMessageHandle message = new BtUnchokeMessage();
+ return message;
+}
+
+void BtUnchokeMessage::doReceivedAction() {
+ peer->peerChoking = false;
+}
+
+bool BtUnchokeMessage::sendPredicate() const {
+ return peer->amChoking;
+}
+
+uint32_t BtUnchokeMessage::MESSAGE_LENGTH = 5;
+
+const char* BtUnchokeMessage::getMessage() {
+ if(!msg) {
+ /**
+ * len --- 1, 4bytes
+ * id --- 1, 1byte
+ * total: 5bytes
+ */
+ msg = new char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(msg, MESSAGE_LENGTH, 1, ID);
+ }
+ return msg;
+}
+
+uint32_t BtUnchokeMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
+void BtUnchokeMessage::onSendComplete() {
+ peer->amChoking = false;
+}
+
+string BtUnchokeMessage::toString() const {
+ return "unchoke";
+}
diff --git a/src/BtUnchokeMessage.h b/src/BtUnchokeMessage.h
new file mode 100644
index 00000000..b673621e
--- /dev/null
+++ b/src/BtUnchokeMessage.h
@@ -0,0 +1,76 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_UNCHOKE_MESSAGE_H_
+#define _D_BT_UNCHOKE_MESSAGE_H_
+
+#include "SimpleBtMessage.h"
+
+class BtUnchokeMessage;
+
+typedef SharedHandle<BtUnchokeMessage> BtUnchokeMessageHandle;
+
+class BtUnchokeMessage : public SimpleBtMessage {
+private:
+ char* msg;
+ static uint32_t MESSAGE_LENGTH;
+public:
+ BtUnchokeMessage():msg(0) {}
+
+ virtual ~BtUnchokeMessage() {
+ delete [] msg;
+ }
+
+ enum ID_t {
+ ID = 1
+ };
+
+ static BtUnchokeMessageHandle create(const unsigned char* data, uint32_t dataLength);
+
+ virtual int32_t getId() const { return ID; }
+
+ virtual void doReceivedAction();
+
+ virtual const char* getMessage();
+
+ virtual uint32_t getMessageLength();
+
+ virtual string toString() const;
+
+ virtual bool sendPredicate() const;
+
+ virtual void onSendComplete();
+};
+
+#endif // _D_BT_UNCHOKE_MESSAGE_H_
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
index 04e069eb..ab9cad07 100644
--- a/src/DefaultBtAnnounce.cc
+++ b/src/DefaultBtAnnounce.cc
@@ -62,7 +62,6 @@ DefaultBtAnnounce::DefaultBtAnnounce(BtContextHandle btContext,
{
prevAnnounceTime.setTimeInSec(0);
key = generateKey();
- peerId = generatePeerId();
logger = LogFactory::getInstance();
}
@@ -73,12 +72,6 @@ string DefaultBtAnnounce::generateKey() const {
return Util::randomAlpha(8);
}
-string DefaultBtAnnounce::generatePeerId() const {
- string peerId = "-aria2-";
- peerId += Util::randomAlpha(20-peerId.size());
- return peerId;
-}
-
bool DefaultBtAnnounce::isDefaultAnnounceReady() {
return (trackers == 0 && prevAnnounceTime.elapsed(minInterval));
}
@@ -131,7 +124,7 @@ string DefaultBtAnnounce::getAnnounceUrl() {
string url = announceList.getAnnounce()+"?"+
"info_hash="+Util::torrentUrlencode(btContext->getInfoHash(),
btContext->getInfoHashLength())+"&"+
- "peer_id="+peerId+"&"+
+ "peer_id="+Util::torrentUrlencode(btContext->getPeerId(), 20)+"&"+
"port="+Util::itos(btRuntime->getListenPort())+"&"+
"uploaded="+Util::llitos(stat.getSessionUploadLength())+"&"+
"downloaded="+Util::llitos(stat.getSessionDownloadLength())+"&"+
diff --git a/src/DefaultBtAnnounce.h b/src/DefaultBtAnnounce.h
index f54c1ac9..128c02fd 100644
--- a/src/DefaultBtAnnounce.h
+++ b/src/DefaultBtAnnounce.h
@@ -60,7 +60,6 @@ private:
string trackerId;
string key;
int trackerNumTry;
- string peerId;
const Option* option;
Logger* logger;
BtRuntimeHandle btRuntime;
@@ -112,11 +111,7 @@ public:
virtual void shuffleAnnounce();
- string generateKey() const;
-
- string generatePeerId() const;
-
- virtual string getPeerId() { return peerId; }
+ string generateKey() const;
};
#endif // _D_DEFAULT_BT_ANNOUNCE_H_
diff --git a/src/DefaultBtContext.cc b/src/DefaultBtContext.cc
index 1acf5fc5..0235f410 100644
--- a/src/DefaultBtContext.cc
+++ b/src/DefaultBtContext.cc
@@ -45,6 +45,12 @@ DefaultBtContext::DefaultBtContext() {}
DefaultBtContext::~DefaultBtContext() {}
+string DefaultBtContext::generatePeerId() const {
+ string peerId = "-aria2-";
+ peerId += Util::randomAlpha(20-peerId.size());
+ return peerId;
+}
+
const unsigned char* DefaultBtContext::getInfoHash() const {
return infoHash;
}
diff --git a/src/DefaultBtContext.h b/src/DefaultBtContext.h
index 74bae247..4133d7ab 100644
--- a/src/DefaultBtContext.h
+++ b/src/DefaultBtContext.h
@@ -55,6 +55,7 @@ private:
int pieceLength;
string name;
int numPieces;
+ string peerId;
AnnounceTiers announceTiers;
void clear();
@@ -92,6 +93,15 @@ private:
virtual int getPieceLength() const;
virtual int getNumPieces() const;
+
+ virtual const unsigned char* getPeerId() {
+ if(peerId == "") {
+ peerId = generatePeerId();
+ }
+ return (const unsigned char*)peerId.c_str();
+ }
+
+ string generatePeerId() const;
};
#endif // _D_DEFAULT_BT_CONTEXT_H_
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
new file mode 100644
index 00000000..f3812b01
--- /dev/null
+++ b/src/DefaultBtInteractive.cc
@@ -0,0 +1,307 @@
+/* <!-- 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 "DefaultBtInteractive.h"
+#include "prefs.h"
+#include "message.h"
+#include "BtHandshakeMessage.h"
+#include "Util.h"
+#include "BtKeepAliveMessage.h"
+#include "BtChokeMessage.h"
+#include "BtUnchokeMessage.h"
+#include "DlAbortEx.h"
+
+void DefaultBtInteractive::initiateHandshake() {
+ BtMessageHandle message =
+ BT_MESSAGE_FACTORY(btContext, peer)->
+ createHandshakeMessage(btContext->getInfoHash(),
+ btContext->getPeerId());
+ dispatcher->addMessageToQueue(message);
+ dispatcher->sendMessages();
+}
+
+BtMessageHandle DefaultBtInteractive::receiveHandshake(bool quickReply) {
+ BtHandshakeMessageHandle message =
+ btMessageReceiver->receiveHandshake(quickReply);
+ if(message.isNull()) {
+ return 0;
+ }
+ peer->setPeerId(message->getPeerId());
+ logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
+ peer->ipaddr.c_str(), peer->port,
+ message->toString().c_str());
+ return message;
+}
+
+BtMessageHandle DefaultBtInteractive::receiveAndSendHandshake() {
+ return receiveHandshake(true);
+}
+
+void DefaultBtInteractive::doPostHandshakeProcessing() {
+ // TODO where is the valid place to rest haveCheckTime?
+ haveCheckPoint.reset();
+ keepAliveCheckPoint.reset();
+ floodingCheckPoint.reset();
+ addBitfieldMessageToQueue();
+ addAllowedFastMessageToQueue();
+}
+
+void DefaultBtInteractive::addBitfieldMessageToQueue() {
+ BtMessageFactoryHandle factory = BT_MESSAGE_FACTORY(btContext, peer);
+ if(peer->isFastExtensionEnabled()) {
+ if(pieceStorage->downloadFinished()) {
+ dispatcher->addMessageToQueue(factory->createHaveAllMessage());
+ } else if(pieceStorage->getCompletedLength() > 0) {
+ dispatcher->addMessageToQueue(factory->createBitfieldMessage());
+ } else {
+ dispatcher->addMessageToQueue(factory->createHaveNoneMessage());
+ }
+ } else {
+ if(pieceStorage->getCompletedLength() > 0) {
+ dispatcher->addMessageToQueue(factory->createBitfieldMessage());
+ }
+ }
+}
+
+void DefaultBtInteractive::addAllowedFastMessageToQueue() {
+ if(peer->isFastExtensionEnabled()) {
+ Integers fastSet = Util::computeFastSet(peer->ipaddr,
+ btContext->getInfoHash(),
+ btContext->getNumPieces(),
+ allowedFastSetSize);
+ for(Integers::const_iterator itr = fastSet.begin();
+ itr != fastSet.end(); itr++) {
+ dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createAllowedFastMessage(*itr));
+ }
+ }
+}
+
+void DefaultBtInteractive::decideChoking() {
+ if(peer->shouldBeChoking()) {
+ if(!peer->amChoking) {
+ dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createChokeMessage());
+ }
+ } else {
+ if(peer->amChoking) {
+ dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createUnchokeMessage());
+ }
+ }
+}
+
+void DefaultBtInteractive::checkHave() {
+ BtMessageFactoryHandle factory = BT_MESSAGE_FACTORY(btContext, peer);
+ Integers indexes =
+ pieceStorage->getAdvertisedPieceIndexes(cuid, haveCheckPoint);
+ haveCheckPoint.reset();
+ if(indexes.size() >= 20) {
+ if(peer->isFastExtensionEnabled() && pieceStorage->downloadFinished()) {
+ dispatcher->addMessageToQueue(factory->createHaveAllMessage());
+ } else {
+ dispatcher->addMessageToQueue(factory->createBitfieldMessage());
+ }
+ } else {
+ for(Integers::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
+ dispatcher->addMessageToQueue(factory->createHaveMessage(*itr));
+ }
+ }
+}
+
+void DefaultBtInteractive::sendKeepAlive() {
+ if(keepAliveCheckPoint.elapsed(option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL))) {
+ if(dispatcher->countMessageInQueue() == 0) {
+ dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage());
+ dispatcher->sendMessages();
+ }
+ keepAliveCheckPoint.reset();
+ }
+}
+
+void DefaultBtInteractive::receiveMessages() {
+ for(int i = 0; i < 50; i++) {
+ int maxSpeedLimit = option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT);
+ if(maxSpeedLimit > 0) {
+ TransferStat stat = peerStorage->calculateStat();
+ if(maxSpeedLimit < stat.downloadSpeed) {
+ break;
+ }
+ }
+ BtMessageHandle message = btMessageReceiver->receiveMessage();
+ if(message.isNull()) {
+ break;
+ }
+ logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
+ peer->ipaddr.c_str(), peer->port,
+ message->toString().c_str());
+ message->doReceivedAction();
+
+ switch(message->getId()) {
+ case BtKeepAliveMessage::ID:
+ floodingStat.incKeepAliveCount();
+ break;
+ case BtChokeMessage::ID:
+ if(!peer->peerChoking) {
+ floodingStat.incChokeUnchokeCount();
+ }
+ break;
+ case BtUnchokeMessage::ID:
+ if(peer->peerChoking) {
+ floodingStat.incChokeUnchokeCount();
+ }
+ break;
+ }
+ }
+}
+
+void DefaultBtInteractive::decideInterest() {
+ if(!pieceStorage->hasMissingPiece(peer)) {
+ if(peer->amInterested) {
+ logger->debug("CUID#%d - Not interested in the peer", cuid);
+ dispatcher->
+ addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createNotInterestedMessage());
+ }
+ } else {
+ if(!peer->amInterested) {
+ logger->debug("CUID#%d - Interested in the peer", cuid);
+ dispatcher->
+ addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createInterestedMessage());
+ }
+ }
+}
+
+void DefaultBtInteractive::fillPiece(int maxPieceNum) {
+ if(pieceStorage->hasMissingPiece(peer)) {
+ if(peer->peerChoking) {
+ dispatcher->doChokedAction();
+ if(peer->isFastExtensionEnabled()) {
+ while(btRequestFactory->countTargetPiece() < maxPieceNum) {
+ PieceHandle piece = pieceStorage->getMissingFastPiece(peer);
+ if(piece.isNull()) {
+ break;
+ } else {
+ btRequestFactory->addTargetPiece(piece);
+ }
+ }
+ }
+ } else {
+ while(btRequestFactory->countTargetPiece() < maxPieceNum) {
+ PieceHandle piece = pieceStorage->getMissingPiece(peer);
+ if(piece.isNull()) {
+ break;
+ } else {
+ btRequestFactory->addTargetPiece(piece);
+ }
+ }
+ }
+ }
+}
+
+void DefaultBtInteractive::addRequests() {
+ uint32_t MAX_PENDING_REQUEST;
+ if(peer->getLatency() < 500) {
+ MAX_PENDING_REQUEST = 24;
+ } else if(peer->getLatency() < 1500) {
+ MAX_PENDING_REQUEST = 12;
+ } else {
+ MAX_PENDING_REQUEST = 6;
+ }
+ uint32_t pieceNum;
+ if(pieceStorage->isEndGame()) {
+ pieceNum = 1;
+ } else {
+ uint32_t blocks = DIV_FLOOR(btContext->getPieceLength(), BLOCK_LENGTH);
+ pieceNum = DIV_FLOOR(MAX_PENDING_REQUEST, blocks);
+ }
+ fillPiece(pieceNum);
+
+ uint32_t reqNumToCreate =
+ MAX_PENDING_REQUEST <= dispatcher->countOutstandingRequest() ?
+ 0 : MAX_PENDING_REQUEST-dispatcher->countOutstandingRequest();
+ if(reqNumToCreate > 0) {
+ //logger->debug("CUID#%d - %u requets to go.", cuid, reqNumToCreate);
+ BtMessages requests;
+ if(pieceStorage->isEndGame()) {
+ requests = btRequestFactory->createRequestMessagesOnEndGame(reqNumToCreate);
+ } else {
+ requests = btRequestFactory->createRequestMessages(reqNumToCreate);
+ }
+ dispatcher->addMessageToQueue(requests);
+ }
+}
+
+void DefaultBtInteractive::cancelAllPiece() {
+ btRequestFactory->removeAllTargetPiece();
+}
+
+void DefaultBtInteractive::sendPendingMessage() {
+ dispatcher->sendMessages();
+}
+
+void DefaultBtInteractive::detectMessageFlooding() {
+ if(floodingCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) {
+ if(floodingStat.getChokeUnchokeCount() >= 2 ||
+ floodingStat.getKeepAliveCount() >= 2) {
+ throw new DlAbortEx("Flooding detected.");
+ } else {
+ floodingStat.reset();
+ }
+ floodingCheckPoint.reset();
+ }
+}
+
+void DefaultBtInteractive::doInteractionProcessing() {
+ decideChoking();
+
+ detectMessageFlooding();
+
+ dispatcher->checkRequestSlotAndDoNecessaryThing();
+
+ checkHave();
+
+ sendKeepAlive();
+
+ receiveMessages();
+
+ btRequestFactory->removeCompletedPiece();
+
+ decideInterest();
+ if(!pieceStorage->downloadFinished()) {
+ addRequests();
+ }
+ sendPendingMessage();
+}
diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h
new file mode 100644
index 00000000..cc6f99a9
--- /dev/null
+++ b/src/DefaultBtInteractive.h
@@ -0,0 +1,195 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_INTERACTIVE_H_
+#define _D_DEFAULT_BT_INTERACTIVE_H_
+
+#include "BtInteractive.h"
+#include "Peer.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
+#include "PeerStorage.h"
+#include "BtMessageReceiver.h"
+#include "BtMessageDispatcher.h"
+#include "BtRequestFactory.h"
+#include "PeerConnection.h"
+#include "BtRegistry.h"
+#include "Logger.h"
+#include "LogFactory.h"
+#include "TimeA2.h"
+
+class FloodingStat {
+private:
+ uint32_t chokeUnchokeCount;
+ uint32_t keepAliveCount;
+public:
+ FloodingStat():chokeUnchokeCount(0), keepAliveCount(0) {}
+
+ void incChokeUnchokeCount() {
+ if(chokeUnchokeCount < UINT32_MAX) {
+ chokeUnchokeCount++;
+ }
+ }
+
+ void incKeepAliveCount() {
+ if(keepAliveCount < UINT32_MAX) {
+ keepAliveCount++;
+ }
+ }
+
+ uint32_t getChokeUnchokeCount() const {
+ return chokeUnchokeCount;
+ }
+
+ uint32_t getKeepAliveCount() const {
+ return keepAliveCount;
+ }
+
+ void reset() {
+ chokeUnchokeCount = 0;
+ keepAliveCount = 0;
+ }
+};
+
+class DefaultBtInteractive : public BtInteractive {
+private:
+ int32_t cuid;
+ PeerHandle peer;
+ BtContextHandle btContext;
+ PeerStorageHandle peerStorage;
+ PieceStorageHandle pieceStorage;
+ BtMessageReceiverHandle btMessageReceiver;
+ BtMessageDispatcherHandle dispatcher;
+ BtRequestFactoryHandle btRequestFactory;
+ PeerConnectionHandle peerConnection;
+ const Logger* logger;
+ uint32_t allowedFastSetSize;
+ Time haveCheckPoint;
+ Time keepAliveCheckPoint;
+ Time floodingCheckPoint;
+ FloodingStat floodingStat;
+ const Option* option;
+
+ static const uint32_t FLOODING_CHECK_INTERVAL = 5;
+
+ void addBitfieldMessageToQueue();
+ void addAllowedFastMessageToQueue();
+ void decideChoking();
+ void checkHave();
+ void sendKeepAlive();
+ void decideInterest();
+ void fillPiece(int maxPieceNum);
+ void addRequests();
+ void detectMessageFlooding();
+public:
+ DefaultBtInteractive():peer(0),
+ btContext(0),
+ peerStorage(0),
+ pieceStorage(0),
+ btMessageReceiver(0),
+ dispatcher(0),
+ btRequestFactory(0),
+ peerConnection(0),
+ logger(LogFactory::getInstance()),
+ allowedFastSetSize(10)
+ {
+ logger->debug("DefaultBtInteractive instantiated.");
+ }
+
+ virtual ~DefaultBtInteractive() {
+ logger->debug("DefaultBtInteractive deleted.");
+ }
+
+ virtual void initiateHandshake();
+
+ virtual BtMessageHandle receiveHandshake(bool quickReply = false);
+
+ virtual BtMessageHandle receiveAndSendHandshake();
+
+ virtual void doPostHandshakeProcessing();
+
+ virtual void doInteractionProcessing();
+
+ virtual void cancelAllPiece();
+
+ virtual void sendPendingMessage();
+
+ void receiveMessages();
+
+ virtual uint32_t countPendingMessage() {
+ return dispatcher->countMessageInQueue();
+ }
+
+ virtual bool isSendingMessageInProgress() {
+ return dispatcher->isSendingInProgress();
+ }
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ this->peerStorage = PEER_STORAGE(btContext);
+ this->pieceStorage = PIECE_STORAGE(btContext);
+ }
+
+ void setBtMessageReceiver(const BtMessageReceiverHandle& receiver) {
+ this->btMessageReceiver = receiver;
+ }
+
+ void setDispatcher(const BtMessageDispatcherHandle& dispatcher) {
+ this->dispatcher = dispatcher;
+ }
+
+ void setBtRequestFactory(const BtRequestFactoryHandle& factory) {
+ this->btRequestFactory = factory;
+ }
+
+ void setPeerConnection(const PeerConnectionHandle& peerConnection) {
+ this->peerConnection = peerConnection;
+ }
+
+ void setOption(const Option* option) {
+ this->option = option;
+ }
+};
+
+typedef SharedHandle<DefaultBtInteractive> DefaultBtInteractiveHandle;
+
+#endif // _D_DEFAULT_BT_INTERACTIVE_H_
diff --git a/src/DefaultBtMessageDispatcher.cc b/src/DefaultBtMessageDispatcher.cc
new file mode 100644
index 00000000..18d0dbc0
--- /dev/null
+++ b/src/DefaultBtMessageDispatcher.cc
@@ -0,0 +1,214 @@
+/* <!-- 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 "DefaultBtMessageDispatcher.h"
+#include "BtRegistry.h"
+#include "prefs.h"
+#include "BtAbortOutstandingRequestEvent.h"
+#include "BtCancelSendingPieceEvent.h"
+#include "BtChokedEvent.h"
+#include "BtChokingEvent.h"
+#include "BtRegistry.h"
+#include "BtMessageFactory.h"
+
+void DefaultBtMessageDispatcher::addMessageToQueue(const BtMessageHandle& btMessage)
+{
+ btMessage->onQueued();
+ messageQueue.push_back(btMessage);
+}
+
+void DefaultBtMessageDispatcher::addMessageToQueue(const BtMessages& btMessages)
+{
+ for(BtMessages::const_iterator itr = btMessages.begin(); itr != btMessages.end(); itr++) {
+ addMessageToQueue(*itr);
+ }
+}
+
+
+void DefaultBtMessageDispatcher::sendMessages() {
+ BtMessages tempQueue;
+ int32_t uploadLimit = option->getAsInt(PREF_MAX_UPLOAD_LIMIT);
+ while(messageQueue.size() > 0) {
+ BtMessageHandle msg = messageQueue.front();
+ messageQueue.pop_front();
+ if(uploadLimit > 0) {
+ TransferStat stat = peerStorage->calculateStat();
+ if(uploadLimit < stat.getUploadSpeed() &&
+ msg->isUploading() && !msg->isSendingInProgress()) {
+ tempQueue.push_back(msg);
+ continue;
+ }
+ }
+ msg->send();
+ if(msg->isSendingInProgress()) {
+ messageQueue.push_front(msg);
+ break;
+ }
+ }
+ copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
+}
+
+// Cancel sending piece message to peer.
+void DefaultBtMessageDispatcher::doCancelSendingPieceAction(uint32_t index, uint32_t begin, uint32_t blockLength)
+{
+ BtCancelSendingPieceEventHandle event =
+ new BtCancelSendingPieceEvent(index, begin, blockLength);
+
+ BtMessages tempQueue = messageQueue;
+ for(BtMessages::iterator itr = tempQueue.begin(); itr != tempQueue.end(); itr++) {
+ (*itr)->handleEvent(event);
+ }
+}
+
+// Cancel sending piece message to peer.
+// TODO Is this method really necessary?
+void DefaultBtMessageDispatcher::doCancelSendingPieceAction(const PieceHandle& piece)
+{
+}
+
+// localhost cancels outstanding download requests to the peer.
+void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction(const PieceHandle& piece) {
+ for(RequestSlots::iterator itr = requestSlots.begin();
+ itr != requestSlots.end();) {
+ RequestSlot& slot = *itr;
+ if(slot.getIndex() == piece->getIndex()) {
+ logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d",
+ cuid,
+ slot.getIndex(),
+ slot.getBlockIndex());
+ piece->cancelBlock(slot.getBlockIndex());
+ itr = requestSlots.erase(itr);
+ } else {
+ itr++;
+ }
+ }
+
+ BtAbortOutstandingRequestEventHandle event =
+ new BtAbortOutstandingRequestEvent(piece);
+
+ BtMessages tempQueue = messageQueue;
+ for(BtMessages::iterator itr = tempQueue.begin(); itr != tempQueue.end(); ++itr) {
+ (*itr)->handleEvent(event);
+ }
+}
+
+// localhost received choke message from the peer.
+void DefaultBtMessageDispatcher::doChokedAction()
+{
+ for(RequestSlots::iterator itr = requestSlots.begin();
+ itr != requestSlots.end();) {
+ RequestSlot& slot = *itr;
+ logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d"
+ " because localhost got choked.",
+ cuid,
+ slot.getIndex(),
+ slot.getBlockIndex());
+ PieceHandle piece = pieceStorage->getPiece(slot.getIndex());
+ piece->cancelBlock(slot.getBlockIndex());
+ itr = requestSlots.erase(itr);
+ }
+
+ BtChokedEventHandle event = new BtChokedEvent();
+
+ BtMessages tempQueue = messageQueue;
+ for(BtMessages::iterator itr = tempQueue.begin(); itr != tempQueue.end(); ++itr) {
+ (*itr)->handleEvent(event);
+ }
+}
+
+// localhost dispatched choke message to the peer.
+void DefaultBtMessageDispatcher::doChokingAction()
+{
+ BtChokingEventHandle event = new BtChokingEvent();
+
+ BtMessages tempQueue = messageQueue;
+ for(BtMessages::iterator itr = tempQueue.begin(); itr != tempQueue.end(); ++itr) {
+ (*itr)->handleEvent(event);
+ }
+}
+
+void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing()
+{
+ for(RequestSlots::iterator itr = requestSlots.begin();
+ itr != requestSlots.end();) {
+ RequestSlot& slot = *itr;
+ PieceHandle piece = pieceStorage->getPiece(slot.getIndex());
+ if(slot.isTimeout(option->getAsInt(PREF_BT_REQUEST_TIMEOUT))) {
+ logger->debug("CUID#%d - Deleting request slot blockIndex=%d"
+ " because of time out",
+ cuid,
+ slot.getBlockIndex());
+ piece->cancelBlock(slot.getBlockIndex());
+ peer->snubbing = true;
+ itr = requestSlots.erase(itr);
+ } else if(piece->hasBlock(slot.getBlockIndex())) {
+ logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
+ " the block has been acquired.",
+ cuid,
+ slot.getBlockIndex());
+ addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
+ createCancelMessage(slot.getIndex(),
+ slot.getBegin(),
+ slot.getLength()));
+ itr = requestSlots.erase(itr);
+ } else {
+ itr++;
+ }
+ }
+}
+
+bool DefaultBtMessageDispatcher::isSendingInProgress()
+{
+ if(messageQueue.size() > 0) {
+ return messageQueue.front()->isSendingInProgress();
+ } else {
+ return false;
+ }
+}
+
+uint32_t DefaultBtMessageDispatcher::countOutstandingRequest()
+{
+ return requestSlots.size();
+}
+
+bool DefaultBtMessageDispatcher::isOutstandingRequest(uint32_t index, uint32_t blockIndex) {
+ for(RequestSlots::const_iterator itr = requestSlots.begin();
+ itr != requestSlots.end(); itr++) {
+ const RequestSlot& slot = *itr;
+ if(slot.getIndex() == index && slot.getBlockIndex() == blockIndex) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/DefaultBtMessageDispatcher.h b/src/DefaultBtMessageDispatcher.h
new file mode 100644
index 00000000..de325f65
--- /dev/null
+++ b/src/DefaultBtMessageDispatcher.h
@@ -0,0 +1,163 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_MESSAGE_DISPATCHER_H_
+#define _D_DEFAULT_BT_MESSAGE_DISPATCHER_H_
+
+#include "BtMessageDispatcher.h"
+#include "BtContext.h"
+#include "PeerStorage.h"
+#include "PieceStorage.h"
+#include "RequestSlot.h"
+#include "BtMessage.h"
+#include "Peer.h"
+#include "Option.h"
+#include "LogFactory.h"
+#include "Logger.h"
+#include "BtRegistry.h"
+
+class DefaultBtMessageDispatcher : public BtMessageDispatcher {
+private:
+ int32_t cuid;
+ BtMessages messageQueue;
+ RequestSlots requestSlots;
+ BtContextHandle btContext;
+ PeerStorageHandle peerStorage;
+ PieceStorageHandle pieceStorage;
+ PeerHandle peer;
+ const Option* option;
+ const Logger* logger;
+public:
+ DefaultBtMessageDispatcher():
+ cuid(0),
+ btContext(0),
+ peerStorage(0),
+ pieceStorage(0),
+ peer(0),
+ option(0),
+ logger(LogFactory::getInstance())
+ {
+ logger->debug("DefaultBtMessageDispatcher::instantiated");
+ }
+
+ virtual ~DefaultBtMessageDispatcher()
+ {
+ logger->debug("DefaultBtMessageDispatcher::deleted");
+ }
+
+ virtual void addMessageToQueue(const BtMessageHandle& btMessage);
+
+ virtual void addMessageToQueue(const BtMessages& btMessages);
+
+ virtual void sendMessages();
+
+ virtual void doCancelSendingPieceAction(uint32_t index, uint32_t begin, uint32_t blockLength);
+
+ virtual void doCancelSendingPieceAction(const PieceHandle& piece);
+
+ virtual void doAbortOutstandingRequestAction(const PieceHandle& piece);
+
+ virtual void doChokedAction();
+
+ virtual void doChokingAction();
+
+ virtual void checkRequestSlotAndDoNecessaryThing();
+
+ virtual bool isSendingInProgress();
+
+ virtual uint32_t countMessageInQueue() {
+ return messageQueue.size();
+ }
+
+ virtual uint32_t countOutstandingRequest();
+
+ virtual bool isOutstandingRequest(uint32_t index, uint32_t blockIndex);
+
+ virtual RequestSlot getOutstandingRequest(uint32_t index, uint32_t begin, uint32_t blockLength) {
+ for(RequestSlots::iterator itr = requestSlots.begin();
+ itr != requestSlots.end(); itr++) {
+ if(itr->getIndex() == index &&
+ itr->getBegin() == begin &&
+ itr->getLength() == blockLength) {
+ return *itr;
+ }
+ }
+ return RequestSlot::nullSlot;
+ }
+
+ virtual void removeOutstandingRequest(const RequestSlot& slot) {
+ RequestSlots temp;
+ remove_copy(requestSlots.begin(), requestSlots.end(), back_inserter(temp), slot);
+ requestSlots = temp;
+ }
+
+ virtual void addOutstandingRequest(const RequestSlot& requestSlot) {
+ if(!isOutstandingRequest(requestSlot.getIndex(), requestSlot.getBlockIndex())) {
+ requestSlots.push_back(requestSlot);
+ }
+ }
+
+ BtMessages& getMessageQueue() {
+ return messageQueue;
+ }
+
+ void setOption(const Option* option) {
+ this->option = option;
+ }
+
+ const Option* getOption() const {
+ return option;
+ }
+
+ RequestSlots& getRequestSlots() {
+ return requestSlots;
+ }
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ this->pieceStorage = PIECE_STORAGE(btContext);
+ this->peerStorage = PEER_STORAGE(btContext);
+ }
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+};
+
+typedef SharedHandle<DefaultBtMessageDispatcher> DefaultBtMessageDispatcherHandle;
+#endif // _D_DEFAULT_BT_MESSAGE_DISPATCHER_H_
diff --git a/src/DefaultBtMessageFactory.cc b/src/DefaultBtMessageFactory.cc
new file mode 100644
index 00000000..219635be
--- /dev/null
+++ b/src/DefaultBtMessageFactory.cc
@@ -0,0 +1,347 @@
+/* <!-- 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 "DefaultBtMessageFactory.h"
+#include "DlAbortEx.h"
+#include "PeerMessageUtil.h"
+#include "BtKeepAliveMessage.h"
+#include "BtChokeMessage.h"
+#include "BtUnchokeMessage.h"
+#include "BtInterestedMessage.h"
+#include "BtNotInterestedMessage.h"
+#include "BtHaveMessage.h"
+#include "BtHaveMessageValidator.h"
+#include "BtBitfieldMessage.h"
+#include "BtBitfieldMessageValidator.h"
+#include "BtRequestMessage.h"
+#include "BtRequestMessageValidator.h"
+#include "BtCancelMessage.h"
+#include "BtCancelMessageValidator.h"
+#include "BtPieceMessage.h"
+#include "BtPieceMessageValidator.h"
+#include "BtPortMessage.h"
+#include "BtHaveAllMessage.h"
+#include "BtHaveNoneMessage.h"
+#include "BtRejectMessage.h"
+#include "BtRejectMessageValidator.h"
+#include "BtSuggestPieceMessage.h"
+#include "BtSuggestPieceMessageValidator.h"
+#include "BtAllowedFastMessage.h"
+#include "BtAllowedFastMessageValidator.h"
+#include "BtHandshakeMessage.h"
+#include "BtHandshakeMessageValidator.h"
+
+BtMessageHandle
+DefaultBtMessageFactory::createBtMessage(const unsigned char* data, uint32_t dataLength)
+{
+ AbstractBtMessageHandle msg(0);
+ if(dataLength == 0) {
+ // keep-alive
+ msg = new BtKeepAliveMessage();
+ } else {
+ int32_t id = PeerMessageUtil::getId(data);
+ switch(id) {
+ case BtChokeMessage::ID:
+ msg = BtChokeMessage::create(data, dataLength);
+ break;
+ case BtUnchokeMessage::ID:
+ msg = BtUnchokeMessage::create(data, dataLength);
+ break;
+ case BtInterestedMessage::ID:
+ msg = BtInterestedMessage::create(data, dataLength);
+ break;
+ case BtNotInterestedMessage::ID:
+ msg = BtNotInterestedMessage::create(data, dataLength);
+ break;
+ case BtHaveMessage::ID:
+ msg = BtHaveMessage::create(data, dataLength);
+ msg->setBtMessageValidator(new BtHaveMessageValidator((BtHaveMessage*)msg.get(),
+ btContext->getNumPieces()));
+ break;
+ case BtBitfieldMessage::ID:
+ msg = BtBitfieldMessage::create(data, dataLength);
+ msg->setBtMessageValidator(new BtBitfieldMessageValidator((BtBitfieldMessage*)msg.get(),
+ btContext->getNumPieces()));
+ break;
+ case BtRequestMessage::ID: {
+ BtRequestMessageHandle temp = BtRequestMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtRequestMessageValidator(temp.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(temp->getIndex()));
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ case BtCancelMessage::ID: {
+ BtCancelMessageHandle temp = BtCancelMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtCancelMessageValidator(temp.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(temp->getIndex()));
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ case BtPieceMessage::ID: {
+ BtPieceMessageHandle temp = BtPieceMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtPieceMessageValidator(temp.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(temp->getIndex()));
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ case BtPortMessage::ID:
+ msg = BtPortMessage::create(data, dataLength);
+ break;
+ case BtHaveAllMessage::ID:
+ msg = BtHaveAllMessage::create(data, dataLength);
+ break;
+ case BtHaveNoneMessage::ID:
+ msg = BtHaveNoneMessage::create(data, dataLength);
+ break;
+ case BtRejectMessage::ID: {
+ BtRejectMessageHandle temp = BtRejectMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtRejectMessageValidator(temp.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(temp->getIndex()));
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ case BtSuggestPieceMessage::ID: {
+ BtSuggestPieceMessageHandle temp = BtSuggestPieceMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtSuggestPieceMessageValidator(temp.get(),
+ btContext->getNumPieces());
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ case BtAllowedFastMessage::ID: {
+ BtAllowedFastMessageHandle temp = BtAllowedFastMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtAllowedFastMessageValidator(temp.get(),
+ btContext->getNumPieces());
+ temp->setBtMessageValidator(validator);
+ msg = temp;
+ break;
+ }
+ default:
+ throw new DlAbortEx("Invalid message id. id = %d", id);
+ }
+ }
+ setCommonProperty(msg);
+ return msg;
+}
+
+void DefaultBtMessageFactory::setCommonProperty(const AbstractBtMessageHandle& msg) {
+ msg->setCuid(cuid);
+ msg->setPeer(peer);
+ msg->setBtContext(btContext);
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createHandshakeMessage(const unsigned char* data, uint32_t dataLength)
+{
+ BtHandshakeMessageHandle msg = BtHandshakeMessage::create(data, dataLength);
+ BtMessageValidatorHandle validator =
+ new BtHandshakeMessageValidator(msg.get(),
+ btContext->getInfoHash());
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createHandshakeMessage(const unsigned char* infoHash,
+ const unsigned char* peerId)
+{
+ BtHandshakeMessageHandle msg = new BtHandshakeMessage(infoHash, peerId);
+ BtMessageValidatorHandle validator =
+ new BtHandshakeMessageValidator(msg.get(),
+ btContext->getInfoHash());
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createRequestMessage(const PieceHandle& piece, uint32_t blockIndex)
+{
+ BtRequestMessageHandle msg =
+ new BtRequestMessage(piece->getIndex(),
+ blockIndex*piece->getBlockLength(),
+ piece->getBlockLength(blockIndex),
+ blockIndex);
+ BtMessageValidatorHandle validator =
+ new BtRequestMessageValidator(msg.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(msg->getIndex()));
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createCancelMessage(uint32_t index, uint32_t begin, uint32_t length)
+{
+ BtCancelMessageHandle msg = new BtCancelMessage(index, begin, length);
+ BtMessageValidatorHandle validator =
+ new BtCancelMessageValidator(msg.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(index));
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createPieceMessage(uint32_t index, uint32_t begin, uint32_t length)
+{
+ BtPieceMessageHandle msg = new BtPieceMessage(index, begin, length);
+ BtMessageValidatorHandle validator =
+ new BtPieceMessageValidator(msg.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(index));
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createHaveMessage(uint32_t index)
+{
+ BtHaveMessageHandle msg = new BtHaveMessage(index);
+ msg->setBtMessageValidator(new BtHaveMessageValidator(msg.get(),
+ btContext->getNumPieces()));
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createChokeMessage()
+{
+ BtChokeMessageHandle msg = new BtChokeMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createUnchokeMessage()
+{
+ BtUnchokeMessageHandle msg = new BtUnchokeMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createInterestedMessage()
+{
+ BtInterestedMessageHandle msg = new BtInterestedMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createNotInterestedMessage()
+{
+ BtNotInterestedMessageHandle msg = new BtNotInterestedMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createBitfieldMessage()
+{
+ BtBitfieldMessageHandle msg =
+ new BtBitfieldMessage(pieceStorage->getBitfield(),
+ pieceStorage->getBitfieldLength());
+ msg->setBtMessageValidator(new BtBitfieldMessageValidator(msg.get(),
+ btContext->getNumPieces()));
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createKeepAliveMessage()
+{
+ BtKeepAliveMessageHandle msg = new BtKeepAliveMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createHaveAllMessage()
+{
+ BtHaveAllMessageHandle msg = new BtHaveAllMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createHaveNoneMessage()
+{
+ BtHaveNoneMessageHandle msg = new BtHaveNoneMessage();
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createRejectMessage(uint32_t index, uint32_t begin, uint32_t length)
+{
+ BtRejectMessageHandle msg = new BtRejectMessage(index, begin, length);
+ BtMessageValidatorHandle validator =
+ new BtRejectMessageValidator(msg.get(),
+ btContext->getNumPieces(),
+ pieceStorage->getPieceLength(index));
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
+DefaultBtMessageFactory::createAllowedFastMessage(uint32_t index)
+{
+ BtAllowedFastMessageHandle msg = new BtAllowedFastMessage(index);
+ BtMessageValidatorHandle validator =
+ new BtAllowedFastMessageValidator(msg.get(),
+ btContext->getNumPieces());
+ msg->setBtMessageValidator(validator);
+ setCommonProperty(msg);
+ return msg;
+}
diff --git a/src/DefaultBtMessageFactory.h b/src/DefaultBtMessageFactory.h
new file mode 100644
index 00000000..b0e4b14e
--- /dev/null
+++ b/src/DefaultBtMessageFactory.h
@@ -0,0 +1,131 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_MESSAGE_FACTORY_H_
+#define _D_DEFAULT_BT_MESSAGE_FACTORY_H_
+
+#include "BtMessageFactory.h"
+#include "Peer.h"
+#include "AbstractBtMessage.h"
+#include "BtRegistry.h"
+
+class DefaultBtMessageFactory : public BtMessageFactory {
+private:
+ int32_t cuid;
+ BtContextHandle btContext;
+ PieceStorageHandle pieceStorage;
+ PeerHandle peer;
+
+ void setCommonProperty(const AbstractBtMessageHandle& msg);
+public:
+ DefaultBtMessageFactory():cuid(0),
+ btContext(0),
+ pieceStorage(0),
+ peer(0)
+ {
+ LogFactory::getInstance()->debug("DefaultBtMessageFactory::instantiated");
+ }
+
+ virtual ~DefaultBtMessageFactory()
+ {
+ LogFactory::getInstance()->debug("DefaultBtMessageFactory::deleted");
+ }
+
+ virtual BtMessageHandle
+ createBtMessage(const unsigned char* msg, uint32_t msgLength);
+
+ virtual BtMessageHandle
+ createHandshakeMessage(const unsigned char* msg, uint32_t msgLength);
+
+ virtual BtMessageHandle
+ createHandshakeMessage(const unsigned char* infoHash,
+ const unsigned char* peerId);
+
+ virtual BtMessageHandle
+ createRequestMessage(const PieceHandle& piece, uint32_t blockIndex);
+
+ virtual BtMessageHandle
+ createCancelMessage(uint32_t index, uint32_t begin, uint32_t length);
+
+ virtual BtMessageHandle
+ createPieceMessage(uint32_t index, uint32_t begin, uint32_t length);
+
+ virtual BtMessageHandle createHaveMessage(uint32_t index);
+
+ virtual BtMessageHandle createChokeMessage();
+
+ virtual BtMessageHandle createUnchokeMessage();
+
+ virtual BtMessageHandle createInterestedMessage();
+
+ virtual BtMessageHandle createNotInterestedMessage();
+
+ virtual BtMessageHandle createBitfieldMessage();
+
+ virtual BtMessageHandle createKeepAliveMessage();
+
+ virtual BtMessageHandle createHaveAllMessage();
+
+ virtual BtMessageHandle createHaveNoneMessage();
+
+ virtual BtMessageHandle
+ createRejectMessage(uint32_t index, uint32_t begin, uint32_t length);
+
+ virtual BtMessageHandle createAllowedFastMessage(uint32_t index);
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ PeerHandle getPeer() const {
+ return peer;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ this->pieceStorage = PIECE_STORAGE(btContext);
+ }
+
+ BtContextHandle getBtContext() const {
+ return btContext;
+ }
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+};
+
+typedef SharedHandle<DefaultBtMessageFactory> DefaultBtMessageFactoryHandle;
+
+#endif // _D_DEFAULT_BT_MESSAGE_FACTORY_H_
diff --git a/src/DefaultBtMessageReceiver.cc b/src/DefaultBtMessageReceiver.cc
new file mode 100644
index 00000000..119404fb
--- /dev/null
+++ b/src/DefaultBtMessageReceiver.cc
@@ -0,0 +1,95 @@
+/* <!-- 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 "DefaultBtMessageReceiver.h"
+#include "BtHandshakeMessage.h"
+
+BtMessageHandle DefaultBtMessageReceiver::receiveHandshake(bool quickReply) {
+ unsigned char data[BtHandshakeMessage::MESSAGE_LENGTH];
+ uint32_t dataLength = sizeof(data);
+ bool retval = peerConnection->receiveHandshake(data, dataLength);
+ // To handle tracker's NAT-checking feature
+ if(!handshakeSent && quickReply && dataLength >= 48) {
+ handshakeSent = true;
+ // check info_hash
+ if(memcmp(btContext->getInfoHash(), &data[28], INFO_HASH_LENGTH) == 0) {
+ sendHandshake();
+ }
+ }
+ if(!retval) {
+ return 0;
+ }
+ BtHandshakeMessageHandle msg =
+ BT_MESSAGE_FACTORY(btContext, peer)->createHandshakeMessage(data, dataLength);
+ Errors errors;
+ if(msg->validate(errors)) {
+ if(msg->isFastExtensionSupported()) {
+ peer->setFastExtensionEnabled(true);
+ logger->info("CUID#%d - Fast extension enabled.", cuid);
+ }
+ } else {
+ // TODO throw exception here based on errors
+ }
+ return msg;
+}
+
+BtMessageHandle DefaultBtMessageReceiver::receiveAndSendHandshake() {
+ return receiveHandshake(true);
+}
+
+void DefaultBtMessageReceiver::sendHandshake() {
+ BtHandshakeMessageHandle msg =
+ BT_MESSAGE_FACTORY(btContext, peer)->createHandshakeMessage(btContext->getInfoHash(),
+ btContext->getPeerId());
+ dispatcher->addMessageToQueue(msg);
+ dispatcher->sendMessages();
+}
+
+BtMessageHandle DefaultBtMessageReceiver::receiveMessage() {
+ unsigned char data[MAX_PAYLOAD_LEN];
+ uint32_t dataLength = 0;
+ if(!peerConnection->receiveMessage(data, dataLength)) {
+ return 0;
+ }
+ BtMessageHandle msg =
+ BT_MESSAGE_FACTORY(btContext, peer)->createBtMessage(data, dataLength);
+ Errors errors;
+ if(msg->validate(errors)) {
+ return msg;
+ } else {
+ // TODO throw exception here based on errors;
+ return 0;
+ }
+}
+
diff --git a/src/DefaultBtMessageReceiver.h b/src/DefaultBtMessageReceiver.h
new file mode 100644
index 00000000..b8d0f89e
--- /dev/null
+++ b/src/DefaultBtMessageReceiver.h
@@ -0,0 +1,120 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_MESSAGE_RECEIVER_H_
+#define _D_DEFAULT_BT_MESSAGE_RECEIVER_H_
+
+#include "BtMessageReceiver.h"
+#include "BtContext.h"
+#include "BtRegistry.h"
+#include "Peer.h"
+#include "PeerConnection.h"
+#include "BtMessageDispatcher.h"
+#include "Logger.h"
+#include "LogFactory.h"
+
+class DefaultBtMessageReceiver : public BtMessageReceiver {
+private:
+ int32_t cuid;
+ bool handshakeSent;
+ BtContextHandle btContext;
+ PeerHandle peer;
+ PeerConnectionHandle peerConnection;
+ BtMessageDispatcherHandle dispatcher;
+ const Logger* logger;
+
+ void sendHandshake();
+public:
+ DefaultBtMessageReceiver():cuid(0),
+ handshakeSent(false),
+ btContext(0),
+ peer(0),
+ peerConnection(0),
+ dispatcher(0),
+ logger(LogFactory::getInstance())
+ {
+ logger->debug("DefaultBtMessageReceiver::instantiated");
+ }
+
+ virtual ~DefaultBtMessageReceiver()
+ {
+ logger->debug("DefaultBtMessageReceiver::deleted");
+ }
+
+ virtual BtMessageHandle receiveHandshake(bool quickReply = false);
+
+ virtual BtMessageHandle receiveAndSendHandshake();
+
+ virtual BtMessageHandle receiveMessage();
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+
+ int32_t getCuid() const {
+ return cuid;
+ }
+
+ void setPeerConnection(const PeerConnectionHandle& peerConnection) {
+ this->peerConnection = peerConnection;
+ }
+
+ PeerConnectionHandle getPeerConnection() const {
+ return peerConnection;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ }
+
+ BtContextHandle getBtContext() const {
+ return btContext;
+ }
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ PeerHandle getPeer() const {
+ return peer;
+ }
+
+ void setDispatcher(const BtMessageDispatcherHandle& dispatcher) {
+ this->dispatcher = dispatcher;
+ }
+};
+
+typedef SharedHandle<DefaultBtMessageReceiver> DefaultBtMessageReceiverHandle;
+
+#endif // _D_DEFAULT_BT_MESSAGE_RECEIVER_H_
diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc
new file mode 100644
index 00000000..657f0631
--- /dev/null
+++ b/src/DefaultBtRequestFactory.cc
@@ -0,0 +1,99 @@
+/* <!-- 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 "DefaultBtRequestFactory.h"
+
+void DefaultBtRequestFactory::removeCompletedPiece() {
+ for(Pieces::iterator itr = pieces.begin(); itr != pieces.end();) {
+ PieceHandle& piece = *itr;
+ if(piece->pieceComplete()) {
+ dispatcher->doAbortOutstandingRequestAction(piece);
+ itr = pieces.erase(itr);
+ } else {
+ itr++;
+ }
+ }
+}
+
+void DefaultBtRequestFactory::removeTargetPiece(const PieceHandle& piece) {
+ Pieces temp;
+ remove_copy(pieces.begin(), pieces.end(), back_inserter(temp), piece);
+ pieces = temp;
+ dispatcher->doAbortOutstandingRequestAction(piece);
+ pieceStorage->cancelPiece(piece);
+}
+
+void DefaultBtRequestFactory::removeAllTargetPiece() {
+ for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
+ dispatcher->doAbortOutstandingRequestAction(*itr);
+ pieceStorage->cancelPiece(*itr);
+ }
+ pieces.clear();
+}
+
+BtMessages DefaultBtRequestFactory::createRequestMessages(int max) {
+ BtMessages requests;
+ for(Pieces::iterator itr = pieces.begin();
+ itr != pieces.end() && requests.size() < (size_t)max; itr++) {
+ PieceHandle& piece = *itr;
+ int blockIndex;
+ while(requests.size() < (size_t)max &&
+ (blockIndex = piece->getMissingUnusedBlockIndex()) != -1) {
+ requests.push_back(BT_MESSAGE_FACTORY(btContext, peer)->
+ createRequestMessage(piece, blockIndex));
+ }
+ }
+ return requests;
+}
+
+BtMessages DefaultBtRequestFactory::createRequestMessagesOnEndGame(int max) {
+ BtMessages requests;
+ for(Pieces::iterator itr = pieces.begin();
+ itr != pieces.end() && requests.size() < (size_t)max; itr++) {
+ PieceHandle& piece = *itr;
+ BlockIndexes missingBlockIndexes = piece->getAllMissingBlockIndexes();
+ random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
+ for(BlockIndexes::const_iterator bitr = missingBlockIndexes.begin();
+ bitr != missingBlockIndexes.end() && requests.size() < (size_t)max;
+ bitr++) {
+ int blockIndex = *bitr;
+ if(!dispatcher->isOutstandingRequest(piece->getIndex(),
+ blockIndex)) {
+ requests.push_back(BT_MESSAGE_FACTORY(btContext, peer)->
+ createRequestMessage(piece, blockIndex));
+ }
+ }
+ }
+ return requests;
+}
diff --git a/src/DefaultBtRequestFactory.h b/src/DefaultBtRequestFactory.h
new file mode 100644
index 00000000..c8c95a9a
--- /dev/null
+++ b/src/DefaultBtRequestFactory.h
@@ -0,0 +1,125 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_REQUEST_FACTORY_H_
+#define _D_DEFAULT_BT_REQUEST_FACTORY_H_
+
+#include "BtRequestFactory.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
+#include "Piece.h"
+#include "Peer.h"
+#include "BtMessageDispatcher.h"
+#include "BtRegistry.h"
+#include "LogFactory.h"
+
+class DefaultBtRequestFactory : public BtRequestFactory {
+private:
+ int cuid;
+ BtContextHandle btContext;
+ PieceStorageHandle pieceStorage;
+ PeerHandle peer;
+ BtMessageDispatcherHandle dispatcher;
+ Pieces pieces;
+public:
+ DefaultBtRequestFactory():
+ cuid(0),
+ btContext(0),
+ pieceStorage(0),
+ peer(0),
+ dispatcher(0)
+ {
+ LogFactory::getInstance()->debug("DefaultBtRequestFactory::instantiated");
+ }
+
+ virtual ~DefaultBtRequestFactory()
+ {
+ LogFactory::getInstance()->debug("DefaultBtRequestFactory::deleted");
+ }
+
+ virtual void addTargetPiece(const PieceHandle& piece) {
+ pieces.push_back(piece);
+ }
+
+ virtual void removeTargetPiece(const PieceHandle& piece);
+
+ virtual void removeAllTargetPiece();
+
+ virtual int countTargetPiece() {
+ return pieces.size();
+ }
+
+ virtual void removeCompletedPiece();
+
+ virtual BtMessages createRequestMessages(int max);
+
+ virtual BtMessages createRequestMessagesOnEndGame(int max);
+
+ Pieces& getTargetPieces() {
+ return pieces;
+ }
+
+ void setCuid(int32_t cuid) {
+ this->cuid = cuid;
+ }
+
+ int32_t getCuid() const {
+ return cuid;
+ }
+
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ this->pieceStorage = PIECE_STORAGE(btContext);
+ }
+
+ BtContextHandle getBtContext() const {
+ return btContext;
+ }
+
+ PeerHandle getPeer() const {
+ return peer;
+ }
+
+ void setPeer(const PeerHandle& peer) {
+ this->peer = peer;
+ }
+
+ void setBtMessageDispatcher(const BtMessageDispatcherHandle& dispatcher) {
+ this->dispatcher = dispatcher;
+ }
+};
+
+typedef SharedHandle<DefaultBtRequestFactory> DefaultBtRequestFactoryHandle;
+
+#endif // _D_DEFAULT_BT_REQUEST_FACTORY_H_
diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc
index 3344a1f0..39c6ae5c 100644
--- a/src/DefaultPeerStorage.cc
+++ b/src/DefaultPeerStorage.cc
@@ -36,14 +36,11 @@
#include "LogFactory.h"
#include "BtRegistry.h"
-extern PeerHandle nullPeer;
-
DefaultPeerStorage::DefaultPeerStorage(BtContextHandle btContext,
const Option* option):
btContext(btContext),
option(option),
maxPeerListSize(MAX_PEER_LIST_SIZE),
- peerEntryIdCounter(0),
btRuntime(BT_RUNTIME(btContext)),
removedPeerSessionDownloadLength(0),
removedPeerSessionUploadLength(0)
@@ -59,8 +56,6 @@ bool DefaultPeerStorage::addPeer(const PeerHandle& peer) {
if(peers.size() >= (size_t)maxPeerListSize) {
deleteUnusedPeer(peers.size()-maxPeerListSize+1);
}
- ++peerEntryIdCounter;
- peer->entryId = peerEntryIdCounter;
peers.push_back(peer);
return true;
} else {
@@ -100,7 +95,7 @@ PeerHandle DefaultPeerStorage::getUnusedPeer() {
Peers::const_iterator itr = find_if(peers.begin(), peers.end(),
FindFinePeer());
if(itr == peers.end()) {
- return nullPeer;
+ return 0;
} else {
return *itr;
}
@@ -123,7 +118,7 @@ PeerHandle DefaultPeerStorage::getPeer(const string& ipaddr,
Peers::const_iterator itr = find_if(peers.begin(), peers.end(),
FindPeer(ipaddr, port));
if(itr == peers.end()) {
- return nullPeer;
+ return 0;
} else {
return *itr;
}
@@ -134,7 +129,7 @@ int DefaultPeerStorage::countPeer() const {
}
bool DefaultPeerStorage::isPeerAvailable() {
- return getUnusedPeer() != nullPeer;
+ return !getUnusedPeer().isNull();
}
Peers DefaultPeerStorage::getActivePeers() {
diff --git a/src/DefaultPeerStorage.h b/src/DefaultPeerStorage.h
index 0bda4187..756700dd 100644
--- a/src/DefaultPeerStorage.h
+++ b/src/DefaultPeerStorage.h
@@ -50,7 +50,6 @@ private:
const Option* option;
Peers peers;
int maxPeerListSize;
- int peerEntryIdCounter;
Logger* logger;
BtRuntimeHandle btRuntime;
long long int removedPeerSessionDownloadLength;
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index 24fa364e..58f9d455 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -42,6 +42,7 @@
#include "MultiDiskWriter.h"
#include "PreAllocationDiskWriter.h"
#include "DlAbortEx.h"
+#include "BitfieldManFactory.h"
DefaultPieceStorage::DefaultPieceStorage(BtContextHandle btContext, const Option* option):
btContext(btContext),
@@ -49,13 +50,16 @@ DefaultPieceStorage::DefaultPieceStorage(BtContextHandle btContext, const Option
endGamePieceNum(END_GAME_PIECE_NUM),
option(option)
{
- bitfieldMan = new BitfieldMan(btContext->getPieceLength(),
- btContext->getTotalLength());
+ bitfieldMan =
+ BitfieldManFactory::getNewFactory()->
+ createBitfieldMan(btContext->getPieceLength(),
+ btContext->getTotalLength());
logger = LogFactory::getInstance();
}
DefaultPieceStorage::~DefaultPieceStorage() {
delete bitfieldMan;
+ delete diskAdaptor;
}
bool DefaultPieceStorage::hasMissingPiece(const PeerHandle& peer) {
@@ -79,15 +83,15 @@ int DefaultPieceStorage::getMissingPieceIndex(const PeerHandle& peer) {
return index;
}
-Piece DefaultPieceStorage::checkOutPiece(int index) {
+PieceHandle DefaultPieceStorage::checkOutPiece(int index) {
if(index == -1) {
- return Piece::nullPiece;
+ return 0;
}
bitfieldMan->setUseBit(index);
- Piece piece = findUsedPiece(index);
- if(Piece::isNull(piece)) {
- Piece piece(index, bitfieldMan->getBlockLength(index));
+ PieceHandle piece = findUsedPiece(index);
+ if(piece.isNull()) {
+ piece = new Piece(index, bitfieldMan->getBlockLength(index));
addUsedPiece(piece);
return piece;
} else {
@@ -95,8 +99,26 @@ Piece DefaultPieceStorage::checkOutPiece(int index) {
}
}
-void DefaultPieceStorage::addUsedPiece(const Piece& piece) {
- // TODO ? if nullPiece
+/**
+ * Newly instantiated piece is not added to usedPieces.
+ * Because it is waste of memory and there is no chance to use them later.
+ */
+PieceHandle DefaultPieceStorage::getPiece(int index) {
+ if(0 <= index && index <= bitfieldMan->getMaxIndex()) {
+ PieceHandle piece = findUsedPiece(index);
+ if(piece.isNull()) {
+ piece = new Piece(index, bitfieldMan->getBlockLength(index));
+ if(hasPiece(index)) {
+ piece->setAllBlock();
+ }
+ }
+ return piece;
+ } else {
+ return 0;
+ }
+}
+
+void DefaultPieceStorage::addUsedPiece(const PieceHandle& piece) {
usedPieces.push_back(piece);
}
@@ -106,23 +128,23 @@ private:
public:
FindPiece(int index):index(index) {}
- bool operator()(const Piece& piece) {
- return piece.getIndex() == index;
+ bool operator()(const PieceHandle& piece) {
+ return piece->getIndex() == index;
}
};
-Piece DefaultPieceStorage::findUsedPiece(int index) const {
+PieceHandle DefaultPieceStorage::findUsedPiece(int index) const {
Pieces::const_iterator itr = find_if(usedPieces.begin(),
usedPieces.end(),
FindPiece(index));
if(itr == usedPieces.end()) {
- return Piece::nullPiece;
+ return 0;
} else {
return *itr;
}
}
-Piece DefaultPieceStorage::getMissingPiece(const PeerHandle& peer) {
+PieceHandle DefaultPieceStorage::getMissingPiece(const PeerHandle& peer) {
int index = getMissingPieceIndex(peer);
return checkOutPiece(index);
}
@@ -149,13 +171,13 @@ int DefaultPieceStorage::getMissingFastPieceIndex(const PeerHandle& peer) {
return index;
}
-Piece DefaultPieceStorage::getMissingFastPiece(const PeerHandle& peer) {
+PieceHandle DefaultPieceStorage::getMissingFastPiece(const PeerHandle& peer) {
int index = getMissingFastPieceIndex(peer);
return checkOutPiece(index);
}
-void DefaultPieceStorage::deleteUsedPiece(const Piece& piece) {
- if(Piece::isNull(piece)) {
+void DefaultPieceStorage::deleteUsedPiece(const PieceHandle& piece) {
+ if(piece.isNull()) {
return;
}
Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(), piece);
@@ -185,12 +207,12 @@ int DefaultPieceStorage::deleteUsedPiecesByFillRate(int fillRate,
int deleted = 0;
for(Pieces::iterator itr = usedPieces.begin();
itr != usedPieces.end() && deleted < toDelete;) {
- Piece& piece = *itr;
- if(!bitfieldMan->isUseBitSet(piece.getIndex()) &&
- piece.countCompleteBlock() <= piece.countBlock()*(fillRate/100.0)) {
+ PieceHandle& piece = *itr;
+ if(!bitfieldMan->isUseBitSet(piece->getIndex()) &&
+ piece->countCompleteBlock() <= piece->countBlock()*(fillRate/100.0)) {
logger->debug("Deleting used piece index=%d, fillRate(%%)=%d<=%d",
- piece.getIndex(),
- (piece.countCompleteBlock()*100)/piece.countBlock(),
+ piece->getIndex(),
+ (piece->countCompleteBlock()*100)/piece->countBlock(),
fillRate);
itr = usedPieces.erase(itr);
deleted++;
@@ -201,8 +223,8 @@ int DefaultPieceStorage::deleteUsedPiecesByFillRate(int fillRate,
return deleted;
}
-void DefaultPieceStorage::completePiece(const Piece& piece) {
- if(Piece::isNull(piece)) {
+void DefaultPieceStorage::completePiece(const PieceHandle& piece) {
+ if(piece.isNull()) {
return;
}
deleteUsedPiece(piece);
@@ -212,8 +234,8 @@ void DefaultPieceStorage::completePiece(const Piece& piece) {
if(downloadFinished()) {
return;
}
- bitfieldMan->setBit(piece.getIndex());
- bitfieldMan->unsetUseBit(piece.getIndex());
+ bitfieldMan->setBit(piece->getIndex());
+ bitfieldMan->unsetUseBit(piece->getIndex());
if(downloadFinished()) {
diskAdaptor->onDownloadComplete();
if(isSelectiveDownloadingMode()) {
@@ -235,50 +257,18 @@ void DefaultPieceStorage::finishSelectiveDownloadingMode() {
}
// not unittested
-void DefaultPieceStorage::cancelPiece(const Piece& piece) {
- if(Piece::isNull(piece)) {
+void DefaultPieceStorage::cancelPiece(const PieceHandle& piece) {
+ if(piece.isNull()) {
return;
}
- updatePiece(piece);
- bitfieldMan->unsetUseBit(piece.getIndex());
+ bitfieldMan->unsetUseBit(piece->getIndex());
if(!isEndGame()) {
- if(piece.countCompleteBlock() == 0) {
+ if(piece->countCompleteBlock() == 0) {
deleteUsedPiece(piece);
}
}
}
-// not unittested
-void DefaultPieceStorage::updatePiece(const Piece& piece) {
- if(Piece::isNull(piece)) {
- return;
- }
- Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(),
- piece);
- if(itr != usedPieces.end()) {
- *itr = piece;
- }
-}
-
-// not unittested
-void DefaultPieceStorage::syncPiece(Piece& piece) {
- if(Piece::isNull(piece)) {
- return;
- }
- Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(),
- piece);
- if(itr != usedPieces.end()) {
- piece = *itr;
- return;
- } else {
- // hasPiece(piece.getIndex()) is true, then set all bit of
- // piece.bitfield to 1
- if(hasPiece(piece.getIndex())) {
- piece.setAllBlock();
- }
- }
-}
-
bool DefaultPieceStorage::hasPiece(int index) {
return bitfieldMan->isBitSet(index);
}
diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h
index 4b9a2066..2a41a4ce 100644
--- a/src/DefaultPieceStorage.h
+++ b/src/DefaultPieceStorage.h
@@ -77,29 +77,26 @@ private:
int getMissingPieceIndex(const PeerHandle& peer);
int getMissingFastPieceIndex(const PeerHandle& peer);
- Piece checkOutPiece(int index);
- void addUsedPiece(const Piece& piece);
- Piece findUsedPiece(int index) const;
+ PieceHandle checkOutPiece(int index);
int deleteUsedPiecesByFillRate(int fillRate, int toDelete);
void reduceUsedPieces(int delMax);
- void deleteUsedPiece(const Piece& piece);
+ void deleteUsedPiece(const PieceHandle& piece);
+ PieceHandle findUsedPiece(int index) const;
public:
DefaultPieceStorage(BtContextHandle btContext, const Option* option);
virtual ~DefaultPieceStorage();
virtual bool hasMissingPiece(const PeerHandle& peer);
- virtual Piece getMissingPiece(const PeerHandle& peer);
+ virtual PieceHandle getMissingPiece(const PeerHandle& peer);
- virtual Piece getMissingFastPiece(const PeerHandle& peer);
+ virtual PieceHandle getMissingFastPiece(const PeerHandle& peer);
- virtual void completePiece(const Piece& piece);
+ virtual PieceHandle getPiece(int index);
- virtual void cancelPiece(const Piece& piece);
+ virtual void completePiece(const PieceHandle& piece);
- virtual void updatePiece(const Piece& piece);
-
- virtual void syncPiece(Piece& piece);
+ virtual void cancelPiece(const PieceHandle& piece);
virtual bool hasPiece(int index);
@@ -153,6 +150,10 @@ public:
virtual void removeAdvertisedPiece(int elapsed);
+ /**
+ * This method is made private for test purpose only.
+ */
+ void addUsedPiece(const PieceHandle& piece);
};
#endif // _D_DEFAULT_PIECE_STORAGE_H_
diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc
index 2bb84da2..c688b03c 100644
--- a/src/DownloadEngineFactory.cc
+++ b/src/DownloadEngineFactory.cc
@@ -107,6 +107,24 @@ DownloadEngineFactory::newTorrentConsoleEngine(const BtContextHandle& btContext,
BtRegistry::registerBtProgressInfoFile(btContext->getInfoHashAsString(),
btProgressInfoFile);
+ BtRegistry::registerPeerObjectCluster(btContext->getInfoHashAsString(),
+ new PeerObjectCluster());
+
+ /*
+ DefaultBtMessageFactoryAdaptorHandle factoryAdaptor =
+ new DefaultBtMessageFactoryAdaptor();
+ BtRegistry::registerBtMessageFactoryAdaptor(btContext->getInfoHashAsString(),
+ factoryAdaptor);
+
+ BtMessageFactoryClusterHandle factoryCluster = new BtMessageFactoryCluster();
+ BtRegistry::registerBtMessageFactoryCluster(btContext->getInfoHashAsString(),
+ factoryCluster);
+
+ BtMessageDispatcherClusterHandle dispatcherCluster =
+ new BtMessageDispatcherCluster();
+ BtRegistry::registerBtMessageDispatcherCluster(btContext->getInfoHashAsString(),
+ dispatcherCluster);
+ */
te->setBtContext(btContext);
// initialize file storage
pieceStorage->initStorage();
diff --git a/src/HandleRegistry.h b/src/HandleRegistry.h
new file mode 100644
index 00000000..de8fca38
--- /dev/null
+++ b/src/HandleRegistry.h
@@ -0,0 +1,73 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_HANDLE_REGISTRY_H_
+#define _D_HANDLE_REGISTRY_H_
+
+#include "SharedHandle.h"
+#include <map>
+
+using namespace std;
+
+template<typename K, typename T>
+class HandleRegistry {
+ typedef map<K, SharedHandle<T> > HandleMap;
+private:
+ HandleMap handleMap;
+public:
+ void registerHandle(const K& key, const SharedHandle<T>& obj) {
+ unregisterHandle(key);
+ typename HandleMap::value_type p(key, obj);
+ handleMap.insert(p);
+ }
+
+ void unregisterHandle(const K& key) {
+ handleMap.erase(key);
+ }
+
+ SharedHandle<T> getHandle(const K& key) {
+ typename HandleMap::const_iterator itr = handleMap.find(key);
+ if(itr == handleMap.end()) {
+ return 0;
+ } else {
+ return itr->second;
+ }
+ }
+
+ void clear() {
+ handleMap.clear();
+ }
+};
+
+#endif // _D_HANDLE_REGISTRY_H_
diff --git a/src/Makefile.am b/src/Makefile.am
index e7860354..888d9f6c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,13 +49,18 @@ SRCS = Socket.h\
NullLogger.h\
TimeA2.cc TimeA2.h\
SharedHandle.h\
+ HandleRegistry.h\
FeatureConfig.cc FeatureConfig.h\
DownloadEngineFactory.cc DownloadEngineFactory.h\
RequestInfo.h\
UrlRequestInfo.cc UrlRequestInfo.h\
SpeedCalc.cc SpeedCalc.h\
PeerStat.h\
- BitfieldMan.cc BitfieldMan.h
+ BitfieldMan.cc BitfieldMan.h\
+ BitfieldManFactory.cc BitfieldManFactory.h\
+ Randomizer.h\
+ SimpleRandomizer.cc SimpleRandomizer.h
+# debug_new.cpp
if ENABLE_ASYNC_DNS
SRCS += NameResolver.cc NameResolver.h
@@ -138,7 +143,54 @@ SRCS += MetaEntry.h\
BtRuntime.h\
BtProgressInfoFile.h\
DefaultBtProgressInfoFile.cc DefaultBtProgressInfoFile.h\
- BtContextAwareCommand.cc BtContextAwareCommand.h
+ BtContextAwareCommand.cc BtContextAwareCommand.h\
+ BtMessage.h\
+ AbstractBtMessage.h\
+ SimpleBtMessage.cc SimpleBtMessage.h\
+ BtAllowedFastMessage.cc BtAllowedFastMessage.h\
+ BtBitfieldMessage.cc BtBitfieldMessage.h\
+ BtCancelMessage.cc BtCancelMessage.h\
+ BtChokeMessage.cc BtChokeMessage.h\
+ BtHaveAllMessage.cc BtHaveAllMessage.h\
+ BtHaveMessage.cc BtHaveMessage.h\
+ BtHaveNoneMessage.cc BtHaveNoneMessage.h\
+ BtInterestedMessage.cc BtInterestedMessage.h\
+ BtKeepAliveMessage.cc BtKeepAliveMessage.h\
+ BtNotInterestedMessage.cc BtNotInterestedMessage.h\
+ BtPieceMessage.cc BtPieceMessage.h\
+ BtPortMessage.cc BtPortMessage.h\
+ BtRejectMessage.cc BtRejectMessage.h\
+ BtRequestMessage.cc BtRequestMessage.h\
+ BtSuggestPieceMessage.cc BtSuggestPieceMessage.h\
+ BtUnchokeMessage.cc BtUnchokeMessage.h\
+ BtHandshakeMessage.cc BtHandshakeMessage.h\
+ BtMessageValidator.h\
+ BtAllowedFastMessageValidator.h\
+ BtBitfieldMessageValidator.h\
+ BtCancelMessageValidator.h\
+ BtHaveMessageValidator.h\
+ BtPieceMessageValidator.h\
+ BtRejectMessageValidator.h\
+ BtRequestMessageValidator.h\
+ BtSuggestPieceMessageValidator.h\
+ BtHandshakeMessageValidator.h\
+ BtMessageFactory.h\
+ DefaultBtMessageFactory.cc DefaultBtMessageFactory.h\
+ BtMessageDispatcher.h\
+ DefaultBtMessageDispatcher.cc DefaultBtMessageDispatcher.h\
+ BtMessageReceiver.h\
+ DefaultBtMessageReceiver.cc DefaultBtMessageReceiver.h\
+ BtRequestFactory.h\
+ DefaultBtRequestFactory.cc DefaultBtRequestFactory.h\
+ BtEvent.h\
+ BtEventListener.h\
+ BtCancelSendingPieceEvent.h\
+ BtAbortOutstandingRequestEvent.h\
+ BtChokedEvent.h\
+ BtChokingEvent.h\
+ BtInteractive.h\
+ DefaultBtInteractive.cc DefaultBtInteractive.h\
+ PeerObject.h
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
diff --git a/src/Makefile.in b/src/Makefile.in
index 3ebd9e44..b1458c07 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -115,7 +115,54 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ BtRuntime.h\
@ENABLE_BITTORRENT_TRUE@ BtProgressInfoFile.h\
@ENABLE_BITTORRENT_TRUE@ DefaultBtProgressInfoFile.cc DefaultBtProgressInfoFile.h\
-@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.cc BtContextAwareCommand.h
+@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.cc BtContextAwareCommand.h\
+@ENABLE_BITTORRENT_TRUE@ BtMessage.h\
+@ENABLE_BITTORRENT_TRUE@ AbstractBtMessage.h\
+@ENABLE_BITTORRENT_TRUE@ SimpleBtMessage.cc SimpleBtMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtAllowedFastMessage.cc BtAllowedFastMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessage.cc BtBitfieldMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtCancelMessage.cc BtCancelMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtChokeMessage.cc BtChokeMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtHaveAllMessage.cc BtHaveAllMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtHaveMessage.cc BtHaveMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtHaveNoneMessage.cc BtHaveNoneMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtInterestedMessage.cc BtInterestedMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtKeepAliveMessage.cc BtKeepAliveMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtNotInterestedMessage.cc BtNotInterestedMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtPieceMessage.cc BtPieceMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtPortMessage.cc BtPortMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtRejectMessage.cc BtRejectMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtRequestMessage.cc BtRequestMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtSuggestPieceMessage.cc BtSuggestPieceMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtUnchokeMessage.cc BtUnchokeMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtHandshakeMessage.cc BtHandshakeMessage.h\
+@ENABLE_BITTORRENT_TRUE@ BtMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtAllowedFastMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtCancelMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtHaveMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtPieceMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtRejectMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtRequestMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtSuggestPieceMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtHandshakeMessageValidator.h\
+@ENABLE_BITTORRENT_TRUE@ BtMessageFactory.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactory.cc DefaultBtMessageFactory.h\
+@ENABLE_BITTORRENT_TRUE@ BtMessageDispatcher.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageDispatcher.cc DefaultBtMessageDispatcher.h\
+@ENABLE_BITTORRENT_TRUE@ BtMessageReceiver.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageReceiver.cc DefaultBtMessageReceiver.h\
+@ENABLE_BITTORRENT_TRUE@ BtRequestFactory.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtRequestFactory.cc DefaultBtRequestFactory.h\
+@ENABLE_BITTORRENT_TRUE@ BtEvent.h\
+@ENABLE_BITTORRENT_TRUE@ BtEventListener.h\
+@ENABLE_BITTORRENT_TRUE@ BtCancelSendingPieceEvent.h\
+@ENABLE_BITTORRENT_TRUE@ BtAbortOutstandingRequestEvent.h\
+@ENABLE_BITTORRENT_TRUE@ BtChokedEvent.h\
+@ENABLE_BITTORRENT_TRUE@ BtChokingEvent.h\
+@ENABLE_BITTORRENT_TRUE@ BtInteractive.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtInteractive.cc DefaultBtInteractive.h\
+@ENABLE_BITTORRENT_TRUE@ PeerObject.h
@ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@@ -178,16 +225,19 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
AbstractDiskWriter.cc AbstractDiskWriter.h File.cc File.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \
- TimeA2.cc TimeA2.h SharedHandle.h FeatureConfig.cc \
- FeatureConfig.h DownloadEngineFactory.cc \
+ TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \
+ FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \
- BitfieldMan.cc BitfieldMan.h NameResolver.cc NameResolver.h \
- MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \
- List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
- ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \
- PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
- PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
+ BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
+ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
+ SimpleRandomizer.h debug_new.cpp NameResolver.cc \
+ NameResolver.h MetaEntry.h Data.cc Data.h Dictionary.cc \
+ Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
+ MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h \
+ PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
+ PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
+ PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h \
TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@@ -231,9 +281,38 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
DefaultBtAnnounce.h BtRegistry.cc BtRegistry.h BtRuntime.h \
BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
DefaultBtProgressInfoFile.h BtContextAwareCommand.cc \
- BtContextAwareCommand.h Metalinker.cc Metalinker.h \
- MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
- MetalinkResource.h MetalinkProcessor.h \
+ BtContextAwareCommand.h BtMessage.h AbstractBtMessage.h \
+ SimpleBtMessage.cc SimpleBtMessage.h BtAllowedFastMessage.cc \
+ BtAllowedFastMessage.h BtBitfieldMessage.cc \
+ BtBitfieldMessage.h BtCancelMessage.cc BtCancelMessage.h \
+ BtChokeMessage.cc BtChokeMessage.h BtHaveAllMessage.cc \
+ BtHaveAllMessage.h BtHaveMessage.cc BtHaveMessage.h \
+ BtHaveNoneMessage.cc BtHaveNoneMessage.h \
+ BtInterestedMessage.cc BtInterestedMessage.h \
+ BtKeepAliveMessage.cc BtKeepAliveMessage.h \
+ BtNotInterestedMessage.cc BtNotInterestedMessage.h \
+ BtPieceMessage.cc BtPieceMessage.h BtPortMessage.cc \
+ BtPortMessage.h BtRejectMessage.cc BtRejectMessage.h \
+ BtRequestMessage.cc BtRequestMessage.h \
+ BtSuggestPieceMessage.cc BtSuggestPieceMessage.h \
+ BtUnchokeMessage.cc BtUnchokeMessage.h BtHandshakeMessage.cc \
+ BtHandshakeMessage.h BtMessageValidator.h \
+ BtAllowedFastMessageValidator.h BtBitfieldMessageValidator.h \
+ BtCancelMessageValidator.h BtHaveMessageValidator.h \
+ BtPieceMessageValidator.h BtRejectMessageValidator.h \
+ BtRequestMessageValidator.h BtSuggestPieceMessageValidator.h \
+ BtHandshakeMessageValidator.h BtMessageFactory.h \
+ DefaultBtMessageFactory.cc DefaultBtMessageFactory.h \
+ BtMessageDispatcher.h DefaultBtMessageDispatcher.cc \
+ DefaultBtMessageDispatcher.h BtMessageReceiver.h \
+ DefaultBtMessageReceiver.cc DefaultBtMessageReceiver.h \
+ BtRequestFactory.h DefaultBtRequestFactory.cc \
+ DefaultBtRequestFactory.h BtEvent.h BtEventListener.h \
+ BtCancelSendingPieceEvent.h BtAbortOutstandingRequestEvent.h \
+ BtChokedEvent.h BtChokingEvent.h BtInteractive.h \
+ DefaultBtInteractive.cc DefaultBtInteractive.h PeerObject.h \
+ Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
+ MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \
MetalinkRequestInfo.cc MetalinkRequestInfo.h
@ENABLE_ASYNC_DNS_TRUE@am__objects_1 = NameResolver.$(OBJEXT)
@@ -297,7 +376,30 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ DefaultBtAnnounce.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ BtRegistry.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultBtProgressInfoFile.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ SimpleBtMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtAllowedFastMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtCancelMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtChokeMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtHaveAllMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtHaveMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtHaveNoneMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtInterestedMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtKeepAliveMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtNotInterestedMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtPieceMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtPortMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtRejectMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtRequestMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtSuggestPieceMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtUnchokeMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtHandshakeMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactory.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageDispatcher.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageReceiver.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtRequestFactory.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtInteractive.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@@ -326,8 +428,9 @@ am__objects_4 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) TimeA2.$(OBJEXT) \
FeatureConfig.$(OBJEXT) DownloadEngineFactory.$(OBJEXT) \
UrlRequestInfo.$(OBJEXT) SpeedCalc.$(OBJEXT) \
- BitfieldMan.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
- $(am__objects_3)
+ BitfieldMan.$(OBJEXT) BitfieldManFactory.$(OBJEXT) \
+ SimpleRandomizer.$(OBJEXT) debug_new.$(OBJEXT) \
+ $(am__objects_1) $(am__objects_2) $(am__objects_3)
am_libaria2c_a_OBJECTS = $(am__objects_4)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@@ -525,12 +628,14 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
AbstractDiskWriter.cc AbstractDiskWriter.h File.cc File.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \
- TimeA2.cc TimeA2.h SharedHandle.h FeatureConfig.cc \
- FeatureConfig.h DownloadEngineFactory.cc \
+ TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \
+ FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \
- BitfieldMan.cc BitfieldMan.h $(am__append_1) $(am__append_2) \
- $(am__append_3)
+ BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
+ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
+ SimpleRandomizer.h debug_new.cpp $(am__append_1) \
+ $(am__append_2) $(am__append_3)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@@ -547,7 +652,7 @@ AM_CPPFLAGS = -Wall\
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .o .obj
+.SUFFIXES: .cc .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -624,9 +729,27 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceList.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtBitfieldMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtCancelMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtChokeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtContextAwareCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHandshakeMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveAllMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveNoneMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtInterestedMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtKeepAliveMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtNotInterestedMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtPieceMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtPortMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtRegistry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtRejectMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtRequestMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtSuggestPieceMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtUnchokeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CancelMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChokeMessage.Po@am__quote@
@@ -639,7 +762,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Data.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtAnnounce.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtContext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtInteractive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageDispatcher.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageFactory.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageReceiver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorage.Po@am__quote@
@@ -712,8 +840,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Segment.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimplePeerMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleRandomizer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SleepCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketCore.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalc.Po@am__quote@
@@ -729,6 +859,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlRequestInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_new.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
.cc.o:
@@ -744,6 +875,20 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
diff --git a/src/Peer.cc b/src/Peer.cc
index 9016c9cc..b9591d23 100644
--- a/src/Peer.cc
+++ b/src/Peer.cc
@@ -33,8 +33,33 @@
*/
/* copyright --> */
#include "Peer.h"
+#include "BitfieldManFactory.h"
+#include "Util.h"
-PeerHandle nullPeer = PeerHandle(new Peer("", 0, 0, 0));
+Peer::Peer(string ipaddr, int port, int pieceLength, long long int totalLength):
+ ipaddr(ipaddr),
+ port(port),
+ error(0),
+ sessionUploadLength(0),
+ sessionDownloadLength(0),
+ pieceLength(pieceLength),
+ active(false)
+{
+ resetStatus();
+ this->bitfield = BitfieldManFactory::getNewFactory()->
+ createBitfieldMan(pieceLength, totalLength);
+ string idSeed = ipaddr+":"+Util::itos(port);
+ id = Util::simpleMessageDigest(idSeed);
+}
+
+/*
+Peer::Peer():entryId(0), ipaddr(""), port(0), bitfield(0),
+ sessionUploadLength(0), sessionDownloadLength(0),
+ pieceLength(0)
+{
+ resetStatus();
+}
+*/
void Peer::updateBitfield(int index, int operation) {
if(operation == 1) {
@@ -74,6 +99,8 @@ void Peer::resetStatus() {
fastExtensionEnabled = false;
latency = DEFAULT_LATENCY;
fastSet.clear();
+ peerAllowedIndexSet.clear();
+ amAllowedIndexSet.clear();
peerStat.reset();
}
@@ -87,6 +114,28 @@ void Peer::addFastSetIndex(int index) {
}
}
+bool Peer::isInPeerAllowedIndexSet(int index) const {
+ return find(peerAllowedIndexSet.begin(), peerAllowedIndexSet.end(),
+ index) != peerAllowedIndexSet.end();
+}
+
+void Peer::addPeerAllowedIndex(int index) {
+ if(!isInPeerAllowedIndexSet(index)) {
+ peerAllowedIndexSet.push_back(index);
+ }
+}
+
+bool Peer::isInAmAllowedIndexSet(int index) const {
+ return find(amAllowedIndexSet.begin(), amAllowedIndexSet.end(),
+ index) != amAllowedIndexSet.end();
+}
+
+void Peer::addAmAllowedIndex(int index) {
+ if(!isInAmAllowedIndexSet(index)) {
+ amAllowedIndexSet.push_back(index);
+ }
+}
+
void Peer::setAllBitfield() {
bitfield->setAllBit();
}
diff --git a/src/Peer.h b/src/Peer.h
index c7af34ee..cecd27f9 100644
--- a/src/Peer.h
+++ b/src/Peer.h
@@ -51,7 +51,6 @@ class Peer {
friend bool operator==(const Peer& p1, const Peer& p2);
friend bool operator!=(const Peer& p1, const Peer& p2);
public:
- int entryId;
string ipaddr;
int port;
bool amChoking;
@@ -65,42 +64,32 @@ public:
bool optUnchoking;
bool snubbing;
private:
- char peerId[PEER_ID_LENGTH];
+ unsigned char peerId[PEER_ID_LENGTH];
BitfieldMan* bitfield;
bool fastExtensionEnabled;
// allowed fast indexes that peer has sent by Allowed Fast message
Integers fastSet;
+ // fast index set which a peer has sent to localhost.
+ Integers peerAllowedIndexSet;
+ // fast index set which localhost has sent to a peer.
+ Integers amAllowedIndexSet;
PeerStat peerStat;
long long int sessionUploadLength;
long long int sessionDownloadLength;
int pieceLength;
int latency;
bool active;
+ string id;
public:
- Peer(string ipaddr, int port, int pieceLength, long long int totalLength):
- entryId(0), ipaddr(ipaddr), port(port), error(0),
- sessionUploadLength(0), sessionDownloadLength(0),
- pieceLength(pieceLength), active(false)
- {
- resetStatus();
- this->bitfield = new BitfieldMan(pieceLength, totalLength);
- }
-
- Peer():entryId(0), ipaddr(""), port(0), bitfield(0),
- sessionUploadLength(0), sessionDownloadLength(0),
- pieceLength(0)
- {
- resetStatus();
- }
+ Peer(string ipaddr, int port, int pieceLength, long long int totalLength);
~Peer() {
- if(bitfield != NULL) {
- delete bitfield;
- }
+ delete bitfield;
}
bool operator==(const Peer& p) {
- return ipaddr == p.ipaddr && port == p.port;
+ //return ipaddr == p.ipaddr && port == p.port;
+ return id == p.id;
}
bool operator!=(const Peer& p) {
@@ -161,10 +150,10 @@ public:
return active;
}
- void setPeerId(const char* peerId) {
+ void setPeerId(const unsigned char* peerId) {
memcpy(this->peerId, peerId, PEER_ID_LENGTH);
}
- const char* getPeerId() const { return this->peerId; }
+ const unsigned char* getPeerId() const { return this->peerId; }
void setBitfield(const unsigned char* bitfield, int bitfieldLength) {
this->bitfield->setBitfield(bitfield, bitfieldLength);
@@ -189,6 +178,12 @@ public:
bool isInFastSet(int index) const;
int countFastSet() const { return fastSet.size(); }
+ void addPeerAllowedIndex(int index);
+ bool isInPeerAllowedIndexSet(int index) const;
+
+ void addAmAllowedIndex(int index);
+ bool isInAmAllowedIndexSet(int index) const;
+
bool shouldBeChoking() const;
bool hasPiece(int index) const;
@@ -197,6 +192,10 @@ public:
void updateLatency(int latency);
int getLatency() const { return latency; }
+
+ const string& getId() const {
+ return id;
+ }
};
typedef SharedHandle<Peer> PeerHandle;
diff --git a/src/PeerConnection.cc b/src/PeerConnection.cc
index e8a5257e..6608149a 100644
--- a/src/PeerConnection.cc
+++ b/src/PeerConnection.cc
@@ -38,9 +38,10 @@
#include "PeerMessageUtil.h"
#include "Util.h"
#include "LogFactory.h"
+#include "BtHandshakeMessage.h"
#include <netinet/in.h>
-PeerConnection::PeerConnection(int cuid,
+PeerConnection::PeerConnection(int32_t cuid,
const SocketHandle& socket,
const Option* op)
:cuid(cuid),
@@ -55,24 +56,26 @@ PeerConnection::PeerConnection(int cuid,
PeerConnection::~PeerConnection() {}
-int PeerConnection::sendMessage(const char* msg, int length) {
- int writtenLength = 0;
+uint32_t PeerConnection::sendMessage(const unsigned char* data, uint32_t dataLength) {
+ uint32_t writtenLength = 0;
if(socket->isWritable(0)) {
- socket->writeData(msg, length);
- writtenLength += length;
+ // TODO fix this
+ socket->writeData((const char*)data, dataLength);
+ writtenLength += dataLength;
}
return writtenLength;
}
-bool PeerConnection::receiveMessage(char* msg, int& length) {
+bool PeerConnection::receiveMessage(unsigned char* data, uint32_t& dataLength) {
if(!socket->isReadable(0)) {
return false;
}
if(resbufLength == 0 && lenbufLength != 4) {
// read payload size, 4-byte integer
- int remain = 4-lenbufLength;
- int temp = remain;
- socket->readData(lenbuf+lenbufLength, temp);
+ uint32_t remain = 4-lenbufLength;
+ uint32_t temp = remain;
+ // TODO fix this
+ socket->readData((char*)lenbuf+lenbufLength, (int&)temp);
if(temp == 0) {
// we got EOF
throw new DlAbortEx(EX_EOF_FROM_PEER);
@@ -83,7 +86,7 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
return false;
}
//payloadLen = ntohl(nPayloadLen);
- int payloadLength = ntohl(*((int*)lenbuf));
+ uint32_t payloadLength = ntohl(*((uint32_t*)lenbuf));
if(payloadLength > MAX_PAYLOAD_LEN || payloadLength < 0) {
throw new DlAbortEx("max payload length exceeded or invalid. length = %d",
payloadLength);
@@ -91,9 +94,9 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
currentPayloadLength = payloadLength;
}
// we have currentPayloadLen-resbufLen bytes to read
- int remaining = currentPayloadLength-resbufLength;
+ uint32_t remaining = currentPayloadLength-resbufLength;
if(remaining > 0) {
- socket->readData(resbuf+resbufLength, remaining);
+ socket->readData((char*)resbuf+resbufLength, (int&)remaining);
if(remaining == 0) {
// we got EOF
throw new DlAbortEx(EX_EOF_FROM_PEER);
@@ -107,19 +110,19 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
resbufLength = 0;
lenbufLength = 0;
- memcpy(msg, resbuf, currentPayloadLength);
- length = currentPayloadLength;
+ memcpy(data, resbuf, currentPayloadLength);
+ dataLength = currentPayloadLength;
return true;
}
-bool PeerConnection::receiveHandshake(char* msg, int& length) {
+bool PeerConnection::receiveHandshake(unsigned char* data, uint32_t& dataLength) {
if(!socket->isReadable(0)) {
- length = 0;
+ dataLength = 0;
return false;
}
- int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
- int temp = remain;
- socket->readData(resbuf+resbufLength, temp);
+ uint32_t remain = BtHandshakeMessage::MESSAGE_LENGTH-resbufLength;
+ uint32_t temp = remain;
+ socket->readData((char*)resbuf+resbufLength, (int&)temp);
if(temp == 0) {
// we got EOF
throw new DlAbortEx(EX_EOF_FROM_PEER);
@@ -132,9 +135,9 @@ bool PeerConnection::receiveHandshake(char* msg, int& length) {
}
resbufLength += temp;
// we got whole handshake payload
- int writeLength = resbufLength > length ? length : resbufLength;
- memcpy(msg, resbuf, writeLength);
- length = writeLength;
+ uint32_t writeLength = resbufLength > dataLength ? dataLength : resbufLength;
+ memcpy(data, resbuf, writeLength);
+ dataLength = writeLength;
if(retval) {
resbufLength = 0;
}
diff --git a/src/PeerConnection.h b/src/PeerConnection.h
index de52f004..5787db80 100644
--- a/src/PeerConnection.h
+++ b/src/PeerConnection.h
@@ -38,7 +38,6 @@
#include "Option.h"
#include "Socket.h"
#include "Logger.h"
-#include "PeerMessage.h"
#include "common.h"
// we assume maximum length of incoming message is "piece" message with 16KB
@@ -47,32 +46,44 @@
class PeerConnection {
private:
- int cuid;
+ int32_t cuid;
SocketHandle socket;
const Option* option;
const Logger* logger;
char resbuf[MAX_PAYLOAD_LEN];
- int resbufLength;
- int currentPayloadLength;
- char lenbuf[4];
- int lenbufLength;
+ uint32_t resbufLength;
+ uint32_t currentPayloadLength;
+ unsigned char lenbuf[4];
+ uint32_t lenbufLength;
public:
- PeerConnection(int cuid, const SocketHandle& socket, const Option* op);
+ PeerConnection(int32_t cuid, const SocketHandle& socket, const Option* op);
~PeerConnection();
// Returns the number of bytes written
- int sendMessage(const char* msg, int length);
+ uint32_t sendMessage(const unsigned char* data, uint32_t dataLength);
+ uint32_t sendMessage(const char* msg, int length) {
+ return sendMessage((const unsigned char*)msg, (uint32_t)length);
+ }
+
+ bool receiveMessage(unsigned char* data, uint32_t& dataLength);
+ bool receiveMessage(char* msg, int& length) {
+ return receiveMessage((unsigned char*)msg, (uint32_t&)length);
+ }
- bool receiveMessage(char* msg, int& length);
/**
* Returns true if a handshake message is fully received, otherwise returns
* false.
* In both cases, 'msg' is filled with received bytes and the filled length
* is assigned to 'length'.
*/
- bool receiveHandshake(char* msg, int& length);
+ bool receiveHandshake(unsigned char* data, uint32_t& dataLength);
+ bool receiveHandshake(char* msg, int& length) {
+ return receiveHandshake((unsigned char*)msg, (uint32_t&)length);
+ }
};
+typedef SharedHandle<PeerConnection> PeerConnectionHandle;
+
#endif // _D_PEER_CONNECTION_H_
diff --git a/src/PeerInteraction.cc b/src/PeerInteraction.cc
index 1ec87ce0..bed01a01 100644
--- a/src/PeerInteraction.cc
+++ b/src/PeerInteraction.cc
@@ -123,8 +123,8 @@ void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length
void PeerInteraction::onChoked() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end();) {
- Piece& piece = *itr;
- if(!peer->isInFastSet(piece.getIndex())) {
+ PieceHandle& piece = *itr;
+ if(!peer->isInFastSet(piece->getIndex())) {
abortPiece(piece);
itr = pieces.erase(itr);
} else {
@@ -140,20 +140,20 @@ void PeerInteraction::abortAllPieces() {
}
}
-void PeerInteraction::abortPiece(Piece& piece) {
- if(!Piece::isNull(piece)) {
+void PeerInteraction::abortPiece(const PieceHandle& piece) {
+ if(!piece.isNull()) {
int size = messageQueue.size();
for(int i = 0; i < size; i++) {
messageQueue.at(i)->onAbortPiece(piece);
}
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
- if(itr->getIndex() == piece.getIndex()) {
+ if(itr->getIndex() == piece->getIndex()) {
logger->debug("CUID#%d - Deleting request slot blockIndex=%d"
" because piece was canceled",
cuid,
itr->getBlockIndex());
- piece.cancelBlock(itr->getBlockIndex());
+ piece->cancelBlock(itr->getBlockIndex());
itr = requestSlots.erase(itr);
} else {
itr++;
@@ -181,14 +181,14 @@ void PeerInteraction::checkRequestSlot() {
" because of time out",
cuid,
slot.getBlockIndex());
- Piece& piece = getDownloadPiece(slot.getIndex());
- piece.cancelBlock(slot.getBlockIndex());
+ PieceHandle 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()) ||
- pieceStorage->hasPiece(piece.getIndex())) {
+ PieceHandle piece = getDownloadPiece(slot.getIndex());
+ if(piece->hasBlock(slot.getBlockIndex()) ||
+ pieceStorage->hasPiece(piece->getIndex())) {
logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
" the block has been acquired.", cuid,
slot.getBlockIndex());
@@ -275,15 +275,19 @@ PeerMessageHandle PeerInteraction::receiveMessage() {
}
void PeerInteraction::syncPiece() {
+ /*
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
pieceStorage->syncPiece(*itr);
}
+ */
}
void PeerInteraction::updatePiece() {
+ /*
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
pieceStorage->updatePiece(*itr);
}
+ */
}
void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
@@ -297,8 +301,8 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
onChoked();
if(peer->isFastExtensionEnabled()) {
while((int)pieces.size() < pieceNum) {
- Piece piece = pieceStorage->getMissingFastPiece(peer);
- if(Piece::isNull(piece)) {
+ PieceHandle piece = pieceStorage->getMissingFastPiece(peer);
+ if(piece.isNull()) {
break;
} else {
pieces.push_back(piece);
@@ -307,8 +311,8 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
}
} else {
while((int)pieces.size() < pieceNum) {
- Piece piece = pieceStorage->getMissingPiece(peer);
- if(Piece::isNull(piece)) {
+ PieceHandle piece = pieceStorage->getMissingPiece(peer);
+ if(piece.isNull()) {
break;
} else {
pieces.push_back(piece);
@@ -325,8 +329,8 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
void PeerInteraction::addRequests() {
// Abort downloading of completed piece.
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end();) {
- Piece& piece = *itr;
- if(piece.pieceComplete()) {
+ PieceHandle& piece = *itr;
+ if(piece->pieceComplete()) {
abortPiece(piece);
itr = pieces.erase(itr);
} else {
@@ -350,16 +354,16 @@ void PeerInteraction::addRequests() {
}
getNewPieceAndSendInterest(pieceNum);
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
- Piece& piece = *itr;
+ PieceHandle& piece = *itr;
if(pieceStorage->isEndGame()) {
- BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
+ BlockIndexes missingBlockIndexes = piece->getAllMissingBlockIndexes();
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
int count = countRequestSlot();
for(BlockIndexes::const_iterator bitr = missingBlockIndexes.begin();
bitr != missingBlockIndexes.end() && count < MAX_PENDING_REQUEST;
bitr++) {
int blockIndex = *bitr;
- if(!isInRequestSlot(piece.getIndex(), blockIndex)) {
+ if(!isInRequestSlot(piece->getIndex(), blockIndex)) {
addMessage(peerMessageFactory->createRequestMessage(piece,
blockIndex));
count++;
@@ -367,7 +371,7 @@ void PeerInteraction::addRequests() {
}
} else {
while(countRequestSlot() < MAX_PENDING_REQUEST) {
- int blockIndex = piece.getMissingUnusedBlockIndex();
+ int blockIndex = piece->getMissingUnusedBlockIndex();
if(blockIndex == -1) {
break;
}
@@ -385,7 +389,7 @@ void PeerInteraction::addRequests() {
void PeerInteraction::sendHandshake() {
PeerMessageHandle handle =
peerMessageFactory->createHandshakeMessage(btContext->getInfoHash(),
- btAnnounce->getPeerId().c_str());
+ (const char*)btContext->getPeerId());
addMessage(handle);
sendMessages();
}
@@ -420,9 +424,9 @@ void PeerInteraction::sendAllowedFast() {
}
}
-Piece& PeerInteraction::getDownloadPiece(int index) {
+PieceHandle PeerInteraction::getDownloadPiece(int index) {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
- if(itr->getIndex() == index) {
+ if((*itr)->getIndex() == index) {
return *itr;
}
}
@@ -431,7 +435,7 @@ Piece& PeerInteraction::getDownloadPiece(int index) {
bool PeerInteraction::hasDownloadPiece(int index) const {
for(Pieces::const_iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
- if(itr->getIndex() == index) {
+ if((*itr)->getIndex() == index) {
return true;
}
}
diff --git a/src/PeerInteraction.h b/src/PeerInteraction.h
index 670cb0e2..de2d5d57 100644
--- a/src/PeerInteraction.h
+++ b/src/PeerInteraction.h
@@ -48,7 +48,6 @@
#define REQUEST_TIME_OUT 60
#define ALLOWED_FAST_SET_SIZE 10
-typedef deque<RequestSlot> RequestSlots;
typedef deque<PeerMessageHandle> MessageQueue;
class PeerInteraction {
@@ -85,7 +84,7 @@ public:
void rejectPieceMessageInQueue(int index, int begin, int length);
void rejectAllPieceMessageInQueue();
void onChoked();
- void abortPiece(Piece& piece);
+ void abortPiece(const PieceHandle& piece);
void abortAllPieces();
bool isSendingMessageInProgress() const;
@@ -104,7 +103,7 @@ public:
// If the piece which this object has is nullPiece, then throws an exception.
// So before calling this function, call hasDownloadPiece and make sure
// this has valid piece, not nullPiece.
- Piece& getDownloadPiece(int index);
+ PieceHandle getDownloadPiece(int index);
bool isInFastSet(int index) const;
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index 86a6c3cd..20992357 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -35,15 +35,17 @@
#include "PeerInteractionCommand.h"
#include "PeerInitiateConnectionCommand.h"
#include "PeerMessageUtil.h"
-#include "HandshakeMessage.h"
-#include "KeepAliveMessage.h"
-#include "ChokeMessage.h"
-#include "UnchokeMessage.h"
-#include "HaveMessage.h"
+#include "DefaultBtInteractive.h"
#include "DlAbortEx.h"
#include "Util.h"
#include "message.h"
#include "prefs.h"
+#include "DefaultBtMessageDispatcher.h"
+#include "DefaultBtMessageReceiver.h"
+#include "DefaultBtRequestFactory.h"
+#include "DefaultBtMessageFactory.h"
+#include "DefaultBtInteractive.h"
+#include "PeerConnection.h"
#include <algorithm>
PeerInteractionCommand::PeerInteractionCommand(int cuid,
@@ -52,196 +54,133 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid,
const BtContextHandle& btContext,
const SocketHandle& s,
int sequence)
- :PeerAbstractCommand(cuid, p, e, btContext, s), sequence(sequence) {
+ :PeerAbstractCommand(cuid, p, e, btContext, s),
+ sequence(sequence),
+ btInteractive(0)
+{
+ // TODO move following bunch of processing to separate method, like init()
if(sequence == INITIATOR_SEND_HANDSHAKE) {
disableReadCheckSocket();
setWriteCheckSocket(socket);
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
- peerInteraction = new PeerInteraction(cuid, peer, socket, e->option,
- btContext);
+ PeerConnectionHandle peerConnection =
+ new PeerConnection(cuid, socket, e->option);
+
+ DefaultBtMessageDispatcherHandle dispatcher = new DefaultBtMessageDispatcher();
+ dispatcher->setCuid(cuid);
+ dispatcher->setPeer(peer);
+ dispatcher->setBtContext(btContext);
+ dispatcher->setOption(e->option);
+
+ DefaultBtMessageReceiverHandle receiver = new DefaultBtMessageReceiver();
+ receiver->setCuid(cuid);
+ receiver->setPeer(peer);
+ receiver->setBtContext(btContext);
+ receiver->setPeerConnection(peerConnection);
+ receiver->setDispatcher(dispatcher);
+
+ DefaultBtRequestFactoryHandle reqFactory = new DefaultBtRequestFactory();
+ reqFactory->setCuid(cuid);
+ reqFactory->setPeer(peer);
+ reqFactory->setBtContext(btContext);
+ reqFactory->setBtMessageDispatcher(dispatcher);
+
+ DefaultBtInteractiveHandle btInteractive = new DefaultBtInteractive();
+ btInteractive->setCuid(cuid);
+ btInteractive->setPeer(peer);
+ btInteractive->setBtContext(btContext);
+ btInteractive->setBtMessageReceiver(receiver);
+ btInteractive->setDispatcher(dispatcher);
+ btInteractive->setBtRequestFactory(reqFactory);
+ btInteractive->setPeerConnection(peerConnection);
+ btInteractive->setOption(e->option);
+ this->btInteractive = btInteractive;
+
+ DefaultBtMessageFactoryHandle factory = new DefaultBtMessageFactory();
+ factory->setCuid(cuid);
+ factory->setBtContext(btContext);
+ factory->setPeer(peer);
+
+ PeerObjectHandle peerObject = new PeerObject();
+ peerObject->btMessageDispatcher = dispatcher;
+ peerObject->btMessageFactory = factory;
+ peerObject->btRequestFactory = reqFactory;
+ peerObject->peerConnection = peerConnection;
+
+ PEER_OBJECT_CLUSTER(btContext)->registerHandle(peer->getId(), peerObject);
+
setUploadLimit(e->option->getAsInt(PREF_MAX_UPLOAD_LIMIT));
- chokeUnchokeCount = 0;
- haveCount = 0;
- keepAliveCount = 0;
peer->activate();
}
PeerInteractionCommand::~PeerInteractionCommand() {
- delete peerInteraction;
peer->deactivate();
+ PEER_OBJECT_CLUSTER(btContext)->unregisterHandle(peer->getId());
+
+ logger->debug("CUID#%d - unregistered message factory using ID:%s",
+ cuid, peer->getId().c_str());
}
bool PeerInteractionCommand::executeInternal() {
+ setReadCheckSocket(socket);
disableWriteCheckSocket();
setUploadLimitCheck(false);
setNoCheck(false);
-
switch(sequence) {
case INITIATOR_SEND_HANDSHAKE:
if(!socket->isWritable(0)) {
+ disableReadCheckSocket();
setWriteCheckSocket(socket);
break;
}
socket->setBlockingMode();
- setReadCheckSocket(socket);
- setTimeout(e->option->getAsInt(PREF_TIMEOUT));
- peerInteraction->sendHandshake();
+ setTimeout(e->option->getAsInt(PREF_BT_TIMEOUT));
+ btInteractive->initiateHandshake();
sequence = INITIATOR_WAIT_HANDSHAKE;
break;
case INITIATOR_WAIT_HANDSHAKE: {
- if(peerInteraction->countMessageInQueue() > 0) {
- peerInteraction->sendMessages();
- if(peerInteraction->countMessageInQueue() > 0) {
+ if(btInteractive->countPendingMessage() > 0) {
+ btInteractive->sendPendingMessage();
+ if(btInteractive->countPendingMessage() > 0) {
break;
}
}
- PeerMessageHandle handshakeMessage =
- peerInteraction->receiveHandshake();
- if(handshakeMessage.get() == 0) {
+ BtMessageHandle handshakeMessage = btInteractive->receiveHandshake();
+ if(handshakeMessage.isNull()) {
break;
}
- peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
- logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
- peer->ipaddr.c_str(), peer->port,
- handshakeMessage->toString().c_str());
- haveCheckTime.reset();
- peerInteraction->sendBitfield();
- peerInteraction->sendAllowedFast();
+ btInteractive->doPostHandshakeProcessing();
sequence = WIRED;
break;
}
case RECEIVER_WAIT_HANDSHAKE: {
- PeerMessageHandle handshakeMessage =
- peerInteraction->receiveHandshake(true);
- if(handshakeMessage.get() == 0) {
+ BtMessageHandle handshakeMessage = btInteractive->receiveAndSendHandshake();
+ if(handshakeMessage.isNull()) {
break;
}
- peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
- logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
- peer->ipaddr.c_str(), peer->port,
- handshakeMessage->toString().c_str());
- haveCheckTime.reset();
- peerInteraction->sendBitfield();
- peerInteraction->sendAllowedFast();
+ btInteractive->doPostHandshakeProcessing();
sequence = WIRED;
break;
}
case WIRED:
- peerInteraction->syncPiece();
- decideChoking();
+ btInteractive->doInteractionProcessing();
- if(periodicExecPoint.elapsedInMillis(500)) {
- periodicExecPoint.reset();
- detectMessageFlooding();
- peerInteraction->checkRequestSlot();
- checkHave();
- sendKeepAlive();
- }
- receiveMessages();
-
- peerInteraction->addRequests();
-
- peerInteraction->sendMessages();
break;
}
- if(peerInteraction->countMessageInQueue() > 0) {
- if(peerInteraction->isSendingMessageInProgress()) {
- setUploadLimitCheck(true);
- }
+ if(btInteractive->countPendingMessage() > 0) {
setNoCheck(true);
}
- e->commands.push_back(this);
- return false;
-}
-
-#define FLOODING_CHECK_INTERVAL 5
-
-void PeerInteractionCommand::detectMessageFlooding() {
- 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();
+ int maxSpeedLimit = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT);
+ if(maxSpeedLimit > 0) {
+ TransferStat stat = peerStorage->calculateStat();
+ if(maxSpeedLimit < stat.downloadSpeed) {
+ disableReadCheckSocket();
+ setNoCheck(true);
}
}
-}
-
-/*
-void PeerInteractionCommand::checkLongTimePeerChoking() {
- if(pieceStorage->downloadFinished()) {
- return;
- }
- 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 {
- chokeCheckPoint.reset();
- }
-}
-*/
-
-void PeerInteractionCommand::decideChoking() {
- if(peer->shouldBeChoking()) {
- if(!peer->amChoking) {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createChokeMessage());
- }
- } else {
- if(peer->amChoking) {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createUnchokeMessage());
- }
- }
-}
-
-void PeerInteractionCommand::receiveMessages() {
- for(int i = 0; i < 50; i++) {
- int maxSpeedLimit = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT);
- if(maxSpeedLimit > 0) {
- TransferStat stat = peerStorage->calculateStat();
- if(maxSpeedLimit < stat.downloadSpeed) {
- disableReadCheckSocket();
- setNoCheck(true);
- break;
- }
- }
-
- PeerMessageHandle message = peerInteraction->receiveMessage();
- if(message.get() == NULL) {
- return;
- }
- logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
- peer->ipaddr.c_str(), peer->port,
- message->toString().c_str());
- // to detect flooding
- switch(message->getId()) {
- case KeepAliveMessage::ID:
- keepAliveCount++;
- break;
- case ChokeMessage::ID:
- if(!peer->peerChoking) {
- chokeUnchokeCount++;
- }
- break;
- case UnchokeMessage::ID:
- if(peer->peerChoking) {
- chokeUnchokeCount++;
- }
- break;
- case HaveMessage::ID:
- haveCount++;
- break;
- }
- message->receivedAction();
- }
+ e->commands.push_back(this);
+ return false;
}
// TODO this method removed when PeerBalancerCommand is implemented
@@ -266,42 +205,6 @@ bool PeerInteractionCommand::prepareForRetry(int wait) {
}
void PeerInteractionCommand::onAbort(Exception* ex) {
- peerInteraction->abortAllPieces();
+ btInteractive->cancelAllPiece();
PeerAbstractCommand::onAbort(ex);
}
-
-void PeerInteractionCommand::sendKeepAlive() {
- if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) {
- if(peerInteraction->countMessageInQueue() == 0) {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createKeepAliveMessage());
- peerInteraction->sendMessages();
- }
- keepAliveCheckPoint.reset();
- }
-}
-
-void PeerInteractionCommand::checkHave() {
- Integers indexes =
- pieceStorage->getAdvertisedPieceIndexes(cuid, haveCheckTime);
- haveCheckTime.reset();
- if(indexes.size() >= 20) {
- if(peer->isFastExtensionEnabled()) {
- if(pieceStorage->downloadFinished()) {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createHaveAllMessage());
- } else {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createBitfieldMessage());
- }
- } else {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createBitfieldMessage());
- }
- } else {
- for(Integers::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
- peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
- createHaveMessage(*itr));
- }
- }
-}
diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h
index 73b9fc54..e4842e7b 100644
--- a/src/PeerInteractionCommand.h
+++ b/src/PeerInteractionCommand.h
@@ -36,45 +36,24 @@
#define _D_PEER_INTERACTION_COMMAND_H_
#include "PeerAbstractCommand.h"
-#include "PeerConnection.h"
-#include "PeerInteraction.h"
-#include "TimeA2.h"
-
-using namespace std;
-
-#define MAX_PEER_CHOKING_INTERVAL (1*60)
-#define KEEP_ALIVE_INTERVAL 120
+#include "BtInteractive.h"
class PeerInteractionCommand : public PeerAbstractCommand {
private:
int sequence;
- PeerInteraction* peerInteraction;
-
- Time keepAliveCheckPoint;
- //Time chokeCheckPoint;
- Time freqCheckPoint;
- Time haveCheckTime;
- Time periodicExecPoint;
- int chokeUnchokeCount;
- int haveCount;
- int keepAliveCount;
- void receiveMessages();
- void detectMessageFlooding();
- void checkLongTimePeerChoking();
- void detectTimeoutAndDuplicateBlock();
- void decideChoking();
- void sendKeepAlive();
- void checkHave();
+ BtInteractiveHandle btInteractive;
protected:
bool executeInternal();
bool prepareForRetry(int wait);
bool prepareForNextPeer(int wait);
void onAbort(Exception* ex);
public:
- PeerInteractionCommand(int cuid, const PeerHandle& peer,
+ PeerInteractionCommand(int cuid,
+ const PeerHandle& peer,
TorrentDownloadEngine* e,
const BtContextHandle& btContext,
- const SocketHandle& s, int sequence);
+ const SocketHandle& s,
+ int sequence);
~PeerInteractionCommand();
diff --git a/src/PeerMessage.cc b/src/PeerMessage.cc
index fe440668..2ce7903b 100644
--- a/src/PeerMessage.cc
+++ b/src/PeerMessage.cc
@@ -39,6 +39,7 @@ PeerMessage::PeerMessage()
:inProgress(false),
invalidate(false),
uploading(false),
+ peer(0),
btContext(0),
peerStorage(0),
pieceStorage(0)
diff --git a/src/PeerMessage.h b/src/PeerMessage.h
index 2d54646b..ebe581c3 100644
--- a/src/PeerMessage.h
+++ b/src/PeerMessage.h
@@ -100,7 +100,7 @@ public:
virtual void onPush() {}
virtual void onChoked() {}
virtual void onCanceled(int index, int begin, int blockLength) {}
- virtual void onAbortPiece(const Piece& piece) {}
+ virtual void onAbortPiece(const PieceHandle& piece) {}
};
typedef SharedHandle<PeerMessage> PeerMessageHandle;
diff --git a/src/PeerMessageFactory.cc b/src/PeerMessageFactory.cc
index 95709c8e..f3f4b810 100644
--- a/src/PeerMessageFactory.cc
+++ b/src/PeerMessageFactory.cc
@@ -171,12 +171,12 @@ PeerMessageFactory::setPeerMessageCommonProperty(PeerMessageHandle& peerMessage)
peerMessage->setBtContext(btContext);
}
-PeerMessageHandle PeerMessageFactory::createRequestMessage(const Piece& piece,
+PeerMessageHandle PeerMessageFactory::createRequestMessage(const PieceHandle& piece,
int blockIndex) const {
PeerMessageHandle handle =
- PeerMessageHandle(new RequestMessage(piece.getIndex(),
- blockIndex*piece.getBlockLength(),
- piece.getBlockLength(blockIndex),
+ PeerMessageHandle(new RequestMessage(piece->getIndex(),
+ blockIndex*piece->getBlockLength(),
+ piece->getBlockLength(blockIndex),
blockIndex));
setPeerMessageCommonProperty(handle);
return handle;
diff --git a/src/PeerMessageFactory.h b/src/PeerMessageFactory.h
index 481a0b31..7d7856f7 100644
--- a/src/PeerMessageFactory.h
+++ b/src/PeerMessageFactory.h
@@ -71,7 +71,7 @@ public:
createHandshakeMessage(const unsigned char* infoHash,
const char* peerId) const;
- PeerMessageHandle createRequestMessage(const Piece& piece,
+ PeerMessageHandle createRequestMessage(const PieceHandle& piece,
int blockIndex) const;
PeerMessageHandle createCancelMessage(int index, int begin, int length) const;
PeerMessageHandle createPieceMessage(int index, int begin, int length) const;
diff --git a/src/PeerMessageUtil.cc b/src/PeerMessageUtil.cc
index 58728a9c..33cfe7be 100644
--- a/src/PeerMessageUtil.cc
+++ b/src/PeerMessageUtil.cc
@@ -37,67 +37,69 @@
#include "Util.h"
#include <netinet/in.h>
-int PeerMessageUtil::getId(const char* msg) {
- return (int)msg[0];
+int32_t PeerMessageUtil::getId(const unsigned char* msg) {
+ return (int32_t)msg[0];
}
-int PeerMessageUtil::getIntParam(const char* msg, int offset) {
- int nParam;
- memcpy(&nParam, msg+offset, 4);
+uint32_t PeerMessageUtil::getIntParam(const unsigned char* msg, int32_t offset) {
+ uint32_t nParam;
+ memcpy(&nParam, msg+offset, sizeof(uint32_t));
return ntohl(nParam);
}
-int PeerMessageUtil::getShortIntParam(const char* msg, int offset) {
- short int nParam;
- memcpy(&nParam, msg+offset, 2);
+uint16_t PeerMessageUtil::getShortIntParam(const unsigned char* msg, int32_t offset) {
+ uint16_t nParam;
+ memcpy(&nParam, msg+offset, sizeof(uint16_t));
return ntohs(nParam);
}
-void PeerMessageUtil::checkIndex(int index, int pieces) {
+void PeerMessageUtil::checkIndex(uint32_t index, uint32_t pieces) {
if(!(0 <= index && index < pieces)) {
- throw new DlAbortEx("invalid index = %d", index);
+ throw new DlAbortEx("invalid index = %u", index);
}
}
-void PeerMessageUtil::checkBegin(int begin, int pieceLength) {
+void PeerMessageUtil::checkBegin(uint32_t begin, uint32_t pieceLength) {
if(!(0 <= begin && begin < pieceLength)) {
- throw new DlAbortEx("invalid begin = %d", begin);
+ throw new DlAbortEx("invalid begin = %u", begin);
}
}
-void PeerMessageUtil::checkLength(int length) {
+void PeerMessageUtil::checkLength(uint32_t length) {
if(length > MAX_BLOCK_LENGTH) {
- throw new DlAbortEx("too large length %d > %dKB", length,
+ throw new DlAbortEx("too large length %u > %dKB", length,
MAX_BLOCK_LENGTH/1024);
}
if(length <= 0) {
- throw new DlAbortEx("invalid length %d", length);
+ throw new DlAbortEx("invalid length %u", length);
}
if(!Util::isPowerOf(length, 2)) {
- throw new DlAbortEx("invalid length %d, which is not power of 2",
+ throw new DlAbortEx("invalid length %u, which is not power of 2",
length);
}
}
-void PeerMessageUtil::checkRange(int begin, int length, int pieceLength) {
+void PeerMessageUtil::checkRange(uint32_t begin, uint32_t length, uint32_t pieceLength) {
if(!(0 <= begin && 0 < length)) {
- throw new DlAbortEx("invalid range, begin = %d, length = %d",
+ throw new DlAbortEx("invalid range, begin = %u, length = %u",
begin, length);
}
- int end = begin+length;
+ uint32_t end = begin+length;
if(!(0 < end && end <= pieceLength)) {
- throw new DlAbortEx("invalid range, begin = %d, length = %d",
+ throw new DlAbortEx("invalid range, begin = %u, length = %u",
begin, length);
}
}
-void PeerMessageUtil::checkBitfield(const unsigned char* bitfield, int bitfieldLength, int pieces) {
+void PeerMessageUtil::checkBitfield(const unsigned char* bitfield,
+ uint32_t bitfieldLength,
+ uint32_t pieces) {
if(!(bitfieldLength == BITFIELD_LEN_FROM_PIECES(pieces))) {
throw new DlAbortEx("invalid bitfield length = %d",
bitfieldLength);
}
char lastbyte = bitfield[bitfieldLength-1];
- for(int i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) {
+ for(uint32_t i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) {
if(!(((lastbyte >> i) & 1) == 0)) {
throw new DlAbortEx("invalid bitfield");
}
@@ -119,14 +121,20 @@ void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsi
}
}
-void PeerMessageUtil::setIntParam(char* dest, int param) {
- int nParam = htonl(param);
- memcpy(dest, &nParam, 4);
+void PeerMessageUtil::setIntParam(unsigned char* dest, uint32_t param) {
+ uint32_t nParam = htonl(param);
+ memcpy(dest, &nParam, sizeof(uint32_t));
}
-void PeerMessageUtil::createPeerMessageString(char* msg, int msgLength,
- int payloadLength,
- int messageId) {
+void PeerMessageUtil::setShortIntParam(unsigned char* dest, uint16_t param) {
+ uint16_t nParam = htons(param);
+ memcpy(dest, &nParam, sizeof(uint16_t));
+}
+
+void PeerMessageUtil::createPeerMessageString(unsigned char* msg,
+ uint32_t msgLength,
+ uint32_t payloadLength,
+ int32_t messageId) {
assert(msgLength >= 5);
memset(msg, 0, msgLength);
setIntParam(msg, payloadLength);
diff --git a/src/PeerMessageUtil.h b/src/PeerMessageUtil.h
index 3d11b1b3..aac462d3 100644
--- a/src/PeerMessageUtil.h
+++ b/src/PeerMessageUtil.h
@@ -44,25 +44,57 @@ class PeerMessageUtil {
private:
PeerMessageUtil() {}
public:
- static int getIntParam(const char* msg, int offset);
- static int getShortIntParam(const char* msg, int offset);
- static void setIntParam(char* dest, int param);
+ static uint32_t getIntParam(const unsigned char* msg, int32_t offset);
+ static uint32_t getIntParam(const char* msg, int32_t offset) {
+ return getIntParam((const unsigned char*)msg, offset);
+ }
- static int getId(const char* msg);
+ static uint16_t getShortIntParam(const unsigned char* msg, int32_t offset);
+ static uint16_t getShortIntParam(const char* msg, int32_t offset) {
+ return getShortIntParam((const unsigned char*)msg, offset);
+ }
+
+ static void setIntParam(unsigned char* dest, uint32_t param);
+ static void setIntParam(char* dest, uint32_t param) {
+ setIntParam((unsigned char*)dest, param);
+ }
+
+ static void setShortIntParam(unsigned char* dest, uint16_t param);
+ static void setShortIntParam(char* dest, uint16_t param) {
+ setShortIntParam((unsigned char*)dest, param);
+ }
+
+ static int32_t getId(const unsigned char* msg);
+ static int32_t getId(const char* msg) {
+ return getId((const unsigned char*)msg);
+ }
- static void checkIndex(int index, int pieces);
- static void checkBegin(int begin, int pieceLength);
- static void checkLength(int length);
- static void checkRange(int begin, int length, int pieceLength);
+ static void checkIndex(uint32_t index, uint32_t pieces);
+ static void checkBegin(uint32_t begin, uint32_t pieceLength);
+ static void checkLength(uint32_t length);
+ static void checkRange(uint32_t begin, uint32_t length, uint32_t pieceLength);
static void checkBitfield(const unsigned char* bitfield,
- int bitfieldLength,
- int pieces);
+ uint32_t bitfieldLength,
+ uint32_t pieces);
+ static void checkBitfield(const char* bitfield,
+ uint32_t bitfieldLength,
+ uint32_t pieces) {
+ checkBitfield((unsigned char*)bitfield, bitfieldLength, pieces);
+ }
static void checkHandshake(const HandshakeMessage* message,
const unsigned char* infoHash);
- static void createPeerMessageString(char* msg, int msgLength,
- int payloadLength, int messageId);
+ static void createPeerMessageString(unsigned char* msg,
+ uint32_t msgLength,
+ uint32_t payloadLength,
+ int32_t messageId);
+ static void createPeerMessageString(char* msg,
+ uint32_t msgLength,
+ uint32_t payloadLength,
+ int32_t messageId) {
+ createPeerMessageString((unsigned char*)msg, msgLength, payloadLength, messageId);
+ }
};
#endif // _D_PEER_MESSAGE_UTIL_H_
diff --git a/src/PeerObject.h b/src/PeerObject.h
new file mode 100644
index 00000000..3accdc03
--- /dev/null
+++ b/src/PeerObject.h
@@ -0,0 +1,59 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_PEER_OBJECT_H_
+#define _D_PEER_OBJECT_H_
+
+#include "common.h"
+#include "BtMessageFactory.h"
+#include "BtRequestFactory.h"
+#include "BtMessageDispatcher.h"
+#include "PeerConnection.h"
+
+class PeerObject {
+public:
+ PeerObject():btMessageFactory(0),
+ btRequestFactory(0),
+ btMessageDispatcher(0),
+ peerConnection(0) {}
+
+ BtMessageFactoryHandle btMessageFactory;
+ BtRequestFactoryHandle btRequestFactory;
+ BtMessageDispatcherHandle btMessageDispatcher;
+ PeerConnectionHandle peerConnection;
+};
+
+typedef SharedHandle<PeerObject> PeerObjectHandle;
+
+#endif // _D_PEER_OBJECT_H_
diff --git a/src/Piece.cc b/src/Piece.cc
index f8d5ed68..1bba051b 100644
--- a/src/Piece.cc
+++ b/src/Piece.cc
@@ -34,8 +34,25 @@
/* copyright --> */
#include "Piece.h"
#include "Util.h"
+#include "BitfieldManFactory.h"
+
+Piece::Piece():index(0), length(0), bitfield(0) {}
+
+Piece::Piece(int index, int length):index(index), length(length) {
+ bitfield =
+ BitfieldManFactory::getNewFactory()->createBitfieldMan(BLOCK_LENGTH, length);
+}
+
+Piece::Piece(const Piece& piece) {
+ index = piece.index;
+ length = piece.length;
+ if(piece.bitfield == 0) {
+ bitfield = 0;
+ } else {
+ bitfield = new BitfieldMan(*piece.bitfield);
+ }
+}
-Piece Piece::nullPiece;
void Piece::completeBlock(int blockIndex) {
bitfield->setBit(blockIndex);
diff --git a/src/Piece.h b/src/Piece.h
index f18eae38..79be4b3f 100644
--- a/src/Piece.h
+++ b/src/Piece.h
@@ -46,20 +46,11 @@ private:
int length;
BitfieldMan* bitfield;
public:
- Piece():index(0), length(0), bitfield(NULL) {}
- Piece(int index, int length):index(index), length(length) {
- bitfield = new BitfieldMan(BLOCK_LENGTH, length);
- }
+ Piece();
- Piece(const Piece& piece) {
- index = piece.index;
- length = piece.length;
- if(piece.bitfield == NULL) {
- bitfield = NULL;
- } else {
- bitfield = new BitfieldMan(*piece.bitfield);
- }
- }
+ Piece(int index, int length);
+
+ Piece(const Piece& piece);
~Piece() {
delete bitfield;
@@ -119,12 +110,12 @@ public:
string toString() const;
- static Piece nullPiece;
- static bool isNull(const Piece& piece) {
- return piece.index == 0 && piece.length == 0;
+ bool isBlockUsed(int index) const {
+ return bitfield->isUseBitSet(index);
}
};
-typedef deque<Piece> Pieces;
+typedef SharedHandle<Piece> PieceHandle;
+typedef deque<PieceHandle> Pieces;
#endif // _D_PIECE_H_
diff --git a/src/PieceMessage.cc b/src/PieceMessage.cc
index 367ad2f9..0e55a92f 100644
--- a/src/PieceMessage.cc
+++ b/src/PieceMessage.cc
@@ -74,7 +74,7 @@ void PieceMessage::receivedAction() {
peer->snubbing = false;
//logger->debug("CUID#%d - Latency=%d", cuid, slot.getLatencyInMillis());
peer->updateLatency(slot.getLatencyInMillis());
- Piece& piece = peerInteraction->getDownloadPiece(slot.getIndex());
+ PieceHandle piece = peerInteraction->getDownloadPiece(slot.getIndex());
long long int offset =
((long long int)index)*btContext->getPieceLength()+begin;
logger->debug("CUID#%d - Writing the block length=%d, offset=%lld",
@@ -82,12 +82,12 @@ void PieceMessage::receivedAction() {
pieceStorage->getDiskAdaptor()->writeData(block,
blockLength,
offset);
- piece.completeBlock(slot.getBlockIndex());
+ piece->completeBlock(slot.getBlockIndex());
peerInteraction->deleteRequestSlot(slot);
- pieceStorage->updatePiece(piece);
+ //pieceStorage->updatePiece(piece);
logger->debug("CUID#%d - Setting piece block index=%d",
cuid, slot.getBlockIndex());
- if(piece.pieceComplete()) {
+ if(piece->pieceComplete()) {
if(checkPieceHash(piece)) {
onGotNewPiece(piece);
} else {
@@ -196,38 +196,38 @@ string PieceMessage::toString() const {
", length="+Util::itos(blockLength);
}
-bool PieceMessage::checkPieceHash(const Piece& piece) {
+bool PieceMessage::checkPieceHash(const PieceHandle& piece) {
long long int offset =
- ((long long int)piece.getIndex())*btContext->getPieceLength();
- return pieceStorage->getDiskAdaptor()->sha1Sum(offset, piece.getLength()) ==
- btContext->getPieceHash(piece.getIndex());
+ ((long long int)piece->getIndex())*btContext->getPieceLength();
+ return pieceStorage->getDiskAdaptor()->sha1Sum(offset, piece->getLength()) ==
+ btContext->getPieceHash(piece->getIndex());
}
-void PieceMessage::onGotNewPiece(Piece& piece) {
- logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex());
+void PieceMessage::onGotNewPiece(const PieceHandle& piece) {
+ logger->info(MSG_GOT_NEW_PIECE, cuid, piece->getIndex());
pieceStorage->completePiece(piece);
- pieceStorage->advertisePiece(cuid, piece.getIndex());
+ pieceStorage->advertisePiece(cuid, piece->getIndex());
}
-void PieceMessage::onGotWrongPiece(Piece& piece) {
- logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex());
+void PieceMessage::onGotWrongPiece(const PieceHandle& piece) {
+ logger->error(MSG_GOT_WRONG_PIECE, cuid, piece->getIndex());
erasePieceOnDisk(piece);
- piece.clearAllBlock();
- pieceStorage->updatePiece(piece);
+ piece->clearAllBlock();
+ //pieceStorage->updatePiece(piece);
peerInteraction->abortPiece(piece);
}
-void PieceMessage::erasePieceOnDisk(const Piece& piece) {
+void PieceMessage::erasePieceOnDisk(const PieceHandle& piece) {
int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
long long int offset =
- ((long long int)piece.getIndex())*btContext->getPieceLength();
- for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
+ ((long long int)piece->getIndex())*btContext->getPieceLength();
+ for(int i = 0; i < piece->getLength()/BUFSIZE; i++) {
pieceStorage->getDiskAdaptor()->writeData(buf, BUFSIZE, offset);
offset += BUFSIZE;
}
- int r = piece.getLength()%BUFSIZE;
+ int r = piece->getLength()%BUFSIZE;
if(r > 0) {
pieceStorage->getDiskAdaptor()->writeData(buf, r, offset);
}
diff --git a/src/PieceMessage.h b/src/PieceMessage.h
index 328ff7bd..48b5cac1 100644
--- a/src/PieceMessage.h
+++ b/src/PieceMessage.h
@@ -52,10 +52,10 @@ private:
char msgHeader[13];
- bool checkPieceHash(const Piece& piece);
- void onGotNewPiece(Piece& piece);
- void onGotWrongPiece(Piece& piece);
- void erasePieceOnDisk(const Piece& piece);
+ bool checkPieceHash(const PieceHandle& piece);
+ void onGotNewPiece(const PieceHandle& piece);
+ void onGotWrongPiece(const PieceHandle& piece);
+ void erasePieceOnDisk(const PieceHandle& piece);
int sendPieceData(long long int offset, int length) const;
PeerMessageHandle createRejectMessage(int index, int begin, int blockLength) const;
public:
@@ -75,9 +75,7 @@ public:
}
virtual ~PieceMessage() {
- if(block != NULL) {
delete [] block;
- }
}
enum ID_t {
diff --git a/src/PieceStorage.h b/src/PieceStorage.h
index 4ee76e05..892ffa8e 100644
--- a/src/PieceStorage.h
+++ b/src/PieceStorage.h
@@ -56,7 +56,7 @@ public:
* from get the same piece. But in end game mode, same piece may be returned
* to several commands.
*/
- virtual Piece getMissingPiece(const PeerHandle& peer) = 0;
+ virtual PieceHandle getMissingPiece(const PeerHandle& peer) = 0;
/**
* Returns a piece that the peer has but localhost doesn't.
* Only pieces that declared as "fast" are returned.
@@ -64,27 +64,23 @@ public:
* from get the same piece. But in end game mode, same piece may be returned
* to several commands.
*/
- virtual Piece getMissingFastPiece(const PeerHandle& peer) = 0;
+ virtual PieceHandle getMissingFastPiece(const PeerHandle& peer) = 0;
/**
- * Tells that the download of the specfied piece completes.
+ * Returns the piece denoted by index.
+ * No status of the piece is changed in this method.
*/
- virtual void completePiece(const Piece& piece) = 0;
+ virtual PieceHandle getPiece(int index) = 0;
/**
- * Tells that the download of the specified piece is canceled.
- */
- virtual void cancelPiece(const Piece& piece) = 0;
-
- /**
- * Updates the internal piece data with the specified piece data.
+ * Tells that the download of the specfied piece completes.
*/
- virtual void updatePiece(const Piece& piece) = 0;
+ virtual void completePiece(const PieceHandle& piece) = 0;
/**
- * Updates the spcefied piece data with the internal piece data.
+ * Tells that the download of the specified piece is canceled.
*/
- virtual void syncPiece(Piece& piece) = 0;
+ virtual void cancelPiece(const PieceHandle& piece) = 0;
/**
* Returns true if the specified piece is already downloaded.
diff --git a/src/Randomizer.h b/src/Randomizer.h
new file mode 100644
index 00000000..cbfcc8bb
--- /dev/null
+++ b/src/Randomizer.h
@@ -0,0 +1,50 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_RANDOMIZER_H_
+#define _D_RANDOMIZER_H_
+
+#include "common.h"
+
+class Randomizer {
+public:
+ virtual ~Randomizer() {}
+
+ virtual int getRandomNumber() = 0;
+
+ virtual int getMaxRandomNumber() = 0;
+};
+
+typedef SharedHandle<Randomizer> RandomizerHandle;
+#endif // _D_RANDOMIZER_H_
diff --git a/src/RequestSlot.cc b/src/RequestSlot.cc
index 4d595c3e..9d677bf8 100644
--- a/src/RequestSlot.cc
+++ b/src/RequestSlot.cc
@@ -35,7 +35,7 @@
#include "RequestSlot.h"
#include "Util.h"
-RequestSlot::RequestSlot(int index, int begin, int length, int blockIndex)
+RequestSlot::RequestSlot(uint32_t index, uint32_t begin, uint32_t length, uint32_t blockIndex)
:index(index), begin(begin), length(length), blockIndex(blockIndex) {}
RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
@@ -56,7 +56,11 @@ void RequestSlot::setDispatchedTime() {
dispatchedTime.reset();
}
-bool RequestSlot::isTimeout(int timeoutSec) const {
+void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
+ dispatchedTime.setTimeInSec(secFromEpoch);
+}
+
+bool RequestSlot::isTimeout(time_t timeoutSec) const {
return dispatchedTime.differenceInMillis() > timeoutSec*1000;
}
diff --git a/src/RequestSlot.h b/src/RequestSlot.h
index 2fb6cdee..20a6078d 100644
--- a/src/RequestSlot.h
+++ b/src/RequestSlot.h
@@ -41,13 +41,13 @@
class RequestSlot {
private:
Time dispatchedTime;
- int index;
- int begin;
- int length;
- int blockIndex;
+ uint32_t index;
+ uint32_t begin;
+ uint32_t length;
+ uint32_t blockIndex;
void copy(const RequestSlot& requestSlot);
public:
- RequestSlot(int index, int begin, int legnth, int blockIndex);
+ RequestSlot(uint32_t index, uint32_t begin, uint32_t length, uint32_t blockIndex);
RequestSlot(const RequestSlot& requestSlot);
~RequestSlot() {}
@@ -65,22 +65,25 @@ public:
}
void setDispatchedTime();
+ void setDispatchedTime(time_t secFromEpoch);
- bool isTimeout(int timeoutSec) const;
+ bool isTimeout(time_t timeoutSec) const;
int getLatencyInMillis() const;
- int getIndex() const { return index; }
- void setIndex(int index) { this->index = index; }
- int getBegin() const { return begin; }
- void setBegin(int begin) { this->begin = begin; }
- int getLength() const { return length; }
- void setLength(int length) { this->length = length; }
- int getBlockIndex() const { return blockIndex; }
- void setBlockIndex(int blockIndex) { this->blockIndex = blockIndex; }
+ uint32_t getIndex() const { return index; }
+ void setIndex(uint32_t index) { this->index = index; }
+ uint32_t getBegin() const { return begin; }
+ void setBegin(uint32_t begin) { this->begin = begin; }
+ uint32_t getLength() const { return length; }
+ void setLength(uint32_t length) { this->length = length; }
+ uint32_t getBlockIndex() const { return blockIndex; }
+ void setBlockIndex(uint32_t blockIndex) { this->blockIndex = blockIndex; }
static RequestSlot nullSlot;
static bool isNull(const RequestSlot& requestSlot);
};
+typedef deque<RequestSlot> RequestSlots;
+
#endif // _D_REQUEST_SLOT_H_
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index 7afdd58a..5d8dfe2f 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -39,6 +39,7 @@
#include "message.h"
#include "prefs.h"
#include "LogFactory.h"
+#include "BitfieldManFactory.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -229,7 +230,7 @@ void SegmentMan::init() {
}
void SegmentMan::initBitfield(int segmentLength, long long int totalLength) {
- this->bitfield = new BitfieldMan(segmentLength, totalLength);
+ this->bitfield = BitfieldManFactory::getNewFactory()->createBitfieldMan(segmentLength, totalLength);
}
class FindSegmentEntryByIndex {
diff --git a/src/SharedHandle.h b/src/SharedHandle.h
index 2b01ee38..0cb08575 100644
--- a/src/SharedHandle.h
+++ b/src/SharedHandle.h
@@ -64,8 +64,14 @@ public:
++*ucount;
}
template<class S>
- SharedHandle(const SharedHandle<S>& t):obj(t.get()), ucount(t.getRefCount()) {
- ++*ucount;
+ SharedHandle(const SharedHandle<S>& t) {
+ obj = dynamic_cast<T*>(t.get());
+ if(obj) {
+ ucount = t.getRefCount();
+ ++*ucount;
+ } else {
+ ucount = new int(1);
+ }
}
~SharedHandle() {
@@ -108,6 +114,10 @@ public:
int* getRefCount() const {
return ucount;
}
+
+ bool isNull() const {
+ return obj == 0;
+ }
};
template<class T>
diff --git a/src/SimpleBtMessage.cc b/src/SimpleBtMessage.cc
new file mode 100644
index 00000000..ff08a287
--- /dev/null
+++ b/src/SimpleBtMessage.cc
@@ -0,0 +1,64 @@
+/* <!-- 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 "SimpleBtMessage.h"
+#include "message.h"
+#include "BtRegistry.h"
+
+SimpleBtMessage::SimpleBtMessage():leftDataLength(0) {}
+
+SimpleBtMessage::~SimpleBtMessage() {}
+
+void SimpleBtMessage::send() {
+ if(invalidate) {
+ return;
+ }
+ if(sendPredicate() || sendingInProgress) {
+ const char* msg = getMessage();
+ int msgLength = getMessageLength();
+ if(!sendingInProgress) {
+ logger->info(MSG_SEND_PEER_MESSAGE,
+ cuid, peer->ipaddr.c_str(), peer->port, toString().c_str());
+ leftDataLength = getMessageLength();
+ }
+ sendingInProgress = false;
+ int writtenLength = PEER_CONNECTION(btContext, peer)->sendMessage(msg+msgLength-leftDataLength, leftDataLength);
+ if(writtenLength == leftDataLength) {
+ onSendComplete();
+ } else {
+ leftDataLength -= writtenLength;
+ sendingInProgress = true;
+ }
+ }
+}
diff --git a/src/SimpleBtMessage.h b/src/SimpleBtMessage.h
new file mode 100644
index 00000000..b1a25310
--- /dev/null
+++ b/src/SimpleBtMessage.h
@@ -0,0 +1,60 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_SIMPLE_BT_MESSAGE_H_
+#define _D_SIMPLE_BT_MESSAGE_H_
+
+#include "AbstractBtMessage.h"
+
+class SimpleBtMessage : public AbstractBtMessage {
+private:
+ int leftDataLength;
+public:
+ SimpleBtMessage();
+
+ virtual ~SimpleBtMessage();
+
+ virtual void send();
+
+ virtual const char* getMessage() = 0;
+
+ virtual uint32_t getMessageLength() = 0;
+
+ virtual void onSendComplete() {};
+
+ virtual bool sendPredicate() const { return true; };
+
+};
+
+#endif // _D_SIMPLE_BT_MESSAGE_H_
diff --git a/src/SimpleRandomizer.cc b/src/SimpleRandomizer.cc
new file mode 100644
index 00000000..f975aa7e
--- /dev/null
+++ b/src/SimpleRandomizer.cc
@@ -0,0 +1,37 @@
+/* <!-- 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 "SimpleRandomizer.h"
+
+RandomizerHandle SimpleRandomizer::randomizer = RandomizerHandle(new SimpleRandomizer());
diff --git a/src/SimpleRandomizer.h b/src/SimpleRandomizer.h
new file mode 100644
index 00000000..c826e5dd
--- /dev/null
+++ b/src/SimpleRandomizer.h
@@ -0,0 +1,68 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_SIMPLE_RANDOMIZER_H_
+#define _D_SIMPLE_RANDOMIZER_H_
+
+#include "Randomizer.h"
+#include <stdlib.h>
+#include <time.h>
+
+class SimpleRandomizer : public Randomizer {
+private:
+ static RandomizerHandle randomizer;
+
+ SimpleRandomizer() {}
+public:
+
+ static RandomizerHandle getInstance() {
+ return randomizer;
+ }
+
+ static void init() {
+ srandom(time(NULL));
+ }
+
+ virtual ~SimpleRandomizer() {}
+
+ virtual int getRandomNumber() {
+ return random();
+ }
+
+ virtual int getMaxRandomNumber() {
+ return RAND_MAX;
+ }
+};
+
+#endif // _D_SIMPLE_RANDOMIZER_H_
diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc
index 2fddf138..84a2af3f 100644
--- a/src/TorrentRequestInfo.cc
+++ b/src/TorrentRequestInfo.cc
@@ -73,6 +73,9 @@ RequestInfos TorrentRequestInfo::execute() {
fail = true;
delete ex;
}
+ // TODO we want just 1 torrent download to clear
+ BtRegistry::clear();
+
Util::setGlobalSignalHandler(SIGINT, SIG_DFL, 0);
Util::setGlobalSignalHandler(SIGTERM, SIG_DFL, 0);
diff --git a/src/TrackerUpdateCommand.cc b/src/TrackerUpdateCommand.cc
index c314f41a..23a762b7 100644
--- a/src/TrackerUpdateCommand.cc
+++ b/src/TrackerUpdateCommand.cc
@@ -40,8 +40,6 @@
#include "SleepCommand.h"
#include "Util.h"
-extern PeerHandle nullPeer;
-
TrackerUpdateCommand::TrackerUpdateCommand(int cuid,
TorrentDownloadEngine* e,
const BtContextHandle& btContext):
@@ -89,7 +87,7 @@ bool TrackerUpdateCommand::execute() {
if(!e->segmentMan->finished()) {
return prepareForRetry();
}
- char* trackerResponse = NULL;
+ char* trackerResponse = 0;
size_t trackerResponseLength = 0;
try {
@@ -99,7 +97,7 @@ bool TrackerUpdateCommand::execute() {
trackerResponseLength);
while(!btRuntime->isHalt() && btRuntime->lessThanMinPeer()) {
PeerHandle peer = peerStorage->getUnusedPeer();
- if(peer == nullPeer) {
+ if(peer.isNull()) {
break;
}
int newCuid = btRuntime->getNewCuid();
diff --git a/src/Util.cc b/src/Util.cc
index a37ff330..f767a163 100644
--- a/src/Util.cc
+++ b/src/Util.cc
@@ -48,13 +48,9 @@
#include <unistd.h>
#include <signal.h>
-string Util::itos(int value, bool comma) {
- string str = llitos(value, comma);
- return str;
-}
-string Util::llitos(long long int value, bool comma)
-{
+template<typename T>
+string int2str(T value, bool comma) {
string str;
bool flag = false;
if(value < 0) {
@@ -80,6 +76,27 @@ string Util::llitos(long long int value, bool comma)
return str;
}
+string Util::uitos(uint16_t value, bool comma) {
+ return int2str<uint16_t>(value, comma);
+}
+
+string Util::itos(int16_t value, bool comma) {
+ return int2str<int16_t>(value, comma);
+}
+
+string Util::uitos(uint32_t value, bool comma) {
+ return int2str<uint32_t>(value, comma);
+}
+
+string Util::itos(int32_t value, bool comma) {
+ return int2str<int32_t>(value, comma);
+}
+
+string Util::llitos(int64_t value, bool comma)
+{
+ return int2str<int64_t>(value, comma);
+}
+
string Util::trim(const string& src) {
string::size_type sp = src.find_first_not_of("\r\n\t ");
string::size_type ep = src.find_last_not_of("\r\n\t ");
@@ -430,6 +447,13 @@ void Util::sha1Sum(unsigned char* digest, const void* data, int dataLength) {
ctx.digestFinal(digest);
ctx.digestFree();
}
+
+string Util::simpleMessageDigest(const string& data) {
+ unsigned char checksum[20];
+ sha1Sum(checksum, data.c_str(), data.size());
+ return Util::toHex(checksum, sizeof(checksum));
+}
+
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_MESSAGE_DIGEST
diff --git a/src/Util.h b/src/Util.h
index 379ff4ec..1fdaa4c1 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -52,8 +52,12 @@ using namespace std;
class Util {
public:
static void split(pair<string, string>& hp, const string& src, char delim);
- static string llitos(long long int value, bool comma = false);
- static string itos(int value, bool comma = false);
+ static string llitos(int64_t value, bool comma = false);
+ static string itos(int32_t value, bool comma = false);
+ static string uitos(uint32_t value, bool comma = false);
+ static string itos(int16_t value, bool comma = false);
+ static string uitos(uint16_t value, bool comma = false);
+
/**
* Computes difference in micro-seconds between tv1 and tv2,
* assuming tv1 is newer than tv2.
@@ -103,6 +107,7 @@ public:
// digest must be at least 20 bytes long.
#ifdef ENABLE_MESSAGE_DIGEST
static void sha1Sum(unsigned char* digest, const void* data, int dataLength);
+ static string simpleMessageDigest(const string& data);
#endif // ENABLE_MESSAGE_DIGEST
// Before call this method, allocate enough memory to the parameter "digest".
diff --git a/src/common.h b/src/common.h
index 15ebb043..94e686cc 100644
--- a/src/common.h
+++ b/src/common.h
@@ -34,6 +34,8 @@
/* copyright --> */
#ifndef _D_COMMON_H_
#define _D_COMMON_H_
+// use C99 limit macros
+#define __STDC_LIMIT_MACROS
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -62,6 +64,7 @@
#define DIV_FLOOR(X,Y) ((X)/(Y)+((X)%(Y)? 1:0))
using namespace std;
+//#include "debug_new.h"
class Deleter {
public:
@@ -74,6 +77,6 @@ public:
#include "SharedHandle.h"
typedef deque<string> Strings;
-typedef deque<int> Integers;
+typedef deque<int32_t> Integers;
#endif // _D_COMMON_H_
diff --git a/src/main.cc b/src/main.cc
index e6b04b13..610f6dd6 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -45,6 +45,8 @@
#include "DownloadEngineFactory.h"
#include "UrlRequestInfo.h"
#include "TorrentRequestInfo.h"
+#include "BitfieldManFactory.h"
+#include "SimpleRandomizer.h"
#include <deque>
#include <algorithm>
#include <time.h>
@@ -308,6 +310,8 @@ int main(int argc, char* argv[]) {
op->put(PREF_DNS_TIMEOUT, "10");
op->put(PREF_PEER_CONNECTION_TIMEOUT, "60");
op->put(PREF_BT_TIMEOUT, "180");
+ op->put(PREF_BT_REQUEST_TIMEOUT, "60");
+ op->put(PREF_BT_KEEP_ALIVE_INTERVAL, "120");
op->put(PREF_MIN_SEGMENT_SIZE, "1048576");// 1M
op->put(PREF_MAX_TRIES, "5");
op->put(PREF_HTTP_AUTH_SCHEME, V_BASIC);
@@ -710,7 +714,8 @@ int main(int argc, char* argv[]) {
#ifdef ENABLE_METALINK
xmlInitParser();
#endif // ENABLE_METALINK
- srandom(time(NULL));
+ SimpleRandomizer::init();
+ BitfieldManFactory::setDefaultRandomizer(SimpleRandomizer::getInstance());
if(op->getAsBool(PREF_STDOUT_LOG)) {
LogFactory::setLogFile("/dev/stdout");
} else if(op->get(PREF_LOG).size()) {
diff --git a/src/prefs.h b/src/prefs.h
index 371cbfc9..6a0c05fe 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -131,6 +131,8 @@
#define PREF_PEER_CONNECTION_TIMEOUT "peer_connection_timeout"
// values: 1*digit
#define PREF_BT_TIMEOUT "bt_timeout"
+// values: 1*digit
+#define PREF_BT_REQUEST_TIMEOUT "bt_request_timeout"
// values: true | false
#define PREF_SHOW_FILES "show_files"
// values: true | false
@@ -153,6 +155,8 @@
#define PREF_SEED_RATIO "seed_ratio"
// values: 1*digit
#define PREF_TRACKER_MAX_TRIES "tracker_max_tries"
+// values: 1*digit
+#define PREF_BT_KEEP_ALIVE_INTERVAL "bt_keep_alive_interval"
/**
* Metalink related preferences