DHTMessageFactoryImplTest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include "DHTMessageFactoryImpl.h"
  2. #include <cstring>
  3. #include <iostream>
  4. #include <cppunit/extensions/HelperMacros.h>
  5. #include "RecoverableException.h"
  6. #include "util.h"
  7. #include "DHTNode.h"
  8. #include "DHTRoutingTable.h"
  9. #include "Peer.h"
  10. #include "bittorrent_helper.h"
  11. #include "DHTBucket.h"
  12. #include "DHTPingMessage.h"
  13. #include "DHTPingReplyMessage.h"
  14. #include "DHTFindNodeMessage.h"
  15. #include "DHTFindNodeReplyMessage.h"
  16. #include "DHTGetPeersMessage.h"
  17. #include "DHTGetPeersReplyMessage.h"
  18. #include "DHTAnnouncePeerMessage.h"
  19. #include "DHTAnnouncePeerReplyMessage.h"
  20. #include "bencode2.h"
  21. namespace aria2 {
  22. class DHTMessageFactoryImplTest:public CppUnit::TestFixture {
  23. CPPUNIT_TEST_SUITE(DHTMessageFactoryImplTest);
  24. CPPUNIT_TEST(testCreatePingMessage);
  25. CPPUNIT_TEST(testCreatePingReplyMessage);
  26. CPPUNIT_TEST(testCreateFindNodeMessage);
  27. CPPUNIT_TEST(testCreateFindNodeReplyMessage);
  28. CPPUNIT_TEST(testCreateFindNodeReplyMessage6);
  29. CPPUNIT_TEST(testCreateGetPeersMessage);
  30. CPPUNIT_TEST(testCreateGetPeersReplyMessage);
  31. CPPUNIT_TEST(testCreateGetPeersReplyMessage6);
  32. CPPUNIT_TEST(testCreateAnnouncePeerMessage);
  33. CPPUNIT_TEST(testCreateAnnouncePeerReplyMessage);
  34. CPPUNIT_TEST(testReceivedErrorMessage);
  35. CPPUNIT_TEST_SUITE_END();
  36. public:
  37. std::unique_ptr<DHTMessageFactoryImpl> factory;
  38. std::unique_ptr<DHTRoutingTable> routingTable;
  39. std::shared_ptr<DHTNode> localNode;
  40. std::unique_ptr<DHTNode> remoteNode_;
  41. std::unique_ptr<DHTNode> remoteNode6_;
  42. unsigned char transactionID[DHT_TRANSACTION_ID_LENGTH];
  43. unsigned char remoteNodeID[DHT_ID_LENGTH];
  44. void setUp()
  45. {
  46. localNode = std::make_shared<DHTNode>();
  47. factory = make_unique<DHTMessageFactoryImpl>(AF_INET);
  48. factory->setLocalNode(localNode);
  49. memset(transactionID, 0xff, DHT_TRANSACTION_ID_LENGTH);
  50. memset(remoteNodeID, 0x0f, DHT_ID_LENGTH);
  51. routingTable = make_unique<DHTRoutingTable>(localNode);
  52. factory->setRoutingTable(routingTable.get());
  53. remoteNode_ = make_unique<DHTNode>(remoteNodeID);
  54. remoteNode_->setIPAddress("192.168.0.1");
  55. remoteNode_->setPort(6881);
  56. remoteNode6_ = make_unique<DHTNode>(remoteNodeID);
  57. remoteNode6_->setIPAddress("2001::2001");
  58. remoteNode6_->setPort(6881);
  59. }
  60. void tearDown() {}
  61. void testCreatePingMessage();
  62. void testCreatePingReplyMessage();
  63. void testCreateFindNodeMessage();
  64. void testCreateFindNodeReplyMessage();
  65. void testCreateFindNodeReplyMessage6();
  66. void testCreateGetPeersMessage();
  67. void testCreateGetPeersReplyMessage();
  68. void testCreateGetPeersReplyMessage6();
  69. void testCreateAnnouncePeerMessage();
  70. void testCreateAnnouncePeerReplyMessage();
  71. void testReceivedErrorMessage();
  72. };
  73. CPPUNIT_TEST_SUITE_REGISTRATION(DHTMessageFactoryImplTest);
  74. void DHTMessageFactoryImplTest::testCreatePingMessage()
  75. {
  76. Dict dict;
  77. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  78. dict.put("y", "q");
  79. dict.put("q", "ping");
  80. auto aDict = Dict::g();
  81. aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  82. dict.put("a", std::move(aDict));
  83. auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
  84. auto m = dynamic_cast<DHTPingMessage*>(r.get());
  85. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  86. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  87. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  88. util::toHex(m->getTransactionID()));
  89. }
  90. void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
  91. {
  92. Dict dict;
  93. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  94. dict.put("y", "r");
  95. auto rDict = Dict::g();
  96. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  97. dict.put("r", std::move(rDict));
  98. auto r = factory->createResponseMessage("ping", &dict,
  99. remoteNode_->getIPAddress(),
  100. remoteNode_->getPort());
  101. auto m = dynamic_cast<DHTPingReplyMessage*>(r.get());
  102. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  103. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  104. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  105. util::toHex(m->getTransactionID()));
  106. }
  107. void DHTMessageFactoryImplTest::testCreateFindNodeMessage()
  108. {
  109. Dict dict;
  110. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  111. dict.put("y", "q");
  112. dict.put("q", "find_node");
  113. auto aDict = Dict::g();
  114. aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  115. unsigned char targetNodeID[DHT_ID_LENGTH];
  116. memset(targetNodeID, 0x11, DHT_ID_LENGTH);
  117. aDict->put("target", String::g(targetNodeID, DHT_ID_LENGTH));
  118. dict.put("a", std::move(aDict));
  119. auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
  120. auto m = dynamic_cast<DHTFindNodeMessage*>(r.get());
  121. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  122. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  123. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  124. util::toHex(m->getTransactionID()));
  125. CPPUNIT_ASSERT_EQUAL(util::toHex(targetNodeID, DHT_ID_LENGTH),
  126. util::toHex(m->getTargetNodeID(), DHT_ID_LENGTH));
  127. }
  128. void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
  129. {
  130. try {
  131. Dict dict;
  132. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  133. dict.put("y", "r");
  134. auto rDict = Dict::g();
  135. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  136. std::string compactNodeInfo;
  137. std::shared_ptr<DHTNode> nodes[8];
  138. for(size_t i = 0; i < DHTBucket::K; ++i) {
  139. nodes[i] = std::make_shared<DHTNode>();
  140. nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
  141. nodes[i]->setPort(6881+i);
  142. unsigned char buf[COMPACT_LEN_IPV6];
  143. CPPUNIT_ASSERT_EQUAL
  144. (COMPACT_LEN_IPV4,
  145. bittorrent::packcompact
  146. (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  147. compactNodeInfo +=
  148. std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  149. std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
  150. }
  151. rDict->put("nodes", compactNodeInfo);
  152. dict.put("r", std::move(rDict));
  153. auto r = factory->createResponseMessage("find_node", &dict,
  154. remoteNode_->getIPAddress(),
  155. remoteNode_->getPort());
  156. auto m = dynamic_cast<DHTFindNodeReplyMessage*>(r.get());
  157. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  158. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  159. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  160. CPPUNIT_ASSERT(*nodes[0] == *m->getClosestKNodes()[0]);
  161. CPPUNIT_ASSERT(*nodes[7] == *m->getClosestKNodes()[7]);
  162. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  163. util::toHex(m->getTransactionID()));
  164. } catch(Exception& e) {
  165. CPPUNIT_FAIL(e.stackTrace());
  166. }
  167. }
  168. void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage6()
  169. {
  170. factory = make_unique<DHTMessageFactoryImpl>(AF_INET6);
  171. factory->setLocalNode(localNode);
  172. factory->setRoutingTable(routingTable.get());
  173. try {
  174. Dict dict;
  175. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  176. dict.put("y", "r");
  177. auto rDict = Dict::g();
  178. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  179. std::string compactNodeInfo;
  180. std::shared_ptr<DHTNode> nodes[8];
  181. for(size_t i = 0; i < DHTBucket::K; ++i) {
  182. nodes[i] = std::make_shared<DHTNode>();
  183. nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
  184. nodes[i]->setPort(6881+i);
  185. unsigned char buf[COMPACT_LEN_IPV6];
  186. CPPUNIT_ASSERT_EQUAL
  187. (COMPACT_LEN_IPV6,
  188. bittorrent::packcompact
  189. (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  190. compactNodeInfo +=
  191. std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  192. std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
  193. }
  194. rDict->put("nodes6", compactNodeInfo);
  195. dict.put("r", std::move(rDict));
  196. auto r = factory->createResponseMessage("find_node", &dict,
  197. remoteNode_->getIPAddress(),
  198. remoteNode_->getPort());
  199. auto m = dynamic_cast<DHTFindNodeReplyMessage*>(r.get());
  200. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  201. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  202. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  203. CPPUNIT_ASSERT(*nodes[0] == *m->getClosestKNodes()[0]);
  204. CPPUNIT_ASSERT(*nodes[7] == *m->getClosestKNodes()[7]);
  205. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  206. util::toHex(m->getTransactionID()));
  207. } catch(Exception& e) {
  208. CPPUNIT_FAIL(e.stackTrace());
  209. }
  210. }
  211. void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
  212. {
  213. Dict dict;
  214. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  215. dict.put("y", "q");
  216. dict.put("q", "get_peers");
  217. auto aDict = Dict::g();
  218. aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  219. unsigned char infoHash[DHT_ID_LENGTH];
  220. memset(infoHash, 0x11, DHT_ID_LENGTH);
  221. aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
  222. dict.put("a", std::move(aDict));
  223. auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
  224. auto m = dynamic_cast<DHTGetPeersMessage*>(r.get());
  225. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  226. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  227. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  228. util::toHex(m->getTransactionID()));
  229. CPPUNIT_ASSERT_EQUAL(util::toHex(infoHash, DHT_ID_LENGTH),
  230. util::toHex(m->getInfoHash(), DHT_ID_LENGTH));
  231. }
  232. void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage()
  233. {
  234. try {
  235. Dict dict;
  236. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  237. dict.put("y", "r");
  238. auto rDict = Dict::g();
  239. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  240. std::string compactNodeInfo;
  241. std::shared_ptr<DHTNode> nodes[8];
  242. for(size_t i = 0; i < DHTBucket::K; ++i) {
  243. nodes[i] = std::make_shared<DHTNode>();
  244. nodes[i]->setIPAddress("192.168.0."+util::uitos(i+1));
  245. nodes[i]->setPort(6881+i);
  246. unsigned char buf[COMPACT_LEN_IPV6];
  247. CPPUNIT_ASSERT_EQUAL
  248. (COMPACT_LEN_IPV4,
  249. bittorrent::packcompact
  250. (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  251. compactNodeInfo +=
  252. std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  253. std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
  254. }
  255. rDict->put("nodes", compactNodeInfo);
  256. std::deque<std::shared_ptr<Peer> > peers;
  257. auto valuesList = List::g();
  258. for(size_t i = 0; i < 4; ++i) {
  259. auto peer = std::make_shared<Peer>("192.168.0."+util::uitos(i+1),
  260. 6881+i);
  261. unsigned char buffer[COMPACT_LEN_IPV6];
  262. CPPUNIT_ASSERT_EQUAL
  263. (COMPACT_LEN_IPV4,
  264. bittorrent::packcompact
  265. (buffer, peer->getIPAddress(), peer->getPort()));
  266. valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
  267. peers.push_back(peer);
  268. }
  269. rDict->put("values", std::move(valuesList));
  270. rDict->put("token", "token");
  271. dict.put("r", std::move(rDict));
  272. auto r = factory->createResponseMessage("get_peers", &dict,
  273. remoteNode_->getIPAddress(),
  274. remoteNode_->getPort());
  275. auto m = dynamic_cast<DHTGetPeersReplyMessage*>(r.get());
  276. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  277. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  278. CPPUNIT_ASSERT_EQUAL(std::string("token"), m->getToken());
  279. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  280. CPPUNIT_ASSERT(*nodes[0] == *m->getClosestKNodes()[0]);
  281. CPPUNIT_ASSERT(*nodes[7] == *m->getClosestKNodes()[7]);
  282. CPPUNIT_ASSERT_EQUAL((size_t)4, m->getValues().size());
  283. for(int i = 0; i < 4; ++i) {
  284. CPPUNIT_ASSERT_EQUAL(peers[i]->getIPAddress(),
  285. m->getValues()[i]->getIPAddress());
  286. CPPUNIT_ASSERT_EQUAL(peers[i]->getPort(), m->getValues()[i]->getPort());
  287. }
  288. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  289. util::toHex(m->getTransactionID()));
  290. } catch(Exception& e) {
  291. CPPUNIT_FAIL(e.stackTrace());
  292. }
  293. }
  294. void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage6()
  295. {
  296. factory = make_unique<DHTMessageFactoryImpl>(AF_INET6);
  297. factory->setLocalNode(localNode);
  298. factory->setRoutingTable(routingTable.get());
  299. try {
  300. Dict dict;
  301. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  302. dict.put("y", "r");
  303. auto rDict = Dict::g();
  304. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  305. std::string compactNodeInfo;
  306. std::shared_ptr<DHTNode> nodes[8];
  307. for(size_t i = 0; i < DHTBucket::K; ++i) {
  308. nodes[i] = std::make_shared<DHTNode>();
  309. nodes[i]->setIPAddress("2001::000"+util::uitos(i+1));
  310. nodes[i]->setPort(6881+i);
  311. unsigned char buf[COMPACT_LEN_IPV6];
  312. CPPUNIT_ASSERT_EQUAL
  313. (COMPACT_LEN_IPV6,
  314. bittorrent::packcompact
  315. (buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  316. compactNodeInfo +=
  317. std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  318. std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
  319. }
  320. rDict->put("nodes6", compactNodeInfo);
  321. std::deque<std::shared_ptr<Peer>> peers;
  322. auto valuesList = List::g();
  323. for(size_t i = 0; i < 4; ++i) {
  324. auto peer = std::make_shared<Peer>("2001::100"+util::uitos(i+1), 6881+i);
  325. unsigned char buffer[COMPACT_LEN_IPV6];
  326. CPPUNIT_ASSERT_EQUAL
  327. (COMPACT_LEN_IPV6,
  328. bittorrent::packcompact
  329. (buffer, peer->getIPAddress(), peer->getPort()));
  330. valuesList->append(String::g(buffer, COMPACT_LEN_IPV6));
  331. peers.push_back(peer);
  332. }
  333. rDict->put("values", std::move(valuesList));
  334. rDict->put("token", "token");
  335. dict.put("r", std::move(rDict));
  336. auto r = factory->createResponseMessage("get_peers", &dict,
  337. remoteNode_->getIPAddress(),
  338. remoteNode_->getPort());
  339. auto m = dynamic_cast<DHTGetPeersReplyMessage*>(r.get());
  340. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  341. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  342. CPPUNIT_ASSERT_EQUAL(std::string("token"), m->getToken());
  343. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  344. CPPUNIT_ASSERT(*nodes[0] == *m->getClosestKNodes()[0]);
  345. CPPUNIT_ASSERT(*nodes[7] == *m->getClosestKNodes()[7]);
  346. CPPUNIT_ASSERT_EQUAL((size_t)4, m->getValues().size());
  347. for(int i = 0; i < 4; ++i) {
  348. CPPUNIT_ASSERT_EQUAL(peers[i]->getIPAddress(),
  349. m->getValues()[i]->getIPAddress());
  350. CPPUNIT_ASSERT_EQUAL(peers[i]->getPort(), m->getValues()[i]->getPort());
  351. }
  352. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  353. util::toHex(m->getTransactionID()));
  354. } catch(Exception& e) {
  355. CPPUNIT_FAIL(e.stackTrace());
  356. }
  357. }
  358. void DHTMessageFactoryImplTest::testCreateAnnouncePeerMessage()
  359. {
  360. try {
  361. Dict dict;
  362. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  363. dict.put("y", "q");
  364. dict.put("q", "announce_peer");
  365. auto aDict = Dict::g();
  366. aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  367. unsigned char infoHash[DHT_ID_LENGTH];
  368. memset(infoHash, 0x11, DHT_ID_LENGTH);
  369. aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
  370. std::string token = "ffff";
  371. uint16_t port = 6881;
  372. aDict->put("port", Integer::g(port));
  373. aDict->put("token", token);
  374. dict.put("a", std::move(aDict));
  375. remoteNode_->setPort(6882);
  376. auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6882);
  377. auto m = dynamic_cast<DHTAnnouncePeerMessage*>(r.get());
  378. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  379. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  380. CPPUNIT_ASSERT_EQUAL(token, m->getToken());
  381. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  382. util::toHex(m->getTransactionID()));
  383. CPPUNIT_ASSERT_EQUAL(util::toHex(infoHash, DHT_ID_LENGTH),
  384. util::toHex(m->getInfoHash(), DHT_ID_LENGTH));
  385. CPPUNIT_ASSERT_EQUAL(port, m->getTCPPort());
  386. } catch(Exception& e) {
  387. CPPUNIT_FAIL(e.stackTrace());
  388. }
  389. }
  390. void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
  391. {
  392. Dict dict;
  393. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  394. dict.put("y", "r");
  395. auto rDict = Dict::g();
  396. rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
  397. dict.put("r", std::move(rDict));
  398. auto r = factory->createResponseMessage("announce_peer", &dict,
  399. remoteNode_->getIPAddress(),
  400. remoteNode_->getPort());
  401. auto m = dynamic_cast<DHTAnnouncePeerReplyMessage*>(r.get());
  402. CPPUNIT_ASSERT(*localNode == *m->getLocalNode());
  403. CPPUNIT_ASSERT(*remoteNode_ == *m->getRemoteNode());
  404. CPPUNIT_ASSERT_EQUAL(util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  405. util::toHex(m->getTransactionID()));
  406. }
  407. void DHTMessageFactoryImplTest::testReceivedErrorMessage()
  408. {
  409. Dict dict;
  410. dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
  411. dict.put("y", "e");
  412. auto list = List::g();
  413. list->append(Integer::g(404));
  414. list->append("Not found");
  415. dict.put("e", std::move(list));
  416. try {
  417. factory->createResponseMessage("announce_peer", &dict,
  418. remoteNode_->getIPAddress(),
  419. remoteNode_->getPort());
  420. CPPUNIT_FAIL("exception must be thrown.");
  421. } catch(RecoverableException& e) {
  422. std::cerr << e.stackTrace() << std::endl;
  423. }
  424. }
  425. } // namespace aria2