From 555efd92794f4a5030f5e2b49a091e044f18436e Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 4 May 2014 06:46:47 +0000 Subject: [PATCH] factor out address/endpoint I/O into it's own unit test. merge write_string from bencode and socket_io. extend unit test --- CMakeLists.txt | 3 + include/libtorrent/bencode.hpp | 14 +--- include/libtorrent/io.hpp | 11 ++-- include/libtorrent/socket_io.hpp | 23 ++++++- src/kademlia/dht_tracker.cpp | 23 ------- test/Jamfile | 1 + test/Makefile.am | 4 +- test/test_primitives.cpp | 8 --- test/test_socket_io.cpp | 106 +++++++++++++++++++++++++++++++ 9 files changed, 145 insertions(+), 48 deletions(-) create mode 100644 test/test_socket_io.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 23196b40d..3af4b6958 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -341,6 +341,9 @@ if(build_tests) test_session test_torrent_parse test_threads + test_gzip + test_utf8 + test_socket_io ) add_library(test_common STATIC test/main.cpp test/setup_transfer.cpp) diff --git a/include/libtorrent/bencode.hpp b/include/libtorrent/bencode.hpp index 5d2a99e1f..d8f57e13c 100644 --- a/include/libtorrent/bencode.hpp +++ b/include/libtorrent/bencode.hpp @@ -97,6 +97,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/assert.hpp" #include "libtorrent/escape_string.hpp" +#include "libtorrent/io.hpp" // for write_string namespace libtorrent { @@ -110,15 +111,6 @@ namespace libtorrent namespace detail { - template - int write_string(OutIt& out, const std::string& val) - { - for (std::string::const_iterator i = val.begin() - , end(val.end()); i != end; ++i) - *out++ = *i; - return int(val.length()); - } - // this is used in the template, so it must be available to the client TORRENT_EXPORT char const* integer_to_str(char* buf, int size , entry::integer_type val); @@ -202,7 +194,7 @@ namespace libtorrent case entry::string_t: ret += write_integer(out, e.string().length()); write_char(out, ':'); - ret += write_string(out, e.string()); + ret += write_string(e.string(), out); ret += 1; break; case entry::list_t: @@ -220,7 +212,7 @@ namespace libtorrent // write key ret += write_integer(out, i->first.length()); write_char(out, ':'); - ret += write_string(out, i->first); + ret += write_string(i->first, out); // write value ret += bencode_recursive(out, i->second); ret += 1; diff --git a/include/libtorrent/io.hpp b/include/libtorrent/io.hpp index 4501845de..6e0c054fb 100644 --- a/include/libtorrent/io.hpp +++ b/include/libtorrent/io.hpp @@ -149,18 +149,21 @@ namespace libtorrent void write_int8(boost::int8_t val, OutIt& start) { write_impl(val, start); } - inline void write_string(std::string const& str, char*& start) + inline int write_string(std::string const& str, char*& start) { std::memcpy((void*)start, str.c_str(), str.size()); start += str.size(); + return str.size(); } template - void write_string(std::string const& str, OutIt& start) + int write_string(std::string const& val, OutIt& out) { - std::copy(str.begin(), str.end(), start); + for (std::string::const_iterator i = val.begin() + , end(val.end()); i != end; ++i) + *out++ = *i; + return int(val.length()); } - } } diff --git a/include/libtorrent/socket_io.hpp b/include/libtorrent/socket_io.hpp index d08cd69a7..efe1e6edc 100644 --- a/include/libtorrent/socket_io.hpp +++ b/include/libtorrent/socket_io.hpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/io.hpp" #include "libtorrent/error_code.hpp" #include "libtorrent/lazy_entry.hpp" +#include "libtorrent/bencode.hpp" #include "libtorrent/peer_id.hpp" // for sha1_hash #include @@ -138,9 +139,29 @@ namespace libtorrent #endif } } - } + template + void read_endpoint_list(libtorrent::entry const* n, std::vector& epl) + { + using namespace libtorrent; + if (n->type() != entry::list_t) return; + entry::list_type const& contacts = n->list(); + for (entry::list_type::const_iterator i = contacts.begin() + , end(contacts.end()); i != end; ++i) + { + if (i->type() != entry::string_t) return; + std::string const& p = i->string(); + if (p.size() < 6) continue; + std::string::const_iterator in = p.begin(); + if (p.size() == 6) + epl.push_back(read_v4_endpoint(in)); +#if TORRENT_USE_IPV6 + else if (p.size() == 18) + epl.push_back(read_v6_endpoint(in)); +#endif + } + } } diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp index ea4dc18d6..ea3c96907 100644 --- a/src/kademlia/dht_tracker.cpp +++ b/src/kademlia/dht_tracker.cpp @@ -70,29 +70,6 @@ enum namespace { const int tick_period = 1; // minutes - - template - void read_endpoint_list(libtorrent::entry const* n, std::vector& epl) - { - using namespace libtorrent; - if (n->type() != entry::list_t) return; - entry::list_type const& contacts = n->list(); - for (entry::list_type::const_iterator i = contacts.begin() - , end(contacts.end()); i != end; ++i) - { - if (i->type() != entry::string_t) return; - std::string const& p = i->string(); - if (p.size() < 6) continue; - std::string::const_iterator in = p.begin(); - if (p.size() == 6) - epl.push_back(read_v4_endpoint(in)); -#if TORRENT_USE_IPV6 - else if (p.size() == 18) - epl.push_back(read_v6_endpoint(in)); -#endif - } - } - } namespace libtorrent { namespace dht diff --git a/test/Jamfile b/test/Jamfile index 1b7070731..5eba24318 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -88,6 +88,7 @@ feature launcher : none valgrind : composite ; feature.compose valgrind : "valgrind --tool=memcheck -v --num-callers=20 --read-var-info=yes --track-origins=yes --error-exitcode=222 --suppressions=valgrind_suppressions.txt" on ; test-suite libtorrent : + [ run test_socket_io.cpp ] [ run test_utf8.cpp ] [ run test_gzip.cpp ] [ run test_bitfield.cpp ] diff --git a/test/Makefile.am b/test/Makefile.am index be044f432..9a4bca930 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -45,7 +45,8 @@ test_programs = \ test_web_seed \ test_remap_files \ test_gzip \ - test_utf8 + test_utf8 \ + test_socket_io if ENABLE_TESTS check_PROGRAMS = $(test_programs) @@ -174,6 +175,7 @@ test_web_seed_SOURCES = test_web_seed.cpp test_remap_files_SOURCES = test_remap_files.cpp test_gzip_SOURCES = test_gzip.cpp test_utf8_SOURCES = test_utf8.cpp +test_socket_io_SOURCES = test_socket_io.cpp LDADD = $(top_builddir)/src/libtorrent-rasterbar.la libtest.la diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index f406ca035..9874d8557 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -359,14 +359,6 @@ int test_main() h2 = to_hash("0123456789abcdef11232456789abcdef0123456"); TEST_CHECK(common_bits(&h1[0], &h2[0], 20) == 16 * 4 + 3); - - // test address_to_bytes - TEST_EQUAL(address_to_bytes(address_v4::from_string("10.11.12.13")), "\x0a\x0b\x0c\x0d"); - TEST_EQUAL(address_to_bytes(address_v4::from_string("16.5.127.1")), "\x10\x05\x7f\x01"); - - // test endpoint_to_bytes - TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("10.11.12.13"), 8080)), "\x0a\x0b\x0c\x0d\x1f\x90"); - TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("16.5.127.1"), 12345)), "\x10\x05\x7f\x01\x30\x39"); return 0; } diff --git a/test/test_socket_io.cpp b/test/test_socket_io.cpp new file mode 100644 index 000000000..6be746d37 --- /dev/null +++ b/test/test_socket_io.cpp @@ -0,0 +1,106 @@ +/* + +Copyright (c) 2014, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "test.hpp" +#include "setup_transfer.hpp" +#include "libtorrent/socket_io.hpp" +#include "libtorrent/socket.hpp" + +#include + +using namespace libtorrent; +using namespace libtorrent::detail; + +int test_main() +{ + // test address_to_bytes + TEST_EQUAL(address_to_bytes(address_v4::from_string("10.11.12.13")), "\x0a\x0b\x0c\x0d"); + TEST_EQUAL(address_to_bytes(address_v4::from_string("16.5.127.1")), "\x10\x05\x7f\x01"); + + // test endpoint_to_bytes + TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("10.11.12.13"), 8080)), "\x0a\x0b\x0c\x0d\x1f\x90"); + TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("16.5.127.1"), 12345)), "\x10\x05\x7f\x01\x30\x39"); + + std::string buf; + write_address(address_v4::from_string("16.5.128.1"), std::back_inserter(buf)); + TEST_EQUAL(buf, "\x10\x05\x80\x01"); + std::string::iterator in = buf.begin(); + address addr4 = read_v4_address(in); + TEST_EQUAL(addr4, address_v4::from_string("16.5.128.1")); + + buf.clear(); + write_endpoint(udp::endpoint(address_v4::from_string("16.5.128.1"), 1337), std::back_inserter(buf)); + TEST_EQUAL(buf, "\x10\x05\x80\x01\x05\x39"); + in = buf.begin(); + udp::endpoint ep4 = read_v4_endpoint(in); + TEST_EQUAL(ep4, udp::endpoint(address_v4::from_string("16.5.128.1"), 1337)); + +#if TORRENT_USE_IPV6 + buf.clear(); + write_address(address_v6::from_string("[1000::ffff]"), std::back_inserter(buf)); + TEST_CHECK(std::equal(buf.begin(), buf.end(), "\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff")); + in = buf.begin(); + address addr6 = read_v6_address(in); + TEST_EQUAL(addr6, address_v6::from_string("[1000::ffff]")); + + buf.clear(); + write_endpoint(udp::endpoint(address_v6::from_string("[1000::ffff]"), 1337), std::back_inserter(buf)); + TEST_CHECK(std::equal(buf.begin(), buf.end(), "\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x05\x39")); + TEST_EQUAL(buf.size(), 18); + in = buf.begin(); + udp::endpoint ep6 = read_v6_endpoint(in); + TEST_EQUAL(ep6, udp::endpoint(address_v6::from_string("[1000::ffff]"), 1337)); +#endif + + char const eplist[] = "l6:\x10\x05\x80\x01\x05\x39" "18:\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x05\x39" "e"; + lazy_entry e; + error_code ec; + lazy_bdecode(eplist, eplist + sizeof(eplist)-1, e, ec); + TEST_CHECK(!ec); + std::vector list; + read_endpoint_list(&e, list); + + TEST_EQUAL(list.size(), 2); + TEST_EQUAL(list[0], udp::endpoint(address_v4::from_string("16.5.128.1"), 1337)); + TEST_EQUAL(list[1], udp::endpoint(address_v6::from_string("[1000::ffff]"), 1337)); + + entry e2 = bdecode(eplist, eplist + sizeof(eplist)-1); + list.clear(); + read_endpoint_list(&e2, list); + + TEST_EQUAL(list.size(), 2); + TEST_EQUAL(list[0], udp::endpoint(address_v4::from_string("16.5.128.1"), 1337)); + TEST_EQUAL(list[1], udp::endpoint(address_v6::from_string("[1000::ffff]"), 1337)); + + return 0; +} +