2008-02-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Adding handling of DHT error message. Just log error message and
	throw exception.
	* src/DHTMessageFactoryImpl.cc
	* test/DHTMessageFactoryImplTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-02-11 06:23:01 +00:00
parent 34e6a1dc9a
commit 413cbe192b
3 changed files with 56 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2008-02-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Adding handling of DHT error message. Just log error message and
throw exception.
* src/DHTMessageFactoryImpl.cc
* test/DHTMessageFactoryImplTest.cc
2008-02-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added handling of dynamic cast failure.

View File

@ -57,6 +57,7 @@
#include "BtRuntime.h"
#include "Util.h"
#include "Peer.h"
#include "Logger.h"
#include <cstring>
#include <utility>
@ -99,6 +100,17 @@ static const Data* getData(const Dictionary* d, const std::string& key)
}
}
static const Data* getData(const List* l, size_t index)
{
const Data* c = dynamic_cast<const Data*>(l->getList()[index]);
if(c) {
return c;
} else {
throw new DlAbortEx("Malformed DHT message. element[%u] is not Data.",
index);
}
}
static const List* getList(const Dictionary* d, const std::string& key)
{
const List* l = dynamic_cast<const List*>(d->get(key));
@ -187,12 +199,22 @@ SharedHandle<DHTMessage> DHTMessageFactoryImpl::createResponseMessage(const std:
{
const Data* t = getData(d, "t");
const Data* y = getData(d, "y");
const Dictionary* r = getDictionary(d, "r");
// TODO handle y == "e" case
if(y->toString() != "r") {
if(y->toString() == "e") {
// for now, just report error message arrived and throw exception.
const List* e = getList(d, "e");
if(e->getList().size() == 2) {
_logger->info("Received Error DHT message. code=%s, msg=%s",
Util::urlencode(getData(e, 0)->toString()).c_str(),
Util::urlencode(getData(e, 1)->toString()).c_str());
} else {
_logger->debug("e doesn't have 2 elements.");
}
throw new DlAbortEx("Received Error DHT message.");
} else if(y->toString() != "r") {
throw new DlAbortEx("Malformed DHT message. y != r: y=%s",
Util::urlencode(y->toString()).c_str());
}
const Dictionary* r = getDictionary(d, "r");
const Data* id = getData(r, "id");
validateID(id);
validateIDMatch(remoteNode->getID(),

View File

@ -33,6 +33,7 @@ class DHTMessageFactoryImplTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreateGetPeersReplyMessage_values);
CPPUNIT_TEST(testCreateAnnouncePeerMessage);
CPPUNIT_TEST(testCreateAnnouncePeerReplyMessage);
CPPUNIT_TEST(testReceivedErrorMessage);
CPPUNIT_TEST_SUITE_END();
public:
DHTMessageFactoryImplTest():factory(0), routingTable(0), localNode(0) {}
@ -72,6 +73,7 @@ public:
void testCreateGetPeersReplyMessage_values();
void testCreateAnnouncePeerMessage();
void testCreateAnnouncePeerReplyMessage();
void testReceivedErrorMessage();
};
@ -362,4 +364,26 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
Util::toHex(m->getTransactionID()));
}
void DHTMessageFactoryImplTest::testReceivedErrorMessage()
{
SharedHandle<Dictionary> d = new Dictionary();
d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
d->put("y", new Data("e"));
List* l = new List();
l->add(new Data("404"));
l->add(new Data("Not found"));
d->put("e", l);
SharedHandle<DHTNode> remoteNode = new DHTNode(remoteNodeID);
remoteNode->setIPAddress("192.168.0.1");
remoteNode->setPort(6881);
try {
factory->createResponseMessage("announce_peer", d.get(), remoteNode);
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException* e) {
std::cerr << *e << std::endl;
}
}
} // namespace aria2