summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog55
-rw-r--r--src/BtSetup.cc37
-rw-r--r--src/DHTAutoSaveCommand.cc10
-rw-r--r--src/DHTAutoSaveCommand.h5
-rw-r--r--src/DHTConnectionImpl.cc24
-rw-r--r--src/DHTConnectionImpl.h21
-rw-r--r--src/DHTEntryPointNameResolveCommand.cc7
-rw-r--r--src/DHTFindNodeReplyMessage.cc24
-rw-r--r--src/DHTFindNodeReplyMessage.h7
-rw-r--r--src/DHTGetPeersMessage.cc17
-rw-r--r--src/DHTGetPeersReplyMessage.cc46
-rw-r--r--src/DHTGetPeersReplyMessage.h7
-rw-r--r--src/DHTMessageFactory.h6
-rw-r--r--src/DHTMessageFactoryImpl.cc121
-rw-r--r--src/DHTMessageFactoryImpl.h23
-rw-r--r--src/DHTMessageTracker.cc27
-rw-r--r--src/DHTRegistry.cc31
-rw-r--r--src/DHTRegistry.h40
-rw-r--r--src/DHTRoutingTableDeserializer.cc40
-rw-r--r--src/DHTRoutingTableDeserializer.h4
-rw-r--r--src/DHTRoutingTableSerializer.cc26
-rw-r--r--src/DHTRoutingTableSerializer.h4
-rw-r--r--src/DHTSetup.cc89
-rw-r--r--src/DHTSetup.h7
-rw-r--r--src/FtpConnection.cc2
-rw-r--r--src/LpdMessageReceiver.cc2
-rw-r--r--src/OptionHandlerFactory.cc48
-rw-r--r--src/OptionHandlerImpl.h15
-rw-r--r--src/PeerInteractionCommand.cc51
-rw-r--r--src/RequestGroup.cc48
-rw-r--r--src/SocketCore.cc40
-rw-r--r--src/SocketCore.h5
-rw-r--r--src/bittorrent_helper.cc11
-rw-r--r--src/bittorrent_helper.h5
-rw-r--r--src/prefs.cc14
-rw-r--r--src/prefs.h14
-rw-r--r--src/usage_text.h28
-rw-r--r--test/DHTConnectionImplTest.cc15
-rw-r--r--test/DHTFindNodeReplyMessageTest.cc51
-rw-r--r--test/DHTGetPeersMessageTest.cc28
-rw-r--r--test/DHTGetPeersReplyMessageTest.cc89
-rw-r--r--test/DHTMessageFactoryImplTest.cc134
-rw-r--r--test/DHTRoutingTableDeserializerTest.cc47
-rw-r--r--test/DHTRoutingTableSerializerTest.cc161
-rw-r--r--test/LpdMessageDispatcherTest.cc2
-rw-r--r--test/MockDHTMessageFactory.h15
46 files changed, 1093 insertions, 410 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f8943a9..b2ea2662 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,57 @@
-2010-08-05 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+2010-08-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+
+ Added IPv6 DHT. Added --dht-entry-porint6, --dht-file-path6,
+ --dht-listen-addr6 and --enable-dht6 option. IPv6 DHT is disabled
+ by default. To use IPv6 DHT, you need to use --enable-dht6 and
+ specify a global unicast address to --dht-listen-addr6. IPv6 DHT
+ is highly experimental.
+ * src/BtSetup.cc
+ * src/DHTAutoSaveCommand.cc
+ * src/DHTAutoSaveCommand.h
+ * src/DHTConnectionImpl.cc
+ * src/DHTConnectionImpl.h
+ * src/DHTEntryPointNameResolveCommand.cc
+ * src/DHTFindNodeReplyMessage.cc
+ * src/DHTFindNodeReplyMessage.h
+ * src/DHTGetPeersMessage.cc
+ * src/DHTGetPeersReplyMessage.cc
+ * src/DHTGetPeersReplyMessage.h
+ * src/DHTMessageFactory.h
+ * src/DHTMessageFactoryImpl.cc
+ * src/DHTMessageFactoryImpl.h
+ * src/DHTMessageTracker.cc
+ * src/DHTRegistry.cc
+ * src/DHTRegistry.h
+ * src/DHTRoutingTableDeserializer.cc
+ * src/DHTRoutingTableDeserializer.h
+ * src/DHTRoutingTableSerializer.cc
+ * src/DHTRoutingTableSerializer.h
+ * src/DHTSetup.cc
+ * src/DHTSetup.h
+ * src/FtpConnection.cc
+ * src/LpdMessageReceiver.cc
+ * src/OptionHandlerFactory.cc
+ * src/OptionHandlerImpl.h
+ * src/PeerInteractionCommand.cc
+ * src/RequestGroup.cc
+ * src/SocketCore.cc
+ * src/SocketCore.h
+ * src/bittorrent_helper.cc
+ * src/bittorrent_helper.h
+ * src/prefs.cc
+ * src/prefs.h
+ * src/usage_text.h
+ * test/DHTConnectionImplTest.cc
+ * test/DHTFindNodeReplyMessageTest.cc
+ * test/DHTGetPeersMessageTest.cc
+ * test/DHTGetPeersReplyMessageTest.cc
+ * test/DHTMessageFactoryImplTest.cc
+ * test/DHTRoutingTableDeserializerTest.cc
+ * test/DHTRoutingTableSerializerTest.cc
+ * test/LpdMessageDispatcherTest.cc
+ * test/MockDHTMessageFactory.h
+
+2010-08-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Removed AI_V4MAPPED from DEFAULT_AI_FLAGS
* src/a2netcompat.h
diff --git a/src/BtSetup.cc b/src/BtSetup.cc
index f17757e5..fdd467fa 100644
--- a/src/BtSetup.cc
+++ b/src/BtSetup.cc
@@ -58,6 +58,15 @@
#include "DHTPeerAnnounceStorage.h"
#include "DHTSetup.h"
#include "DHTRegistry.h"
+#include "DHTNode.h"
+#include "DHTRoutingTable.h"
+#include "DHTTaskQueue.h"
+#include "DHTTaskFactory.h"
+#include "DHTTokenTracker.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageReceiver.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageCallback.h"
#include "BtProgressInfoFile.h"
#include "BtAnnounce.h"
#include "BtRuntime.h"
@@ -126,15 +135,25 @@ void BtSetup::setup(std::vector<Command*>& commands,
commands.push_back(c);
}
- if((metadataGetMode || !torrentAttrs->privateTorrent) &&
- DHTSetup::initialized()) {
- DHTGetPeersCommand* command =
- new DHTGetPeersCommand(e->newCUID(), requestGroup, e);
- command->setTaskQueue(DHTRegistry::getData().taskQueue);
- command->setTaskFactory(DHTRegistry::getData().taskFactory);
- command->setBtRuntime(btRuntime);
- command->setPeerStorage(peerStorage);
- commands.push_back(command);
+ if(metadataGetMode || !torrentAttrs->privateTorrent) {
+ if(DHTRegistry::isInitialized()) {
+ DHTGetPeersCommand* command =
+ new DHTGetPeersCommand(e->newCUID(), requestGroup, e);
+ command->setTaskQueue(DHTRegistry::getData().taskQueue);
+ command->setTaskFactory(DHTRegistry::getData().taskFactory);
+ command->setBtRuntime(btRuntime);
+ command->setPeerStorage(peerStorage);
+ commands.push_back(command);
+ }
+ if(DHTRegistry::isInitialized6()) {
+ DHTGetPeersCommand* command =
+ new DHTGetPeersCommand(e->newCUID(), requestGroup, e);
+ command->setTaskQueue(DHTRegistry::getData6().taskQueue);
+ command->setTaskFactory(DHTRegistry::getData6().taskFactory);
+ command->setBtRuntime(btRuntime);
+ command->setPeerStorage(peerStorage);
+ commands.push_back(command);
+ }
}
if(!metadataGetMode) {
SharedHandle<UnionSeedCriteria> unionCri(new UnionSeedCriteria());
diff --git a/src/DHTAutoSaveCommand.cc b/src/DHTAutoSaveCommand.cc
index f5ae60ec..63f8b2c6 100644
--- a/src/DHTAutoSaveCommand.cc
+++ b/src/DHTAutoSaveCommand.cc
@@ -62,8 +62,9 @@
namespace aria2 {
DHTAutoSaveCommand::DHTAutoSaveCommand
-(cuid_t cuid, DownloadEngine* e, time_t interval):
- TimeBasedCommand(cuid, e, interval) {}
+(cuid_t cuid, DownloadEngine* e, int family, time_t interval):
+ TimeBasedCommand(cuid, e, interval),
+ family_(family) {}
DHTAutoSaveCommand::~DHTAutoSaveCommand() {}
@@ -84,7 +85,8 @@ void DHTAutoSaveCommand::process()
void DHTAutoSaveCommand::save()
{
std::string dhtFile =
- getDownloadEngine()->getOption()->get(PREF_DHT_FILE_PATH);
+ getDownloadEngine()->getOption()->
+ get(family_ == AF_INET? PREF_DHT_FILE_PATH : PREF_DHT_FILE_PATH6);
getLogger()->info("Saving DHT routing table to %s.", dhtFile.c_str());
std::string tempFile = dhtFile;
@@ -116,7 +118,7 @@ void DHTAutoSaveCommand::save()
nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end());
}
- DHTRoutingTableSerializer serializer;
+ DHTRoutingTableSerializer serializer(family_);
serializer.setLocalNode(localNode_);
serializer.setNodes(nodes);
diff --git a/src/DHTAutoSaveCommand.h b/src/DHTAutoSaveCommand.h
index f7a0ad5a..1a14e90e 100644
--- a/src/DHTAutoSaveCommand.h
+++ b/src/DHTAutoSaveCommand.h
@@ -46,13 +46,16 @@ class DHTNode;
class DHTAutoSaveCommand : public TimeBasedCommand
{
private:
+ int family_;
+
SharedHandle<DHTNode> localNode_;
SharedHandle<DHTRoutingTable> routingTable_;
void save();
public:
- DHTAutoSaveCommand(cuid_t cuid, DownloadEngine* e, time_t interval);
+ DHTAutoSaveCommand
+ (cuid_t cuid, DownloadEngine* e, int family, time_t interval);
virtual ~DHTAutoSaveCommand();
diff --git a/src/DHTConnectionImpl.cc b/src/DHTConnectionImpl.cc
index 26bd31ce..9a2e44f6 100644
--- a/src/DHTConnectionImpl.cc
+++ b/src/DHTConnectionImpl.cc
@@ -46,12 +46,15 @@
namespace aria2 {
-DHTConnectionImpl::DHTConnectionImpl():socket_(new SocketCore(SOCK_DGRAM)),
- logger_(LogFactory::getInstance()) {}
+DHTConnectionImpl::DHTConnectionImpl(int family):
+ socket_(new SocketCore(SOCK_DGRAM)),
+ family_(family),
+ logger_(LogFactory::getInstance()) {}
DHTConnectionImpl::~DHTConnectionImpl() {}
-bool DHTConnectionImpl::bind(uint16_t& port, IntSequence& ports)
+bool DHTConnectionImpl::bind
+(uint16_t& port, const std::string& addr, IntSequence& ports)
{
std::vector<int32_t> randPorts = ports.flush();
std::random_shuffle(randPorts.begin(), randPorts.end(),
@@ -63,25 +66,30 @@ bool DHTConnectionImpl::bind(uint16_t& port, IntSequence& ports)
continue;
}
port = (*portItr);
- if(bind(port)) {
+ if(bind(port, addr)) {
return true;
}
}
return false;
}
-bool DHTConnectionImpl::bind(uint16_t& port)
+bool DHTConnectionImpl::bind(uint16_t& port, const std::string& addr)
{
+ int ipv = family_ == AF_INET?4:6;
try {
- socket_->bind(port);
+ if(addr.empty()) {
+ socket_->bind(A2STR::NIL, port, family_);
+ } else {
+ socket_->bind(addr, port, family_);
+ }
socket_->setNonBlockingMode();
std::pair<std::string, uint16_t> svaddr;
socket_->getAddrInfo(svaddr);
port = svaddr.second;
- logger_->notice("DHT: listening to port %d", port);
+ logger_->notice("IPv%d DHT: listening to port %d", ipv, port);
return true;
} catch(RecoverableException& e) {
- logger_->error("Failed to bind for DHT. port=%u", e, port);
+ logger_->error("Failed to bind for IPv%d DHT. port=%u", e, ipv, port);
}
return false;
}
diff --git a/src/DHTConnectionImpl.h b/src/DHTConnectionImpl.h
index 24099edd..7f0808fa 100644
--- a/src/DHTConnectionImpl.h
+++ b/src/DHTConnectionImpl.h
@@ -48,28 +48,33 @@ class DHTConnectionImpl:public DHTConnection {
private:
SharedHandle<SocketCore> socket_;
+ int family_;
+
Logger* logger_;
public:
- DHTConnectionImpl();
+ DHTConnectionImpl(int family);
virtual ~DHTConnectionImpl();
/**
- * Binds port. All number in ports are tried.
- * If successful, the binded port is assigned to port and returns true.
- * Otherwise return false and port is undefined in this case.
+ * Binds port. All number in ports are tried. If successful, the
+ * binded port is assigned to port and returns true. Otherwise
+ * return false and port is undefined in this case. If non-empty
+ * string addr is given, the socket is associated to the address.
*/
- bool bind(uint16_t& port, IntSequence& ports);
+ bool bind(uint16_t& port, const std::string& addr, IntSequence& ports);
/**
* Binds port. The port number specified by port is used to bind.
- * If successful, the binded port is assigned to port and returns true.
- * Otherwise return false and port is undefined in this case.
+ * If successful, the binded port is assigned to port and returns
+ * true. Otherwise return false and port is undefined in this case.
+ * If non-empty string addr is given, the socket is associated to
+ * the address.
*
* If you want to bind arbitrary port, give 0 as port and if successful,
* the binded port is assigned to port.
*/
- bool bind(uint16_t& port);
+ bool bind(uint16_t& port, const std::string& addr);
virtual ssize_t receiveMessage(unsigned char* data, size_t len,
std::string& host, uint16_t& port);
diff --git a/src/DHTEntryPointNameResolveCommand.cc b/src/DHTEntryPointNameResolveCommand.cc
index 9db92f60..d59cbdec 100644
--- a/src/DHTEntryPointNameResolveCommand.cc
+++ b/src/DHTEntryPointNameResolveCommand.cc
@@ -96,7 +96,12 @@ bool DHTEntryPointNameResolveCommand::execute()
while(!entryPoints_.empty()) {
std::string hostname = entryPoints_.front().first;
try {
- if(resolveHostname(hostname, resolver_)) {
+ if(util::isNumericHost(hostname)) {
+ std::pair<std::string, uint16_t> p
+ (hostname, entryPoints_.front().second);
+ resolvedEntryPoints_.push_back(p);
+ addPingTask(p);
+ } else if(resolveHostname(hostname, resolver_)) {
hostname = resolver_->getResolvedAddresses().front();
std::pair<std::string, uint16_t> p(hostname,
entryPoints_.front().second);
diff --git a/src/DHTFindNodeReplyMessage.cc b/src/DHTFindNodeReplyMessage.cc
index 99acbce1..4c255332 100644
--- a/src/DHTFindNodeReplyMessage.cc
+++ b/src/DHTFindNodeReplyMessage.cc
@@ -51,11 +51,15 @@ const std::string DHTFindNodeReplyMessage::FIND_NODE("find_node");
const std::string DHTFindNodeReplyMessage::NODES("nodes");
+const std::string DHTFindNodeReplyMessage::NODES6("nodes6");
+
DHTFindNodeReplyMessage::DHTFindNodeReplyMessage
-(const SharedHandle<DHTNode>& localNode,
+(int family,
+ const SharedHandle<DHTNode>& localNode,
const SharedHandle<DHTNode>& remoteNode,
const std::string& transactionID):
- DHTResponseMessage(localNode, remoteNode, transactionID) {}
+ DHTResponseMessage(localNode, remoteNode, transactionID),
+ family_(family) {}
DHTFindNodeReplyMessage::~DHTFindNodeReplyMessage() {}
@@ -73,23 +77,27 @@ SharedHandle<Dict> DHTFindNodeReplyMessage::getResponse()
{
SharedHandle<Dict> aDict = Dict::g();
aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
+ unsigned char buffer[DHTBucket::K*38];
+ const int clen = bittorrent::getCompactLength(family_);
+ const int unit = clen+20;
+ assert(unit <= 38);
size_t offset = 0;
- unsigned char buffer[DHTBucket::K*26];
- // TODO if closestKNodes_.size() > DHTBucket::K ??
+ size_t k = 0;
for(std::vector<SharedHandle<DHTNode> >::const_iterator i =
closestKNodes_.begin(), eoi = closestKNodes_.end();
- i != eoi && offset < DHTBucket::K*26; ++i) {
+ i != eoi && k < DHTBucket::K; ++i) {
SharedHandle<DHTNode> node = *i;
memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, node->getIPAddress(), node->getPort());
- if(compactlen == COMPACT_LEN_IPV4) {
+ if(compactlen == clen) {
memcpy(buffer+20+offset, compact, compactlen);
- offset += 26;
+ offset += unit;
+ ++k;
}
}
- aDict->put(NODES, String::g(buffer, offset));
+ aDict->put(family_ == AF_INET?NODES:NODES6, String::g(buffer, offset));
return aDict;
}
diff --git a/src/DHTFindNodeReplyMessage.h b/src/DHTFindNodeReplyMessage.h
index 9e14bd2c..15f1dd5d 100644
--- a/src/DHTFindNodeReplyMessage.h
+++ b/src/DHTFindNodeReplyMessage.h
@@ -42,11 +42,14 @@ namespace aria2 {
class DHTFindNodeReplyMessage:public DHTResponseMessage {
private:
+ int family_;
+
std::vector<SharedHandle<DHTNode> > closestKNodes_;
protected:
virtual std::string toStringOptional() const;
public:
- DHTFindNodeReplyMessage(const SharedHandle<DHTNode>& localNode,
+ DHTFindNodeReplyMessage(int family,
+ const SharedHandle<DHTNode>& localNode,
const SharedHandle<DHTNode>& remoteNode,
const std::string& transactionID);
@@ -71,6 +74,8 @@ public:
static const std::string FIND_NODE;
static const std::string NODES;
+
+ static const std::string NODES6;
};
} // namespace aria2
diff --git a/src/DHTGetPeersMessage.cc b/src/DHTGetPeersMessage.cc
index 9f838a05..2a553792 100644
--- a/src/DHTGetPeersMessage.cc
+++ b/src/DHTGetPeersMessage.cc
@@ -70,18 +70,11 @@ void DHTGetPeersMessage::doReceivedAction()
// Check to see localhost has the contents which has same infohash
std::vector<SharedHandle<Peer> > peers;
peerAnnounceStorage_->getPeers(peers, infoHash_);
- SharedHandle<DHTMessage> reply;
- if(peers.empty()) {
- std::vector<SharedHandle<DHTNode> > nodes;
- getRoutingTable()->getClosestKNodes(nodes, infoHash_);
- reply =
- getMessageFactory()->createGetPeersReplyMessage
- (getRemoteNode(), nodes, token, getTransactionID());
- } else {
- reply =
- getMessageFactory()->createGetPeersReplyMessage
- (getRemoteNode(), peers, token, getTransactionID());
- }
+ std::vector<SharedHandle<DHTNode> > nodes;
+ getRoutingTable()->getClosestKNodes(nodes, infoHash_);
+ SharedHandle<DHTMessage> reply =
+ getMessageFactory()->createGetPeersReplyMessage
+ (getRemoteNode(), nodes, peers, token, getTransactionID());
getMessageDispatcher()->addMessageToQueue(reply);
}
diff --git a/src/DHTGetPeersReplyMessage.cc b/src/DHTGetPeersReplyMessage.cc
index 6a0532c9..76c525c7 100644
--- a/src/DHTGetPeersReplyMessage.cc
+++ b/src/DHTGetPeersReplyMessage.cc
@@ -57,12 +57,16 @@ const std::string DHTGetPeersReplyMessage::VALUES("values");
const std::string DHTGetPeersReplyMessage::NODES("nodes");
+const std::string DHTGetPeersReplyMessage::NODES6("nodes6");
+
DHTGetPeersReplyMessage::DHTGetPeersReplyMessage
-(const SharedHandle<DHTNode>& localNode,
+(int family,
+ const SharedHandle<DHTNode>& localNode,
const SharedHandle<DHTNode>& remoteNode,
const std::string& token,
const std::string& transactionID):
DHTResponseMessage(localNode, remoteNode, transactionID),
+ family_(family),
token_(token) {}
DHTGetPeersReplyMessage::~DHTGetPeersReplyMessage() {}
@@ -77,59 +81,69 @@ SharedHandle<Dict> DHTGetPeersReplyMessage::getResponse()
SharedHandle<Dict> rDict = Dict::g();
rDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
rDict->put(TOKEN, token_);
- if(values_.empty()) {
+ // TODO want parameter
+ if(!closestKNodes_.empty()) {
+ unsigned char buffer[DHTBucket::K*38];
+ const int clen = bittorrent::getCompactLength(family_);
+ const int unit = clen+20;
size_t offset = 0;
- unsigned char buffer[DHTBucket::K*26];
+ size_t k = 0;
for(std::vector<SharedHandle<DHTNode> >::const_iterator i =
closestKNodes_.begin(), eoi = closestKNodes_.end();
- i != eoi && offset < DHTBucket::K*26; ++i) {
+ i != eoi && k < DHTBucket::K; ++i) {
SharedHandle<DHTNode> node = *i;
memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, node->getIPAddress(), node->getPort());
- if(compactlen == COMPACT_LEN_IPV4) {
+ if(compactlen == clen) {
memcpy(buffer+20+offset, compact, compactlen);
- offset += 26;
+ offset += unit;
+ ++k;
}
}
- rDict->put(NODES, String::g(buffer, offset));
- } else {
+ rDict->put(family_ == AF_INET?NODES:NODES6, String::g(buffer, offset));
+ }
+ if(!values_.empty()) {
// Limit the size of values list. The maxmum size of UDP datagram
// is limited to 65535 bytes. aria2 uses 20bytes token and 2byte
// transaction ID. The size of get_peers reply message without
- // values list is 87bytes:
+ // values list and nodes is 87bytes:
//
// d1:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:token20:aaaaaaaaaaaaaaaaaaaa
// 6:valueslee1:t2:bb1:y1:re
//
+ // nodes are 38 bytes per host for IPv6 and the number of hosts is
+ // K(=8) max. So without values list, we already 87+38*8+4 = 395.
+ //
// Because of Path MTU Discovery, UDP packet size which need not
// to be fragmented is much smaller. Since Linux uses Path MTU
// Dicoverry by default and returning ICMP message might be
// filtered, we should avoid fragmentation. MTU of pppoe is 1492
// max according to RFC2516. We use maximum packet size to be
- // 1000. Since it contains 20 bytes IP header and 8 bytes UDP
- // header and 87 bytes reply message template described above, We
- // can carry (1000-28-87)/8 = 110 peer info. Since DHT spec
+ // 1024. Since it contains 20 bytes IP header and 8 bytes UDP
+ // header and 395 bytes reply message template described above, We
+ // can carry (1024-28-395)/(18+3) = 28 peer info. Since DHT spec
// doesn't specify the maximum size of token, reply message
- // template may get bigger than 87 bytes. So we use 100 as maximum
+ // template may get bigger than 395 bytes. So we use 25 as maximum
// number of peer info that a message can carry.
- static const size_t MAX_VALUES_SIZE = 100;
+ static const size_t MAX_VALUES_SIZE = 25;
SharedHandle<List> valuesList = List::g();
for(std::vector<SharedHandle<Peer> >::const_iterator i = values_.begin(),
eoi = values_.end(); i != eoi && valuesList->size() < MAX_VALUES_SIZE;
++i) {
const SharedHandle<Peer>& peer = *i;
unsigned char compact[COMPACT_LEN_IPV6];
+ const int clen = bittorrent::getCompactLength(family_);
int compactlen = bittorrent::packcompact
(compact, peer->getIPAddress(), peer->getPort());
- if(compactlen == COMPACT_LEN_IPV4) {
+ if(compactlen == clen) {
valuesList->append(String::g(compact, compactlen));
}
}
rDict->put(VALUES, valuesList);
}
- return rDict;
+ return rDict;
}
const std::string& DHTGetPeersReplyMessage::getMessageType() const
diff --git a/src/DHTGetPeersReplyMessage.h b/src/DHTGetPeersReplyMessage.h
index b15a41c4..8494a2d7 100644
--- a/src/DHTGetPeersReplyMessage.h
+++ b/src/DHTGetPeersReplyMessage.h
@@ -47,6 +47,8 @@ class Peer;
class DHTGetPeersReplyMessage:public DHTResponseMessage {
private:
+ int family_;
+
std::string token_;
std::vector<SharedHandle<DHTNode> > closestKNodes_;
@@ -55,7 +57,8 @@ private:
protected:
virtual std::string toStringOptional() const;
public:
- DHTGetPeersReplyMessage(const SharedHandle<DHTNode>& localNode,
+ DHTGetPeersReplyMessage(int family,
+ const SharedHandle<DHTNode>& localNode,
const SharedHandle<DHTNode>& remoteNode,
const std::string& token,
const std::string& transactionID);
@@ -103,6 +106,8 @@ public:
static const std::string VALUES;
static const std::string NODES;
+
+ static const std::string NODES6;
};
} // namespace aria2
diff --git a/src/DHTMessageFactory.h b/src/DHTMessageFactory.h
index f0140f12..f363150f 100644
--- a/src/DHTMessageFactory.h
+++ b/src/DHTMessageFactory.h
@@ -94,12 +94,6 @@ public:
createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
const std::vector<SharedHandle<DHTNode> >& closestKNodes,
- const std::string& token,
- const std::string& transactionID) = 0;
-
- virtual SharedHandle<DHTResponseMessage>
- createGetPeersReplyMessage
- (const SharedHandle<DHTNode>& remoteNode,
const std::vector<SharedHandle<Peer> >& peers,
const std::string& token,
const std::string& transactionID) = 0;
diff --git a/src/DHTMessageFactoryImpl.cc b/src/DHTMessageFactoryImpl.cc
index 5567711d..9b781115 100644
--- a/src/DHTMessageFactoryImpl.cc
+++ b/src/DHTMessageFactoryImpl.cc
@@ -64,7 +64,8 @@
namespace aria2 {
-DHTMessageFactoryImpl::DHTMessageFactoryImpl():
+DHTMessageFactoryImpl::DHTMessageFactoryImpl(int family):
+ family_(family),
logger_(LogFactory::getInstance()) {}
DHTMessageFactoryImpl::~DHTMessageFactoryImpl() {}
@@ -261,21 +262,7 @@ DHTMessageFactoryImpl::createResponseMessage
} else if(messageType == DHTFindNodeReplyMessage::FIND_NODE) {
msg = createFindNodeReplyMessage(remoteNode, dict, transactionID->s());
} else if(messageType == DHTGetPeersReplyMessage::GET_PEERS) {
- const List* valuesList =
- asList(rDict->get(DHTGetPeersReplyMessage::VALUES));
- if(valuesList) {
- msg = createGetPeersReplyMessageWithValues
- (remoteNode, dict, transactionID->s());
- } else {
- const String* nodes = asString
- (rDict->get(DHTGetPeersReplyMessage::NODES));
- if(nodes) {
- msg = createGetPeersReplyMessageWithNodes
- (remoteNode, dict, transactionID->s());
- } else {
- throw DL_ABORT_EX("Malformed DHT message: missing nodes/values");
- }
- }
+ msg = createGetPeersReplyMessage(remoteNode, dict, transactionID->s());
} else if(messageType == DHTAnnouncePeerReplyMessage::ANNOUNCE_PEER) {
msg = createAnnouncePeerReplyMessage(remoteNode, transactionID->s());
} else {
@@ -349,23 +336,26 @@ DHTMessageFactoryImpl::createFindNodeReplyMessage
const std::string& transactionID)
{
SharedHandle<DHTFindNodeReplyMessage> m
- (new DHTFindNodeReplyMessage(localNode_, remoteNode, transactionID));
+ (new DHTFindNodeReplyMessage
+ (family_, localNode_, remoteNode, transactionID));
m->setClosestKNodes(closestKNodes);
setCommonProperty(m);
return m;
}
-std::vector<SharedHandle<DHTNode> >
-DHTMessageFactoryImpl::extractNodes(const unsigned char* src, size_t length)
+void DHTMessageFactoryImpl::extractNodes
+(std::vector<SharedHandle<DHTNode> >& nodes,
+ const unsigned char* src, size_t length)
{
- if(length%26 != 0) {
- throw DL_ABORT_EX("Nodes length is not multiple of 26");
+ int unit = bittorrent::getCompactLength(family_)+20;
+ if(length%unit != 0) {
+ throw DL_ABORT_EX
+ (StringFormat("Nodes length is not multiple of %d", unit).str());
}
- std::vector<SharedHandle<DHTNode> > nodes;
- for(size_t offset = 0; offset < length; offset += 26) {
+ for(size_t offset = 0; offset < length; offset += unit) {
SharedHandle<DHTNode> node(new DHTNode(src+offset));
std::pair<std::string, uint16_t> addr =
- bittorrent::unpackcompact(src+offset+DHT_ID_LENGTH, AF_INET);
+ bittorrent::unpackcompact(src+offset+DHT_ID_LENGTH, family_);
if(addr.first.empty()) {
continue;
}
@@ -373,7 +363,6 @@ DHTMessageFactoryImpl::extractNodes(const unsigned char* src, size_t length)
node->setPort(addr.second);
nodes.push_back(node);
}
- return nodes;
}
SharedHandle<DHTResponseMessage>
@@ -383,10 +372,13 @@ DHTMessageFactoryImpl::createFindNodeReplyMessage
const std::string& transactionID)
{
const String* nodesData =
- getString(getDictionary(dict, DHTResponseMessage::R),
- DHTFindNodeReplyMessage::NODES);
- std::vector<SharedHandle<DHTNode> > nodes =
- extractNodes(nodesData->uc(), nodesData->s().size());
+ asString(getDictionary(dict, DHTResponseMessage::R)->
+ get(family_ == AF_INET?DHTFindNodeReplyMessage::NODES:
+ DHTFindNodeReplyMessage::NODES6));
+ std::vector<SharedHandle<DHTNode> > nodes;
+ if(nodesData) {
+ extractNodes(nodes, nodesData->uc(), nodesData->s().size());
+ }
return createFindNodeReplyMessage(remoteNode, nodes, transactionID);
}
@@ -405,68 +397,55 @@ DHTMessageFactoryImpl::createGetPeersMessage
}
SharedHandle<DHTResponseMessage>
-DHTMessageFactoryImpl::createGetPeersReplyMessageWithNodes
-(const SharedHandle<DHTNode>& remoteNode,
- const Dict* dict,
- const std::string& transactionID)
-{
- const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
- const String* nodesData = getString(rDict, DHTGetPeersReplyMessage::NODES);
- std::vector<SharedHandle<DHTNode> > nodes = extractNodes
- (nodesData->uc(), nodesData->s().size());
- const String* token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
- return createGetPeersReplyMessage
- (remoteNode, nodes, token->s(), transactionID);
-}
-
-SharedHandle<DHTResponseMessage>
DHTMessageFactoryImpl::createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
- const std::vector<SharedHandle<DHTNode> >& closestKNodes,
- const std::string& token,
- const std::string& transactionID)
-{
- SharedHandle<DHTGetPeersReplyMessage> m
- (new DHTGetPeersReplyMessage(localNode_, remoteNode, token, transactionID));
- m->setClosestKNodes(closestKNodes);
- setCommonProperty(m);
- return m;
-}
-
-SharedHandle<DHTResponseMessage>
-DHTMessageFactoryImpl::createGetPeersReplyMessageWithValues
-(const SharedHandle<DHTNode>& remoteNode,
const Dict* dict,
const std::string& transactionID)
{
const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
- const List* valuesList = getList(rDict,
- DHTGetPeersReplyMessage::VALUES);
+ const String* nodesData =
+ asString(rDict->get(family_ == AF_INET?DHTGetPeersReplyMessage::NODES:
+ DHTGetPeersReplyMessage::NODES6));
+ std::vector<SharedHandle<DHTNode> > nodes;
+ if(nodesData) {
+ extractNodes(nodes, nodesData->uc(), nodesData->s().size());
+ }
+ const List* valuesList =
+ asList(rDict->get(DHTGetPeersReplyMessage::VALUES));
std::vector<SharedHandle<Peer> > peers;
- for(List::ValueType::const_iterator i = valuesList->begin(),
- eoi = valuesList->end(); i != eoi; ++i) {
- const String* data = asString(*i);
- if(data && data->s().size() == 6) {
- std::pair<std::string, uint16_t> addr =
- bittorrent::unpackcompact(data->uc(), AF_INET);
- SharedHandle<Peer> peer(new Peer(addr.first, addr.second));
- peers.push_back(peer);
+ size_t clen = bittorrent::getCompactLength(family_);
+ if(valuesList) {
+ for(List::ValueType::const_iterator i = valuesList->begin(),
+ eoi = valuesList->end(); i != eoi; ++i) {
+ const String* data = asString(*i);
+ if(data && data->s().size() == clen) {
+ std::pair<std::string, uint16_t> addr =
+ bittorrent::unpackcompact(data->uc(), family_);
+ if(addr.first.empty()) {
+ continue;
+ }
+ SharedHandle<Peer> peer(new Peer(addr.first, addr.second));
+ peers.push_back(peer);
+ }
}
- }
+ }
const String* token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
return createGetPeersReplyMessage
- (remoteNode, peers, token->s(), transactionID);
+ (remoteNode, nodes, peers, token->s(), transactionID);
}
SharedHandle<DHTResponseMessage>
DHTMessageFactoryImpl::createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
+ const std::vector<SharedHandle<DHTNode> >& closestKNodes,
const std::vector<SharedHandle<Peer> >& values,
const std::string& token,
const std::string& transactionID)
{
SharedHandle<DHTGetPeersReplyMessage> m
- (new DHTGetPeersReplyMessage(localNode_, remoteNode, token, transactionID));
+ (new DHTGetPeersReplyMessage
+ (family_, localNode_, remoteNode, token, transactionID));
+ m->setClosestKNodes(closestKNodes);
m->setValues(values);
setCommonProperty(m);
return m;
diff --git a/src/DHTMessageFactoryImpl.h b/src/DHTMessageFactoryImpl.h
index d7b639bf..f3e06895 100644
--- a/src/DHTMessageFactoryImpl.h
+++ b/src/DHTMessageFactoryImpl.h
@@ -51,6 +51,8 @@ class DHTAbstractMessage;
class DHTMessageFactoryImpl:public DHTMessageFactory {
private:
+ int family_;
+
SharedHandle<DHTNode> localNode_;
WeakHandle<DHTConnection> connection_;
@@ -73,13 +75,14 @@ private:
void validatePort(const Integer* i) const;
- std::vector<SharedHandle<DHTNode> >
- extractNodes(const unsigned char* src, size_t length);
+ void extractNodes
+ (std::vector<SharedHandle<DHTNode> >& nodes,
+ const unsigned char* src, size_t length);
void setCommonProperty(const SharedHandle<DHTAbstractMessage>& m);
public:
- DHTMessageFactoryImpl();
+ DHTMessageFactoryImpl(int family);
virtual ~DHTMessageFactoryImpl();
@@ -127,26 +130,16 @@ public:
createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
const std::vector<SharedHandle<DHTNode> >& closestKNodes,
+ const std::vector<SharedHandle<Peer> >& peers,
const std::string& token,
const std::string& transactionID);
SharedHandle<DHTResponseMessage>
- createGetPeersReplyMessageWithNodes(const SharedHandle<DHTNode>& remoteNode,
- const Dict* dict,
- const std::string& transactionID);
-
- virtual SharedHandle<DHTResponseMessage>
createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
- const std::vector<SharedHandle<Peer> >& peers,
- const std::string& token,
+ const Dict* dict,
const std::string& transactionID);
- SharedHandle<DHTResponseMessage>
- createGetPeersReplyMessageWithValues(const SharedHandle<DHTNode>& remoteNode,
- const Dict* dict,
- const std::string& transactionID);
-
virtual SharedHandle<DHTQueryMessage>
createAnnouncePeerMessage(const SharedHandle<DHTNode>& remoteNode,
const unsigned char* infoHash,
diff --git a/src/DHTMessageTracker.cc b/src/DHTMessageTracker.cc
index ebbc8a9e..ed15f322 100644
--- a/src/DHTMessageTracker.cc
+++ b/src/DHTMessageTracker.cc
@@ -84,19 +84,24 @@ DHTMessageTracker::messageArrived
logger_->debug("Tracker entry found.");
}
SharedHandle<DHTNode> targetNode = entry->getTargetNode();
+ try {
+ SharedHandle<DHTResponseMessage> message =
+ factory_->createResponseMessage(entry->getMessageType(), dict,
+ targetNode->getIPAddress(),
+ targetNode->getPort());
- SharedHandle<DHTResponseMessage> message =
- factory_->createResponseMessage(entry->getMessageType(), dict,
- targetNode->getIPAddress(),
- targetNode->getPort());
-
- int64_t rtt = entry->getElapsedMillis();
- if(logger_->debug()) {
- logger_->debug("RTT is %s", util::itos(rtt).c_str());
+ int64_t rtt = entry->getElapsedMillis();
+ if(logger_->debug()) {
+ logger_->debug("RTT is %s", util::itos(rtt).c_str());
+ }
+ message->getRemoteNode()->updateRTT(rtt);
+ SharedHandle<DHTMessageCallback> callback = entry->getCallback();
+ return std::make_pair(message, callback);
+ } catch(RecoverableException& e) {
+ entry->getCallback()->onTimeout(targetNode);
+ return std::pair<SharedHandle<DHTResponseMessage>,
+ SharedHandle<DHTMessageCallback> >();
}
- message->getRemoteNode()->updateRTT(rtt);
- SharedHandle<DHTMessageCallback> callback = entry->getCallback();
- return std::make_pair(message, callback);
}
}
if(logger_->debug()) {
diff --git a/src/DHTRegistry.cc b/src/DHTRegistry.cc
index 909225e2..464f54f9 100644
--- a/src/DHTRegistry.cc
+++ b/src/DHTRegistry.cc
@@ -49,17 +49,30 @@ namespace aria2 {
DHTRegistry::Data DHTRegistry::data_;
+DHTRegistry::Data DHTRegistry::data6_;
+
+void DHTRegistry::clear(DHTRegistry::Data& data)
+{
+ data.initialized = false;
+ data.localNode.reset();
+ data.routingTable.reset();
+ data.taskQueue.reset();
+ data.taskFactory.reset();
+ data.peerAnnounceStorage.reset();
+ data.tokenTracker.reset();
+ data.messageDispatcher.reset();
+ data.messageReceiver.reset();
+ data.messageFactory.reset();
+}
+
void DHTRegistry::clearData()
{
- data_.localNode.reset();
- data_.routingTable.reset();
- data_.taskQueue.reset();
- data_.taskFactory.reset();
- data_.peerAnnounceStorage.reset();
- data_.tokenTracker.reset();
- data_.messageDispatcher.reset();
- data_.messageReceiver.reset();
- data_.messageFactory.reset();
+ clear(data_);
+}
+
+void DHTRegistry::clearData6()
+{
+ clear(data6_);
}
} // namespace aria2
diff --git a/src/DHTRegistry.h b/src/DHTRegistry.h
index 5248d710..d3c13417 100644
--- a/src/DHTRegistry.h
+++ b/src/DHTRegistry.h
@@ -53,6 +53,8 @@ class DHTMessageFactory;
class DHTRegistry {
private:
struct Data {
+ bool initialized;
+
SharedHandle<DHTNode> localNode;
SharedHandle<DHTRoutingTable> routingTable;
@@ -70,9 +72,15 @@ private:
SharedHandle<DHTMessageReceiver> messageReceiver;
SharedHandle<DHTMessageFactory> messageFactory;
+
+ Data():initialized(false) {}
};
static Data data_;
+ static Data data6_;
+
+ static void clear(Data& data);
+
DHTRegistry();
public:
static const Data& getData()
@@ -86,6 +94,38 @@ public:
}
static void clearData();
+
+ static bool isInitialized()
+ {
+ return data_.initialized;
+ }
+
+ static void setInitialized(bool f)
+ {
+ data_.initialized = f;
+ }
+
+ static const Data& getData6()
+ {
+ return data6_;
+ }
+
+ static Data& getMutableData6()
+ {
+ return data6_;
+ }
+
+ static void clearData6();
+
+ static bool isInitialized6()
+ {
+ return data6_.initialized;
+ }
+
+ static void setInitialized6(bool f)
+ {
+ data6_.initialized = f;
+ }
};
} // namespace aria2
diff --git a/src/DHTRoutingTableDeserializer.cc b/src/DHTRoutingTableDeserializer.cc
index bed629ca..d06de4b3 100644
--- a/src/DHTRoutingTableDeserializer.cc
+++ b/src/DHTRoutingTableDeserializer.cc
@@ -52,7 +52,8 @@
namespace aria2 {
-DHTRoutingTableDeserializer::DHTRoutingTableDeserializer() {}
+DHTRoutingTableDeserializer::DHTRoutingTableDeserializer(int family):
+ family_(family) {}
DHTRoutingTableDeserializer::~DHTRoutingTableDeserializer() {}
@@ -99,7 +100,7 @@ void DHTRoutingTableDeserializer::deserialize(std::istream& in)
headerCompat[6] = 0;
headerCompat[7] = 0x02;
- char zero[8];
+ char zero[18];
memset(zero, 0, sizeof(zero));
int version;
@@ -159,44 +160,39 @@ void DHTRoutingTableDeserializer::deserialize(std::istream& in)
std::vector<SharedHandle<DHTNode> > nodes;
// nodes
+ const int compactlen = bittorrent::getCompactLength(family_);
for(size_t i = 0; i < numNodes; ++i) {
- // Currently, only IPv4 addresses are supported.
// 1byte compact peer info length
uint8_t peerInfoLen;
in >> peerInfoLen;
- if(peerInfoLen != 6) {
+ if(peerInfoLen != compactlen) {
// skip this entry
- readBytes(buf, buf.size(), in, 42+7+6);
- CHECK_STREAM(in, 42+7+6);
+ readBytes(buf, buf.size(), in, 7+48);
+ CHECK_STREAM(in, 7+48);
continue;
}
// 7bytes reserved
readBytes(buf, buf.size(), in, 7);
CHECK_STREAM(in, 7);
- // 6bytes compact peer info
- readBytes(buf, buf.size(), in, 6);
- CHECK_STREAM(in, 6);
- if(memcmp(zero, buf, 6) == 0) {
+ // compactlen bytes compact peer info
+ readBytes(buf, buf.size(), in, compactlen);
+ CHECK_STREAM(in, compactlen);
+ if(memcmp(zero, buf, compactlen) == 0) {
// skip this entry
- readBytes(buf, buf.size(), in, 42);
- CHECK_STREAM(in, 42);
+ readBytes(buf, buf.size(), in, 48-compactlen);
+ CHECK_STREAM(in, 48-compactlen);
continue;
}
- // TODO DHT6 protocol family should be configurable.
std::pair<std::string, uint16_t> peer =
- bittorrent::unpackcompact(buf, AF_INET);
+ bittorrent::unpackcompact(buf, family_);
if(peer.first.empty()) {
// skip this entry
- readBytes(buf, buf.size(), in, 42);
- CHECK_STREAM(in, 42);
+ readBytes(buf, buf.size(), in, 48-compactlen);
+ CHECK_STREAM(in, 48-compactlen);
continue;
}
- // 2bytes reserved
- readBytes(buf, buf.size(), in, 2);
- CHECK_STREAM(in, 2);
- // 16byte reserved
- readBytes(buf, buf.size(), in, 16);
- CHECK_STREAM(in, 16);
+ // 24-compactlen bytes reserved
+ readBytes(buf, buf.size(), in, 24-compactlen);
// node ID
readBytes(buf, buf.size(), in, DHT_ID_LENGTH);
CHECK_STREAM(in, DHT_ID_LENGTH);
diff --git a/src/DHTRoutingTableDeserializer.h b/src/DHTRoutingTableDeserializer.h
index efa55a76..bd83fca4 100644
--- a/src/DHTRoutingTableDeserializer.h
+++ b/src/DHTRoutingTableDeserializer.h
@@ -49,13 +49,15 @@ class DHTNode;
class DHTRoutingTableDeserializer {
private:
+ int family_;
+
SharedHandle<DHTNode> localNode_;
std::vector<SharedHandle<DHTNode> > nodes_;
Time serializedTime_;
public:
- DHTRoutingTableDeserializer();
+ DHTRoutingTableDeserializer(int family);
~DHTRoutingTableDeserializer();
diff --git a/src/DHTRoutingTableSerializer.cc b/src/DHTRoutingTableSerializer.cc
index 81976c50..d1bfa3f4 100644
--- a/src/DHTRoutingTableSerializer.cc
+++ b/src/DHTRoutingTableSerializer.cc
@@ -50,7 +50,8 @@
namespace aria2 {
-DHTRoutingTableSerializer::DHTRoutingTableSerializer() {}
+DHTRoutingTableSerializer::DHTRoutingTableSerializer(int family):
+ family_(family) {}
DHTRoutingTableSerializer::~DHTRoutingTableSerializer() {}
@@ -79,7 +80,7 @@ void DHTRoutingTableSerializer::serialize(std::ostream& o)
header[6] = 0;
header[7] = 0x03;
- char zero[16];
+ char zero[18];
memset(zero, 0, sizeof(zero));
o.write(header, 8);
@@ -101,29 +102,26 @@ void DHTRoutingTableSerializer::serialize(std::ostream& o)
// 4bytes reserved
o.write(zero, 4);
+ const int clen = bittorrent::getCompactLength(family_);
// nodes
for(std::vector<SharedHandle<DHTNode> >::const_iterator i = nodes_.begin(),
eoi = nodes_.end(); i != eoi; ++i) {
const SharedHandle<DHTNode>& node = *i;
- // Currently, only IPv4 addresses are saved.
- // 6bytes: write IP address + port in Compact IP-address/port info form.
+ // Write IP address + port in Compact IP-address/port info form.
unsigned char compactPeer[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compactPeer, node->getIPAddress(), node->getPort());
- if(compactlen != COMPACT_LEN_IPV4) {
- compactlen = COMPACT_LEN_IPV4;
- memset(compactPeer, 0, COMPACT_LEN_IPV4);
+ if(compactlen != clen) {
+ memset(compactPeer, 0, clen);
}
// 1byte compact peer format length
- o << static_cast<uint8_t>(compactlen);
+ o << static_cast<uint8_t>(clen);
// 7bytes reserved
o.write(zero, 7);
- // 6 bytes compact peer
- o.write(reinterpret_cast<const char*>(compactPeer), compactlen);
- // 2bytes reserved
- o.write(zero, 2);
- // 16bytes reserved
- o.write(zero, 16);
+ // clen bytes compact peer
+ o.write(reinterpret_cast<const char*>(compactPeer), clen);
+ // 24-clen bytes reserved
+ o.write(zero, 24-clen);
// 20bytes: node ID
o.write(reinterpret_cast<const char*>(node->getID()), DHT_ID_LENGTH);
// 4bytes reserved
diff --git a/src/DHTRoutingTableSerializer.h b/src/DHTRoutingTableSerializer.h
index 352bc08a..b2660518 100644
--- a/src/DHTRoutingTableSerializer.h
+++ b/src/DHTRoutingTableSerializer.h
@@ -48,11 +48,13 @@ class DHTNode;
class DHTRoutingTableSerializer {
private:
+ int family_;
+
SharedHandle<DHTNode> localNode_;
std::vector<SharedHandle<DHTNode> > nodes_;
public:
- DHTRoutingTableSerializer();
+ DHTRoutingTableSerializer(int family);
~DHTRoutingTableSerializer();
diff --git a/src/DHTSetup.cc b/src/DHTSetup.cc
index c6e623e8..ec8b7ac7 100644
--- a/src/DHTSetup.cc
+++ b/src/DHTSetup.cc
@@ -79,16 +79,18 @@
namespace aria2 {
-// TODO DownloadEngine should hold this flag.
-bool DHTSetup::initialized_ = false;
-
DHTSetup::DHTSetup():logger_(LogFactory::getInstance()) {}
DHTSetup::~DHTSetup() {}
-void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
+void DHTSetup::setup
+(std::vector<Command*>& commands, DownloadEngine* e, int family)
{
- if(initialized_) {
+ if(family != AF_INET && family != AF_INET6) {
+ return;
+ }
+ if((family == AF_INET && DHTRegistry::isInitialized()) ||
+ (family == AF_INET6 && DHTRegistry::isInitialized6())) {
return;
}
try {
@@ -98,8 +100,10 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
SharedHandle<DHTNode> localNode;
- DHTRoutingTableDeserializer deserializer;
- std::string dhtFile = e->getOption()->get(PREF_DHT_FILE_PATH);
+ DHTRoutingTableDeserializer deserializer(family);
+ const std::string& dhtFile =
+ e->getOption()->get(family == AF_INET?PREF_DHT_FILE_PATH:
+ PREF_DHT_FILE_PATH6);
try {
std::ifstream in(dhtFile.c_str(), std::ios::binary);
if(!in) {
@@ -115,12 +119,15 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
localNode.reset(new DHTNode());
}
- SharedHandle<DHTConnectionImpl> connection(new DHTConnectionImpl());
+ SharedHandle<DHTConnectionImpl> connection(new DHTConnectionImpl(family));
{
IntSequence seq =
util::parseIntRange(e->getOption()->get(PREF_DHT_LISTEN_PORT));
uint16_t port;
- if(!connection->bind(port, seq)) {
+ const std::string& addr =
+ e->getOption()->get(family == AF_INET?PREF_DHT_LISTEN_ADDR:
+ PREF_DHT_LISTEN_ADDR6);
+ if(!connection->bind(port, addr, seq)) {
throw DL_ABORT_EX("Error occurred while binding port for DHT");
}
localNode->setPort(port);
@@ -131,7 +138,8 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
}
SharedHandle<DHTRoutingTable> routingTable(new DHTRoutingTable(localNode));
- SharedHandle<DHTMessageFactoryImpl> factory(new DHTMessageFactoryImpl());
+ SharedHandle<DHTMessageFactoryImpl> factory
+ (new DHTMessageFactoryImpl(family));
SharedHandle<DHTMessageTracker> tracker(new DHTMessageTracker());
@@ -179,16 +187,27 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
factory->setLocalNode(localNode);
// assign them into DHTRegistry
- DHTRegistry::getMutableData().localNode = localNode;
- DHTRegistry::getMutableData().routingTable = routingTable;
- DHTRegistry::getMutableData().taskQueue = taskQueue;
- DHTRegistry::getMutableData().taskFactory = taskFactory;
- DHTRegistry::getMutableData().peerAnnounceStorage = peerAnnounceStorage;
- DHTRegistry::getMutableData().tokenTracker = tokenTracker;
- DHTRegistry::getMutableData().messageDispatcher = dispatcher;
- DHTRegistry::getMutableData().messageReceiver = receiver;
- DHTRegistry::getMutableData().messageFactory = factory;
-
+ if(family == AF_INET) {
+ DHTRegistry::getMutableData().localNode = localNode;
+ DHTRegistry::getMutableData().routingTable = routingTable;
+ DHTRegistry::getMutableData().taskQueue = taskQueue;
+ DHTRegistry::getMutableData().taskFactory = taskFactory;
+ DHTRegistry::getMutableData().peerAnnounceStorage = peerAnnounceStorage;
+ DHTRegistry::getMutableData().tokenTracker = tokenTracker;
+ DHTRegistry::getMutableData().messageDispatcher = dispatcher;
+ DHTRegistry::getMutableData().messageReceiver = receiver;
+ DHTRegistry::getMutableData().messageFactory = factory;
+ } else {
+ DHTRegistry::getMutableData6().localNode = localNode;
+ DHTRegistry::getMutableData6().routingTable = routingTable;
+ DHTRegistry::getMutableData6().taskQueue = taskQueue;
+ DHTRegistry::getMutableData6().taskFactory = taskFactory;
+ DHTRegistry::getMutableData6().peerAnnounceStorage = peerAnnounceStorage;
+ DHTRegistry::getMutableData6().tokenTracker = tokenTracker;
+ DHTRegistry::getMutableData6().messageDispatcher = dispatcher;
+ DHTRegistry::getMutableData6().messageReceiver = receiver;
+ DHTRegistry::getMutableData6().messageFactory = factory;
+ }
// add deserialized nodes to routing table
const std::vector<SharedHandle<DHTNode> >& desnodes =
deserializer.getNodes();
@@ -206,11 +225,16 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
taskQueue->addPeriodicTask1(task);
}
- if(!e->getOption()->get(PREF_DHT_ENTRY_POINT_HOST).empty()) {
+ const std::string& prefEntryPointHost =
+ family == AF_INET?PREF_DHT_ENTRY_POINT_HOST:PREF_DHT_ENTRY_POINT_HOST6;
+ if(!e->getOption()->get(prefEntryPointHost).empty()) {
{
+ const std::string& prefEntryPointPort =
+ family == AF_INET?PREF_DHT_ENTRY_POINT_PORT:
+ PREF_DHT_ENTRY_POINT_PORT6;
std::pair<std::string, uint16_t> addr
- (e->getOption()->get(PREF_DHT_ENTRY_POINT_HOST),
- e->getOption()->getAsInt(PREF_DHT_ENTRY_POINT_PORT));
+ (e->getOption()->get(prefEntryPointHost),
+ e->getOption()->getAsInt(prefEntryPointPort));
std::vector<std::pair<std::string, uint16_t> > entryPoints;
entryPoints.push_back(addr);
DHTEntryPointNameResolveCommand* command =
@@ -258,24 +282,27 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
}
{
DHTAutoSaveCommand* command =
- new DHTAutoSaveCommand(e->newCUID(), e, 30*60);
+ new DHTAutoSaveCommand(e->newCUID(), e, family, 30*60);
command->setLocalNode(localNode);
command->setRoutingTable(routingTable);
tempCommands->push_back(command);
}
- initialized_ = true;
+ if(family == AF_INET) {
+ DHTRegistry::setInitialized(true);
+ } else {
+ DHTRegistry::setInitialized6(true);
+ }
commands.insert(commands.end(), tempCommands->begin(), tempCommands->end());
tempCommands->clear();
} catch(RecoverableException& e) {
logger_->error("Exception caught while initializing DHT functionality."
" DHT is disabled.", e);
- DHTRegistry::clearData();
+ if(family == AF_INET) {
+ DHTRegistry::clearData();
+ } else {
+ DHTRegistry::clearData6();
+ }
}
}
-bool DHTSetup::initialized()
-{
- return initialized_;
-}
-
} // namespace aria2
diff --git a/src/DHTSetup.h b/src/DHTSetup.h
index ca932554..08d5cdd7 100644
--- a/src/DHTSetup.h
+++ b/src/DHTSetup.h
@@ -45,18 +45,13 @@ class Command;
class DHTSetup {
private:
- static bool initialized_;
-
Logger* logger_;
-
public:
DHTSetup();
~DHTSetup();
- void setup(std::vector<Command*>& commands, DownloadEngine* e);
-
- static bool initialized();
+ void setup(std::vector<Command*>& commands, DownloadEngine* e, int family);
};
} // namespace aria2
diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc
index d0b22e33..6dbdcb5e 100644
--- a/src/FtpConnection.cc
+++ b/src/FtpConnection.cc
@@ -223,7 +223,7 @@ SharedHandle<SocketCore> FtpConnection::createServerSocket()
std::pair<std::string, uint16_t> addrinfo;
socket_->getAddrInfo(addrinfo);
SharedHandle<SocketCore> serverSocket(new SocketCore());
- serverSocket->bind(addrinfo.first, 0);
+ serverSocket->bind(addrinfo.first, 0, AF_UNSPEC);
serverSocket->beginListen();
serverSocket->setNonBlockingMode();
return serverSocket;
diff --git a/src/LpdMessageReceiver.cc b/src/LpdMessageReceiver.cc
index 81256bad..4935d6fa 100644
--- a/src/LpdMessageReceiver.cc
+++ b/src/LpdMessageReceiver.cc
@@ -56,7 +56,7 @@ bool LpdMessageReceiver::init(const std::string& localAddr)
// Binding multicast address fails under Windows.
socket_->bindWithFamily(multicastPort_, AF_INET);
#else // !__MINGW32__
- socket_->bind(multicastAddress_, multicastPort_);
+ socket_->bind(multicastAddress_, multicastPort_, AF_INET);
#endif // !__MINGW32__
if(logger_->debug()) {
logger_->debug("Joining multicast group. %s:%u, localAddr=%s",
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
index 52dafb22..7766ef0a 100644
--- a/src/OptionHandlerFactory.cc
+++ b/src/OptionHandlerFactory.cc
@@ -1326,6 +1326,16 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
+ SharedHandle<OptionHandler> op(new HostPortOptionHandler
+ (PREF_DHT_ENTRY_POINT6,
+ TEXT_DHT_ENTRY_POINT6,
+ NO_DEFAULT_VALUE,
+ PREF_DHT_ENTRY_POINT_HOST6,
+ PREF_DHT_ENTRY_POINT_PORT6));
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_DHT_FILE_PATH,
TEXT_DHT_FILE_PATH,
@@ -1335,6 +1345,34 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
+ SharedHandle<OptionHandler> op(new DefaultOptionHandler
+ (PREF_DHT_FILE_PATH6,
+ TEXT_DHT_FILE_PATH6,
+ util::getHomeDir()+"/.aria2/dht6.dat",
+ "/PATH/TO/DHT_DAT"));
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
+ SharedHandle<OptionHandler> op(new DefaultOptionHandler
+ (PREF_DHT_LISTEN_ADDR,
+ NO_DESCRIPTION,
+ NO_DEFAULT_VALUE));
+ op->hide();
+ op->addTag(TAG_BASIC);
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
+ SharedHandle<OptionHandler> op(new DefaultOptionHandler
+ (PREF_DHT_LISTEN_ADDR6,
+ TEXT_DHT_LISTEN_ADDR6,
+ NO_DEFAULT_VALUE));
+ op->addTag(TAG_BASIC);
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
(PREF_DHT_LISTEN_PORT,
TEXT_DHT_LISTEN_PORT,
@@ -1365,6 +1403,16 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
}
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
+ (PREF_ENABLE_DHT6,
+ TEXT_ENABLE_DHT6,
+ V_FALSE,
+ OptionHandler::OPT_ARG));
+ op->addTag(TAG_BASIC);
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
+ SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_PEER_EXCHANGE,
TEXT_ENABLE_PEER_EXCHANGE,
V_TRUE,
diff --git a/src/OptionHandlerImpl.h b/src/OptionHandlerImpl.h
index a1d63c90..b39578d5 100644
--- a/src/OptionHandlerImpl.h
+++ b/src/OptionHandlerImpl.h
@@ -522,17 +522,18 @@ public:
virtual void parseArg(Option& option, const std::string& optarg)
{
- std::pair<std::string, std::string> proxy = util::split(optarg, ":");
- int32_t port = util::parseInt(proxy.second);
- if(proxy.first.empty() || proxy.second.empty() ||
- port <= 0 || 65535 < port) {
- throw DL_ABORT_EX(_("unrecognized proxy format"));
+ std::string uri = "http://";
+ uri += optarg;
+ Request req;
+ if(!req.setUri(uri)) {
+ throw DL_ABORT_EX(_("Unrecognized format"));
}
option.put(optName_, optarg);
- setHostAndPort(option, proxy.first, port);
+ setHostAndPort(option, req.getHost(), req.getPort());
}
- void setHostAndPort(Option& option, const std::string& hostname, uint16_t port)
+ void setHostAndPort
+ (Option& option, const std::string& hostname, uint16_t port)
{
option.put(hostOptionName_, hostname);
option.put(portOptionName_, util::uitos(port));
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index 87d4b1c9..31c8f57a 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -60,8 +60,13 @@
#include "DHTTaskQueue.h"
#include "DHTTaskFactory.h"
#include "DHTNode.h"
-#include "DHTSetup.h"
#include "DHTRegistry.h"
+#include "DHTPeerAnnounceStorage.h"
+#include "DHTTokenTracker.h"
+#include "DHTMessageDispatcher.h"
+#include "DHTMessageReceiver.h"
+#include "DHTMessageFactory.h"
+#include "DHTMessageCallback.h"
#include "PieceStorage.h"
#include "RequestGroup.h"
#include "BtAnnounce.h"
@@ -102,6 +107,17 @@ PeerInteractionCommand::PeerInteractionCommand
setWriteCheckSocket(getSocket());
setTimeout(getOption()->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
+
+ int family;
+ unsigned char compact[COMPACT_LEN_IPV6];
+ int compactlen = bittorrent::packcompact
+ (compact, getPeer()->getIPAddress(), getPeer()->getPort());
+ if(compactlen == COMPACT_LEN_IPV6) {
+ family = AF_INET6;
+ } else {
+ family = AF_INET;
+ }
+
SharedHandle<TorrentAttribute> torrentAttrs =
bittorrent::getTorrentAttrs(requestGroup_->getDownloadContext());
bool metadataGetMode = torrentAttrs->metadata.empty();
@@ -131,11 +147,18 @@ PeerInteractionCommand::PeerInteractionCommand
factory->setPieceStorage(pieceStorage);
factory->setPeerStorage(peerStorage);
factory->setExtensionMessageFactory(extensionMessageFactory);
- factory->setPeer(getPeer());
- factory->setLocalNode(DHTRegistry::getData().localNode);
- factory->setRoutingTable(DHTRegistry::getData().routingTable);
- factory->setTaskQueue(DHTRegistry::getData().taskQueue);
- factory->setTaskFactory(DHTRegistry::getData().taskFactory);
+ factory->setPeer(getPeer());
+ if(family == AF_INET) {
+ factory->setLocalNode(DHTRegistry::getData().localNode);
+ factory->setRoutingTable(DHTRegistry::getData().routingTable);
+ factory->setTaskQueue(DHTRegistry::getData().taskQueue);
+ factory->setTaskFactory(DHTRegistry::getData().taskFactory);
+ } else {
+ factory->setLocalNode(DHTRegistry::getData6().localNode);
+ factory->setRoutingTable(DHTRegistry::getData6().routingTable);
+ factory->setTaskQueue(DHTRegistry::getData6().taskQueue);
+ factory->setTaskFactory(DHTRegistry::getData6().taskFactory);
+ }
if(metadataGetMode) {
factory->enableMetadataGetMode();
}
@@ -192,10 +215,18 @@ PeerInteractionCommand::PeerInteractionCommand
if(getOption()->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
btInteractive->setUTPexEnabled(true);
}
- if(DHTSetup::initialized()) {
- btInteractive->setDHTEnabled(true);
- btInteractive->setLocalNode(DHTRegistry::getData().localNode);
- factory->setDHTEnabled(true);
+ if(family == AF_INET) {
+ if(DHTRegistry::isInitialized()) {
+ btInteractive->setDHTEnabled(true);
+ factory->setDHTEnabled(true);
+ btInteractive->setLocalNode(DHTRegistry::getData().localNode);
+ }
+ } else {
+ if(DHTRegistry::isInitialized6()) {
+ btInteractive->setDHTEnabled(true);
+ factory->setDHTEnabled(true);
+ btInteractive->setLocalNode(DHTRegistry::getData6().localNode);
+ }
}
}
btInteractive->setUTMetadataRequestFactory(utMetadataRequestFactory);
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index 42d65bd0..c5606e16 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -94,6 +94,15 @@
# include "BtPostDownloadHandler.h"
# include "DHTSetup.h"
# include "DHTRegistry.h"
+# include "DHTNode.h"
+# include "DHTRoutingTable.h"
+# include "DHTTaskQueue.h"
+# include "DHTTaskFactory.h"
+# include "DHTTokenTracker.h"
+# include "DHTMessageDispatcher.h"
+# include "DHTMessageReceiver.h"
+# include "DHTMessageFactory.h"
+# include "DHTMessageCallback.h"
# include "BtMessageFactory.h"
# include "BtRequestFactory.h"
# include "BtMessageDispatcher.h"
@@ -283,10 +292,18 @@ void RequestGroup::createInitialCommand
SharedHandle<BtProgressInfoFile>
(progressInfoFile))));
if(metadataGetMode) {
- if(option_->getAsBool(PREF_ENABLE_DHT)) {
- std::vector<Command*> dhtCommands;
- DHTSetup().setup(dhtCommands, e);
- e->addCommand(dhtCommands);
+ if(option_->getAsBool(PREF_ENABLE_DHT) ||
+ option_->getAsBool(PREF_ENABLE_DHT6)) {
+ if(option_->getAsBool(PREF_ENABLE_DHT)) {
+ std::vector<Command*> dhtCommands;
+ DHTSetup().setup(dhtCommands, e, AF_INET);
+ e->addCommand(dhtCommands);
+ }
+ if(option_->getAsBool(PREF_ENABLE_DHT6)) {
+ std::vector<Command*> dhtCommands;
+ DHTSetup().setup(dhtCommands, e, AF_INET6);
+ e->addCommand(dhtCommands);
+ }
} else {
logger_->notice("For BitTorrent Magnet URI, enabling DHT is strongly"
" recommended. See --enable-dht option.");
@@ -343,16 +360,25 @@ void RequestGroup::createInitialCommand
}
progressInfoFile_ = progressInfoFile;
- if(!torrentAttrs->privateTorrent && option_->getAsBool(PREF_ENABLE_DHT)) {
- std::vector<Command*> dhtCommands;
- DHTSetup().setup(dhtCommands, e);
- e->addCommand(dhtCommands);
+ if(!torrentAttrs->privateTorrent &&
+ (option_->getAsBool(PREF_ENABLE_DHT) ||
+ option_->getAsBool(PREF_ENABLE_DHT6))) {
+ if(option_->getAsBool(PREF_ENABLE_DHT)) {
+ std::vector<Command*> dhtCommands;
+ DHTSetup().setup(dhtCommands, e, AF_INET);
+ e->addCommand(dhtCommands);
+ }
+ if(option_->getAsBool(PREF_ENABLE_DHT6)) {
+ std::vector<Command*> dhtCommands;
+ DHTSetup().setup(dhtCommands, e, AF_INET6);
+ e->addCommand(dhtCommands);
+ }
const std::vector<std::pair<std::string, uint16_t> >& nodes =
torrentAttrs->nodes;
- if(!nodes.empty() && DHTSetup::initialized()) {
- std::vector<std::pair<std::string, uint16_t> > entryPoints(nodes);
+ // TODO Are nodes in torrent IPv4 only?
+ if(!nodes.empty() && DHTRegistry::isInitialized()) {
DHTEntryPointNameResolveCommand* command =
- new DHTEntryPointNameResolveCommand(e->newCUID(), e, entryPoints);
+ new DHTEntryPointNameResolveCommand(e->newCUID(), e, nodes);
command->setTaskQueue(DHTRegistry::getData().taskQueue);
command->setTaskFactory(DHTRegistry::getData().taskFactory);
command->setRoutingTable(DHTRegistry::getData().routingTable);
diff --git a/src/SocketCore.cc b/src/SocketCore.cc
index 7d8b076b..a445b35c 100644
--- a/src/SocketCore.cc
+++ b/src/SocketCore.cc
@@ -54,6 +54,7 @@
#include "TimeA2.h"
#include "a2functional.h"
#include "LogFactory.h"
+#include "A2STR.h"
#ifdef ENABLE_SSL
# include "TLSContext.h"
#endif // ENABLE_SSL
@@ -215,6 +216,14 @@ static sock_t bindInternal(int family, int socktype, int protocol,
CLOSE(fd);
return -1;
}
+ if(family == AF_INET6) {
+ int sockopt = 1;
+ if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (a2_sockopt_t) &sockopt,
+ sizeof(sockopt)) < 0) {
+ CLOSE(fd);
+ return -1;
+ }
+ }
if(::bind(fd, addr, addrlen) == -1) {
error = errorMsg();
CLOSE(fd);
@@ -258,25 +267,19 @@ void SocketCore::bindWithFamily(uint16_t port, int family, int flags)
}
}
-void SocketCore::bind(const std::string& addr, uint16_t port, int flags)
+void SocketCore::bind
+(const std::string& addr, uint16_t port, int family, int flags)
{
closeConnection();
std::string error;
- sock_t fd =
- bindTo(addr.c_str(), port, protocolFamily_, sockType_, flags, error);
- if(fd == (sock_t)-1) {
- throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, error.c_str()).str());
+ const char* addrp;
+ if(addr.empty()) {
+ addrp = 0;
} else {
- sockfd_ = fd;
+ addrp = addr.c_str();
}
-}
-
-void SocketCore::bind(uint16_t port, int flags)
-{
- closeConnection();
- std::string error;
if(!(flags&AI_PASSIVE) || bindAddrs_.empty()) {
- sock_t fd = bindTo(0, port, protocolFamily_, sockType_, flags, error);
+ sock_t fd = bindTo(addrp, port, family, sockType_, flags, error);
if(fd != (sock_t) -1) {
sockfd_ = fd;
}
@@ -294,7 +297,11 @@ void SocketCore::bind(uint16_t port, int flags)
error = gai_strerror(s);
continue;
}
- sock_t fd = bindTo(host, port, protocolFamily_, sockType_, flags, error);
+ if(addrp && strcmp(host, addrp) != 0) {
+ // TODO we should assign something to error?
+ continue;
+ }
+ sock_t fd = bindTo(addrp, port, family, sockType_, flags, error);
if(fd != (sock_t)-1) {
sockfd_ = fd;
break;
@@ -306,6 +313,11 @@ void SocketCore::bind(uint16_t port, int flags)
}
}
+void SocketCore::bind(uint16_t port, int flags)
+{
+ bind(A2STR::NIL, port, protocolFamily_, flags);
+}
+
void SocketCore::bind(const struct sockaddr* addr, socklen_t addrlen)
{
closeConnection();
diff --git a/src/SocketCore.h b/src/SocketCore.h
index 7de5a0eb..3ea31b87 100644
--- a/src/SocketCore.h
+++ b/src/SocketCore.h
@@ -137,8 +137,6 @@ public:
void bindWithFamily(uint16_t port, int family, int flags = AI_PASSIVE);
- void bind(const std::string& addr, uint16_t port, int flags = AI_PASSIVE);
-
/**
* Creates a socket and bind it with locahost's address and port.
* flags is set to struct addrinfo's ai_flags.
@@ -147,6 +145,9 @@ public:
*/
void bind(uint16_t port, int flags = AI_PASSIVE);
+ void bind
+ (const std::string& addr, uint16_t port, int family, int flags = AI_PASSIVE);
+
/**
* Listens form connection on it.
* Call bind(uint16_t) before calling this function.
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
index 7b342aa9..6801e95e 100644
--- a/src/bittorrent_helper.cc
+++ b/src/bittorrent_helper.cc
@@ -994,6 +994,17 @@ std::string torrent2Magnet(const SharedHandle<TorrentAttribute>& attrs)
return uri;
}
+int getCompactLength(int family)
+{
+ if(family == AF_INET) {
+ return COMPACT_LEN_IPV4;
+ } else if(family == AF_INET6) {
+ return COMPACT_LEN_IPV6;
+ } else {
+ return 0;
+ }
+}
+
} // namespace bittorrent
} // namespace aria2
diff --git a/src/bittorrent_helper.h b/src/bittorrent_helper.h
index 8d890b5b..cf9a40f5 100644
--- a/src/bittorrent_helper.h
+++ b/src/bittorrent_helper.h
@@ -246,6 +246,9 @@ void extractPeer(const ValueBase* peerData, int family, OutputIterator dest)
const unsigned char* end = base+length;
for(; base != end; base += unit) {
std::pair<std::string, uint16_t> p = unpackcompact(base, family_);
+ if(p.first.empty()) {
+ continue;
+ }
*dest_++ = SharedHandle<Peer>(new Peer(p.first, p.second));
}
}
@@ -288,6 +291,8 @@ void extractPeer
return extractPeer(peerData.get(), family, dest);
}
+int getCompactLength(int family);
+
} // namespace bittorrent
} // namespace aria2
diff --git a/src/prefs.cc b/src/prefs.cc
index 2712fb48..a11ac8ad 100644
--- a/src/prefs.cc
+++ b/src/prefs.cc
@@ -308,6 +308,8 @@ const std::string PREF_PEER_ID_PREFIX("peer-id-prefix");
const std::string PREF_ENABLE_PEER_EXCHANGE("enable-peer-exchange");
// values: true | false
const std::string PREF_ENABLE_DHT("enable-dht");
+// values: a string
+const std::string PREF_DHT_LISTEN_ADDR("dht-listen-addr");
// values: 1*digit
const std::string PREF_DHT_LISTEN_PORT("dht-listen-port");
// values: a string
@@ -318,6 +320,18 @@ const std::string PREF_DHT_ENTRY_POINT_PORT("dht-entry-point-port");
const std::string PREF_DHT_ENTRY_POINT("dht-entry-point");
// values: a string
const std::string PREF_DHT_FILE_PATH("dht-file-path");
+// values: true | false
+const std::string PREF_ENABLE_DHT6("enable-dht6");
+// values: a string
+const std::string PREF_DHT_LISTEN_ADDR6("dht-listen-addr6");
+// values: a string
+const std::string PREF_DHT_ENTRY_POINT_HOST6("dht-entry-point-host6");
+// values: 1*digit
+const std::string PREF_DHT_ENTRY_POINT_PORT6("dht-entry-point-port6");
+// values: a string (hostname:port)
+const std::string PREF_DHT_ENTRY_POINT6("dht-entry-point6");
+// values: a string
+const std::string PREF_DHT_FILE_PATH6("dht-file-path6");
// values: plain | arc4
const std::string PREF_BT_MIN_CRYPTO_LEVEL("bt-min-crypto-level");
const std::string V_PLAIN("plain");
diff --git a/src/prefs.h b/src/prefs.h
index 34193d9c..d49d4556 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -312,6 +312,8 @@ extern const std::string PREF_PEER_ID_PREFIX;
extern const std::string PREF_ENABLE_PEER_EXCHANGE;
// values: true | false
extern const std::string PREF_ENABLE_DHT;
+// values: a string
+extern const std::string PREF_DHT_LISTEN_ADDR;
// values: 1*digit
extern const std::string PREF_DHT_LISTEN_PORT;
// values: a string
@@ -322,6 +324,18 @@ extern const std::string PREF_DHT_ENTRY_POINT_PORT;
extern const std::string PREF_DHT_ENTRY_POINT;
// values: a string
extern const std::string PREF_DHT_FILE_PATH;
+// values: true | false
+extern const std::string PREF_ENABLE_DHT6;
+// values: a string
+extern const std::string PREF_DHT_LISTEN_ADDR6;
+// values: a string
+extern const std::string PREF_DHT_ENTRY_POINT_HOST6;
+// values: 1*digit
+extern const std::string PREF_DHT_ENTRY_POINT_PORT6;
+// values: a string (hostname:port)
+extern const std::string PREF_DHT_ENTRY_POINT6;
+// values: a string
+extern const std::string PREF_DHT_FILE_PATH6;
// values: plain | arc4
extern const std::string PREF_BT_MIN_CRYPTO_LEVEL;
extern const std::string V_PLAIN;
diff --git a/src/usage_text.h b/src/usage_text.h
index 6eb97ee2..6c805c01 100644
--- a/src/usage_text.h
+++ b/src/usage_text.h
@@ -297,18 +297,18 @@
#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.")
+ _(" --enable-dht[=true|false] Enable IPv4 DHT functionality.")
#define TEXT_DHT_LISTEN_PORT \
- _(" --dht-listen-port=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.")
+ _(" --dht-listen-port=PORT... Set UDP listening port for both IPv4 and IPv6\n" \
+ " DHT. Multiple ports can be specified by using\n" \
+ " ',', for example: \"6881,6885\". You can also\n" \
+ " use '-' to specify a range: \"6881-6999\". ','\n" \
+ " and '-' can be used together.")
#define TEXT_DHT_ENTRY_POINT \
- _(" --dht-entry-point=HOST:PORT Set host and port as an entry point to DHT\n" \
+ _(" --dht-entry-point=HOST:PORT Set host and port as an entry point to IPv4 DHT\n" \
" network.")
#define TEXT_DHT_FILE_PATH \
- _(" --dht-file-path=PATH Change the DHT routing table file to PATH.")
+ _(" --dht-file-path=PATH Change the IPv4 DHT routing table file to PATH.")
#define TEXT_BT_MIN_CRYPTO_LEVEL \
_(" --bt-min-crypto-level=plain|arc4 Set minimum level of encryption method.\n" \
" If several encryption methods are provided by a\n" \
@@ -714,3 +714,15 @@
_(" --enable-async-dns6[=true|false] Enable IPv6 name resolution in asynchronous\n" \
" DNS resolver. This option will be ignored when\n" \
" --async-dns=false.")
+#define TEXT_ENABLE_DHT6 \
+ _(" --enable-dht6[=true|false] Enable IPv6 DHT functionality. See also\n" \
+ " --dht-listen-addr6 option.")
+#define TEXT_DHT_LISTEN_ADDR6 \
+ _(" --dht-listen-addr6=ADDR Specify address to bind socket for IPv6 DHT. \n" \
+ " It should be a global unicast IPv6 address of the\n" \
+ " host.")
+#define TEXT_DHT_ENTRY_POINT6 \
+ _(" --dht-entry-point6=HOST:PORT Set host and port as an entry point to IPv6 DHT\n" \
+ " network.")
+#define TEXT_DHT_FILE_PATH6 \
+ _(" --dht-file-path6=PATH Change the IPv6 DHT routing table file to PATH.")
diff --git a/test/DHTConnectionImplTest.cc b/test/DHTConnectionImplTest.cc
index 15a66a16..2e24ef31 100644
--- a/test/DHTConnectionImplTest.cc
+++ b/test/DHTConnectionImplTest.cc
@@ -1,9 +1,12 @@
#include "DHTConnectionImpl.h"
-#include "Exception.h"
-#include "SocketCore.h"
+
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
+#include "Exception.h"
+#include "SocketCore.h"
+#include "A2STR.h"
+
namespace aria2 {
class DHTConnectionImplTest:public CppUnit::TestFixture {
@@ -25,13 +28,13 @@ CPPUNIT_TEST_SUITE_REGISTRATION(DHTConnectionImplTest);
void DHTConnectionImplTest::testWriteAndReadData()
{
try {
- DHTConnectionImpl con1;
+ DHTConnectionImpl con1(AF_INET);
uint16_t con1port = 0;
- CPPUNIT_ASSERT(con1.bind(con1port));
+ CPPUNIT_ASSERT(con1.bind(con1port, A2STR::NIL));
- DHTConnectionImpl con2;
+ DHTConnectionImpl con2(AF_INET);
uint16_t con2port = 0;
- CPPUNIT_ASSERT(con2.bind(con2port));
+ CPPUNIT_ASSERT(con2.bind(con2port, A2STR::NIL));
std::string message1 = "hello world.";
// hostname should be "localhost", not 127.0.0.1. Test failed on Mac OSX10.5
diff --git a/test/DHTFindNodeReplyMessageTest.cc b/test/DHTFindNodeReplyMessageTest.cc
index 1191e279..7a15b445 100644
--- a/test/DHTFindNodeReplyMessageTest.cc
+++ b/test/DHTFindNodeReplyMessageTest.cc
@@ -15,6 +15,7 @@ class DHTFindNodeReplyMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DHTFindNodeReplyMessageTest);
CPPUNIT_TEST(testGetBencodedMessage);
+ CPPUNIT_TEST(testGetBencodedMessage6);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@@ -22,6 +23,8 @@ public:
void tearDown() {}
void testGetBencodedMessage();
+
+ void testGetBencodedMessage6();
};
@@ -36,7 +39,7 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
util::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
std::string transactionID(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
- DHTFindNodeReplyMessage msg(localNode, remoteNode, transactionID);
+ DHTFindNodeReplyMessage msg(AF_INET, localNode, remoteNode, transactionID);
msg.setVersion("A200");
std::string compactNodeInfo;
SharedHandle<DHTNode> nodes[8];
@@ -46,8 +49,8 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
nodes[i]->setPort(6881+i);
unsigned char buf[COMPACT_LEN_IPV6];
- bittorrent::packcompact
- (buf, nodes[i]->getIPAddress(), nodes[i]->getPort());
+ CPPUNIT_ASSERT_EQUAL(COMPACT_LEN_IPV4, bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
compactNodeInfo +=
std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
@@ -69,4 +72,46 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
}
+void DHTFindNodeReplyMessageTest::testGetBencodedMessage6()
+{
+ SharedHandle<DHTNode> localNode(new DHTNode());
+ SharedHandle<DHTNode> remoteNode(new DHTNode());
+
+ unsigned char tid[DHT_TRANSACTION_ID_LENGTH];
+ util::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
+ std::string transactionID(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
+
+ DHTFindNodeReplyMessage msg(AF_INET6, localNode, remoteNode, transactionID);
+ msg.setVersion("A200");
+ std::string compactNodeInfo;
+ SharedHandle<DHTNode> nodes[8];
+ for(size_t i = 0; i < DHTBucket::K; ++i) {
+ nodes[i].reset(new DHTNode());
+ nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
+ nodes[i]->setPort(6881+i);
+
+ unsigned char buf[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL(COMPACT_LEN_IPV6, bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
+ compactNodeInfo +=
+ std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
+ std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
+ }
+ msg.setClosestKNodes
+ (std::vector<SharedHandle<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));
+
+ std::string msgbody = msg.getBencodedMessage();
+
+ Dict dict;
+ dict.put("t", transactionID);
+ dict.put("v", "A200");
+ dict.put("y", "r");
+ SharedHandle<Dict> rDict = Dict::g();
+ rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+ rDict->put("nodes6", compactNodeInfo);
+ dict.put("r", rDict);
+
+ CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
+}
+
} // namespace aria2
diff --git a/test/DHTGetPeersMessageTest.cc b/test/DHTGetPeersMessageTest.cc
index 9a817cbf..11a280c1 100644
--- a/test/DHTGetPeersMessageTest.cc
+++ b/test/DHTGetPeersMessageTest.cc
@@ -32,23 +32,10 @@ public:
class MockDHTMessageFactory2:public MockDHTMessageFactory {
public:
virtual SharedHandle<DHTResponseMessage>
- createGetPeersReplyMessage(const SharedHandle<DHTNode>& remoteNode,
- const std::vector<SharedHandle<Peer> >& peers,
- const std::string& token,
- const std::string& transactionID)
- {
- SharedHandle<MockDHTResponseMessage> m
- (new MockDHTResponseMessage
- (localNode_, remoteNode, "get_peers", transactionID));
- m->peers_ = peers;
- m->token_ = token;
- return m;
- }
-
- virtual SharedHandle<DHTResponseMessage>
createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
const std::vector<SharedHandle<DHTNode> >& closestKNodes,
+ const std::vector<SharedHandle<Peer> >& peers,
const std::string& token,
const std::string& transactionID)
{
@@ -56,10 +43,10 @@ public:
(new MockDHTResponseMessage
(localNode_, remoteNode, "get_peers", transactionID));
m->nodes_ = closestKNodes;
+ m->peers_ = peers;
m->token_ = token;
return m;
}
-
};
};
@@ -115,14 +102,13 @@ void DHTGetPeersMessageTest::testDoReceivedAction()
MockDHTMessageDispatcher dispatcher;
MockDHTMessageFactory2 factory;
factory.setLocalNode(localNode);
+ DHTRoutingTable routingTable(localNode);
DHTGetPeersMessage msg(localNode, remoteNode, infoHash, transactionID);
- msg.setTokenTracker(WeakHandle<DHTTokenTracker>
- (&tokenTracker));
- msg.setMessageDispatcher(WeakHandle<DHTMessageDispatcher>
- (&dispatcher));
- msg.setMessageFactory(WeakHandle<DHTMessageFactory>
- (&factory));
+ msg.setRoutingTable(WeakHandle<DHTRoutingTable>(&routingTable));
+ msg.setTokenTracker(WeakHandle<DHTTokenTracker>(&tokenTracker));
+ msg.setMessageDispatcher(WeakHandle<DHTMessageDispatcher>(&dispatcher));
+ msg.setMessageFactory(WeakHandle<DHTMessageFactory>(&factory));
{
// localhost has peer contact information for that infohash.
DHTPeerAnnounceStorage peerAnnounceStorage;
diff --git a/test/DHTGetPeersReplyMessageTest.cc b/test/DHTGetPeersReplyMessageTest.cc
index 1eff779e..064a2bd5 100644
--- a/test/DHTGetPeersReplyMessageTest.cc
+++ b/test/DHTGetPeersReplyMessageTest.cc
@@ -16,6 +16,7 @@ class DHTGetPeersReplyMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DHTGetPeersReplyMessageTest);
CPPUNIT_TEST(testGetBencodedMessage);
+ CPPUNIT_TEST(testGetBencodedMessage6);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@@ -23,6 +24,8 @@ public:
void tearDown() {}
void testGetBencodedMessage();
+
+ void testGetBencodedMessage6();
};
@@ -39,7 +42,8 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
std::string token = "token";
- DHTGetPeersReplyMessage msg(localNode, remoteNode, token, transactionID);
+ DHTGetPeersReplyMessage msg
+ (AF_INET, localNode, remoteNode, token, transactionID);
msg.setVersion("A200");
Dict dict;
dict.put("t", transactionID);
@@ -58,38 +62,97 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
nodes[i]->setPort(6881+i);
unsigned char buf[COMPACT_LEN_IPV6];
- bittorrent::packcompact
- (buf, nodes[i]->getIPAddress(), nodes[i]->getPort());
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV4,
+ bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
compactNodeInfo +=
std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
msg.setClosestKNodes
(std::vector<SharedHandle<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));
-
- std::string msgbody = msg.getBencodedMessage();
-
rDict->put("nodes", compactNodeInfo);
- CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
- util::percentEncode(msgbody));
- }
- rDict->removeKey("nodes");
- {
std::vector<SharedHandle<Peer> > peers;
SharedHandle<List> valuesList = List::g();
for(size_t i = 0; i < 4; ++i) {
SharedHandle<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
unsigned char buffer[COMPACT_LEN_IPV6];
- bittorrent::packcompact(buffer, peer->getIPAddress(), peer->getPort());
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV4,
+ bittorrent::packcompact
+ (buffer, peer->getIPAddress(), peer->getPort()));
valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
peers.push_back(peer);
}
+ msg.setValues(peers);
rDict->put("values", valuesList);
+ std::string msgbody = msg.getBencodedMessage();
+ CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
+ util::percentEncode(msgbody));
+ }
+}
+
+void DHTGetPeersReplyMessageTest::testGetBencodedMessage6()
+{
+ SharedHandle<DHTNode> localNode(new DHTNode());
+ SharedHandle<DHTNode> remoteNode(new DHTNode());
+
+ unsigned char tid[DHT_TRANSACTION_ID_LENGTH];
+ util::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
+ std::string transactionID(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
+
+ std::string token = "token";
+
+ DHTGetPeersReplyMessage msg
+ (AF_INET6, localNode, remoteNode, token, transactionID);
+ msg.setVersion("A200");
+ Dict dict;
+ dict.put("t", transactionID);
+ dict.put("v", "A200");
+ dict.put("y", "r");
+ SharedHandle<Dict> rDict = Dict::g();
+ rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+ rDict->put("token", token);
+ dict.put("r", rDict);
+ {
+ std::string compactNodeInfo;
+ SharedHandle<DHTNode> nodes[8];
+ for(size_t i = 0; i < DHTBucket::K; ++i) {
+ nodes[i].reset(new DHTNode());
+ nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
+ nodes[i]->setPort(6881+i);
+
+ unsigned char buf[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV6, bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
+ compactNodeInfo +=
+ std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
+ std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
+ }
+ msg.setClosestKNodes
+ (std::vector<SharedHandle<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));
+ rDict->put("nodes6", compactNodeInfo);
+
+ std::vector<SharedHandle<Peer> > peers;
+ SharedHandle<List> valuesList = List::g();
+ for(size_t i = 0; i < 4; ++i) {
+ SharedHandle<Peer> peer(new Peer("2001::100"+util::uitos(i+1), 6881+i));
+ unsigned char buffer[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV6,
+ bittorrent::packcompact
+ (buffer, peer->getIPAddress(), peer->getPort()));
+ valuesList->append(String::g(buffer, COMPACT_LEN_IPV6));
+ peers.push_back(peer);
+ }
msg.setValues(peers);
- std::string msgbody = msg.getBencodedMessage();
+ rDict->put("values", valuesList);
+ std::string msgbody = msg.getBencodedMessage();
CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
util::percentEncode(msgbody));
}
diff --git a/test/DHTMessageFactoryImplTest.cc b/test/DHTMessageFactoryImplTest.cc
index 6210c27a..04bd2ff5 100644
--- a/test/DHTMessageFactoryImplTest.cc
+++ b/test/DHTMessageFactoryImplTest.cc
@@ -31,9 +31,10 @@ class DHTMessageFactoryImplTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreatePingReplyMessage);
CPPUNIT_TEST(testCreateFindNodeMessage);
CPPUNIT_TEST(testCreateFindNodeReplyMessage);
+ CPPUNIT_TEST(testCreateFindNodeReplyMessage6);
CPPUNIT_TEST(testCreateGetPeersMessage);
- CPPUNIT_TEST(testCreateGetPeersReplyMessage_nodes);
- CPPUNIT_TEST(testCreateGetPeersReplyMessage_values);
+ CPPUNIT_TEST(testCreateGetPeersReplyMessage);
+ CPPUNIT_TEST(testCreateGetPeersReplyMessage6);
CPPUNIT_TEST(testCreateAnnouncePeerMessage);
CPPUNIT_TEST(testCreateAnnouncePeerReplyMessage);
CPPUNIT_TEST(testReceivedErrorMessage);
@@ -52,7 +53,7 @@ public:
void setUp()
{
localNode.reset(new DHTNode());
- factory.reset(new DHTMessageFactoryImpl());
+ factory.reset(new DHTMessageFactoryImpl(AF_INET));
factory->setLocalNode(localNode);
memset(transactionID, 0xff, DHT_TRANSACTION_ID_LENGTH);
memset(remoteNodeID, 0x0f, DHT_ID_LENGTH);
@@ -66,9 +67,10 @@ public:
void testCreatePingReplyMessage();
void testCreateFindNodeMessage();
void testCreateFindNodeReplyMessage();
+ void testCreateFindNodeReplyMessage6();
void testCreateGetPeersMessage();
- void testCreateGetPeersReplyMessage_nodes();
- void testCreateGetPeersReplyMessage_values();
+ void testCreateGetPeersReplyMessage();
+ void testCreateGetPeersReplyMessage6();
void testCreateAnnouncePeerMessage();
void testCreateAnnouncePeerReplyMessage();
void testReceivedErrorMessage();
@@ -169,8 +171,10 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
nodes[i]->setPort(6881+i);
unsigned char buf[COMPACT_LEN_IPV6];
- bittorrent::packcompact
- (buf, nodes[i]->getIPAddress(), nodes[i]->getPort());
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV4,
+ bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
compactNodeInfo +=
std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
@@ -200,6 +204,58 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
}
}
+void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage6()
+{
+ factory.reset(new DHTMessageFactoryImpl(AF_INET6));
+ factory->setLocalNode(localNode);
+ factory->setRoutingTable(routingTable);
+ try {
+ Dict dict;
+ dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+ dict.put("y", "r");
+ SharedHandle<Dict> rDict = Dict::g();
+ rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
+ std::string compactNodeInfo;
+ SharedHandle<DHTNode> nodes[8];
+ for(size_t i = 0; i < DHTBucket::K; ++i) {
+ nodes[i].reset(new DHTNode());
+ nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
+ nodes[i]->setPort(6881+i);
+
+ unsigned char buf[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV6,
+ bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
+ compactNodeInfo +=
+ std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
+ std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
+ }
+ rDict->put("nodes6", compactNodeInfo);
+ dict.put("r", rDict);
+
+ SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
+ remoteNode->setIPAddress("2001::2001");
+ remoteNode->setPort(6881);
+
+ SharedHandle<DHTFindNodeReplyMessage> m
+ (dynamic_pointer_cast<DHTFindNodeReplyMessage>
+ (factory->createResponseMessage("find_node", &dict,
+ remoteNode->getIPAddress(),
+ remoteNode->getPort())));
+
+ CPPUNIT_ASSERT(localNode == m->getLocalNode());
+ CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
+ CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
+ CPPUNIT_ASSERT(nodes[0] == m->getClosestKNodes()[0]);
+ CPPUNIT_ASSERT(nodes[7] == m->getClosestKNodes()[7]);
+ CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
+ util::toHex(m->getTransactionID()));
+ } catch(Exception& e) {
+ CPPUNIT_FAIL(e.stackTrace());
+ }
+}
+
void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
{
Dict dict;
@@ -228,7 +284,7 @@ void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
util::toHex(m->getInfoHash(), DHT_ID_LENGTH));
}
-void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
+void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage()
{
try {
Dict dict;
@@ -244,13 +300,30 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
nodes[i]->setPort(6881+i);
unsigned char buf[COMPACT_LEN_IPV6];
- bittorrent::packcompact
- (buf, nodes[i]->getIPAddress(), nodes[i]->getPort());
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV4,
+ bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
compactNodeInfo +=
std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
rDict->put("nodes", compactNodeInfo);
+
+ std::deque<SharedHandle<Peer> > peers;
+ SharedHandle<List> valuesList = List::g();
+ for(size_t i = 0; i < 4; ++i) {
+ SharedHandle<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
+ unsigned char buffer[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV4,
+ bittorrent::packcompact
+ (buffer, peer->getIPAddress(), peer->getPort()));
+ valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
+ peers.push_back(peer);
+ }
+ rDict->put("values", valuesList);
+
rDict->put("token", "token");
dict.put("r", rDict);
@@ -270,6 +343,9 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
CPPUNIT_ASSERT(nodes[0] == m->getClosestKNodes()[0]);
CPPUNIT_ASSERT(nodes[7] == m->getClosestKNodes()[7]);
+ CPPUNIT_ASSERT_EQUAL((size_t)4, m->getValues().size());
+ CPPUNIT_ASSERT(peers[0] == m->getValues()[0]);
+ CPPUNIT_ASSERT(peers[3] == m->getValues()[3]);
CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
util::toHex(m->getTransactionID()));
} catch(Exception& e) {
@@ -277,31 +353,54 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
}
}
-void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
+void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage6()
{
+ factory.reset(new DHTMessageFactoryImpl(AF_INET6));
+ factory->setLocalNode(localNode);
+ factory->setRoutingTable(routingTable);
try {
Dict dict;
dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
dict.put("y", "r");
SharedHandle<Dict> rDict = Dict::g();
rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
+ std::string compactNodeInfo;
+ SharedHandle<DHTNode> nodes[8];
+ for(size_t i = 0; i < DHTBucket::K; ++i) {
+ nodes[i].reset(new DHTNode());
+ nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
+ nodes[i]->setPort(6881+i);
+
+ unsigned char buf[COMPACT_LEN_IPV6];
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV6,
+ bittorrent::packcompact
+ (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
+ compactNodeInfo +=
+ std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
+ std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
+ }
+ rDict->put("nodes6", compactNodeInfo);
std::deque<SharedHandle<Peer> > peers;
SharedHandle<List> valuesList = List::g();
for(size_t i = 0; i < 4; ++i) {
- SharedHandle<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
+ SharedHandle<Peer> peer(new Peer("2001::100"+util::uitos(i+1), 6881+i));
unsigned char buffer[COMPACT_LEN_IPV6];
- bittorrent::packcompact
- (buffer, peer->getIPAddress(), peer->getPort());
- valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
+ CPPUNIT_ASSERT_EQUAL
+ (COMPACT_LEN_IPV6,
+ bittorrent::packcompact
+ (buffer, peer->getIPAddress(), peer->getPort()));
+ valuesList->append(String::g(buffer, COMPACT_LEN_IPV6));
peers.push_back(peer);
}
rDict->put("values", valuesList);
+
rDict->put("token", "token");
dict.put("r", rDict);
SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
- remoteNode->setIPAddress("192.168.0.1");
+ remoteNode->setIPAddress("2001::2001");
remoteNode->setPort(6881);
SharedHandle<DHTGetPeersReplyMessage> m
@@ -313,6 +412,9 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
CPPUNIT_ASSERT(localNode == m->getLocalNode());
CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
CPPUNIT_ASSERT_EQUAL(std::string("token"), m->getToken());
+ CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
+ CPPUNIT_ASSERT(nodes[0] == m->getClosestKNodes()[0]);
+ CPPUNIT_ASSERT(nodes[7] == m->getClosestKNodes()[7]);
CPPUNIT_ASSERT_EQUAL((size_t)4, m->getValues().size());
CPPUNIT_ASSERT(peers[0] == m->getValues()[0]);
CPPUNIT_ASSERT(peers[3] == m->getValues()[3]);
diff --git a/test/DHTRoutingTableDeserializerTest.cc b/test/DHTRoutingTableDeserializerTest.cc
index 7f2c8d7e..fcd737c4 100644
--- a/test/DHTRoutingTableDeserializerTest.cc
+++ b/test/DHTRoutingTableDeserializerTest.cc
@@ -20,6 +20,7 @@ class DHTRoutingTableDeserializerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DHTRoutingTableDeserializerTest);
CPPUNIT_TEST(testDeserialize);
+ CPPUNIT_TEST(testDeserialize6);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@@ -27,6 +28,8 @@ public:
void tearDown() {}
void testDeserialize();
+
+ void testDeserialize6();
};
@@ -45,14 +48,14 @@ void DHTRoutingTableDeserializerTest::testDeserialize()
nodesSrc[1]->setIPAddress("non-numerical-name");
std::vector<SharedHandle<DHTNode> > nodes(vbegin(nodesSrc), vend(nodesSrc));
- DHTRoutingTableSerializer s;
+ DHTRoutingTableSerializer s(AF_INET);
s.setLocalNode(localNode);
s.setNodes(nodes);
std::stringstream ss;
s.serialize(ss);
- DHTRoutingTableDeserializer d;
+ DHTRoutingTableDeserializer d(AF_INET);
d.deserialize(ss);
CPPUNIT_ASSERT(memcmp(localNode->getID(), d.getLocalNode()->getID(),
@@ -70,4 +73,44 @@ void DHTRoutingTableDeserializerTest::testDeserialize()
CPPUNIT_ASSERT(memcmp(nodes[2]->getID(), dsnodes[1]->getID(), DHT_ID_LENGTH) == 0);
}
+void DHTRoutingTableDeserializerTest::testDeserialize6()
+{
+ SharedHandle<DHTNode> localNode(new DHTNode());
+
+ SharedHandle<DHTNode> nodesSrc[3];
+ for(size_t i = 0; i < A2_ARRAY_LEN(nodesSrc); ++i) {
+ nodesSrc[i].reset(new DHTNode());
+ nodesSrc[i]->setIPAddress("2001::100"+util::uitos(i+1));
+ nodesSrc[i]->setPort(6881+i);
+ }
+ nodesSrc[1]->setIPAddress("non-numerical-name");
+ std::vector<SharedHandle<DHTNode> > nodes(vbegin(nodesSrc), vend(nodesSrc));
+
+ DHTRoutingTableSerializer s(AF_INET6);
+ s.setLocalNode(localNode);
+ s.setNodes(nodes);
+
+ std::stringstream ss;
+ s.serialize(ss);
+
+ DHTRoutingTableDeserializer d(AF_INET6);
+ d.deserialize(ss);
+
+ CPPUNIT_ASSERT(memcmp(localNode->getID(), d.getLocalNode()->getID(),
+ DHT_ID_LENGTH) == 0);
+
+ std::cout << d.getSerializedTime().getTime() << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL((size_t)2, d.getNodes().size());
+ const std::vector<SharedHandle<DHTNode> >& dsnodes = d.getNodes();
+ CPPUNIT_ASSERT_EQUAL(std::string("2001::1001"), dsnodes[0]->getIPAddress());
+ CPPUNIT_ASSERT_EQUAL((uint16_t)6881, dsnodes[0]->getPort());
+ CPPUNIT_ASSERT(memcmp(nodes[0]->getID(), dsnodes[0]->getID(),
+ DHT_ID_LENGTH) == 0);
+ CPPUNIT_ASSERT_EQUAL(std::string("2001::1003"), dsnodes[1]->getIPAddress());
+ CPPUNIT_ASSERT_EQUAL((uint16_t)6883, dsnodes[1]->getPort());
+ CPPUNIT_ASSERT(memcmp(nodes[2]->getID(), dsnodes[1]->getID(),
+ DHT_ID_LENGTH) == 0);
+}
+
} // namespace aria2
diff --git a/test/DHTRoutingTableSerializerTest.cc b/test/DHTRoutingTableSerializerTest.cc
index 81450a6b..3523e341 100644
--- a/test/DHTRoutingTableSerializerTest.cc
+++ b/test/DHTRoutingTableSerializerTest.cc
@@ -20,42 +20,35 @@ class DHTRoutingTableSerializerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DHTRoutingTableSerializerTest);
CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST(testSerialize6);
CPPUNIT_TEST_SUITE_END();
+private:
+ char zero[256];
+ char buf[20];
+
+ void checkToLocalnode
+ (std::istream& ss, const SharedHandle<DHTNode>& localNode);
+
+ void checkNumNodes(std::istream& ss, size_t expected);
public:
- void setUp() {}
+ void setUp()
+ {
+ memset(zero, 0, sizeof(zero));
+ }
void tearDown() {}
void testSerialize();
+
+ void testSerialize6();
};
CPPUNIT_TEST_SUITE_REGISTRATION(DHTRoutingTableSerializerTest);
-void DHTRoutingTableSerializerTest::testSerialize()
+void DHTRoutingTableSerializerTest::checkToLocalnode
+(std::istream& ss, const SharedHandle<DHTNode>& localNode)
{
- SharedHandle<DHTNode> localNode(new DHTNode());
-
- SharedHandle<DHTNode> nodesSrc[3];
- for(size_t i = 0; i < A2_ARRAY_LEN(nodesSrc); ++i) {
- nodesSrc[i].reset(new DHTNode());
- nodesSrc[i]->setIPAddress("192.168.0."+util::uitos(i+1));
- nodesSrc[i]->setPort(6881+i);
- }
- nodesSrc[1]->setIPAddress("non-numerical-name");
- std::vector<SharedHandle<DHTNode> > nodes(vbegin(nodesSrc), vend(nodesSrc));
-
- DHTRoutingTableSerializer s;
- s.setLocalNode(localNode);
- s.setNodes(nodes);
-
- std::stringstream ss;
- s.serialize(ss);
-
- char zero[16];
- memset(zero, 0, sizeof(zero));
-
- char buf[20];
// header
ss.read(buf, 8);
// magic
@@ -89,14 +82,44 @@ void DHTRoutingTableSerializerTest::testSerialize()
// 4bytes reserved
ss.read(buf, 4);
CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
+}
+void DHTRoutingTableSerializerTest::checkNumNodes
+(std::istream& ss, size_t expected)
+{
// number of nodes saved
ss.read(buf, 4);
uint32_t numNodes;
memcpy(&numNodes, buf, sizeof(numNodes));
numNodes = ntohl(numNodes);
- CPPUNIT_ASSERT_EQUAL((uint32_t)3, numNodes);
+ CPPUNIT_ASSERT_EQUAL((uint32_t)expected, numNodes);
+}
+
+void DHTRoutingTableSerializerTest::testSerialize()
+{
+ SharedHandle<DHTNode> localNode(new DHTNode());
+
+ SharedHandle<DHTNode> nodesSrc[3];
+ for(size_t i = 0; i < A2_ARRAY_LEN(nodesSrc); ++i) {
+ nodesSrc[i].reset(new DHTNode());
+ nodesSrc[i]->setIPAddress("192.168.0."+util::uitos(i+1));
+ nodesSrc[i]->setPort(6881+i);
+ }
+ nodesSrc[1]->setIPAddress("non-numerical-name");
+ std::vector<SharedHandle<DHTNode> > nodes(vbegin(nodesSrc), vend(nodesSrc));
+
+ DHTRoutingTableSerializer s(AF_INET);
+ s.setLocalNode(localNode);
+ s.setNodes(nodes);
+
+ std::stringstream ss;
+ s.serialize(ss);
+
+ checkToLocalnode(ss, localNode);
+ size_t numNodes = 3;
+ checkNumNodes(ss, numNodes);
+
// 4bytes reserved
ss.read(buf, 4);
CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
@@ -199,4 +222,92 @@ void DHTRoutingTableSerializerTest::testSerialize()
CPPUNIT_ASSERT(ss.eof());
}
+void DHTRoutingTableSerializerTest::testSerialize6()
+{
+ SharedHandle<DHTNode> localNode(new DHTNode());
+
+ SharedHandle<DHTNode> nodesSrc[2];
+ for(size_t i = 0; i < A2_ARRAY_LEN(nodesSrc); ++i) {
+ nodesSrc[i].reset(new DHTNode());
+ nodesSrc[i]->setIPAddress("2001::100"+util::uitos(i+1));
+ nodesSrc[i]->setPort(6881+i);
+ }
+ nodesSrc[1]->setIPAddress("non-numerical-name");
+ std::vector<SharedHandle<DHTNode> > nodes(vbegin(nodesSrc), vend(nodesSrc));
+
+ DHTRoutingTableSerializer s(AF_INET6);
+ s.setLocalNode(localNode);
+ s.setNodes(nodes);
+
+ std::stringstream ss;
+ s.serialize(ss);
+
+ checkToLocalnode(ss, localNode);
+ size_t numNodes = 2;
+ checkNumNodes(ss, numNodes);
+
+ // 4bytes reserved
+ ss.read(buf, 4);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
+
+ // node[0]
+ // 1byte compatc peer format length
+ {
+ uint8_t len;
+ ss >> len;
+ CPPUNIT_ASSERT_EQUAL((uint8_t)18, len);
+ }
+ // 7bytes reserved
+ ss.read(buf, 7);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 7) == 0);
+ // 18 bytes compact peer info
+ ss.read(buf, 18);
+ {
+ std::pair<std::string, uint16_t> peer =
+ bittorrent::unpackcompact(reinterpret_cast<const unsigned char*>(buf),
+ AF_INET6);
+ CPPUNIT_ASSERT_EQUAL(std::string("2001::1001"), peer.first);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peer.second);
+ }
+ // 6bytes reserved
+ ss.read(buf, 6);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 6) == 0);
+ // localnode ID
+ ss.read(buf, DHT_ID_LENGTH);
+ CPPUNIT_ASSERT(memcmp(nodes[0]->getID(), buf, DHT_ID_LENGTH) == 0);
+ // 4bytes reserved
+ ss.read(buf, 4);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
+
+ // node[1]
+ // 1byte compatc peer format length
+ {
+ uint8_t len;
+ ss >> len;
+ CPPUNIT_ASSERT_EQUAL((uint8_t)18, len);
+ }
+ // 7bytes reserved
+ ss.read(buf, 7);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 7) == 0);
+ // 18bytes compact peer info
+ ss.read(buf, 18);
+ // zero filled because node[1]'s hostname is not numerical form
+ // deserializer should skip this entry
+ CPPUNIT_ASSERT(memcmp(zero, buf, 18) == 0);
+ // 6bytes reserved
+ ss.read(buf, 6);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 6) == 0);
+ // localnode ID
+ ss.read(buf, DHT_ID_LENGTH);
+ CPPUNIT_ASSERT(memcmp(nodes[1]->getID(), buf, DHT_ID_LENGTH) == 0);
+ // 4bytes reserved
+ ss.read(buf, 4);
+ CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
+
+ // check to see stream ends
+ ss.read(buf, 1);
+ CPPUNIT_ASSERT_EQUAL((std::streamsize)0, ss.gcount());
+ CPPUNIT_ASSERT(ss.eof());
+}
+
} // namespace aria2
diff --git a/test/LpdMessageDispatcherTest.cc b/test/LpdMessageDispatcherTest.cc
index 598178c6..3324bf84 100644
--- a/test/LpdMessageDispatcherTest.cc
+++ b/test/LpdMessageDispatcherTest.cc
@@ -46,7 +46,7 @@ void LpdMessageDispatcherTest::testSendMessage()
#ifdef __MINGW32__
recvsock->bindWithFamily(LPD_MULTICAST_PORT, AF_INET);
#else // !__MINGW32__
- recvsock->bind(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
+ recvsock->bind(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT, AF_INET);
#endif // !__MINGW32__
recvsock->joinMulticastGroup(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT, "");
diff --git a/test/MockDHTMessageFactory.h b/test/MockDHTMessageFactory.h
index efb83b52..7382bd69 100644
--- a/test/MockDHTMessageFactory.h
+++ b/test/MockDHTMessageFactory.h
@@ -81,18 +81,9 @@ public:
createGetPeersReplyMessage
(const SharedHandle<DHTNode>& remoteNode,
const std::vector<SharedHandle<DHTNode> >& closestKNodes,
- const std::string& token,
- const std::string& transactionID)
- {
- return SharedHandle<DHTResponseMessage>();
- }
-
-
- virtual SharedHandle<DHTResponseMessage>
- createGetPeersReplyMessage(const SharedHandle<DHTNode>& remoteNode,
- const std::vector<SharedHandle<Peer> >& peers,
- const std::string& token,
- const std::string& transactionID)
+ const std::vector<SharedHandle<Peer> >& peers,
+ const std::string& token,
+ const std::string& transactionID)
{
return SharedHandle<DHTResponseMessage>();
}