2010-08-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added bittorrent::packcompact() which replaces
	bittorrent::createcompact() and supports IPv6 addresses. Rewritten
	bittorrent::unpackcompact() and bittorrent::extractPeer() to
	support IPv6 addresses. Fixed added.f flags in ut_pex.
	* src/BtConstants.h
	* src/DHTFindNodeReplyMessage.cc
	* src/DHTGetPeersReplyMessage.cc
	* src/DHTMessageFactoryImpl.cc
	* src/DHTRoutingTableDeserializer.cc
	* src/DHTRoutingTableSerializer.cc
	* src/DHTTokenTracker.cc
	* src/DefaultBtAnnounce.cc
	* src/UTPexExtensionMessage.cc
	* src/bittorrent_helper.cc
	* src/bittorrent_helper.h
	* test/BittorrentHelperTest.cc
	* test/DHTFindNodeReplyMessageTest.cc
	* test/DHTGetPeersReplyMessageTest.cc
	* test/DHTMessageFactoryImplTest.cc
	* test/DHTRoutingTableSerializerTest.cc
	* test/DefaultExtensionMessageFactoryTest.cc
	* test/UTPexExtensionMessageTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-08-03 11:44:24 +00:00
parent 939a372727
commit 2bd5020f81
19 changed files with 275 additions and 162 deletions

View File

@ -1,3 +1,28 @@
2010-08-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added bittorrent::packcompact() which replaces
bittorrent::createcompact() and supports IPv6 addresses. Rewritten
bittorrent::unpackcompact() and bittorrent::extractPeer() to
support IPv6 addresses. Fixed added.f flags in ut_pex.
* src/BtConstants.h
* src/DHTFindNodeReplyMessage.cc
* src/DHTGetPeersReplyMessage.cc
* src/DHTMessageFactoryImpl.cc
* src/DHTRoutingTableDeserializer.cc
* src/DHTRoutingTableSerializer.cc
* src/DHTTokenTracker.cc
* src/DefaultBtAnnounce.cc
* src/UTPexExtensionMessage.cc
* src/bittorrent_helper.cc
* src/bittorrent_helper.h
* test/BittorrentHelperTest.cc
* test/DHTFindNodeReplyMessageTest.cc
* test/DHTGetPeersReplyMessageTest.cc
* test/DHTMessageFactoryImplTest.cc
* test/DHTRoutingTableSerializerTest.cc
* test/DefaultExtensionMessageFactoryTest.cc
* test/UTPexExtensionMessageTest.cc
2010-08-01 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added --enable-async-dns6 option. This option enables IPv6 name

View File

@ -62,4 +62,8 @@ typedef std::map<std::string, uint8_t> Extensions;
#define LPD_MULTICAST_PORT 6771
#define COMPACT_LEN_IPV4 6
#define COMPACT_LEN_IPV6 18
#endif // _D_BT_CONSTANTS_

View File

@ -81,8 +81,11 @@ SharedHandle<Dict> DHTFindNodeReplyMessage::getResponse()
i != eoi && offset < DHTBucket::K*26; ++i) {
SharedHandle<DHTNode> node = *i;
memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
if(bittorrent::createcompact(buffer+20+offset, node->getIPAddress(),
node->getPort())) {
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, node->getIPAddress(), node->getPort());
if(compactlen == COMPACT_LEN_IPV4) {
memcpy(buffer+20+offset, compact, compactlen);
offset += 26;
}
}

View File

@ -85,8 +85,11 @@ SharedHandle<Dict> DHTGetPeersReplyMessage::getResponse()
i != eoi && offset < DHTBucket::K*26; ++i) {
SharedHandle<DHTNode> node = *i;
memcpy(buffer+offset, node->getID(), DHT_ID_LENGTH);
if(bittorrent::createcompact
(buffer+20+offset, node->getIPAddress(), node->getPort())) {
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, node->getIPAddress(), node->getPort());
if(compactlen == COMPACT_LEN_IPV4) {
memcpy(buffer+20+offset, compact, compactlen);
offset += 26;
}
}
@ -117,10 +120,11 @@ SharedHandle<Dict> DHTGetPeersReplyMessage::getResponse()
eoi = values_.end(); i != eoi && valuesList->size() < MAX_VALUES_SIZE;
++i) {
const SharedHandle<Peer>& peer = *i;
unsigned char buffer[6];
if(bittorrent::createcompact
(buffer, peer->getIPAddress(), peer->getPort())) {
valuesList->append(String::g(buffer, sizeof(buffer)));
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, peer->getIPAddress(), peer->getPort());
if(compactlen == COMPACT_LEN_IPV4) {
valuesList->append(String::g(compact, compactlen));
}
}
rDict->put(VALUES, valuesList);

View File

@ -365,7 +365,7 @@ DHTMessageFactoryImpl::extractNodes(const unsigned char* src, size_t length)
for(size_t offset = 0; offset < length; offset += 26) {
SharedHandle<DHTNode> node(new DHTNode(src+offset));
std::pair<std::string, uint16_t> addr =
bittorrent::unpackcompact(src+offset+DHT_ID_LENGTH);
bittorrent::unpackcompact(src+offset+DHT_ID_LENGTH, AF_INET);
if(addr.first.empty()) {
continue;
}
@ -448,7 +448,7 @@ DHTMessageFactoryImpl::createGetPeersReplyMessageWithValues
const String* data = asString(*i);
if(data && data->s().size() == 6) {
std::pair<std::string, uint16_t> addr =
bittorrent::unpackcompact(data->uc());
bittorrent::unpackcompact(data->uc(), AF_INET);
SharedHandle<Peer> peer(new Peer(addr.first, addr.second));
peers.push_back(peer);
}

View File

@ -182,7 +182,9 @@ void DHTRoutingTableDeserializer::deserialize(std::istream& in)
CHECK_STREAM(in, 42);
continue;
}
std::pair<std::string, uint16_t> peer = bittorrent::unpackcompact(buf);
// TODO DHT6 protocol family should be configurable.
std::pair<std::string, uint16_t> peer =
bittorrent::unpackcompact(buf, AF_INET);
if(peer.first.empty()) {
// skip this entry
readBytes(buf, buf.size(), in, 42);

View File

@ -105,19 +105,21 @@ void DHTRoutingTableSerializer::serialize(std::ostream& o)
for(std::vector<SharedHandle<DHTNode> >::const_iterator i = nodes_.begin(),
eoi = nodes_.end(); i != eoi; ++i) {
const SharedHandle<DHTNode>& node = *i;
// Currently, only IPv4 address and IPv4-mapped address are saved.
// Currently, only IPv4 addresses are saved.
// 6bytes: write IP address + port in Compact IP-address/port info form.
unsigned char compactPeer[6];
if(!bittorrent::createcompact
(compactPeer, node->getIPAddress(), node->getPort())) {
memset(compactPeer, 0, 6);
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);
}
// 1byte compact peer format length
o << static_cast<uint8_t>(sizeof(compactPeer));
o << static_cast<uint8_t>(compactlen);
// 7bytes reserved
o.write(zero, 7);
// 6 bytes compact peer
o.write(reinterpret_cast<const char*>(compactPeer), 6);
o.write(reinterpret_cast<const char*>(compactPeer), compactlen);
// 2bytes reserved
o.write(zero, 2);
// 16bytes reserved

View File

@ -59,20 +59,24 @@ DHTTokenTracker::DHTTokenTracker(const unsigned char* initialSecret)
DHTTokenTracker::~DHTTokenTracker() {}
std::string DHTTokenTracker::generateToken(const unsigned char* infoHash,
const std::string& ipaddr, uint16_t port,
const unsigned char* secret) const
std::string DHTTokenTracker::generateToken
(const unsigned char* infoHash,
const std::string& ipaddr, uint16_t port,
const unsigned char* secret) const
{
unsigned char src[DHT_ID_LENGTH+6+SECRET_SIZE];
if(!bittorrent::createcompact(src+DHT_ID_LENGTH, ipaddr, port)) {
unsigned char src[DHT_ID_LENGTH+COMPACT_LEN_IPV6+SECRET_SIZE];
memset(src, 0, sizeof(src));
int compactlen = bittorrent::packcompact(src+DHT_ID_LENGTH, ipaddr, port);
if(compactlen == 0) {
throw DL_ABORT_EX
(StringFormat("Token generation failed: ipaddr=%s, port=%u",
ipaddr.c_str(), port).str());
}
memcpy(src, infoHash, DHT_ID_LENGTH);
memcpy(src+DHT_ID_LENGTH+6, secret, SECRET_SIZE);
memcpy(src+DHT_ID_LENGTH+COMPACT_LEN_IPV6, secret, SECRET_SIZE);
unsigned char md[20];
MessageDigestHelper::digest(md, sizeof(md), MessageDigestContext::SHA1, src, sizeof(src));
MessageDigestHelper::digest(md, sizeof(md), MessageDigestContext::SHA1,
src, sizeof(src));
return std::string(&md[0], &md[sizeof(md)]);
}

View File

@ -276,7 +276,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
} else {
if(!btRuntime_->isHalt() && btRuntime_->lessThanMinPeers()) {
std::vector<SharedHandle<Peer> > peers;
bittorrent::extractPeer(peerData, std::back_inserter(peers));
bittorrent::extractPeer(peerData, AF_INET, std::back_inserter(peers));
peerStorage_->addPeer(peers);
}
}

View File

@ -78,11 +78,12 @@ UTPexExtensionMessage::createCompactPeerListAndFlag
std::string flagstring;
for(std::vector<SharedHandle<Peer> >::const_iterator itr = peers.begin(),
eoi = peers.end(); itr != eoi; ++itr) {
unsigned char compact[6];
if(bittorrent::createcompact
(compact, (*itr)->getIPAddress(), (*itr)->getPort())) {
addrstring.append(&compact[0], &compact[6]);
flagstring += (*itr)->isSeeder() ? "2" : "0";
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = bittorrent::packcompact
(compact, (*itr)->getIPAddress(), (*itr)->getPort());
if(compactlen == COMPACT_LEN_IPV4) {
addrstring.append(&compact[0], &compact[compactlen]);
flagstring += (*itr)->isSeeder() ? 0x02 : 0x00;
}
}
return std::pair<std::string, std::string>(addrstring, flagstring);
@ -162,11 +163,13 @@ UTPexExtensionMessage::create(const unsigned char* data, size_t len)
if(dict) {
const String* added = asString(dict->get("added"));
if(added) {
bittorrent::extractPeer(added, std::back_inserter(msg->freshPeers_));
bittorrent::extractPeer
(added, AF_INET, std::back_inserter(msg->freshPeers_));
}
const String* dropped = asString(dict->get("dropped"));
if(dropped) {
bittorrent::extractPeer(dropped, std::back_inserter(msg->droppedPeers_));
bittorrent::extractPeer
(dropped, AF_INET, std::back_inserter(msg->droppedPeers_));
}
}
return msg;

View File

@ -54,6 +54,7 @@
#include "magnet.h"
#include "bencode2.h"
#include "TorrentAttribute.h"
#include "SocketCore.h"
namespace aria2 {
@ -623,8 +624,9 @@ void computeFastSet
(std::vector<size_t>& fastSet, const std::string& ipaddr,
size_t numPieces, const unsigned char* infoHash, size_t fastSetSize)
{
unsigned char compact[6];
if(!createcompact(compact, ipaddr, 0)) {
unsigned char compact[COMPACT_LEN_IPV6];
int compactlen = packcompact(compact, ipaddr, 0);
if(compactlen != COMPACT_LEN_IPV4) {
return;
}
if(numPieces < fastSetSize) {
@ -801,51 +803,51 @@ void createPeerMessageString
msg[4] = messageId;
}
bool createcompact
int packcompact
(unsigned char* compact, const std::string& addr, uint16_t port)
{
struct addrinfo hints;
struct addrinfo* res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // since compact peer format is ipv4 only.
hints.ai_flags = AI_NUMERICHOST;
if(getaddrinfo(addr.c_str(), 0, &hints, &res)) {
return false;
int s =
callGetaddrinfo(&res, addr.c_str(), 0, AF_UNSPEC, 0, AI_NUMERICHOST, 0);
if(s != 0) {
return 0;
}
struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(res->ai_addr);
memcpy(compact, &(in->sin_addr.s_addr), sizeof(uint32_t));
uint16_t port_nworder(htons(port));
memcpy(compact+4, &port_nworder, sizeof(uint16_t));
freeaddrinfo(res);
return true;
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
uint16_t portN = htons(port);
for(struct addrinfo* rp = res; rp; rp = rp->ai_next) {
if(rp->ai_family == AF_INET) {
struct sockaddr_in* in =
reinterpret_cast<struct sockaddr_in*>(res->ai_addr);
memcpy(compact, &(in->sin_addr), 4);
memcpy(compact+4, &portN, sizeof(portN));
return COMPACT_LEN_IPV4;
} else if(rp->ai_family == AF_INET6) {
struct sockaddr_in6* in6 =
reinterpret_cast<struct sockaddr_in6*>(res->ai_addr);
memcpy(compact, &(in6->sin6_addr), 16);
memcpy(compact+16, &portN, sizeof(portN));
return COMPACT_LEN_IPV6;
}
}
return 0;
}
std::pair<std::string, uint16_t> unpackcompact(const unsigned char* compact)
std::pair<std::string, uint16_t> unpackcompact
(const unsigned char* compact, int family)
{
struct sockaddr_in in;
memset(&in, 0, sizeof(in));
#ifdef HAVE_SOCKADDR_IN_SIN_LEN
// For netbsd
in.sin_len = sizeof(in);
#endif // HAVE_SOCKADDR_IN_SIN_LEN
in.sin_family = AF_INET;
memcpy(&(in.sin_addr.s_addr), compact, sizeof(uint32_t));
in.sin_port = 0;
char host[NI_MAXHOST];
int s;
s = getnameinfo(reinterpret_cast<const struct sockaddr*>(&in), sizeof(in),
host, NI_MAXHOST, 0, 0,
NI_NUMERICHOST);
if(s) {
return std::pair<std::string, uint16_t>();
int portOffset = family == AF_INET?4:16;
std::pair<std::string, uint16_t> r;
char buf[INET6_ADDRSTRLEN];
if(!inet_ntop(family, compact, buf, sizeof(buf))) {
return r;
}
uint16_t port_nworder;
memcpy(&port_nworder, compact+sizeof(uint32_t), sizeof(uint16_t));
uint16_t port = ntohs(port_nworder);
return std::make_pair(host, port);
r.first = buf;
uint16_t portN;
memcpy(&portN, compact+portOffset, sizeof(portN));
r.second = ntohs(portN);
return r;
}
void assertPayloadLengthGreater
(size_t threshold, size_t actual, const std::string& msgName)
{

View File

@ -182,18 +182,25 @@ void createPeerMessageString
(unsigned char* msg, size_t msgLength, size_t payloadLength, uint8_t messageId);
/**
* Creates compact tracker format(6bytes for ipv4 address and port)
* and stores the results in compact.
* compact must be at least 6 bytes and pre-allocated.
* Returns true if creation is successful, otherwise returns false.
* The example of failure reason is that addr is not numbers-and-dots
* notation.
* Creates compact form(packed addresss + 2bytes port) and stores the
* results in compact. This function looks addr and if it is IPv4
* address, it stores 6bytes in compact and if it is IPv6, it stores
* 18bytes in compact. So compact must be at least 18 bytes and
* pre-allocated. Returns the number of written bytes; for IPv4
* address, it is 6 and for IPv6, it is 18. On failure, returns 0.
*/
bool createcompact
int packcompact
(unsigned char* compact, const std::string& addr, uint16_t port);
// Unpack compact into pair of IPv4 address and port.
std::pair<std::string, uint16_t> unpackcompact(const unsigned char* compact);
/**
* Unpack packed address and port in compact and returns address and
* port pair. family must be AF_INET or AF_INET6. If family is
* AF_INET, first 6 bytes from compact is used. If family is
* AF_INET6, first 18 bytes from compact is used. On failure, returns
* std::pair<std::string, uint16_t>().
*/
std::pair<std::string, uint16_t>
unpackcompact(const unsigned char* compact, int family);
// Throws exception if threshold >= actual
void assertPayloadLengthGreater
@ -216,30 +223,30 @@ std::string metadata2Torrent
std::string torrent2Magnet(const SharedHandle<TorrentAttribute>& attrs);
template<typename OutputIterator>
void extractPeer(const ValueBase* peerData, OutputIterator dest)
void extractPeer(const ValueBase* peerData, int family, OutputIterator dest)
{
class PeerListValueBaseVisitor:public ValueBaseVisitor {
private:
OutputIterator dest_;
int family_;
public:
PeerListValueBaseVisitor(OutputIterator dest):dest_(dest) {}
PeerListValueBaseVisitor(OutputIterator dest, int family):
dest_(dest),
family_(family) {}
virtual ~PeerListValueBaseVisitor() {}
virtual void visit(const String& peerData)
{
int unit = family_ == AF_INET?6:18;
size_t length = peerData.s().size();
if(length%6 == 0) {
const char* base = peerData.s().data();
for(size_t i = 0; i < length; i += 6) {
struct in_addr in;
memcpy(&in.s_addr, base+i, sizeof(uint32_t));
std::string ipaddr = inet_ntoa(in);
uint16_t port_nworder;
memcpy(&port_nworder, base+i+4, sizeof(uint16_t));
uint16_t port = ntohs(port_nworder);
*dest_ = SharedHandle<Peer>(new Peer(ipaddr, port));
++dest_;
if(length%unit == 0) {
const unsigned char* base =
reinterpret_cast<const unsigned char*>(peerData.s().data());
const unsigned char* end = base+length;
for(; base != end; base += unit) {
std::pair<std::string, uint16_t> p = unpackcompact(base, family_);
*dest_++ = SharedHandle<Peer>(new Peer(p.first, p.second));
}
}
}
@ -269,15 +276,16 @@ void extractPeer(const ValueBase* peerData, OutputIterator dest)
virtual void visit(const Dict& v) {}
};
if(peerData) {
PeerListValueBaseVisitor visitor(dest);
PeerListValueBaseVisitor visitor(dest, family);
peerData->accept(visitor);
}
}
template<typename OutputIterator>
void extractPeer(const SharedHandle<ValueBase>& peerData, OutputIterator dest)
void extractPeer
(const SharedHandle<ValueBase>& peerData, int family, OutputIterator dest)
{
return extractPeer(peerData.get(), dest);
return extractPeer(peerData.get(), family, dest);
}
} // namespace bittorrent

View File

@ -56,15 +56,17 @@ class BittorrentHelperTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSetFileFilter_multi);
CPPUNIT_TEST(testUTF8Torrent);
CPPUNIT_TEST(testEtc);
CPPUNIT_TEST(testCreatecompact);
CPPUNIT_TEST(testCheckBitfield);
CPPUNIT_TEST(testMetadata);
CPPUNIT_TEST(testParseMagnet);
CPPUNIT_TEST(testParseMagnet_base32);
CPPUNIT_TEST(testMetadata2Torrent);
CPPUNIT_TEST(testTorrent2Magnet);
CPPUNIT_TEST(testExtractPeerFromString);
CPPUNIT_TEST(testExtractPeerFromList);
CPPUNIT_TEST(testExtract2PeersFromList);
CPPUNIT_TEST(testPackcompact);
CPPUNIT_TEST(testUnpackcompact);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
@ -101,15 +103,17 @@ public:
void testSetFileFilter_multi();
void testUTF8Torrent();
void testEtc();
void testCreatecompact();
void testCheckBitfield();
void testMetadata();
void testParseMagnet();
void testParseMagnet_base32();
void testMetadata2Torrent();
void testTorrent2Magnet();
void testExtractPeerFromString();
void testExtractPeerFromList();
void testExtract2PeersFromList();
void testPackcompact();
void testUnpackcompact();
};
@ -645,18 +649,6 @@ void BittorrentHelperTest::testEtc()
getTorrentAttrs(dctx)->creationDate);
}
void BittorrentHelperTest::testCreatecompact()
{
unsigned char compact[6];
// Note: bittorrent::createcompact() on linux can handle IPv4-mapped
// addresses like `ffff::127.0.0.1', but on cygwin, it doesn't.
CPPUNIT_ASSERT(createcompact(compact, "127.0.0.1", 6881));
std::pair<std::string, uint16_t> p = unpackcompact(compact);
CPPUNIT_ASSERT_EQUAL(std::string("127.0.0.1"), p.first);
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
}
void BittorrentHelperTest::testCheckBitfield()
{
unsigned char bitfield[] = { 0xff, 0xe0 };
@ -760,6 +752,35 @@ void BittorrentHelperTest::testTorrent2Magnet()
torrent2Magnet(getTorrentAttrs(dctx)));
}
void BittorrentHelperTest::testExtractPeerFromString()
{
std::string hextext = "100210354527354678541237324732171ae1";
hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
std::string peersstr = "36:"+util::fromHex(hextext);
SharedHandle<ValueBase> str = bencode2::decode(peersstr);
std::deque<SharedHandle<Peer> > peers;
extractPeer(str, AF_INET6, std::back_inserter(peers));
CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
peers[0]->getIPAddress());
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
CPPUNIT_ASSERT_EQUAL(std::string("2001:db8:bd05:1d2:288a:1fc0:1:10ee"),
peers[1]->getIPAddress());
CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
hextext = "c0a800011ae1";
hextext += "c0a800021ae2";
peersstr = "12:"+util::fromHex(hextext);
str = bencode2::decode(peersstr);
peers.clear();
extractPeer(str, AF_INET, std::back_inserter(peers));
CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peers[0]->getIPAddress());
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peers[1]->getIPAddress());
CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
}
void BittorrentHelperTest::testExtractPeerFromList()
{
std::string peersString =
@ -769,7 +790,7 @@ void BittorrentHelperTest::testExtractPeerFromList()
SharedHandle<ValueBase> dict = bencode2::decode(peersString);
std::deque<SharedHandle<Peer> > peers;
extractPeer(asDict(dict)->get("peers"), std::back_inserter(peers));
extractPeer(asDict(dict)->get("peers"), AF_INET, std::back_inserter(peers));
CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
SharedHandle<Peer> peer = *peers.begin();
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
@ -786,7 +807,7 @@ void BittorrentHelperTest::testExtract2PeersFromList()
SharedHandle<ValueBase> dict = bencode2::decode(peersString);
std::deque<SharedHandle<Peer> > peers;
extractPeer(asDict(dict)->get("peers"), std::back_inserter(peers));
extractPeer(asDict(dict)->get("peers"), AF_INET, std::back_inserter(peers));
CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
SharedHandle<Peer> peer = *peers.begin();
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
@ -797,6 +818,40 @@ void BittorrentHelperTest::testExtract2PeersFromList()
CPPUNIT_ASSERT_EQUAL((uint16_t)2007, peer->getPort());
}
void BittorrentHelperTest::testPackcompact()
{
unsigned char compact[COMPACT_LEN_IPV6];
CPPUNIT_ASSERT_EQUAL(18,
packcompact(compact,
"1002:1035:4527:3546:7854:1237:3247:3217",
6881));
CPPUNIT_ASSERT_EQUAL(std::string("100210354527354678541237324732171ae1"),
util::toHex(compact, 18));
CPPUNIT_ASSERT_EQUAL(6, packcompact(compact, "192.168.0.1", 6881));
CPPUNIT_ASSERT_EQUAL(std::string("c0a800011ae1"), util::toHex(compact, 6));
CPPUNIT_ASSERT_EQUAL(0, packcompact(compact, "badaddr", 6881));
}
void BittorrentHelperTest::testUnpackcompact()
{
unsigned char compact6[] = {
0x10, 0x02, 0x10, 0x35, 0x45, 0x27, 0x35, 0x46,
0x78, 0x54, 0x12, 0x37, 0x32, 0x47, 0x32, 0x17,
0x1A, 0xE1 };
std::pair<std::string, uint16_t> p =
unpackcompact(compact6, AF_INET6);
CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
p.first);
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
unsigned char compact[] = { 0xC0, 0xa8, 0x00, 0x01, 0x1A, 0xE1 };
p = unpackcompact(compact, AF_INET);
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), p.first);
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
}
} // namespace bittorrent
} // namespace aria2

View File

@ -45,12 +45,12 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
nodes[i]->setPort(6881+i);
unsigned char buf[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
unsigned char buf[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[sizeof(buf)]);
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
msg.setClosestKNodes
(std::vector<SharedHandle<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));

View File

@ -57,12 +57,12 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
nodes[i]->setPort(6881+i);
unsigned char buf[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
unsigned char buf[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[sizeof(buf)]);
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
msg.setClosestKNodes
(std::vector<SharedHandle<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));
@ -80,10 +80,9 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
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[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buffer, peer->getIPAddress(), peer->getPort()));
valuesList->append(String::g(buffer, sizeof(buffer)));
unsigned char buffer[COMPACT_LEN_IPV6];
bittorrent::packcompact(buffer, peer->getIPAddress(), peer->getPort());
valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
peers.push_back(peer);
}
rDict->put("values", valuesList);

View File

@ -168,12 +168,12 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
nodes[i]->setPort(6881+i);
unsigned char buf[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
unsigned char buf[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[sizeof(buf)]);
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
rDict->put("nodes", compactNodeInfo);
dict.put("r", rDict);
@ -243,12 +243,12 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
nodes[i]->setPort(6881+i);
unsigned char buf[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
unsigned char buf[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[sizeof(buf)]);
std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
}
rDict->put("nodes", compactNodeInfo);
rDict->put("token", "token");
@ -290,10 +290,10 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
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[6];
CPPUNIT_ASSERT(bittorrent::createcompact
(buffer, peer->getIPAddress(), peer->getPort()));
valuesList->append(String::g(buffer, sizeof(buffer)));
unsigned char buffer[COMPACT_LEN_IPV6];
bittorrent::packcompact
(buffer, peer->getIPAddress(), peer->getPort());
valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
peers.push_back(peer);
}
rDict->put("values", valuesList);

View File

@ -115,7 +115,8 @@ void DHTRoutingTableSerializerTest::testSerialize()
ss.read(buf, 6);
{
std::pair<std::string, uint16_t> peer =
bittorrent::unpackcompact(reinterpret_cast<const unsigned char*>(buf));
bittorrent::unpackcompact(reinterpret_cast<const unsigned char*>(buf),
AF_INET);
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer.first);
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peer.second);
}
@ -174,7 +175,8 @@ void DHTRoutingTableSerializerTest::testSerialize()
ss.read(buf, 6);
{
std::pair<std::string, uint16_t> peer =
bittorrent::unpackcompact(reinterpret_cast<const unsigned char*>(buf));
bittorrent::unpackcompact(reinterpret_cast<const unsigned char*>(buf),
AF_INET);
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.3"), peer.first);
CPPUNIT_ASSERT_EQUAL((uint16_t)6883, peer.second);
}

View File

@ -131,14 +131,14 @@ void DefaultExtensionMessageFactoryTest::testCreateMessage_Handshake()
void DefaultExtensionMessageFactoryTest::testCreateMessage_UTPex()
{
unsigned char c1[6];
unsigned char c2[6];
unsigned char c3[6];
unsigned char c4[6];
bittorrent::createcompact(c1, "192.168.0.1", 6881);
bittorrent::createcompact(c2, "10.1.1.2", 9999);
bittorrent::createcompact(c3, "192.168.0.2", 6882);
bittorrent::createcompact(c4, "10.1.1.3",10000);
unsigned char c1[COMPACT_LEN_IPV6];
unsigned char c2[COMPACT_LEN_IPV6];
unsigned char c3[COMPACT_LEN_IPV6];
unsigned char c4[COMPACT_LEN_IPV6];
bittorrent::packcompact(c1, "192.168.0.1", 6881);
bittorrent::packcompact(c2, "10.1.1.2", 9999);
bittorrent::packcompact(c3, "192.168.0.2", 6882);
bittorrent::packcompact(c4, "10.1.1.3",10000);
std::string data = getExtensionMessageID("ut_pex")+"d5:added12:"+
std::string(&c1[0], &c1[6])+std::string(&c2[0], &c2[6])+

View File

@ -81,18 +81,18 @@ void UTPexExtensionMessageTest::testGetBencodedData()
p4->startBadCondition();
CPPUNIT_ASSERT(msg.addDroppedPeer(p4));
unsigned char c1[6];
unsigned char c2[6];
unsigned char c3[6];
unsigned char c4[6];
bittorrent::createcompact(c1, p1->getIPAddress(), p1->getPort());
bittorrent::createcompact(c2, p2->getIPAddress(), p2->getPort());
bittorrent::createcompact(c3, p3->getIPAddress(), p3->getPort());
bittorrent::createcompact(c4, p4->getIPAddress(), p4->getPort());
unsigned char c1[COMPACT_LEN_IPV6];
unsigned char c2[COMPACT_LEN_IPV6];
unsigned char c3[COMPACT_LEN_IPV6];
unsigned char c4[COMPACT_LEN_IPV6];
bittorrent::packcompact(c1, p1->getIPAddress(), p1->getPort());
bittorrent::packcompact(c2, p2->getIPAddress(), p2->getPort());
bittorrent::packcompact(c3, p3->getIPAddress(), p3->getPort());
bittorrent::packcompact(c4, p4->getIPAddress(), p4->getPort());
std::string expected = "d5:added12:"+
std::string(&c1[0], &c1[6])+std::string(&c2[0], &c2[6])+
"7:added.f2:207:dropped12:"+
"7:added.f2:"+util::fromHex("0200")+"7:dropped12:"+
std::string(&c3[0], &c3[6])+std::string(&c4[0], &c4[6])+
"e";
std::string bd = msg.getPayload();
@ -152,14 +152,14 @@ void UTPexExtensionMessageTest::testDoReceivedAction()
void UTPexExtensionMessageTest::testCreate()
{
unsigned char c1[6];
unsigned char c2[6];
unsigned char c3[6];
unsigned char c4[6];
bittorrent::createcompact(c1, "192.168.0.1", 6881);
bittorrent::createcompact(c2, "10.1.1.2", 9999);
bittorrent::createcompact(c3, "192.168.0.2", 6882);
bittorrent::createcompact(c4, "10.1.1.3",10000);
unsigned char c1[COMPACT_LEN_IPV6];
unsigned char c2[COMPACT_LEN_IPV6];
unsigned char c3[COMPACT_LEN_IPV6];
unsigned char c4[COMPACT_LEN_IPV6];
bittorrent::packcompact(c1, "192.168.0.1", 6881);
bittorrent::packcompact(c2, "10.1.1.2", 9999);
bittorrent::packcompact(c3, "192.168.0.2", 6882);
bittorrent::packcompact(c4, "10.1.1.3",10000);
char id[1] = { 1 };