mirror of
https://github.com/aria2/aria2.git
synced 2025-04-04 21:17:41 +03:00
Bump up version number of dht.dat file to 3. In version 3 format, time is stored in 64bit, network byte order. New build can load old format(version 2) but it saves the file in new format. It means once you used new build, your dht.dat becomes incompatible with older build. * src/DHTRoutingTableDeserializer.cc * src/DHTRoutingTableSerializer.cc * test/DHTRoutingTableSerializerTest.cc
191 lines
5 KiB
C++
191 lines
5 KiB
C++
#include "DHTRoutingTableSerializer.h"
|
|
#include "Exception.h"
|
|
#include "Util.h"
|
|
#include "DHTNode.h"
|
|
#include "array_fun.h"
|
|
#include "DHTConstants.h"
|
|
#include "PeerMessageUtil.h"
|
|
#include "a2netcompat.h"
|
|
#include <cstring>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <cppunit/extensions/HelperMacros.h>
|
|
|
|
namespace aria2 {
|
|
|
|
class DHTRoutingTableSerializerTest:public CppUnit::TestFixture {
|
|
|
|
CPPUNIT_TEST_SUITE(DHTRoutingTableSerializerTest);
|
|
CPPUNIT_TEST(testSerialize);
|
|
CPPUNIT_TEST_SUITE_END();
|
|
public:
|
|
void setUp() {}
|
|
|
|
void tearDown() {}
|
|
|
|
void testSerialize();
|
|
};
|
|
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(DHTRoutingTableSerializerTest);
|
|
|
|
void DHTRoutingTableSerializerTest::testSerialize()
|
|
{
|
|
SharedHandle<DHTNode> localNode(new DHTNode());
|
|
|
|
SharedHandle<DHTNode> nodesSrc[3];
|
|
for(size_t i = 0; i < arrayLength(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::deque<SharedHandle<DHTNode> > nodes(&nodesSrc[0], &nodesSrc[arrayLength(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
|
|
CPPUNIT_ASSERT((char)0xa1 == buf[0]);
|
|
CPPUNIT_ASSERT((char)0xa2 == buf[1]);
|
|
// format ID
|
|
CPPUNIT_ASSERT((char)0x02 == buf[2]);
|
|
// reserved
|
|
CPPUNIT_ASSERT((char)0x00 == buf[3]);
|
|
CPPUNIT_ASSERT((char)0x00 == buf[4]);
|
|
CPPUNIT_ASSERT((char)0x00 == buf[5]);
|
|
// version
|
|
CPPUNIT_ASSERT((char)0x00 == buf[6]);
|
|
CPPUNIT_ASSERT((char)0x03 == buf[7]);
|
|
|
|
// time
|
|
ss.read(buf, 8);
|
|
time_t time = ntoh64(*reinterpret_cast<uint64_t*>(buf));
|
|
std::cerr << time << std::endl;
|
|
|
|
// localnode
|
|
// 8bytes reserved
|
|
ss.read(buf, 8);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 8) == 0);
|
|
// localnode ID
|
|
ss.read(buf, DHT_ID_LENGTH);
|
|
CPPUNIT_ASSERT(memcmp(localNode->getID(), buf, DHT_ID_LENGTH) == 0);
|
|
// 4bytes reserved
|
|
ss.read(buf, 4);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 4) == 0);
|
|
|
|
// number of nodes saved
|
|
ss.read(buf, 4);
|
|
uint32_t numNodes = ntohl(*reinterpret_cast<uint32_t*>(buf));
|
|
CPPUNIT_ASSERT_EQUAL((uint32_t)3, 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)6, len);
|
|
}
|
|
// 7bytes reserved
|
|
ss.read(buf, 7);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 7) == 0);
|
|
// 6bytes compact peer info
|
|
ss.read(buf, 6);
|
|
{
|
|
std::pair<std::string, uint16_t> peer =
|
|
PeerMessageUtil::unpackcompact(reinterpret_cast<const unsigned char*>(buf));
|
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer.first);
|
|
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peer.second);
|
|
}
|
|
// 2bytes reserved
|
|
ss.read(buf, 2);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 2) == 0);
|
|
// 16bytes reserved
|
|
ss.read(buf, 16);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 16) == 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)6, len);
|
|
}
|
|
// 7bytes reserved
|
|
ss.read(buf, 7);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 7) == 0);
|
|
// 6bytes compact peer info
|
|
ss.read(buf, 6);
|
|
// zero filled because node[1]'s hostname is not numerical form
|
|
// deserializer should skip this entry
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 6) == 0);
|
|
// 2bytes reserved
|
|
ss.read(buf, 2);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 2) == 0);
|
|
// 16bytes reserved
|
|
ss.read(buf, 16);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 16) == 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);
|
|
|
|
// node[2]
|
|
// 1byte compatc peer format length
|
|
{
|
|
uint8_t len;
|
|
ss >> len;
|
|
CPPUNIT_ASSERT_EQUAL((uint8_t)6, len);
|
|
}
|
|
// 7bytes reserved
|
|
ss.read(buf, 7);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 7) == 0);
|
|
// 6bytes compact peer info
|
|
ss.read(buf, 6);
|
|
{
|
|
std::pair<std::string, uint16_t> peer =
|
|
PeerMessageUtil::unpackcompact(reinterpret_cast<const unsigned char*>(buf));
|
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.3"), peer.first);
|
|
CPPUNIT_ASSERT_EQUAL((uint16_t)6883, peer.second);
|
|
}
|
|
// 2bytes reserved
|
|
ss.read(buf, 2);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 2) == 0);
|
|
// 16bytes reserved
|
|
ss.read(buf, 16);
|
|
CPPUNIT_ASSERT(memcmp(zero, buf, 16) == 0);
|
|
// localnode ID
|
|
ss.read(buf, DHT_ID_LENGTH);
|
|
CPPUNIT_ASSERT(memcmp(nodes[2]->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
|