From 2bd5020f81bc8c9995590209d0bf024147c8a51a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 3 Aug 2010 11:44:24 +0000 Subject: [PATCH] 2010-08-03 Tatsuhiro Tsujikawa 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 --- ChangeLog | 25 +++++++ src/BtConstants.h | 4 + src/DHTFindNodeReplyMessage.cc | 7 +- src/DHTGetPeersReplyMessage.cc | 16 ++-- src/DHTMessageFactoryImpl.cc | 4 +- src/DHTRoutingTableDeserializer.cc | 4 +- src/DHTRoutingTableSerializer.cc | 16 ++-- src/DHTTokenTracker.cc | 18 +++-- src/DefaultBtAnnounce.cc | 2 +- src/UTPexExtensionMessage.cc | 17 +++-- src/bittorrent_helper.cc | 76 ++++++++++--------- src/bittorrent_helper.h | 58 ++++++++------- test/BittorrentHelperTest.cc | 87 ++++++++++++++++++---- test/DHTFindNodeReplyMessageTest.cc | 8 +- test/DHTGetPeersReplyMessageTest.cc | 15 ++-- test/DHTMessageFactoryImplTest.cc | 24 +++--- test/DHTRoutingTableSerializerTest.cc | 6 +- test/DefaultExtensionMessageFactoryTest.cc | 16 ++-- test/UTPexExtensionMessageTest.cc | 34 ++++----- 19 files changed, 275 insertions(+), 162 deletions(-) diff --git a/ChangeLog b/ChangeLog index febf602b..f4e30831 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2010-08-03 Tatsuhiro Tsujikawa + + 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 Added --enable-async-dns6 option. This option enables IPv6 name diff --git a/src/BtConstants.h b/src/BtConstants.h index d590647e..71020832 100644 --- a/src/BtConstants.h +++ b/src/BtConstants.h @@ -62,4 +62,8 @@ typedef std::map Extensions; #define LPD_MULTICAST_PORT 6771 +#define COMPACT_LEN_IPV4 6 + +#define COMPACT_LEN_IPV6 18 + #endif // _D_BT_CONSTANTS_ diff --git a/src/DHTFindNodeReplyMessage.cc b/src/DHTFindNodeReplyMessage.cc index 9bd3fcb6..99acbce1 100644 --- a/src/DHTFindNodeReplyMessage.cc +++ b/src/DHTFindNodeReplyMessage.cc @@ -81,8 +81,11 @@ SharedHandle DHTFindNodeReplyMessage::getResponse() i != eoi && offset < DHTBucket::K*26; ++i) { SharedHandle 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; } } diff --git a/src/DHTGetPeersReplyMessage.cc b/src/DHTGetPeersReplyMessage.cc index a7ead1b0..6a0532c9 100644 --- a/src/DHTGetPeersReplyMessage.cc +++ b/src/DHTGetPeersReplyMessage.cc @@ -85,8 +85,11 @@ SharedHandle DHTGetPeersReplyMessage::getResponse() i != eoi && offset < DHTBucket::K*26; ++i) { SharedHandle 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 DHTGetPeersReplyMessage::getResponse() eoi = values_.end(); i != eoi && valuesList->size() < MAX_VALUES_SIZE; ++i) { const SharedHandle& 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); diff --git a/src/DHTMessageFactoryImpl.cc b/src/DHTMessageFactoryImpl.cc index 1bd803c2..5567711d 100644 --- a/src/DHTMessageFactoryImpl.cc +++ b/src/DHTMessageFactoryImpl.cc @@ -365,7 +365,7 @@ DHTMessageFactoryImpl::extractNodes(const unsigned char* src, size_t length) for(size_t offset = 0; offset < length; offset += 26) { SharedHandle node(new DHTNode(src+offset)); std::pair 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 addr = - bittorrent::unpackcompact(data->uc()); + bittorrent::unpackcompact(data->uc(), AF_INET); SharedHandle peer(new Peer(addr.first, addr.second)); peers.push_back(peer); } diff --git a/src/DHTRoutingTableDeserializer.cc b/src/DHTRoutingTableDeserializer.cc index df43c5c5..bed629ca 100644 --- a/src/DHTRoutingTableDeserializer.cc +++ b/src/DHTRoutingTableDeserializer.cc @@ -182,7 +182,9 @@ void DHTRoutingTableDeserializer::deserialize(std::istream& in) CHECK_STREAM(in, 42); continue; } - std::pair peer = bittorrent::unpackcompact(buf); + // TODO DHT6 protocol family should be configurable. + std::pair peer = + bittorrent::unpackcompact(buf, AF_INET); if(peer.first.empty()) { // skip this entry readBytes(buf, buf.size(), in, 42); diff --git a/src/DHTRoutingTableSerializer.cc b/src/DHTRoutingTableSerializer.cc index 8038a739..81976c50 100644 --- a/src/DHTRoutingTableSerializer.cc +++ b/src/DHTRoutingTableSerializer.cc @@ -105,19 +105,21 @@ void DHTRoutingTableSerializer::serialize(std::ostream& o) for(std::vector >::const_iterator i = nodes_.begin(), eoi = nodes_.end(); i != eoi; ++i) { const SharedHandle& 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(sizeof(compactPeer)); + o << static_cast(compactlen); // 7bytes reserved o.write(zero, 7); // 6 bytes compact peer - o.write(reinterpret_cast(compactPeer), 6); + o.write(reinterpret_cast(compactPeer), compactlen); // 2bytes reserved o.write(zero, 2); // 16bytes reserved diff --git a/src/DHTTokenTracker.cc b/src/DHTTokenTracker.cc index 6583e69e..209e3c27 100644 --- a/src/DHTTokenTracker.cc +++ b/src/DHTTokenTracker.cc @@ -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)]); } diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc index b6f58709..e47cf6b6 100644 --- a/src/DefaultBtAnnounce.cc +++ b/src/DefaultBtAnnounce.cc @@ -276,7 +276,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse, } else { if(!btRuntime_->isHalt() && btRuntime_->lessThanMinPeers()) { std::vector > peers; - bittorrent::extractPeer(peerData, std::back_inserter(peers)); + bittorrent::extractPeer(peerData, AF_INET, std::back_inserter(peers)); peerStorage_->addPeer(peers); } } diff --git a/src/UTPexExtensionMessage.cc b/src/UTPexExtensionMessage.cc index 726510c8..5a1b9aa4 100644 --- a/src/UTPexExtensionMessage.cc +++ b/src/UTPexExtensionMessage.cc @@ -78,11 +78,12 @@ UTPexExtensionMessage::createCompactPeerListAndFlag std::string flagstring; for(std::vector >::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(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; diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc index 2754c6c3..7b342aa9 100644 --- a/src/bittorrent_helper.cc +++ b/src/bittorrent_helper.cc @@ -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& 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(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 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(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(res->ai_addr); + memcpy(compact, &(in6->sin6_addr), 16); + memcpy(compact+16, &portN, sizeof(portN)); + return COMPACT_LEN_IPV6; + } + } + return 0; } -std::pair unpackcompact(const unsigned char* compact) +std::pair 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(&in), sizeof(in), - host, NI_MAXHOST, 0, 0, - NI_NUMERICHOST); - if(s) { - return std::pair(); + int portOffset = family == AF_INET?4:16; + std::pair 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) { diff --git a/src/bittorrent_helper.h b/src/bittorrent_helper.h index 2ed34c27..8d890b5b 100644 --- a/src/bittorrent_helper.h +++ b/src/bittorrent_helper.h @@ -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 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::pair +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& attrs); template -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(new Peer(ipaddr, port)); - ++dest_; + if(length%unit == 0) { + const unsigned char* base = + reinterpret_cast(peerData.s().data()); + const unsigned char* end = base+length; + for(; base != end; base += unit) { + std::pair p = unpackcompact(base, family_); + *dest_++ = SharedHandle(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 -void extractPeer(const SharedHandle& peerData, OutputIterator dest) +void extractPeer +(const SharedHandle& peerData, int family, OutputIterator dest) { - return extractPeer(peerData.get(), dest); + return extractPeer(peerData.get(), family, dest); } } // namespace bittorrent diff --git a/test/BittorrentHelperTest.cc b/test/BittorrentHelperTest.cc index b8724970..669c42ec 100644 --- a/test/BittorrentHelperTest.cc +++ b/test/BittorrentHelperTest.cc @@ -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 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 str = bencode2::decode(peersstr); + std::deque > 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 dict = bencode2::decode(peersString); std::deque > 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 = *peers.begin(); CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress()); @@ -786,7 +807,7 @@ void BittorrentHelperTest::testExtract2PeersFromList() SharedHandle dict = bencode2::decode(peersString); std::deque > 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 = *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 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 diff --git a/test/DHTFindNodeReplyMessageTest.cc b/test/DHTFindNodeReplyMessageTest.cc index a0c8923e..1191e279 100644 --- a/test/DHTFindNodeReplyMessageTest.cc +++ b/test/DHTFindNodeReplyMessageTest.cc @@ -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 >(&nodes[0], &nodes[DHTBucket::K])); diff --git a/test/DHTGetPeersReplyMessageTest.cc b/test/DHTGetPeersReplyMessageTest.cc index b85a9611..1eff779e 100644 --- a/test/DHTGetPeersReplyMessageTest.cc +++ b/test/DHTGetPeersReplyMessageTest.cc @@ -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 >(&nodes[0], &nodes[DHTBucket::K])); @@ -80,10 +80,9 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage() SharedHandle valuesList = List::g(); for(size_t i = 0; i < 4; ++i) { SharedHandle 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); diff --git a/test/DHTMessageFactoryImplTest.cc b/test/DHTMessageFactoryImplTest.cc index 272c2d14..6210c27a 100644 --- a/test/DHTMessageFactoryImplTest.cc +++ b/test/DHTMessageFactoryImplTest.cc @@ -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 valuesList = List::g(); for(size_t i = 0; i < 4; ++i) { SharedHandle 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); diff --git a/test/DHTRoutingTableSerializerTest.cc b/test/DHTRoutingTableSerializerTest.cc index 4b069819..81450a6b 100644 --- a/test/DHTRoutingTableSerializerTest.cc +++ b/test/DHTRoutingTableSerializerTest.cc @@ -115,7 +115,8 @@ void DHTRoutingTableSerializerTest::testSerialize() ss.read(buf, 6); { std::pair peer = - bittorrent::unpackcompact(reinterpret_cast(buf)); + bittorrent::unpackcompact(reinterpret_cast(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 peer = - bittorrent::unpackcompact(reinterpret_cast(buf)); + bittorrent::unpackcompact(reinterpret_cast(buf), + AF_INET); CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.3"), peer.first); CPPUNIT_ASSERT_EQUAL((uint16_t)6883, peer.second); } diff --git a/test/DefaultExtensionMessageFactoryTest.cc b/test/DefaultExtensionMessageFactoryTest.cc index 0eb16520..e74edb29 100644 --- a/test/DefaultExtensionMessageFactoryTest.cc +++ b/test/DefaultExtensionMessageFactoryTest.cc @@ -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])+ diff --git a/test/UTPexExtensionMessageTest.cc b/test/UTPexExtensionMessageTest.cc index c2afa55a..0aa700ea 100644 --- a/test/UTPexExtensionMessageTest.cc +++ b/test/UTPexExtensionMessageTest.cc @@ -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 };