From aa94f26b26ad3bfdedc8b57f52ae0441ad30de89 Mon Sep 17 00:00:00 2001 From: Steven Siloti Date: Sun, 27 Sep 2015 16:03:58 -0700 Subject: [PATCH] test_dht: use named parameter pattern for passing message arguments The number of optional parameters for send_dht_request was already beyond ridiculous and the addition of the 'want' argument pushed me over the top. --- test/test_dht.cpp | 285 ++++++++++++++++++++++++++++------------------ 1 file changed, 172 insertions(+), 113 deletions(-) diff --git a/test/test_dht.cpp b/test/test_dht.cpp index dfd7c5d75..4139a3425 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -186,15 +186,78 @@ void send_simple_dht_request(node& node, char const* msg, udp::endpoint const& e } } +void write_peers(entry::dictionary_type& r, std::set const& peers) +{ + entry::list_type& pe = r["values"].list(); + for (std::set::const_iterator it = peers.begin() + ; it != peers.end(); ++it) + { + std::string endpoint(18, '\0'); + std::string::iterator out = endpoint.begin(); + libtorrent::detail::write_endpoint(*it, out); + endpoint.resize(out - endpoint.begin()); + pe.push_back(entry(endpoint)); + } +} + +struct msg_args +{ + msg_args& info_hash(char const* i) + { if (i) a["info_hash"] = std::string(i, 20); return *this; } + + msg_args& name(char const* n) + { if (n) a["n"] = n; return *this; } + + msg_args& token(std::string t) + { a["token"] = t; return *this; } + + msg_args& port(int p) + { a["port"] = p; return *this; } + + msg_args& target(char const* t) + { if (t) a["target"] = std::string(t, 20); return *this; } + + msg_args& value(entry const& v) + { a["v"] = v; return *this; } + + msg_args& scrape(bool s) + { a["scrape"] = s ? 1 : 0; return *this; } + + msg_args& seed(bool s) + { a["seed"] = s ? 1 : 0; return *this; } + + msg_args& key(std::string k) + { a["k"] = k; return *this; } + + msg_args& sig(std::string s) + { a["sig"] = s; return *this; } + + msg_args& seq(int s) + { a["seq"] = s; return *this; } + + msg_args& cas(boost::int64_t c) + { a["cas"] = c; return *this; } + + msg_args& nid(sha1_hash const& n) + { a["id"] = n.to_string(); return *this; } + + msg_args& salt(char const* s) + { if (s) a["salt"] = s; return *this; } + + msg_args& want(std::string w) + { a["want"].list().push_back(w); return *this; } + + msg_args& nodes(nodes_t const& n) + { if (!n.empty()) dht::write_nodes_entry(a, n); return *this; } + + msg_args& peers(std::set const& p) + { if (!p.empty()) write_peers(a.dict(), p); return *this; } + + entry a; +}; void send_dht_request(node& node, char const* msg, udp::endpoint const& ep - , bdecode_node* reply, char const* t = "10", char const* info_hash = 0 - , char const* name = 0, std::string const token = std::string(), int port = 0 - , char const* target = 0, entry const* value = 0 - , bool scrape = false, bool seed = false - , std::string const key = std::string(), std::string const sig = std::string() - , int seq = -1, boost::int64_t cas = -1, sha1_hash const* nid = NULL - , char const* put_salt = NULL) + , bdecode_node* reply, char const* t = "10", msg_args const& args = msg_args()) { // we're about to clear out the backing buffer // for this lazy_entry, so we better clear it now @@ -203,22 +266,8 @@ void send_dht_request(node& node, char const* msg, udp::endpoint const& ep e["q"] = msg; e["t"] = t; e["y"] = "q"; - entry::dictionary_type& a = e["a"].dict(); - if (nid == NULL) a["id"] = generate_next().to_string(); - else a["id"] = nid->to_string(); - if (info_hash) a["info_hash"] = std::string(info_hash, 20); - if (name) a["n"] = name; - if (!token.empty()) a["token"] = token; - if (port) a["port"] = port; - if (target) a["target"] = std::string(target, 20); - if (value) a["v"] = *value; - if (!sig.empty()) a["sig"] = sig; - if (!key.empty()) a["k"] = key; - if (scrape) a["scrape"] = 1; - if (seed) a["seed"] = 1; - if (seq >= 0) a["seq"] = seq; - if (cas != -1) a["cas"] = cas; - if (put_salt) a["salt"] = put_salt; + e["a"] = args.a; + e["a"].dict().insert(std::make_pair("id", generate_next().to_string())); char msg_buf[1500]; int size = bencode(msg_buf, e); #if defined TORRENT_DEBUG && TORRENT_USE_IOSTREAM @@ -253,43 +302,15 @@ void send_dht_request(node& node, char const* msg, udp::endpoint const& ep g_sent_packets.erase(i); } -void write_peers(entry::dictionary_type& r, std::set const& peers) -{ - entry::list_type& pe = r["values"].list(); - for (std::set::const_iterator it = peers.begin() - ; it != peers.end(); ++it) - { - std::string endpoint(18, '\0'); - std::string::iterator out = endpoint.begin(); - libtorrent::detail::write_endpoint(*it, out); - endpoint.resize(out - endpoint.begin()); - pe.push_back(entry(endpoint)); - } -} - void send_dht_response(node& node, bdecode_node const& request, udp::endpoint const& ep - , nodes_t const& nodes = nodes_t() - , std::string const token = std::string(), int port = 0 - , std::set const& peers = std::set() - , char const* target = 0, entry const* value = 0 - , std::string const key = std::string(), std::string const sig = std::string() - , int seq = -1, sha1_hash const* nid = NULL) + , msg_args const& args = msg_args()) { entry e; e["y"] = "r"; e["t"] = request.dict_find_string_value("t"); // e["ip"] = endpoint_to_bytes(ep); - entry::dictionary_type& r = e["r"].dict(); - if (nid == NULL) r["id"] = generate_next().to_string(); - else r["id"] = nid->to_string(); - if (!token.empty()) r["token"] = token; - if (port) r["p"] = port; - if (!nodes.empty()) dht::write_nodes_entry(e["r"], nodes); - if (!peers.empty()) write_peers(r, peers); - if (value) r["v"] = *value; - if (!sig.empty()) r["sig"] = sig; - if (!key.empty()) r["k"] = key; - if (seq >= 0) r["seq"] = seq; + e["r"] = args.a; + e["r"].dict().insert(std::make_pair("id", generate_next().to_string())); char msg_buf[1500]; int size = bencode(msg_buf, e); #if defined TORRENT_DEBUG && TORRENT_USE_IOSTREAM @@ -341,8 +362,8 @@ void announce_immutable_items(node& node, udp::endpoint const* eps { if ((i % items[j].num_peers) == 0) continue; bdecode_node response; - send_dht_request(node, "get", eps[i], &response, "10", 0 - , 0, no, 0, (char const*)&items[j].target[0]); + send_dht_request(node, "get", eps[i], &response, "10" + , msg_args().target((char const*)&items[j].target[0])); key_desc_t desc[] = { @@ -380,8 +401,11 @@ void announce_immutable_items(node& node, udp::endpoint const* eps TEST_EQUAL(addr, eps[i].address()); } - send_dht_request(node, "put", eps[i], &response, "10", 0 - , 0, token, 0, (char const*)&items[j].target[0], &items[j].ent); + send_dht_request(node, "put", eps[i], &response, "10" + , msg_args() + .token(token) + .target((char const*)&items[j].target[0]) + .value(items[j].ent)); key_desc_t desc2[] = { @@ -410,9 +434,9 @@ void announce_immutable_items(node& node, udp::endpoint const* eps for (int j = 0; j < num_items; ++j) { bdecode_node response; - send_dht_request(node, "get", eps[j], &response, "10", 0 - , 0, no, 0, (char const*)&items[j].target[0]); - + send_dht_request(node, "get", eps[j], &response, "10" + , msg_args().target((char const*)&items[j].target[0])); + key_desc_t desc[] = { { "r", bdecode_node::dict_t, 0, key_desc_t::parse_children }, @@ -586,7 +610,8 @@ TORRENT_TEST(dht) // ====== get_peers ====== - send_dht_request(node, "get_peers", source, &response, "10", "01010101010101010101"); + send_dht_request(node, "get_peers", source, &response, "10" + , msg_args().info_hash("01010101010101010101")); dht::key_desc_t peer1_desc[] = { {"y", bdecode_node::string_t, 1, 0}, @@ -614,7 +639,13 @@ TORRENT_TEST(dht) // ====== announce ====== - send_dht_request(node, "announce_peer", source, &response, "10", "01010101010101010101", "test", token, 8080); + send_dht_request(node, "announce_peer", source, &response, "10" + , msg_args() + .info_hash("01010101010101010101") + .name("test") + .token(token) + .port(8080)); + dht::key_desc_t ann_desc[] = { {"y", bdecode_node::string_t, 1, 0}, @@ -642,7 +673,9 @@ TORRENT_TEST(dht) for (int i = 0; i < 100; ++i) { source = udp::endpoint(rand_v4(), 6000); - send_dht_request(node, "get_peers", source, &response, "10", "01010101010101010101"); + send_dht_request(node, "get_peers", source, &response, "10" + , msg_args().info_hash("01010101010101010101")); + ret = dht::verify_message(response, peer1_desc, parsed, 4, error_string , sizeof(error_string)); @@ -658,15 +691,21 @@ TORRENT_TEST(dht) fprintf(stderr, " invalid get_peers response: %s\n", error_string); } response.clear(); - send_dht_request(node, "announce_peer", source, &response, "10", "01010101010101010101" - , "test", token, 8080, 0, 0, false, i >= 50); + send_dht_request(node, "announce_peer", source, &response, "10" + , msg_args() + .info_hash("01010101010101010101") + .name("test") + .token(token) + .port(8080) + .seed(i >= 50)); + response.clear(); } // ====== get_peers ====== - send_dht_request(node, "get_peers", source, &response, "10", "01010101010101010101" - , 0, no, 0, 0, 0, true); + send_dht_request(node, "get_peers", source, &response, "10" + , msg_args().info_hash("01010101010101010101").scrape(true)); dht::key_desc_t peer2_desc[] = { {"y", bdecode_node::string_t, 1, 0}, @@ -729,8 +768,8 @@ TORRENT_TEST(dht) // this is now an invalid node-id for 'source' nid[0] = 0x18; int nodes_num = node.size().get<0>(); - send_dht_request(node, "find_node", source, &response, "10", 0, 0, std::string() - , 0, "0101010101010101010101010101010101010101", 0, false, false, std::string(), std::string(), -1, 0, &nid); + send_dht_request(node, "find_node", source, &response, "10" + , msg_args().target("0101010101010101010101010101010101010101").nid(nid)); ret = dht::verify_message(response, err_desc, parsed, 2, error_string , sizeof(error_string)); @@ -760,8 +799,8 @@ TORRENT_TEST(dht) // now the node-id is valid. nid[0] = 0x5f; - send_dht_request(node, "find_node", source, &response, "10", 0, 0, std::string() - , 0, "0101010101010101010101010101010101010101", 0, false, false, std::string(), std::string(), -1, 0, &nid); + send_dht_request(node, "find_node", source, &response, "10" + , msg_args().target("0101010101010101010101010101010101010101").nid(nid)); dht::key_desc_t nodes_desc[] = { {"y", bdecode_node::string_t, 1, 0}, @@ -905,9 +944,8 @@ TORRENT_TEST(dht) fprintf(stderr, "target_id: %s\n" , to_hex(target_id.to_string()).c_str()); - send_dht_request(node, "get", source, &response, "10", 0 - , 0, no, 0, (char*)&target_id[0] - , 0, false, false, std::string(), std::string()); + send_dht_request(node, "get", source, &response, "10" + , msg_args().target((char*)&target_id[0])); key_desc_t desc[] = { @@ -943,10 +981,14 @@ TORRENT_TEST(dht) VALGRIND_CHECK_MEM_IS_DEFINED(signature, item_sig_len); #endif - send_dht_request(node, "put", source, &response, "10", 0 - , 0, token, 0, 0, &items[0].ent, false, false - , std::string(public_key, item_pk_len) - , std::string(signature, item_sig_len), seq, -1, NULL, salt.first); + send_dht_request(node, "put", source, &response, "10" + , msg_args() + .token(token) + .value(items[0].ent) + .key(std::string(public_key, item_pk_len)) + .sig(std::string(signature, item_sig_len)) + .seq(seq) + .salt(salt.first)); ret = verify_message(response, desc2, parsed, 1, error_string , sizeof(error_string)); @@ -963,9 +1005,8 @@ TORRENT_TEST(dht) TEST_ERROR(error_string); } - send_dht_request(node, "get", source, &response, "10", 0 - , 0, no, 0, (char*)&target_id[0] - , 0, false, false, std::string(), std::string()); + send_dht_request(node, "get", source, &response, "10" + , msg_args().target((char*)&target_id[0])); fprintf(stderr, "target_id: %s\n" , to_hex(target_id.to_string()).c_str()); @@ -1018,10 +1059,14 @@ TORRENT_TEST(dht) TEST_CHECK(verify_mutable_item(itemv, salt, seq, public_key, signature) != 1); - send_dht_request(node, "put", source, &response, "10", 0 - , 0, token, 0, 0, &items[0].ent, false, false - , std::string(public_key, item_pk_len) - , std::string(signature, item_sig_len), seq, -1, NULL, salt.first); + send_dht_request(node, "put", source, &response, "10" + , msg_args() + .token(token) + .value(items[0].ent) + .key(std::string(public_key, item_pk_len)) + .sig(std::string(signature, item_sig_len)) + .seq(seq) + .salt(salt.first)); ret = verify_message(response, desc_error, parsed, 2, error_string , sizeof(error_string)); @@ -1041,9 +1086,8 @@ TORRENT_TEST(dht) // === test conditional get === - send_dht_request(node, "get", source, &response, "10", 0 - , 0, no, 0, (char*)&target_id[0] - , 0, false, false, std::string(), std::string(), seq-1); + send_dht_request(node, "get", source, &response, "10" + , msg_args().target((char*)&target_id[0]).seq(seq - 1)); { bdecode_node r = response.dict_find_dict("r"); @@ -1052,9 +1096,8 @@ TORRENT_TEST(dht) TEST_CHECK(r.dict_find("sig")); } - send_dht_request(node, "get", source, &response, "10", 0 - , 0, no, 0, (char*)&target_id[0] - , 0, false, false, std::string(), std::string(), seq); + send_dht_request(node, "get", source, &response, "10" + , msg_args().target((char*)&target_id[0]).seq(seq)); { bdecode_node r = response.dict_find_dict("r"); @@ -1082,11 +1125,15 @@ TORRENT_TEST(dht) fprintf(stderr, "PUT CAS 1\n"); - send_dht_request(node, "put", source, &response, "10", 0 - , 0, token, 0, 0, &items[1].ent, false, false - , std::string(public_key, item_pk_len) - , std::string(signature, item_sig_len), seq - , cas, NULL, salt.first); + send_dht_request(node, "put", source, &response, "10" + , msg_args() + .token(token) + .value(items[1].ent) + .key(std::string(public_key, item_pk_len)) + .sig(std::string(signature, item_sig_len)) + .seq(seq) + .cas(cas) + .salt(salt.first)); ret = verify_message(response, desc2, parsed, 1, error_string , sizeof(error_string)); @@ -1108,11 +1155,15 @@ TORRENT_TEST(dht) // put the same message again. This should fail because the // CAS hash is outdated, it's not the hash of the value that's // stored anymore - send_dht_request(node, "put", source, &response, "10", 0 - , 0, token, 0, 0, &items[1].ent, false, false - , std::string(public_key, item_pk_len) - , std::string(signature, item_sig_len), seq - , cas, NULL, salt.first); + send_dht_request(node, "put", source, &response, "10" + , msg_args() + .token(token) + .value(items[1].ent) + .key(std::string(public_key, item_pk_len)) + .sig(std::string(signature, item_sig_len)) + .seq(seq) + .cas(cas) + .salt(salt.first)); ret = verify_message(response, desc_error, parsed, 2, error_string , sizeof(error_string)); @@ -1445,7 +1496,7 @@ TORRENT_TEST(dht) nodes_t nodes; nodes.push_back(found_node); g_sent_packets.clear(); - send_dht_response(node, response, initial_node, nodes); + send_dht_response(node, response, initial_node, msg_args().nodes(nodes)); TEST_EQUAL(g_sent_packets.size(), 1); if (g_sent_packets.empty()) break; @@ -1520,7 +1571,8 @@ TORRENT_TEST(dht) nodes.push_back(next_node); g_sent_packets.clear(); - send_dht_response(node, response, initial_node, nodes, "10", 1234, peers[0]); + send_dht_response(node, response, initial_node + , msg_args().nodes(nodes).token("10").port(1234).peers(peers[0])); TEST_EQUAL(g_sent_packets.size(), 1); if (g_sent_packets.empty()) break; @@ -1548,7 +1600,8 @@ TORRENT_TEST(dht) peers[1].insert(tcp::endpoint(address_v4::from_string("4.1.1.6"), 4116)); g_sent_packets.clear(); - send_dht_response(node, response, next_node, nodes_t(), "11", 1234, peers[1]); + send_dht_response(node, response, next_node + , msg_args().token("11").port(1234).peers(peers[1])); for (std::list >::iterator i = g_sent_packets.begin() , end(g_sent_packets.end()); i != end; ++i) @@ -1604,8 +1657,8 @@ TORRENT_TEST(dht) } g_sent_packets.clear(); - send_dht_response(node, response, initial_node, nodes_t(), "10", 1234, std::set() - , NULL, &items[0].ent); + send_dht_response(node, response, initial_node + , msg_args().token("10").port(1234).value(items[0].ent)); TEST_CHECK(g_sent_packets.empty()); TEST_EQUAL(g_got_items.size(), 1); @@ -1654,8 +1707,14 @@ TORRENT_TEST(dht) itemv.second = bencode(buffer, items[0].ent); sign_mutable_item(itemv, empty_salt, seq, public_key, private_key, signature); - send_dht_response(node, response, initial_node, nodes_t(), "10", 1234, std::set() - , NULL, &items[0].ent, std::string(public_key, item_pk_len), std::string(signature, item_sig_len), seq); + send_dht_response(node, response, initial_node + , msg_args() + .token("10") + .port(1234) + .value(items[0].ent) + .key(std::string(public_key, item_pk_len)) + .sig(std::string(signature, item_sig_len)) + .seq(seq)); TEST_CHECK(g_sent_packets.empty()); TEST_EQUAL(g_got_items.size(), 1); @@ -1729,8 +1788,8 @@ TORRENT_TEST(dht) } char t[10]; snprintf(t, sizeof(t), "%02d", i); - send_dht_response(node, response, nodes[i].ep(), nodes_t(), t, 1234, - std::set(), 0, 0, std::string(), std::string(), -1, &nodes[i].id); + send_dht_response(node, response, nodes[i].ep() + , msg_args().token(t).port(1234).nid(nodes[i].id)); g_sent_packets.erase(packet); } @@ -1813,8 +1872,8 @@ TORRENT_TEST(dht) } char t[10]; snprintf(t, sizeof(t), "%02d", i); - send_dht_response(node, response, nodes[i].ep(), nodes_t(), t, 1234, - std::set(), 0, 0, std::string(), std::string(), -1, &nodes[i].id); + send_dht_response(node, response, nodes[i].ep() + , msg_args().token(t).port(1234).nid(nodes[i].id)); g_sent_packets.erase(packet); }