diff --git a/CMakeLists.txt b/CMakeLists.txt index bd3a2733f..7506ecc72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ set(sources web_peer_connection http_seed_connection instantiate_connection + merkle natpmp part_file packet_buffer diff --git a/Jamfile b/Jamfile index 19a333377..9585bc83e 100755 --- a/Jamfile +++ b/Jamfile @@ -597,6 +597,7 @@ SOURCES = identify_client ip_filter ip_voter + merkle peer_connection platform_util bt_peer_connection diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 9d2cadf99..4384c64a1 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -162,6 +162,7 @@ nobase_include_HEADERS = \ aux_/escape_string.hpp \ aux_/disable_warnings_push.hpp \ aux_/disable_warnings_pop.hpp \ + aux_/merkle.hpp \ \ extensions/lt_trackers.hpp \ extensions/metadata_transfer.hpp \ diff --git a/include/libtorrent/aux_/merkle.hpp b/include/libtorrent/aux_/merkle.hpp new file mode 100644 index 000000000..8e99c7efe --- /dev/null +++ b/include/libtorrent/aux_/merkle.hpp @@ -0,0 +1,48 @@ +/* + +Copyright (c) 2003-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. + +*/ + +#ifndef TORRENT_MERKLE_HPP_INCLUDED +#define TORRENT_MERKLE_HPP_INCLUDED + +#include "libtorrent/config.hpp" +#include "libtorrent/assert.hpp" + +namespace libtorrent +{ + TORRENT_EXTRA_EXPORT int merkle_num_leafs(int); + TORRENT_EXTRA_EXPORT int merkle_num_nodes(int); + TORRENT_EXTRA_EXPORT int merkle_get_parent(int); + TORRENT_EXTRA_EXPORT int merkle_get_sibling(int); +} + +#endif + diff --git a/include/libtorrent/config.hpp b/include/libtorrent/config.hpp index 0022711f2..39a99f816 100644 --- a/include/libtorrent/config.hpp +++ b/include/libtorrent/config.hpp @@ -62,10 +62,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LINK -#error you must define either BOOST_ASIO_SEPARATE_COMPILATION or BOOST_ASIO_DYN_LINK in your project in \ - order for asios declarations to be correct. If you are linking dynamically against libtorrent, define \ - BOOST_ASIO_DYN_LINK otherwise BOOST_ASIO_SEPARATE_COMPILATION. You can also use pkg-config or boost \ - build, to automatically apply these defines +#define BOOST_ASIO_SEPARATE_COMPILATION #endif #ifndef _MSC_VER diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index e5d0551de..0ce5d87c0 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -72,11 +72,6 @@ namespace libtorrent , tracker_retry_delay_max = 60 * 60 }; - TORRENT_EXTRA_EXPORT int merkle_num_leafs(int); - TORRENT_EXTRA_EXPORT int merkle_num_nodes(int); - TORRENT_EXTRA_EXPORT int merkle_get_parent(int); - TORRENT_EXTRA_EXPORT int merkle_get_sibling(int); - // this class holds information about one bittorrent tracker, as it // relates to a specific torrent. struct TORRENT_EXPORT announce_entry diff --git a/src/Makefile.am b/src/Makefile.am index 804cb8856..6492afabd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -84,6 +84,7 @@ libtorrent_rasterbar_la_SOURCES = \ lsd.cpp \ lt_trackers.cpp \ magnet_uri.cpp \ + merkle.cpp \ metadata_transfer.cpp \ mpi.c \ natpmp.cpp \ diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index d222a2d94..39fcf2896 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -35,7 +35,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/storage.hpp" #include "libtorrent/aux_/escape_string.hpp" // for convert_to_wstring #include "libtorrent/disk_io_thread.hpp" -#include "libtorrent/torrent_info.hpp" // for merkle_*() +#include "libtorrent/aux_/merkle.hpp" // for merkle_*() +#include "libtorrent/torrent_info.hpp" #include "libtorrent/performance_counters.hpp" // for counters #include "libtorrent/alert_manager.hpp" diff --git a/src/merkle.cpp b/src/merkle.cpp new file mode 100644 index 000000000..b44ebe3d4 --- /dev/null +++ b/src/merkle.cpp @@ -0,0 +1,69 @@ +/* + +Copyright (c) 2003-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 "libtorrent/aux_/merkle.hpp" + +namespace libtorrent +{ + int merkle_get_parent(int tree_node) + { + // node 0 doesn't have a parent + TORRENT_ASSERT(tree_node > 0); + return (tree_node - 1) / 2; + } + + int merkle_get_sibling(int tree_node) + { + // node 0 doesn't have a sibling + TORRENT_ASSERT(tree_node > 0); + // even numbers have their sibling to the left + // odd numbers have their sibling to the right + return tree_node + (tree_node&1?1:-1); + } + + int merkle_num_nodes(int leafs) + { + TORRENT_ASSERT(leafs > 0); + return (leafs << 1) - 1; + } + + int merkle_num_leafs(int pieces) + { + TORRENT_ASSERT(pieces > 0); + // round up to nearest 2 exponent + int ret = 1; + while (pieces > ret) ret <<= 1; + return ret; + } + +} + diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 6d047e277..6c441bdc4 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/invariant_check.hpp" #include "libtorrent/aux_/session_settings.hpp" #include "libtorrent/aux_/escape_string.hpp" // maybe_url_encode +#include "libtorrent/aux_/merkle.hpp" // for merkle_* #include "libtorrent/add_torrent_params.hpp" #include "libtorrent/magnet_uri.hpp" @@ -597,39 +598,6 @@ namespace libtorrent } // anonymous namespace - // TODO: 3 move the merkle functions out into its own file - // and header file - int merkle_get_parent(int tree_node) - { - // node 0 doesn't have a parent - TORRENT_ASSERT(tree_node > 0); - return (tree_node - 1) / 2; - } - - int merkle_get_sibling(int tree_node) - { - // node 0 doesn't have a sibling - TORRENT_ASSERT(tree_node > 0); - // even numbers have their sibling to the left - // odd numbers have their sibling to the right - return tree_node + (tree_node&1?1:-1); - } - - int merkle_num_nodes(int leafs) - { - TORRENT_ASSERT(leafs > 0); - return (leafs << 1) - 1; - } - - int merkle_num_leafs(int pieces) - { - TORRENT_ASSERT(pieces > 0); - // round up to nearest 2 exponent - int ret = 1; - while (pieces > ret) ret <<= 1; - return ret; - } - announce_entry::announce_entry(std::string const& u) : url(u) , next_announce(min_time()) diff --git a/test/Jamfile b/test/Jamfile index 3791b374b..cb91ccd31 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -97,6 +97,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_merkle.cpp ] [ run test_alert_manager.cpp ] [ run test_resolve_links.cpp ] [ run test_crc32.cpp ] diff --git a/test/Makefile.am b/test/Makefile.am index caf81d08e..13f65ac39 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -62,7 +62,8 @@ test_programs = \ test_gzip \ test_utf8 \ test_socket_io \ - test_sliding_average + test_sliding_average \ + test_merkle if ENABLE_TESTS check_PROGRAMS = $(test_programs) @@ -200,6 +201,7 @@ test_gzip_SOURCES = test_gzip.cpp test_utf8_SOURCES = test_utf8.cpp test_socket_io_SOURCES = test_socket_io.cpp test_sliding_average_SOURCES = test_sliding_average.cpp +test_merkle_SOURCES = test_merkle.cpp LDADD = libtest.la $(top_builddir)/src/libtorrent-rasterbar.la diff --git a/test/test_merkle.cpp b/test/test_merkle.cpp new file mode 100644 index 000000000..b179840dc --- /dev/null +++ b/test/test_merkle.cpp @@ -0,0 +1,108 @@ +/* + +Copyright (c) 2012, 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 "libtorrent/aux_/merkle.hpp" + +int test_main() +{ + using namespace libtorrent; + + // test merkle_*() functions + + // this is the structure: + // 0 + // 1 2 + // 3 4 5 6 + // 7 8 9 10 11 12 13 14 + // num_leafs = 8 + + TEST_EQUAL(merkle_num_leafs(1), 1); + TEST_EQUAL(merkle_num_leafs(2), 2); + TEST_EQUAL(merkle_num_leafs(3), 4); + TEST_EQUAL(merkle_num_leafs(4), 4); + TEST_EQUAL(merkle_num_leafs(5), 8); + TEST_EQUAL(merkle_num_leafs(6), 8); + TEST_EQUAL(merkle_num_leafs(7), 8); + TEST_EQUAL(merkle_num_leafs(8), 8); + TEST_EQUAL(merkle_num_leafs(9), 16); + TEST_EQUAL(merkle_num_leafs(10), 16); + TEST_EQUAL(merkle_num_leafs(11), 16); + TEST_EQUAL(merkle_num_leafs(12), 16); + TEST_EQUAL(merkle_num_leafs(13), 16); + TEST_EQUAL(merkle_num_leafs(14), 16); + TEST_EQUAL(merkle_num_leafs(15), 16); + TEST_EQUAL(merkle_num_leafs(16), 16); + TEST_EQUAL(merkle_num_leafs(17), 32); + TEST_EQUAL(merkle_num_leafs(18), 32); + + // parents + TEST_EQUAL(merkle_get_parent(1), 0); + TEST_EQUAL(merkle_get_parent(2), 0); + TEST_EQUAL(merkle_get_parent(3), 1); + TEST_EQUAL(merkle_get_parent(4), 1); + TEST_EQUAL(merkle_get_parent(5), 2); + TEST_EQUAL(merkle_get_parent(6), 2); + TEST_EQUAL(merkle_get_parent(7), 3); + TEST_EQUAL(merkle_get_parent(8), 3); + TEST_EQUAL(merkle_get_parent(9), 4); + TEST_EQUAL(merkle_get_parent(10), 4); + TEST_EQUAL(merkle_get_parent(11), 5); + TEST_EQUAL(merkle_get_parent(12), 5); + TEST_EQUAL(merkle_get_parent(13), 6); + TEST_EQUAL(merkle_get_parent(14), 6); + + // siblings + TEST_EQUAL(merkle_get_sibling(1), 2); + TEST_EQUAL(merkle_get_sibling(2), 1); + TEST_EQUAL(merkle_get_sibling(3), 4); + TEST_EQUAL(merkle_get_sibling(4), 3); + TEST_EQUAL(merkle_get_sibling(5), 6); + TEST_EQUAL(merkle_get_sibling(6), 5); + TEST_EQUAL(merkle_get_sibling(7), 8); + TEST_EQUAL(merkle_get_sibling(8), 7); + TEST_EQUAL(merkle_get_sibling(9), 10); + TEST_EQUAL(merkle_get_sibling(10), 9); + TEST_EQUAL(merkle_get_sibling(11), 12); + TEST_EQUAL(merkle_get_sibling(12), 11); + TEST_EQUAL(merkle_get_sibling(13), 14); + TEST_EQUAL(merkle_get_sibling(14), 13); + + // total number of nodes given the number of leafs + TEST_EQUAL(merkle_num_nodes(1), 1); + TEST_EQUAL(merkle_num_nodes(2), 3); + TEST_EQUAL(merkle_num_nodes(4), 7); + TEST_EQUAL(merkle_num_nodes(8), 15); + TEST_EQUAL(merkle_num_nodes(16), 31); + +} + diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index a89c2c5d7..53b4ea1a6 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -187,73 +187,6 @@ int test_torrent_parse() { error_code ec; - // test merkle_*() functions - - // this is the structure: - // 0 - // 1 2 - // 3 4 5 6 - // 7 8 9 10 11 12 13 14 - // num_leafs = 8 - - TEST_EQUAL(merkle_num_leafs(1), 1); - TEST_EQUAL(merkle_num_leafs(2), 2); - TEST_EQUAL(merkle_num_leafs(3), 4); - TEST_EQUAL(merkle_num_leafs(4), 4); - TEST_EQUAL(merkle_num_leafs(5), 8); - TEST_EQUAL(merkle_num_leafs(6), 8); - TEST_EQUAL(merkle_num_leafs(7), 8); - TEST_EQUAL(merkle_num_leafs(8), 8); - TEST_EQUAL(merkle_num_leafs(9), 16); - TEST_EQUAL(merkle_num_leafs(10), 16); - TEST_EQUAL(merkle_num_leafs(11), 16); - TEST_EQUAL(merkle_num_leafs(12), 16); - TEST_EQUAL(merkle_num_leafs(13), 16); - TEST_EQUAL(merkle_num_leafs(14), 16); - TEST_EQUAL(merkle_num_leafs(15), 16); - TEST_EQUAL(merkle_num_leafs(16), 16); - TEST_EQUAL(merkle_num_leafs(17), 32); - TEST_EQUAL(merkle_num_leafs(18), 32); - - // parents - TEST_EQUAL(merkle_get_parent(1), 0); - TEST_EQUAL(merkle_get_parent(2), 0); - TEST_EQUAL(merkle_get_parent(3), 1); - TEST_EQUAL(merkle_get_parent(4), 1); - TEST_EQUAL(merkle_get_parent(5), 2); - TEST_EQUAL(merkle_get_parent(6), 2); - TEST_EQUAL(merkle_get_parent(7), 3); - TEST_EQUAL(merkle_get_parent(8), 3); - TEST_EQUAL(merkle_get_parent(9), 4); - TEST_EQUAL(merkle_get_parent(10), 4); - TEST_EQUAL(merkle_get_parent(11), 5); - TEST_EQUAL(merkle_get_parent(12), 5); - TEST_EQUAL(merkle_get_parent(13), 6); - TEST_EQUAL(merkle_get_parent(14), 6); - - // siblings - TEST_EQUAL(merkle_get_sibling(1), 2); - TEST_EQUAL(merkle_get_sibling(2), 1); - TEST_EQUAL(merkle_get_sibling(3), 4); - TEST_EQUAL(merkle_get_sibling(4), 3); - TEST_EQUAL(merkle_get_sibling(5), 6); - TEST_EQUAL(merkle_get_sibling(6), 5); - TEST_EQUAL(merkle_get_sibling(7), 8); - TEST_EQUAL(merkle_get_sibling(8), 7); - TEST_EQUAL(merkle_get_sibling(9), 10); - TEST_EQUAL(merkle_get_sibling(10), 9); - TEST_EQUAL(merkle_get_sibling(11), 12); - TEST_EQUAL(merkle_get_sibling(12), 11); - TEST_EQUAL(merkle_get_sibling(13), 14); - TEST_EQUAL(merkle_get_sibling(14), 13); - - // total number of nodes given the number of leafs - TEST_EQUAL(merkle_num_nodes(1), 1); - TEST_EQUAL(merkle_num_nodes(2), 3); - TEST_EQUAL(merkle_num_nodes(4), 7); - TEST_EQUAL(merkle_num_nodes(8), 15); - TEST_EQUAL(merkle_num_nodes(16), 31); - // test sanitize_append_path_element std::string path;