DHTGetPeersMessageTest.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "DHTGetPeersMessage.h"
  2. #include <cppunit/extensions/HelperMacros.h>
  3. #include "DHTNode.h"
  4. #include "Exception.h"
  5. #include "util.h"
  6. #include "MockDHTMessageFactory.h"
  7. #include "MockDHTMessage.h"
  8. #include "MockDHTMessageDispatcher.h"
  9. #include "DHTTokenTracker.h"
  10. #include "DHTPeerAnnounceStorage.h"
  11. #include "DHTRoutingTable.h"
  12. #include "bencode2.h"
  13. #include "GroupId.h"
  14. #include "DownloadContext.h"
  15. #include "Option.h"
  16. #include "RequestGroup.h"
  17. #include "BtRegistry.h"
  18. #include "TorrentAttribute.h"
  19. namespace aria2 {
  20. class DHTGetPeersMessageTest : public CppUnit::TestFixture {
  21. CPPUNIT_TEST_SUITE(DHTGetPeersMessageTest);
  22. CPPUNIT_TEST(testGetBencodedMessage);
  23. CPPUNIT_TEST(testDoReceivedAction);
  24. CPPUNIT_TEST_SUITE_END();
  25. public:
  26. std::shared_ptr<DHTNode> localNode_;
  27. std::shared_ptr<DHTNode> remoteNode_;
  28. void setUp()
  29. {
  30. localNode_ = std::make_shared<DHTNode>();
  31. remoteNode_ = std::make_shared<DHTNode>();
  32. }
  33. void tearDown() {}
  34. void testGetBencodedMessage();
  35. void testDoReceivedAction();
  36. class MockDHTMessageFactory2 : public MockDHTMessageFactory {
  37. public:
  38. virtual std::unique_ptr<DHTGetPeersReplyMessage> createGetPeersReplyMessage(
  39. const std::shared_ptr<DHTNode>& remoteNode,
  40. std::vector<std::shared_ptr<DHTNode>> closestKNodes,
  41. std::vector<std::shared_ptr<Peer>> peers, const std::string& token,
  42. const std::string& transactionID) CXX11_OVERRIDE
  43. {
  44. auto m = make_unique<DHTGetPeersReplyMessage>(
  45. AF_INET, localNode_, remoteNode, token, transactionID);
  46. m->setClosestKNodes(closestKNodes);
  47. m->setValues(peers);
  48. return m;
  49. }
  50. };
  51. };
  52. CPPUNIT_TEST_SUITE_REGISTRATION(DHTGetPeersMessageTest);
  53. void DHTGetPeersMessageTest::testGetBencodedMessage()
  54. {
  55. unsigned char tid[DHT_TRANSACTION_ID_LENGTH];
  56. util::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
  57. std::string transactionID(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
  58. unsigned char infoHash[DHT_ID_LENGTH];
  59. util::generateRandomData(infoHash, DHT_ID_LENGTH);
  60. DHTGetPeersMessage msg(localNode_, remoteNode_, infoHash, transactionID);
  61. msg.setVersion("A200");
  62. std::string msgbody = msg.getBencodedMessage();
  63. Dict dict;
  64. dict.put("t", transactionID);
  65. dict.put("v", "A200");
  66. dict.put("y", "q");
  67. dict.put("q", "get_peers");
  68. auto aDict = Dict::g();
  69. aDict->put("id", String::g(localNode_->getID(), DHT_ID_LENGTH));
  70. aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
  71. dict.put("a", std::move(aDict));
  72. CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
  73. util::percentEncode(msgbody));
  74. }
  75. void DHTGetPeersMessageTest::testDoReceivedAction()
  76. {
  77. remoteNode_->setIPAddress("192.168.0.1");
  78. remoteNode_->setPort(6881);
  79. unsigned char tid[DHT_TRANSACTION_ID_LENGTH];
  80. util::generateRandomData(tid, DHT_TRANSACTION_ID_LENGTH);
  81. std::string transactionID(&tid[0], &tid[DHT_TRANSACTION_ID_LENGTH]);
  82. unsigned char infoHash[DHT_ID_LENGTH];
  83. util::generateRandomData(infoHash, DHT_ID_LENGTH);
  84. DHTTokenTracker tokenTracker;
  85. MockDHTMessageDispatcher dispatcher;
  86. MockDHTMessageFactory2 factory;
  87. factory.setLocalNode(localNode_);
  88. DHTRoutingTable routingTable(localNode_);
  89. auto torrentAttrs = std::make_shared<TorrentAttribute>();
  90. torrentAttrs->infoHash = std::string(infoHash, infoHash + DHT_ID_LENGTH);
  91. auto dctx = std::make_shared<DownloadContext>();
  92. dctx->setAttribute(CTX_ATTR_BT, torrentAttrs);
  93. auto option = std::make_shared<Option>();
  94. option->put(PREF_BT_EXTERNAL_IP, "192.168.0.1");
  95. auto gid = GroupId::create();
  96. RequestGroup group(gid, option);
  97. dctx->setOwnerRequestGroup(&group);
  98. BtRegistry btReg;
  99. btReg.put(
  100. gid->getNumericId(),
  101. make_unique<BtObject>(dctx, nullptr, nullptr, nullptr, nullptr, nullptr));
  102. btReg.setTcpPort(6890);
  103. DHTGetPeersMessage msg(localNode_, remoteNode_, infoHash, transactionID);
  104. msg.setRoutingTable(&routingTable);
  105. msg.setTokenTracker(&tokenTracker);
  106. msg.setMessageDispatcher(&dispatcher);
  107. msg.setMessageFactory(&factory);
  108. msg.setBtRegistry(&btReg);
  109. msg.setFamily(AF_INET);
  110. {
  111. // localhost has peer contact information for that infohash.
  112. DHTPeerAnnounceStorage peerAnnounceStorage;
  113. peerAnnounceStorage.addPeerAnnounce(infoHash, "192.168.0.100", 6888);
  114. peerAnnounceStorage.addPeerAnnounce(infoHash, "192.168.0.101", 6889);
  115. msg.setPeerAnnounceStorage(&peerAnnounceStorage);
  116. msg.doReceivedAction();
  117. CPPUNIT_ASSERT_EQUAL((size_t)1, dispatcher.messageQueue_.size());
  118. auto m = dynamic_cast<DHTGetPeersReplyMessage*>(
  119. dispatcher.messageQueue_[0].message_.get());
  120. CPPUNIT_ASSERT(*localNode_ == *m->getLocalNode());
  121. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  122. CPPUNIT_ASSERT_EQUAL(std::string("get_peers"), m->getMessageType());
  123. CPPUNIT_ASSERT_EQUAL(msg.getTransactionID(), m->getTransactionID());
  124. CPPUNIT_ASSERT_EQUAL(tokenTracker.generateToken(infoHash,
  125. remoteNode_->getIPAddress(),
  126. remoteNode_->getPort()),
  127. m->getToken());
  128. CPPUNIT_ASSERT_EQUAL((size_t)0, m->getClosestKNodes().size());
  129. CPPUNIT_ASSERT_EQUAL((size_t)3, m->getValues().size());
  130. {
  131. auto peer = m->getValues()[0];
  132. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.100"), peer->getIPAddress());
  133. CPPUNIT_ASSERT_EQUAL((uint16_t)6888, peer->getPort());
  134. }
  135. {
  136. auto peer = m->getValues()[1];
  137. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.101"), peer->getIPAddress());
  138. CPPUNIT_ASSERT_EQUAL((uint16_t)6889, peer->getPort());
  139. }
  140. {
  141. auto peer = m->getValues()[2];
  142. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  143. CPPUNIT_ASSERT_EQUAL((uint16_t)6890, peer->getPort());
  144. }
  145. }
  146. msg.setBtRegistry(nullptr);
  147. dispatcher.messageQueue_.clear();
  148. {
  149. // localhost doesn't have peer contact information for that infohash.
  150. DHTPeerAnnounceStorage peerAnnounceStorage;
  151. DHTRoutingTable routingTable(localNode_);
  152. std::shared_ptr<DHTNode> returnNode1(new DHTNode());
  153. routingTable.addNode(returnNode1);
  154. msg.setPeerAnnounceStorage(&peerAnnounceStorage);
  155. msg.setRoutingTable(&routingTable);
  156. msg.doReceivedAction();
  157. CPPUNIT_ASSERT_EQUAL((size_t)1, dispatcher.messageQueue_.size());
  158. auto m = dynamic_cast<DHTGetPeersReplyMessage*>(
  159. dispatcher.messageQueue_[0].message_.get());
  160. CPPUNIT_ASSERT(*localNode_ == *m->getLocalNode());
  161. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  162. CPPUNIT_ASSERT_EQUAL(std::string("get_peers"), m->getMessageType());
  163. CPPUNIT_ASSERT_EQUAL(msg.getTransactionID(), m->getTransactionID());
  164. CPPUNIT_ASSERT_EQUAL(tokenTracker.generateToken(infoHash,
  165. remoteNode_->getIPAddress(),
  166. remoteNode_->getPort()),
  167. m->getToken());
  168. CPPUNIT_ASSERT_EQUAL((size_t)1, m->getClosestKNodes().size());
  169. CPPUNIT_ASSERT(*returnNode1 == *m->getClosestKNodes()[0]);
  170. CPPUNIT_ASSERT_EQUAL((size_t)0, m->getValues().size());
  171. }
  172. }
  173. } // namespace aria2