summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-02-01 17:36:33 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-02-01 17:36:33 +0000
commit0f133632298e31dab0efe6fd36f00c84d2175f33 (patch)
tree0e9effc84f05b47e3a6c6ec4a9f7b38391d8be86 /src
parent0bce06348e3be57c97e246d2a7af71683dc76ede (diff)
2008-02-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added DHT functionality, compatible with mainline. DHT is disabled by default. To enable it, give --enable-dht to aria2c. You may need to specify entry point to DHT network using --dht-entry-point. DHT uses UDP port to listen incoming message. Use --dht-listen-port to specify port number. Make sure that your firewall configuration can pass through UDP traffic to the port. The routing table is saved in $HOME/.aria2/dht.dat. * src/DHT* * src/BNode.{h, cc} * src/PeerInteractionCommand.cc: enable DHT functionality for a particular torrent. * src/Data.cc: Rewritten ctor. * src/OptionHandlerFactory.cc: Added --enable-dht, --dht-listen-port, --dht-entry-point. * src/DefaultBtInteractive.cc: Send port message if dht is enabled. * src/RequestGroup.cc: Initialize DHT functionality. When download ends, remove BtContext from DHTPeerAnnounceStorage. * src/BtPortMessage.{h, cc}: Rewritten. * src/message.h * src/OptionHandlerImpl.cc * src/option_processing.cc: Added --enable-dht, --dht-listen-port, --dht-entry-point. * src/Dictionary.{h, cc} (remove): New function. * src/prefs.h * src/DefaultBtMessageFactory.h * src/BtHandshakeMessage.cc * src/ActivePeerConnectionCommand.cc * src/SocketCore.{h, cc}: Added datagram socket support. * src/DefaultBtMessageFactory.cc * src/BtSetup.cc: Add BtContext to DHTPeerAnnounceStorage here. Create DHT commands. * src/BtMessageFactory.h * src/PeerMessageUtil.{h, cc}
Diffstat (limited to 'src')
-rw-r--r--src/ActivePeerConnectionCommand.cc6
-rw-r--r--src/BNode.cc217
-rw-r--r--src/BNode.h85
-rw-r--r--src/BNodeDecl.h44
-rw-r--r--src/BtContext.h3
-rw-r--r--src/BtContextDecl.h43
-rw-r--r--src/BtHandshakeMessage.cc6
-rw-r--r--src/BtHandshakeMessage.h11
-rw-r--r--src/BtMessageFactory.h2
-rw-r--r--src/BtPortMessage.cc64
-rw-r--r--src/BtPortMessage.h37
-rw-r--r--src/BtSetup.cc17
-rw-r--r--src/DHTAbstractMessage.cc90
-rw-r--r--src/DHTAbstractMessage.h78
-rw-r--r--src/DHTAbstractNodeLookupTask.cc150
-rw-r--r--src/DHTAbstractNodeLookupTask.h82
-rw-r--r--src/DHTAbstractTask.cc81
-rw-r--r--src/DHTAbstractTask.h82
-rw-r--r--src/DHTAbstractTaskDecl.h43
-rw-r--r--src/DHTAnnouncePeerMessage.cc113
-rw-r--r--src/DHTAnnouncePeerMessage.h92
-rw-r--r--src/DHTAnnouncePeerReplyMessage.cc61
-rw-r--r--src/DHTAnnouncePeerReplyMessage.h57
-rw-r--r--src/DHTAutoSaveCommand.cc109
-rw-r--r--src/DHTAutoSaveCommand.h64
-rw-r--r--src/DHTBucket.cc281
-rw-r--r--src/DHTBucket.h132
-rw-r--r--src/DHTBucketDecl.h45
-rw-r--r--src/DHTBucketRefreshCommand.cc75
-rw-r--r--src/DHTBucketRefreshCommand.h66
-rw-r--r--src/DHTBucketRefreshTask.cc69
-rw-r--r--src/DHTBucketRefreshTask.h49
-rw-r--r--src/DHTConnection.h49
-rw-r--r--src/DHTConnectionDecl.h43
-rw-r--r--src/DHTConnectionImpl.cc91
-rw-r--r--src/DHTConnectionImpl.h65
-rw-r--r--src/DHTConstants.h60
-rw-r--r--src/DHTEntryPointNameResolveCommand.cc161
-rw-r--r--src/DHTEntryPointNameResolveCommand.h80
-rw-r--r--src/DHTFindNodeMessage.cc78
-rw-r--r--src/DHTFindNodeMessage.h66
-rw-r--r--src/DHTFindNodeReplyMessage.cc95
-rw-r--r--src/DHTFindNodeReplyMessage.h63
-rw-r--r--src/DHTGetPeersCommand.cc96
-rw-r--r--src/DHTGetPeersCommand.h85
-rw-r--r--src/DHTGetPeersMessage.cc103
-rw-r--r--src/DHTGetPeersMessage.h77
-rw-r--r--src/DHTGetPeersReplyMessage.cc119
-rw-r--r--src/DHTGetPeersReplyMessage.h79
-rw-r--r--src/DHTIDCloser.h57
-rw-r--r--src/DHTInteractionCommand.cc111
-rw-r--r--src/DHTInteractionCommand.h74
-rw-r--r--src/DHTMessage.cc67
-rw-r--r--src/DHTMessage.h80
-rw-r--r--src/DHTMessageCallback.h52
-rw-r--r--src/DHTMessageCallbackDecl.h43
-rw-r--r--src/DHTMessageCallbackImpl.cc55
-rw-r--r--src/DHTMessageCallbackImpl.h55
-rw-r--r--src/DHTMessageCallbackListener.h51
-rw-r--r--src/DHTMessageDecl.h45
-rw-r--r--src/DHTMessageDispatcher.cc86
-rw-r--r--src/DHTMessageDispatcher.h73
-rw-r--r--src/DHTMessageDispatcherDecl.h43
-rw-r--r--src/DHTMessageEntry.cc44
-rw-r--r--src/DHTMessageEntry.h54
-rw-r--r--src/DHTMessageEntryDecl.h45
-rw-r--r--src/DHTMessageFactory.h107
-rw-r--r--src/DHTMessageFactoryDecl.h43
-rw-r--r--src/DHTMessageFactoryImpl.cc418
-rw-r--r--src/DHTMessageFactoryImpl.h168
-rw-r--r--src/DHTMessageReceiver.cc134
-rw-r--r--src/DHTMessageReceiver.h80
-rw-r--r--src/DHTMessageReceiverDecl.h43
-rw-r--r--src/DHTMessageTracker.cc149
-rw-r--r--src/DHTMessageTracker.h81
-rw-r--r--src/DHTMessageTrackerDecl.h43
-rw-r--r--src/DHTMessageTrackerEntry.cc73
-rw-r--r--src/DHTMessageTrackerEntry.h85
-rw-r--r--src/DHTMessageTrackerEntryDecl.h45
-rw-r--r--src/DHTNode.cc115
-rw-r--r--src/DHTNode.h123
-rw-r--r--src/DHTNodeDecl.h44
-rw-r--r--src/DHTNodeLookupEntry.cc47
-rw-r--r--src/DHTNodeLookupEntry.h54
-rw-r--r--src/DHTNodeLookupEntryDecl.h45
-rw-r--r--src/DHTNodeLookupTask.cc56
-rw-r--r--src/DHTNodeLookupTask.h49
-rw-r--r--src/DHTPeerAnnounceCommand.cc68
-rw-r--r--src/DHTPeerAnnounceCommand.h56
-rw-r--r--src/DHTPeerAnnounceEntry.cc121
-rw-r--r--src/DHTPeerAnnounceEntry.h91
-rw-r--r--src/DHTPeerAnnounceEntryDecl.h45
-rw-r--r--src/DHTPeerAnnounceStorage.cc165
-rw-r--r--src/DHTPeerAnnounceStorage.h92
-rw-r--r--src/DHTPeerAnnounceStorageDecl.h43
-rw-r--r--src/DHTPeerLookupTask.cc102
-rw-r--r--src/DHTPeerLookupTask.h73
-rw-r--r--src/DHTPingMessage.cc70
-rw-r--r--src/DHTPingMessage.h57
-rw-r--r--src/DHTPingReplyMessage.cc65
-rw-r--r--src/DHTPingReplyMessage.h66
-rw-r--r--src/DHTPingTask.cc80
-rw-r--r--src/DHTPingTask.h71
-rw-r--r--src/DHTQueryMessage.cc70
-rw-r--r--src/DHTQueryMessage.h59
-rw-r--r--src/DHTRegistry.cc75
-rw-r--r--src/DHTRegistry.h74
-rw-r--r--src/DHTReplaceNodeTask.cc91
-rw-r--r--src/DHTReplaceNodeTask.h67
-rw-r--r--src/DHTResponseMessage.cc69
-rw-r--r--src/DHTResponseMessage.h59
-rw-r--r--src/DHTRoutingTable.cc171
-rw-r--r--src/DHTRoutingTable.h97
-rw-r--r--src/DHTRoutingTableDecl.h43
-rw-r--r--src/DHTRoutingTableDeserializer.cc134
-rw-r--r--src/DHTRoutingTableDeserializer.h67
-rw-r--r--src/DHTRoutingTableSerializer.cc116
-rw-r--r--src/DHTRoutingTableSerializer.h59
-rw-r--r--src/DHTSetup.cc233
-rw-r--r--src/DHTSetup.h62
-rw-r--r--src/DHTTask.h50
-rw-r--r--src/DHTTaskDecl.h45
-rw-r--r--src/DHTTaskFactory.h64
-rw-r--r--src/DHTTaskFactoryDecl.h43
-rw-r--r--src/DHTTaskFactoryImpl.cc143
-rw-r--r--src/DHTTaskFactoryImpl.h94
-rw-r--r--src/DHTTaskQueue.h55
-rw-r--r--src/DHTTaskQueueDecl.h42
-rw-r--r--src/DHTTaskQueueImpl.cc81
-rw-r--r--src/DHTTaskQueueImpl.h70
-rw-r--r--src/DHTTokenTracker.cc92
-rw-r--r--src/DHTTokenTracker.h68
-rw-r--r--src/DHTTokenTrackerDecl.h43
-rw-r--r--src/DHTTokenUpdateCommand.cc70
-rw-r--r--src/DHTTokenUpdateCommand.h56
-rw-r--r--src/DHTUtil.cc59
-rw-r--r--src/DHTUtil.h56
-rw-r--r--src/Data.cc34
-rw-r--r--src/Data.h4
-rw-r--r--src/DefaultBtInteractive.cc19
-rw-r--r--src/DefaultBtInteractive.h14
-rw-r--r--src/DefaultBtMessageFactory.cc38
-rw-r--r--src/DefaultBtMessageFactory.h30
-rw-r--r--src/Dictionary.cc6
-rw-r--r--src/Dictionary.h1
-rw-r--r--src/DownloadEngine.cc1
-rw-r--r--src/FtpConnection.cc1
-rw-r--r--src/HelpItemFactory.cc15
-rw-r--r--src/Makefile.am51
-rw-r--r--src/Makefile.in173
-rw-r--r--src/OptionHandlerFactory.cc9
-rw-r--r--src/OptionHandlerImpl.h41
-rw-r--r--src/Peer.cc1
-rw-r--r--src/Peer.h15
-rw-r--r--src/PeerAddrEntry.h80
-rw-r--r--src/PeerDecl.h45
-rw-r--r--src/PeerInteractionCommand.cc18
-rw-r--r--src/PeerListenCommand.cc3
-rw-r--r--src/PeerMessageUtil.cc8
-rw-r--r--src/PeerMessageUtil.h2
-rw-r--r--src/RequestGroup.cc8
-rw-r--r--src/SocketCore.cc115
-rw-r--r--src/SocketCore.h28
-rw-r--r--src/Util.h5
-rw-r--r--src/XORCloser.h64
-rw-r--r--src/message.h1
-rw-r--r--src/option_processing.cc17
-rw-r--r--src/prefs.h12
-rw-r--r--src/usage_text.h11
169 files changed, 11522 insertions, 91 deletions
diff --git a/src/ActivePeerConnectionCommand.cc b/src/ActivePeerConnectionCommand.cc
index ef7e1a32..4a8659a9 100644
--- a/src/ActivePeerConnectionCommand.cc
+++ b/src/ActivePeerConnectionCommand.cc
@@ -59,10 +59,10 @@ bool ActivePeerConnectionCommand::execute() {
}
if(!pieceStorage->downloadFinished() && checkPoint.elapsed(interval)) {
checkPoint.reset();
-
TransferStat tstat = peerStorage->calculateStat();
- if(tstat.getDownloadSpeed() < _lowestSpeedLimit) {
- for(int i = 0; i < _numNewConnection && peerStorage->isPeerAvailable(); ++i) {
+ size_t numAdd = btRuntime->lessThanEqMinPeer() ? MIN_PEERS-btRuntime->getConnections():_numNewConnection;
+ if(tstat.getDownloadSpeed() < _lowestSpeedLimit || btRuntime->lessThanEqMinPeer()) {
+ for(; numAdd > 0 && peerStorage->isPeerAvailable(); --numAdd) {
PeerHandle peer = peerStorage->getUnusedPeer();
connectToPeer(peer);
}
diff --git a/src/BNode.cc b/src/BNode.cc
new file mode 100644
index 00000000..6e8f7d69
--- /dev/null
+++ b/src/BNode.cc
@@ -0,0 +1,217 @@
+/* <!-- 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 "BNode.h"
+#include "DHTBucket.h"
+#include "DHTNode.h"
+
+BNode::BNode(const DHTBucketHandle& bucket):_bucket(bucket),
+ _up(0),
+ _left(0), _right(0) {}
+
+BNode::~BNode()
+{
+ delete _left;
+ delete _right;
+}
+
+DHTBucketHandle BNode::getBucket() const
+{
+ return _bucket;
+}
+
+BNode* BNode::getLeft() const
+{
+ return _left;
+}
+
+BNode* BNode::getRight() const
+{
+ return _right;
+}
+
+BNode* BNode::getUp() const
+{
+ return _up;
+}
+
+void BNode::setLeft(BNode* left)
+{
+ _left = left;
+ _left->_up = this;
+}
+
+void BNode::setRight(BNode* right)
+{
+ _right = right;
+ _right->_up = this;
+}
+
+void BNode::setUp(BNode* up)
+{
+ _up = up;
+}
+
+void BNode::setBucket(const DHTBucketHandle& bucket)
+{
+ _bucket = bucket;
+}
+
+bool BNode::isInRange(const unsigned char* key) const
+{
+ if(_bucket.isNull()) {
+ return _left->isInRange(key) || _right->isInRange(key);
+ } else {
+ return _bucket->isInRange(key);
+ }
+}
+
+BNode* BNode::findBNodeFor(BNode* b, const unsigned char* key)
+{
+ if(!b->isInRange(key)) {
+ return 0;
+ }
+ while(1) {
+ if(!b->getBucket().isNull()) {
+ return b;
+ }
+ // we assume key fits in either left or right bucket range.
+ if(b->getLeft()->isInRange(key)) {
+ b = b->getLeft();
+ } else {
+ b = b->getRight();
+ }
+ }
+ // for properly configured BNode tree, here is unreachable.
+ return 0;
+}
+
+DHTBucketHandle BNode::findBucketFor(BNode* b, const unsigned char* key)
+{
+ BNode* bnode = findBNodeFor(b, key);
+ if(bnode) {
+ return bnode->getBucket();
+ } else {
+ return 0;
+ }
+}
+
+
+DHTNodes BNode::findClosestKNodes(BNode* b, const unsigned char* key)
+{
+ BNode* bnode = findBNodeFor(b, key);
+ DHTNodes nodes;
+ if(!bnode) {
+ return nodes;
+ }
+ {
+ DHTBucketHandle bucket = bnode->getBucket();
+ DHTNodes goodNodes = bucket->getGoodNodes();
+ nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end());
+ }
+ if(nodes.size() >= DHTBucket::K) {
+ return nodes;
+ }
+ BNodes visited;
+ visited.push_back(bnode);
+
+ BNode* up = bnode->getUp();
+ if(!up) {
+ return nodes;
+ }
+ bool leftFirst = false;
+ if(up->getLeft() == bnode) {
+ leftFirst = true;
+ }
+ bnode = up;
+
+ const_mem_fun_t<BNode*, BNode> firstfunc = leftFirst?mem_fun(&BNode::getLeft):mem_fun(&BNode::getRight);
+ const_mem_fun_t<BNode*, BNode> secondfunc = leftFirst?mem_fun(&BNode::getRight):mem_fun(&BNode::getLeft);
+ while(nodes.size() < DHTBucket::K) {
+
+ if(!bnode->getLeft() && !bnode->getRight()) {
+ bnode = bnode->getUp();
+ } else {
+ if(find(visited.begin(), visited.end(), firstfunc(bnode)) == visited.end()) {
+ bnode = firstfunc(bnode);
+ } else if(find(visited.begin(), visited.end(), secondfunc(bnode)) == visited.end()) {
+ bnode = secondfunc(bnode);
+ } else {
+ bnode = bnode->getUp();
+ }
+ }
+ visited.push_back(bnode);
+ if(!bnode) {
+ break;
+ }
+ {
+ DHTBucketHandle bucket = bnode->getBucket();
+ if(!bucket.isNull()) {
+ DHTNodes goodNodes = bucket->getGoodNodes();
+ size_t r = DHTBucket::K-nodes.size();
+ if(goodNodes.size() <= r) {
+ nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end());
+ } else {
+ nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.begin()+r);
+ }
+ }
+ }
+ }
+ return nodes;
+}
+
+DHTBuckets BNode::enumerateBucket(const BNode* b)
+{
+ DHTBuckets buckets;
+ deque<const BNode*> visited;
+ visited.push_back(b);
+ while(1) {
+ if(!b) {
+ break;
+ }
+ if(!b->getBucket().isNull()) {
+ buckets.push_back(b->getBucket());
+ b = b->getUp();
+ } else if(find(visited.begin(), visited.end(), b->getLeft()) == visited.end()) {
+ b = b->getLeft();
+ visited.push_back(b);
+ } else if(find(visited.begin(), visited.end(), b->getRight()) == visited.end()) {
+ b = b->getRight();
+ visited.push_back(b);
+ } else {
+ b = b->getUp();
+ }
+ }
+ return buckets;
+}
diff --git a/src/BNode.h b/src/BNode.h
new file mode 100644
index 00000000..4be3ac8f
--- /dev/null
+++ b/src/BNode.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_BNODE_H_
+#define _D_BNODE_H_
+
+#include "common.h"
+#include "DHTBucketDecl.h"
+#include "BNodeDecl.h"
+#include "DHTNodeDecl.h"
+
+class BNode {
+private:
+ DHTBucketHandle _bucket;
+
+ BNode* _up;
+
+ BNode* _left;
+
+ BNode* _right;
+
+public:
+ BNode(const DHTBucketHandle& bucket = 0);
+
+ ~BNode();
+
+ DHTBucketHandle getBucket() const;
+
+ void setBucket(const DHTBucketHandle& bucket);
+
+ BNode* getLeft() const;
+
+ void setLeft(BNode* left);
+
+ BNode* getRight() const;
+
+ void setRight(BNode* right);
+
+ BNode* getUp() const;
+
+ void setUp(BNode* up);
+
+ bool isInRange(const unsigned char* key) const;
+
+ static BNode* findBNodeFor(BNode* b, const unsigned char* key);
+
+ static DHTBucketHandle findBucketFor(BNode* b, const unsigned char* key);
+
+ static DHTNodes findClosestKNodes(BNode* b, const unsigned char* key);
+
+ static DHTBuckets enumerateBucket(const BNode* b);
+};
+
+#endif // _D_BNODE_H_
diff --git a/src/BNodeDecl.h b/src/BNodeDecl.h
new file mode 100644
index 00000000..56abb655
--- /dev/null
+++ b/src/BNodeDecl.h
@@ -0,0 +1,44 @@
+/* <!-- 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_BNODE_DECL_H_
+#define _D_BNODE_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class BNode;
+
+typedef std::deque<BNode*> BNodes;
+#endif // _D_BNODE_DECL_H_
diff --git a/src/BtContext.h b/src/BtContext.h
index 6cec275b..c48dff74 100644
--- a/src/BtContext.h
+++ b/src/BtContext.h
@@ -36,6 +36,7 @@
#define _D_BT_CONTEXT_H_
#include "DownloadContext.h"
+#include "BtContextDecl.h"
#define INFO_HASH_LENGTH 20
#define MAX_PEER_ERROR 5
@@ -81,6 +82,4 @@ public:
};
-typedef SharedHandle<BtContext> BtContextHandle;
-
#endif // _D_BT_CONTEXT_H_
diff --git a/src/BtContextDecl.h b/src/BtContextDecl.h
new file mode 100644
index 00000000..2cc3b5cf
--- /dev/null
+++ b/src/BtContextDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_CONTEXT_DECL_H_
+#define _D_BT_CONTEXT_DECL_H_
+
+#include "SharedHandle.h"
+
+class BtContext;
+typedef SharedHandle<BtContext> BtContextHandle;
+
+#endif // _D_BT_CONTEXT_DECL_H_
diff --git a/src/BtHandshakeMessage.cc b/src/BtHandshakeMessage.cc
index 33ad8915..c79e2119 100644
--- a/src/BtHandshakeMessage.cc
+++ b/src/BtHandshakeMessage.cc
@@ -105,3 +105,9 @@ bool BtHandshakeMessage::isExtendedMessagingEnabled() const
{
return reserved[5]&0x10;
}
+
+bool BtHandshakeMessage::isDHTEnabled() const
+{
+ return reserved[7]&0x01;
+}
+
diff --git a/src/BtHandshakeMessage.h b/src/BtHandshakeMessage.h
index 9ad92f08..bbf9afa3 100644
--- a/src/BtHandshakeMessage.h
+++ b/src/BtHandshakeMessage.h
@@ -89,6 +89,17 @@ public:
bool isExtendedMessagingEnabled() const;
+ bool isDHTEnabled() const;
+
+ void setDHTEnabled(bool enabled)
+ {
+ if(enabled) {
+ this->reserved[7] |= 0x01;
+ } else {
+ this->reserved[7] &= ~0x01;
+ }
+ }
+
int8_t getPstrlen() const {
return pstrlen;
}
diff --git a/src/BtMessageFactory.h b/src/BtMessageFactory.h
index 11ea7926..24fac205 100644
--- a/src/BtMessageFactory.h
+++ b/src/BtMessageFactory.h
@@ -88,6 +88,8 @@ public:
virtual BtMessageHandle createAllowedFastMessage(int32_t index) = 0;
+ virtual BtMessageHandle createPortMessage(uint16_t port) = 0;
+
virtual BtMessageHandle createBtExtendedMessage(const ExensionMessageHandle& msg) = 0;
};
diff --git a/src/BtPortMessage.cc b/src/BtPortMessage.cc
index 4358dc5b..d81e7101 100644
--- a/src/BtPortMessage.cc
+++ b/src/BtPortMessage.cc
@@ -37,8 +37,20 @@
#include "DlAbortEx.h"
#include "Util.h"
#include "message.h"
+#include "DHTNode.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
-BtPortMessageHandle BtPortMessage::create(const unsigned char* data, int32_t dataLength) {
+BtPortMessage::BtPortMessage(uint16_t port): _port(port), _msg(0) {}
+
+BtPortMessage::~BtPortMessage()
+{
+ delete [] _msg;
+}
+
+SharedHandle<BtPortMessage> BtPortMessage::create(const unsigned char* data, int32_t dataLength)
+{
if(dataLength != 3) {
throw new DlAbortEx(EX_INVALID_PAYLOAD_SIZE, "port", dataLength, 3);
}
@@ -46,11 +58,55 @@ BtPortMessageHandle BtPortMessage::create(const unsigned char* data, int32_t dat
if(id != ID) {
throw new DlAbortEx(EX_INVALID_BT_MESSAGE_ID, id, "piece", ID);
}
- BtPortMessageHandle message = new BtPortMessage();
- message->setPort(PeerMessageUtil::getShortIntParam(data, 1));
+ uint16_t port = PeerMessageUtil::getShortIntParam(data, 1);
+ SharedHandle<BtPortMessage> message = new BtPortMessage(port);
return message;
}
+void BtPortMessage::doReceivedAction()
+{
+ if(!_taskFactory.isNull() && !_taskQueue.isNull()) {
+ // node id is random at this point. When ping reply received, new DHTNode
+ // instance created with proper node ID and is added to a routing table.
+ DHTNodeHandle node = new DHTNode();
+ node->setIPAddress(peer->ipaddr);
+ node->setPort(_port);
+ DHTTaskHandle task = _taskFactory->createPingTask(node);
+ _taskQueue->addImmediateTask(task);
+ } else {
+ logger->info("DHT port message received while localhost didn't declare support it.");
+ }
+}
+
+const unsigned char* BtPortMessage::getMessage() {
+ if(!_msg) {
+ /**
+ * len --- 5, 4bytes
+ * id --- 4, 1byte
+ * port --- port number, 2bytes
+ * total: 7bytes
+ */
+ _msg = new unsigned char[MESSAGE_LENGTH];
+ PeerMessageUtil::createPeerMessageString(_msg, MESSAGE_LENGTH, 3, ID);
+ PeerMessageUtil::setShortIntParam(&_msg[5], _port);
+ }
+ return _msg;
+}
+
+int32_t BtPortMessage::getMessageLength() {
+ return MESSAGE_LENGTH;
+}
+
string BtPortMessage::toString() const {
- return "port port="+Util::itos(port);
+ return "port port="+Util::uitos(_port);
+}
+
+void BtPortMessage::setTaskQueue(const WeakHandle<DHTTaskQueue>& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void BtPortMessage::setTaskFactory(const WeakHandle<DHTTaskFactory>& taskFactory)
+{
+ _taskFactory = taskFactory;
}
diff --git a/src/BtPortMessage.h b/src/BtPortMessage.h
index 9b8e8297..d500a446 100644
--- a/src/BtPortMessage.h
+++ b/src/BtPortMessage.h
@@ -35,36 +35,43 @@
#ifndef _D_BT_PORT_MESSAGE_H_
#define _D_BT_PORT_MESSAGE_H_
-#include "AbstractBtMessage.h"
+#include "SimpleBtMessage.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
-class BtPortMessage;
+class BtPortMessage : public SimpleBtMessage {
+private:
+ uint16_t _port;
+ unsigned char* _msg;
+ static const size_t MESSAGE_LENGTH = 7;
-typedef SharedHandle<BtPortMessage> BtPortMessageHandle;
+ WeakHandle<DHTTaskQueue> _taskQueue;
-class BtPortMessage : public AbstractBtMessage {
-private:
- int16_t port;
+ WeakHandle<DHTTaskFactory> _taskFactory;
public:
- BtPortMessage(int16_t port = 0):port(port) {}
+ BtPortMessage(uint16_t port);
- virtual ~BtPortMessage() {}
+ virtual ~BtPortMessage();
static const int8_t ID = 9;
- int16_t getPort() const { return port; }
+ uint16_t getPort() const { return _port; }
- void setPort(int16_t port) { this->port = port; }
+ static SharedHandle<BtPortMessage> create(const unsigned char* data, int32_t dataLength);
virtual int8_t getId() { return ID; }
- static BtPortMessageHandle create(const unsigned char* data, int32_t dataLength);
+ virtual void doReceivedAction();
+
+ virtual const unsigned char* getMessage();
- virtual void doReceivedAction() {
- logger->info("DHT is not supported yet.");
- }
- virtual void send() {}
+ virtual int32_t getMessageLength();
virtual string toString() const;
+
+ void setTaskQueue(const WeakHandle<DHTTaskQueue>& taskQueue);
+
+ void setTaskFactory(const WeakHandle<DHTTaskFactory>& taskFactory);
};
#endif // _D_BT_PORT_MESSAGE_H_
diff --git a/src/BtSetup.cc b/src/BtSetup.cc
index 03026c40..666c1027 100644
--- a/src/BtSetup.cc
+++ b/src/BtSetup.cc
@@ -54,6 +54,10 @@
#include "Logger.h"
#include "Util.h"
#include "IntSequence.h"
+#include "DHTGetPeersCommand.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTSetup.h"
+#include "DHTRegistry.h"
BtSetup::BtSetup():_logger(LogFactory::getInstance()) {}
@@ -80,8 +84,17 @@ Commands BtSetup::setup(RequestGroup* requestGroup,
requestGroup,
e,
btContext,
- 30));
-
+ 10));
+ if(!btContext->isPrivate() && DHTSetup::initialized()) {
+ DHTRegistry::_peerAnnounceStorage->addPeerAnnounce(btContext);
+ DHTGetPeersCommand* command = new DHTGetPeersCommand(CUIDCounterSingletonHolder::instance()->newID(),
+ requestGroup,
+ e,
+ btContext);
+ command->setTaskQueue(DHTRegistry::_taskQueue);
+ command->setTaskFactory(DHTRegistry::_taskFactory);
+ commands.push_back(command);
+ }
SharedHandle<UnionSeedCriteria> unionCri = new UnionSeedCriteria();
if(option->defined(PREF_SEED_TIME)) {
unionCri->addSeedCriteria(new TimeSeedCriteria(option->getAsInt(PREF_SEED_TIME)*60));
diff --git a/src/DHTAbstractMessage.cc b/src/DHTAbstractMessage.cc
new file mode 100644
index 00000000..6e3d585c
--- /dev/null
+++ b/src/DHTAbstractMessage.cc
@@ -0,0 +1,90 @@
+/* <!-- 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 "DHTAbstractMessage.h"
+#include "DHTNode.h"
+#include "BencodeVisitor.h"
+#include "DHTConnection.h"
+#include "Data.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageFactory.h"
+#include "DHTRoutingTable.h"
+
+DHTAbstractMessage::DHTAbstractMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTMessage(localNode, remoteNode, transactionID) {}
+
+DHTAbstractMessage::~DHTAbstractMessage() {}
+
+string DHTAbstractMessage::getBencodedMessage()
+{
+ SharedHandle<Dictionary> msg = new Dictionary();
+ msg->put(string("t"), new Data(_transactionID));
+ msg->put(string("y"), new Data(getType()));
+ fillMessage(msg.get());
+
+ BencodeVisitor v;
+ msg->accept(&v);
+ return v.getBencodedData();
+}
+
+void DHTAbstractMessage::send()
+{
+ string message = getBencodedMessage();
+ _connection->sendMessage(message.c_str(),
+ message.size(),
+ _remoteNode->getIPAddress(),
+ _remoteNode->getPort());
+}
+
+void DHTAbstractMessage::setConnection(const WeakHandle<DHTConnection>& connection)
+{
+ _connection = connection;
+}
+
+void DHTAbstractMessage::setMessageDispatcher(const WeakHandle<DHTMessageDispatcher>& dispatcher)
+{
+ _dispatcher = dispatcher;
+}
+
+void DHTAbstractMessage::setMessageFactory(const WeakHandle<DHTMessageFactory>& factory)
+{
+ _factory = factory;
+}
+
+void DHTAbstractMessage::setRoutingTable(const WeakHandle<DHTRoutingTable>& routingTable)
+{
+ _routingTable = routingTable;
+}
diff --git a/src/DHTAbstractMessage.h b/src/DHTAbstractMessage.h
new file mode 100644
index 00000000..42d658b3
--- /dev/null
+++ b/src/DHTAbstractMessage.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_DHT_ABSTRACT_MESSAGE_H_
+#define _D_DHT_ABSTRACT_MESSAGE_H_
+
+#include "DHTMessage.h"
+#include "Dictionary.h"
+#include "DHTConnectionDecl.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageFactoryDecl.h"
+#include "DHTRoutingTableDecl.h"
+
+class DHTAbstractMessage:public DHTMessage {
+protected:
+ WeakHandle<DHTConnection> _connection;
+
+ WeakHandle<DHTMessageDispatcher> _dispatcher;
+
+ WeakHandle<DHTMessageFactory> _factory;
+
+ WeakHandle<DHTRoutingTable> _routingTable;
+public:
+ DHTAbstractMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID = "");
+
+ virtual ~DHTAbstractMessage();
+
+ virtual void send();
+
+ virtual string getType() const = 0;
+
+ virtual void fillMessage(Dictionary* message) = 0;
+
+ string getBencodedMessage();
+
+ void setConnection(const WeakHandle<DHTConnection>& connection);
+
+ void setMessageDispatcher(const WeakHandle<DHTMessageDispatcher>& dispatcher);
+
+ void setMessageFactory(const WeakHandle<DHTMessageFactory>& factory);
+
+ void setRoutingTable(const WeakHandle<DHTRoutingTable>& routingTable);
+};
+
+#endif // _D_DHT_ABSTRACT_MESSAGE_H_
diff --git a/src/DHTAbstractNodeLookupTask.cc b/src/DHTAbstractNodeLookupTask.cc
new file mode 100644
index 00000000..9bc8ddf8
--- /dev/null
+++ b/src/DHTAbstractNodeLookupTask.cc
@@ -0,0 +1,150 @@
+/* <!-- 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 "DHTAbstractNodeLookupTask.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessage.h"
+#include "DHTNode.h"
+#include "DHTNodeLookupEntry.h"
+#include "DHTMessageCallbackImpl.h"
+#include "DHTBucket.h"
+#include "LogFactory.h"
+#include "Util.h"
+#include "DHTIDCloser.h"
+
+DHTAbstractNodeLookupTask::DHTAbstractNodeLookupTask(const unsigned char* targetID):
+ _inFlightMessage(0)
+{
+ memcpy(_targetID, targetID, DHT_ID_LENGTH);
+}
+
+void DHTAbstractNodeLookupTask::onReceived(const DHTMessageHandle& message)
+{
+ --_inFlightMessage;
+ onReceivedInternal(message);
+ DHTNodeLookupEntries newEntries = toEntries(getNodesFromMessage(message));
+ size_t count = 0;
+ for(DHTNodeLookupEntries::const_iterator i = newEntries.begin();
+ i != newEntries.end(); ++i) {
+ if(memcmp(_localNode->getID(), (*i)->_node->getID(), DHT_ID_LENGTH) != 0) {
+ _entries.push_front(*i);
+ ++count;
+ }
+ }
+ _logger->debug("%u node lookup entries added.", count);
+ stable_sort(_entries.begin(), _entries.end(), DHTIDCloser(_targetID));
+ _entries.erase(unique(_entries.begin(), _entries.end()), _entries.end());
+ _logger->debug("%u node lookup entries are unique.", _entries.size());
+ if(_entries.size() > DHTBucket::K) {
+ _entries.erase(_entries.begin()+DHTBucket::K, _entries.end());
+ }
+ if(needsAdditionalOutgoingMessage()) {
+ sendMessage();
+ }
+ if(_inFlightMessage == 0) {
+ _logger->debug("Finished node_lookup for node ID %s",
+ Util::toHex(_targetID, DHT_ID_LENGTH).c_str());
+ onFinish();
+ updateBucket();
+ _finished = true;
+ }
+}
+
+void DHTAbstractNodeLookupTask::onTimeout(const DHTNodeHandle& node)
+{
+ _logger->debug("node lookup message timeout for node ID=%s",
+ Util::toHex(node->getID(), DHT_ID_LENGTH).c_str());
+ --_inFlightMessage;
+ for(DHTNodeLookupEntries::iterator i = _entries.begin(); i != _entries.end(); ++i) {
+ if((*i)->_node == node) {
+ _entries.erase(i);
+ break;
+ }
+ }
+ if(needsAdditionalOutgoingMessage()) {
+ sendMessage();
+ }
+ if(_inFlightMessage == 0) {
+ _logger->debug("Finished node_lookup for node ID %s",
+ Util::toHex(_targetID, DHT_ID_LENGTH).c_str());
+ onFinish();
+ updateBucket();
+ _finished = true;
+ }
+}
+
+void DHTAbstractNodeLookupTask::sendMessage()
+{
+ for(DHTNodeLookupEntries::iterator i = _entries.begin(); i != _entries.end() && _inFlightMessage < ALPHA; ++i) {
+ if((*i)->_used == false) {
+ ++_inFlightMessage;
+ (*i)->_used = true;
+ DHTMessageHandle m = createMessage((*i)->_node);
+ _dispatcher->addMessageToQueue(m, new DHTMessageCallbackImpl(this));
+ }
+ }
+}
+
+void DHTAbstractNodeLookupTask::updateBucket()
+{
+ // TODO we have to something here?
+}
+
+void DHTAbstractNodeLookupTask::startup()
+{
+ _entries = toEntries(_routingTable->getClosestKNodes(_targetID));
+ if(_entries.empty()) {
+ _finished = true;
+ } else {
+ // TODO use RTT here
+ _inFlightMessage = 0;
+ sendMessage();
+ if(_inFlightMessage == 0) {
+ _logger->debug("No message was sent in this lookup stage. Finished.");
+ _finished = true;
+ }
+ }
+}
+
+DHTNodeLookupEntries DHTAbstractNodeLookupTask::toEntries(const DHTNodes& nodes) const
+{
+ DHTNodeLookupEntries entries;
+ for(DHTNodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
+ DHTNodeLookupEntryHandle e = new DHTNodeLookupEntry(*i);
+ entries.push_back(e);
+ }
+ return entries;
+}
diff --git a/src/DHTAbstractNodeLookupTask.h b/src/DHTAbstractNodeLookupTask.h
new file mode 100644
index 00000000..28255a43
--- /dev/null
+++ b/src/DHTAbstractNodeLookupTask.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_DHT_ABSTRACT_NODE_LOOKUP_TASK_H_
+#define _D_DHT_ABSTRACT_NODE_LOOKUP_TASK_H_
+
+#include "DHTAbstractTask.h"
+#include "DHTNodeDecl.h"
+#include "DHTNodeLookupEntryDecl.h"
+#include "DHTConstants.h"
+#include "DHTTask.h"
+#include "DHTMessageDecl.h"
+#include "DHTMessageCallbackListener.h"
+
+class DHTAbstractNodeLookupTask:public DHTAbstractTask, public DHTMessageCallbackListener {
+protected:
+ unsigned char _targetID[DHT_ID_LENGTH];
+
+ DHTNodeLookupEntries _entries;
+
+ size_t _inFlightMessage;
+
+ DHTNodeLookupEntries toEntries(const DHTNodes& nodes) const;
+
+ void sendMessage();
+
+ void updateBucket();
+
+public:
+ DHTAbstractNodeLookupTask(const unsigned char* targetID);
+
+ static const size_t ALPHA = 3;
+
+ virtual void startup();
+
+ virtual void onReceived(const DHTMessageHandle& message);
+
+ virtual void onTimeout(const DHTNodeHandle& node);
+
+ virtual DHTNodes getNodesFromMessage(const DHTMessageHandle& message) = 0;
+
+ virtual void onReceivedInternal(const DHTMessageHandle& message) {}
+
+ virtual bool needsAdditionalOutgoingMessage() { return true; }
+
+ virtual void onFinish() {}
+
+ virtual DHTMessageHandle createMessage(const DHTNodeHandle& remoteNode) = 0;
+};
+
+#endif // _D_DHT_ABSTRACT_NODE_LOOKUP_TASK_H_
diff --git a/src/DHTAbstractTask.cc b/src/DHTAbstractTask.cc
new file mode 100644
index 00000000..e43e554f
--- /dev/null
+++ b/src/DHTAbstractTask.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 "DHTAbstractTask.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessage.h"
+#include "DHTNode.h"
+#include "DHTMessageCallback.h"
+#include "DHTBucket.h"
+#include "DHTTaskQueue.h"
+#include "LogFactory.h"
+#include "Util.h"
+
+DHTAbstractTask::DHTAbstractTask():
+ _finished(false),
+ _logger(LogFactory::getInstance()),
+ _localNode(0)
+{}
+
+bool DHTAbstractTask::finished()
+{
+ return _finished;
+}
+
+void DHTAbstractTask::setRoutingTable(const WeakHandle<DHTRoutingTable> routingTable)
+{
+ _routingTable = routingTable;
+}
+
+void DHTAbstractTask::setMessageDispatcher(const WeakHandle<DHTMessageDispatcher> dispatcher)
+{
+ _dispatcher = dispatcher;
+}
+
+void DHTAbstractTask::setMessageFactory(const WeakHandle<DHTMessageFactory> factory)
+{
+ _factory = factory;
+}
+
+void DHTAbstractTask::setTaskQueue(const WeakHandle<DHTTaskQueue> taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTAbstractTask::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
diff --git a/src/DHTAbstractTask.h b/src/DHTAbstractTask.h
new file mode 100644
index 00000000..0efdcc8e
--- /dev/null
+++ b/src/DHTAbstractTask.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_DHT_ABSTRACT_TASK_H_
+#define _D_DHT_ABSTRACT_TASK_H_
+
+#include "common.h"
+#include "DHTAbstractTaskDecl.h"
+#include "DHTNodeDecl.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageFactoryDecl.h"
+#include "DHTConstants.h"
+#include "DHTTask.h"
+#include "DHTMessageDecl.h"
+#include "DHTTaskQueueDecl.h"
+
+class Logger;
+
+class DHTAbstractTask:public DHTTask {
+protected:
+ bool _finished;
+
+ const Logger* _logger;
+
+ DHTNodeHandle _localNode;
+
+ WeakHandle<DHTRoutingTable> _routingTable;
+
+ WeakHandle<DHTMessageDispatcher> _dispatcher;
+
+ WeakHandle<DHTMessageFactory> _factory;
+
+ WeakHandle<DHTTaskQueue> _taskQueue;
+public:
+ DHTAbstractTask();
+
+ virtual bool finished();
+
+ void setRoutingTable(const WeakHandle<DHTRoutingTable> routingTable);
+
+ void setMessageDispatcher(const WeakHandle<DHTMessageDispatcher> dispatcher);
+
+ void setMessageFactory(const WeakHandle<DHTMessageFactory> factory);
+
+ void setTaskQueue(const WeakHandle<DHTTaskQueue> taskQueue);
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+};
+
+#endif // _D_DHT_ABSTRACT_TASK_H_
diff --git a/src/DHTAbstractTaskDecl.h b/src/DHTAbstractTaskDecl.h
new file mode 100644
index 00000000..f68bf702
--- /dev/null
+++ b/src/DHTAbstractTaskDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_ABSTRACT_TASK_DECL_H_
+#define _D_DHT_ABSTRACT_TASK_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTAbstractTask;
+typedef SharedHandle<DHTAbstractTask> DHTAbstractTaskHandle;
+
+#endif // _D_DHT_ABSTRACT_TASK_DECL_H_
diff --git a/src/DHTAnnouncePeerMessage.cc b/src/DHTAnnouncePeerMessage.cc
new file mode 100644
index 00000000..414511e7
--- /dev/null
+++ b/src/DHTAnnouncePeerMessage.cc
@@ -0,0 +1,113 @@
+/* <!-- 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 "DHTAnnouncePeerMessage.h"
+#include "DHTNode.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+#include "Util.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTracker.h"
+#include "DlAbortEx.h"
+
+DHTAnnouncePeerMessage::DHTAnnouncePeerMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ uint16_t tcpPort,
+ const string& token,
+ const string& transactionID):
+ DHTQueryMessage(localNode, remoteNode, transactionID),
+ _token(token),
+ _tcpPort(tcpPort),
+ _peerAnnounceStorage(0),
+ _tokenTracker(0)
+{
+ memcpy(_infoHash, infoHash, DHT_ID_LENGTH);
+}
+
+DHTAnnouncePeerMessage::~DHTAnnouncePeerMessage() {}
+
+void DHTAnnouncePeerMessage::doReceivedAction()
+{
+ _peerAnnounceStorage->addPeerAnnounce(_infoHash, _remoteNode->getIPAddress(),
+ _tcpPort);
+
+ DHTMessageHandle reply =
+ _factory->createAnnouncePeerReplyMessage(_remoteNode, _transactionID);
+ _dispatcher->addMessageToQueue(reply);
+}
+
+Dictionary* DHTAnnouncePeerMessage::getArgument()
+{
+ Dictionary* a = new Dictionary();
+ a->put("id", new Data(reinterpret_cast<const char*>(_localNode->getID()),
+ DHT_ID_LENGTH));
+ a->put("info_hash", new Data(reinterpret_cast<const char*>(_infoHash),
+ DHT_ID_LENGTH));
+ a->put("port", new Data(Util::uitos(_tcpPort), true));
+ a->put("token", new Data(_token));
+
+ return a;
+}
+
+string DHTAnnouncePeerMessage::getMessageType() const
+{
+ return "announce_peer";
+}
+
+void DHTAnnouncePeerMessage::validate() const
+{
+ if(!_tokenTracker->validateToken(_token, _infoHash,
+ _remoteNode->getIPAddress(),
+ _remoteNode->getPort())) {
+ throw new DlAbortEx("Invalid token=%s from %s:%u",
+ Util::toHex(_token).c_str(),
+ _remoteNode->getIPAddress().c_str(),
+ _remoteNode->getPort());
+ }
+}
+
+void DHTAnnouncePeerMessage::setPeerAnnounceStorage(const WeakHandle<DHTPeerAnnounceStorage>& storage)
+{
+ _peerAnnounceStorage = storage;
+}
+
+void DHTAnnouncePeerMessage::setTokenTracker(const WeakHandle<DHTTokenTracker>& tokenTracker)
+{
+ _tokenTracker = tokenTracker;
+}
diff --git a/src/DHTAnnouncePeerMessage.h b/src/DHTAnnouncePeerMessage.h
new file mode 100644
index 00000000..452629c4
--- /dev/null
+++ b/src/DHTAnnouncePeerMessage.h
@@ -0,0 +1,92 @@
+/* <!-- 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_DHT_ANNOUNCE_PEER_MESSAGE_H_
+#define _D_DHT_ANNOUNCE_PEER_MESSAGE_H_
+
+#include "DHTQueryMessage.h"
+#include "DHTConstants.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTrackerDecl.h"
+
+class DHTAnnouncePeerMessage:public DHTQueryMessage {
+private:
+ string _token;
+
+ unsigned char _infoHash[DHT_ID_LENGTH];
+
+ uint16_t _tcpPort;
+
+ WeakHandle<DHTPeerAnnounceStorage> _peerAnnounceStorage;
+
+ WeakHandle<DHTTokenTracker> _tokenTracker;
+public:
+ DHTAnnouncePeerMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ uint16_t tcpPort,
+ const string& token,
+ const string& transactionID = "");
+
+ virtual ~DHTAnnouncePeerMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getArgument();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const unsigned char* getInfoHash() const
+ {
+ return _infoHash;
+ }
+
+ const string& getToken() const
+ {
+ return _token;
+ }
+
+ uint16_t getTCPPort() const
+ {
+ return _tcpPort;
+ }
+
+ void setPeerAnnounceStorage(const WeakHandle<DHTPeerAnnounceStorage>& storage);
+
+ void setTokenTracker(const WeakHandle<DHTTokenTracker>& tokenTracker);
+};
+
+#endif // _D_DHT_ANNOUNCE_PEER_MESSAGE_H_
diff --git a/src/DHTAnnouncePeerReplyMessage.cc b/src/DHTAnnouncePeerReplyMessage.cc
new file mode 100644
index 00000000..b3674c08
--- /dev/null
+++ b/src/DHTAnnouncePeerReplyMessage.cc
@@ -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 --> */
+#include "DHTAnnouncePeerReplyMessage.h"
+#include "DHTNode.h"
+#include "Dictionary.h"
+#include "Data.h"
+
+DHTAnnouncePeerReplyMessage::DHTAnnouncePeerReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTResponseMessage(localNode, remoteNode, transactionID) {}
+
+DHTAnnouncePeerReplyMessage::~DHTAnnouncePeerReplyMessage() {}
+
+void DHTAnnouncePeerReplyMessage::doReceivedAction() {}
+
+Dictionary* DHTAnnouncePeerReplyMessage::getResponse()
+{
+ Dictionary* r = new Dictionary();
+ r->put("id", new Data(_localNode->getID(), DHT_ID_LENGTH));
+ return r;
+}
+
+string DHTAnnouncePeerReplyMessage::getMessageType() const
+{
+ return "announce_peer";
+}
+
+void DHTAnnouncePeerReplyMessage::validate() const {}
diff --git a/src/DHTAnnouncePeerReplyMessage.h b/src/DHTAnnouncePeerReplyMessage.h
new file mode 100644
index 00000000..f134fadb
--- /dev/null
+++ b/src/DHTAnnouncePeerReplyMessage.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_DHT_ANNOUNCE_PEER_REPLY_MESSAGE_H_
+#define _D_DHT_ANNOUNCE_PEER_REPLY_MESSAGE_H_
+
+#include "DHTResponseMessage.h"
+
+class DHTAnnouncePeerReplyMessage:public DHTResponseMessage {
+public:
+ DHTAnnouncePeerReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID);
+
+ virtual ~DHTAnnouncePeerReplyMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getResponse();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+};
+
+#endif // _D_DHT_ANNOUNCE_PEER_REPLY_MESSAGE_H_
diff --git a/src/DHTAutoSaveCommand.cc b/src/DHTAutoSaveCommand.cc
new file mode 100644
index 00000000..b7809bf9
--- /dev/null
+++ b/src/DHTAutoSaveCommand.cc
@@ -0,0 +1,109 @@
+/* <!-- 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 "DHTAutoSaveCommand.h"
+#include "DHTRoutingTable.h"
+#include "DHTNode.h"
+#include "File.h"
+#include "DHTRoutingTableSerializer.h"
+#include "RecoverableException.h"
+#include "DownloadEngine.h"
+#include "Util.h"
+#include "DHTBucket.h"
+#include "RequestGroupMan.h"
+#include "prefs.h"
+#include "Option.h"
+#include <fstream>
+
+DHTAutoSaveCommand::DHTAutoSaveCommand(int32_t cuid, DownloadEngine* e, int32_t interval):
+ TimeBasedCommand(cuid, e, interval),
+ _localNode(0),
+ _routingTable(0) {}
+
+DHTAutoSaveCommand::~DHTAutoSaveCommand() {}
+
+void DHTAutoSaveCommand::preProcess()
+{
+ if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
+ save();
+ _exit = true;
+ }
+}
+
+void DHTAutoSaveCommand::process()
+{
+ save();
+}
+
+void DHTAutoSaveCommand::save()
+{
+ DHTNodes nodes;
+ DHTBuckets buckets = _routingTable->getBuckets();
+ for(DHTBuckets::const_iterator i = buckets.begin(); i != buckets.end(); ++i) {
+ const DHTBucketHandle& bucket = *i;
+ DHTNodes goodNodes = bucket->getGoodNodes();
+ nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end());
+ }
+
+ DHTRoutingTableSerializer serializer;
+ serializer.setLocalNode(_localNode);
+ serializer.setNodes(nodes);
+
+ string dhtFile = _e->option->get(PREF_DHT_FILE_PATH);
+ string tempFile = dhtFile+"__temp";
+ ofstream o(tempFile.c_str(), ios::out|ios::binary);
+ o.exceptions(ios::failbit);
+ try {
+ serializer.serialize(o);
+
+ if(!File(tempFile).renameTo(dhtFile)) {
+ logger->error("Cannot move file from %s to %s.",
+ tempFile.c_str(), dhtFile.c_str());
+ }
+ } catch(RecoverableException* e) {
+ logger->error("Exception caught while saving DHT routing table to %s",
+ e, tempFile.c_str());
+ delete e;
+ }
+}
+
+void DHTAutoSaveCommand::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
+
+void DHTAutoSaveCommand::setRoutingTable(const DHTRoutingTableHandle& routingTable)
+{
+ _routingTable = routingTable;
+}
diff --git a/src/DHTAutoSaveCommand.h b/src/DHTAutoSaveCommand.h
new file mode 100644
index 00000000..86f586bf
--- /dev/null
+++ b/src/DHTAutoSaveCommand.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_DHT_AUTO_SAVE_COMMAND_H_
+#define _D_DHT_AUTO_SAVE_COMMAND_H_
+
+#include "TimeBasedCommand.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTNodeDecl.h"
+
+class DHTAutoSaveCommand : public TimeBasedCommand
+{
+private:
+ DHTNodeHandle _localNode;
+
+ DHTRoutingTableHandle _routingTable;
+
+ void save();
+public:
+ DHTAutoSaveCommand(int32_t cuid, DownloadEngine* e, int32_t interval);
+
+ virtual ~DHTAutoSaveCommand();
+
+ virtual void preProcess();
+
+ virtual void process();
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+
+ void setRoutingTable(const DHTRoutingTableHandle& routingTable);
+};
+
+#endif // _D_DHT_AUTO_SAVE_COMMAND_H_
diff --git a/src/DHTBucket.cc b/src/DHTBucket.cc
new file mode 100644
index 00000000..4088dbc1
--- /dev/null
+++ b/src/DHTBucket.cc
@@ -0,0 +1,281 @@
+/* <!-- 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 "DHTBucket.h"
+#include "DHTUtil.h"
+#include "DHTNode.h"
+#include "LogFactory.h"
+#include "Util.h"
+#include "DHTConstants.h"
+#include "a2functional.h"
+
+DHTBucket::DHTBucket(uint32_t prefixLength,
+ const unsigned char* max, const unsigned char* min,
+ const DHTNodeHandle& localNode):
+ _prefixLength(prefixLength),
+ _localNode(localNode),
+ _logger(LogFactory::getInstance())
+{
+ memcpy(_max, max, DHT_ID_LENGTH);
+ memcpy(_min, min, DHT_ID_LENGTH);
+}
+
+DHTBucket::DHTBucket(const DHTNodeHandle& localNode):
+ _prefixLength(0),
+ _localNode(localNode),
+ _logger(LogFactory::getInstance())
+{
+ memset(_max, 0xff, DHT_ID_LENGTH);
+ memset(_min, 0, DHT_ID_LENGTH);
+}
+
+DHTBucket::~DHTBucket() {}
+
+void DHTBucket::getRandomNodeID(unsigned char* nodeID) const
+{
+ if(_prefixLength == 0) {
+ DHTUtil::generateRandomKey(nodeID);
+ } else {
+ size_t lastByteIndex = (_prefixLength-1)/8;
+ DHTUtil::generateRandomKey(nodeID);
+ memcpy(nodeID, _min, lastByteIndex+1);
+ }
+}
+
+bool DHTBucket::isInRange(const DHTNodeHandle& node) const
+{
+ return isInRange(node->getID());
+}
+
+bool DHTBucket::isInRange(const unsigned char* nodeID) const
+{
+ for(size_t i = 0; i < DHT_ID_LENGTH; ++i) {
+ if(nodeID[i] < _min[i]) {
+ return false;
+ } else if(_min[i] < nodeID[i]) {
+ break;
+ }
+ }
+ for(size_t i = 0; i < DHT_ID_LENGTH; ++i) {
+ if(_max[i] < nodeID[i]) {
+ return false;
+ } else if(nodeID[i] < _max[i]) {
+ break;
+ }
+ }
+ return true;
+}
+
+bool DHTBucket::addNode(const DHTNodeHandle& node)
+{
+ notifyUpdate();
+ DHTNodes::iterator itr = find(_nodes.begin(), _nodes.end(), node);
+ if(itr == _nodes.end()) {
+ if(_nodes.size() < K) {
+ _nodes.push_back(node);
+ return true;
+ } else {
+ if(_nodes.front()->isBad()) {
+ _nodes.erase(_nodes.begin());
+ _nodes.push_back(node);
+ return true;
+ } else {
+ return false;
+ }
+ /*
+ } else if(splitAllowed()) {
+ return false;
+ } else {
+ DHTNodes::iterator ci = find(_cachedNodes.begin(), _cachedNodes.end(), node);
+ if(ci == _cachedNodes.end()) {
+ _cachedNodes.push_back(node);
+ if(_cachedNodes.size() > CACHE_SIZE) {
+ _cachedNodes.erase(_cachedNodes.begin(), _cachedNodes().begin()+CACHE_SIZE-_cachedNodes.size());
+ }
+ } else {
+ _cachedNodes.erase(ci);
+ _cachedNodes.push_back(node);
+ }
+ return true;
+ }
+ */
+ }
+ } else {
+ _nodes.erase(itr);
+ _nodes.push_back(node);
+ return true;
+ }
+}
+
+void DHTBucket::dropNode(const DHTNodeHandle& node)
+{
+ return;
+ /*
+ DHTNodes::iterator itr = find(_nodes.begin(), _nodes.end(), node);
+ if(itr != _nodes.end()) {
+ _nodes.erase(itr);
+ if(_cachedNodes.size()) {
+ _nodes.push_back(_cachedNodes.back());
+ _cachedNodes.erase(_cachedNodes.begin()+_cachedNodes.size()-1);
+ }
+ }
+ */
+}
+
+void DHTBucket::moveToHead(const DHTNodeHandle& node)
+{
+ DHTNodes::iterator itr = find(_nodes.begin(), _nodes.end(), node);
+ if(itr != _nodes.end()) {
+ _nodes.erase(itr);
+ _nodes.push_front(node);
+ }
+}
+
+void DHTBucket::moveToTail(const DHTNodeHandle& node)
+{
+ DHTNodes::iterator itr = find(_nodes.begin(), _nodes.end(), node);
+ if(itr != _nodes.end()) {
+ _nodes.erase(itr);
+ _nodes.push_back(node);
+ }
+}
+
+bool DHTBucket::splitAllowed() const
+{
+ return _prefixLength < DHT_ID_LENGTH*8-1 && isInRange(_localNode);
+}
+
+DHTBucketHandle DHTBucket::split()
+{
+ assert(splitAllowed());
+ size_t newPrefixLength = _prefixLength+1;
+
+ unsigned char rMax[DHT_ID_LENGTH];
+ memcpy(rMax, _max, DHT_ID_LENGTH);
+ DHTUtil::flipBit(rMax, DHT_ID_LENGTH, _prefixLength);
+
+ DHTBucketHandle rBucket = new DHTBucket(newPrefixLength,
+ rMax, _min, _localNode);
+ DHTNodes tempNodes = _nodes;
+ for(DHTNodes::iterator i = tempNodes.begin(); i != tempNodes.end();) {
+ if(rBucket->isInRange(*i)) {
+ assert(rBucket->addNode(*i));
+ i = tempNodes.erase(i);
+ } else {
+ ++i;
+ }
+ }
+ DHTUtil::flipBit(_min, DHT_ID_LENGTH, _prefixLength);
+ _prefixLength = newPrefixLength;
+ _nodes = tempNodes;
+ // TODO create toString() and use it.
+ _logger->debug("New bucket. Range:%s-%s",
+ Util::toHex(rBucket->getMinID(), DHT_ID_LENGTH).c_str(),
+ Util::toHex(rBucket->getMaxID(), DHT_ID_LENGTH).c_str());
+ _logger->debug("Existing bucket. Range:%s-%s",
+ Util::toHex(getMinID(), DHT_ID_LENGTH).c_str(),
+ Util::toHex(getMaxID(), DHT_ID_LENGTH).c_str());
+
+ return rBucket;
+}
+
+size_t DHTBucket::countNode() const
+{
+ return _nodes.size();
+}
+
+const DHTNodes& DHTBucket::getNodes() const
+{
+ return _nodes;
+}
+
+DHTNodes DHTBucket::getGoodNodes() const
+{
+ DHTNodes goodNodes = _nodes;
+ goodNodes.erase(remove_if(goodNodes.begin(), goodNodes.end(),
+ mem_fun_sh(&DHTNode::isBad)), goodNodes.end());
+ return goodNodes;
+}
+
+DHTNodeHandle DHTBucket::getNode(const unsigned char* nodeID, const string& ipaddr, uint16_t port) const
+{
+ DHTNodeHandle node = new DHTNode(nodeID);
+ node->setIPAddress(ipaddr);
+ node->setPort(port);
+ DHTNodes::const_iterator itr = find(_nodes.begin(), _nodes.end(), node);
+ if(itr == _nodes.end()) {
+ return 0;
+ } else {
+ return *itr;
+ }
+}
+
+bool DHTBucket::operator==(const DHTBucket& bucket) const
+{
+ return memcmp(_max, bucket._max, DHT_ID_LENGTH) == 0 &&
+ memcmp(_min, bucket._min, DHT_ID_LENGTH) == 0;
+}
+
+bool DHTBucket::needsRefresh() const
+{
+ return _nodes.size() < K || _lastUpdated.elapsed(DHT_BUCKET_REFRESH_INTERVAL);
+}
+
+void DHTBucket::notifyUpdate()
+{
+ _lastUpdated.reset();
+}
+
+class FindQuestionableNode {
+public:
+ bool operator()(const DHTNodeHandle& node) const
+ {
+ return node->isQuestionable();
+ }
+};
+
+bool DHTBucket::containsQuestionableNode() const
+{
+ return find_if(_nodes.begin(), _nodes.end(), FindQuestionableNode()) != _nodes.end();
+}
+
+DHTNodeHandle DHTBucket::getLRUQuestionableNode() const
+{
+ DHTNodes::const_iterator i = find_if(_nodes.begin(), _nodes.end(), FindQuestionableNode());
+ if(i == _nodes.end()) {
+ return 0;
+ } else {
+ return *i;
+ }
+}
diff --git a/src/DHTBucket.h b/src/DHTBucket.h
new file mode 100644
index 00000000..42ca67b2
--- /dev/null
+++ b/src/DHTBucket.h
@@ -0,0 +1,132 @@
+/* <!-- 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_DHT_BUCKET_H_
+#define _D_DHT_BUCKET_H_
+
+#include "common.h"
+#include "DHTConstants.h"
+#include "DHTNodeDecl.h"
+#include "DHTBucketDecl.h"
+#include "TimeA2.h"
+
+class Logger;
+
+class DHTBucket {
+private:
+ size_t _prefixLength;
+
+ // this bucket contains nodes of distance between [_min, _max](inclusive).
+ unsigned char _min[DHT_ID_LENGTH];
+
+ unsigned char _max[DHT_ID_LENGTH];
+
+ DHTNodeHandle _localNode;
+
+ // sorted in ascending order
+ DHTNodes _nodes;
+
+ DHTNodes _cachedNodes;
+
+ Time _lastUpdated;
+
+ const Logger* _logger;
+public:
+ DHTBucket(const DHTNodeHandle& localNode);
+
+ DHTBucket(size_t prefixLength,
+ const unsigned char* max, const unsigned char* min,
+ const DHTNodeHandle& localNode);
+
+ ~DHTBucket();
+
+ static const size_t K = 8;
+
+ static const size_t CACHE_SIZE = 2;
+
+ void getRandomNodeID(unsigned char* nodeID) const;
+
+ DHTBucketHandle split();
+
+ bool isInRange(const DHTNodeHandle& node) const;
+
+ bool isInRange(const unsigned char* nodeID) const;
+
+ bool addNode(const DHTNodeHandle& node);
+
+ bool splitAllowed() const;
+
+ size_t getPrefixLength() const
+ {
+ return _prefixLength;
+ }
+
+ const unsigned char* getMaxID() const
+ {
+ return _max;
+ }
+
+ const unsigned char* getMinID() const
+ {
+ return _min;
+ }
+
+ size_t countNode() const;
+
+ const DHTNodes& getNodes() const;
+
+ DHTNodes getGoodNodes() const;
+
+ void dropNode(const DHTNodeHandle& node);
+
+ void moveToHead(const DHTNodeHandle& node);
+
+ void moveToTail(const DHTNodeHandle& node);
+
+ bool contains(const DHTNodeHandle& node) const;
+
+ DHTNodeHandle getNode(const unsigned char* nodeID, const string& ipaddr, uint16_t port) const;
+
+ bool operator==(const DHTBucket& bucket) const;
+
+ bool needsRefresh() const;
+
+ void notifyUpdate();
+
+ bool containsQuestionableNode() const;
+
+ DHTNodeHandle getLRUQuestionableNode() const;
+};
+
+#endif // _D_DHT_BUCKET_H_
diff --git a/src/DHTBucketDecl.h b/src/DHTBucketDecl.h
new file mode 100644
index 00000000..a3ab9751
--- /dev/null
+++ b/src/DHTBucketDecl.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_DHT_BUCKET_DECL_H_
+#define _D_DHT_BUCKET_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTBucket;
+typedef SharedHandle<DHTBucket> DHTBucketHandle;
+typedef std::deque<DHTBucketHandle> DHTBuckets;
+
+#endif // _D_DHT_BUCKET_DECL_H_
diff --git a/src/DHTBucketRefreshCommand.cc b/src/DHTBucketRefreshCommand.cc
new file mode 100644
index 00000000..0a31938d
--- /dev/null
+++ b/src/DHTBucketRefreshCommand.cc
@@ -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 --> */
+#include "DHTBucketRefreshCommand.h"
+#include "DHTRoutingTable.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
+#include "DownloadEngine.h"
+#include "SingletonHolder.h"
+#include "RequestGroupMan.h"
+
+DHTBucketRefreshCommand::DHTBucketRefreshCommand(int32_t cuid, DownloadEngine* e, time_t interval):
+ TimeBasedCommand(cuid, e, interval),
+ _routingTable(0),
+ _taskQueue(0),
+ _taskFactory(0) {}
+
+DHTBucketRefreshCommand::~DHTBucketRefreshCommand() {}
+
+void DHTBucketRefreshCommand::preProcess()
+{
+ _exit = _e->_requestGroupMan->downloadFinished() || _e->isHaltRequested();
+}
+
+void DHTBucketRefreshCommand::process()
+{
+ _taskQueue->addPeriodicTask1(_taskFactory->createBucketRefreshTask());
+}
+
+void DHTBucketRefreshCommand::setRoutingTable(const DHTRoutingTableHandle& routingTable)
+{
+ _routingTable = routingTable;
+}
+
+void DHTBucketRefreshCommand::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTBucketRefreshCommand::setTaskFactory(const DHTTaskFactoryHandle& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
diff --git a/src/DHTBucketRefreshCommand.h b/src/DHTBucketRefreshCommand.h
new file mode 100644
index 00000000..e000c5e0
--- /dev/null
+++ b/src/DHTBucketRefreshCommand.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_DHT_BUCKET_REFRESH_COMMAND_H_
+#define _D_DHT_BUCKET_REFRESH_COMMAND_H_
+
+#include "TimeBasedCommand.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+
+class DHTBucketRefreshCommand:public TimeBasedCommand {
+private:
+ DHTRoutingTableHandle _routingTable;
+
+ DHTTaskQueueHandle _taskQueue;
+
+ DHTTaskFactoryHandle _taskFactory;
+public:
+ DHTBucketRefreshCommand(int32_t cuid, DownloadEngine* e, time_t interval);
+
+ virtual ~DHTBucketRefreshCommand();
+
+ virtual void preProcess();
+
+ virtual void process();
+
+ void setRoutingTable(const DHTRoutingTableHandle& routingTable);
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+
+ void setTaskFactory(const DHTTaskFactoryHandle& taskFactory);
+};
+
+#endif // _D_DHT_BUCKET_REFRESH_COMMAND_H_
diff --git a/src/DHTBucketRefreshTask.cc b/src/DHTBucketRefreshTask.cc
new file mode 100644
index 00000000..5d1f6b89
--- /dev/null
+++ b/src/DHTBucketRefreshTask.cc
@@ -0,0 +1,69 @@
+/* <!-- 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 "DHTBucketRefreshTask.h"
+#include "DHTBucket.h"
+#include "DHTRoutingTable.h"
+#include "DHTNodeLookupTask.h"
+#include "DHTTaskQueue.h"
+#include "DHTNode.h"
+#include "DHTNodeLookupEntry.h"
+#include "Util.h"
+#include "Logger.h"
+
+DHTBucketRefreshTask::DHTBucketRefreshTask() {}
+
+DHTBucketRefreshTask::~DHTBucketRefreshTask() {}
+
+void DHTBucketRefreshTask::startup()
+{
+ DHTBuckets buckets = _routingTable->getBuckets();
+ for(DHTBuckets::iterator i = buckets.begin(); i != buckets.end(); ++i) {
+ if((*i)->needsRefresh()) {
+ (*i)->notifyUpdate();
+ unsigned char targetID[DHT_ID_LENGTH];
+ (*i)->getRandomNodeID(targetID);
+ SharedHandle<DHTNodeLookupTask> task = new DHTNodeLookupTask(targetID);
+ task->setRoutingTable(_routingTable);
+ task->setMessageDispatcher(_dispatcher);
+ task->setMessageFactory(_factory);
+ task->setTaskQueue(_taskQueue);
+ task->setLocalNode(_localNode);
+
+ _logger->info("Dispating bucket refresh. targetID=%s", Util::toHex(targetID, DHT_ID_LENGTH).c_str());
+ _taskQueue->addPeriodicTask1(task);
+ }
+ }
+ _finished = true;
+}
diff --git a/src/DHTBucketRefreshTask.h b/src/DHTBucketRefreshTask.h
new file mode 100644
index 00000000..38212b78
--- /dev/null
+++ b/src/DHTBucketRefreshTask.h
@@ -0,0 +1,49 @@
+/* <!-- 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_DHT_BUCKET_REFRESH_TASK_H_
+#define _D_DHT_BUCKET_REFRESH_TASK_H_
+
+#include "DHTAbstractTask.h"
+
+class DHTBucketRefreshTask:public DHTAbstractTask {
+public:
+ DHTBucketRefreshTask();
+
+ virtual ~DHTBucketRefreshTask();
+
+ virtual void startup();
+};
+
+#endif // _D_DHT_BUCKET_REFRESH_TASK_H_
diff --git a/src/DHTConnection.h b/src/DHTConnection.h
new file mode 100644
index 00000000..5bedca3c
--- /dev/null
+++ b/src/DHTConnection.h
@@ -0,0 +1,49 @@
+/* <!-- 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_DHT_CONNECTION_H_
+#define _D_DHT_CONNECTION_H_
+
+#include "common.h"
+
+class DHTConnection {
+public:
+ virtual ~DHTConnection() {}
+
+ virtual ssize_t receiveMessage(char* data, size_t len, string& host, uint16_t& port) = 0;
+
+ virtual void sendMessage(const char* data, size_t len, const string& host, uint16_t port) = 0;
+};
+
+#endif // _D_DHT_CONNECTION_H_
diff --git a/src/DHTConnectionDecl.h b/src/DHTConnectionDecl.h
new file mode 100644
index 00000000..8744ccf9
--- /dev/null
+++ b/src/DHTConnectionDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_CONNECTION_DECL_H_
+#define _D_DHT_CONNECTION_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTConnection;
+typedef SharedHandle<DHTConnection> DHTConnectionHandle;
+
+#endif // _D_DHT_CONNECTION_DECL_H_
diff --git a/src/DHTConnectionImpl.cc b/src/DHTConnectionImpl.cc
new file mode 100644
index 00000000..605b2d54
--- /dev/null
+++ b/src/DHTConnectionImpl.cc
@@ -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 --> */
+#include "DHTConnectionImpl.h"
+#include "LogFactory.h"
+#include "RecoverableException.h"
+#include "Util.h"
+DHTConnectionImpl::DHTConnectionImpl():_socket(new SocketCore(SOCK_DGRAM)),
+ _logger(LogFactory::getInstance()) {}
+
+DHTConnectionImpl::~DHTConnectionImpl() {}
+
+uint16_t DHTConnectionImpl::bind(IntSequence& ports)
+{
+ while(ports.hasNext()) {
+ uint16_t port = bind(ports.next());
+ if(port > 0) {
+ return port;
+ }
+ }
+ return 0;
+}
+
+uint16_t DHTConnectionImpl::bind(uint16_t port)
+{
+ try {
+ _socket->bind(port);
+ pair<string, int32_t> svaddr;
+ _socket->getAddrInfo(svaddr);
+ _logger->info("Bind socket for DHT. port=%u", port);
+ return svaddr.second;
+ } catch(RecoverableException* e) {
+ _logger->error("Failed to bind for DHT. port=%u", e, port);
+ delete e;
+ }
+ return 0;
+}
+
+ssize_t DHTConnectionImpl::receiveMessage(char* data, size_t len, string& host, uint16_t& port)
+{
+ if(_socket->isReadable(0)) {
+ pair<string, uint16_t> remoteHost;
+ ssize_t length = _socket->readDataFrom(data, len, remoteHost);
+ host = remoteHost.first;
+ port = remoteHost.second;
+ return length;
+ } else {
+ return -1;
+ }
+}
+
+void DHTConnectionImpl::sendMessage(const char* data, size_t len, const string& host, uint16_t port)
+{
+ _socket->writeData(data, len, host, port);
+}
+
+SocketHandle DHTConnectionImpl::getSocket() const
+{
+ return _socket;
+}
diff --git a/src/DHTConnectionImpl.h b/src/DHTConnectionImpl.h
new file mode 100644
index 00000000..011b232f
--- /dev/null
+++ b/src/DHTConnectionImpl.h
@@ -0,0 +1,65 @@
+/* <!-- 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_DHT_CONNECTION_IMPL_H_
+#define _D_DHT_CONNECTION_IMPL_H_
+
+#include "DHTConnection.h"
+#include "Socket.h"
+#include "IntSequence.h"
+
+class Logger;
+
+class DHTConnectionImpl:public DHTConnection {
+private:
+ SocketHandle _socket;
+
+ const Logger* _logger;
+public:
+ DHTConnectionImpl();
+
+ virtual ~DHTConnectionImpl();
+
+ uint16_t bind(IntSequence& ports);
+
+ uint16_t bind(uint16_t port);
+
+ virtual ssize_t receiveMessage(char* data, size_t len, string& host, uint16_t& port);
+
+ virtual void sendMessage(const char* data, size_t len, const string& host, uint16_t port);
+
+ SocketHandle getSocket() const;
+};
+
+#endif // _D_DHT_CONNECTION_IMPL_H_
diff --git a/src/DHTConstants.h b/src/DHTConstants.h
new file mode 100644
index 00000000..16f1aea4
--- /dev/null
+++ b/src/DHTConstants.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_DHT_CONSTANTS_H_
+#define _D_DHT_CONSTANTS_H_
+
+#define DHT_ID_LENGTH 20
+
+#define DHT_TRANSACTION_ID_LENGTH 2
+
+#define DHT_TOKEN_LENGTH 4
+
+#define DHT_MESSAGE_TIMEOUT 15
+
+#define DHT_NODE_CONTACT_INTERVAL (15*60)
+
+#define DHT_BUCKET_REFRESH_INTERVAL (15*60)
+
+#define DHT_BUCKET_REFRESH_CHECK_INTERVAL (5*60)
+
+#define DHT_PEER_ANNOUNCE_PURGE_INTERVAL (30*60)
+
+#define DHT_PEER_ANNOUNCE_INTERVAL (15*60)
+
+#define DHT_PEER_ANNOUNCE_CHECK_INTERVAL (5*60)
+
+#define DHT_TOKEN_UPDATE_INTERVAL (10*60)
+
+#endif // _D_DHT_CONSTANTS_H_
diff --git a/src/DHTEntryPointNameResolveCommand.cc b/src/DHTEntryPointNameResolveCommand.cc
new file mode 100644
index 00000000..b0721517
--- /dev/null
+++ b/src/DHTEntryPointNameResolveCommand.cc
@@ -0,0 +1,161 @@
+/* <!-- 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 "DHTEntryPointNameResolveCommand.h"
+#include "DownloadEngine.h"
+#include "NameResolver.h"
+#include "DNSCache.h"
+#include "DlAbortEx.h"
+#include "prefs.h"
+#include "message.h"
+#include "Util.h"
+#include "Option.h"
+#include "DHTNode.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
+#include "RequestGroupMan.h"
+
+DHTEntryPointNameResolveCommand::DHTEntryPointNameResolveCommand(int32_t cuid, DownloadEngine* e):
+ Command(cuid),
+ _e(e),
+ _resolver(new NameResolver()),
+ _taskQueue(0),
+ _taskFactory(0),
+ _localNode(0)
+{}
+
+DHTEntryPointNameResolveCommand::~DHTEntryPointNameResolveCommand()
+{
+#ifdef ENABLE_ASYNC_DNS
+ disableNameResolverCheck(_resolver);
+#endif // ENABLE_ASYNC_DNS
+}
+
+bool DHTEntryPointNameResolveCommand::execute()
+{
+ if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
+ return true;
+ }
+
+ try {
+ string hostname = _e->option->get(PREF_DHT_ENTRY_POINT_HOST);
+ if(!Util::isNumbersAndDotsNotation(hostname)) {
+ if(resolveHostname(hostname, _resolver)) {
+ hostname = _resolver->getAddrString();
+ } else {
+ _e->commands.push_back(this);
+ return false;
+ }
+ }
+
+ DHTNodeHandle entryNode = new DHTNode();
+ entryNode->setIPAddress(hostname);
+ entryNode->setPort(_e->option->getAsInt(PREF_DHT_ENTRY_POINT_PORT));
+
+ _taskQueue->addPeriodicTask1(_taskFactory->createPingTask(entryNode, 10));
+ _taskQueue->addPeriodicTask1(_taskFactory->createNodeLookupTask(_localNode->getID()));
+ _taskQueue->addPeriodicTask1(_taskFactory->createBucketRefreshTask());
+ } catch(RecoverableException* e) {
+ logger->error(EX_EXCEPTION_CAUGHT, e);
+ delete e;
+ }
+ return true;
+}
+
+bool DHTEntryPointNameResolveCommand::resolveHostname(const string& hostname,
+ const NameResolverHandle& resolver)
+{
+ string ipaddr = DNSCacheSingletonHolder::instance()->find(hostname);
+ if(ipaddr.empty()) {
+#ifdef ENABLE_ASYNC_DNS
+ switch(resolver->getStatus()) {
+ case NameResolver::STATUS_READY:
+ logger->info(MSG_RESOLVING_HOSTNAME, cuid, hostname.c_str());
+ resolver->resolve(hostname);
+ setNameResolverCheck(resolver);
+ return false;
+ case NameResolver::STATUS_SUCCESS:
+ logger->info(MSG_NAME_RESOLUTION_COMPLETE, cuid,
+ hostname.c_str(), resolver->getAddrString().c_str());
+ DNSCacheSingletonHolder::instance()->put(hostname, resolver->getAddrString());
+ return true;
+ break;
+ case NameResolver::STATUS_ERROR:
+ throw new DlAbortEx(MSG_NAME_RESOLUTION_FAILED, cuid,
+ hostname.c_str(),
+ resolver->getError().c_str());
+ default:
+ return false;
+ }
+#else
+ logger->info(MSG_RESOLVING_HOSTNAME, cuid, hostname.c_str());
+ resolver->resolve(hostname);
+ logger->info(MSG_NAME_RESOLUTION_COMPLETE, cuid,
+ hostname.c_str(), resolver->getAddrString().c_str());
+ DNSCacheSingletonHolder::instance()->put(hostname, resolver->getAddrString());
+ return true;
+#endif // ENABLE_ASYNC_DNS
+ } else {
+ logger->info(MSG_DNS_CACHE_HIT, cuid,
+ hostname.c_str(), ipaddr.c_str());
+ resolver->setAddr(ipaddr);
+ return true;
+ }
+}
+
+#ifdef ENABLE_ASYNC_DNS
+void DHTEntryPointNameResolveCommand::setNameResolverCheck(const NameResolverHandle& resolver) {
+ _e->addNameResolverCheck(resolver, this);
+}
+
+void DHTEntryPointNameResolveCommand::disableNameResolverCheck(const NameResolverHandle& resolver) {
+ _e->deleteNameResolverCheck(resolver, this);
+}
+#endif // ENABLE_ASYNC_DNS
+
+void DHTEntryPointNameResolveCommand::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTEntryPointNameResolveCommand::setTaskFactory(const DHTTaskFactoryHandle& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
+
+void DHTEntryPointNameResolveCommand::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
diff --git a/src/DHTEntryPointNameResolveCommand.h b/src/DHTEntryPointNameResolveCommand.h
new file mode 100644
index 00000000..2bf3a9db
--- /dev/null
+++ b/src/DHTEntryPointNameResolveCommand.h
@@ -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 --> */
+#ifndef _D_DHT_ENTRY_POINT_NAME_RESOVE_COMMAND_H_
+#define _D_DHT_ENTRY_POINT_NAME_RESOVE_COMMAND_H_
+
+#include "Command.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+#include "DHTNodeDecl.h"
+
+class DownloadEngine;
+class NameResolver;
+typedef SharedHandle<NameResolver> NameResolverHandle;
+
+class DHTEntryPointNameResolveCommand:public Command {
+protected:
+ DownloadEngine* _e;
+private:
+ NameResolverHandle _resolver;
+
+ DHTTaskQueueHandle _taskQueue;
+
+ DHTTaskFactoryHandle _taskFactory;
+
+ DHTNodeHandle _localNode;
+
+ bool resolveHostname(const string& hostname,
+ const NameResolverHandle& resolver);
+
+ void setNameResolverCheck(const NameResolverHandle& resolver);
+
+ void disableNameResolverCheck(const NameResolverHandle& resolver);
+
+public:
+ DHTEntryPointNameResolveCommand(int32_t cuid, DownloadEngine* e);
+
+ virtual ~DHTEntryPointNameResolveCommand();
+
+ virtual bool execute();
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+
+ void setTaskFactory(const DHTTaskFactoryHandle& taskFactory);
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+};
+
+#endif // _D_DHT_ENTRY_POINT_NAME_RESOVE_COMMAND_H_
diff --git a/src/DHTFindNodeMessage.cc b/src/DHTFindNodeMessage.cc
new file mode 100644
index 00000000..72aaa398
--- /dev/null
+++ b/src/DHTFindNodeMessage.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 "DHTFindNodeMessage.h"
+#include "DHTNode.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+
+DHTFindNodeMessage::DHTFindNodeMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* targetNodeID,
+ const string& transactionID):
+ DHTQueryMessage(localNode, remoteNode, transactionID)
+{
+ memcpy(_targetNodeID, targetNodeID, DHT_ID_LENGTH);
+}
+
+DHTFindNodeMessage::~DHTFindNodeMessage() {}
+
+void DHTFindNodeMessage::doReceivedAction()
+{
+ DHTNodes nodes = _routingTable->getClosestKNodes(_targetNodeID);
+ DHTMessageHandle reply =
+ _factory->createFindNodeReplyMessage(_remoteNode, nodes, _transactionID);
+ _dispatcher->addMessageToQueue(reply);
+}
+
+Dictionary* DHTFindNodeMessage::getArgument()
+{
+ Dictionary* a = new Dictionary();
+ a->put("id", new Data(reinterpret_cast<const char*>(_localNode->getID()),
+ DHT_ID_LENGTH));
+ a->put("target", new Data(reinterpret_cast<const char*>(_targetNodeID),
+ DHT_ID_LENGTH));
+ return a;
+}
+
+string DHTFindNodeMessage::getMessageType() const
+{
+ return "find_node";
+}
+
+void DHTFindNodeMessage::validate() const {}
diff --git a/src/DHTFindNodeMessage.h b/src/DHTFindNodeMessage.h
new file mode 100644
index 00000000..88bdbece
--- /dev/null
+++ b/src/DHTFindNodeMessage.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_DHT_FIND_NODE_MESSAGE_H_
+#define _D_DHT_FIND_NODE_MESSAGE_H_
+
+#include "DHTQueryMessage.h"
+#include "DHTConstants.h"
+
+class DHTFindNodeMessage:public DHTQueryMessage {
+private:
+ unsigned char _targetNodeID[DHT_ID_LENGTH];
+public:
+ DHTFindNodeMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* targetNodeID,
+ const string& transactionID = "");
+
+ virtual ~DHTFindNodeMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getArgument();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const unsigned char* getTargetNodeID() const
+ {
+ return _targetNodeID;
+ }
+};
+
+#endif // _D_DHT_FIND_NODE_MESSAGE_H_
diff --git a/src/DHTFindNodeReplyMessage.cc b/src/DHTFindNodeReplyMessage.cc
new file mode 100644
index 00000000..b5cfdcad
--- /dev/null
+++ b/src/DHTFindNodeReplyMessage.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 "DHTFindNodeReplyMessage.h"
+#include "DHTNode.h"
+#include "DHTBucket.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+#include "PeerMessageUtil.h"
+
+DHTFindNodeReplyMessage::DHTFindNodeReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTResponseMessage(localNode, remoteNode, transactionID) {}
+
+DHTFindNodeReplyMessage::~DHTFindNodeReplyMessage() {}
+
+void DHTFindNodeReplyMessage::doReceivedAction()
+{
+ for(DHTNodes::iterator i = _closestKNodes.begin(); i != _closestKNodes.end(); ++i) {
+ if(memcmp((*i)->getID(), _localNode->getID(), DHT_ID_LENGTH) != 0) {
+ _routingTable->addNode(*i);
+ }
+ }
+}
+
+Dictionary* DHTFindNodeReplyMessage::getResponse()
+{
+ Dictionary* a = new Dictionary();
+ a->put("id", new Data(reinterpret_cast<const char*>(_localNode->getID()),
+ DHT_ID_LENGTH));
+ size_t offset = 0;
+ char buffer[DHTBucket::K*26];
+ for(DHTNodes::const_iterator i = _closestKNodes.begin(); i != _closestKNodes.end(); ++i) {
+ DHTNodeHandle node = *i;
+ memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
+ if(PeerMessageUtil::createcompact(buffer+20+offset, node->getIPAddress(), node->getPort())) {
+ offset += 26;
+ }
+ }
+ a->put("nodes", new Data(buffer, offset));
+ return a;
+}
+
+string DHTFindNodeReplyMessage::getMessageType() const
+{
+ return "find_node";
+}
+
+void DHTFindNodeReplyMessage::validate() const {}
+
+const DHTNodes& DHTFindNodeReplyMessage::getClosestKNodes() const
+{
+ return _closestKNodes;
+}
+
+void DHTFindNodeReplyMessage::setClosestKNodes(const DHTNodes& closestKNodes)
+{
+ _closestKNodes = closestKNodes;
+}
diff --git a/src/DHTFindNodeReplyMessage.h b/src/DHTFindNodeReplyMessage.h
new file mode 100644
index 00000000..80ab387c
--- /dev/null
+++ b/src/DHTFindNodeReplyMessage.h
@@ -0,0 +1,63 @@
+/* <!-- 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_DHT_FIND_NODE_REPLY_MESSAGE_H_
+#define _D_DHT_FIND_NODE_REPLY_MESSAGE_H_
+
+#include "DHTResponseMessage.h"
+
+class DHTFindNodeReplyMessage:public DHTResponseMessage {
+private:
+ DHTNodes _closestKNodes;
+public:
+ DHTFindNodeReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID);
+
+ virtual ~DHTFindNodeReplyMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getResponse();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const DHTNodes& getClosestKNodes() const;
+
+ void setClosestKNodes(const DHTNodes& closestKNodes);
+};
+
+#endif // _D_DHT_FIND_NODE_REPLY_MESSAGE_H_
diff --git a/src/DHTGetPeersCommand.cc b/src/DHTGetPeersCommand.cc
new file mode 100644
index 00000000..7788577e
--- /dev/null
+++ b/src/DHTGetPeersCommand.cc
@@ -0,0 +1,96 @@
+/* <!-- 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 "DHTGetPeersCommand.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
+#include "DownloadEngine.h"
+#include "RequestGroup.h"
+#include "DHTPeerLookupTask.h"
+#include "DHTNode.h"
+#include "DHTNodeLookupEntry.h"
+
+DHTGetPeersCommand::DHTGetPeersCommand(int32_t cuid,
+ RequestGroup* requestGroup,
+ DownloadEngine* e,
+ const BtContextHandle& ctx):
+ Command(cuid),
+ BtContextAwareCommand(ctx),
+ RequestGroupAware(requestGroup),
+ _e(e),
+ _taskQueue(0),
+ _taskFactory(0),
+ _task(0),
+ _numRetry(0),
+ _lastGetPeerTime(0)
+{}
+
+DHTGetPeersCommand::~DHTGetPeersCommand() {}
+
+bool DHTGetPeersCommand::execute()
+{
+ if(btRuntime->isHalt()) {
+ return true;
+ }
+ if(_task.isNull() &&
+ (_numRetry > 0 && _lastGetPeerTime.elapsed(RETRY_INTERVAL) ||
+ _lastGetPeerTime.elapsed(GET_PEER_INTERVAL))) {
+ logger->debug("Issuing PeerLookup for infoHash=%s",
+ btContext->getInfoHashAsString().c_str());
+ _task = _taskFactory->createPeerLookupTask(btContext);
+ _taskQueue->addPeriodicTask2(_task);
+ } else if(!_task.isNull() && _task->finished()) {
+ _lastGetPeerTime.reset();
+ if(_numRetry < MAX_RETRIES && btRuntime->lessThanEqMinPeer()) {
+ ++_numRetry;
+ } else {
+ _numRetry = 0;
+ }
+ _task = 0;
+ }
+
+ _e->commands.push_back(this);
+ return false;
+}
+
+void DHTGetPeersCommand::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTGetPeersCommand::setTaskFactory(const DHTTaskFactoryHandle& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
diff --git a/src/DHTGetPeersCommand.h b/src/DHTGetPeersCommand.h
new file mode 100644
index 00000000..9661bc95
--- /dev/null
+++ b/src/DHTGetPeersCommand.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_DHT_GET_PEERS_COMMAND_H_
+#define _D_DHT_GET_PEERS_COMMAND_H_
+
+#include "Command.h"
+#include "BtContextAwareCommand.h"
+#include "RequestGroupAware.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+#include "TimeA2.h"
+
+class DHTPeerLookupTask;
+class DownloadEngine;
+class RequestGroup;
+typedef SharedHandle<RequestGroup> RequestGroupHandle;
+
+class DHTGetPeersCommand:public Command,
+ public BtContextAwareCommand,
+ public RequestGroupAware
+{
+private:
+ static const time_t GET_PEER_INTERVAL = (15*60);
+
+ static const time_t RETRY_INTERVAL = 60;
+
+ static const size_t MAX_RETRIES = 10;
+
+ DownloadEngine* _e;
+
+ DHTTaskQueueHandle _taskQueue;
+
+ DHTTaskFactoryHandle _taskFactory;
+
+ SharedHandle<DHTPeerLookupTask> _task;
+
+ size_t _numRetry;
+
+ Time _lastGetPeerTime;
+public:
+ DHTGetPeersCommand(int32_t cuid, RequestGroup* requestGroup,
+ DownloadEngine* e, const BtContextHandle& ctx);
+
+ virtual ~DHTGetPeersCommand();
+
+ virtual bool execute();
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+
+ void setTaskFactory(const DHTTaskFactoryHandle& taskFactory);
+};
+
+#endif // _D_DHT_GET_PEERS_COMMAND_H_
diff --git a/src/DHTGetPeersMessage.cc b/src/DHTGetPeersMessage.cc
new file mode 100644
index 00000000..cb0a5ee4
--- /dev/null
+++ b/src/DHTGetPeersMessage.cc
@@ -0,0 +1,103 @@
+/* <!-- 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 "DHTGetPeersMessage.h"
+#include "DHTNode.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTUtil.h"
+#include "Peer.h"
+#include "DHTTokenTracker.h"
+
+DHTGetPeersMessage::DHTGetPeersMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ const string& transactionID):
+ DHTQueryMessage(localNode, remoteNode, transactionID)
+{
+ memcpy(_infoHash, infoHash, DHT_ID_LENGTH);
+}
+
+DHTGetPeersMessage::~DHTGetPeersMessage() {}
+
+void DHTGetPeersMessage::doReceivedAction()
+{
+ string token = _tokenTracker->generateToken(_infoHash,
+ _remoteNode->getIPAddress(),
+ _remoteNode->getPort());
+ // Check to see localhost has the contents which has same infohash
+ Peers peers = _peerAnnounceStorage->getPeers(_infoHash);
+ DHTMessageHandle reply = 0;
+ if(peers.empty()) {
+ DHTNodes nodes = _routingTable->getClosestKNodes(_infoHash);
+ reply =
+ _factory->createGetPeersReplyMessage(_remoteNode, nodes, token,
+ _transactionID);
+ } else {
+ reply =
+ _factory->createGetPeersReplyMessage(_remoteNode, peers, token,
+ _transactionID);
+ }
+ _dispatcher->addMessageToQueue(reply);
+}
+
+Dictionary* DHTGetPeersMessage::getArgument()
+{
+ Dictionary* a = new Dictionary();
+ a->put("id", new Data(_localNode->getID(), DHT_ID_LENGTH));
+ a->put("info_hash", new Data(_infoHash, DHT_ID_LENGTH));
+ return a;
+}
+
+string DHTGetPeersMessage::getMessageType() const
+{
+ return "get_peers";
+}
+
+void DHTGetPeersMessage::validate() const {}
+
+void DHTGetPeersMessage::setPeerAnnounceStorage(const WeakHandle<DHTPeerAnnounceStorage>& storage)
+{
+ _peerAnnounceStorage = storage;
+}
+
+void DHTGetPeersMessage::setTokenTracker(const WeakHandle<DHTTokenTracker>& tokenTracker)
+{
+ _tokenTracker = tokenTracker;
+}
diff --git a/src/DHTGetPeersMessage.h b/src/DHTGetPeersMessage.h
new file mode 100644
index 00000000..926a0430
--- /dev/null
+++ b/src/DHTGetPeersMessage.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_DHT_GET_PEERS_MESSAGE_H_
+#define _D_DHT_GET_PEERS_MESSAGE_H_
+
+#include "DHTQueryMessage.h"
+#include "DHTConstants.h"
+#include "DHTPeerAnnounceStorageDecl.h"
+#include "DHTTokenTrackerDecl.h"
+
+class DHTGetPeersMessage:public DHTQueryMessage {
+private:
+ unsigned char _infoHash[DHT_ID_LENGTH];
+
+ WeakHandle<DHTPeerAnnounceStorage> _peerAnnounceStorage;
+
+ WeakHandle<DHTTokenTracker> _tokenTracker;
+public:
+ DHTGetPeersMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ const string& transactionID = "");
+
+ virtual ~DHTGetPeersMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getArgument();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const unsigned char* getInfoHash() const
+ {
+ return _infoHash;
+ }
+
+ void setPeerAnnounceStorage(const WeakHandle<DHTPeerAnnounceStorage>& storage);
+
+
+ void setTokenTracker(const WeakHandle<DHTTokenTracker>& tokenTracker);
+};
+
+#endif // _D_DHT_GET_PEERS_MESSAGE_H_
diff --git a/src/DHTGetPeersReplyMessage.cc b/src/DHTGetPeersReplyMessage.cc
new file mode 100644
index 00000000..7bdf421e
--- /dev/null
+++ b/src/DHTGetPeersReplyMessage.cc
@@ -0,0 +1,119 @@
+/* <!-- 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 "DHTGetPeersReplyMessage.h"
+#include "DHTNode.h"
+#include "DHTBucket.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "List.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+#include "PeerMessageUtil.h"
+#include "Peer.h"
+#include "DHTUtil.h"
+
+DHTGetPeersReplyMessage::DHTGetPeersReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& token,
+ const string& transactionID):
+ DHTResponseMessage(localNode, remoteNode, transactionID),
+ _token(token) {}
+
+DHTGetPeersReplyMessage::~DHTGetPeersReplyMessage() {}
+
+void DHTGetPeersReplyMessage::doReceivedAction()
+{
+ // Returned peers and nodes are handled in DHTPeerLookupTask.
+}
+
+Dictionary* DHTGetPeersReplyMessage::getResponse()
+{
+ Dictionary* r = new Dictionary();
+ r->put("id", new Data(reinterpret_cast<const char*>(_localNode->getID()),
+ DHT_ID_LENGTH));
+ r->put("token", new Data(_token));
+ if(_values.size()) {
+ List* valuesList = new List();
+ r->put("values", valuesList);
+ for(Peers::const_iterator i = _values.begin(); i != _values.end(); ++i) {
+ PeerHandle peer = *i;
+ char buffer[6];
+ if(PeerMessageUtil::createcompact(buffer, peer->ipaddr, peer->port)) {
+ valuesList->add(new Data(buffer, sizeof(buffer)));
+ }
+ }
+ } else {
+ size_t offset = 0;
+ char buffer[DHTBucket::K*26];
+ for(DHTNodes::const_iterator i = _closestKNodes.begin(); i != _closestKNodes.end(); ++i) {
+ DHTNodeHandle node = *i;
+ memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
+ if(PeerMessageUtil::createcompact(buffer+20+offset, node->getIPAddress(), node->getPort())) {
+ offset += 26;
+ }
+ }
+ r->put("nodes", new Data(buffer, offset));
+ }
+ return r;
+}
+
+string DHTGetPeersReplyMessage::getMessageType() const
+{
+ return "get_peers";
+}
+
+void DHTGetPeersReplyMessage::validate() const {}
+
+const DHTNodes& DHTGetPeersReplyMessage::getClosestKNodes() const
+{
+ return _closestKNodes;
+}
+
+void DHTGetPeersReplyMessage::setClosestKNodes(const DHTNodes& closestKNodes)
+{
+ _closestKNodes = closestKNodes;
+}
+
+const Peers& DHTGetPeersReplyMessage::getValues() const
+{
+ return _values;
+}
+
+void DHTGetPeersReplyMessage::setValues(const Peers& peers)
+{
+ _values = peers;
+}
diff --git a/src/DHTGetPeersReplyMessage.h b/src/DHTGetPeersReplyMessage.h
new file mode 100644
index 00000000..0d9a88ac
--- /dev/null
+++ b/src/DHTGetPeersReplyMessage.h
@@ -0,0 +1,79 @@
+/* <!-- 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_DHT_GET_PEERS_REPLY_MESSAGE_H_
+#define _D_DHT_GET_PEERS_REPLY_MESSAGE_H_
+
+#include "DHTResponseMessage.h"
+#include "DHTConstants.h"
+#include "PeerDecl.h"
+
+class DHTGetPeersReplyMessage:public DHTResponseMessage {
+private:
+ string _token;
+
+ DHTNodes _closestKNodes;
+
+ Peers _values;
+public:
+ DHTGetPeersReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& token,
+ const string& transactionID);
+
+ virtual ~DHTGetPeersReplyMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getResponse();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const DHTNodes& getClosestKNodes() const;
+
+ const Peers& getValues() const;
+
+ void setClosestKNodes(const DHTNodes& closestKNodes);
+
+ void setValues(const Peers& peers);
+
+ const string& getToken() const
+ {
+ return _token;
+ }
+};
+
+#endif // _D_DHT_GET_PEERS_REPLY_MESSAGE_H_
diff --git a/src/DHTIDCloser.h b/src/DHTIDCloser.h
new file mode 100644
index 00000000..978f4e01
--- /dev/null
+++ b/src/DHTIDCloser.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_DHT_ID_CLOSER_H_
+#define _D_DHT_ID_CLOSER_H_
+
+#include "DHTNodeLookupEntryDecl.h"
+#include "DHTConstants.h"
+#include "XORCloser.h"
+
+class DHTIDCloser {
+private:
+ const unsigned char* _targetID;
+
+ XORCloser _closer;
+public:
+ DHTIDCloser(const unsigned char* targetID):_closer(targetID, DHT_ID_LENGTH) {}
+
+ bool operator()(const DHTNodeLookupEntryHandle& m1,
+ const DHTNodeLookupEntryHandle& m2) const
+ {
+ return _closer(m1->_node->getID(), m2->_node->getID());
+ }
+};
+
+#endif // _D_DHT_ID_CLOSER_H_
diff --git a/src/DHTInteractionCommand.cc b/src/DHTInteractionCommand.cc
new file mode 100644
index 00000000..0b4b0323
--- /dev/null
+++ b/src/DHTInteractionCommand.cc
@@ -0,0 +1,111 @@
+/* <!-- 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 "DHTInteractionCommand.h"
+#include "DownloadEngine.h"
+#include "RecoverableException.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageReceiver.h"
+#include "DHTTaskQueue.h"
+#include "DHTMessage.h"
+#include "Socket.h"
+#include "message.h"
+#include "RequestGroupMan.h"
+
+DHTInteractionCommand::DHTInteractionCommand(int32_t cuid, DownloadEngine* e):
+ Command(cuid),
+ _e(e),
+ _dispatcher(0),
+ _receiver(0),
+ _taskQueue(0),
+ _readCheckSocket(0)
+{}
+
+DHTInteractionCommand::~DHTInteractionCommand()
+{
+ disableReadCheckSocket(_readCheckSocket);
+}
+
+void DHTInteractionCommand::setReadCheckSocket(const SocketHandle& socket)
+{
+ _readCheckSocket = socket;
+ _e->addSocketForReadCheck(socket, this);
+}
+
+void DHTInteractionCommand::disableReadCheckSocket(const SocketHandle& socket)
+{
+ _e->deleteSocketForReadCheck(socket, this);
+}
+
+bool DHTInteractionCommand::execute()
+{
+ if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
+ return true;
+ }
+
+ _taskQueue->executeTask();
+
+ for(size_t i = 0; i < 20 && _readCheckSocket->isReadable(0); ++i) {
+ try {
+ _receiver->receiveMessage();
+ } catch(RecoverableException* e) {
+ logger->error(EX_EXCEPTION_CAUGHT, e);
+ delete e;
+ }
+ }
+ try {
+ _receiver->handleTimeout();
+ _dispatcher->sendMessages();
+ } catch(RecoverableException* e) {
+ logger->error(EX_EXCEPTION_CAUGHT, e);
+ delete e;
+ }
+ _e->commands.push_back(this);
+ return false;
+}
+
+void DHTInteractionCommand::setMessageDispatcher(const DHTMessageDispatcherHandle& dispatcher)
+{
+ _dispatcher = dispatcher;
+}
+
+void DHTInteractionCommand::setMessageReceiver(const DHTMessageReceiverHandle& receiver)
+{
+ _receiver = receiver;
+}
+
+void DHTInteractionCommand::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
diff --git a/src/DHTInteractionCommand.h b/src/DHTInteractionCommand.h
new file mode 100644
index 00000000..40e6d0fb
--- /dev/null
+++ b/src/DHTInteractionCommand.h
@@ -0,0 +1,74 @@
+/* <!-- 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_DHT_INTERACTION_COMMAND_H_
+#define _D_DHT_INTERACTION_COMMAND_H_
+
+#include "Command.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageReceiverDecl.h"
+#include "DHTTaskQueueDecl.h"
+
+class DownloadEngine;
+class SocketCore;
+typedef SharedHandle<SocketCore> SocketHandle;
+
+class DHTInteractionCommand:public Command {
+protected:
+ DownloadEngine* _e;
+private:
+ DHTMessageDispatcherHandle _dispatcher;
+ DHTMessageReceiverHandle _receiver;
+ DHTTaskQueueHandle _taskQueue;
+ SocketHandle _readCheckSocket;
+
+public:
+ DHTInteractionCommand(int32_t cuid, DownloadEngine* e);
+
+ virtual ~DHTInteractionCommand();
+
+ virtual bool execute();
+
+ void setReadCheckSocket(const SocketHandle& socket);
+
+ void disableReadCheckSocket(const SocketHandle& socket);
+
+ void setMessageDispatcher(const DHTMessageDispatcherHandle& dispatcher);
+
+ void setMessageReceiver(const DHTMessageReceiverHandle& receiver);
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+};
+
+#endif // _D_DHT_INTERACTION_COMMAND_H_
diff --git a/src/DHTMessage.cc b/src/DHTMessage.cc
new file mode 100644
index 00000000..ac32e691
--- /dev/null
+++ b/src/DHTMessage.cc
@@ -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 --> */
+#include "DHTMessage.h"
+#include "DHTNode.h"
+#include "DHTUtil.h"
+
+DHTMessage::DHTMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ _localNode(localNode), _remoteNode(remoteNode), _transactionID(transactionID)
+{
+ if(transactionID.empty()) {
+ generateTransactionID();
+ }
+}
+
+DHTMessage::~DHTMessage() {}
+
+void DHTMessage::generateTransactionID()
+{
+ char tid[DHT_TRANSACTION_ID_LENGTH];
+ DHTUtil::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
+ _transactionID = string(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
+}
+
+DHTNodeHandle DHTMessage::getLocalNode() const
+{
+ return _localNode;
+}
+
+DHTNodeHandle DHTMessage::getRemoteNode() const
+{
+ return _remoteNode;
+}
+
diff --git a/src/DHTMessage.h b/src/DHTMessage.h
new file mode 100644
index 00000000..e2417624
--- /dev/null
+++ b/src/DHTMessage.h
@@ -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 --> */
+#ifndef _D_DHT_MESSAGE_H_
+#define _D_DHT_MESSAGE_H_
+
+#include "common.h"
+#include "DHTMessageDecl.h"
+#include "DHTNodeDecl.h"
+
+class DHTMessage {
+protected:
+ DHTNodeHandle _localNode;
+
+ DHTNodeHandle _remoteNode;
+
+ string _transactionID;
+
+ void generateTransactionID();
+public:
+ DHTMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID = "");
+
+ virtual ~DHTMessage();
+
+ const string& getTransactionID() const
+ {
+ return _transactionID;
+ }
+
+ DHTNodeHandle getLocalNode() const;
+
+ DHTNodeHandle getRemoteNode() const;
+
+ virtual void doReceivedAction() = 0;
+
+ virtual void send() = 0;
+
+ virtual bool isReply() const = 0;
+
+ virtual void validate() const = 0;
+
+ virtual string getMessageType() const = 0;
+
+ virtual string toString() const = 0;
+};
+
+#endif // _D_DHT_MESSAGE_H_
diff --git a/src/DHTMessageCallback.h b/src/DHTMessageCallback.h
new file mode 100644
index 00000000..56fbfd01
--- /dev/null
+++ b/src/DHTMessageCallback.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_DHT_MESSAGE_CALLBACK_H_
+#define _D_DHT_MESSAGE_CALLBACK_H_
+
+#include "common.h"
+#include "DHTMessageCallbackDecl.h"
+#include "DHTMessageDecl.h"
+#include "DHTNodeDecl.h"
+
+class DHTMessageCallback {
+public:
+ virtual ~DHTMessageCallback() {}
+
+ virtual void onReceived(const DHTMessageHandle& message) = 0;
+
+ virtual void onTimeout(const DHTNodeHandle& remoteNode) = 0;
+};
+
+#endif // _D_DHT_MESSAGE_CALLBACK_H_
diff --git a/src/DHTMessageCallbackDecl.h b/src/DHTMessageCallbackDecl.h
new file mode 100644
index 00000000..f0fadcee
--- /dev/null
+++ b/src/DHTMessageCallbackDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_MESSAGE_CALLBACK_DECL_H_
+#define _D_DHT_MESSAGE_CALLBACK_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTMessageCallback;
+typedef SharedHandle<DHTMessageCallback> DHTMessageCallbackHandle;
+
+#endif // _D_DHT_MESSAGE_CALLBACK_DECL_H_
diff --git a/src/DHTMessageCallbackImpl.cc b/src/DHTMessageCallbackImpl.cc
new file mode 100644
index 00000000..a6e96545
--- /dev/null
+++ b/src/DHTMessageCallbackImpl.cc
@@ -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 --> */
+#include "DHTMessageCallbackImpl.h"
+#include "DHTMessage.h"
+#include "DHTNode.h"
+
+DHTMessageCallbackImpl::DHTMessageCallbackImpl(const WeakHandle<DHTMessageCallbackListener>& listener):_listener(listener) {}
+
+DHTMessageCallbackImpl::~DHTMessageCallbackImpl() {}
+
+void DHTMessageCallbackImpl::onReceived(const DHTMessageHandle& message)
+{
+ if(!_listener.isNull()) {
+ _listener->onReceived(message);
+ }
+}
+
+void DHTMessageCallbackImpl::onTimeout(const DHTNodeHandle& remoteNode)
+{
+ if(!_listener.isNull()) {
+ _listener->onTimeout(remoteNode);
+ }
+}
diff --git a/src/DHTMessageCallbackImpl.h b/src/DHTMessageCallbackImpl.h
new file mode 100644
index 00000000..b7a2e912
--- /dev/null
+++ b/src/DHTMessageCallbackImpl.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_DHT_MESSAGE_CALLBACK_IMPL_H_
+#define _D_DHT_MESSAGE_CALLBACK_IMPL_H_
+
+#include "DHTMessageCallback.h"
+#include "DHTMessageCallbackListener.h"
+
+class DHTMessageCallbackImpl:public DHTMessageCallback {
+private:
+ WeakHandle<DHTMessageCallbackListener> _listener;
+
+public:
+ DHTMessageCallbackImpl(const WeakHandle<DHTMessageCallbackListener>& listener);
+
+ virtual ~DHTMessageCallbackImpl();
+
+ virtual void onReceived(const DHTMessageHandle& message);
+
+ virtual void onTimeout(const DHTNodeHandle& remoteNode);
+};
+
+#endif // _D_DHT_MESSAGE_CALLBACK_IMPL_H_
diff --git a/src/DHTMessageCallbackListener.h b/src/DHTMessageCallbackListener.h
new file mode 100644
index 00000000..6a77a529
--- /dev/null
+++ b/src/DHTMessageCallbackListener.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_DHT_MESSAGE_CALLBACK_LISTENER_H_
+#define _D_DHT_MESSAGE_CALLBACK_LISTENER_H_
+
+#include "common.h"
+#include "DHTMessageDecl.h"
+#include "DHTNodeDecl.h"
+
+class DHTMessageCallbackListener {
+public:
+ virtual ~DHTMessageCallbackListener() {}
+
+ virtual void onReceived(const DHTMessageHandle& message) = 0;
+
+ virtual void onTimeout(const DHTNodeHandle& remoteNode) = 0;
+};
+
+#endif // _D_DHT_MESSAGE_CALLBACK_LISTENER_H_
diff --git a/src/DHTMessageDecl.h b/src/DHTMessageDecl.h
new file mode 100644
index 00000000..0d5c7351
--- /dev/null
+++ b/src/DHTMessageDecl.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_DHT_MESSAGE_DECL_H_
+#define _D_DHT_MESSAGE_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTMessage;
+typedef SharedHandle<DHTMessage> DHTMessageHandle;
+typedef std::deque<DHTMessageHandle> DHTMessages;
+
+#endif // _D_DHT_MESSAGE_DECL_H_
diff --git a/src/DHTMessageDispatcher.cc b/src/DHTMessageDispatcher.cc
new file mode 100644
index 00000000..73be8beb
--- /dev/null
+++ b/src/DHTMessageDispatcher.cc
@@ -0,0 +1,86 @@
+/* <!-- 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 "DHTMessageDispatcher.h"
+#include "DHTMessage.h"
+#include "DHTMessageCallback.h"
+#include "DHTMessageEntry.h"
+#include "DHTMessageTracker.h"
+#include "RecoverableException.h"
+#include "LogFactory.h"
+#include "DHTConstants.h"
+
+DHTMessageDispatcher::DHTMessageDispatcher(const DHTMessageTrackerHandle& tracker):_tracker(tracker), _logger(LogFactory::getInstance()) {}
+
+DHTMessageDispatcher::~DHTMessageDispatcher() {}
+
+void DHTMessageDispatcher::addMessageToQueue(const DHTMessageHandle& message,
+ time_t timeout,
+ const DHTMessageCallbackHandle& callback)
+{
+ _messageQueue.push_back(new DHTMessageEntry(message, timeout, callback));
+}
+
+void DHTMessageDispatcher::addMessageToQueue(const DHTMessageHandle& message,
+ const DHTMessageCallbackHandle& callback)
+{
+ addMessageToQueue(message, DHT_MESSAGE_TIMEOUT, callback);
+}
+
+void DHTMessageDispatcher::sendMessage(const DHTMessageEntryHandle& entry)
+{
+ try {
+ entry->_message->send();
+ if(!entry->_message->isReply()) {
+ _tracker->addMessage(entry->_message, entry->_timeout, entry->_callback);
+ }
+ _logger->info("Message sent: %s", entry->_message->toString().c_str());
+ } catch(RecoverableException* e) {
+ _logger->error("Failed to send message: %s", e, entry->_message->toString().c_str());
+ delete e;
+ }
+}
+
+void DHTMessageDispatcher::sendMessages()
+{
+ for(DHTMessageEntries::iterator itr = _messageQueue.begin(); itr != _messageQueue.end(); ++itr) {
+ sendMessage(*itr);
+ }
+ _messageQueue.clear();
+}
+
+size_t DHTMessageDispatcher::countMessageInQueue() const
+{
+ return _messageQueue.size();
+}
diff --git a/src/DHTMessageDispatcher.h b/src/DHTMessageDispatcher.h
new file mode 100644
index 00000000..b2c63a4a
--- /dev/null
+++ b/src/DHTMessageDispatcher.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_DHT_MESSAGE_DISPATCHER_H_
+#define _D_DHT_MESSAGE_DISPATCHER_H_
+
+#include "common.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageTrackerDecl.h"
+#include "DHTMessageCallbackDecl.h"
+#include "DHTMessageEntryDecl.h"
+#include "DHTMessageDecl.h"
+
+class Logger;
+
+class DHTMessageDispatcher {
+private:
+ DHTMessageTrackerHandle _tracker;
+
+ DHTMessageEntries _messageQueue;
+
+ const Logger* _logger;
+
+ void sendMessage(const DHTMessageEntryHandle& msg);
+public:
+ DHTMessageDispatcher(const DHTMessageTrackerHandle& tracker);
+
+ ~DHTMessageDispatcher();
+
+ void addMessageToQueue(const DHTMessageHandle& message,
+ time_t timeout,
+ const DHTMessageCallbackHandle& callback = 0);
+
+ void addMessageToQueue(const DHTMessageHandle& message,
+ const DHTMessageCallbackHandle& callback = 0);
+
+ void sendMessages();
+
+ size_t countMessageInQueue() const;
+};
+
+#endif // _D_DHT_MESSAGE_DISPATCHER_H_
diff --git a/src/DHTMessageDispatcherDecl.h b/src/DHTMessageDispatcherDecl.h
new file mode 100644
index 00000000..e3836347
--- /dev/null
+++ b/src/DHTMessageDispatcherDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_MESSAGE_DISPATCHER_DECL_H_
+#define _D_DHT_MESSAGE_DISPATCHER_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTMessageDispatcher;
+typedef SharedHandle<DHTMessageDispatcher> DHTMessageDispatcherHandle;
+
+#endif // _D_DHT_MESSAGE_DISPATCHER_DECL_H_
diff --git a/src/DHTMessageEntry.cc b/src/DHTMessageEntry.cc
new file mode 100644
index 00000000..c3882f3c
--- /dev/null
+++ b/src/DHTMessageEntry.cc
@@ -0,0 +1,44 @@
+/* <!-- 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 "DHTMessageEntry.h"
+#include "DHTMessage.h"
+#include "DHTMessageCallback.h"
+
+DHTMessageEntry::DHTMessageEntry(const DHTMessageHandle& message, time_t timeout, const DHTMessageCallbackHandle& callback):
+ _message(message),
+ _timeout(timeout),
+ _callback(callback) {}
+
+DHTMessageEntry::~DHTMessageEntry() {}
diff --git a/src/DHTMessageEntry.h b/src/DHTMessageEntry.h
new file mode 100644
index 00000000..46e8a261
--- /dev/null
+++ b/src/DHTMessageEntry.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_DHT_MESSAGE_ENTRY_H_
+#define _D_DHT_MESSAGE_ENTRY_H_
+
+#include "common.h"
+#include "DHTMessageEntryDecl.h"
+#include "DHTMessageDecl.h"
+#include "DHTMessageCallbackDecl.h"
+
+class DHTMessageEntry {
+public:
+ DHTMessageHandle _message;
+ time_t _timeout;
+ DHTMessageCallbackHandle _callback;
+
+ DHTMessageEntry(const DHTMessageHandle& message, time_t timeout, const DHTMessageCallbackHandle& callback);
+
+ ~DHTMessageEntry();
+};
+
+#endif // _D_DHT_MESSAGE_ENTRY_H_
diff --git a/src/DHTMessageEntryDecl.h b/src/DHTMessageEntryDecl.h
new file mode 100644
index 00000000..2c80a9dd
--- /dev/null
+++ b/src/DHTMessageEntryDecl.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_DHT_MESSAGE_ENTRY_DECL_H_
+#define _D_DHT_MESSAGE_ENTRY_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTMessageEntry;
+typedef SharedHandle<DHTMessageEntry> DHTMessageEntryHandle;
+typedef std::deque<DHTMessageEntryHandle> DHTMessageEntries;
+
+#endif // _D_DHT_MESSAGE_ENTRY_DECL_H_
diff --git a/src/DHTMessageFactory.h b/src/DHTMessageFactory.h
new file mode 100644
index 00000000..59472164
--- /dev/null
+++ b/src/DHTMessageFactory.h
@@ -0,0 +1,107 @@
+/* <!-- 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_DHT_MESSAGE_FACTORY_H_
+#define _D_DHT_MESSAGE_FACTORY_H_
+
+#include "common.h"
+#include "DHTMessageDecl.h"
+#include "DHTNodeDecl.h"
+#include "PeerDecl.h"
+
+class Dictionary;
+
+class DHTMessageFactory {
+public:
+ virtual ~DHTMessageFactory() {}
+
+ virtual DHTMessageHandle
+ createQueryMessage(const Dictionary* d,
+ const string& ipaddr, uint16_t port) = 0;
+
+ virtual DHTMessageHandle
+ createResponseMessage(const string& messageType,
+ const Dictionary* d,
+ const DHTNodeHandle& remoteNode) = 0;
+
+ virtual DHTMessageHandle
+ createPingMessage(const DHTNodeHandle& remoteNode,
+ const string& transactionID = "") = 0;
+
+ virtual DHTMessageHandle
+ createPingReplyMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* id,
+ const string& transactionID) = 0;
+
+ virtual DHTMessageHandle
+ createFindNodeMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* targetNodeID,
+ const string& transactionID = "") = 0;
+
+ virtual DHTMessageHandle
+ createFindNodeReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& transactionID) = 0;
+
+ virtual DHTMessageHandle
+ createGetPeersMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ const string& transactionID = "") = 0;
+
+ virtual DHTMessageHandle
+ createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& token,
+ const string& transactionID) = 0;
+
+ virtual DHTMessageHandle
+ createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const Peers& peers,
+ const string& token,
+ const string& transactionID) = 0;
+
+ virtual DHTMessageHandle
+ createAnnouncePeerMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ uint16_t tcpPort,
+ const string& token,
+ const string& transactionID = "") = 0;
+
+ virtual DHTMessageHandle
+ createAnnouncePeerReplyMessage(const DHTNodeHandle& remoteNode,
+ const string& transactionID) = 0;
+
+};
+
+#endif // _D_DHT_MESSAGE_FACTORY_H_
diff --git a/src/DHTMessageFactoryDecl.h b/src/DHTMessageFactoryDecl.h
new file mode 100644
index 00000000..131d1053
--- /dev/null
+++ b/src/DHTMessageFactoryDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_MESSAGE_FACTORY_DECL_H_
+#define _D_DHT_MESSAGE_FACTORY_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTMessageFactory;
+typedef SharedHandle<DHTMessageFactory> DHTMessageFactoryHandle;
+
+#endif // _D_DHT_MESSAGE_FACTORY_DECL_H_
diff --git a/src/DHTMessageFactoryImpl.cc b/src/DHTMessageFactoryImpl.cc
new file mode 100644
index 00000000..12bf3d65
--- /dev/null
+++ b/src/DHTMessageFactoryImpl.cc
@@ -0,0 +1,418 @@
+/* <!-- 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 "DHTMessageFactoryImpl.h"
+#include "LogFactory.h"
+#include "DlAbortEx.h"
+#include "Data.h"
+#include "Dictionary.h"
+#include "List.h"
+#include "DHTNode.h"
+#include "DHTRoutingTable.h"
+#include "DHTPingMessage.h"
+#include "DHTPingReplyMessage.h"
+#include "DHTFindNodeMessage.h"
+#include "DHTFindNodeReplyMessage.h"
+#include "DHTGetPeersMessage.h"
+#include "DHTGetPeersReplyMessage.h"
+#include "DHTAnnouncePeerMessage.h"
+#include "DHTAnnouncePeerReplyMessage.h"
+#include "DHTConnection.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTracker.h"
+#include "PeerMessageUtil.h"
+#include "BtRuntime.h"
+#include "Util.h"
+#include "Peer.h"
+
+DHTMessageFactoryImpl::DHTMessageFactoryImpl():_localNode(0),
+ _logger(LogFactory::getInstance()) {}
+
+DHTMessageFactoryImpl::~DHTMessageFactoryImpl() {}
+
+DHTNodeHandle
+DHTMessageFactoryImpl::getRemoteNode(const unsigned char* id, const string& ipaddr, uint16_t port) const
+{
+ DHTNodeHandle node = _routingTable->getNode(id, ipaddr, port);
+ if(node.isNull()) {
+ node = new DHTNode(id);
+ node->setIPAddress(ipaddr);
+ node->setPort(port);
+ }
+ return node;
+}
+
+static const Dictionary* getDictionary(const Dictionary* d, const string& key)
+{
+ const Dictionary* c = dynamic_cast<const Dictionary*>(d->get(key));
+ if(c) {
+ return c;
+ } else {
+ throw new DlAbortEx("Malformed DHT message. Missing %s", key.c_str());
+ }
+}
+
+static const Data* getData(const Dictionary* d, const string& key)
+{
+ const Data* c = dynamic_cast<const Data*>(d->get(key));
+ if(c) {
+ return c;
+ } else {
+ throw new DlAbortEx("Malformed DHT message. Missing %s", key.c_str());
+ }
+}
+
+static const List* getList(const Dictionary* d, const string& key)
+{
+ const List* l = dynamic_cast<const List*>(d->get(key));
+ if(l) {
+ return l;
+ } else {
+ throw new DlAbortEx("Malformed DHT message. Missing %s", key.c_str());
+ }
+}
+
+void DHTMessageFactoryImpl::validateID(const Data* id) const
+{
+ if(id->getLen() != DHT_ID_LENGTH) {
+ throw new DlAbortEx("Malformed DHT message. Invalid ID length. Expected:%d, Actual:%d", DHT_ID_LENGTH, id->getLen());
+ }
+}
+
+void DHTMessageFactoryImpl::validateIDMatch(const unsigned char* expected, const unsigned char* actual) const
+{
+ if(memcmp(expected, actual, DHT_ID_LENGTH) != 0) {
+ //throw new DlAbortEx("Different ID received.");
+ }
+}
+
+void DHTMessageFactoryImpl::validatePort(const Data* i) const
+{
+ if(!i->isNumber()) {
+ throw new DlAbortEx("Malformed DHT message. Invalid port=%s",
+ Util::toHex(i->toString()).c_str());
+ }
+ uint32_t port = i->toInt();
+ if(UINT16_MAX < port) {
+ throw new DlAbortEx("Malformed DHT message. Invalid port=%u", port);
+ }
+}
+
+DHTMessageHandle DHTMessageFactoryImpl::createQueryMessage(const Dictionary* d,
+ const string& ipaddr,
+ uint16_t port)
+{
+ const Data* q = getData(d, "q");
+ const Data* t = getData(d, "t");
+ const Data* y = getData(d, "y");
+ const Dictionary* a = getDictionary(d, "a");
+ if(y->toString() != "q") {
+ throw new DlAbortEx("Malformed DHT message. y != q");
+ }
+ const Data* id = getData(getDictionary(d, "a"), "id");
+ validateID(id);
+ DHTNodeHandle remoteNode = getRemoteNode((const unsigned char*)id->toString().c_str(), ipaddr, port);
+ string messageType = q->toString();
+ string transactionID = t->toString();
+ if(messageType == "ping") {
+ return createPingMessage(remoteNode, transactionID);
+ } else if(messageType == "find_node") {
+ const Data* targetNodeID = getData(a, "target");
+ validateID(targetNodeID);
+ return createFindNodeMessage(remoteNode,
+ (const unsigned char*)targetNodeID->getData(),
+ transactionID);
+ } else if(messageType == "get_peers") {
+ const Data* infoHash = getData(a, "info_hash");
+ validateID(infoHash);
+ return createGetPeersMessage(remoteNode,
+ (const unsigned char*)infoHash->getData(),
+ transactionID);
+ } else if(messageType == "announce_peer") {
+ const Data* infoHash = getData(a, "info_hash");
+ validateID(infoHash);
+ const Data* port = getData(a, "port");
+ validatePort(port);
+ const Data* token = getData(a, "token");
+ return createAnnouncePeerMessage(remoteNode,
+ (const unsigned char*)infoHash->getData(),
+ (uint16_t)port->toInt(),
+ token->toString(),
+ transactionID);
+ } else {
+ throw new DlAbortEx("Unsupported message type: %s", messageType.c_str());
+ }
+}
+
+DHTMessageHandle DHTMessageFactoryImpl::createResponseMessage(const string& messageType,
+ const Dictionary* d,
+ const DHTNodeHandle& remoteNode)
+{
+ const Data* t = getData(d, "t");
+ const Data* y = getData(d, "y");
+ const Dictionary* r = getDictionary(d, "r");
+ // TODO handle y == "e" case
+ if(y->toString() != "r") {
+ throw new DlAbortEx("Malformed DHT message. y != r: y=%s",
+ Util::urlencode(y->toString()).c_str());
+ }
+ const Data* id = getData(r, "id");
+ validateID(id);
+ validateIDMatch(remoteNode->getID(),
+ (const unsigned char*)id->toString().c_str());
+ string transactionID = t->toString();
+ if(messageType == "ping") {
+ return createPingReplyMessage(remoteNode, (const unsigned char*)id->getData(), transactionID);
+ } else if(messageType == "find_node") {
+ return createFindNodeReplyMessage(remoteNode, d, transactionID);
+ } else if(messageType == "get_peers") {
+ const List* values = dynamic_cast<const List*>(r->get("values"));
+ if(values) {
+ return createGetPeersReplyMessageWithValues(remoteNode, d, transactionID);
+ } else {
+ const Data* nodes = dynamic_cast<const Data*>(r->get("nodes"));
+ if(nodes) {
+ return createGetPeersReplyMessageWithNodes(remoteNode, d, transactionID);
+ } else {
+ throw new DlAbortEx("Malformed DHT message: missing nodes/values");
+ }
+ }
+ } else if(messageType == "announce_peer") {
+ return createAnnouncePeerReplyMessage(remoteNode, transactionID);
+ } else {
+ throw new DlAbortEx("Unsupported message type: %s", messageType.c_str());
+ }
+}
+
+void DHTMessageFactoryImpl::setCommonProperty(const SharedHandle<DHTAbstractMessage>& m)
+{
+ m->setConnection(_connection);
+ m->setMessageDispatcher(_dispatcher);
+ m->setRoutingTable(_routingTable);
+ m->setMessageFactory(this);
+}
+
+DHTMessageHandle DHTMessageFactoryImpl::createPingMessage(const DHTNodeHandle& remoteNode, const string& transactionID)
+{
+ SharedHandle<DHTPingMessage> m = new DHTPingMessage(_localNode, remoteNode, transactionID);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createPingReplyMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* id,
+ const string& transactionID)
+{
+ SharedHandle<DHTPingReplyMessage> m = new DHTPingReplyMessage(_localNode, remoteNode, id, transactionID);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createFindNodeMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* targetNodeID,
+ const string& transactionID)
+{
+ SharedHandle<DHTFindNodeMessage> m = new DHTFindNodeMessage(_localNode, remoteNode, targetNodeID, transactionID);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createFindNodeReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& transactionID)
+{
+ SharedHandle<DHTFindNodeReplyMessage> m = new DHTFindNodeReplyMessage(_localNode, remoteNode, transactionID);
+ m->setClosestKNodes(closestKNodes);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTNodes DHTMessageFactoryImpl::extractNodes(const char* src, size_t length)
+{
+ if(length%26 != 0) {
+ throw new DlAbortEx("Nodes length is not multiple of 26");
+ }
+ DHTNodes nodes;
+ for(size_t offset = 0; offset < length; offset += 26) {
+ DHTNodeHandle node = new DHTNode(reinterpret_cast<const unsigned char*>(src+offset));
+ pair<string, uint16_t> addr =
+ PeerMessageUtil::unpackcompact(src+offset+DHT_ID_LENGTH);
+ node->setIPAddress(addr.first);
+ node->setPort(addr.second);
+ nodes.push_back(node);
+ }
+ return nodes;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createFindNodeReplyMessage(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID)
+{
+ const Data* nodesData = getData(getDictionary(d, "r"), "nodes");
+ DHTNodes nodes = extractNodes(nodesData->getData(), nodesData->getLen());
+ return createFindNodeReplyMessage(remoteNode, nodes, transactionID);
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createGetPeersMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ const string& transactionID)
+{
+ SharedHandle<DHTGetPeersMessage> m = new DHTGetPeersMessage(_localNode,
+ remoteNode,
+ infoHash,
+ transactionID);
+ m->setPeerAnnounceStorage(_peerAnnounceStorage);
+ m->setTokenTracker(_tokenTracker);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createGetPeersReplyMessageWithNodes(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID)
+{
+ const Dictionary* r = getDictionary(d, "r");
+ const Data* nodesData = getData(r, "nodes");
+ DHTNodes nodes = extractNodes(nodesData->getData(), nodesData->getLen());
+ const Data* token = getData(r, "token");
+ return createGetPeersReplyMessage(remoteNode, nodes, token->toString(),
+ transactionID);
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& token,
+ const string& transactionID)
+{
+ SharedHandle<DHTGetPeersReplyMessage> m = new DHTGetPeersReplyMessage(_localNode, remoteNode, token, transactionID);
+ m->setClosestKNodes(closestKNodes);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createGetPeersReplyMessageWithValues(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID)
+{
+ const Dictionary* r = getDictionary(d, "r");
+ const List* valuesList = getList(r, "values");
+ Peers peers;
+ for(MetaList::const_iterator i = valuesList->getList().begin(); i != valuesList->getList().end(); ++i) {
+ const Data* data = dynamic_cast<const Data*>(*i);
+ if(data && data->getLen() == 6) {
+ pair<string, uint16_t> addr = PeerMessageUtil::unpackcompact(data->getData());
+ PeerHandle peer = new Peer(addr.first, addr.second);
+ peers.push_back(peer);
+ }
+ }
+ const Data* token = getData(r, "token");
+ return createGetPeersReplyMessage(remoteNode, peers, token->toString(),
+ transactionID);
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const Peers& values,
+ const string& token,
+ const string& transactionID)
+{
+ SharedHandle<DHTGetPeersReplyMessage> m = new DHTGetPeersReplyMessage(_localNode, remoteNode, token, transactionID);
+ m->setValues(values);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createAnnouncePeerMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ uint16_t tcpPort,
+ const string& token,
+ const string& transactionID)
+{
+ SharedHandle<DHTAnnouncePeerMessage> m =
+ new DHTAnnouncePeerMessage(_localNode, remoteNode, infoHash, tcpPort, token, transactionID);
+ m->setPeerAnnounceStorage(_peerAnnounceStorage);
+ m->setTokenTracker(_tokenTracker);
+ setCommonProperty(m);
+ return m;
+}
+
+DHTMessageHandle
+DHTMessageFactoryImpl::createAnnouncePeerReplyMessage(const DHTNodeHandle& remoteNode,
+ const string& transactionID)
+{
+ SharedHandle<DHTAnnouncePeerReplyMessage> m =
+ new DHTAnnouncePeerReplyMessage(_localNode, remoteNode, transactionID);
+ setCommonProperty(m);
+ return m;
+}
+
+void DHTMessageFactoryImpl::setRoutingTable(const DHTRoutingTableHandle& routingTable)
+{
+ _routingTable = routingTable;
+}
+
+void DHTMessageFactoryImpl::setConnection(const DHTConnectionHandle& connection)
+{
+ _connection = connection;
+}
+
+void DHTMessageFactoryImpl::setMessageDispatcher(const DHTMessageDispatcherHandle& dispatcher)
+{
+ _dispatcher = dispatcher;
+}
+
+void DHTMessageFactoryImpl::setPeerAnnounceStorage(const DHTPeerAnnounceStorageHandle& storage)
+{
+ _peerAnnounceStorage = storage;
+}
+
+void DHTMessageFactoryImpl::setTokenTracker(const DHTTokenTrackerHandle& tokenTracker)
+{
+ _tokenTracker = tokenTracker;
+}
+
+void DHTMessageFactoryImpl::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
diff --git a/src/DHTMessageFactoryImpl.h b/src/DHTMessageFactoryImpl.h
new file mode 100644
index 00000000..1176740c
--- /dev/null
+++ b/src/DHTMessageFactoryImpl.h
@@ -0,0 +1,168 @@
+/* <!-- 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_DHT_MESSAGE_FACTORY_IMPL_H_
+#define _D_DHT_MESSAGE_FACTORY_IMPL_H_
+
+#include "DHTMessageFactory.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTConnectionDecl.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTPeerAnnounceStorageDecl.h"
+#include "DHTTokenTrackerDecl.h"
+
+class Logger;
+class Data;
+class DHTAbstractMessage;
+
+class DHTMessageFactoryImpl:public DHTMessageFactory {
+private:
+ DHTNodeHandle _localNode;
+
+ WeakHandle<DHTConnection> _connection;
+
+ WeakHandle<DHTMessageDispatcher> _dispatcher;
+
+ WeakHandle<DHTRoutingTable> _routingTable;
+
+ WeakHandle<DHTPeerAnnounceStorage> _peerAnnounceStorage;
+
+ WeakHandle<DHTTokenTracker> _tokenTracker;
+
+ const Logger* _logger;
+
+ // search node in routingTable. If it is not found, create new one.
+ DHTNodeHandle getRemoteNode(const unsigned char* id, const string& ipaddr, uint16_t port) const;
+
+ void validateID(const Data* id) const;
+
+ void validateIDMatch(const unsigned char* expected, const unsigned char* actual) const;
+
+ void validatePort(const Data* i) const;
+
+ DHTNodes extractNodes(const char* src, size_t length);
+
+ void setCommonProperty(const SharedHandle<DHTAbstractMessage>& m);
+
+public:
+ DHTMessageFactoryImpl();
+
+ virtual ~DHTMessageFactoryImpl();
+
+ virtual DHTMessageHandle
+ createQueryMessage(const Dictionary* d,
+ const string& ipaddr, uint16_t port);
+
+ virtual DHTMessageHandle
+ createResponseMessage(const string& messageType,
+ const Dictionary* d,
+ const DHTNodeHandle& remoteNode);
+
+ virtual DHTMessageHandle
+ createPingMessage(const DHTNodeHandle& remoteNode,
+ const string& transactionID = "");
+
+ virtual DHTMessageHandle
+ createPingReplyMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* id,
+ const string& transactionID);
+
+ virtual DHTMessageHandle
+ createFindNodeMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* targetNodeID,
+ const string& transactionID = "");
+
+ DHTMessageHandle
+ createFindNodeReplyMessage(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID);
+
+
+ virtual DHTMessageHandle
+ createFindNodeReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& transactionID);
+
+ virtual DHTMessageHandle
+ createGetPeersMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ const string& transactionID = "");
+
+ virtual DHTMessageHandle
+ createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const DHTNodes& closestKNodes,
+ const string& token,
+ const string& transactionID);
+
+ DHTMessageHandle
+ createGetPeersReplyMessageWithNodes(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID);
+
+ virtual DHTMessageHandle
+ createGetPeersReplyMessage(const DHTNodeHandle& remoteNode,
+ const Peers& peers,
+ const string& token,
+ const string& transactionID);
+
+ DHTMessageHandle
+ createGetPeersReplyMessageWithValues(const DHTNodeHandle& remoteNode,
+ const Dictionary* d,
+ const string& transactionID);
+
+ virtual DHTMessageHandle
+ createAnnouncePeerMessage(const DHTNodeHandle& remoteNode,
+ const unsigned char* infoHash,
+ uint16_t tcpPort,
+ const string& token,
+ const string& transactionID = "");
+
+ virtual DHTMessageHandle
+ createAnnouncePeerReplyMessage(const DHTNodeHandle& remoteNode,
+ const string& transactionID);
+
+ void setRoutingTable(const DHTRoutingTableHandle& routingTable);
+
+ void setConnection(const DHTConnectionHandle& connection);
+
+ void setMessageDispatcher(const DHTMessageDispatcherHandle& dispatcher);
+
+ void setPeerAnnounceStorage(const DHTPeerAnnounceStorageHandle& storage);
+
+ void setTokenTracker(const DHTTokenTrackerHandle& tokenTracker);
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+};
+
+#endif // _D_DHT_MESSAGE_FACTORY_IMPL_H_
diff --git a/src/DHTMessageReceiver.cc b/src/DHTMessageReceiver.cc
new file mode 100644
index 00000000..f763f813
--- /dev/null
+++ b/src/DHTMessageReceiver.cc
@@ -0,0 +1,134 @@
+/* <!-- 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 "DHTMessageReceiver.h"
+#include "DHTMessageTracker.h"
+#include "DHTConnection.h"
+#include "DHTMessage.h"
+#include "DHTMessageFactory.h"
+#include "DHTRoutingTable.h"
+#include "DHTNode.h"
+#include "DHTMessageCallback.h"
+#include "MetaEntry.h"
+#include "MetaFileUtil.h"
+#include "DlAbortEx.h"
+#include "LogFactory.h"
+#include "Util.h"
+
+DHTMessageReceiver::DHTMessageReceiver(const DHTMessageTrackerHandle& tracker):
+ _tracker(tracker),
+ _connection(0),
+ _factory(0),
+ _routingTable(0),
+ _logger(LogFactory::getInstance())
+{}
+
+DHTMessageReceiver::~DHTMessageReceiver() {}
+
+DHTMessageHandle DHTMessageReceiver::receiveMessage()
+{
+ string remoteAddr;
+ uint16_t remotePort;
+ char data[64*1024];
+ ssize_t length = _connection->receiveMessage(data, sizeof(data),
+ remoteAddr,
+ remotePort);
+ if(length <= 0) {
+ return 0;
+ }
+ bool isReply = false;
+ MetaEntryHandle msgroot = MetaFileUtil::bdecoding(data, length);
+ const Dictionary* d = dynamic_cast<const Dictionary*>(msgroot.get());
+ if(d) {
+ const Data* y = dynamic_cast<const Data*>(d->get("y"));
+ if(y->toString() == "r" || y->toString() == "e") {
+ isReply = true;
+ }
+ } else {
+ throw new DlAbortEx("Malformed DHT message. From:%s:%u", remoteAddr.c_str(), remotePort);
+ }
+ DHTMessageHandle message = 0;
+ DHTMessageCallbackHandle callback = 0;
+ if(isReply) {
+ std::pair<DHTMessageHandle, DHTMessageCallbackHandle> p = _tracker->messageArrived(d, remoteAddr, remotePort);
+ message = p.first;
+ callback = p.second;
+ if(message.isNull()) {
+ // timeout or malicious message
+ return 0;
+ }
+ } else {
+ message = _factory->createQueryMessage(d, remoteAddr, remotePort);
+ }
+ _logger->info("Message received: %s", message->toString().c_str());
+ message->validate();
+ message->doReceivedAction();
+ message->getRemoteNode()->markGood();
+ message->getRemoteNode()->updateLastContact();
+ _routingTable->addGoodNode(message->getRemoteNode());
+ if(!callback.isNull()) {
+ callback->onReceived(message);
+ }
+ return message;
+}
+
+void DHTMessageReceiver::handleTimeout()
+{
+ _tracker->handleTimeout();
+}
+
+DHTConnectionHandle DHTMessageReceiver::getConnection() const
+{
+ return _connection;
+}
+
+DHTMessageTrackerHandle DHTMessageReceiver::getMessageTracker() const
+{
+ return _tracker;
+}
+
+void DHTMessageReceiver::setConnection(const DHTConnectionHandle& connection)
+{
+ _connection = connection;
+}
+
+void DHTMessageReceiver::setMessageFactory(const DHTMessageFactoryHandle& factory)
+{
+ _factory = factory;
+}
+
+void DHTMessageReceiver::setRoutingTable(const DHTRoutingTableHandle& routingTable)
+{
+ _routingTable = routingTable;
+}
diff --git a/src/DHTMessageReceiver.h b/src/DHTMessageReceiver.h
new file mode 100644
index 00000000..b5b30d72
--- /dev/null
+++ b/src/DHTMessageReceiver.h
@@ -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 --> */
+#ifndef _D_DHT_MESSAGE_RECEIVER_H_
+#define _D_DHT_MESSAGE_RECEIVER_H_
+
+#include "common.h"
+#include "DHTMessageReceiverDecl.h"
+#include "DHTMessageTrackerDecl.h"
+#include "DHTMessageDecl.h"
+#include "DHTConnectionDecl.h"
+#include "DHTMessageFactoryDecl.h"
+#include "DHTRoutingTableDecl.h"
+
+class Logger;
+
+class DHTMessageReceiver {
+private:
+ DHTMessageTrackerHandle _tracker;
+
+ DHTConnectionHandle _connection;
+
+ DHTMessageFactoryHandle _factory;
+
+ DHTRoutingTableHandle _routingTable;
+
+ const Logger* _logger;
+public:
+ DHTMessageReceiver(const DHTMessageTrackerHandle& tracker);
+
+ ~DHTMessageReceiver();
+
+ // caller must handle thrown exception.
+ DHTMessageHandle receiveMessage();
+
+ void handleTimeout();
+
+ DHTConnectionHandle getConnection() const;
+
+ DHTMessageTrackerHandle getMessageTracker() const;
+
+ void setConnection(const DHTConnectionHandle& connection);
+
+ void setMessageFactory(const DHTMessageFactoryHandle& factory);
+
+ void setRoutingTable(const DHTRoutingTableHandle& routingTable);
+};
+
+#endif // _D_DHT_MESSAGE_RECEIVER_H_
diff --git a/src/DHTMessageReceiverDecl.h b/src/DHTMessageReceiverDecl.h
new file mode 100644
index 00000000..09405759
--- /dev/null
+++ b/src/DHTMessageReceiverDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_MESSAGE_RECEIVER_DECL_H_
+#define _D_DHT_MESSAGE_RECEIVER_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTMessageReceiver;
+typedef SharedHandle<DHTMessageReceiver> DHTMessageReceiverHandle;
+
+#endif // _D_DHT_MESSAGE_RECEIVER_DECL_H_
diff --git a/src/DHTMessageTracker.cc b/src/DHTMessageTracker.cc
new file mode 100644
index 00000000..cd9753a7
--- /dev/null
+++ b/src/DHTMessageTracker.cc
@@ -0,0 +1,149 @@
+/* <!-- 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 "DHTMessageTracker.h"
+#include "DHTMessage.h"
+#include "DHTMessageCallback.h"
+#include "DHTMessageTrackerEntry.h"
+#include "DHTNode.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactory.h"
+#include "Util.h"
+#include "LogFactory.h"
+#include "Dictionary.h"
+#include "Data.h"
+#include "DlAbortEx.h"
+#include "DHTConstants.h"
+
+DHTMessageTracker::DHTMessageTracker():
+ _routingTable(0),
+ _factory(0),
+ _logger(LogFactory::getInstance()) {}
+
+DHTMessageTracker::~DHTMessageTracker() {}
+
+void DHTMessageTracker::addMessage(const DHTMessageHandle& message, time_t timeout, const DHTMessageCallbackHandle& callback)
+{
+ _entries.push_back(new DHTMessageTrackerEntry(message, timeout, callback));
+}
+
+void DHTMessageTracker::addMessage(const DHTMessageHandle& message, const DHTMessageCallbackHandle& callback)
+{
+ addMessage(message, DHT_MESSAGE_TIMEOUT, callback);
+}
+
+pair<DHTMessageHandle, DHTMessageCallbackHandle>
+DHTMessageTracker::messageArrived(const Dictionary* d,
+ const string& ipaddr, uint16_t port)
+{
+ const Data* tid = dynamic_cast<const Data*>(d->get("t"));
+ if(!tid) {
+ throw new DlAbortEx("Malformed DHT message. From:%s:%u", ipaddr.c_str(), port);
+ }
+ _logger->debug("Searching tracker entry for TransactionID=%s, Remote=%s:%u",
+ Util::toHex(tid->toString()).c_str(), ipaddr.c_str(), port);
+ for(DHTMessageTrackerEntries::iterator i = _entries.begin();
+ i != _entries.end(); ++i) {
+ if((*i)->match(tid->toString(), ipaddr, port)) {
+ DHTMessageTrackerEntryHandle entry = *i;
+ _entries.erase(i);
+ _logger->debug("Tracker entry found.");
+ DHTNodeHandle targetNode = entry->getTargetNode();
+
+ DHTMessageHandle message = _factory->createResponseMessage(entry->getMessageType(),
+ d, targetNode);
+ int64_t rtt = entry->getElapsedMillis();
+ _logger->debug("RTT is %s", Util::llitos(rtt).c_str());
+ targetNode->updateRTT(rtt);
+ DHTMessageCallbackHandle callback = entry->getCallback();
+ return pair<DHTMessageHandle, DHTMessageCallbackHandle>(message, callback);
+ }
+ }
+ _logger->debug("Tracker entry not found.");
+ return pair<DHTMessageHandle, DHTMessageCallbackHandle>(0, 0);
+}
+
+void DHTMessageTracker::handleTimeout()
+{
+ for(DHTMessageTrackerEntries::iterator i = _entries.begin();
+ i != _entries.end();) {
+ if((*i)->isTimeout()) {
+ DHTMessageTrackerEntryHandle entry = *i;
+ i = _entries.erase(i);
+ DHTNodeHandle node = entry->getTargetNode();
+ _logger->debug("Message timeout: To:%s:%u",
+ node->getIPAddress().c_str(), node->getPort());
+ node->updateRTT(entry->getElapsedMillis());
+ node->timeout();
+ if(node->isBad()) {
+ _logger->debug("Marked bad: %s:%u",
+ node->getIPAddress().c_str(), node->getPort());
+ _routingTable->dropNode(node);
+ }
+ DHTMessageCallbackHandle callback = entry->getCallback();
+ if(!callback.isNull()) {
+ callback->onTimeout(node);
+ }
+ } else {
+ ++i;
+ }
+ }
+}
+
+DHTMessageTrackerEntryHandle
+DHTMessageTracker::getEntryFor(const DHTMessageHandle& message) const
+{
+ for(DHTMessageTrackerEntries::const_iterator i = _entries.begin();
+ i != _entries.end(); ++i) {
+ if((*i)->match(message->getTransactionID(), message->getRemoteNode()->getIPAddress(), message->getRemoteNode()->getPort())) {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+size_t DHTMessageTracker::countEntry() const
+{
+ return _entries.size();
+}
+
+void DHTMessageTracker::setRoutingTable(const DHTRoutingTableHandle& routingTable)
+{
+ _routingTable = routingTable;
+}
+
+void DHTMessageTracker::setMessageFactory(const DHTMessageFactoryHandle& factory)
+{
+ _factory = factory;
+}
diff --git a/src/DHTMessageTracker.h b/src/DHTMessageTracker.h
new file mode 100644
index 00000000..e4cf6b3a
--- /dev/null
+++ b/src/DHTMessageTracker.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_DHT_MESSAGE_TRACKER_H_
+#define _D_DHT_MESSAGE_TRACKER_H_
+
+#include "common.h"
+#include "DHTMessageTrackerDecl.h"
+#include "DHTMessageDecl.h"
+#include "DHTMessageCallbackDecl.h"
+#include "DHTMessageTrackerEntryDecl.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTMessageFactoryDecl.h"
+
+class Logger;
+class Dictionary;
+
+class DHTMessageTracker {
+private:
+ DHTMessageTrackerEntries _entries;
+
+ DHTRoutingTableHandle _routingTable;
+
+ DHTMessageFactoryHandle _factory;
+
+ const Logger* _logger;
+public:
+ DHTMessageTracker();
+
+ ~DHTMessageTracker();
+
+ void addMessage(const DHTMessageHandle& message, time_t timeout, const DHTMessageCallbackHandle& callback = 0);
+
+ void addMessage(const DHTMessageHandle& message, const DHTMessageCallbackHandle& callback = 0);
+
+ pair<DHTMessageHandle, DHTMessageCallbackHandle>
+ messageArrived(const Dictionary* d, const string& ipaddr, uint16_t port);
+
+ void handleTimeout();
+
+ DHTMessageTrackerEntryHandle getEntryFor(const DHTMessageHandle& message) const;
+
+ size_t countEntry() const;
+
+ void setRoutingTable(const DHTRoutingTableHandle& routingTable);
+
+ void setMessageFactory(const DHTMessageFactoryHandle& factory);
+};
+
+#endif // _D_DHT_MESSAGE_TRACKER_H_
diff --git a/src/DHTMessageTrackerDecl.h b/src/DHTMessageTrackerDecl.h
new file mode 100644
index 00000000..59e6d062
--- /dev/null
+++ b/src/DHTMessageTrackerDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_MESSAGE_TRACKER_DECL_H_
+#define _D_DHT_MESSAGE_TRACKER_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTMessageTracker;
+typedef SharedHandle<DHTMessageTracker> DHTMessageTrackerHandle;
+
+#endif // _D_DHT_MESSAGE_TRACKER_DECL_H_
diff --git a/src/DHTMessageTrackerEntry.cc b/src/DHTMessageTrackerEntry.cc
new file mode 100644
index 00000000..ab0231d7
--- /dev/null
+++ b/src/DHTMessageTrackerEntry.cc
@@ -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 --> */
+#include "DHTMessageTrackerEntry.h"
+#include "DHTNode.h"
+#include "DHTMessage.h"
+#include "DHTMessageCallback.h"
+#include "DHTConstants.h"
+
+DHTMessageTrackerEntry::DHTMessageTrackerEntry(const DHTMessageHandle& sentMessage,
+ time_t timeout,
+ const DHTMessageCallbackHandle& callback):
+ _targetNode(sentMessage->getRemoteNode()),
+ _transactionID(sentMessage->getTransactionID()),
+ _messageType(sentMessage->getMessageType()),
+ _callback(callback),
+ _timeout(timeout)
+{}
+
+bool DHTMessageTrackerEntry::isTimeout() const
+{
+ return _dispatchedTime.elapsed(_timeout);
+}
+
+void DHTMessageTrackerEntry::extendTimeout()
+{}
+
+bool DHTMessageTrackerEntry::match(const string& transactionID, const string& ipaddr, uint16_t port) const
+{
+ return _transactionID == transactionID &&
+ _targetNode->getIPAddress() == ipaddr && _targetNode->getPort() == port;
+}
+
+DHTMessageCallbackHandle DHTMessageTrackerEntry::getCallback() const
+{
+ return _callback;
+}
+
+DHTNodeHandle DHTMessageTrackerEntry::getTargetNode() const
+{
+ return _targetNode;
+}
diff --git a/src/DHTMessageTrackerEntry.h b/src/DHTMessageTrackerEntry.h
new file mode 100644
index 00000000..b6425e24
--- /dev/null
+++ b/src/DHTMessageTrackerEntry.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_DHT_MESSAGE_TRACKER_ENTRY_H_
+#define _D_DHT_MESSAGE_TRACKER_ENTRY_H_
+
+#include "common.h"
+#include "DHTMessageTrackerEntryDecl.h"
+#include "DHTConstants.h"
+#include "DHTNodeDecl.h"
+#include "DHTMessageDecl.h"
+#include "DHTMessageCallbackDecl.h"
+#include "TimeA2.h"
+
+class DHTMessageTrackerEntry {
+private:
+ DHTNodeHandle _targetNode;
+
+ string _transactionID;
+
+ string _messageType;
+
+ DHTMessageCallbackHandle _callback;
+
+ Time _dispatchedTime;
+
+ time_t _timeout;
+public:
+ DHTMessageTrackerEntry(const DHTMessageHandle& sentMessage,
+ time_t timeout,
+ const DHTMessageCallbackHandle& callback = 0);
+
+ bool isTimeout() const;
+
+ void extendTimeout();
+
+ bool match(const string& transactionID, const string& ipaddr, uint16_t port) const;
+
+ DHTNodeHandle getTargetNode() const;
+
+ const string& getMessageType() const
+ {
+ return _messageType;
+ }
+
+ DHTMessageCallbackHandle getCallback() const;
+
+ int64_t getElapsedMillis() const
+ {
+ return _dispatchedTime.differenceInMillis();
+ }
+};
+
+#endif // _D_DHT_MESSAGE_TRACKER_ENTRY_H_
diff --git a/src/DHTMessageTrackerEntryDecl.h b/src/DHTMessageTrackerEntryDecl.h
new file mode 100644
index 00000000..cb3c565f
--- /dev/null
+++ b/src/DHTMessageTrackerEntryDecl.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_DHT_MESSAGE_TRACKER_ENTRY_DECL_H_
+#define _D_DHT_MESSAGE_TRACKER_ENTRY_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTMessageTrackerEntry;
+typedef SharedHandle<DHTMessageTrackerEntry> DHTMessageTrackerEntryHandle;
+typedef std::deque<DHTMessageTrackerEntryHandle> DHTMessageTrackerEntries;
+
+#endif // _D_DHT_MESSAGE_TRACKER_ENTRY_DECL_H_
diff --git a/src/DHTNode.cc b/src/DHTNode.cc
new file mode 100644
index 00000000..cca92f55
--- /dev/null
+++ b/src/DHTNode.cc
@@ -0,0 +1,115 @@
+/* <!-- 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 "DHTNode.h"
+#include "DHTUtil.h"
+#include "Util.h"
+
+DHTNode::DHTNode():_port(0), _rtt(0), _condition(0), _lastContact(0)
+{
+ generateID();
+}
+
+DHTNode::DHTNode(const unsigned char* id):_port(0), _rtt(0), _condition(1), _lastContact(0)
+{
+ memcpy(_id, id, DHT_ID_LENGTH);
+}
+
+void DHTNode::generateID()
+{
+ DHTUtil::generateRandomKey(_id);
+}
+
+bool DHTNode::operator==(const DHTNode& node) const
+{
+ return memcmp(_id, node._id, DHT_ID_LENGTH) == 0 &&
+ _ipaddr == node._ipaddr && _port == node._port;
+}
+
+bool DHTNode::operator<(const DHTNode& node) const
+{
+ for(size_t i = 0; i < DHT_ID_LENGTH; ++i) {
+ if(_id[i] > node._id[i]) {
+ return false;
+ } else if(_id[i] < node._id[i]) {
+ return true;
+ }
+ }
+ return true;
+}
+
+bool DHTNode::isGood() const
+{
+ return !isBad() && !isQuestionable();
+}
+
+#define BAD_CONDITION 5
+
+bool DHTNode::isBad() const
+{
+ return _condition >= BAD_CONDITION;
+}
+
+bool DHTNode::isQuestionable() const
+{
+ return !isBad() && _lastContact.elapsed(DHT_NODE_CONTACT_INTERVAL);
+}
+
+void DHTNode::markGood()
+{
+ _condition = 0;
+}
+
+void DHTNode::markBad()
+{
+ _condition = BAD_CONDITION;
+}
+
+void DHTNode::updateLastContact()
+{
+ _lastContact.reset();
+}
+
+void DHTNode::timeout()
+{
+ ++_condition;
+}
+
+string DHTNode::toString() const
+{
+ return "DHTNode ID="+Util::toHex(_id, DHT_ID_LENGTH)+
+ ", Host="+_ipaddr+":"+Util::uitos(_port)+
+ ", Condition="+Util::uitos(_condition)+
+ ", RTT="+Util::itos(_rtt);
+}
diff --git a/src/DHTNode.h b/src/DHTNode.h
new file mode 100644
index 00000000..c6af39aa
--- /dev/null
+++ b/src/DHTNode.h
@@ -0,0 +1,123 @@
+/* <!-- 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_DHT_NODE_H_
+#define _D_DHT_NODE_H_
+
+#include "common.h"
+#include "DHTConstants.h"
+#include "DHTNodeDecl.h"
+#include "TimeA2.h"
+
+class DHTNode {
+private:
+ unsigned char _id[DHT_ID_LENGTH];
+
+ string _ipaddr;
+
+ uint16_t _port;
+
+ // in milli sec
+ int32_t _rtt;
+
+ uint32_t _condition;
+
+ Time _lastContact;
+public:
+ DHTNode();
+
+ /**
+ * id must be 20 bytes length
+ */
+ DHTNode(const unsigned char* id);
+
+ void generateID();
+
+ const unsigned char* getID() const
+ {
+ return _id;
+ }
+
+ void updateRTT(int32_t millisec)
+ {
+ _rtt = millisec;
+ }
+
+ string getIPAddress() const
+ {
+ return _ipaddr;
+ }
+
+ void setIPAddress(const string& ipaddr)
+ {
+ _ipaddr = ipaddr;
+ }
+
+ void setID(const unsigned char* id)
+ {
+ memcpy(_id, id, DHT_ID_LENGTH);
+ }
+
+ uint16_t getPort() const
+ {
+ return _port;
+ }
+
+ void setPort(uint16_t port)
+ {
+ _port = port;
+ }
+
+ bool isGood() const;
+
+ bool isBad() const;
+
+ bool isQuestionable() const;
+
+ void updateLastContact();
+
+ void markGood();
+
+ void markBad();
+
+ void timeout();
+
+ bool operator==(const DHTNode& node) const;
+
+ bool operator<(const DHTNode& node) const;
+
+ string toString() const;
+};
+
+#endif // _D_DHT_NODE_H_
diff --git a/src/DHTNodeDecl.h b/src/DHTNodeDecl.h
new file mode 100644
index 00000000..9648e3d6
--- /dev/null
+++ b/src/DHTNodeDecl.h
@@ -0,0 +1,44 @@
+/* <!-- 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_DHT_NODE_DECL_H_
+#define _D_DHT_NODE_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTNode;
+typedef SharedHandle<DHTNode> DHTNodeHandle;
+typedef std::deque<DHTNodeHandle> DHTNodes;
+#endif // _D_DHT_NODE_DECL_H_
diff --git a/src/DHTNodeLookupEntry.cc b/src/DHTNodeLookupEntry.cc
new file mode 100644
index 00000000..473cb47d
--- /dev/null
+++ b/src/DHTNodeLookupEntry.cc
@@ -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 --> */
+#include "DHTNodeLookupEntry.h"
+#include "DHTNode.h"
+
+DHTNodeLookupEntry::DHTNodeLookupEntry(const DHTNodeHandle& node):
+ _node(node), _used(false) {}
+
+DHTNodeLookupEntry::DHTNodeLookupEntry():
+ _node(0), _used(false) {}
+
+bool DHTNodeLookupEntry::operator==(const DHTNodeLookupEntry& entry) const
+{
+ return _node == entry._node;
+}
diff --git a/src/DHTNodeLookupEntry.h b/src/DHTNodeLookupEntry.h
new file mode 100644
index 00000000..e041f6b0
--- /dev/null
+++ b/src/DHTNodeLookupEntry.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_DHT_NODE_LOOKUP_ENTRY_H_
+#define _D_DHT_NODE_LOOKUP_ENTRY_H_
+
+#include "common.h"
+#include "DHTNodeDecl.h"
+
+class DHTNodeLookupEntry {
+public:
+ DHTNodeHandle _node;
+
+ bool _used;
+
+ DHTNodeLookupEntry(const DHTNodeHandle& node);
+
+ DHTNodeLookupEntry();
+
+ bool operator==(const DHTNodeLookupEntry& entry) const;
+};
+
+#endif // _D_DHT_NODE_LOOKUP_ENTRY_H_
diff --git a/src/DHTNodeLookupEntryDecl.h b/src/DHTNodeLookupEntryDecl.h
new file mode 100644
index 00000000..0d1e54fa
--- /dev/null
+++ b/src/DHTNodeLookupEntryDecl.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_DHT_NODE_LOOKUP_ENTRY_DECL_H_
+#define _D_DHT_NODE_LOOKUP_ENTRY_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTNodeLookupEntry;
+typedef SharedHandle<DHTNodeLookupEntry> DHTNodeLookupEntryHandle;
+typedef std::deque<DHTNodeLookupEntryHandle> DHTNodeLookupEntries;
+
+#endif // _D_DHT_NODE_LOOKUP_ENTRY_DECL_H_
diff --git a/src/DHTNodeLookupTask.cc b/src/DHTNodeLookupTask.cc
new file mode 100644
index 00000000..7770d55b
--- /dev/null
+++ b/src/DHTNodeLookupTask.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 "DHTNodeLookupTask.h"
+#include "DHTMessageFactory.h"
+#include "DHTFindNodeReplyMessage.h"
+#include "DHTNode.h"
+#include "DHTNodeLookupEntry.h"
+#include "LogFactory.h"
+#include "Util.h"
+
+DHTNodeLookupTask::DHTNodeLookupTask(const unsigned char* targetNodeID):
+ DHTAbstractNodeLookupTask(targetNodeID)
+{}
+
+DHTNodes DHTNodeLookupTask::getNodesFromMessage(const DHTMessageHandle& message)
+{
+ SharedHandle<DHTFindNodeReplyMessage> m = message;
+ return m->getClosestKNodes();
+}
+
+DHTMessageHandle DHTNodeLookupTask::createMessage(const DHTNodeHandle& remoteNode)
+{
+ return _factory->createFindNodeMessage(remoteNode, _targetID);
+}
diff --git a/src/DHTNodeLookupTask.h b/src/DHTNodeLookupTask.h
new file mode 100644
index 00000000..3fbf2ce7
--- /dev/null
+++ b/src/DHTNodeLookupTask.h
@@ -0,0 +1,49 @@
+/* <!-- 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_DHT_NODE_LOOKUP_TASK_H_
+#define _D_DHT_NODE_LOOKUP_TASK_H_
+
+#include "DHTAbstractNodeLookupTask.h"
+
+class DHTNodeLookupTask:public DHTAbstractNodeLookupTask {
+public:
+ DHTNodeLookupTask(const unsigned char* targetNodeID);
+
+ virtual DHTNodes getNodesFromMessage(const DHTMessageHandle& message);
+
+ virtual DHTMessageHandle createMessage(const DHTNodeHandle& remoteNode);
+};
+
+#endif // _D_DHT_NODE_LOOKUP_TASK_H_
diff --git a/src/DHTPeerAnnounceCommand.cc b/src/DHTPeerAnnounceCommand.cc
new file mode 100644
index 00000000..e6272e54
--- /dev/null
+++ b/src/DHTPeerAnnounceCommand.cc
@@ -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 --> */
+#include "DHTPeerAnnounceCommand.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DownloadEngine.h"
+#include "SingletonHolder.h"
+#include "RequestGroupMan.h"
+#include "RecoverableException.h"
+#include "message.h"
+
+DHTPeerAnnounceCommand::DHTPeerAnnounceCommand(int32_t cuid, DownloadEngine* e, time_t interval):
+ TimeBasedCommand(cuid, e, interval),
+ _peerAnnounceStorage(0)
+{}
+
+DHTPeerAnnounceCommand::~DHTPeerAnnounceCommand() {}
+
+void DHTPeerAnnounceCommand::preProcess()
+{
+ _exit = _e->_requestGroupMan->downloadFinished() || _e->isHaltRequested();
+}
+
+void DHTPeerAnnounceCommand::process()
+{
+ try {
+ _peerAnnounceStorage->handleTimeout();
+ } catch(RecoverableException* e) {
+ logger->error(EX_EXCEPTION_CAUGHT, e);
+ delete e;
+ }
+}
+
+void DHTPeerAnnounceCommand::setPeerAnnounceStorage(const DHTPeerAnnounceStorageHandle& storage)
+{
+ _peerAnnounceStorage = storage;
+}
diff --git a/src/DHTPeerAnnounceCommand.h b/src/DHTPeerAnnounceCommand.h
new file mode 100644
index 00000000..6eec7717
--- /dev/null
+++ b/src/DHTPeerAnnounceCommand.h
@@ -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 --> */
+#ifndef _D_DHT_PEER_ANNOUNCE_COMMAND_H_
+#define _D_DHT_PEER_ANNOUNCE_COMMAND_H_
+
+#include "TimeBasedCommand.h"
+#include "DHTPeerAnnounceStorageDecl.h"
+
+class DHTPeerAnnounceCommand:public TimeBasedCommand {
+private:
+ DHTPeerAnnounceStorageHandle _peerAnnounceStorage;
+public:
+ DHTPeerAnnounceCommand(int32_t cuid, DownloadEngine* e, time_t interval);
+
+ virtual ~DHTPeerAnnounceCommand();
+
+ virtual void preProcess();
+
+ virtual void process();
+
+ void setPeerAnnounceStorage(const DHTPeerAnnounceStorageHandle& storage);
+};
+
+#endif // _D_DHT_PEER_ANNOUNCE_COMMAND_H_
diff --git a/src/DHTPeerAnnounceEntry.cc b/src/DHTPeerAnnounceEntry.cc
new file mode 100644
index 00000000..74b27b29
--- /dev/null
+++ b/src/DHTPeerAnnounceEntry.cc
@@ -0,0 +1,121 @@
+/* <!-- 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 "DHTPeerAnnounceEntry.h"
+#include "BtContext.h"
+#include "Peer.h"
+#include "BtRegistry.h"
+
+DHTPeerAnnounceEntry::DHTPeerAnnounceEntry(const unsigned char* infoHash):
+ _btCtx(0)
+{
+ memcpy(_infoHash, infoHash, DHT_ID_LENGTH);
+}
+
+DHTPeerAnnounceEntry::~DHTPeerAnnounceEntry() {}
+
+void DHTPeerAnnounceEntry::addPeerAddrEntry(const PeerAddrEntry& entry)
+{
+ PeerAddrEntries::iterator i = find(_peerAddrEntries.begin(), _peerAddrEntries.end(), entry);
+ if(i == _peerAddrEntries.end()) {
+ _peerAddrEntries.push_back(entry);
+ } else {
+ (*i).notifyUpdate();
+ }
+ notifyUpdate();
+}
+
+void DHTPeerAnnounceEntry::setBtContext(const BtContextHandle& btCtx)
+{
+ _btCtx = btCtx;
+}
+
+size_t DHTPeerAnnounceEntry::countPeerAddrEntry() const
+{
+ return _peerAddrEntries.size();
+}
+
+const PeerAddrEntries& DHTPeerAnnounceEntry::getPeerAddrEntries() const
+{
+ return _peerAddrEntries;
+}
+
+class FindStaleEntry {
+private:
+ time_t _timeout;
+public:
+ FindStaleEntry(time_t timeout):_timeout(timeout) {}
+
+ bool operator()(const PeerAddrEntry& entry) const
+ {
+ if(entry.getLastUpdated().elapsed(_timeout)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+void DHTPeerAnnounceEntry::removeStalePeerAddrEntry(time_t timeout)
+{
+ _peerAddrEntries.erase(remove_if(_peerAddrEntries.begin(), _peerAddrEntries.end(),
+ FindStaleEntry(timeout)), _peerAddrEntries.end());
+}
+
+bool DHTPeerAnnounceEntry::empty() const
+{
+ return _peerAddrEntries.empty() && _btCtx.isNull();
+}
+
+Peers DHTPeerAnnounceEntry::getPeers() const
+{
+ Peers peers;
+ for(PeerAddrEntries::const_iterator i = _peerAddrEntries.begin();
+ i != _peerAddrEntries.end(); ++i) {
+ peers.push_back(new Peer((*i).getIPAddress(), (*i).getPort()));
+ }
+ if(!_btCtx.isNull()) {
+ PeerStorageHandle peerStorage = PEER_STORAGE(_btCtx);
+ if(!peerStorage.isNull()) {
+ const Peers& activePeers = peerStorage->getActivePeers();
+ peers.insert(peers.end(), activePeers.begin(), activePeers.end());
+ }
+ }
+ return peers;
+}
+
+void DHTPeerAnnounceEntry::notifyUpdate()
+{
+ _lastUpdated.reset();
+}
diff --git a/src/DHTPeerAnnounceEntry.h b/src/DHTPeerAnnounceEntry.h
new file mode 100644
index 00000000..b4cb6d56
--- /dev/null
+++ b/src/DHTPeerAnnounceEntry.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_DHT_PEER_ANNOUNCE_ENTRY_H_
+#define _D_DHT_PEER_ANNOUNCE_ENTRY_H_
+
+#include "common.h"
+#include "DHTConstants.h"
+#include "PeerAddrEntry.h"
+#include "PeerDecl.h"
+#include "TimeA2.h"
+
+class BtContext;
+typedef SharedHandle<BtContext> BtContextHandle;
+
+class DHTPeerAnnounceEntry {
+private:
+ unsigned char _infoHash[DHT_ID_LENGTH];
+
+ PeerAddrEntries _peerAddrEntries;
+
+ BtContextHandle _btCtx;
+
+ Time _lastUpdated;
+public:
+ DHTPeerAnnounceEntry(const unsigned char* infoHash);
+
+ ~DHTPeerAnnounceEntry();
+
+ // add peer addr entry.
+ // if it already exists, update "Last Updated" property.
+ void addPeerAddrEntry(const PeerAddrEntry& entry);
+
+ void setBtContext(const BtContextHandle& btCtx);
+
+ size_t countPeerAddrEntry() const;
+
+ const PeerAddrEntries& getPeerAddrEntries() const;
+
+ void removeStalePeerAddrEntry(time_t timeout);
+
+ bool empty() const;
+
+ const Time& getLastUpdated() const
+ {
+ return _lastUpdated;
+ }
+
+ void notifyUpdate();
+
+ const unsigned char* getInfoHash() const
+ {
+ return _infoHash;
+ }
+
+ Peers getPeers() const;
+
+};
+
+#endif // _D_DHT_PEER_ANNOUNCE_ENTRY_H_
diff --git a/src/DHTPeerAnnounceEntryDecl.h b/src/DHTPeerAnnounceEntryDecl.h
new file mode 100644
index 00000000..047c55f5
--- /dev/null
+++ b/src/DHTPeerAnnounceEntryDecl.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_DHT_PEER_ANNOUNCE_ENTRY_DECL_H_
+#define _D_DHT_PEER_ANNOUNCE_ENTRY_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTPeerAnnounceEntry;
+typedef SharedHandle<DHTPeerAnnounceEntry> DHTPeerAnnounceEntryHandle;
+typedef std::deque<DHTPeerAnnounceEntryHandle> DHTPeerAnnounceEntries;
+
+#endif // _D_DHT_PEER_ANNOUNCE_ENTRY_DECL_H_
diff --git a/src/DHTPeerAnnounceStorage.cc b/src/DHTPeerAnnounceStorage.cc
new file mode 100644
index 00000000..f36ef9ac
--- /dev/null
+++ b/src/DHTPeerAnnounceStorage.cc
@@ -0,0 +1,165 @@
+/* <!-- 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 "DHTPeerAnnounceStorage.h"
+#include "DHTPeerAnnounceEntry.h"
+#include "Peer.h"
+#include "BtContext.h"
+#include "DHTConstants.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
+#include "LogFactory.h"
+#include "Util.h"
+
+DHTPeerAnnounceStorage::DHTPeerAnnounceStorage():_taskQueue(0),
+ _taskFactory(0),
+ _logger(LogFactory::getInstance()) {}
+
+DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {}
+
+class FindPeerAnnounceEntry {
+private:
+ unsigned char _infoHash[DHT_ID_LENGTH];
+public:
+ FindPeerAnnounceEntry(const unsigned char* infoHash)
+ {
+ memcpy(_infoHash, infoHash, DHT_ID_LENGTH);
+ }
+
+ bool operator()(const DHTPeerAnnounceEntryHandle& entry) const
+ {
+ return memcmp(_infoHash, entry->getInfoHash(), DHT_ID_LENGTH) == 0;
+ }
+};
+
+DHTPeerAnnounceEntryHandle
+DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash)
+{
+ DHTPeerAnnounceEntries::iterator i =
+ find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash));
+ DHTPeerAnnounceEntryHandle entry = 0;
+ if(i == _entries.end()) {
+ entry = new DHTPeerAnnounceEntry(infoHash);
+ _entries.push_back(entry);
+ } else {
+ entry = *i;
+ }
+ return entry;
+}
+
+void
+DHTPeerAnnounceStorage::addPeerAnnounce(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port)
+{
+ _logger->debug("Adding %s:%u to peer announce list: infoHash=%s",
+ ipaddr.c_str(), port, Util::toHex(infoHash, DHT_ID_LENGTH).c_str());
+ getPeerAnnounceEntry(infoHash)->addPeerAddrEntry(PeerAddrEntry(ipaddr, port));
+}
+
+// add peer announce as localhost downloading the content
+void DHTPeerAnnounceStorage::addPeerAnnounce(const BtContextHandle& ctx)
+{
+ _logger->debug("Adding localhost to peer announce list: infoHash=%s",
+ ctx->getInfoHashAsString().c_str());
+ getPeerAnnounceEntry(ctx->getInfoHash())->setBtContext(ctx);
+}
+
+void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx)
+{
+ DHTPeerAnnounceEntries::iterator i =
+ find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(ctx->getInfoHash()));
+ if(i != _entries.end()) {
+ (*i)->setBtContext(0);
+ if((*i)->empty()) {
+ _entries.erase(i);
+ }
+ }
+}
+
+bool DHTPeerAnnounceStorage::contains(const unsigned char* infoHash) const
+{
+ return
+ find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash))
+ != _entries.end();
+}
+
+Peers DHTPeerAnnounceStorage::getPeers(const unsigned char* infoHash)
+{
+ DHTPeerAnnounceEntries::iterator i =
+ find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash));
+ if(i == _entries.end() || (*i)->empty()) {
+ return Peers();
+ }
+ return (*i)->getPeers();
+}
+
+void DHTPeerAnnounceStorage::handleTimeout()
+{
+ _logger->debug("Now purge peer announces which are timed out.");
+ for(DHTPeerAnnounceEntries::iterator i = _entries.begin(); i != _entries.end();) {
+ (*i)->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL);
+ if((*i)->empty()) {
+ _logger->debug("1 entry purged: infoHash=%s",
+ Util::toHex((*i)->getInfoHash(), DHT_ID_LENGTH).c_str());
+ i = _entries.erase(i);
+ } else {
+ ++i;
+ }
+ }
+}
+
+void DHTPeerAnnounceStorage::announcePeer()
+{
+ _logger->debug("Now announcing peer.");
+ for(DHTPeerAnnounceEntries::iterator i = _entries.begin(); i != _entries.end(); ++i) {
+ if((*i)->getLastUpdated().elapsed(DHT_PEER_ANNOUNCE_INTERVAL)) {
+ (*i)->notifyUpdate();
+ DHTTaskHandle task = _taskFactory->createPeerAnnounceTask((*i)->getInfoHash());
+ _taskQueue->addPeriodicTask2(task);
+ _logger->debug("Added 1 peer announce: infoHash=%s",
+ Util::toHex((*i)->getInfoHash(), DHT_ID_LENGTH).c_str());
+ }
+ }
+}
+
+void DHTPeerAnnounceStorage::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTPeerAnnounceStorage::setTaskFactory(const DHTTaskFactoryHandle& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
diff --git a/src/DHTPeerAnnounceStorage.h b/src/DHTPeerAnnounceStorage.h
new file mode 100644
index 00000000..93dbb73f
--- /dev/null
+++ b/src/DHTPeerAnnounceStorage.h
@@ -0,0 +1,92 @@
+/* <!-- 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_DHT_PEER_ANNOUNCE_STORAGE_H_
+#define _D_DHT_PEER_ANNOUNCE_STORAGE_H_
+
+#include "common.h"
+#include "DHTPeerAnnounceStorageDecl.h"
+#include "DHTPeerAnnounceEntryDecl.h"
+#include "PeerDecl.h"
+#include "BtContextDecl.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+
+class Logger;
+
+class DHTPeerAnnounceStorage {
+private:
+ DHTPeerAnnounceEntries _entries;
+
+ DHTPeerAnnounceEntryHandle getPeerAnnounceEntry(const unsigned char* infoHash);
+
+ DHTTaskQueueHandle _taskQueue;
+
+ DHTTaskFactoryHandle _taskFactory;
+
+ const Logger* _logger;
+public:
+ DHTPeerAnnounceStorage();
+
+ ~DHTPeerAnnounceStorage();
+
+ void addPeerAnnounce(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port);
+
+ // add peer announce as localhost downloading the content
+ void addPeerAnnounce(const BtContextHandle& ctx);
+
+ // give 0 to DHTPeerAnnounceEntry::setBtContext().
+ // If DHTPeerAnnounceEntry is empty, it is erased.
+ void removePeerAnnounce(const BtContextHandle& ctx);
+
+ bool contains(const unsigned char* infoHash) const;
+
+ Peers getPeers(const unsigned char* infoHash);
+
+ // drop peer announce entry which is not updated in the past
+ // DHT_PEER_ANNOUNCE_PURGE_INTERVAL seconds.
+ void handleTimeout();
+
+ // announce peer in every DHT_PEER_ANNOUNCE_PURGE_INTERVAL.
+ // The torrents which are announced in the past DHT_PEER_ANNOUNCE_PURGE_INTERVAL
+ // are excluded from announce.
+ void announcePeer();
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+
+ void setTaskFactory(const DHTTaskFactoryHandle& taskFactory);
+};
+
+#endif // _D_DHT_PEER_ANNOUNCE_STORAGE_H_
diff --git a/src/DHTPeerAnnounceStorageDecl.h b/src/DHTPeerAnnounceStorageDecl.h
new file mode 100644
index 00000000..132f8742
--- /dev/null
+++ b/src/DHTPeerAnnounceStorageDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_PEER_ANNOUNCE_STORAGE_DECL_H_
+#define _D_DHT_PEER_ANNOUNCE_STORAGE_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTPeerAnnounceStorage;
+typedef SharedHandle<DHTPeerAnnounceStorage> DHTPeerAnnounceStorageHandle;
+
+#endif // _D_DHT_PEER_ANNOUNCE_STORAGE_DECL_H_
diff --git a/src/DHTPeerLookupTask.cc b/src/DHTPeerLookupTask.cc
new file mode 100644
index 00000000..f16409e3
--- /dev/null
+++ b/src/DHTPeerLookupTask.cc
@@ -0,0 +1,102 @@
+/* <!-- 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 "DHTPeerLookupTask.h"
+#include "Peer.h"
+#include "DHTGetPeersReplyMessage.h"
+#include "Logger.h"
+#include "DHTMessageFactory.h"
+#include "DHTNode.h"
+#include "DHTNodeLookupEntry.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallback.h"
+#include "BtRegistry.h"
+#include "PeerStorage.h"
+#include "BtRuntime.h"
+#include "BtContext.h"
+#include "Util.h"
+#include "DHTBucket.h"
+
+DHTPeerLookupTask::DHTPeerLookupTask(const BtContextHandle& btContext):
+ DHTAbstractNodeLookupTask(btContext->getInfoHash()),
+ _ctx(btContext),
+ _peerStorage(PEER_STORAGE(btContext)),
+ _btRuntime(BT_RUNTIME(btContext)) {}
+
+DHTNodes DHTPeerLookupTask::getNodesFromMessage(const DHTMessageHandle& message)
+{
+ SharedHandle<DHTGetPeersReplyMessage> m = message;
+ return m->getClosestKNodes();
+}
+
+void DHTPeerLookupTask::onReceivedInternal(const DHTMessageHandle& message)
+{
+ SharedHandle<DHTGetPeersReplyMessage> m = message;
+
+ DHTNodeHandle remoteNode = m->getRemoteNode();
+ _tokenStorage[Util::toHex(remoteNode->getID(), DHT_ID_LENGTH)] = m->getToken();
+
+ _peerStorage->addPeer(m->getValues());
+ _peers.insert(_peers.end(), m->getValues().begin(), m->getValues().end());
+ _logger->info("Received %u peers.", m->getValues().size());
+}
+
+DHTMessageHandle DHTPeerLookupTask::createMessage(const DHTNodeHandle& remoteNode)
+{
+ return _factory->createGetPeersMessage(remoteNode, _targetID);
+}
+
+void DHTPeerLookupTask::onFinish()
+{
+ // send announce_peer message to K closest nodes
+ size_t num = DHTBucket::K;
+ for(DHTNodeLookupEntries::const_iterator i = _entries.begin();
+ i != _entries.end() && num > 0; ++i, --num) {
+ if((*i)->_used) {
+ const DHTNodeHandle& node = (*i)->_node;
+ DHTMessageHandle m =
+ _factory->createAnnouncePeerMessage(node,
+ _ctx->getInfoHash(),
+ _btRuntime->getListenPort(),
+ _tokenStorage[Util::toHex(node->getID(),
+ DHT_ID_LENGTH)]);
+ _dispatcher->addMessageToQueue(m);
+ }
+ }
+}
+
+const Peers& DHTPeerLookupTask::getPeers() const
+{
+ return _peers;
+}
diff --git a/src/DHTPeerLookupTask.h b/src/DHTPeerLookupTask.h
new file mode 100644
index 00000000..396b2033
--- /dev/null
+++ b/src/DHTPeerLookupTask.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_DHT_PEER_LOOKUP_TASK_H_
+#define _D_DHT_PEER_LOOKUP_TASK_H_
+
+#include "DHTAbstractNodeLookupTask.h"
+#include "BtContextDecl.h"
+#include "PeerDecl.h"
+#include <map>
+
+class PeerStorage;
+typedef SharedHandle<PeerStorage> PeerStorageHandle;
+class BtRuntime;
+typedef SharedHandle<BtRuntime> BtRuntimeHandle;
+
+class DHTPeerLookupTask:public DHTAbstractNodeLookupTask {
+private:
+ std::map<string, string> _tokenStorage;
+
+ Peers _peers;
+
+ BtContextHandle _ctx;
+
+ PeerStorageHandle _peerStorage;
+
+ BtRuntimeHandle _btRuntime;
+public:
+ DHTPeerLookupTask(const BtContextHandle& btContext);
+
+ virtual DHTNodes getNodesFromMessage(const DHTMessageHandle& message);
+
+ virtual void onReceivedInternal(const DHTMessageHandle& message);
+
+ virtual DHTMessageHandle createMessage(const DHTNodeHandle& remoteNode);
+
+ virtual void onFinish();
+
+ const Peers& getPeers() const;
+};
+
+#endif // _D_DHT_PEER_LOOKUP_TASK_H_
diff --git a/src/DHTPingMessage.cc b/src/DHTPingMessage.cc
new file mode 100644
index 00000000..844a4a9e
--- /dev/null
+++ b/src/DHTPingMessage.cc
@@ -0,0 +1,70 @@
+/* <!-- 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 "DHTPingMessage.h"
+#include "DHTNode.h"
+#include "Data.h"
+#include "DHTConstants.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageCallback.h"
+
+DHTPingMessage::DHTPingMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTQueryMessage(localNode, remoteNode, transactionID) {}
+
+DHTPingMessage::~DHTPingMessage() {}
+
+void DHTPingMessage::doReceivedAction()
+{
+ // send back ping reply
+ DHTMessageHandle reply = _factory->createPingReplyMessage(_remoteNode, _localNode->getID(), _transactionID);
+ _dispatcher->addMessageToQueue(reply);
+}
+
+Dictionary* DHTPingMessage::getArgument()
+{
+ Dictionary* a = new Dictionary();
+ a->put("id", new Data(reinterpret_cast<const char*>(_localNode->getID()),
+ DHT_ID_LENGTH));
+ return a;
+}
+
+string DHTPingMessage::getMessageType() const
+{
+ return "ping";
+}
+
+void DHTPingMessage::validate() const {}
diff --git a/src/DHTPingMessage.h b/src/DHTPingMessage.h
new file mode 100644
index 00000000..16b5d8ab
--- /dev/null
+++ b/src/DHTPingMessage.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_DHT_PING_MESSAGE_H_
+#define _D_DHT_PING_MESSAGE_H_
+
+#include "DHTQueryMessage.h"
+
+class DHTPingMessage:public DHTQueryMessage {
+public:
+ DHTPingMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID = "");
+
+ virtual ~DHTPingMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getArgument();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+};
+
+#endif // _D_DHT_PING_MESSAGE_H_
diff --git a/src/DHTPingReplyMessage.cc b/src/DHTPingReplyMessage.cc
new file mode 100644
index 00000000..f8ac1848
--- /dev/null
+++ b/src/DHTPingReplyMessage.cc
@@ -0,0 +1,65 @@
+/* <!-- 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 "DHTPingReplyMessage.h"
+#include "DHTNode.h"
+#include "Dictionary.h"
+#include "Data.h"
+
+DHTPingReplyMessage::DHTPingReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* id,
+ const string& transactionID):
+ DHTResponseMessage(localNode, remoteNode, transactionID)
+{
+ memcpy(_id, id, DHT_ID_LENGTH);
+}
+
+DHTPingReplyMessage::~DHTPingReplyMessage() {}
+
+void DHTPingReplyMessage::doReceivedAction() {}
+
+Dictionary* DHTPingReplyMessage::getResponse()
+{
+ Dictionary* r = new Dictionary();
+ r->put("id", new Data(_id, DHT_ID_LENGTH));
+ return r;
+}
+
+string DHTPingReplyMessage::getMessageType() const
+{
+ return "ping";
+}
+
+void DHTPingReplyMessage::validate() const {}
diff --git a/src/DHTPingReplyMessage.h b/src/DHTPingReplyMessage.h
new file mode 100644
index 00000000..33659956
--- /dev/null
+++ b/src/DHTPingReplyMessage.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_DHT_PING_REPLY_MESSAGE_H_
+#define _D_DHT_PING_REPLY_MESSAGE_H_
+
+#include "DHTResponseMessage.h"
+#include "DHTConstants.h"
+
+class DHTPingReplyMessage:public DHTResponseMessage {
+private:
+ unsigned char _id[DHT_ID_LENGTH];
+public:
+ DHTPingReplyMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const unsigned char* id,
+ const string& transactionID);
+
+ virtual ~DHTPingReplyMessage();
+
+ virtual void doReceivedAction();
+
+ virtual Dictionary* getResponse();
+
+ virtual string getMessageType() const;
+
+ virtual void validate() const;
+
+ const unsigned char* getRemoteID()
+ {
+ return _id;
+ }
+};
+
+#endif // _D_DHT_PING_REPLY_MESSAGE_H_
diff --git a/src/DHTPingTask.cc b/src/DHTPingTask.cc
new file mode 100644
index 00000000..9f31b388
--- /dev/null
+++ b/src/DHTPingTask.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 "DHTPingTask.h"
+#include "DHTMessageCallbackImpl.h"
+#include "DHTMessage.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTNode.h"
+#include "DHTConstants.h"
+
+DHTPingTask::DHTPingTask(const DHTNodeHandle& remoteNode, size_t numMaxRetry):
+ _remoteNode(remoteNode),
+ _numMaxRetry(numMaxRetry),
+ _numRetry(0),
+ _pingSuccessful(false),
+ _timeout(DHT_MESSAGE_TIMEOUT)
+{}
+
+DHTPingTask::~DHTPingTask() {}
+
+void DHTPingTask::startup()
+{
+ DHTMessageHandle m = _factory->createPingMessage(_remoteNode);
+ _dispatcher->addMessageToQueue(m, _timeout, new DHTMessageCallbackImpl(this));
+}
+
+void DHTPingTask::onReceived(const DHTMessageHandle& message)
+{
+ _pingSuccessful = true;
+ _finished = true;
+}
+
+void DHTPingTask::onTimeout(const DHTNodeHandle& node)
+{
+ ++_numRetry;
+ if(_numRetry >= _numMaxRetry) {
+ _pingSuccessful = false;
+ _finished = true;
+ } else {
+ DHTMessageHandle m = _factory->createPingMessage(_remoteNode);
+ _dispatcher->addMessageToQueue(m, _timeout, new DHTMessageCallbackImpl(this));
+ }
+}
+
+bool DHTPingTask::isPingSuccessful() const
+{
+ return _pingSuccessful;
+}
diff --git a/src/DHTPingTask.h b/src/DHTPingTask.h
new file mode 100644
index 00000000..7e84cbc3
--- /dev/null
+++ b/src/DHTPingTask.h
@@ -0,0 +1,71 @@
+/* <!-- 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_DHT_PING_TASK_H_
+#define _D_DHT_PING_TASK_H_
+
+#include "DHTAbstractTask.h"
+#include "DHTMessageCallbackListener.h"
+
+class DHTPingTask:public DHTAbstractTask, public DHTMessageCallbackListener {
+protected:
+ DHTNodeHandle _remoteNode;
+
+ size_t _numMaxRetry;
+
+ size_t _numRetry;
+
+ bool _pingSuccessful;
+
+ time_t _timeout;
+public:
+ DHTPingTask(const DHTNodeHandle& remoteNode, size_t numMaxRetry = 0);
+
+ virtual ~DHTPingTask();
+
+ virtual void startup();
+
+ virtual void onReceived(const DHTMessageHandle& message);
+
+ virtual void onTimeout(const DHTNodeHandle& node);
+
+ void setTimeout(time_t timeout)
+ {
+ _timeout = timeout;
+ }
+
+ bool isPingSuccessful() const;
+};
+
+#endif // _D_DHT_PING_TASK_H_
diff --git a/src/DHTQueryMessage.cc b/src/DHTQueryMessage.cc
new file mode 100644
index 00000000..a6862230
--- /dev/null
+++ b/src/DHTQueryMessage.cc
@@ -0,0 +1,70 @@
+/* <!-- 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 "DHTQueryMessage.h"
+#include "DHTNode.h"
+#include "Util.h"
+#include "Data.h"
+
+DHTQueryMessage::DHTQueryMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTAbstractMessage(localNode, remoteNode, transactionID) {}
+
+DHTQueryMessage::~DHTQueryMessage() {}
+
+string DHTQueryMessage::getType() const
+{
+ return "q";
+}
+
+void DHTQueryMessage::fillMessage(Dictionary* message)
+{
+ message->put("q", new Data(getMessageType()));
+ message->put("a", getArgument());
+}
+
+bool DHTQueryMessage::isReply() const
+{
+ return false;
+}
+
+string DHTQueryMessage::toString() const
+{
+ return "dht query "+getMessageType()+
+ " TransactionID="+Util::toHex(_transactionID)+
+ " Remote:"+
+ _remoteNode->getIPAddress()+":"+Util::itos(_remoteNode->getPort())+
+ ", id="+Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH);
+}
diff --git a/src/DHTQueryMessage.h b/src/DHTQueryMessage.h
new file mode 100644
index 00000000..29057f67
--- /dev/null
+++ b/src/DHTQueryMessage.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_DHT_QUERY_MESSAGE_H_
+#define _D_DHT_QUERY_MESSAGE_H_
+
+#include "DHTAbstractMessage.h"
+
+class DHTQueryMessage:public DHTAbstractMessage {
+public:
+ DHTQueryMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID = "");
+
+ virtual ~DHTQueryMessage();
+
+ virtual string getType() const;
+
+ virtual void fillMessage(Dictionary* message);
+
+ virtual Dictionary* getArgument() = 0;
+
+ virtual bool isReply() const;
+
+ virtual string toString() const;
+};
+
+#endif // _D_DHT_QUERY_MESSAGE_H_
diff --git a/src/DHTRegistry.cc b/src/DHTRegistry.cc
new file mode 100644
index 00000000..7210c0b3
--- /dev/null
+++ b/src/DHTRegistry.cc
@@ -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 --> */
+#include "DHTRegistry.h"
+#include "DHTNode.h"
+#include "DHTRoutingTable.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTracker.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageReceiver.h"
+#include "DHTMessageFactory.h"
+
+DHTNodeHandle DHTRegistry::_localNode = 0;
+
+DHTRoutingTableHandle DHTRegistry::_routingTable = 0;
+
+DHTTaskQueueHandle DHTRegistry::_taskQueue = 0;
+
+DHTTaskFactoryHandle DHTRegistry::_taskFactory = 0;
+
+DHTPeerAnnounceStorageHandle DHTRegistry::_peerAnnounceStorage = 0;
+
+DHTTokenTrackerHandle DHTRegistry::_tokenTracker = 0;
+
+DHTMessageDispatcherHandle DHTRegistry::_messageDispatcher = 0;
+
+DHTMessageReceiverHandle DHTRegistry::_messageReceiver = 0;
+
+DHTMessageFactoryHandle DHTRegistry::_messageFactory = 0;
+
+void DHTRegistry::clear()
+{
+ _localNode = 0;
+ _routingTable = 0;
+ _taskQueue = 0;
+ _taskFactory = 0;
+ _peerAnnounceStorage = 0;
+ _tokenTracker = 0;
+ _messageDispatcher = 0;
+ _messageReceiver = 0;
+ _messageFactory = 0;
+}
diff --git a/src/DHTRegistry.h b/src/DHTRegistry.h
new file mode 100644
index 00000000..2962b4ee
--- /dev/null
+++ b/src/DHTRegistry.h
@@ -0,0 +1,74 @@
+/* <!-- 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_DHT_REGISTRY_H_
+#define _D_DHT_REGISTRY_H_
+
+#include "common.h"
+#include "DHTNodeDecl.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+#include "DHTPeerAnnounceStorageDecl.h"
+#include "DHTTokenTrackerDecl.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageReceiverDecl.h"
+#include "DHTMessageFactoryDecl.h"
+
+class DHTRegistry {
+public:
+ static DHTNodeHandle _localNode;
+
+ static DHTRoutingTableHandle _routingTable;
+
+ static DHTTaskQueueHandle _taskQueue;
+
+ static DHTTaskFactoryHandle _taskFactory;
+
+ static DHTPeerAnnounceStorageHandle _peerAnnounceStorage;
+
+ static DHTTokenTrackerHandle _tokenTracker;
+
+ static DHTMessageDispatcherHandle _messageDispatcher;
+
+ static DHTMessageReceiverHandle _messageReceiver;
+
+ static DHTMessageFactoryHandle _messageFactory;
+
+ static void clear();
+private:
+ DHTRegistry();
+};
+
+#endif // _D_DHT_REGISTRY_H_
diff --git a/src/DHTReplaceNodeTask.cc b/src/DHTReplaceNodeTask.cc
new file mode 100644
index 00000000..16d5254d
--- /dev/null
+++ b/src/DHTReplaceNodeTask.cc
@@ -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 --> */
+#include "DHTReplaceNodeTask.h"
+#include "DHTBucket.h"
+#include "DHTNode.h"
+#include "DHTMessage.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageCallbackImpl.h"
+#include "Logger.h"
+
+DHTReplaceNodeTask::DHTReplaceNodeTask(const DHTBucketHandle& bucket,
+ const DHTNodeHandle& newNode):
+ _bucket(bucket),
+ _newNode(newNode),
+ _numRetry(0),
+ _timeout(DHT_MESSAGE_TIMEOUT)
+{}
+
+DHTReplaceNodeTask::~DHTReplaceNodeTask() {}
+
+void DHTReplaceNodeTask::startup()
+{
+ sendMessage();
+}
+
+void DHTReplaceNodeTask::sendMessage()
+{
+ DHTNodeHandle questionableNode = _bucket->getLRUQuestionableNode();
+ if(questionableNode.isNull()) {
+ _finished = true;
+ } else {
+ DHTMessageHandle m = _factory->createPingMessage(questionableNode);
+ _dispatcher->addMessageToQueue(m, _timeout, new DHTMessageCallbackImpl(this));
+ }
+}
+
+void DHTReplaceNodeTask::onReceived(const DHTMessageHandle& message)
+{
+ _logger->info("ReplaceNode: Ping reply received from %s.",
+ message->getRemoteNode()->toString().c_str());
+ _finished = true;
+}
+
+void DHTReplaceNodeTask::onTimeout(const DHTNodeHandle& node)
+{
+ ++_numRetry;
+ if(_numRetry >= MAX_RETRY) {
+ _logger->info("ReplaceNode: Ping failed %u times. Replace %s with %s.",
+ _numRetry, node->toString().c_str(), _newNode->toString().c_str());
+ node->markBad();
+ _bucket->addNode(_newNode);
+ _finished = true;
+ } else {
+ _logger->info("ReplaceNode: Ping reply timeout from %s. Try once more.",
+ node->toString().c_str());
+ sendMessage();
+ }
+}
diff --git a/src/DHTReplaceNodeTask.h b/src/DHTReplaceNodeTask.h
new file mode 100644
index 00000000..812c3216
--- /dev/null
+++ b/src/DHTReplaceNodeTask.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_DHT_REPLACE_NODE_TASK_H_
+#define _D_DHT_REPLACE_NODE_TASK_H_
+
+#include "DHTAbstractTask.h"
+#include "DHTMessageCallbackListener.h"
+#include "DHTBucketDecl.h"
+
+class DHTReplaceNodeTask:public DHTAbstractTask, public DHTMessageCallbackListener {
+private:
+ DHTBucketHandle _bucket;
+
+ DHTNodeHandle _newNode;
+
+ static const size_t MAX_RETRY = 2;
+
+ size_t _numRetry;
+
+ time_t _timeout;
+
+ void sendMessage();
+public:
+ DHTReplaceNodeTask(const DHTBucketHandle& bucket, const DHTNodeHandle& newNode);
+
+ virtual ~DHTReplaceNodeTask();
+
+ virtual void startup();
+
+ virtual void onReceived(const DHTMessageHandle& message);
+
+ virtual void onTimeout(const DHTNodeHandle& node);
+};
+
+#endif // _D_DHT_REPLACE_NODE_TASK_H_
diff --git a/src/DHTResponseMessage.cc b/src/DHTResponseMessage.cc
new file mode 100644
index 00000000..6c9f4734
--- /dev/null
+++ b/src/DHTResponseMessage.cc
@@ -0,0 +1,69 @@
+/* <!-- 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 "DHTResponseMessage.h"
+#include "DHTNode.h"
+#include "Util.h"
+#include "Data.h"
+
+DHTResponseMessage::DHTResponseMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID):
+ DHTAbstractMessage(localNode, remoteNode, transactionID) {}
+
+DHTResponseMessage::~DHTResponseMessage() {}
+
+string DHTResponseMessage::getType() const
+{
+ return "r";
+}
+
+void DHTResponseMessage::fillMessage(Dictionary* message)
+{
+ message->put("r", getResponse());
+}
+
+bool DHTResponseMessage::isReply() const
+{
+ return true;
+}
+
+string DHTResponseMessage::toString() const
+{
+ return "dht response "+getMessageType()+
+ " TransactionID="+Util::toHex(_transactionID)+
+ " Remote:"+
+ _remoteNode->getIPAddress()+":"+Util::itos(_remoteNode->getPort())+
+ ", id="+Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH);
+}
diff --git a/src/DHTResponseMessage.h b/src/DHTResponseMessage.h
new file mode 100644
index 00000000..a41335ea
--- /dev/null
+++ b/src/DHTResponseMessage.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_DHT_RESPONSE_MESSAGE_H_
+#define _D_DHT_RESPONSE_MESSAGE_H_
+
+#include "DHTAbstractMessage.h"
+
+class DHTResponseMessage:public DHTAbstractMessage {
+public:
+ DHTResponseMessage(const DHTNodeHandle& localNode,
+ const DHTNodeHandle& remoteNode,
+ const string& transactionID);
+
+ virtual ~DHTResponseMessage();
+
+ virtual string getType() const;
+
+ virtual void fillMessage(Dictionary* message);
+
+ virtual Dictionary* getResponse() = 0;
+
+ virtual bool isReply() const;
+
+ virtual string toString() const;
+};
+
+#endif // _D_DHT_RESPONSE_MESSAGE_H_
diff --git a/src/DHTRoutingTable.cc b/src/DHTRoutingTable.cc
new file mode 100644
index 00000000..bbf6e1f2
--- /dev/null
+++ b/src/DHTRoutingTable.cc
@@ -0,0 +1,171 @@
+/* <!-- 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 "DHTRoutingTable.h"
+#include "DHTNode.h"
+#include "DHTBucket.h"
+#include "Util.h"
+#include "LogFactory.h"
+#include "BNode.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTask.h"
+
+DHTRoutingTable::DHTRoutingTable(const DHTNodeHandle& localNode):
+ _localNode(localNode),
+ _root(new BNode(new DHTBucket(localNode))),
+ _numBucket(1),
+ _taskQueue(0),
+ _taskFactory(0),
+ _logger(LogFactory::getInstance())
+{}
+
+DHTRoutingTable::~DHTRoutingTable()
+{
+ delete _root;
+}
+
+bool DHTRoutingTable::addNode(const DHTNodeHandle& node)
+{
+ return addNode(node, false);
+}
+
+bool DHTRoutingTable::addGoodNode(const DHTNodeHandle& node)
+{
+ return addNode(node, true);
+}
+
+bool DHTRoutingTable::addNode(const DHTNodeHandle& node, bool good)
+{
+ _logger->debug("Trying to add node:%s", node->toString().c_str());
+ BNode* bnode = BNode::findBNodeFor(_root, node->getID());
+ DHTBucketHandle bucket = bnode->getBucket();
+ while(1) {
+ if(bucket->addNode(node)) {
+ _logger->debug("Added DHTNode.");
+ return true;
+ } else if(bucket->splitAllowed()) {
+ _logger->debug("Splitting bucket. Range:%s-%s",
+ Util::toHex(bucket->getMinID(), DHT_ID_LENGTH).c_str(),
+ Util::toHex(bucket->getMaxID(), DHT_ID_LENGTH).c_str());
+ DHTBucketHandle r = bucket->split();
+
+ bnode->setBucket(0);
+ BNode* lbnode = new BNode(bucket);
+ BNode* rbnode = new BNode(r);
+ bnode->setLeft(lbnode);
+ bnode->setRight(rbnode);
+ ++_numBucket;
+
+ if(r->isInRange(node)) {
+ bucket = r;
+ bnode = rbnode;
+ } else {
+ bnode = lbnode;
+ }
+ } else {
+ if(good && bucket->containsQuestionableNode()) {
+ _logger->debug("Issuing ReplaceNodeTask: new node=%s", node->toString().c_str());
+ _taskQueue->addImmediateTask(_taskFactory->createReplaceNodeTask(bucket, node));
+ }
+ return false;
+ }
+ }
+ return false;
+}
+
+DHTNodes DHTRoutingTable::getClosestKNodes(const unsigned char* key) const
+{
+ return BNode::findClosestKNodes(_root, key);
+}
+
+size_t DHTRoutingTable::countBucket() const
+{
+ return _numBucket;
+}
+
+void DHTRoutingTable::showBuckets() const
+{/*
+ for(DHTBuckets::const_iterator itr = _buckets.begin(); itr != _buckets.end(); ++itr) {
+ cerr << "prefix = " << (*itr)->getPrefixLength() << ", "
+ << "nodes = " << (*itr)->countNode() << endl;
+ }
+ */
+}
+
+DHTBucketHandle DHTRoutingTable::getBucketFor(const unsigned char* nodeID) const
+{
+ return BNode::findBucketFor(_root, nodeID);
+}
+
+DHTBucketHandle DHTRoutingTable::getBucketFor(const DHTNodeHandle& node) const
+{
+ return getBucketFor(node->getID());
+}
+
+DHTNodeHandle DHTRoutingTable::getNode(const unsigned char* nodeID, const string& ipaddr, uint16_t port) const
+{
+ DHTBucketHandle bucket = getBucketFor(nodeID);
+ return bucket->getNode(nodeID, ipaddr, port);
+}
+
+void DHTRoutingTable::dropNode(const DHTNodeHandle& node)
+{
+ getBucketFor(node)->dropNode(node);
+}
+/*
+void DHTRoutingTable::moveBucketHead(const DHTNodeHandle& node)
+{
+ getBucketFor(node)->moveToHead(node);
+}
+*/
+void DHTRoutingTable::moveBucketTail(const DHTNodeHandle& node)
+{
+ getBucketFor(node)->moveToTail(node);
+}
+
+DHTBuckets DHTRoutingTable::getBuckets() const
+{
+ return BNode::enumerateBucket(_root);
+}
+
+void DHTRoutingTable::setTaskQueue(const DHTTaskQueueHandle& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTRoutingTable::setTaskFactory(const DHTTaskFactoryHandle& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
diff --git a/src/DHTRoutingTable.h b/src/DHTRoutingTable.h
new file mode 100644
index 00000000..7afa9209
--- /dev/null
+++ b/src/DHTRoutingTable.h
@@ -0,0 +1,97 @@
+/* <!-- 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_DHT_ROUTING_TABLE_H_
+#define _D_DHT_ROUTING_TABLE_H_
+
+#include "common.h"
+#include "DHTBucketDecl.h"
+#include "DHTNodeDecl.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
+
+class BNode;
+
+class Logger;
+
+class DHTRoutingTable {
+private:
+ DHTNodeHandle _localNode;
+
+ BNode* _root;
+
+ size_t _numBucket;
+
+ DHTTaskQueueHandle _taskQueue;
+
+ DHTTaskFactoryHandle _taskFactory;
+
+ const Logger* _logger;
+
+ bool addNode(const DHTNodeHandle& node, bool good);
+public:
+ DHTRoutingTable(const DHTNodeHandle& localNode);
+
+ ~DHTRoutingTable();
+
+ bool addNode(const DHTNodeHandle& node);
+
+ bool addGoodNode(const DHTNodeHandle& node);
+
+ DHTNodes getClosestKNodes(const unsigned char* key) const;
+
+ size_t countBucket() const;
+
+ void showBuckets() const;
+
+ void dropNode(const DHTNodeHandle& node);
+
+ void moveBucketHead(const DHTNodeHandle& node);
+
+ void moveBucketTail(const DHTNodeHandle& node);
+
+ DHTBucketHandle getBucketFor(const unsigned char* nodeID) const;
+
+ DHTBucketHandle getBucketFor(const DHTNodeHandle& node) const;
+
+ DHTNodeHandle getNode(const unsigned char* id, const string& ipaddr, uint16_t port) const;
+
+ DHTBuckets getBuckets() const;
+
+ void setTaskQueue(const DHTTaskQueueHandle& taskQueue);
+
+ void setTaskFactory(const DHTTaskFactoryHandle& taskFactory);
+};
+
+#endif // _D_DHT_ROUTING_TABLE_H_
diff --git a/src/DHTRoutingTableDecl.h b/src/DHTRoutingTableDecl.h
new file mode 100644
index 00000000..517dbf27
--- /dev/null
+++ b/src/DHTRoutingTableDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_ROUTING_TABLE_DECL_H_
+#define _D_DHT_ROUTING_TABLE_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTRoutingTable;
+typedef SharedHandle<DHTRoutingTable> DHTRoutingTableHandle;
+
+#endif // _D_DHT_ROUTING_TABLE_DECL_H_
diff --git a/src/DHTRoutingTableDeserializer.cc b/src/DHTRoutingTableDeserializer.cc
new file mode 100644
index 00000000..17b981f4
--- /dev/null
+++ b/src/DHTRoutingTableDeserializer.cc
@@ -0,0 +1,134 @@
+/* <!-- 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 "DHTRoutingTableDeserializer.h"
+#include "DHTNode.h"
+#include "DHTConstants.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+#include <arpa/inet.h>
+#include <cerrno>
+#include <cstring>
+#include <istream>
+
+DHTRoutingTableDeserializer::DHTRoutingTableDeserializer():
+ _localNode(0) {}
+
+DHTRoutingTableDeserializer::~DHTRoutingTableDeserializer() {}
+
+DHTNodeHandle DHTRoutingTableDeserializer::getLocalNode() const
+{
+ return _localNode;
+}
+
+const DHTNodes& DHTRoutingTableDeserializer::getNodes() const
+{
+ return _nodes;
+}
+
+void DHTRoutingTableDeserializer::deserialize(istream& in)
+{
+ try {
+ char header[8];
+ memset(header, 0, sizeof(header));
+ // magic
+ header[0] = 0xa1;
+ header[1] = 0xa2;
+ // format ID
+ header[2] = 0x02;
+ // version
+ header[6] = 0;
+ header[7] = 0x01;
+
+ char zero[8];
+ memset(zero, 0, sizeof(zero));
+
+ char buf[26];
+ // header
+ in.read(buf, 8);
+ if(memcmp(header, buf, 8) != 0) {
+ throw new DlAbortEx("Failed to load DHT routing table. cause:%s",
+ "bad header");
+ }
+ // time
+ in.read(buf, 4);
+ _serializedTime.setTimeInSec(ntohl(*reinterpret_cast<uint32_t*>(buf)));
+ // 4bytes reserved
+ in.read(buf, 4);
+
+ // localnode
+ // 8bytes reserved
+ in.read(buf, 8);
+ // localnode ID
+ in.read(buf, DHT_ID_LENGTH);
+ DHTNodeHandle localNode = new DHTNode(reinterpret_cast<const unsigned char*>(buf));
+ // 4bytes reserved
+ in.read(buf, 4);
+
+ // number of nodes
+ in.read(buf, 4);
+ uint32_t numNodes = ntohl(*reinterpret_cast<uint32_t*>(buf));
+ // 4bytes reserved
+ in.read(buf, 4);
+
+ // nodes
+ for(size_t i = 0; i < numNodes; ++i) {
+ // 6bytes compact peer info
+ in.read(buf, 6);
+ if(memcmp(zero, buf, 6) == 0) {
+ // skip this entry
+ in.read(buf, 26);
+ continue;
+ }
+ pair<string, uint16_t> peer = PeerMessageUtil::unpackcompact(buf);
+ // 2bytes reserved
+ in.read(buf, 2);
+ // localnode ID
+ in.read(buf, DHT_ID_LENGTH);
+
+ DHTNodeHandle node = new DHTNode(reinterpret_cast<const unsigned char*>(buf));
+ node->setIPAddress(peer.first);
+ node->setPort(peer.second);
+ // 4bytes reserved
+ in.read(buf, 4);
+
+ _nodes.push_back(node);
+ }
+ _localNode = localNode;
+ } catch(ios::failure const& exception) {
+ _nodes.clear();
+ throw new DlAbortEx("Failed to load DHT routing table. cause:%s",
+ strerror(errno));
+ }
+}
diff --git a/src/DHTRoutingTableDeserializer.h b/src/DHTRoutingTableDeserializer.h
new file mode 100644
index 00000000..e3122f55
--- /dev/null
+++ b/src/DHTRoutingTableDeserializer.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_DHT_ROUTING_TABLE_DESERIALIZER_H_
+#define _D_DHT_ROUTING_TABLE_DESERIALIZER_H_
+
+#include "common.h"
+#include "DHTNodeDecl.h"
+#include "TimeA2.h"
+#include <iosfwd>
+
+class DHTRoutingTableDeserializer {
+private:
+ DHTNodeHandle _localNode;
+
+ DHTNodes _nodes;
+
+ Time _serializedTime;
+public:
+ DHTRoutingTableDeserializer();
+
+ ~DHTRoutingTableDeserializer();
+
+ DHTNodeHandle getLocalNode() const;
+
+ const DHTNodes& getNodes() const;
+
+ Time getSerializedTime() const
+ {
+ return _serializedTime;
+ }
+
+ void deserialize(istream& in);
+};
+
+#endif // _D_DHT_ROUTING_TABLE_DESERIALIZER_H_
diff --git a/src/DHTRoutingTableSerializer.cc b/src/DHTRoutingTableSerializer.cc
new file mode 100644
index 00000000..cda73ef9
--- /dev/null
+++ b/src/DHTRoutingTableSerializer.cc
@@ -0,0 +1,116 @@
+/* <!-- 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 "DHTRoutingTableSerializer.h"
+#include "DHTNode.h"
+#include "DlAbortEx.h"
+#include "DHTConstants.h"
+#include "PeerMessageUtil.h"
+#include <arpa/inet.h>
+#include <cerrno>
+#include <cstring>
+#include <ostream>
+
+DHTRoutingTableSerializer::DHTRoutingTableSerializer():_localNode(0) {}
+
+DHTRoutingTableSerializer::~DHTRoutingTableSerializer() {}
+
+void DHTRoutingTableSerializer::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
+
+void DHTRoutingTableSerializer::setNodes(const DHTNodes& nodes)
+{
+ _nodes = nodes;
+}
+
+void DHTRoutingTableSerializer::serialize(ostream& o)
+{
+ char header[8];
+ memset(header, 0, sizeof(header));
+ // magic
+ header[0] = 0xa1;
+ header[1] = 0xa2;
+ // format ID
+ header[2] = 0x02;
+ // version
+ header[6] = 0;
+ header[7] = 0x01;
+
+ char zero[8];
+ memset(zero, 0, sizeof(zero));
+ try {
+ o.write(header, 8);
+ // write save date
+ uint32_t ntime = htonl(Time().getTime());
+ o.write(reinterpret_cast<const char*>(&ntime), sizeof(uint32_t));
+ // 4bytes reserved
+ o.write(zero, 4);
+
+ // localnode
+ // 8bytes reserved
+ o.write(zero, 8);
+ // 20bytes localnode ID
+ o.write(reinterpret_cast<const char*>(_localNode->getID()), DHT_ID_LENGTH);
+ // 4bytes reserved
+ o.write(zero, 4);
+
+ // number of nodes
+ uint32_t numNodes = htonl(_nodes.size());
+ o.write(reinterpret_cast<const char*>(&numNodes), sizeof(uint32_t));
+ // 4bytes reserved
+ o.write(zero, 4);
+
+ // nodes
+ for(DHTNodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ const DHTNodeHandle& node = *i;
+ // 6bytes: write IP address + port in Compact IP-address/port info form.
+ char compactPeer[6];
+ if(!PeerMessageUtil::createcompact(compactPeer, node->getIPAddress(), node->getPort())) {
+ memset(compactPeer, 0, 6);
+ }
+ o.write(compactPeer, 6);
+ // 2bytes reserved
+ o.write(zero, 2);
+ // 20bytes: node ID
+ o.write(reinterpret_cast<const char*>(node->getID()), DHT_ID_LENGTH);
+ // 4bytes reserved
+ o.write(zero, 4);
+ }
+ } catch(ios::failure const& exception) {
+ throw new DlAbortEx("Failed to save DHT routing table. cause:%s",
+ strerror(errno));
+ }
+}
diff --git a/src/DHTRoutingTableSerializer.h b/src/DHTRoutingTableSerializer.h
new file mode 100644
index 00000000..9121379d
--- /dev/null
+++ b/src/DHTRoutingTableSerializer.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_DHT_ROUTING_TABLE_SERIALIZER_H_
+#define _D_DHT_ROUTING_TABLE_SERIALIZER_H_
+
+#include "common.h"
+#include "DHTNodeDecl.h"
+#include <iosfwd>
+
+class DHTRoutingTableSerializer {
+private:
+ DHTNodeHandle _localNode;
+
+ DHTNodes _nodes;
+public:
+ DHTRoutingTableSerializer();
+
+ ~DHTRoutingTableSerializer();
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+
+ void setNodes(const DHTNodes& nodes);
+
+ void serialize(ostream& o);
+};
+
+#endif // _D_DHT_ROUTING_TABLE_SERIALIZER_H_
diff --git a/src/DHTSetup.cc b/src/DHTSetup.cc
new file mode 100644
index 00000000..d1708921
--- /dev/null
+++ b/src/DHTSetup.cc
@@ -0,0 +1,233 @@
+/* <!-- 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 "DHTSetup.h"
+#include "LogFactory.h"
+#include "Util.h"
+#include "DHTNode.h"
+#include "DHTConnectionImpl.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageFactoryImpl.h"
+#include "DHTMessageTracker.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageReceiver.h"
+#include "DHTTaskQueueImpl.h"
+#include "DHTTaskFactoryImpl.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTracker.h"
+#include "DHTInteractionCommand.h"
+#include "DHTTokenUpdateCommand.h"
+#include "DHTBucketRefreshCommand.h"
+#include "DHTPeerAnnounceCommand.h"
+#include "DHTEntryPointNameResolveCommand.h"
+#include "DHTAutoSaveCommand.h"
+#include "DHTTask.h"
+#include "DHTRoutingTableDeserializer.h"
+#include "DHTRegistry.h"
+#include "CUIDCounter.h"
+#include "prefs.h"
+#include "Option.h"
+#include "DlAbortEx.h"
+#include "RecoverableException.h"
+#include <fstream>
+
+size_t DHTSetup::_initialized = 0;
+
+DHTSetup::DHTSetup():_logger(LogFactory::getInstance()) {}
+
+DHTSetup::~DHTSetup() {}
+
+Commands DHTSetup::setup(DownloadEngine* e, const Option* option)
+{
+ if(_initialized) {
+ return Commands();
+ }
+ try {
+ // load routing table and localnode id here
+
+ DHTNodeHandle localNode = 0;
+
+ DHTRoutingTableDeserializer deserializer;
+ string dhtFile = option->get(PREF_DHT_FILE_PATH);
+ if(File(dhtFile).isFile()) {
+ try {
+ ifstream in(dhtFile.c_str());
+ in.exceptions(ios::failbit);
+ deserializer.deserialize(in);
+ localNode = deserializer.getLocalNode();
+ } catch(RecoverableException* e) {
+ _logger->error("Exception caught while loading DHT routing table from %s",
+ e, dhtFile.c_str());
+ delete e;
+ }
+ }
+ if(localNode.isNull()) {
+ localNode = new DHTNode();
+ }
+
+ SharedHandle<DHTConnectionImpl> connection = new DHTConnectionImpl();
+ {
+ IntSequence seq = Util::parseIntRange(option->get(PREF_DHT_LISTEN_PORT));
+ uint16_t port = connection->bind(seq);
+ if(port == 0) {
+ throw new DlAbortEx("Error occurred while binding port for DHT");
+ }
+ localNode->setPort(port);
+ }
+ _logger->debug("Initialized local node ID=%s",
+ Util::toHex(localNode->getID(), DHT_ID_LENGTH).c_str());
+
+ DHTRoutingTableHandle routingTable = new DHTRoutingTable(localNode);
+
+ SharedHandle<DHTMessageFactoryImpl> factory = new DHTMessageFactoryImpl();
+
+ DHTMessageTrackerHandle tracker = new DHTMessageTracker();
+
+ DHTMessageDispatcherHandle dispatcher = new DHTMessageDispatcher(tracker);
+
+ DHTMessageReceiverHandle receiver = new DHTMessageReceiver(tracker);
+
+ DHTTaskQueueHandle taskQueue = new DHTTaskQueueImpl();
+
+ SharedHandle<DHTTaskFactoryImpl> taskFactory = new DHTTaskFactoryImpl();
+
+ DHTPeerAnnounceStorageHandle peerAnnounceStorage = new DHTPeerAnnounceStorage();
+
+ DHTTokenTrackerHandle tokenTracker = new DHTTokenTracker();
+
+ // wiring up
+ tracker->setRoutingTable(routingTable);
+ tracker->setMessageFactory(factory);
+
+ receiver->setConnection(connection);
+ receiver->setMessageFactory(factory);
+ receiver->setRoutingTable(routingTable);
+
+ taskFactory->setLocalNode(localNode);
+ taskFactory->setRoutingTable(routingTable);
+ taskFactory->setMessageDispatcher(dispatcher);
+ taskFactory->setMessageFactory(factory);
+ taskFactory->setTaskQueue(taskQueue);
+
+ routingTable->setTaskQueue(taskQueue);
+ routingTable->setTaskFactory(taskFactory);
+
+ peerAnnounceStorage->setTaskQueue(taskQueue);
+ peerAnnounceStorage->setTaskFactory(taskFactory);
+
+ factory->setRoutingTable(routingTable);
+ factory->setConnection(connection);
+ factory->setMessageDispatcher(dispatcher);
+ factory->setPeerAnnounceStorage(peerAnnounceStorage);
+ factory->setTokenTracker(tokenTracker);
+ factory->setLocalNode(localNode);
+
+ // assign them into DHTRegistry
+ DHTRegistry::_localNode = localNode;
+ DHTRegistry::_routingTable = routingTable;
+ DHTRegistry::_taskQueue = taskQueue;
+ DHTRegistry::_taskFactory = taskFactory;
+ DHTRegistry::_peerAnnounceStorage = peerAnnounceStorage;
+ DHTRegistry::_tokenTracker = tokenTracker;
+ DHTRegistry::_messageDispatcher = dispatcher;
+ DHTRegistry::_messageReceiver = receiver;
+ DHTRegistry::_messageFactory = factory;
+
+ // add deserialized nodes to routing table
+ const DHTNodes& desnodes = deserializer.getNodes();
+ for(DHTNodes::const_iterator i = desnodes.begin(); i != desnodes.end(); ++i) {
+ routingTable->addNode(*i);
+ }
+ if(!desnodes.empty() && deserializer.getSerializedTime().elapsed(DHT_BUCKET_REFRESH_INTERVAL)) {
+ taskQueue->addPeriodicTask1(taskFactory->createBucketRefreshTask());
+ }
+
+ Commands commands;
+ if(!option->get(PREF_DHT_ENTRY_POINT_HOST).empty()) {
+ {
+ DHTEntryPointNameResolveCommand* command = new DHTEntryPointNameResolveCommand(CUIDCounterSingletonHolder::instance()->newID(), e);
+ command->setTaskQueue(taskQueue);
+ command->setTaskFactory(taskFactory);
+ command->setLocalNode(localNode);
+ commands.push_back(command);
+ }
+ } else {
+ _logger->info("No DHT entry point specified.");
+ }
+ {
+ DHTInteractionCommand* command = new DHTInteractionCommand(CUIDCounterSingletonHolder::instance()->newID(), e);
+ command->setMessageDispatcher(dispatcher);
+ command->setMessageReceiver(receiver);
+ command->setTaskQueue(taskQueue);
+ command->setReadCheckSocket(connection->getSocket());
+ commands.push_back(command);
+ }
+ {
+ DHTTokenUpdateCommand* command = new DHTTokenUpdateCommand(CUIDCounterSingletonHolder::instance()->newID(), e, DHT_TOKEN_UPDATE_INTERVAL);
+ command->setTokenTracker(tokenTracker);
+ commands.push_back(command);
+ }
+ {
+ DHTBucketRefreshCommand* command = new DHTBucketRefreshCommand(CUIDCounterSingletonHolder::instance()->newID(), e, DHT_BUCKET_REFRESH_CHECK_INTERVAL);
+ command->setTaskQueue(taskQueue);
+ command->setRoutingTable(routingTable);
+ command->setTaskFactory(taskFactory);
+ commands.push_back(command);
+ }
+ {
+ DHTPeerAnnounceCommand* command = new DHTPeerAnnounceCommand(CUIDCounterSingletonHolder::instance()->newID(), e, DHT_PEER_ANNOUNCE_CHECK_INTERVAL);
+ command->setPeerAnnounceStorage(peerAnnounceStorage);
+ commands.push_back(command);
+ }
+ {
+ DHTAutoSaveCommand* command = new DHTAutoSaveCommand(CUIDCounterSingletonHolder::instance()->newID(), e, 30*60);
+ command->setLocalNode(localNode);
+ command->setRoutingTable(routingTable);
+ commands.push_back(command);
+ }
+ _initialized = true;
+
+ return commands;
+ } catch(RecoverableException* e) {
+ _logger->error("Exception caught while initializing DHT functionality. DHT is disabled.", e);
+ delete e;
+ DHTRegistry::clear();
+ return Commands();
+ }
+}
+
+bool DHTSetup::initialized()
+{
+ return _initialized;
+}
diff --git a/src/DHTSetup.h b/src/DHTSetup.h
new file mode 100644
index 00000000..eb01eb98
--- /dev/null
+++ b/src/DHTSetup.h
@@ -0,0 +1,62 @@
+/* <!-- 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_DHT_SETUP_H_
+#define _D_DHT_SETUP_H_
+
+#include "common.h"
+
+class Logger;
+class Option;
+class DownloadEngine;
+class Command;
+typedef deque<Command*> Commands;
+
+class DHTSetup {
+private:
+ static size_t _initialized;
+
+ const Logger* _logger;
+
+public:
+ DHTSetup();
+
+ ~DHTSetup();
+
+ Commands setup(DownloadEngine* e, const Option* option);
+
+ static bool initialized();
+};
+
+#endif // _D_DHT_SETUP_H_
diff --git a/src/DHTTask.h b/src/DHTTask.h
new file mode 100644
index 00000000..59bac5a1
--- /dev/null
+++ b/src/DHTTask.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_DHT_TASK_H_
+#define _D_DHT_TASK_H_
+
+#include "common.h"
+#include "DHTTaskDecl.h"
+
+class DHTTask {
+public:
+ virtual ~DHTTask() {}
+
+ virtual void startup() = 0;
+
+ virtual bool finished() = 0;
+};
+
+#endif // _D_DHT_TASK_H_
diff --git a/src/DHTTaskDecl.h b/src/DHTTaskDecl.h
new file mode 100644
index 00000000..c837c8fe
--- /dev/null
+++ b/src/DHTTaskDecl.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_DHT_TASK_DECL_H_
+#define _D_DHT_TASK_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class DHTTask;
+typedef SharedHandle<DHTTask> DHTTaskHandle;
+typedef std::deque<DHTTaskHandle> DHTTasks;
+
+#endif // _D_DHT_TASK_DECL_H_
diff --git a/src/DHTTaskFactory.h b/src/DHTTaskFactory.h
new file mode 100644
index 00000000..a603b35d
--- /dev/null
+++ b/src/DHTTaskFactory.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_DHT_TASK_FACTORY_H_
+#define _D_DHT_TASK_FACTORY_H_
+
+#include "common.h"
+#include "DHTTaskFactoryDecl.h"
+#include "DHTTaskDecl.h"
+#include "DHTNodeDecl.h"
+#include "DHTBucketDecl.h"
+#include "BtContextDecl.h"
+
+class DHTTaskFactory {
+public:
+ virtual ~DHTTaskFactory() {}
+
+ virtual DHTTaskHandle createPingTask(const DHTNodeHandle& remoteNode,
+ size_t numRetry = 0) = 0;
+
+ virtual DHTTaskHandle createNodeLookupTask(const unsigned char* targetID) = 0;
+
+ virtual DHTTaskHandle createBucketRefreshTask() = 0;
+
+ virtual DHTTaskHandle createPeerLookupTask(const BtContextHandle& ctx) = 0;
+
+ virtual DHTTaskHandle createPeerAnnounceTask(const unsigned char* infoHash) = 0;
+
+ virtual DHTTaskHandle createReplaceNodeTask(const DHTBucketHandle& bucket,
+ const DHTNodeHandle& newNode) = 0;
+};
+
+#endif // _D_DHT_TASK_FACTORY_H_
diff --git a/src/DHTTaskFactoryDecl.h b/src/DHTTaskFactoryDecl.h
new file mode 100644
index 00000000..a1e442e5
--- /dev/null
+++ b/src/DHTTaskFactoryDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_TASK_FACTORY_DECL_H_
+#define _D_DHT_TASK_FACTORY_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTTaskFactory;
+typedef SharedHandle<DHTTaskFactory> DHTTaskFactoryHandle;
+
+#endif // _D_DHT_TASK_FACTORY_DECL_H_
diff --git a/src/DHTTaskFactoryImpl.cc b/src/DHTTaskFactoryImpl.cc
new file mode 100644
index 00000000..9fd31342
--- /dev/null
+++ b/src/DHTTaskFactoryImpl.cc
@@ -0,0 +1,143 @@
+/* <!-- 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 "DHTTaskFactoryImpl.h"
+#include "DHTNode.h"
+#include "DHTRoutingTable.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageFactory.h"
+#include "DHTTaskQueue.h"
+#include "LogFactory.h"
+#include "DHTPingTask.h"
+#include "DHTNodeLookupTask.h"
+#include "DHTBucketRefreshTask.h"
+#include "DHTPeerLookupTask.h"
+#include "DHTReplaceNodeTask.h"
+#include "Peer.h"
+#include "DHTNodeLookupEntry.h"
+#include "BtContext.h"
+#include "PeerStorage.h"
+#include "BtRuntime.h"
+
+DHTTaskFactoryImpl::DHTTaskFactoryImpl():_localNode(0),
+ _routingTable(0),
+ _dispatcher(0),
+ _factory(0),
+ _taskQueue(0),
+ _logger(LogFactory::getInstance()) {}
+
+DHTTaskFactoryImpl::~DHTTaskFactoryImpl() {}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createPingTask(const DHTNodeHandle& remoteNode,
+ size_t numRetry)
+{
+ SharedHandle<DHTPingTask> task = new DHTPingTask(remoteNode, numRetry);
+ setCommonProperty(task);
+ return task;
+}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createNodeLookupTask(const unsigned char* targetID)
+{
+ SharedHandle<DHTNodeLookupTask> task = new DHTNodeLookupTask(targetID);
+ setCommonProperty(task);
+ return task;
+}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createBucketRefreshTask()
+{
+ SharedHandle<DHTBucketRefreshTask> task = new DHTBucketRefreshTask();
+ setCommonProperty(task);
+ return task;
+}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createPeerLookupTask(const BtContextHandle& ctx)
+{
+ SharedHandle<DHTPeerLookupTask> task = new DHTPeerLookupTask(ctx);
+ setCommonProperty(task);
+ return task;
+}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createPeerAnnounceTask(const unsigned char* infoHash)
+{
+ // TODO
+ return 0;
+}
+
+DHTTaskHandle
+DHTTaskFactoryImpl::createReplaceNodeTask(const DHTBucketHandle& bucket,
+ const DHTNodeHandle& newNode)
+{
+ SharedHandle<DHTReplaceNodeTask> task = new DHTReplaceNodeTask(bucket, newNode);
+ setCommonProperty(task);
+ return task;
+}
+
+void DHTTaskFactoryImpl::setCommonProperty(const DHTAbstractTaskHandle& task)
+{
+ task->setRoutingTable(_routingTable);
+ task->setMessageDispatcher(_dispatcher);
+ task->setMessageFactory(_factory);
+ task->setTaskQueue(_taskQueue);
+ task->setLocalNode(_localNode);
+}
+
+void DHTTaskFactoryImpl::setRoutingTable(const WeakHandle<DHTRoutingTable> routingTable)
+{
+ _routingTable = routingTable;
+}
+
+void DHTTaskFactoryImpl::setMessageDispatcher(const WeakHandle<DHTMessageDispatcher> dispatcher)
+{
+ _dispatcher = dispatcher;
+}
+
+void DHTTaskFactoryImpl::setMessageFactory(const WeakHandle<DHTMessageFactory> factory)
+{
+ _factory = factory;
+}
+
+void DHTTaskFactoryImpl::setTaskQueue(const WeakHandle<DHTTaskQueue> taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DHTTaskFactoryImpl::setLocalNode(const DHTNodeHandle& localNode)
+{
+ _localNode = localNode;
+}
diff --git a/src/DHTTaskFactoryImpl.h b/src/DHTTaskFactoryImpl.h
new file mode 100644
index 00000000..0324f101
--- /dev/null
+++ b/src/DHTTaskFactoryImpl.h
@@ -0,0 +1,94 @@
+/* <!-- 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_DHT_TASK_FACTORY_IMPL_H_
+#define _D_DHT_TASK_FACTORY_IMPL_H_
+
+#include "DHTTaskFactory.h"
+#include "DHTNodeDecl.h"
+#include "DHTRoutingTableDecl.h"
+#include "DHTMessageDispatcherDecl.h"
+#include "DHTMessageFactoryDecl.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTAbstractTaskDecl.h"
+
+class Logger;
+
+class DHTTaskFactoryImpl:public DHTTaskFactory {
+private:
+ DHTNodeHandle _localNode;
+
+ WeakHandle<DHTRoutingTable> _routingTable;
+
+ WeakHandle<DHTMessageDispatcher> _dispatcher;
+
+ WeakHandle<DHTMessageFactory> _factory;
+
+ WeakHandle<DHTTaskQueue> _taskQueue;
+
+ const Logger* _logger;
+
+ void setCommonProperty(const DHTAbstractTaskHandle& task);
+public:
+ DHTTaskFactoryImpl();
+
+ virtual ~DHTTaskFactoryImpl();
+
+ virtual DHTTaskHandle createPingTask(const DHTNodeHandle& remoteNode,
+ size_t numRetry = 0);
+
+ virtual DHTTaskHandle createNodeLookupTask(const unsigned char* targetID);
+
+ virtual DHTTaskHandle createBucketRefreshTask();
+
+ virtual DHTTaskHandle createPeerLookupTask(const BtContextHandle& ctx);
+
+ virtual DHTTaskHandle createPeerAnnounceTask(const unsigned char* infoHash);
+
+ virtual DHTTaskHandle createReplaceNodeTask(const DHTBucketHandle& bucket,
+ const DHTNodeHandle& newNode);
+
+ void setRoutingTable(const WeakHandle<DHTRoutingTable> routingTable);
+
+ void setMessageDispatcher(const WeakHandle<DHTMessageDispatcher> dispatcher);
+
+ void setMessageFactory(const WeakHandle<DHTMessageFactory> factory);
+
+ void setTaskQueue(const WeakHandle<DHTTaskQueue> taskQueue);
+
+ void setLocalNode(const DHTNodeHandle& localNode);
+
+};
+
+#endif // _D_DHT_TASK_FACTORY_IMPL_H_
diff --git a/src/DHTTaskQueue.h b/src/DHTTaskQueue.h
new file mode 100644
index 00000000..46427ba4
--- /dev/null
+++ b/src/DHTTaskQueue.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_DHT_TASK_QUEUE_H_
+#define _D_DHT_TASK_QUEUE_H_
+
+#include "common.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskDecl.h"
+
+class DHTTaskQueue {
+public:
+ virtual ~DHTTaskQueue() {}
+
+ virtual void executeTask() = 0;
+
+ virtual void addPeriodicTask1(const DHTTaskHandle& task) = 0;
+
+ virtual void addPeriodicTask2(const DHTTaskHandle& task) = 0;
+
+ virtual void addImmediateTask(const DHTTaskHandle& task) = 0;
+};
+
+#endif // _D_DHT_TASK_QUEUE_H_
diff --git a/src/DHTTaskQueueDecl.h b/src/DHTTaskQueueDecl.h
new file mode 100644
index 00000000..d8105fbf
--- /dev/null
+++ b/src/DHTTaskQueueDecl.h
@@ -0,0 +1,42 @@
+/* <!-- 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_DHT_TASK_QUEUE_DECL_H_
+#define _D_DHT_TASK_QUEUE_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTTaskQueue;
+typedef SharedHandle<DHTTaskQueue> DHTTaskQueueHandle;
+#endif // _D_DHT_TASK_QUEUE_DECL_H_
diff --git a/src/DHTTaskQueueImpl.cc b/src/DHTTaskQueueImpl.cc
new file mode 100644
index 00000000..85a4e13e
--- /dev/null
+++ b/src/DHTTaskQueueImpl.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 "DHTTaskQueueImpl.h"
+#include "DHTTask.h"
+
+DHTTaskQueueImpl::DHTTaskQueueImpl():_periodicTask1(0),
+ _periodicTask2(0),
+ _immediateTask(0) {}
+
+DHTTaskQueueImpl::~DHTTaskQueueImpl() {}
+
+void DHTTaskQueueImpl::executeTask(DHTTaskHandle& task, DHTTasks& taskQueue)
+{
+ while(1) {
+ if(task.isNull() || task->finished()) {
+ task = 0;
+ if(taskQueue.empty()) {
+ break;
+ }
+ task = taskQueue.front();
+ taskQueue.erase(taskQueue.begin());
+ task->startup();
+ } else {
+ break;
+ }
+ }
+}
+
+void DHTTaskQueueImpl::executeTask()
+{
+ executeTask(_periodicTask1, _periodicTaskQueue1);
+ executeTask(_periodicTask2, _periodicTaskQueue2);
+ executeTask(_immediateTask, _immediateTaskQueue);
+}
+
+void DHTTaskQueueImpl::addPeriodicTask1(const DHTTaskHandle& task)
+{
+ _periodicTaskQueue1.push_back(task);
+}
+
+void DHTTaskQueueImpl::addPeriodicTask2(const DHTTaskHandle& task)
+{
+ _periodicTaskQueue2.push_back(task);
+}
+
+void DHTTaskQueueImpl::addImmediateTask(const DHTTaskHandle& task)
+{
+ _immediateTaskQueue.push_back(task);
+}
diff --git a/src/DHTTaskQueueImpl.h b/src/DHTTaskQueueImpl.h
new file mode 100644
index 00000000..951aa2ba
--- /dev/null
+++ b/src/DHTTaskQueueImpl.h
@@ -0,0 +1,70 @@
+/* <!-- 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_DHT_TASK_QUEUE_IMPL_H_
+#define _D_DHT_TASK_QUEUE_IMPL_H_
+
+#include "DHTTaskQueue.h"
+
+class DHTTaskQueueImpl:public DHTTaskQueue {
+private:
+
+ DHTTaskHandle _periodicTask1;
+
+ DHTTaskHandle _periodicTask2;
+
+ DHTTaskHandle _immediateTask;
+
+ DHTTasks _periodicTaskQueue1;
+
+ DHTTasks _periodicTaskQueue2;
+
+ DHTTasks _immediateTaskQueue;
+
+ void executeTask(DHTTaskHandle& task, DHTTasks& taskQueue);
+public:
+ DHTTaskQueueImpl();
+
+ virtual ~DHTTaskQueueImpl();
+
+ virtual void executeTask();
+
+ virtual void addPeriodicTask1(const DHTTaskHandle& task);
+
+ virtual void addPeriodicTask2(const DHTTaskHandle& task);
+
+ virtual void addImmediateTask(const DHTTaskHandle& task);
+};
+
+#endif // _D_DHT_TASK_QUEUE_IMPL_H_
diff --git a/src/DHTTokenTracker.cc b/src/DHTTokenTracker.cc
new file mode 100644
index 00000000..aaede48a
--- /dev/null
+++ b/src/DHTTokenTracker.cc
@@ -0,0 +1,92 @@
+/* <!-- 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 "DHTTokenTracker.h"
+#include "DHTUtil.h"
+#include "PeerMessageUtil.h"
+#include "DlAbortEx.h"
+#include "DHTConstants.h"
+#include "MessageDigestHelper.h"
+
+DHTTokenTracker::DHTTokenTracker()
+{
+ DHTUtil::generateRandomData(_secret[0], SECRET_SIZE);
+ memcpy(_secret[1], _secret[0], SECRET_SIZE);
+}
+
+DHTTokenTracker::DHTTokenTracker(const char* initialSecret)
+{
+ memcpy(_secret[0], initialSecret, SECRET_SIZE);
+ memcpy(_secret[1], initialSecret, SECRET_SIZE);
+}
+
+DHTTokenTracker::~DHTTokenTracker() {}
+
+string DHTTokenTracker::generateToken(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port,
+ const char* secret) const
+{
+ char src[DHT_ID_LENGTH+6+SECRET_SIZE];
+ if(!PeerMessageUtil::createcompact(src+DHT_ID_LENGTH, ipaddr, port)) {
+ throw new DlAbortEx("Token generation failed: ipaddr=%s, port=%u",
+ ipaddr.c_str(), port);
+ }
+ memcpy(src, infoHash, DHT_ID_LENGTH);
+ memcpy(src+DHT_ID_LENGTH+6, secret, SECRET_SIZE);
+ return MessageDigestHelper::digest("sha1", src, sizeof(src));
+}
+
+string DHTTokenTracker::generateToken(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port) const
+{
+ return generateToken(infoHash, ipaddr, port, _secret[0]);
+}
+
+bool DHTTokenTracker::validateToken(const string& token,
+ const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port) const
+{
+ for(int i = 0; i < 2; ++i) {
+ if(generateToken(infoHash, ipaddr, port, _secret[i]) == token) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void DHTTokenTracker::updateTokenSecret()
+{
+ memcpy(_secret[1], _secret[0], SECRET_SIZE);
+ DHTUtil::generateRandomData(_secret[0], SECRET_SIZE);
+}
diff --git a/src/DHTTokenTracker.h b/src/DHTTokenTracker.h
new file mode 100644
index 00000000..2c510a91
--- /dev/null
+++ b/src/DHTTokenTracker.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_DHT_TOKEN_TRACKER_H_
+#define _D_DHT_TOKEN_TRACKER_H_
+
+#include "common.h"
+#include "DHTTokenTrackerDecl.h"
+
+class DHTTokenTracker {
+private:
+ static const size_t SECRET_SIZE = 4;
+
+ char _secret[2][SECRET_SIZE];
+
+ string generateToken(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port,
+ const char* secret) const;
+public:
+ DHTTokenTracker();
+
+ DHTTokenTracker(const char* initialSecret);
+
+ ~DHTTokenTracker();
+
+ // TODO handle exception thrown by this function.
+ string generateToken(const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port) const;
+
+ bool validateToken(const string& token,
+ const unsigned char* infoHash,
+ const string& ipaddr, uint16_t port) const;
+
+ void updateTokenSecret();
+};
+
+#endif // _D_DHT_TOKEN_TRACKER_H_
diff --git a/src/DHTTokenTrackerDecl.h b/src/DHTTokenTrackerDecl.h
new file mode 100644
index 00000000..a95672e3
--- /dev/null
+++ b/src/DHTTokenTrackerDecl.h
@@ -0,0 +1,43 @@
+/* <!-- 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_DHT_TOKEN_TRACKER_DECL_H_
+#define _D_DHT_TOKEN_TRACKER_DECL_H_
+
+#include "SharedHandle.h"
+
+class DHTTokenTracker;
+typedef SharedHandle<DHTTokenTracker> DHTTokenTrackerHandle;
+
+#endif // _D_DHT_TOKEN_TRACKER_DECL_H_
diff --git a/src/DHTTokenUpdateCommand.cc b/src/DHTTokenUpdateCommand.cc
new file mode 100644
index 00000000..63020169
--- /dev/null
+++ b/src/DHTTokenUpdateCommand.cc
@@ -0,0 +1,70 @@
+/* <!-- 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 "DHTTokenUpdateCommand.h"
+#include "DHTTokenTracker.h"
+#include "SingletonHolder.h"
+#include "DownloadEngine.h"
+#include "RequestGroupMan.h"
+#include "RecoverableException.h"
+#include "message.h"
+
+DHTTokenUpdateCommand::DHTTokenUpdateCommand(int32_t cuid,
+ DownloadEngine* e,
+ time_t interval):
+ TimeBasedCommand(cuid, e, interval),
+ _tokenTracker(0)
+{}
+
+DHTTokenUpdateCommand::~DHTTokenUpdateCommand() {}
+
+void DHTTokenUpdateCommand::preProcess()
+{
+ _exit = _e->_requestGroupMan->downloadFinished() || _e->isHaltRequested();
+}
+
+void DHTTokenUpdateCommand::process()
+{
+ try {
+ _tokenTracker->updateTokenSecret();
+ } catch(RecoverableException* e) {
+ logger->error(EX_EXCEPTION_CAUGHT, e);
+ delete e;
+ }
+}
+
+void DHTTokenUpdateCommand::setTokenTracker(const DHTTokenTrackerHandle& tokenTracker)
+{
+ _tokenTracker = tokenTracker;
+}
diff --git a/src/DHTTokenUpdateCommand.h b/src/DHTTokenUpdateCommand.h
new file mode 100644
index 00000000..1030e843
--- /dev/null
+++ b/src/DHTTokenUpdateCommand.h
@@ -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 --> */
+#ifndef _D_DHT_TOKEN_UPDATE_COMMAND_H_
+#define _D_DHT_TOKEN_UPDATE_COMMAND_H_
+
+#include "TimeBasedCommand.h"
+#include "DHTTokenTrackerDecl.h"
+
+class DHTTokenUpdateCommand:public TimeBasedCommand {
+private:
+ DHTTokenTrackerHandle _tokenTracker;
+public:
+ DHTTokenUpdateCommand(int32_t cuid, DownloadEngine* e, time_t interval);
+
+ virtual ~DHTTokenUpdateCommand();
+
+ virtual void preProcess();
+
+ virtual void process();
+
+ void setTokenTracker(const DHTTokenTrackerHandle& tokenTracker);
+};
+
+#endif // _D_DHT_TOKEN_UPDATE_COMMAND_H_
diff --git a/src/DHTUtil.cc b/src/DHTUtil.cc
new file mode 100644
index 00000000..7c32853e
--- /dev/null
+++ b/src/DHTUtil.cc
@@ -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 --> */
+#include "DHTUtil.h"
+#include "MessageDigestHelper.h"
+#include <fstream>
+#include <iomanip>
+
+void DHTUtil::generateRandomKey(unsigned char* key)
+{
+ char bytes[40];
+ generateRandomData(bytes, sizeof(bytes));
+ MessageDigestHelper::digest(key, 20, "sha1", bytes, sizeof(bytes));
+}
+
+void DHTUtil::generateRandomData(char* data, size_t length)
+{
+ ifstream i("/dev/urandom");
+ i.read(data, length);
+}
+
+void DHTUtil::flipBit(unsigned char* data, size_t length, size_t bitIndex)
+{
+ size_t byteIndex = bitIndex/8;
+ assert(byteIndex <= length);
+ unsigned char mask = 128 >> (bitIndex%8);
+ data[byteIndex] ^= mask;
+}
diff --git a/src/DHTUtil.h b/src/DHTUtil.h
new file mode 100644
index 00000000..9cd59e3b
--- /dev/null
+++ b/src/DHTUtil.h
@@ -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 --> */
+#ifndef _D_DHT_UTIL_H_
+#define _D_DHT_UTIL_H_
+
+#include "common.h"
+
+class DHTUtil {
+public:
+
+ static void generateRandomKey(unsigned char* key);
+
+ static void generateRandomData(char* data, size_t length);
+
+ static void generateRandomData(unsigned char* data, size_t length)
+ {
+ return generateRandomData(reinterpret_cast<char*>(data), length);
+ }
+
+ static void flipBit(unsigned char* data, size_t length, size_t bitIndex);
+
+};
+
+#endif // _D_DHT_UTIL_H_
diff --git a/src/Data.cc b/src/Data.cc
index 0bfc91bd..5767a580 100644
--- a/src/Data.cc
+++ b/src/Data.cc
@@ -36,26 +36,28 @@
#include "MetaEntryVisitor.h"
Data::Data(const char* data, int32_t len, bool number):number(number) {
- if(data == NULL) {
- this->data = NULL;
- this->len = 0;
- } else {
- this->data = new char[len];
- memcpy(this->data, data, len);
- this->len = len;
- }
+ init(data, len);
+}
+
+Data::Data(const unsigned char* data, int32_t len, bool number):number(number) {
+ init(reinterpret_cast<const char*>(data), len);
}
Data::Data(const string& data, bool number):number(number)
{
- if(data.empty()) {
- this->data = 0;
- this->len = 0;
- } else {
- this->data = new char[data.size()];
- memcpy(this->data, data.c_str(), data.size());
- this->len = data.size();
- }
+ init(data.c_str(), data.size());
+}
+
+void Data::init(const char* src, int32_t slen)
+{
+ if(src) {
+ data = new char[slen];
+ memcpy(data, src, slen);
+ len = slen;
+ } else {
+ data = 0;
+ len = 0;
+ }
}
Data::~Data() {
diff --git a/src/Data.h b/src/Data.h
index 03499ea3..4d394c12 100644
--- a/src/Data.h
+++ b/src/Data.h
@@ -45,6 +45,8 @@ private:
int32_t len;
char* data;
bool number;
+
+ void init(const char* data, int32_t len);
public:
/**
* This class stores the copy of data. So caller must take care of freeing
@@ -52,6 +54,8 @@ public:
*/
Data(const char* data, int32_t len, bool number = false);
+ Data(const unsigned char* data, int32_t len, bool number = false);
+
Data(const string& data, bool number = false);
~Data();
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
index cdd35ae9..66b68ce2 100644
--- a/src/DefaultBtInteractive.cc
+++ b/src/DefaultBtInteractive.cc
@@ -48,6 +48,7 @@
#include "UTPexExtensionMessage.h"
#include "DefaultExtensionMessageFactory.h"
#include "BtRegistry.h"
+#include "DHTNode.h"
void DefaultBtInteractive::initiateHandshake() {
BtHandshakeMessageHandle message =
@@ -79,7 +80,10 @@ BtMessageHandle DefaultBtInteractive::receiveHandshake(bool quickReply) {
PEER_OBJECT(btContext, peer)->extensionMessageFactory = factory;
logger->info(MSG_EXTENDED_MESSAGING_ENABLED, cuid);
}
-
+ if(message->isDHTEnabled()) {
+ peer->setDHTEnabled(true);
+ logger->info(MSG_DHT_ENABLED_PEER, cuid);
+ }
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
peer->ipaddr.c_str(), peer->port,
message->toString().c_str());
@@ -100,10 +104,18 @@ void DefaultBtInteractive::doPostHandshakeProcessing() {
addHandshakeExtendedMessageToQueue();
}
addBitfieldMessageToQueue();
+ if(peer->isDHTEnabled() && _dhtEnabled) {
+ addPortMessageToQueue();
+ }
addAllowedFastMessageToQueue();
sendPendingMessage();
}
+void DefaultBtInteractive::addPortMessageToQueue()
+{
+ dispatcher->addMessageToQueue(messageFactory->createPortMessage(_localNode->getPort()));
+}
+
void DefaultBtInteractive::addHandshakeExtendedMessageToQueue()
{
HandshakeExtensionMessageHandle m = new HandshakeExtensionMessage();
@@ -387,3 +399,8 @@ void DefaultBtInteractive::doInteractionProcessing() {
sendPendingMessage();
}
+
+void DefaultBtInteractive::setLocalNode(const WeakHandle<DHTNode>& node)
+{
+ _localNode = node;
+}
diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h
index c0c70077..9247c8ac 100644
--- a/src/DefaultBtInteractive.h
+++ b/src/DefaultBtInteractive.h
@@ -48,6 +48,7 @@
#include "Logger.h"
#include "LogFactory.h"
#include "TimeA2.h"
+#include "DHTNodeDecl.h"
class FloodingStat {
private:
@@ -95,6 +96,7 @@ private:
BtRequestFactoryWeakHandle btRequestFactory;
PeerConnectionWeakHandle peerConnection;
BtMessageFactoryWeakHandle messageFactory;
+ WeakHandle<DHTNode> _localNode;
const Logger* logger;
int32_t allowedFastSetSize;
Time haveCheckPoint;
@@ -106,6 +108,7 @@ private:
int32_t keepAliveInterval;
int32_t maxDownloadSpeedLimit;
bool _utPexEnabled;
+ bool _dhtEnabled;
static const int32_t FLOODING_CHECK_INTERVAL = 5;
@@ -121,6 +124,7 @@ private:
void detectMessageFlooding();
void checkActiveInteraction();
void addPeerExchangeMessage();
+ void addPortMessageToQueue();
public:
DefaultBtInteractive():peer(0),
@@ -136,7 +140,8 @@ public:
allowedFastSetSize(10),
keepAliveInterval(120),
maxDownloadSpeedLimit(0),
- _utPexEnabled(false)
+ _utPexEnabled(false),
+ _dhtEnabled(false)
{}
virtual ~DefaultBtInteractive() {}
@@ -212,6 +217,13 @@ public:
{
_utPexEnabled = f;
}
+
+ void setLocalNode(const WeakHandle<DHTNode>& node);
+
+ void setDHTEnabled(bool f)
+ {
+ _dhtEnabled = f;
+ }
};
typedef SharedHandle<DefaultBtInteractive> DefaultBtInteractiveHandle;
diff --git a/src/DefaultBtMessageFactory.cc b/src/DefaultBtMessageFactory.cc
index c10d47d9..48819d48 100644
--- a/src/DefaultBtMessageFactory.cc
+++ b/src/DefaultBtMessageFactory.cc
@@ -64,6 +64,15 @@
#include "BtExtendedMessage.h"
#include "ExtensionMessage.h"
+DefaultBtMessageFactory::DefaultBtMessageFactory():cuid(0),
+ btContext(0),
+ pieceStorage(0),
+ peer(0),
+ _dhtEnabled(false)
+{}
+
+DefaultBtMessageFactory::~DefaultBtMessageFactory() {}
+
BtMessageHandle
DefaultBtMessageFactory::createBtMessage(const unsigned char* data, int32_t dataLength)
{
@@ -126,9 +135,6 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, int32_t data
msg = temp;
break;
}
- case BtPortMessage::ID:
- msg = BtPortMessage::create(data, dataLength);
- break;
case BtHaveAllMessage::ID:
msg = BtHaveAllMessage::create(data, dataLength);
break;
@@ -163,6 +169,13 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, int32_t data
msg = temp;
break;
}
+ case BtPortMessage::ID: {
+ SharedHandle<BtPortMessage> temp = BtPortMessage::create(data, dataLength);
+ temp->setTaskQueue(_taskQueue);
+ temp->setTaskFactory(_taskFactory);
+ msg = temp;
+ break;
+ }
case BtExtendedMessage::ID: {
if(peer->isExtendedMessagingEnabled()) {
msg = BtExtendedMessage::create(btContext, peer, (const char*)data, dataLength);
@@ -210,6 +223,7 @@ DefaultBtMessageFactory::createHandshakeMessage(const unsigned char* infoHash,
new BtHandshakeMessageValidator(msg.get(),
btContext->getInfoHash());
msg->setBtMessageValidator(validator);
+ msg->setDHTEnabled(_dhtEnabled);
setCommonProperty(msg);
return msg;
}
@@ -361,9 +375,27 @@ DefaultBtMessageFactory::createAllowedFastMessage(int32_t index)
}
BtMessageHandle
+DefaultBtMessageFactory::createPortMessage(uint16_t port)
+{
+ SharedHandle<BtPortMessage> msg = new BtPortMessage(port);
+ setCommonProperty(msg);
+ return msg;
+}
+
+BtMessageHandle
DefaultBtMessageFactory::createBtExtendedMessage(const ExensionMessageHandle& msg)
{
BtExtendedMessageHandle m = new BtExtendedMessage(msg);
setCommonProperty(m);
return m;
}
+
+void DefaultBtMessageFactory::setTaskQueue(const WeakHandle<DHTTaskQueue>& taskQueue)
+{
+ _taskQueue = taskQueue;
+}
+
+void DefaultBtMessageFactory::setTaskFactory(const WeakHandle<DHTTaskFactory>& taskFactory)
+{
+ _taskFactory = taskFactory;
+}
diff --git a/src/DefaultBtMessageFactory.h b/src/DefaultBtMessageFactory.h
index d87da9ec..6b1ad1aa 100644
--- a/src/DefaultBtMessageFactory.h
+++ b/src/DefaultBtMessageFactory.h
@@ -39,6 +39,8 @@
#include "Peer.h"
#include "AbstractBtMessage.h"
#include "BtRegistry.h"
+#include "DHTTaskQueueDecl.h"
+#include "DHTTaskFactoryDecl.h"
class DefaultBtMessageFactory : public BtMessageFactory {
private:
@@ -47,26 +49,23 @@ private:
PieceStorageHandle pieceStorage;
PeerHandle peer;
+ bool _dhtEnabled;
+
BtMessageDispatcherWeakHandle dispatcher;
BtRequestFactoryWeakHandle requestFactory;
PeerConnectionWeakHandle peerConnection;
+ WeakHandle<DHTTaskQueue> _taskQueue;
+
+ WeakHandle<DHTTaskFactory> _taskFactory;
+
void setCommonProperty(const AbstractBtMessageHandle& msg);
public:
- DefaultBtMessageFactory():cuid(0),
- btContext(0),
- pieceStorage(0),
- peer(0)
- {
- LogFactory::getInstance()->debug("DefaultBtMessageFactory::instantiated");
- }
+ DefaultBtMessageFactory();
- virtual ~DefaultBtMessageFactory()
- {
- LogFactory::getInstance()->debug("DefaultBtMessageFactory::deleted");
- }
+ virtual ~DefaultBtMessageFactory();
virtual BtMessageHandle
createBtMessage(const unsigned char* msg, int32_t msgLength);
@@ -110,6 +109,8 @@ public:
virtual BtMessageHandle createAllowedFastMessage(int32_t index);
+ virtual BtMessageHandle createPortMessage(uint16_t port);
+
virtual BtMessageHandle createBtExtendedMessage(const ExensionMessageHandle& msg);
void setPeer(const PeerHandle& peer) {
@@ -133,6 +134,10 @@ public:
this->cuid = cuid;
}
+ void setDHTEnabled(bool enabled) {
+ _dhtEnabled = enabled;
+ }
+
void setBtMessageDispatcher(const BtMessageDispatcherWeakHandle& dispatcher)
{
this->dispatcher = dispatcher;
@@ -146,6 +151,9 @@ public:
this->peerConnection = connection;
}
+ void setTaskQueue(const WeakHandle<DHTTaskQueue>& taskQueue);
+
+ void setTaskFactory(const WeakHandle<DHTTaskFactory>& taskFactory);
};
typedef SharedHandle<DefaultBtMessageFactory> DefaultBtMessageFactoryHandle;
diff --git a/src/Dictionary.cc b/src/Dictionary.cc
index d88e468d..821753dc 100644
--- a/src/Dictionary.cc
+++ b/src/Dictionary.cc
@@ -61,6 +61,12 @@ void Dictionary::put(const string& name, MetaEntry* entry) {
order.push_back(name);
}
+void Dictionary::remove(const string& name)
+{
+ table.erase(name);
+ order.erase(std::remove(order.begin(), order.end(), name), order.end());
+}
+
void Dictionary::accept(MetaEntryVisitor* v) const {
v->visit(this);
}
diff --git a/src/Dictionary.h b/src/Dictionary.h
index a140f416..85c56d04 100644
--- a/src/Dictionary.h
+++ b/src/Dictionary.h
@@ -56,6 +56,7 @@ public:
const MetaEntry* get(const string& name) const;
void put(const string& name, MetaEntry* entry);
+ void remove(const string& name);
void accept(MetaEntryVisitor* v) const;
const Order& getOrder() const;
diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc
index 7fa680a7..1b062b2a 100644
--- a/src/DownloadEngine.cc
+++ b/src/DownloadEngine.cc
@@ -135,6 +135,7 @@ void DownloadEngine::run() {
noWait = false;
calculateStatistics();
}
+ cerr << commands.size() << endl;
onEndOfRun();
}
diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc
index 1395f929..e1548aac 100644
--- a/src/FtpConnection.cc
+++ b/src/FtpConnection.cc
@@ -101,6 +101,7 @@ void FtpConnection::sendPasv() const
SocketHandle FtpConnection::sendPort() const
{
SocketHandle serverSocket;
+ serverSocket->bind(0);
serverSocket->beginListen();
pair<string, int32_t> addrinfo;
diff --git a/src/HelpItemFactory.cc b/src/HelpItemFactory.cc
index 72540044..4c491088 100644
--- a/src/HelpItemFactory.cc
+++ b/src/HelpItemFactory.cc
@@ -334,6 +334,21 @@ TagContainerHandle HelpItemFactory::createHelpItems()
item->addTag(TAG_BITTORRENT);
tc->addItem(item);
}
+ {
+ HelpItemHandle item = new HelpItem(PREF_ENABLE_DHT, TEXT_ENABLE_DHT, V_FALSE);
+ item->addTag(TAG_BITTORRENT);
+ tc->addItem(item);
+ }
+ {
+ HelpItemHandle item = new HelpItem(PREF_DHT_LISTEN_PORT, TEXT_DHT_LISTEN_PORT, "6881-6999");
+ item->addTag(TAG_BITTORRENT);
+ tc->addItem(item);
+ }
+ {
+ HelpItemHandle item = new HelpItem(PREF_DHT_ENTRY_POINT, TEXT_DHT_ENTRY_POINT);
+ item->addTag(TAG_BITTORRENT);
+ tc->addItem(item);
+ }
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
{
diff --git a/src/Makefile.am b/src/Makefile.am
index 7aa71f0a..66214950 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -257,7 +257,56 @@ SRCS += MetaEntry.h\
BtExtendedMessage.cc\
DefaultExtensionMessageFactory.cc\
HandshakeExtensionMessage.cc\
- UTPexExtensionMessage.cc
+ UTPexExtensionMessage.cc\
+ DHTNode.cc\
+ DHTUtil.cc\
+ DHTBucket.cc\
+ DHTRoutingTable.cc\
+ DHTMessageEntry.cc\
+ DHTMessageDispatcher.cc\
+ DHTMessageReceiver.cc\
+ DHTMessageTracker.cc\
+ DHTMessageTrackerEntry.cc\
+ DHTMessage.cc\
+ DHTConnectionImpl.cc\
+ DHTAbstractMessage.cc\
+ DHTQueryMessage.cc\
+ DHTResponseMessage.cc\
+ DHTPingMessage.cc\
+ DHTPingReplyMessage.cc\
+ DHTFindNodeMessage.cc\
+ DHTFindNodeReplyMessage.cc\
+ DHTGetPeersMessage.cc\
+ DHTGetPeersReplyMessage.cc\
+ DHTAnnouncePeerMessage.cc\
+ DHTAnnouncePeerReplyMessage.cc\
+ DHTMessageFactoryImpl.cc\
+ DHTNodeLookupTask.cc\
+ DHTNodeLookupEntry.cc\
+ BNode.cc\
+ DHTMessageCallbackImpl.cc\
+ DHTAbstractTask.cc\
+ DHTPingTask.cc\
+ DHTTaskQueueImpl.cc\
+ DHTBucketRefreshTask.cc\
+ DHTAbstractNodeLookupTask.cc\
+ DHTPeerLookupTask.cc\
+ DHTSetup.cc\
+ DHTTaskFactoryImpl.cc\
+ DHTInteractionCommand.cc\
+ DHTPeerAnnounceEntry.cc\
+ DHTPeerAnnounceStorage.cc\
+ DHTTokenTracker.cc\
+ DHTGetPeersCommand.cc\
+ DHTTokenUpdateCommand.cc\
+ DHTBucketRefreshCommand.cc\
+ DHTPeerAnnounceCommand.cc\
+ DHTReplaceNodeTask.cc\
+ DHTEntryPointNameResolveCommand.cc\
+ DHTRoutingTableSerializer.cc\
+ DHTRoutingTableDeserializer.cc\
+ DHTAutoSaveCommand.cc\
+ DHTRegistry.cc
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
diff --git a/src/Makefile.in b/src/Makefile.in
index ffc90332..215b4f91 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -140,7 +140,56 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessage.cc\
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.cc\
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.cc\
-@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.cc
+@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTNode.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTUtil.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTBucket.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageEntry.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageDispatcher.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageReceiver.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageTracker.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageTrackerEntry.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTConnectionImpl.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTQueryMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTResponseMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPingMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPingReplyMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTFindNodeMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTFindNodeReplyMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersReplyMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAnnouncePeerMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAnnouncePeerReplyMessage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageFactoryImpl.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTNodeLookupTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTNodeLookupEntry.cc\
+@ENABLE_BITTORRENT_TRUE@ BNode.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTMessageCallbackImpl.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPingTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTTaskQueueImpl.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTBucketRefreshTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractNodeLookupTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPeerLookupTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTSetup.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTTaskFactoryImpl.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTInteractionCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceEntry.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceStorage.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTTokenTracker.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTTokenUpdateCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTBucketRefreshCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTReplaceNodeTask.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTEntryPointNameResolveCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializer.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializer.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTAutoSaveCommand.cc\
+@ENABLE_BITTORRENT_TRUE@ DHTRegistry.cc
@ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@@ -365,7 +414,28 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h \
BtExtendedMessage.cc DefaultExtensionMessageFactory.cc \
HandshakeExtensionMessage.cc UTPexExtensionMessage.cc \
- Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
+ DHTNode.cc DHTUtil.cc DHTBucket.cc DHTRoutingTable.cc \
+ DHTMessageEntry.cc DHTMessageDispatcher.cc \
+ DHTMessageReceiver.cc DHTMessageTracker.cc \
+ DHTMessageTrackerEntry.cc DHTMessage.cc DHTConnectionImpl.cc \
+ DHTAbstractMessage.cc DHTQueryMessage.cc DHTResponseMessage.cc \
+ DHTPingMessage.cc DHTPingReplyMessage.cc DHTFindNodeMessage.cc \
+ DHTFindNodeReplyMessage.cc DHTGetPeersMessage.cc \
+ DHTGetPeersReplyMessage.cc DHTAnnouncePeerMessage.cc \
+ DHTAnnouncePeerReplyMessage.cc DHTMessageFactoryImpl.cc \
+ DHTNodeLookupTask.cc DHTNodeLookupEntry.cc BNode.cc \
+ DHTMessageCallbackImpl.cc DHTAbstractTask.cc DHTPingTask.cc \
+ DHTTaskQueueImpl.cc DHTBucketRefreshTask.cc \
+ DHTAbstractNodeLookupTask.cc DHTPeerLookupTask.cc DHTSetup.cc \
+ DHTTaskFactoryImpl.cc DHTInteractionCommand.cc \
+ DHTPeerAnnounceEntry.cc DHTPeerAnnounceStorage.cc \
+ DHTTokenTracker.cc DHTGetPeersCommand.cc \
+ DHTTokenUpdateCommand.cc DHTBucketRefreshCommand.cc \
+ DHTPeerAnnounceCommand.cc DHTReplaceNodeTask.cc \
+ DHTEntryPointNameResolveCommand.cc \
+ DHTRoutingTableSerializer.cc DHTRoutingTableDeserializer.cc \
+ DHTAutoSaveCommand.cc DHTRegistry.cc Metalinker.cc \
+ Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
MetalinkProcessorFactory.cc MetalinkParserController.cc \
MetalinkParserStateMachine.cc InitialMetalinkParserState.cc \
@@ -447,7 +517,55 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTNode.$(OBJEXT) DHTUtil.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTBucket.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageEntry.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageDispatcher.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageReceiver.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageTracker.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageTrackerEntry.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTConnectionImpl.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTQueryMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTResponseMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPingMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPingReplyMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTFindNodeMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTFindNodeReplyMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersReplyMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAnnouncePeerMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAnnouncePeerReplyMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageFactoryImpl.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTNodeLookupTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTNodeLookupEntry.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BNode.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTMessageCallbackImpl.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPingTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTTaskQueueImpl.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTBucketRefreshTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAbstractNodeLookupTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPeerLookupTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTSetup.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTTaskFactoryImpl.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTInteractionCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceEntry.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceStorage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTTokenTracker.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTGetPeersCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTTokenUpdateCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTBucketRefreshCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTPeerAnnounceCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTReplaceNodeTask.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTEntryPointNameResolveCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializer.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializer.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTAutoSaveCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DHTRegistry.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@@ -950,6 +1068,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AutoSaveCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BNode.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BencodeVisitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
@@ -994,6 +1113,54 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBoxFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieParser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CopyDiskAdaptor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAbstractMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAbstractNodeLookupTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAbstractTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAnnouncePeerMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAnnouncePeerReplyMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAutoSaveCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTBucket.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTBucketRefreshCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTBucketRefreshTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTConnectionImpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTEntryPointNameResolveCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTFindNodeMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTFindNodeReplyMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTGetPeersCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTGetPeersMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTGetPeersReplyMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTInteractionCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageCallbackImpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageDispatcher.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageEntry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageFactoryImpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageReceiver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageTracker.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTMessageTrackerEntry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTNode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTNodeLookupEntry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTNodeLookupTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPeerAnnounceCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPeerAnnounceEntry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPeerAnnounceStorage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPeerLookupTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPingMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPingReplyMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTPingTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTQueryMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTRegistry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTReplaceNodeTask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTResponseMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTRoutingTable.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTRoutingTableDeserializer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTRoutingTableSerializer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTSetup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTTaskFactoryImpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTTaskQueueImpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTTokenTracker.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTTokenUpdateCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Data.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultAuthResolver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtAnnounce.Po@am__quote@
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
index 30fdfed3..b9c7b6ba 100644
--- a/src/OptionHandlerFactory.cc
+++ b/src/OptionHandlerFactory.cc
@@ -40,7 +40,9 @@
OptionHandlers OptionHandlerFactory::createOptionHandlers()
{
OptionHandlers handlers;
- handlers.push_back(new HttpProxyOptionHandler(PREF_HTTP_PROXY));
+ handlers.push_back(new HttpProxyOptionHandler(PREF_HTTP_PROXY,
+ PREF_HTTP_PROXY_HOST,
+ PREF_HTTP_PROXY_PORT));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_USER));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_PASSWD));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_PROXY_USER));
@@ -109,6 +111,11 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
Strings(&params[0], &params[arrayLength(params)])));
}
handlers.push_back(new BooleanOptionHandler(PREF_ENABLE_PEER_EXCHANGE));
+ handlers.push_back(new BooleanOptionHandler(PREF_ENABLE_DHT));
+ handlers.push_back(new IntegerRangeOptionHandler(PREF_DHT_LISTEN_PORT, 1024, UINT16_MAX));
+ handlers.push_back(new HostPortOptionHandler(PREF_DHT_ENTRY_POINT,
+ PREF_DHT_ENTRY_POINT_HOST,
+ PREF_DHT_ENTRY_POINT_PORT));
return handlers;
}
diff --git a/src/OptionHandlerImpl.h b/src/OptionHandlerImpl.h
index c48333f6..194f3f73 100644
--- a/src/OptionHandlerImpl.h
+++ b/src/OptionHandlerImpl.h
@@ -243,11 +243,20 @@ public:
}
};
-class HttpProxyOptionHandler : public NameMatchOptionHandler {
+class HostPortOptionHandler : public NameMatchOptionHandler {
+private:
+ string _hostOptionName;
+
+ string _portOptionName;
public:
- HttpProxyOptionHandler(const string& optName):NameMatchOptionHandler(optName) {}
+ HostPortOptionHandler(const string& optName,
+ const string& hostOptionName,
+ const string& portOptionName):
+ NameMatchOptionHandler(optName),
+ _hostOptionName(hostOptionName),
+ _portOptionName(portOptionName) {}
- virtual ~HttpProxyOptionHandler() {}
+ virtual ~HostPortOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
@@ -257,9 +266,29 @@ public:
port <= 0 || 65535 < port) {
throw new FatalException(_("unrecognized proxy format"));
}
- option->put(PREF_HTTP_PROXY, optarg);
- option->put(PREF_HTTP_PROXY_HOST, proxy.first);
- option->put(PREF_HTTP_PROXY_PORT, Util::itos(port));
+ option->put(_optName, optarg);
+ setHostAndPort(option, proxy.first, port);
+ }
+
+ void setHostAndPort(Option* option, const string& hostname, uint16_t port)
+ {
+ option->put(_hostOptionName, hostname);
+ option->put(_portOptionName, Util::uitos(port));
+ }
+};
+
+class HttpProxyOptionHandler : public HostPortOptionHandler {
+public:
+ HttpProxyOptionHandler(const string& optName,
+ const string& hostOptionName,
+ const string& portOptionName):
+ HostPortOptionHandler(optName, hostOptionName, portOptionName) {}
+
+ virtual ~HttpProxyOptionHandler() {}
+
+ virtual void parseArg(Option* option, const string& optarg)
+ {
+ HostPortOptionHandler::parseArg(option, optarg);
option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
}
};
diff --git a/src/Peer.cc b/src/Peer.cc
index 51245cd8..995fbc7d 100644
--- a/src/Peer.cc
+++ b/src/Peer.cc
@@ -117,6 +117,7 @@ void Peer::resetStatus() {
fastExtensionEnabled = false;
_extendedMessagingEnabled = false;
_extensions.clear();
+ _dhtEnabled = false;
latency = DEFAULT_LATENCY;
peerAllowedIndexSet.clear();
amAllowedIndexSet.clear();
diff --git a/src/Peer.h b/src/Peer.h
index a7aae305..37e2d745 100644
--- a/src/Peer.h
+++ b/src/Peer.h
@@ -40,6 +40,7 @@
#include "PeerStat.h"
#include "TimeA2.h"
#include "BtConstants.h"
+#include "PeerDecl.h"
#include <string.h>
#define PEER_ID_LENGTH 20
@@ -71,6 +72,7 @@ private:
Integers amAllowedIndexSet;
bool _extendedMessagingEnabled;
Extensions _extensions;
+ bool _dhtEnabled;
PeerStat peerStat;
int64_t sessionUploadLength;
int64_t sessionDownloadLength;
@@ -219,6 +221,16 @@ public:
return _extendedMessagingEnabled;
}
+ void setDHTEnabled(bool enabled)
+ {
+ _dhtEnabled = enabled;
+ }
+
+ bool isDHTEnabled() const
+ {
+ return _dhtEnabled;
+ }
+
bool shouldBeChoking() const;
bool hasPiece(int32_t index) const;
@@ -260,7 +272,4 @@ public:
void setExtension(const string& name, uint8_t id);
};
-typedef SharedHandle<Peer> PeerHandle;
-typedef deque<PeerHandle> Peers;
-
#endif // _D_PEER_H_
diff --git a/src/PeerAddrEntry.h b/src/PeerAddrEntry.h
new file mode 100644
index 00000000..b2a6d3fe
--- /dev/null
+++ b/src/PeerAddrEntry.h
@@ -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 --> */
+#ifndef _D_DHT_PEER_ADDR_ENTRY_H_
+#define _D_DHT_PEER_ADDR_ENTRY_H_
+
+#include "common.h"
+#include "TimeA2.h"
+
+class PeerAddrEntry {
+private:
+ string _ipaddr;
+
+ uint16_t _port;
+
+ Time _lastUpdated;
+public:
+ PeerAddrEntry(const string& ipaddr, uint16_t port, Time updated = Time()):
+ _ipaddr(ipaddr), _port(port), _lastUpdated(updated) {}
+
+ const string& getIPAddress() const
+ {
+ return _ipaddr;
+ }
+
+ uint16_t getPort() const
+ {
+ return _port;
+ }
+
+ const Time& getLastUpdated() const
+ {
+ return _lastUpdated;
+ }
+
+ void notifyUpdate()
+ {
+ _lastUpdated.reset();
+ }
+
+ bool operator==(const PeerAddrEntry& entry) const
+ {
+ return _ipaddr == entry._ipaddr && _port == entry._port;
+ }
+};
+
+typedef deque<PeerAddrEntry> PeerAddrEntries;
+
+#endif // _D_DHT_PEER_ADDR_ENTRY_H_
diff --git a/src/PeerDecl.h b/src/PeerDecl.h
new file mode 100644
index 00000000..318beff9
--- /dev/null
+++ b/src/PeerDecl.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_PEER_DECL_H_
+#define _D_PEER_DECL_H_
+
+#include "SharedHandle.h"
+#include <deque>
+
+class Peer;
+typedef SharedHandle<Peer> PeerHandle;
+typedef std::deque<PeerHandle> Peers;
+
+#endif // _D_PEER_DECL_H_
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index 2cd64a27..3a60b6b7 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -47,6 +47,11 @@
#include "DefaultBtMessageFactory.h"
#include "DefaultBtInteractive.h"
#include "CUIDCounter.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTNode.h"
+#include "DHTSetup.h"
+#include "DHTRegistry.h"
#include <algorithm>
PeerInteractionCommand::PeerInteractionCommand(int32_t cuid,
@@ -74,6 +79,8 @@ PeerInteractionCommand::PeerInteractionCommand(int32_t cuid,
factory->setCuid(cuid);
factory->setBtContext(btContext);
factory->setPeer(peer);
+ factory->setTaskQueue(DHTRegistry::_taskQueue);
+ factory->setTaskFactory(DHTRegistry::_taskFactory);
PeerConnectionHandle peerConnection = passedPeerConnection.isNull() ?
new PeerConnection(cuid, socket, e->option) : passedPeerConnection;
@@ -112,8 +119,15 @@ PeerInteractionCommand::PeerInteractionCommand(int32_t cuid,
btInteractive->setKeepAliveInterval(e->option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL));
btInteractive->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
btInteractive->setBtMessageFactory(factory);
- if(!btContext->isPrivate() && e->option->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
- btInteractive->setUTPexEnabled(true);
+ if(!btContext->isPrivate()) {
+ if(e->option->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
+ btInteractive->setUTPexEnabled(true);
+ }
+ if(DHTSetup::initialized()) {
+ btInteractive->setDHTEnabled(true);
+ btInteractive->setLocalNode(DHTRegistry::_localNode);
+ factory->setDHTEnabled(true);
+ }
}
this->btInteractive = btInteractive;
diff --git a/src/PeerListenCommand.cc b/src/PeerListenCommand.cc
index 188040b4..a8f52afa 100644
--- a/src/PeerListenCommand.cc
+++ b/src/PeerListenCommand.cc
@@ -63,7 +63,8 @@ int32_t PeerListenCommand::bindPort(IntSequence& seq)
while(seq.hasNext()) {
int32_t port = seq.next();
try {
- socket->beginListen(port);
+ socket->bind(port);
+ socket->beginListen();
logger->info(MSG_LISTENING_PORT,
cuid, port);
return port;
diff --git a/src/PeerMessageUtil.cc b/src/PeerMessageUtil.cc
index 0665939f..eb526407 100644
--- a/src/PeerMessageUtil.cc
+++ b/src/PeerMessageUtil.cc
@@ -135,3 +135,11 @@ bool PeerMessageUtil::createcompact(char* compact, const string& addr, uint16_t
return true;
}
+pair<string, uint16_t> PeerMessageUtil::unpackcompact(const char* compact)
+{
+ struct in_addr in;
+ in.s_addr = *(uint32_t*)(compact);
+ string ipaddr = inet_ntoa(in);
+ uint16_t port = ntohs(*(uint16_t*)(compact+sizeof(uint32_t)));
+ return pair<string, uint16_t>(ipaddr, port);
+}
diff --git a/src/PeerMessageUtil.h b/src/PeerMessageUtil.h
index f66f2f0e..29bf1479 100644
--- a/src/PeerMessageUtil.h
+++ b/src/PeerMessageUtil.h
@@ -75,6 +75,8 @@ public:
* notation.
*/
static bool createcompact(char* compact, const string& addr, uint16_t port);
+
+ static pair<string, uint16_t> unpackcompact(const char* compact);
};
#endif // _D_PEER_MESSAGE_UTIL_H_
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index 4dedd96e..ae3d80f7 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -74,6 +74,9 @@
# include "BtSetup.h"
# include "BtFileAllocationEntry.h"
# include "BtPostDownloadHandler.h"
+# include "DHTSetup.h"
+# include "DHTRegistry.h"
+# include "DHTPeerAnnounceStorage.h"
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
# include "MetalinkPostDownloadHandler.h"
@@ -219,6 +222,10 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
}
}
_progressInfoFile = progressInfoFile;
+
+ if(!btContext->isPrivate() && _option->getAsBool(PREF_ENABLE_DHT)) {
+ e->addCommand(DHTSetup().setup(e, _option));
+ }
CheckIntegrityEntryHandle entry = new BtCheckIntegrityEntry(this);
return processCheckIntegrityEntry(entry, e);
@@ -584,6 +591,7 @@ void RequestGroup::releaseRuntimeResource()
btContextInReg->getOwnerRequestGroup()->getGID() ==
btContext->getOwnerRequestGroup()->getGID()) {
BtRegistry::unregister(btContext->getInfoHashAsString());
+ DHTRegistry::_peerAnnounceStorage->removePeerAnnounce(btContext);
}
}
#endif // ENABLE_BITTORRENT
diff --git a/src/SocketCore.cc b/src/SocketCore.cc
index 6d256a66..7dba735e 100644
--- a/src/SocketCore.cc
+++ b/src/SocketCore.cc
@@ -48,11 +48,11 @@
# define SOCKET_ERRNO (WSAGetLastError())
#endif // __MINGW32__
-SocketCore::SocketCore():sockfd(-1) {
+SocketCore::SocketCore(int sockType):_sockType(sockType), sockfd(-1) {
init();
}
-SocketCore::SocketCore(int32_t sockfd):sockfd(sockfd) {
+SocketCore::SocketCore(int32_t sockfd, int sockType):_sockType(sockType), sockfd(sockfd) {
init();
}
@@ -82,11 +82,11 @@ SocketCore::~SocketCore() {
#endif // HAVE_LIBGNUTLS
}
-void SocketCore::beginListen(int32_t port)
+void SocketCore::bind(uint16_t port)
{
closeConnection();
- //sockfd = socket(AF_UNSPEC, SOCK_STREAM, PF_UNSPEC);
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ //sockfd = socket(AF_UNSPEC, _sockType, PF_UNSPEC);
+ sockfd = socket(AF_INET, _sockType, 0);
if(sockfd == -1) {
throw new DlAbortEx(EX_SOCKET_OPEN, errorMsg());
}
@@ -107,15 +107,16 @@ void SocketCore::beginListen(int32_t port)
sockaddr.sin_addr.s_addr = INADDR_ANY;
sockaddr.sin_port = htons(port);
- if(bind(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == -1) {
+ if(::bind(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == -1) {
throw new DlAbortEx(EX_SOCKET_BIND, errorMsg());
}
+}
+void SocketCore::beginListen()
+{
if(listen(sockfd, 1) == -1) {
throw new DlAbortEx(EX_SOCKET_LISTEN, errorMsg());
}
-
- setNonBlockingMode();
}
SocketCore* SocketCore::acceptConnection() const
@@ -128,7 +129,7 @@ SocketCore* SocketCore::acceptConnection() const
if(fd == -1) {
throw new DlAbortEx(EX_SOCKET_ACCEPT, errorMsg());
}
- SocketCore* s = new SocketCore(fd);
+ SocketCore* s = new SocketCore(fd, _sockType);
return s;
}
@@ -159,7 +160,7 @@ void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
void SocketCore::establishConnection(const string& host, int32_t port)
{
closeConnection();
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ sockfd = socket(AF_INET, _sockType, 0);
if(sockfd == -1) {
throw new DlAbortEx(EX_SOCKET_OPEN, errorMsg());
}
@@ -181,7 +182,7 @@ void SocketCore::establishConnection(const string& host, int32_t port)
memset((char*)&ai, 0, sizeof(ai));
ai.ai_flags = 0;
ai.ai_family = PF_INET;
- ai.ai_socktype = SOCK_STREAM;
+ ai.ai_socktype = _sockType;
ai.ai_protocol = 0;
struct addrinfo* res;
int32_t ec;
@@ -194,6 +195,7 @@ void SocketCore::establishConnection(const string& host, int32_t port)
}
// make socket non-blocking mode
setNonBlockingMode();
+ // TODO handle EINTR
if(connect(sockfd, (struct sockaddr*)&sockaddr, (socklen_t)sizeof(sockaddr)) == -1 && SOCKET_ERRNO !=
#ifndef __MINGW32__
EINPROGRESS
@@ -574,3 +576,94 @@ void SocketCore::initiateSecureConnection()
return buf;
#endif // __MINGW32__
}
+
+template<typename T>
+string uitos(T value)
+{
+ string str;
+ if(value == 0) {
+ str = "0";
+ return str;
+ }
+ int32_t count = 0;
+ while(value) {
+ ++count;
+ char digit = value%10+'0';
+ str.insert(str.begin(), digit);
+ value /= 10;
+ }
+ return str;
+}
+
+void fillSockaddr(sockaddr* addr, int sockType, const string& host, uint16_t port)
+{
+ struct addrinfo hints;
+ struct addrinfo* result;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = sockType;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ {
+ int r = getaddrinfo(host.c_str(), uitos(port).c_str(), &hints, &result);
+ if(r != 0) {
+ throw new DlAbortEx(EX_RESOLVE_HOSTNAME,
+ host.c_str(), gai_strerror(r));
+ }
+ }
+ memcpy(addr, result->ai_addr, result->ai_addrlen);
+ freeaddrinfo(result);
+}
+
+void SocketCore::writeData(const char* data, size_t len, const string& host, uint16_t port)
+{
+ struct sockaddr_storage addrPeer;
+ fillSockaddr((struct sockaddr*)&addrPeer, _sockType, host, port);
+ ssize_t r;
+ while((r = sendto(sockfd, data, len, 0, (const sockaddr*)&addrPeer, sizeof(struct sockaddr_storage))) == -1 && EINTR == errno);
+ if(r == -1) {
+ throw new DlAbortEx(EX_SOCKET_SEND, errorMsg());
+ }
+}
+
+ssize_t SocketCore::readDataFrom(char* data, size_t len, struct sockaddr* sender, socklen_t* senderLength)
+{
+ ssize_t r;
+ while((r = recvfrom(sockfd, data, len, 0, sender, senderLength)) == -1 &&
+ EINTR == errno);
+ if(r == -1) {
+ throw new DlAbortEx(EX_SOCKET_RECV, errorMsg());
+ }
+ return r;
+}
+
+ssize_t SocketCore::readDataFrom(char* data, size_t len)
+{
+
+ return readDataFrom(data, len, 0, 0);
+}
+
+ssize_t SocketCore::readDataFrom(char* data, size_t len,
+ pair<string /* numerichost */,
+ uint16_t /* port */>& sender)
+{
+ struct sockaddr_storage addrSender;
+ socklen_t addrSenderLength = sizeof(struct sockaddr_storage);
+ ssize_t rlength = readDataFrom(data, len, (struct sockaddr*)&addrSender, &addrSenderLength);
+
+ char host[NI_MAXHOST];
+ char service[NI_MAXSERV];
+ {
+ int s = getnameinfo((struct sockaddr*)&addrSender, addrSenderLength,
+ host, NI_MAXHOST, service, NI_MAXSERV,
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ if(s != 0) {
+ throw new DlAbortEx("Failed to get peer's hostname and port. cause: %s",
+ gai_strerror(s));
+ }
+ }
+ sender.first = host;
+ sender.second = atoi(service); // TODO
+ return rlength;
+}
+
diff --git a/src/SocketCore.h b/src/SocketCore.h
index fda3e8a0..262e0d70 100644
--- a/src/SocketCore.h
+++ b/src/SocketCore.h
@@ -38,6 +38,7 @@
#include "common.h"
#include <string>
#include <utility>
+#include <sys/socket.h>
#ifdef HAVE_LIBSSL
// for SSL
@@ -55,6 +56,8 @@ class SocketCore {
friend bool operator!=(const SocketCore& s1, const SocketCore& s2);
friend bool operator<(const SocketCore& s1, const SocketCore& s2);
private:
+ // socket type defined in <sys/socket.h>
+ int _sockType;
// socket endpoint descriptor
int32_t sockfd;
// reference counter for this object.
@@ -80,12 +83,12 @@ private:
#endif // HAVE_LIBGNUTLS
void init();
- SocketCore(int32_t sockfd);
+ SocketCore(int32_t sockfd, int sockType);
static int error();
static const char *errorMsg();
static const char *errorMsg(const int err);
public:
- SocketCore();
+ SocketCore(int sockType = SOCK_STREAM);
~SocketCore();
int32_t getSockfd() const { return sockfd; }
@@ -93,11 +96,17 @@ public:
bool isOpen() const { return sockfd != -1; }
/**
- * Creates a socket and listens form connection on it.
+ * Creates a socket and bind it with locahost's address and port.
* @param port port to listen. If 0 is specified, os automaticaly
* choose avaiable port.
*/
- void beginListen(int32_t port = 0);
+ void bind(uint16_t port);
+
+ /**
+ * Listens form connection on it.
+ * Call bind(uint16_t) before calling this function.
+ */
+ void beginListen();
/**
* Stores host address and port of this socket to addrinfo.
@@ -172,6 +181,8 @@ public:
writeData(msg.c_str(), msg.size());
}
+ void writeData(const char* data, size_t len, const string& host, uint16_t port);
+
/**
* Reads up to len bytes from this socket.
* data is a pointer pointing the first
@@ -186,6 +197,15 @@ public:
*/
void readData(char* data, int32_t& len);
+ ssize_t readDataFrom(char* data, size_t len, struct sockaddr* sender,
+ socklen_t* senderLength);
+
+ ssize_t readDataFrom(char*, size_t len,
+ pair<string /* numerichost */,
+ uint16_t /* port */>& sender);
+
+ ssize_t readDataFrom(char* data, size_t len);
+
/**
* Reads up to len bytes from this socket, but bytes are not removed from
* this socket.
diff --git a/src/Util.h b/src/Util.h
index 811050f7..bf531b58 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -101,6 +101,11 @@ public:
static string toHex(const unsigned char* src, int32_t len);
+ static string toHex(const string& src)
+ {
+ return toHex(reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
+ }
+
static FILE* openFile(const string& filename, const string& mode);
static void fileCopy(const string& destFile, const string& src);
diff --git a/src/XORCloser.h b/src/XORCloser.h
new file mode 100644
index 00000000..33f21047
--- /dev/null
+++ b/src/XORCloser.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_XOR_CLOSER_H_
+#define _D_XOR_CLOSER_H_
+
+#include <cstdlib>
+
+class XORCloser {
+private:
+ const unsigned char* _key;
+ std::size_t _length;
+public:
+ XORCloser(const unsigned char* key, std::size_t length):_key(key), _length(length) {}
+
+ bool operator()(const unsigned char* key1,
+ const unsigned char* key2) const
+ {
+ for(std::size_t i = 0; i < _length; ++i) {
+ unsigned char c1 = _key[i]^key1[i];
+ unsigned char c2 = _key[i]^key2[i];
+
+ if(c1 < c2) {
+ return true;
+ } else if(c1 > c2) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+#endif // _D_XOR_CLOSER_H_
diff --git a/src/message.h b/src/message.h
index 7e08f7ae..f73b0dcd 100644
--- a/src/message.h
+++ b/src/message.h
@@ -89,6 +89,7 @@
#define MSG_TRACKER_RESPONSE_PROCESSING_FAILED _("CUID#%d - Error occurred while processing tracker response.")
#define MSG_TRACKER_REQUEST_CREATION_FAILED _("CUID#%d - Cannot create tracker request.")
#define MSG_CREATING_TRACKER_REQUEST _("CUID#%d - Creating new tracker request command #%d")
+#define MSG_DHT_ENABLED_PEER _("CUID#%d - The peer is DHT-enabled.")
#define MSG_UNRECOGNIZED_URI _("Unrecognized URI or unsupported protocol: %s")
#define MSG_TRACKER_WARNING_MESSAGE _("Tracker returned warning message: %s")
diff --git a/src/option_processing.cc b/src/option_processing.cc
index 4da41332..21e1a607 100644
--- a/src/option_processing.cc
+++ b/src/option_processing.cc
@@ -131,8 +131,11 @@ Option* option_processing(int argc, char* const argv[])
op->put(PREF_ENABLE_DIRECT_IO, V_FALSE);
op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
op->put(PREF_METALINK_PREFERRED_PROTOCOL, V_NONE);
- op->put(PREF_ENABLE_PEER_EXCHANGE, V_TRUE);
op->put(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL, V_TRUE);
+ op->put(PREF_ENABLE_PEER_EXCHANGE, V_TRUE);
+ op->put(PREF_ENABLE_DHT, V_FALSE);
+ op->put(PREF_DHT_LISTEN_PORT, "6881-6999");
+ op->put(PREF_DHT_FILE_PATH, Util::getHomeDir()+"/.aria2/dht.dat");
// following options are not parsed by OptionHandler and not stored in Option.
bool noConf = false;
@@ -210,6 +213,9 @@ Option* option_processing(int argc, char* const argv[])
{ "max-upload-limit", required_argument, &lopt, 24 },
{ "peer-id-prefix", required_argument, &lopt, 25 },
{ "enable-peer-exchange", optional_argument, &lopt, 26 },
+ { "enable-dht", optional_argument, &lopt, 27 },
+ { "dht-listen-port", required_argument, &lopt, 28 },
+ { "dht-entry-point", required_argument, &lopt, 29 },
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
{ "metalink-file", required_argument, NULL, 'M' },
@@ -305,6 +311,15 @@ Option* option_processing(int argc, char* const argv[])
case 26:
cmdstream << PREF_ENABLE_PEER_EXCHANGE << "=" << toBoolArg(optarg) << "\n";
break;
+ case 27:
+ cmdstream << PREF_ENABLE_DHT << "=" << toBoolArg(optarg) << "\n";
+ break;
+ case 28:
+ cmdstream << PREF_DHT_LISTEN_PORT << "=" << optarg << "\n";
+ break;
+ case 29:
+ cmdstream << PREF_DHT_ENTRY_POINT << "=" << optarg << "\n";
+ break;
case 100:
cmdstream << PREF_METALINK_VERSION << "=" << optarg << "\n";
break;
diff --git a/src/prefs.h b/src/prefs.h
index 3a76b46b..88426c3c 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -214,6 +214,18 @@
#define PREF_PEER_ID_PREFIX "peer-id-prefix"
// values: true | false
#define PREF_ENABLE_PEER_EXCHANGE "enable-peer-exchange"
+// values: true | false
+#define PREF_ENABLE_DHT "enable-dht"
+// values: 1*digit
+#define PREF_DHT_LISTEN_PORT "dht-listen-port"
+// values: a string
+#define PREF_DHT_ENTRY_POINT_HOST "dht-entry-point-host"
+// values: 1*digit
+#define PREF_DHT_ENTRY_POINT_PORT "dht-entry-point-port"
+// values: a string (hostname:port)
+#define PREF_DHT_ENTRY_POINT "dht-entry-point"
+// values: a string
+#define PREF_DHT_FILE_PATH "dht-file-path"
/**
* Metalink related preferences
diff --git a/src/usage_text.h b/src/usage_text.h
index d6dfcae1..914bacdf 100644
--- a/src/usage_text.h
+++ b/src/usage_text.h
@@ -256,6 +256,17 @@ _(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID
" Default: -aria2-")
#define TEXT_ENABLE_PEER_EXCHANGE \
_(" --enable-peer-exchange[=true|false] Enable peer exchange extension.")
+#define TEXT_ENABLE_DHT \
+_(" --enable-dht[=true|false] Enable DHT functionality.")
+#define TEXT_DHT_LISTEN_PORT \
+_(" --dht-listen-port... Set UDP listening port for DHT.\n"\
+ " Multiple ports can be specified by using ',',\n"\
+ " for example: \"6881,6885\". You can also use '-'\n"\
+ " to specify a range: \"6881-6999\". ',' and '-' can\n"\
+ " be used together.")
+#define TEXT_DHT_ENTRY_POINT \
+_(" --dht-entry-point=HOST:PORT Set host and port as an entry point to DHT\n"\
+ " network.")
#define TEXT_METALINK_FILE \
_(" -M, --metalink-file=METALINK_FILE The file path to the .metalink file.")
#define TEXT_METALINK_SERVERS \