├── .gitignore ├── .readthedocs.yaml ├── .travis.yml ├── AUTHORS.md ├── BUGS.md ├── CMakeLists.txt ├── INSTALL.md ├── NEWS.md ├── README.md ├── appveyor.yml ├── cmake ├── CMakeFindFrameworks.cmake └── FindSphinx.cmake ├── docs ├── CMakeLists.txt ├── api │ ├── endpoint.rst │ ├── error.rst │ ├── first_session.rst │ └── session.rst ├── conf.py ├── examples │ ├── bootstrap.rst │ └── cli.rst ├── index.rst └── overview │ ├── concept.rst │ ├── installation.rst │ └── walkthrough.rst ├── examples ├── CMakeLists.txt ├── bootstrap.cpp └── cli.cpp ├── include ├── CMakeLists.txt └── kademlia │ ├── detail │ ├── cxx11_macros.hpp │ └── symbol_visibility.hpp │ ├── endpoint.hpp │ ├── error.hpp │ ├── first_session.hpp │ ├── session.hpp │ └── session_base.hpp ├── scripts └── generate_profiling_report.sh ├── specs ├── infocom06-kad.pdf └── maymounkov-kademlia-lncs.pdf ├── src ├── CMakeLists.txt └── kademlia │ ├── CMakeLists.txt │ ├── boost_to_std_error.hpp │ ├── buffer.hpp │ ├── concurrent_guard.hpp │ ├── constants.cpp │ ├── constants.hpp │ ├── discover_neighbors_task.hpp │ ├── endpoint.cpp │ ├── engine.hpp │ ├── error.cpp │ ├── error_impl.cpp │ ├── error_impl.hpp │ ├── find_value_task.hpp │ ├── first_session.cpp │ ├── id.cpp │ ├── id.hpp │ ├── ip_endpoint.cpp │ ├── ip_endpoint.hpp │ ├── log.cpp │ ├── log.hpp │ ├── lookup_task.hpp │ ├── message.cpp │ ├── message.hpp │ ├── message_serializer.cpp │ ├── message_serializer.hpp │ ├── message_socket.hpp │ ├── network.hpp │ ├── notify_peer_task.hpp │ ├── peer.cpp │ ├── peer.hpp │ ├── r.hpp │ ├── response_callbacks.cpp │ ├── response_callbacks.hpp │ ├── response_router.hpp │ ├── routing_table.hpp │ ├── session.cpp │ ├── session_base.cpp │ ├── session_impl.hpp │ ├── store_value_task.hpp │ ├── timer.cpp │ ├── timer.hpp │ ├── tracker.hpp │ └── value_store.hpp └── test ├── CMakeLists.txt ├── fake_socket.hpp ├── test_engine.hpp └── unit_tests ├── CMakeLists.txt ├── captures ├── pattern_empty_routing_table.out ├── pattern_header.out └── pattern_id.out ├── common.cpp ├── common.hpp ├── corrupted_message.hpp ├── llvm_gcov.in ├── network.cpp ├── network.hpp ├── peer_factory.hpp ├── routing_table_mock.hpp ├── socket_mock.hpp ├── task_fixture.hpp ├── test_boost_to_std_error.cpp ├── test_concurrent_guard.cpp ├── test_discover_neighbors_task.cpp ├── test_endpoint.cpp ├── test_engine.cpp ├── test_error.cpp ├── test_fake_socket.cpp ├── test_find_value_task.cpp ├── test_first_session.cpp ├── test_id.cpp ├── test_ip_endpoint.cpp ├── test_log.cpp ├── test_lookup_task.cpp ├── test_message.cpp ├── test_message_serializer.cpp ├── test_message_socket.cpp ├── test_network.cpp ├── test_notify_peer_task.cpp ├── test_peer.cpp ├── test_r.cpp ├── test_response_callbacks.cpp ├── test_response_router.cpp ├── test_routing_table.cpp ├── test_session.cpp ├── test_store_value_task.cpp ├── test_timer.cpp └── tracker_mock.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore vim stuff 2 | *.swp 3 | build/* 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | sphinx: 4 | configuration: docs/conf.py 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: focal 2 | sudo: required 3 | 4 | language: cpp 5 | 6 | addons: 7 | apt: 8 | packages: 9 | - lcov 10 | - libboost-all-dev 11 | 12 | before_script: 13 | - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' 14 | - gem install coveralls-lcov 15 | - mkdir build_cov && cd build_cov && cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON .. 16 | 17 | script: 18 | - make -j $(nproc) coverage 19 | 20 | after_success: 21 | # Upload coverage report to coveralls. 22 | - coveralls-lcov app_total_stripped.info 23 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | David Keller 3 | -------------------------------------------------------------------------------- /BUGS.md: -------------------------------------------------------------------------------- 1 | # Bugs 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | cmake_minimum_required(VERSION 3.5) 26 | 27 | project(kademlia) 28 | include(CTest) 29 | 30 | list(INSERT CMAKE_MODULE_PATH 0 "${PROJECT_SOURCE_DIR}/cmake") 31 | 32 | # C++11. 33 | if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 34 | if (MSVC_VERSION LESS 1910) # 1910 -> VS 15.0 35 | message(FATAL_ERROR "Current compiler does'nt support c++11 yet") 36 | endif() 37 | add_definitions( 38 | -D_WIN32_WINNT=_WIN32_WINNT_WIN7 39 | -D_WINSOCK_DEPRECATED_NO_WARNINGS 40 | ) 41 | else() 42 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 43 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 44 | endif() 45 | 46 | include(CheckCXXCompilerFlag) 47 | check_cxx_compiler_flag(-std=c++11 IS_CXX11_SUPPORTED) 48 | if(NOT IS_CXX11_SUPPORTED) 49 | message(FATAL_ERROR "Current compiler does'nt support c++11 yet") 50 | endif() 51 | set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -fvisibility=hidden ${CMAKE_CXX_FLAGS}") 52 | endif() 53 | 54 | # Coverage 55 | option(ENABLE_COVERAGE "Enable coverage target") 56 | if(ENABLE_COVERAGE) 57 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 58 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 59 | set(CMAKE_EXEC_LINKER_FLAGS "${CMAKE_EXEC_LINKER_FLAGS} --coverage") 60 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 61 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 62 | set(CMAKE_EXEC_LINKER_FLAGS "${CMAKE_EXEC_LINKER_FLAGS} --coverage") 63 | else() 64 | message(FATAL_ERROR "Can't generate coverage target on ${CMAKE_CXX_COMPILER_ID}") 65 | endif() 66 | endif() 67 | 68 | # Documentation 69 | option(ENABLE_DOCUMENTATION "Enable documentation" OFF) 70 | 71 | # Threads 72 | find_package(Threads REQUIRED) 73 | 74 | # Boost 75 | if(WIN32) 76 | set(Boost_USE_STATIC_LIBS ON) 77 | endif() 78 | find_package(Boost 1.65 REQUIRED COMPONENTS 79 | system 80 | filesystem 81 | unit_test_framework) 82 | 83 | # Crypto 84 | find_package(OpenSSL REQUIRED) 85 | 86 | # Setup C++ definitions. 87 | add_definitions(-DPACKAGE_VERSION="0.0.0") 88 | add_definitions(-DPACKAGE_BUGREPORT="david.keller@litchis.fr") 89 | add_definitions(-DBOOST_ALL_NO_LIB 90 | -DBOOST_ASIO_HAS_MOVE 91 | -DBOOST_ASIO_HAS_VARIADIC_TEMPLATES 92 | -DBOOST_ASIO_HAS_STD_SYSTEM_ERROR 93 | -DBOOST_ASIO_HAS_STD_ARRAY 94 | -DBOOST_ASIO_HAS_STD_SHARED_PTR 95 | -DBOOST_ASIO_HAS_STD_ATOMIC 96 | -DBOOST_ASIO_HAS_STD_CHRONO) 97 | if(NOT Boost_USE_STATIC_LIBS) 98 | add_definitions(-DBOOST_ALL_DYN_LINK) 99 | endif() 100 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 101 | add_definitions(-DKADEMLIA_ENABLE_DEBUG) 102 | endif() 103 | 104 | # Setup includes directories. 105 | include_directories(BEFORE include src test) 106 | include_directories(${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR}) 107 | 108 | # Build everything. 109 | add_subdirectory(include) 110 | add_subdirectory(src) 111 | if(BUILD_TESTING) 112 | enable_testing() 113 | add_subdirectory(test) 114 | endif() 115 | add_subdirectory(examples) 116 | 117 | if(ENABLE_DOCUMENTATION) 118 | add_subdirectory(docs) 119 | endif() 120 | 121 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Requirements 4 | * cmake 5 | * boost 6 | * c++11 compiler 7 | 8 | ## Compilation 9 | 1. `$ mkdir build && cd build` 10 | 2. `$ cmake ..` 11 | 2. `$ make` 12 | 13 | ## Installation 14 | 1. `$ sudo make install` 15 | 16 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # 0.0.1 2 | - Add class kademlia::session 3 | - Add class kademlia::endpoint 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Documentation Status](https://readthedocs.org/projects/kademlia-cpp/badge/?version=master)](https://kademlia-cpp.readthedocs.io/en/latest/?badge=master) 2 | [![Build Status Linux](https://app.travis-ci.com/DavidKeller/kademlia.svg?branch=master)](https://app.travis-ci.com/DavidKeller/kademlia) 3 | [![Build status Windows](https://ci.appveyor.com/api/projects/status/vf43m6qq8fk6kri1?svg=true)](https://ci.appveyor.com/project/DavidKeller/kademlia) 4 | [![Coverage Status](https://coveralls.io/repos/github/DavidKeller/kademlia/badge.svg?branch=master)](https://coveralls.io/github/DavidKeller/kademlia?branch=master) 5 | 6 | # Description 7 | C++11 distributed hash table library 8 | 9 | **This software is experimental and under active development**. 10 | 11 | # Development 12 | 13 | ## Bug and feature requests 14 | * [Tracker](http://redmine.litchis.fr/projects/kademlia) 15 | 16 | ## Supported targets 17 | 18 | 19 | 20 | 21 | 22 |
OSCompiler
OSXclang
NIXgcc
Windows 7+MSVC
23 | 24 | ## Project structure 25 | ``` 26 | kademlia/ 27 | | 28 | |-- include API public headers files. 29 | |-- src Implementation sources and headers files. 30 | |-- test/unit_tests Unit tests. 31 | |-- docs User and development documentation. 32 | |-- specs Kademlia protocol papers 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2019 2 | 3 | platform: x64 4 | 5 | environment: 6 | BOOST_ROOT: C:/Libraries/boost_1_73_0 7 | CTEST_OUTPUT_ON_FAILURE: 1 8 | 9 | configuration: Release 10 | 11 | before_build: 12 | - cmd: |- 13 | md build 14 | cd build 15 | cmake -G "Visual Studio 16 2019" -DBOOST_ROOT="%BOOST_ROOT%" -DBoost_USE_STATIC_LIBS=ON .. 16 | 17 | build: 18 | project: build\kademlia.sln 19 | verbosity: minimal 20 | -------------------------------------------------------------------------------- /cmake/CMakeFindFrameworks.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # CMakeFindFrameworks 3 | # ------------------- 4 | # 5 | # helper module to find OSX frameworks 6 | 7 | #============================================================================= 8 | # Copyright 2003-2009 Kitware, Inc. 9 | # 10 | # Distributed under the OSI-approved BSD License (the "License"); 11 | # see accompanying file Copyright.txt for details. 12 | # 13 | # This software is distributed WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | # See the License for more information. 16 | #============================================================================= 17 | # (To distribute this file outside of CMake, substitute the full 18 | # License text for the above reference.) 19 | 20 | if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED) 21 | set(CMAKE_FIND_FRAMEWORKS_INCLUDED 1) 22 | macro(CMAKE_FIND_FRAMEWORKS fwk) 23 | set(${fwk}_FRAMEWORKS) 24 | if(APPLE) 25 | foreach(dir 26 | ~/Library/Frameworks/${fwk}.framework 27 | /usr/local/Frameworks/${fwk}.framework 28 | /Library/Frameworks/${fwk}.framework 29 | /System/Library/Frameworks/${fwk}.framework 30 | /Network/Library/Frameworks/${fwk}.framework) 31 | if(EXISTS ${dir}) 32 | set(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir}) 33 | endif() 34 | endforeach() 35 | endif() 36 | endmacro() 37 | endif() 38 | -------------------------------------------------------------------------------- /cmake/FindSphinx.cmake: -------------------------------------------------------------------------------- 1 | #Look for an executable called sphinx-build 2 | find_program(SPHINX_EXECUTABLE 3 | NAMES sphinx-build 4 | DOC "Path to sphinx-build executable") 5 | 6 | include(FindPackageHandleStandardArgs) 7 | 8 | #Handle standard arguments to find_package like REQUIRED and QUIET 9 | find_package_handle_standard_args(Sphinx 10 | "Failed to find sphinx-build executable" 11 | SPHINX_EXECUTABLE) 12 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | find_package(Sphinx REQUIRED) 27 | 28 | set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}) 29 | set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}) 30 | 31 | add_custom_target(kademlia_doc 32 | ALL 33 | COMMAND ${SPHINX_EXECUTABLE} -b html ${SPHINX_SOURCE} ${SPHINX_BUILD} 34 | VERBATIM 35 | COMMENT "Generating sphinx documentation") 36 | -------------------------------------------------------------------------------- /docs/api/endpoint.rst: -------------------------------------------------------------------------------- 1 | Endpoint 2 | ======== 3 | 4 | **#include ** 5 | 6 | .. cpp:class:: kademlia::endpoint 7 | 8 | Represents a network enpoint. 9 | 10 | This class is used to: 11 | 12 | * Provide the bootstraping participant **address** to the :cpp:class:`session` 13 | * Define the listening address(es) of a :cpp:class:`first_session` & 14 | :cpp:class:`session` instance 15 | 16 | .. rubric:: Constructors 17 | 18 | .. cpp:function:: endpoint \ 19 | ( void ) 20 | 21 | Construct an unitialized endpoint. 22 | 23 | .. cpp:function:: endpoint \ 24 | ( address_type const& address \ 25 | , service_type const& service ) 26 | 27 | Constructs an endpoint from an **address** and a port **service** identifier. 28 | 29 | .. cpp:function:: endpoint \ 30 | ( address_type const& address \ 31 | , service_numeric_type const& service ) 32 | 33 | Constructs an endpoint from an **address** and a port **service** identifier. 34 | 35 | .. rubric:: Methods 36 | 37 | .. cpp:function:: address_type const& \ 38 | address \ 39 | ( void ) const 40 | 41 | Get the **address** of the enpoint. 42 | 43 | .. cpp:function:: void \ 44 | address \ 45 | ( address_type const& address ) 46 | 47 | Set the **address** of the enpoint. 48 | 49 | .. cpp:function:: service_type const& \ 50 | service \ 51 | ( void ) const 52 | 53 | Get the **service** of the enpoint. 54 | 55 | .. cpp:function:: void \ 56 | service \ 57 | ( service_type const& service ) 58 | 59 | Set the **service** of the enpoint. 60 | 61 | .. rubric:: Types 62 | 63 | .. cpp:type:: address_type = std::string 64 | 65 | Represents an address. 66 | 67 | It can be: 68 | 69 | * An IPv4 (e.g. :cpp:expr:`"192.168.1.1"`) 70 | * An IPv6 (e.g. :cpp:expr:`"2001:0db8:85a3:0000:0000:8a2e:0370:7334"`) 71 | * A hostname (e.g. :cpp:expr:`"host-7430"`) 72 | 73 | .. cpp:type:: service_type = std::string 74 | 75 | Represents a port. 76 | 77 | It can be: 78 | 79 | * An unsigned 16 bits integer (e.g. :cpp:expr:`"12345"`) 80 | * A protocol name (e.g. :cpp:expr:`"http"`) 81 | 82 | .. cpp:type:: service_numeric_type = std::uint16_t 83 | 84 | Represents a port as a 16 bits unsigned integer. 85 | 86 | .. rubric:: Helpers 87 | 88 | .. cpp:function:: std::ostream& \ 89 | operator<< \ 90 | ( std::ostream & out \ 91 | , endpoint const& e ) 92 | 93 | Print the endpoint **e** string representation into the stream **out**. 94 | 95 | 96 | .. cpp:function:: std::istream & \ 97 | operator>> \ 98 | ( std::istream & in \ 99 | , endpoint & e ) 100 | 101 | Parse the endpoint **e** string representation from the stream **in**. 102 | 103 | .. cpp:function:: bool \ 104 | operator== \ 105 | ( endpoint const& a \ 106 | , endpoint const& b ) 107 | 108 | Compare endpoints **a** & **b** for equality. 109 | 110 | Return :cpp:expr:`true` if they are equal, :cpp:expr:`false` otherwise 111 | 112 | .. cpp:function:: bool \ 113 | operator!= \ 114 | ( endpoint const& a \ 115 | , endpoint const& b ) 116 | 117 | Compare endpoints **a** & **b** for inequality. 118 | 119 | Return :cpp:expr:`true` if they aren't equal, :cpp:expr:`false` otherwise 120 | -------------------------------------------------------------------------------- /docs/api/error.rst: -------------------------------------------------------------------------------- 1 | Error 2 | ===== 3 | 4 | **#include ** 5 | 6 | .. cpp:enum:: kademlia::error_type 7 | 8 | Represents all the library specific errors 9 | 10 | .. cpp:enumerator:: UNKNOWN_ERROR = 1 11 | 12 | An unknown error. 13 | 14 | .. cpp:enumerator:: RUN_ABORTED 15 | 16 | The :cpp:func:`session::abort()` has been called. 17 | 18 | .. cpp:enumerator:: INITIAL_PEER_FAILED_TO_RESPOND 19 | 20 | The session failed to contact a valid peer uppon creation. 21 | 22 | .. cpp:enumerator:: MISSING_PEERS 23 | 24 | The session routing table is missing peers. 25 | 26 | .. cpp:enumerator:: INVALID_ID 27 | 28 | An id has been corrupted. 29 | 30 | .. cpp:enumerator:: TRUNCATED_ID 31 | 32 | An id has been truncated. 33 | 34 | .. cpp:enumerator:: TRUNCATED_HEADER 35 | 36 | A packet header from the network is corrupted. 37 | 38 | .. cpp:enumerator:: TRUNCATED_ENDPOINT 39 | 40 | An endpoint information has been corrupted. 41 | 42 | .. cpp:enumerator:: TRUNCATED_ADDRESS 43 | 44 | An endpoint address has been corrupted. 45 | 46 | .. cpp:enumerator:: TRUNCATED_SIZE 47 | 48 | A list has been corrupted. 49 | 50 | .. cpp:enumerator:: UNKNOWN_PROTOCOL_VERSION 51 | 52 | A message from an unknown version of the library has been received. 53 | 54 | .. cpp:enumerator:: CORRUPTED_BODY 55 | 56 | A packet body has been corrupted. 57 | 58 | .. cpp:enumerator:: UNASSOCIATED_MESSAGE_ID 59 | 60 | An unexpected response has been received. 61 | 62 | .. cpp:enumerator:: INVALID_IPV4_ADDRESS 63 | 64 | The provided IPv4 address is invalid. 65 | 66 | .. cpp:enumerator:: INVALID_IPV6_ADDRESS 67 | 68 | The provided IPv6 address is invalid. 69 | 70 | .. cpp:enumerator:: UNIMPLEMENTED 71 | 72 | The function/method has been implemented yet. 73 | 74 | .. cpp:enumerator:: VALUE_NOT_FOUND 75 | 76 | The value associated with the requested key has not been found. 77 | 78 | .. cpp:enumerator:: TIMER_MALFUNCTION 79 | 80 | The internal timer failed to tick. 81 | 82 | .. cpp:enumerator:: ALREADY_RUNNING 83 | 84 | Another call to :cpp:func:`session::run()` is still blocked. 85 | -------------------------------------------------------------------------------- /docs/api/first_session.rst: -------------------------------------------------------------------------------- 1 | First Session 2 | ============= 3 | 4 | **#include ** 5 | 6 | .. cpp:class:: kademlia::first_session 7 | 8 | This class is used to bootstrap a network. 9 | 10 | .. note:: First session instances can be *moved* but can't be *copied*. 11 | 12 | .. rubric:: Constructors 13 | 14 | .. cpp:function:: first_session \ 15 | ( endpoint const& listen_on_ipv4 = endpoint( "0.0.0.0", DEFAULT_PORT ) \ 16 | , endpoint const& listen_on_ipv6 = endpoint( "::", DEFAULT_PORT ) ) 17 | 18 | Constructs a passive session. 19 | 20 | .. note:: 21 | 22 | This first_session acts like an active :cpp:class:`session` except it 23 | does'nt try to discover neighbors. It can be used by the first node 24 | of a network as no peer is known uppon its creation. 25 | 26 | Both **listen_on_ipv4** and **listen_on_ipv6** can be provided to 27 | change the addresses and ports this session is using to exchange 28 | with other peers. 29 | 30 | .. rubric:: Methods 31 | 32 | .. cpp:function:: std::error_code \ 33 | run \ 34 | ( void ) 35 | 36 | This blocking call executes the :cpp:class:`first_session` main loop. 37 | 38 | This method should be called in a dedicated thread. 39 | 40 | .. attention:: 41 | 42 | Exception can be thrown from this method. 43 | 44 | These can be library internal exceptions (e.g. failure to reach 45 | initial_peer) or exceptions coming from the user-provided handlers. 46 | 47 | Remember that if exception reaches a thread main funtion, the 48 | application will abort. 49 | Hence this method invocation should be wrapped within a 50 | :cpp:expr:`std::packaged_task<>` (e.g. by using 51 | :cpp:expr:`std::async()`). 52 | 53 | In order to exit from the main loop, :cpp:func:`abort()` should be 54 | called. 55 | 56 | The exit reason is returned. 57 | 58 | .. cpp:function:: void \ 59 | abort \ 60 | ( void ) 61 | 62 | Abort the :cpp:class:`first_session` main loop, that is make the 63 | :cpp:func:`run()` call exit. 64 | 65 | .. rubric:: Members 66 | 67 | .. cpp:member:: constexpr std::uint16_t DEFAULT_PORT = 27980 68 | 69 | The default port used by the session 70 | 71 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'Kademlia C++' 21 | copyright = '2021, David Keller' 22 | author = 'David Keller' 23 | 24 | 25 | # -- General configuration --------------------------------------------------- 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be 28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 29 | # ones. 30 | extensions = [ 31 | 'sphinx_rtd_theme' 32 | ] 33 | 34 | # Add any paths that contain templates here, relative to this directory. 35 | templates_path = ['_templates'] 36 | 37 | # List of patterns, relative to source directory, that match files and 38 | # directories to ignore when looking for source files. 39 | # This pattern also affects html_static_path and html_extra_path. 40 | exclude_patterns = [] 41 | 42 | 43 | # -- Options for HTML output ------------------------------------------------- 44 | 45 | # The theme to use for HTML and HTML Help pages. See the documentation for 46 | # a list of builtin themes. 47 | # 48 | html_theme = 'sphinx_rtd_theme' 49 | 50 | # Add any paths that contain custom static files (such as style sheets) here, 51 | # relative to this directory. They are copied after the builtin static files, 52 | # so a file named "default.css" will overwrite the builtin "default.css". 53 | html_static_path = ['_static'] 54 | 55 | default_role = 'any' 56 | 57 | highlight_language = 'cpp' 58 | -------------------------------------------------------------------------------- /docs/examples/bootstrap.rst: -------------------------------------------------------------------------------- 1 | Bootstraper 2 | =========== 3 | 4 | The following example demonstrates a console application used to bootstrap 5 | a Kademlia network. 6 | 7 | .. literalinclude:: ../../examples/bootstrap.cpp 8 | :language: cpp 9 | :linenos: 10 | -------------------------------------------------------------------------------- /docs/examples/cli.rst: -------------------------------------------------------------------------------- 1 | Command Line Interface 2 | ====================== 3 | 4 | The following example demonstrates a console application that is capable 5 | of saving and loading data from/to a Kademlia network. 6 | 7 | The save & load requests are read from **stdin**. Depending on the request 8 | type, either **load()** or **save()** is called. 9 | 10 | .. literalinclude:: ../../examples/cli.cpp 11 | :language: cpp 12 | :linenos: 13 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Kademlia C++'s documentation 2 | ============================ 3 | 4 | .. toctree:: 5 | :caption: Overview 6 | 7 | overview/concept 8 | overview/walkthrough 9 | overview/installation 10 | 11 | .. toctree:: 12 | :caption: Examples 13 | 14 | examples/cli 15 | examples/bootstrap 16 | 17 | .. toctree:: 18 | :caption: API 19 | 20 | api/endpoint 21 | api/first_session 22 | api/session 23 | api/error 24 | 25 | Indices and tables 26 | ================== 27 | 28 | * :ref:`genindex` 29 | -------------------------------------------------------------------------------- /docs/overview/concept.rst: -------------------------------------------------------------------------------- 1 | Concept 2 | ======= 3 | 4 | Kademlia is a **DHT**, which stands for **D**\ istributed **H**\ ash 5 | **T**\ able. 6 | 7 | Basically it is unordered map, where the *keys* and *values* are stored 8 | on a *decentralized* network, i.e. a network without central server. 9 | 10 | Without central server, the network is more scalable and fault tolerant. 11 | This protocol is not perfect regarding security and it is assumed that every 12 | network participant is benevolent. 13 | -------------------------------------------------------------------------------- /docs/overview/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Requirements 5 | ------------ 6 | 7 | * **CMake** >= **3.5** 8 | * **Boost** >= **1.65** 9 | 10 | BSD or Linux build 11 | ------------------ 12 | 13 | To build from this project root directory: 14 | 15 | .. code-block:: shell 16 | 17 | $ mkdir build; cd build 18 | $ cmake .. 19 | $ make -j `nproc` 20 | $ make check 21 | 22 | Inclusion into existing CMake project 23 | ------------------------------------- 24 | 25 | The project can be integrated into another **CMake** project using 26 | ``add_directory()`` to target the local checkout of this **kademlia** project. 27 | 28 | **Existing project CMakeLists.txt**: 29 | 30 | .. code-block:: cmake 31 | 32 | project(ExistingProject) 33 | 34 | add_subdirectory(PATH/TO/KAMDELIA_PROJECT/LOCAL_CHECKOUT) 35 | 36 | add_executable(app main.cpp) 37 | 38 | # The kademlia target can be referenced directly 39 | add_library(app kademlia) 40 | -------------------------------------------------------------------------------- /docs/overview/walkthrough.rst: -------------------------------------------------------------------------------- 1 | Walk-through 2 | ============ 3 | 4 | .. cpp:namespace:: kademlia 5 | 6 | In order to join the network, the C++ :cpp:class:`session` class should be 7 | instantiated. 8 | 9 | This class provides the :cpp:func:`session::async_save()` & 10 | :cpp:func:`session::async_load()` methods used to respectively store *key* 11 | with its associated *value* within the network and to retrieve the *value* 12 | associated with a *key*. 13 | 14 | Due to the network nature, these methods are asynchronous and take as 15 | an argument the callback to call once the request has completed. 16 | This design allows an application to execute multiple requests in parallel 17 | and hide network latency by performing other tasks in the meantime 18 | These callbacks will be executed within the context of the :cpp:class:`session` 19 | main event loop which is :cpp:func:`session::run()`. 20 | An application should call this :cpp:func:`session::run()` within a dedicated 21 | thread (and will have to use some synchronization mechanism like mutex 22 | within the callbacks when interacting with data touched by other threads). 23 | 24 | The :cpp:class:`session` constructor requires the network address of one 25 | participant, this is mandatory in order to discover other participant. 26 | This first participant is a kind of go-between. 27 | 28 | A skilled reader may wonder what participant address should be provided to 29 | the first participant of the network? 30 | The :cpp:class:`first_session` is dedicated 31 | to this use case, and its constructor doesn't require any participant address. 32 | Once there is at least one other participant within the network, the participant 33 | using the :cpp:class:`first_session` class may leave, the network will still be 34 | functional. 35 | The :cpp:class:`first_session` doesn't act as a server, it's only an ephemeral actor 36 | used to bootstrap the network. 37 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | add_executable(kademlia_cli 26 | cli.cpp) 27 | 28 | target_link_libraries(kademlia_cli 29 | kademlia 30 | Threads::Threads) 31 | 32 | add_executable(kademlia_bootstrap 33 | bootstrap.cpp) 34 | 35 | target_link_libraries(kademlia_bootstrap 36 | kademlia 37 | Threads::Threads) 38 | -------------------------------------------------------------------------------- /examples/bootstrap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace k = kademlia; 14 | 15 | int main 16 | ( int argc 17 | , char** argv ) 18 | { 19 | // Check command line arguments count 20 | if ( argc != 2 ) 21 | { 22 | std::cerr << "usage: " << argv[0] << " " << std::endl; 23 | return EXIT_FAILURE; 24 | } 25 | 26 | // Parse command line arguments 27 | std::uint16_t const port = std::atoi( argv[1] ); 28 | 29 | // Create the session 30 | k::first_session session{ k::endpoint{ "0.0.0.0", port } 31 | , k::endpoint{ "::", port } }; 32 | 33 | // Start the main loop thread 34 | auto main_loop = std::async( std::launch::async 35 | , &k::first_session::run, &session ); 36 | 37 | // Wait for exit request 38 | std::cout << "Press any key to exit" << std::endl; 39 | std::cin.get(); 40 | 41 | // Stop the main loop thread 42 | session.abort(); 43 | 44 | // Wait for the main loop thread termination 45 | auto failure = main_loop.get(); 46 | if ( failure != k::RUN_ABORTED ) 47 | std::cerr << failure.message() << std::endl; 48 | } 49 | -------------------------------------------------------------------------------- /examples/cli.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace k = kademlia; 14 | 15 | namespace { 16 | 17 | const char HELP[] = 18 | "save \n\tSave as \n\n" 19 | "load \n\tLoad value associated with \n\n" 20 | "help\n\tPrint this message\n\n"; 21 | 22 | std::vector< std::string > 23 | split( std::string const& line ) 24 | { 25 | std::istringstream in{ line }; 26 | 27 | using iterator = std::istream_iterator< std::string >; 28 | return std::vector< std::string >{ iterator{ in }, iterator{} }; 29 | } 30 | 31 | void 32 | load( k::session & session 33 | , std::string const& key ) 34 | { 35 | auto on_load = [ key ] ( std::error_code const& error 36 | , k::session::data_type const& data ) 37 | { 38 | if ( error ) 39 | std::cerr << "Failed to load \"" << key << "\"" << std::endl; 40 | else 41 | { 42 | std::string const& str{ data.begin(), data.end() }; 43 | std::cout << "Loaded \"" << key << "\" as \"" 44 | << str << "\"" << std::endl; 45 | } 46 | }; 47 | 48 | session.async_load( key, std::move( on_load ) ); 49 | } 50 | 51 | void 52 | save( k::session & session 53 | , std::string const& key 54 | , std::string const& value ) 55 | { 56 | auto on_save = [ key ] ( std::error_code const& error ) 57 | { 58 | if ( error ) 59 | std::cerr << "Failed to save \"" << key << "\"" << std::endl; 60 | else 61 | std::cout << "Saved \"" << key << "\"" << std::endl; 62 | }; 63 | 64 | session.async_save( key, value, std::move( on_save ) ); 65 | 66 | } 67 | 68 | void 69 | print_interactive_help 70 | ( void ) 71 | { 72 | std::cout << HELP << std::flush; 73 | } 74 | 75 | } // anonymous namespace 76 | 77 | int main 78 | ( int argc 79 | , char** argv ) 80 | { 81 | // Check command line arguments count 82 | if ( argc != 3 ) 83 | { 84 | std::cerr << "usage: " << argv[0] << " " << std::endl; 85 | return EXIT_FAILURE; 86 | } 87 | 88 | // Parse command line arguments 89 | std::uint16_t const port = std::atoi( argv[1] ); 90 | k::endpoint initial_peer; 91 | std::istringstream{ argv[2] } >> initial_peer; 92 | 93 | // Create the session 94 | k::session session{ initial_peer 95 | , k::endpoint{ "0.0.0.0", port } 96 | , k::endpoint{ "::", port } }; 97 | 98 | // Start the main loop thread 99 | auto main_loop = std::async( std::launch::async 100 | , &k::session::run, &session ); 101 | 102 | // Parse stdin until EOF (CTRL-D in Unix, CTRL-Z-Enter on Windows)) 103 | std::cout << "Enter \"help\" to see available actions" << std::endl; 104 | for ( std::string line; std::getline( std::cin, line ); ) 105 | { 106 | auto const tokens = split( line ); 107 | 108 | if ( tokens.empty() ) 109 | continue; 110 | 111 | if ( tokens[0] == "help" ) 112 | { 113 | print_interactive_help(); 114 | } 115 | else if ( tokens[0] == "save" ) 116 | { 117 | if ( tokens.size() != 3 ) 118 | print_interactive_help(); 119 | else 120 | save( session, tokens[1], tokens[2] ); 121 | } 122 | else if ( tokens[0] == "load" ) 123 | { 124 | if ( tokens.size() != 2 ) 125 | print_interactive_help(); 126 | else 127 | load( session, tokens[1] ); 128 | } 129 | else 130 | print_interactive_help(); 131 | } 132 | 133 | // Stop the main loop thread 134 | session.abort(); 135 | 136 | // Wait for the main loop thread termination 137 | auto failure = main_loop.get(); 138 | if ( failure != k::RUN_ABORTED ) 139 | std::cerr << failure.message() << std::endl; 140 | } 141 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /include/kademlia/detail/cxx11_macros.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_DETAIL_CXX11_MACROS_HPP 27 | #define KADEMLIA_DETAIL_CXX11_MACROS_HPP 28 | 29 | #ifdef _MSC_VER 30 | # define CXX11_CONSTEXPR const 31 | # define CXX11_NOEXCEPT throw() 32 | #endif 33 | 34 | #ifdef __clang__ 35 | # define CXX11_CONSTEXPR constexpr 36 | # define CXX11_NOEXCEPT noexcept 37 | #endif 38 | 39 | #ifdef __GNUC__ 40 | # define CXX11_CONSTEXPR constexpr 41 | # define CXX11_NOEXCEPT noexcept 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/kademlia/detail/symbol_visibility.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_DETAIL_SYMBOL_VISIBILITY_HPP 27 | #define KADEMLIA_DETAIL_SYMBOL_VISIBILITY_HPP 28 | 29 | #ifdef _MSC_VER 30 | # define KADEMLIA_EXPORT __declspec(dllexport) 31 | # define KADEMLIA_IMPORT __declspec(dllimport) 32 | #else 33 | # define KADEMLIA_EXPORT __attribute__ ((visibility ("default"))) 34 | # define KADEMLIA_IMPORT __attribute__ ((visibility ("default"))) 35 | #endif 36 | 37 | #ifdef KADEMLIA_AS_SHARED 38 | # ifdef KADEMLIA_BUILDING_AS_SHARED 39 | # define KADEMLIA_SYMBOL_VISIBILITY KADEMLIA_EXPORT 40 | # else 41 | # define KADEMLIA_SYMBOL_VISIBILITY KADEMLIA_IMPORT 42 | # endif 43 | #else 44 | # define KADEMLIA_SYMBOL_VISIBILITY 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/kademlia/endpoint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_ENDPOINT_HPP 27 | #define KADEMLIA_ENDPOINT_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | 41 | namespace kademlia { 42 | 43 | class endpoint final 44 | { 45 | public: 46 | using address_type = std::string; 47 | using service_type = std::string; 48 | using service_numeric_type = std::uint16_t; 49 | 50 | public: 51 | endpoint 52 | ( void ) 53 | { } 54 | 55 | endpoint 56 | ( address_type const& address 57 | , service_type const& service ) 58 | : address_( address ) 59 | , service_( service ) 60 | { } 61 | 62 | endpoint 63 | ( address_type const& address 64 | , service_numeric_type const& service ) 65 | : address_( address ) 66 | , service_( std::to_string( service ) ) 67 | { } 68 | 69 | address_type const& 70 | address 71 | ( void ) 72 | const 73 | { return address_; } 74 | 75 | void 76 | address 77 | ( address_type const& address ) 78 | { address_ = address; } 79 | 80 | service_type const& 81 | service 82 | ( void ) 83 | const 84 | { return service_; } 85 | 86 | void 87 | service 88 | ( service_type const& service ) 89 | { service_ = service; } 90 | 91 | private: 92 | address_type address_; 93 | service_type service_; 94 | }; 95 | 96 | KADEMLIA_SYMBOL_VISIBILITY 97 | std::ostream& 98 | operator<< 99 | ( std::ostream & out 100 | , endpoint const& e ); 101 | 102 | KADEMLIA_SYMBOL_VISIBILITY 103 | std::istream & 104 | operator>> 105 | ( std::istream & in 106 | , endpoint & e ); 107 | 108 | inline bool 109 | operator== 110 | ( endpoint const& a 111 | , endpoint const& b ) 112 | { return a.address() == b.address() && a.service() == b.service(); } 113 | 114 | inline bool 115 | operator!= 116 | ( endpoint const& a 117 | , endpoint const& b ) 118 | { return ! ( a == b ); } 119 | 120 | } // namespace kademlia 121 | 122 | #endif 123 | 124 | -------------------------------------------------------------------------------- /include/kademlia/error.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_ERROR_HPP 27 | #define KADEMLIA_ERROR_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | namespace kademlia { 37 | 38 | /// This enum list all library specific errors. 39 | enum error_type 40 | { 41 | /// An unknown error. 42 | UNKNOWN_ERROR = 1, 43 | /// The session::abort() has been called. 44 | RUN_ABORTED, 45 | /// The session failed to contact a valid peer uppon creation. 46 | INITIAL_PEER_FAILED_TO_RESPOND, 47 | /// The session routing table is missing peers. 48 | MISSING_PEERS, 49 | /// An id has been corrupted. 50 | INVALID_ID, 51 | /// An id has been truncated. 52 | TRUNCATED_ID, 53 | /// A packet header from the network is corrupted. 54 | TRUNCATED_HEADER, 55 | /// An endpoint information has been corrupted. 56 | TRUNCATED_ENDPOINT, 57 | /// An endpoint address has been corrupted. 58 | TRUNCATED_ADDRESS, 59 | /// A list has been corrupted. 60 | TRUNCATED_SIZE, 61 | /// A message from an unknown version of the library has been received. 62 | UNKNOWN_PROTOCOL_VERSION, 63 | /// A packet body has been corrupted. 64 | CORRUPTED_BODY, 65 | /// An unexpected response has been received. 66 | UNASSOCIATED_MESSAGE_ID, 67 | /// The provided IPv4 address is invalid. 68 | INVALID_IPV4_ADDRESS, 69 | /// The provided IPv6 address is invalid. 70 | INVALID_IPV6_ADDRESS, 71 | /// The function/method has been implemented yet. 72 | UNIMPLEMENTED, 73 | /// The value associated with the requested key has not been found. 74 | VALUE_NOT_FOUND, 75 | /// The internal timer failed to tick. 76 | TIMER_MALFUNCTION, 77 | /// Another call to session::run() is still blocked. 78 | ALREADY_RUNNING, 79 | }; 80 | 81 | /** 82 | * @brief Create a library error condition. 83 | * 84 | * @return The created error condition. 85 | */ 86 | KADEMLIA_SYMBOL_VISIBILITY std::error_condition 87 | make_error_condition 88 | ( error_type condition ); 89 | 90 | } // namespace kademlia 91 | 92 | namespace std { 93 | 94 | template <> 95 | struct is_error_condition_enum< kademlia::error_type > : true_type {}; 96 | 97 | } // namespace std 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /include/kademlia/first_session.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_FIRST_SESSION_HPP 27 | #define KADEMLIA_FIRST_SESSION_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace kademlia { 42 | 43 | class first_session final 44 | : public session_base 45 | { 46 | public: 47 | KADEMLIA_SYMBOL_VISIBILITY 48 | first_session 49 | ( endpoint const& listen_on_ipv4 = endpoint{ "0.0.0.0", DEFAULT_PORT } 50 | , endpoint const& listen_on_ipv6 = endpoint{ "::", DEFAULT_PORT } ); 51 | 52 | KADEMLIA_SYMBOL_VISIBILITY 53 | ~first_session 54 | ( void ); 55 | 56 | first_session 57 | ( first_session const& ) 58 | = delete; 59 | 60 | first_session& 61 | operator= 62 | ( first_session const& ) 63 | = delete; 64 | 65 | KADEMLIA_SYMBOL_VISIBILITY 66 | std::error_code 67 | run 68 | ( void ); 69 | 70 | KADEMLIA_SYMBOL_VISIBILITY 71 | void 72 | abort 73 | ( void ); 74 | 75 | private: 76 | struct impl; 77 | 78 | private: 79 | std::unique_ptr< impl > impl_; 80 | }; 81 | 82 | } // namespace kademlia 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /include/kademlia/session.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_SESSION_HPP 27 | #define KADEMLIA_SESSION_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace kademlia { 42 | 43 | class session final 44 | : public session_base 45 | { 46 | public: 47 | KADEMLIA_SYMBOL_VISIBILITY 48 | session 49 | ( endpoint const& initial_peer 50 | , endpoint const& listen_on_ipv4 = endpoint{ "0.0.0.0", DEFAULT_PORT } 51 | , endpoint const& listen_on_ipv6 = endpoint{ "::", DEFAULT_PORT } ); 52 | 53 | KADEMLIA_SYMBOL_VISIBILITY 54 | ~session 55 | ( void ); 56 | 57 | session 58 | ( session const& ) 59 | = delete; 60 | 61 | session& 62 | operator= 63 | ( session const& ) 64 | = delete; 65 | 66 | KADEMLIA_SYMBOL_VISIBILITY 67 | void 68 | async_save 69 | ( key_type const& key 70 | , data_type const& data 71 | , save_handler_type handler ); 72 | 73 | template< typename KeyType, typename DataType > 74 | void 75 | async_save 76 | ( KeyType const& key 77 | , DataType const& data 78 | , save_handler_type handler ) 79 | { 80 | async_save( key_type{ std::begin( key ), std::end( key ) } 81 | , data_type{ std::begin( data ), std::end( data ) } 82 | , std::move( handler ) ); 83 | } 84 | 85 | KADEMLIA_SYMBOL_VISIBILITY 86 | void 87 | async_load 88 | ( key_type const& key 89 | , load_handler_type handler ); 90 | 91 | template< typename KeyType > 92 | void 93 | async_load 94 | ( KeyType const& key 95 | , load_handler_type handler ) 96 | { 97 | async_load( key_type{ std::begin( key ), std::end( key ) } 98 | , std::move( handler ) ); 99 | } 100 | 101 | KADEMLIA_SYMBOL_VISIBILITY 102 | std::error_code 103 | run 104 | ( void ); 105 | 106 | KADEMLIA_SYMBOL_VISIBILITY 107 | void 108 | abort 109 | ( void ); 110 | 111 | private: 112 | struct impl; 113 | 114 | private: 115 | std::unique_ptr< impl > impl_; 116 | }; 117 | 118 | } // namespace kademlia 119 | 120 | #endif 121 | 122 | -------------------------------------------------------------------------------- /include/kademlia/session_base.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_SESSION_BASE_HPP 27 | #define KADEMLIA_SESSION_BASE_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | namespace kademlia { 41 | 42 | /** 43 | * @brief This object contains session types. 44 | */ 45 | class session_base 46 | { 47 | public: 48 | /// The key type used to find data. 49 | using key_type = std::vector< std::uint8_t >; 50 | 51 | /// The stored data type. 52 | using data_type = std::vector< std::uint8_t >; 53 | 54 | /// The callback type called to signal an async save status. 55 | using save_handler_type = std::function 56 | < void 57 | ( std::error_code const& error ) 58 | >; 59 | /// The callback type called to signal an async load status. 60 | using load_handler_type = std::function 61 | < void 62 | ( std::error_code const& error 63 | , data_type const& data ) 64 | >; 65 | 66 | /// This kademlia implementation default port. 67 | static CXX11_CONSTEXPR std::uint16_t DEFAULT_PORT = 27980; 68 | 69 | protected: 70 | /** 71 | * @brief Destructor used to prevent 72 | * usage dervied classes as this 73 | * base. 74 | */ 75 | ~session_base 76 | ( void ) 77 | = default; 78 | }; 79 | 80 | } // namespace kademlia 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /scripts/generate_profiling_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ "$#" -ne 1 ] || ! [ -d "$1" ]; then 6 | echo "Usage: $0 SOURCE_ROOT" >&2 7 | exit -1 8 | fi 9 | 10 | source_root=$(cd "$1"; pwd) 11 | 12 | CXXFLAGS='-pg' cmake -DCMAKE_BUILD_TYPE=Release ${source_root} 13 | make -j`nproc` 14 | 15 | time test/simulator/simulator --clients-count=50 --messages-count=10000 16 | 17 | gprof test/simulator/simulator | gprof2dot --strip --node-thres=5 | dot -Tpng -o profile.png 18 | 19 | -------------------------------------------------------------------------------- /specs/infocom06-kad.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidKeller/kademlia/4ccfd508f1b50734ff9f4c1db3c5b3bb48bdb404/specs/infocom06-kad.pdf -------------------------------------------------------------------------------- /specs/maymounkov-kademlia-lncs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidKeller/kademlia/4ccfd508f1b50734ff9f4c1db3c5b3bb48bdb404/specs/maymounkov-kademlia-lncs.pdf -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | add_subdirectory(kademlia) 27 | 28 | -------------------------------------------------------------------------------- /src/kademlia/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | set(kademlia_sources 27 | ${CMAKE_SOURCE_DIR}/include/kademlia/endpoint.hpp 28 | ${CMAKE_SOURCE_DIR}/include/kademlia/error.hpp 29 | ${CMAKE_SOURCE_DIR}/include/kademlia/session_base.hpp 30 | ${CMAKE_SOURCE_DIR}/include/kademlia/first_session.hpp 31 | ${CMAKE_SOURCE_DIR}/include/kademlia/session.hpp 32 | session_impl.hpp 33 | boost_to_std_error.hpp 34 | buffer.hpp 35 | concurrent_guard.hpp 36 | constants.cpp 37 | constants.hpp 38 | endpoint.cpp 39 | engine.hpp 40 | error.cpp 41 | error_impl.hpp 42 | error_impl.cpp 43 | find_value_task.hpp 44 | id.cpp 45 | id.hpp 46 | ip_endpoint.cpp 47 | ip_endpoint.hpp 48 | log.cpp 49 | log.hpp 50 | network.hpp 51 | message.cpp 52 | message.hpp 53 | message_serializer.cpp 54 | message_serializer.hpp 55 | message_socket.hpp 56 | peer.cpp 57 | peer.hpp 58 | response_callbacks.cpp 59 | response_callbacks.hpp 60 | response_router.hpp 61 | routing_table.hpp 62 | session.cpp 63 | session_base.cpp 64 | first_session.cpp 65 | store_value_task.hpp 66 | discover_neighbors_task.hpp 67 | timer.cpp 68 | timer.hpp 69 | tracker.hpp 70 | value_store.hpp 71 | lookup_task.hpp) 72 | 73 | # Kademlia shared 74 | add_library(kademlia SHARED 75 | ${kademlia_sources}) 76 | 77 | set_target_properties(kademlia 78 | PROPERTIES 79 | MACOSX_RPATH ON 80 | COMPILE_DEFINITIONS "KADEMLIA_BUILDING_AS_SHARED;KADEMLIA_AS_SHARED") 81 | 82 | target_link_libraries(kademlia 83 | ${Boost_SYSTEM_LIBRARY} 84 | ${OPENSSL_CRYPTO_LIBRARY} 85 | ${CMAKE_THREAD_LIBS_INIT}) 86 | 87 | # Kademlia static 88 | add_library(kademlia_static STATIC 89 | ${kademlia_sources}) 90 | 91 | target_link_libraries(kademlia_static 92 | ${Boost_SYSTEM_LIBRARY} 93 | ${OPENSSL_CRYPTO_LIBRARY} 94 | ${CMAKE_THREAD_LIBS_INIT}) 95 | 96 | set_target_properties(kademlia_static 97 | PROPERTIES 98 | POSITION_INDEPENDENT_CODE ON) 99 | 100 | -------------------------------------------------------------------------------- /src/kademlia/boost_to_std_error.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_BOOST_TO_STD_ERROR_HPP 27 | #define KADEMLIA_BOOST_TO_STD_ERROR_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #include "kademlia/error_impl.hpp" 37 | 38 | namespace kademlia { 39 | namespace detail { 40 | 41 | /** 42 | * 43 | */ 44 | inline std::error_code 45 | boost_to_std_error 46 | ( boost::system::error_code const& failure ) 47 | { 48 | if ( failure.category() == boost::system::generic_category() ) 49 | return std::error_code{ failure.value(), std::generic_category() }; 50 | else if ( failure.category() == boost::system::system_category() ) 51 | return std::error_code{ failure.value(), std::system_category() }; 52 | else 53 | return make_error_code( UNKNOWN_ERROR ); 54 | } 55 | 56 | } // namespace detail 57 | } // namespace kademlia 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /src/kademlia/buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_BUFFER_HPP 27 | #define KADEMLIA_BUFFER_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | namespace kademlia { 37 | namespace detail { 38 | 39 | using buffer = std::vector< std::uint8_t >; 40 | 41 | } // namespace detail 42 | } // namespace kademlia 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/kademlia/concurrent_guard.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, Davflag Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provflaged that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provflaged with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_CONCURRENT_GUARD_HPP 27 | #define KADEMLIA_CONCURRENT_GUARD_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | 35 | namespace kademlia { 36 | namespace detail { 37 | 38 | /** 39 | * @brief This class ensure no concurrent access to the same 40 | * method is performed. 41 | */ 42 | class concurrent_guard 43 | { 44 | public: 45 | /** 46 | * 47 | */ 48 | class sentry; 49 | 50 | public: 51 | /** 52 | * 53 | */ 54 | explicit concurrent_guard 55 | ( void ) 56 | { flag_.clear(); } 57 | 58 | private: 59 | /// 60 | std::atomic_flag flag_; 61 | }; 62 | 63 | /** 64 | * 65 | */ 66 | class concurrent_guard::sentry 67 | { 68 | public: 69 | /** 70 | * 71 | */ 72 | explicit sentry 73 | ( concurrent_guard & guard ) 74 | : guard_( guard ) 75 | { is_owner_of_flag_ = ! guard_.flag_.test_and_set(); } 76 | 77 | 78 | /** 79 | * 80 | */ 81 | ~sentry 82 | ( void ) 83 | { 84 | if ( is_owner_of_flag_ ) 85 | guard_.flag_.clear(); 86 | } 87 | 88 | /** 89 | * 90 | */ 91 | sentry 92 | ( sentry const& ) 93 | = delete; 94 | 95 | /** 96 | * 97 | */ 98 | sentry & 99 | operator= 100 | ( sentry const& ) 101 | = delete; 102 | 103 | /** 104 | * 105 | */ 106 | explicit operator bool 107 | ( void ) 108 | const 109 | { return is_owner_of_flag_; } 110 | 111 | private: 112 | /// 113 | concurrent_guard & guard_; 114 | /// 115 | bool is_owner_of_flag_; 116 | }; 117 | 118 | } // namespace detail 119 | } // namespace kademlia 120 | 121 | #endif 122 | 123 | -------------------------------------------------------------------------------- /src/kademlia/constants.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/constants.hpp" 27 | 28 | namespace kademlia { 29 | namespace detail { 30 | 31 | std::size_t const ROUTING_TABLE_BUCKET_SIZE{ 20 }; 32 | std::size_t const CONCURRENT_FIND_PEER_REQUESTS_COUNT{ 3 }; 33 | std::size_t const REDUNDANT_SAVE_COUNT{ 3 }; 34 | 35 | std::chrono::milliseconds const INITIAL_CONTACT_RECEIVE_TIMEOUT{ 1000 }; 36 | std::chrono::milliseconds const PEER_LOOKUP_TIMEOUT{ 200 }; 37 | 38 | } // namespace detail 39 | } // namespace kademlia 40 | 41 | -------------------------------------------------------------------------------- /src/kademlia/constants.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_CONSTANTS_HPP 27 | #define KADEMLIA_CONSTANTS_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | 35 | namespace kademlia { 36 | namespace detail { 37 | 38 | // k 39 | extern std::size_t const ROUTING_TABLE_BUCKET_SIZE; 40 | // a 41 | extern std::size_t const CONCURRENT_FIND_PEER_REQUESTS_COUNT; 42 | // c 43 | extern std::size_t const REDUNDANT_SAVE_COUNT; 44 | 45 | // 46 | extern std::chrono::milliseconds const INITIAL_CONTACT_RECEIVE_TIMEOUT; 47 | // 48 | extern std::chrono::milliseconds const PEER_LOOKUP_TIMEOUT; 49 | 50 | } // namespace detail 51 | } // namespace kademlia 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /src/kademlia/endpoint.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | namespace kademlia { 35 | 36 | namespace { 37 | 38 | std::string 39 | parse_ipv6( std::istream & in ) 40 | { 41 | std::string ipv6; 42 | 43 | char c = in.get(); 44 | assert( c == '[' && "An IPv6 address starts with '['"); 45 | 46 | for ( c = in.get(); std::isalnum( c ) || c == ':'; c = in.get() ) 47 | ipv6.push_back(c); 48 | 49 | if ( ipv6.empty() || c != ']' ) 50 | in.setstate( std::istream::failbit ); 51 | 52 | return ipv6; 53 | } 54 | 55 | std::string 56 | parse_ipv4( std::istream & in ) 57 | { 58 | std::string ipv4; 59 | 60 | while ( std::isdigit( in.peek() ) || in.peek() == '.' ) 61 | ipv4.push_back( in.get() ); 62 | 63 | if ( ipv4.empty() ) 64 | in.setstate( std::istream::failbit ); 65 | 66 | return ipv4; 67 | } 68 | 69 | std::string 70 | parse_ip( std::istream & in ) 71 | { 72 | // Check if the address is an IPv6 73 | if ( in.peek() == '[' ) 74 | return parse_ipv6( in ); 75 | 76 | return parse_ipv4( in ); 77 | } 78 | 79 | std::string 80 | parse_service( std::istream & in ) 81 | { 82 | std::string service; 83 | 84 | in >> service; 85 | 86 | return service; 87 | } 88 | 89 | } 90 | 91 | std::istream& 92 | operator>> 93 | ( std::istream & in 94 | , endpoint & e ) 95 | { 96 | std::istream::sentry s{ in }; 97 | 98 | if ( s ) 99 | { 100 | std::string const address = parse_ip( in ); 101 | 102 | if ( in.get() != ':' ) 103 | in.setstate( std::istream::failbit ); 104 | 105 | std::string const service = parse_service( in ); 106 | 107 | if ( in ) 108 | e = endpoint{ address, service }; 109 | } 110 | 111 | return in; 112 | } 113 | 114 | std::ostream& 115 | operator<< 116 | ( std::ostream & out 117 | , endpoint const& e ) 118 | { 119 | std::ostream::sentry s{ out }; 120 | 121 | if ( s ) 122 | out << e.address() << ":" << e.service(); 123 | 124 | return out; 125 | } 126 | 127 | } // namespace kademlia 128 | -------------------------------------------------------------------------------- /src/kademlia/error.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/error_impl.hpp" 27 | 28 | namespace kademlia { 29 | 30 | std::error_condition 31 | make_error_condition 32 | ( error_type condition ) 33 | { 34 | return std::error_condition{ static_cast< int >( condition ) 35 | , detail::error_category() }; 36 | } 37 | 38 | } // namespace kademlia 39 | 40 | -------------------------------------------------------------------------------- /src/kademlia/error_impl.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/error_impl.hpp" 27 | 28 | #include 29 | 30 | #include 31 | 32 | namespace kademlia { 33 | namespace detail { 34 | 35 | namespace { 36 | 37 | /** 38 | * 39 | */ 40 | struct kademlia_error_category : std::error_category 41 | { 42 | char const* 43 | name 44 | ( void ) 45 | const CXX11_NOEXCEPT override 46 | { 47 | return "kademlia"; 48 | } 49 | 50 | std::string 51 | message 52 | ( int condition ) 53 | const CXX11_NOEXCEPT override 54 | { 55 | switch ( condition ) 56 | { 57 | case RUN_ABORTED: 58 | return "run aborted"; 59 | case INITIAL_PEER_FAILED_TO_RESPOND: 60 | return "initial peer failed to respond"; 61 | case MISSING_PEERS: 62 | return "missing peers"; 63 | case UNIMPLEMENTED: 64 | return "unimplemented"; 65 | case INVALID_ID: 66 | return "invalid id"; 67 | case TRUNCATED_ID: 68 | return "truncated id"; 69 | case TRUNCATED_ENDPOINT: 70 | return "truncated endpoint"; 71 | case TRUNCATED_ADDRESS: 72 | return "truncated address"; 73 | case TRUNCATED_HEADER: 74 | return "truncated header"; 75 | case TRUNCATED_SIZE: 76 | return "truncated size"; 77 | case CORRUPTED_BODY: 78 | return "corrupted body"; 79 | case UNKNOWN_PROTOCOL_VERSION: 80 | return "unknown protocol version"; 81 | case UNASSOCIATED_MESSAGE_ID: 82 | return "unassociated message id"; 83 | case INVALID_IPV4_ADDRESS: 84 | return "invalid IPv4 address"; 85 | case INVALID_IPV6_ADDRESS: 86 | return "invalid IPv6 address"; 87 | case VALUE_NOT_FOUND: 88 | return "value not found"; 89 | case TIMER_MALFUNCTION: 90 | return "timer malfunction"; 91 | case ALREADY_RUNNING: 92 | return "already running"; 93 | default: 94 | return "unknown error"; 95 | } 96 | } 97 | }; 98 | 99 | } // namespace 100 | 101 | std::error_category const& 102 | error_category 103 | ( void ) 104 | { 105 | static const kademlia_error_category category_{}; 106 | return category_; 107 | } 108 | 109 | std::error_code 110 | make_error_code 111 | ( error_type code ) 112 | { 113 | return std::error_code{ static_cast< int >( code ) 114 | , error_category() }; 115 | } 116 | 117 | } // namespace detail 118 | } // namespace kademlia 119 | 120 | -------------------------------------------------------------------------------- /src/kademlia/error_impl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | namespace kademlia { 29 | namespace detail { 30 | 31 | std::error_category const& 32 | error_category 33 | ( void ); 34 | 35 | std::error_code 36 | make_error_code 37 | ( error_type code ); 38 | 39 | } // namespace detail 40 | } // namespace kademlia 41 | 42 | -------------------------------------------------------------------------------- /src/kademlia/first_session.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | #include "kademlia/session_impl.hpp" 29 | 30 | namespace kademlia { 31 | 32 | /** 33 | * 34 | */ 35 | struct first_session::impl final 36 | : detail::session_impl 37 | { 38 | /** 39 | * 40 | */ 41 | impl 42 | ( endpoint const& listen_on_ipv4 43 | , endpoint const& listen_on_ipv6 ) 44 | : session_impl{ listen_on_ipv4 45 | , listen_on_ipv6 } 46 | { } 47 | }; 48 | 49 | first_session::first_session 50 | ( endpoint const& listen_on_ipv4 51 | , endpoint const& listen_on_ipv6 ) 52 | : impl_{ new impl{ listen_on_ipv4, listen_on_ipv6 } } 53 | { } 54 | 55 | first_session::~first_session 56 | ( void ) 57 | { } 58 | 59 | std::error_code 60 | first_session::run 61 | ( void ) 62 | { return impl_->run(); } 63 | 64 | void 65 | first_session::abort 66 | ( void ) 67 | { impl_->abort(); } 68 | 69 | } // namespace kademlia 70 | 71 | -------------------------------------------------------------------------------- /src/kademlia/id.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/id.hpp" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #include "kademlia/error_impl.hpp" 41 | 42 | namespace kademlia { 43 | namespace detail { 44 | 45 | static CXX11_CONSTEXPR std::size_t HEX_CHAR_PER_BLOCK = id::BYTE_PER_BLOCK * 2; 46 | 47 | namespace { 48 | 49 | id::block_type 50 | to_block 51 | ( std::string const& s ) 52 | { 53 | auto is_id_digit = []( int c ) { return std::isxdigit( c ); }; 54 | if ( ! std::all_of( s.begin(), s.end(), is_id_digit ) ) 55 | throw std::system_error{ make_error_code( INVALID_ID ) }; 56 | 57 | std::stringstream converter{ s }; 58 | 59 | std::uint64_t result; 60 | converter >> std::hex >> result; 61 | 62 | assert( ! converter.fail() && "hexa to decimal conversion failed" ); 63 | 64 | return static_cast< id::block_type >( result ); 65 | } 66 | 67 | } // namespace 68 | 69 | id::id 70 | ( std::default_random_engine & random_engine ) 71 | { 72 | // The output of the generator is treated as boolean value. 73 | std::uniform_int_distribution<> distribution 74 | ( std::numeric_limits< block_type >::min() 75 | , std::numeric_limits< block_type >::max() ); 76 | 77 | std::generate( blocks_.begin(), blocks_.end() 78 | , std::bind( distribution, std::ref( random_engine ) ) ); 79 | } 80 | 81 | id::id 82 | ( std::string s ) 83 | { 84 | auto CXX11_CONSTEXPR STRING_MAX_SIZE = BLOCKS_COUNT * HEX_CHAR_PER_BLOCK; 85 | 86 | if ( s.size() > STRING_MAX_SIZE ) 87 | throw std::system_error{ make_error_code( INVALID_ID ) }; 88 | 89 | // Insert leading 0. 90 | s.insert( s.begin(), STRING_MAX_SIZE - s.size(), '0' ); 91 | 92 | assert( s.size() == STRING_MAX_SIZE && "string padding failed" ); 93 | for ( std::size_t i = 0; i != BLOCKS_COUNT; ++ i ) 94 | blocks_[ i ] = to_block( s.substr( i * HEX_CHAR_PER_BLOCK 95 | , HEX_CHAR_PER_BLOCK ) ); 96 | } 97 | 98 | id::id 99 | ( value_to_hash_type const& value ) 100 | { 101 | // Use OpenSSL crypto hash. 102 | SHA1( value.data(), value.size(), blocks_.data() ); 103 | } 104 | 105 | std::ostream & 106 | operator<< 107 | ( std::ostream & out 108 | , id const& id_to_print ) 109 | { 110 | auto e = id_to_print.end(); 111 | 112 | // Skip leading 0. 113 | auto is_not_0 = []( id::block_type b ) { return b != 0; }; 114 | auto i = std::find_if( id_to_print.begin(), e, is_not_0 ); 115 | 116 | auto const previous_flags = out.flags(); 117 | 118 | out << std::hex 119 | << std::setfill( '0' ) 120 | << std::setw( HEX_CHAR_PER_BLOCK ); 121 | 122 | std::copy( i, e, std::ostream_iterator< std::uint64_t >{ out } ); 123 | 124 | out.flags( previous_flags ); 125 | 126 | return out; 127 | } 128 | 129 | } // namespace detail 130 | } // namespace kademlia 131 | -------------------------------------------------------------------------------- /src/kademlia/ip_endpoint.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/ip_endpoint.hpp" 27 | 28 | #include 29 | 30 | namespace kademlia { 31 | namespace detail { 32 | 33 | std::ostream & 34 | operator<< 35 | ( std::ostream & out 36 | , ip_endpoint const& i ) 37 | { return out << i.address_ << ":" << i.port_; } 38 | 39 | 40 | } // namespace detail 41 | } // namespace kademlia 42 | 43 | -------------------------------------------------------------------------------- /src/kademlia/ip_endpoint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_IP_ENDPOINT_HPP 27 | #define KADEMLIA_IP_ENDPOINT_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | namespace kademlia { 40 | namespace detail { 41 | 42 | /// 43 | struct ip_endpoint final 44 | { 45 | boost::asio::ip::address address_; 46 | uint16_t port_; 47 | }; 48 | 49 | /** 50 | * 51 | */ 52 | inline ip_endpoint 53 | to_ip_endpoint( std::string const& ip 54 | , std::uint16_t port ) 55 | { 56 | return ip_endpoint 57 | { boost::asio::ip::address::from_string( ip ) 58 | , port }; 59 | } 60 | 61 | /** 62 | * 63 | */ 64 | std::ostream & 65 | operator<< 66 | ( std::ostream & out 67 | , ip_endpoint const& i ); 68 | 69 | /** 70 | * 71 | */ 72 | inline bool 73 | operator== 74 | ( const ip_endpoint & a 75 | , const ip_endpoint & b ) 76 | { return a.address_ == b.address_ && a.port_ == b.port_; } 77 | 78 | /** 79 | * 80 | */ 81 | inline bool 82 | operator!= 83 | ( ip_endpoint const& a 84 | , ip_endpoint const& b ) 85 | { return ! ( a == b ); } 86 | 87 | 88 | } // namespace detail 89 | } // namespace kademlia 90 | 91 | #endif 92 | 93 | -------------------------------------------------------------------------------- /src/kademlia/log.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/log.hpp" 27 | 28 | #include 29 | #include 30 | 31 | namespace kademlia { 32 | namespace detail { 33 | 34 | namespace { 35 | 36 | using enabled_modules_log_type = std::set< std::string >; 37 | 38 | enabled_modules_log_type & 39 | get_enabled_modules 40 | ( void ) 41 | { 42 | static enabled_modules_log_type enabled_modules_; 43 | return enabled_modules_; 44 | } 45 | 46 | } // anonymous namespace 47 | 48 | std::ostream & 49 | get_debug_log 50 | ( char const * module 51 | , void const * thiz ) 52 | { 53 | return std::cout << "[debug] (" << module << " @ " 54 | << std::hex << ( std::uintptr_t( thiz ) & 0xffffff ) 55 | << std::dec << ") "; 56 | } 57 | 58 | /** 59 | * 60 | */ 61 | void 62 | enable_log_for 63 | ( std::string const& module ) 64 | { get_enabled_modules().insert( module ); } 65 | 66 | /** 67 | * 68 | */ 69 | void 70 | disable_log_for 71 | ( std::string const& module ) 72 | { get_enabled_modules().erase( module ); } 73 | 74 | /** 75 | * 76 | */ 77 | bool 78 | is_log_enabled 79 | ( std::string const& module ) 80 | { 81 | return get_enabled_modules().count( "*" ) > 0 82 | || get_enabled_modules().count( module ) > 0; 83 | } 84 | 85 | } // namespace detail 86 | } // namespace kademlia 87 | 88 | -------------------------------------------------------------------------------- /src/kademlia/log.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVLOGED BY DAVLOG KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCLOGENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_LOG_HPP 27 | #define KADEMLIA_LOG_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace kademlia { 40 | namespace detail { 41 | 42 | /** 43 | * 44 | */ 45 | std::ostream & 46 | get_debug_log 47 | ( char const * module 48 | , void const * thiz ); 49 | 50 | /** 51 | * 52 | */ 53 | void 54 | enable_log_for 55 | ( std::string const& module ); 56 | 57 | /** 58 | * 59 | */ 60 | void 61 | disable_log_for 62 | ( std::string const& module ); 63 | 64 | 65 | /** 66 | * 67 | */ 68 | bool 69 | is_log_enabled 70 | ( std::string const& module ); 71 | 72 | /** 73 | * This macro deserves some explanation. 74 | * The goal here is to provide a macro that can be called like: 75 | * LOG_DEBUG( my_module ) << "my content" << std::endl; 76 | * Depending on 'my_module' string, the code may or may not be executed. 77 | * To achieve this, the call to an actual stream is made inside 78 | * a for loop whose condition checks if the module associated with 79 | * my_module is enabled. Because the call to is_log_enabled() 80 | * can be costly, its result is cached in a static variable. 81 | */ 82 | #ifdef KADEMLIA_ENABLE_DEBUG 83 | # define LOG_DEBUG( module, thiz ) \ 84 | for ( bool used = false; ! used; used = true ) \ 85 | for ( static bool enabled = kademlia::detail::is_log_enabled( #module )\ 86 | ; enabled && ! used; used = true ) \ 87 | kademlia::detail::get_debug_log( #module, thiz ) 88 | #else 89 | # define LOG_DEBUG( module, thiz ) \ 90 | while ( false ) \ 91 | kademlia::detail::get_debug_log( #module, thiz ) 92 | #endif 93 | 94 | /** 95 | * 96 | */ 97 | template< typename Container > 98 | inline std::string 99 | to_string 100 | ( const Container & c ) 101 | { 102 | std::ostringstream out; 103 | 104 | for ( auto const& v : c ) 105 | { 106 | if ( std::isprint( v ) ) 107 | out << v; 108 | else 109 | out << '\\' << uint16_t( v ); 110 | } 111 | 112 | return out.str(); 113 | } 114 | 115 | } // namespace detail 116 | } // namespace kademlia 117 | 118 | #endif 119 | 120 | -------------------------------------------------------------------------------- /src/kademlia/message_serializer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/message_serializer.hpp" 27 | 28 | namespace kademlia { 29 | namespace detail { 30 | 31 | message_serializer::message_serializer 32 | ( id const& my_id ) 33 | : my_id_( my_id ) 34 | { } 35 | 36 | header 37 | message_serializer::generate_header 38 | ( header::type const& type 39 | , id const& token ) 40 | { 41 | return header 42 | { detail::header::V1 43 | , type 44 | , my_id_ 45 | , token }; 46 | } 47 | 48 | buffer 49 | message_serializer::serialize 50 | ( header::type const& type 51 | , id const& token ) 52 | { 53 | auto const header = generate_header( type, token ); 54 | 55 | buffer b; 56 | detail::serialize( header, b ); 57 | 58 | return b; 59 | } 60 | 61 | } // namespace detail 62 | } // namespace kademlia 63 | 64 | -------------------------------------------------------------------------------- /src/kademlia/message_serializer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_MESSAGE_SERIALIZER_HPP 27 | #define KADEMLIA_MESSAGE_SERIALIZER_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | 35 | #include "kademlia/message.hpp" 36 | 37 | namespace kademlia { 38 | namespace detail { 39 | 40 | /** 41 | * 42 | */ 43 | class message_serializer 44 | { 45 | public: 46 | /** 47 | * 48 | */ 49 | message_serializer 50 | ( id const& my_id ); 51 | 52 | /** 53 | * 54 | */ 55 | template< typename Message > 56 | buffer 57 | serialize 58 | ( Message const& message 59 | , id const& token ); 60 | 61 | /** 62 | * 63 | */ 64 | buffer 65 | serialize 66 | ( header::type const& type 67 | , id const& token ); 68 | 69 | private: 70 | /** 71 | * 72 | */ 73 | header 74 | generate_header 75 | ( header::type const& type 76 | , id const& token ); 77 | 78 | private: 79 | /// 80 | id const& my_id_; 81 | }; 82 | 83 | template< typename Message > 84 | buffer 85 | message_serializer::serialize 86 | ( Message const& message 87 | , id const& token ) 88 | { 89 | auto const type = message_traits< Message >::TYPE_ID; 90 | auto const header = generate_header( type, token ); 91 | 92 | buffer b; 93 | detail::serialize( header, b ); 94 | detail::serialize( message, b ); 95 | 96 | return b; 97 | } 98 | 99 | } // namespace detail 100 | } // namespace kademlia 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /src/kademlia/peer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/peer.hpp" 27 | 28 | namespace kademlia { 29 | namespace detail { 30 | 31 | std::ostream & 32 | operator<< 33 | ( std::ostream & out 34 | , peer const& p ) 35 | { return out << p.id_ << "@" << p.endpoint_; } 36 | 37 | } // namespace detail 38 | } // namespace kademlia 39 | 40 | -------------------------------------------------------------------------------- /src/kademlia/peer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_PEER_HPP 27 | #define KADEMLIA_PEER_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | 35 | #include "kademlia/id.hpp" 36 | #include "kademlia/ip_endpoint.hpp" 37 | 38 | namespace kademlia { 39 | namespace detail { 40 | 41 | /// 42 | struct peer final 43 | { 44 | id id_; 45 | ip_endpoint endpoint_; 46 | }; 47 | 48 | /** 49 | * 50 | */ 51 | std::ostream & 52 | operator<< 53 | ( std::ostream & out 54 | , peer const& p ); 55 | 56 | /** 57 | * 58 | */ 59 | inline bool 60 | operator== 61 | ( const peer & a 62 | , const peer & b ) 63 | { return a.id_ == b.id_ && a.endpoint_ == b.endpoint_; } 64 | 65 | /** 66 | * 67 | */ 68 | inline bool 69 | operator!= 70 | ( peer const& a 71 | , peer const& b ) 72 | { return ! ( a == b ); } 73 | 74 | } // namespace detail 75 | } // namespace kademlia 76 | 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /src/kademlia/response_callbacks.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/response_callbacks.hpp" 27 | 28 | #include 29 | 30 | #include "kademlia/error_impl.hpp" 31 | 32 | namespace kademlia { 33 | namespace detail { 34 | 35 | void 36 | response_callbacks::push_callback 37 | ( id const& message_id 38 | , callback const& on_message_received ) 39 | { 40 | auto i = callbacks_.emplace( message_id, on_message_received ); 41 | (void)i; 42 | assert( i.second && "an id can't be registered twice" ); 43 | } 44 | 45 | bool 46 | response_callbacks::remove_callback 47 | ( id const& message_id ) 48 | { return callbacks_.erase( message_id ) > 0; } 49 | 50 | std::error_code 51 | response_callbacks::dispatch_response 52 | ( endpoint_type const& sender 53 | , header const& h 54 | , buffer::const_iterator i 55 | , buffer::const_iterator e ) 56 | { 57 | auto callback = callbacks_.find( h.random_token_ ); 58 | if ( callback == callbacks_.end() ) 59 | return make_error_code( UNASSOCIATED_MESSAGE_ID ); 60 | 61 | callback->second( sender, h, i, e ); 62 | callbacks_.erase( callback ); 63 | 64 | return std::error_code{}; 65 | } 66 | 67 | } // namespace detail 68 | } // namespace kademlia 69 | 70 | -------------------------------------------------------------------------------- /src/kademlia/response_callbacks.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_RESPONSE_CALLBACKS_HPP 27 | #define KADEMLIA_RESPONSE_CALLBACKS_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #include "kademlia/id.hpp" 37 | #include "kademlia/ip_endpoint.hpp" 38 | #include "kademlia/message.hpp" 39 | 40 | namespace kademlia { 41 | namespace detail { 42 | 43 | /// 44 | class response_callbacks final 45 | { 46 | public: 47 | /// 48 | using endpoint_type = ip_endpoint; 49 | 50 | /// 51 | using callback = std::function< void 52 | ( endpoint_type const& sender 53 | , header const& h 54 | , buffer::const_iterator i 55 | , buffer::const_iterator e ) >; 56 | 57 | public: 58 | /** 59 | * 60 | */ 61 | void 62 | push_callback 63 | ( id const& message_id 64 | , callback const& on_message_received ); 65 | 66 | /** 67 | * 68 | */ 69 | bool 70 | remove_callback 71 | ( id const& message_id ); 72 | 73 | /** 74 | * 75 | */ 76 | std::error_code 77 | dispatch_response 78 | ( endpoint_type const& sender 79 | , header const& h 80 | , buffer::const_iterator i 81 | , buffer::const_iterator e ); 82 | 83 | private: 84 | /// 85 | using callbacks = std::map< id, callback >; 86 | 87 | private: 88 | /// 89 | callbacks callbacks_; 90 | }; 91 | 92 | } // namespace detail 93 | } // namespace kademlia 94 | 95 | #endif 96 | 97 | -------------------------------------------------------------------------------- /src/kademlia/response_router.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_RESPONSE_ROUTER_HPP 27 | #define KADEMLIA_RESPONSE_ROUTER_HPP 28 | 29 | #include 30 | #include "kademlia/ip_endpoint.hpp" 31 | #include "kademlia/response_callbacks.hpp" 32 | #include "kademlia/timer.hpp" 33 | #include "kademlia/log.hpp" 34 | 35 | #ifdef _MSC_VER 36 | # pragma once 37 | #endif 38 | 39 | namespace kademlia { 40 | namespace detail { 41 | 42 | /** 43 | * 44 | */ 45 | class response_router final 46 | { 47 | public: 48 | /// 49 | using endpoint_type = ip_endpoint; 50 | 51 | public: 52 | /** 53 | * 54 | */ 55 | explicit 56 | response_router 57 | ( boost::asio::io_service & io_service ) 58 | : response_callbacks_() 59 | , timer_( io_service ) 60 | { } 61 | 62 | /** 63 | * 64 | */ 65 | response_router 66 | ( response_router const& ) 67 | = delete; 68 | 69 | /** 70 | * 71 | */ 72 | response_router & 73 | operator= 74 | ( response_router const& ) 75 | = delete; 76 | 77 | /** 78 | * 79 | */ 80 | void 81 | handle_new_response 82 | ( endpoint_type const& sender 83 | , header const& h 84 | , buffer::const_iterator i 85 | , buffer::const_iterator e ) 86 | { 87 | // Try to forward the message to its associated callback. 88 | auto failure = response_callbacks_.dispatch_response( sender 89 | , h, i, e ); 90 | if ( failure == UNASSOCIATED_MESSAGE_ID ) 91 | // Unknown request or unassociated responses 92 | // are discarded. 93 | LOG_DEBUG( response_router, this ) << "dropping unknown response." 94 | << std::endl; 95 | } 96 | 97 | /** 98 | * 99 | */ 100 | template< typename OnResponseReceived, typename OnError > 101 | void 102 | register_temporary_callback 103 | ( id const& response_id 104 | , timer::duration const& callback_ttl 105 | , OnResponseReceived const& on_response_received 106 | , OnError const& on_error ) 107 | { 108 | auto on_timeout = [ this, on_error, response_id ] 109 | ( void ) 110 | { 111 | // If a callback has been removed, that means 112 | // the message has never been received 113 | // hence report the timeout to the client. 114 | if ( response_callbacks_.remove_callback( response_id ) ) 115 | on_error( make_error_code( std::errc::timed_out ) ); 116 | }; 117 | 118 | // Associate the response id with the 119 | // on_response_received callback. 120 | response_callbacks_.push_callback( response_id 121 | , on_response_received ); 122 | 123 | timer_.expires_from_now( callback_ttl, on_timeout ); 124 | } 125 | 126 | private: 127 | /// 128 | response_callbacks response_callbacks_; 129 | /// 130 | timer timer_; 131 | }; 132 | 133 | } // namespace detail 134 | } // namespace kademlia 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /src/kademlia/session.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | #include "kademlia/session_impl.hpp" 29 | 30 | namespace kademlia { 31 | 32 | /** 33 | * 34 | */ 35 | struct session::impl final 36 | : detail::session_impl 37 | { 38 | /** 39 | * 40 | */ 41 | impl 42 | ( endpoint const& initial_peer 43 | , endpoint const& listen_on_ipv4 44 | , endpoint const& listen_on_ipv6 ) 45 | : session_impl{ initial_peer 46 | , listen_on_ipv4 47 | , listen_on_ipv6 } 48 | { } 49 | }; 50 | 51 | session::session 52 | ( endpoint const& initial_peer 53 | , endpoint const& listen_on_ipv4 54 | , endpoint const& listen_on_ipv6 ) 55 | : impl_{ new impl{ initial_peer, listen_on_ipv4, listen_on_ipv6 } } 56 | { } 57 | 58 | session::~session 59 | ( void ) 60 | { } 61 | 62 | void 63 | session::async_save 64 | ( key_type const& key 65 | , data_type const& data 66 | , save_handler_type handler ) 67 | { impl_->async_save( key, data, std::move( handler ) ); } 68 | 69 | void 70 | session::async_load 71 | ( key_type const& key 72 | , load_handler_type handler ) 73 | { impl_->async_load( key, std::move( handler ) ); } 74 | 75 | std::error_code 76 | session::run 77 | ( void ) 78 | { return impl_->run(); } 79 | 80 | void 81 | session::abort 82 | ( void ) 83 | { impl_->abort(); } 84 | 85 | } // namespace kademlia 86 | 87 | -------------------------------------------------------------------------------- /src/kademlia/session_base.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/session_base.hpp" 27 | 28 | namespace kademlia { 29 | 30 | CXX11_CONSTEXPR std::uint16_t session_base::DEFAULT_PORT; 31 | 32 | } // namespace kademlia 33 | 34 | -------------------------------------------------------------------------------- /src/kademlia/timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/timer.hpp" 27 | 28 | #include 29 | 30 | #include "kademlia/error_impl.hpp" 31 | #include "kademlia/log.hpp" 32 | 33 | namespace kademlia { 34 | namespace detail { 35 | 36 | timer::timer 37 | ( boost::asio::io_service & io_service ) 38 | : timer_{ io_service } 39 | , timeouts_{} 40 | {} 41 | 42 | void 43 | timer::schedule_next_tick 44 | ( time_point const& expiration_time ) 45 | { 46 | // This will cancel any pending task. 47 | timer_.expires_at( expiration_time ); 48 | 49 | LOG_DEBUG( timer, this ) << "schedule callback at " 50 | << expiration_time.time_since_epoch().count() 51 | << "." << std::endl; 52 | 53 | using std::placeholders::_1; 54 | timer_.async_wait( std::bind( &timer::on_fire, this, _1 ) ); 55 | } 56 | 57 | void 58 | timer::on_fire 59 | ( boost::system::error_code const& failure ) 60 | { 61 | // The current timeout has been canceled 62 | // hence stop right there. 63 | if ( failure == boost::asio::error::operation_aborted ) 64 | return; 65 | 66 | if ( failure ) 67 | throw std::system_error{ make_error_code( TIMER_MALFUNCTION ) }; 68 | 69 | // The callbacks to execute are the first 70 | // n callbacks with the same keys. 71 | auto begin = timeouts_.begin(); 72 | auto end = timeouts_.upper_bound( begin->first ); 73 | // Call the user callbacks. 74 | for ( auto i = begin; i != end; ++ i ) 75 | i->second(); 76 | 77 | LOG_DEBUG( timer, this ) 78 | << "remove " << std::distance( begin, end ) 79 | << " callback(s) scheduled at " 80 | << begin->first.time_since_epoch().count() 81 | << "." << std::endl; 82 | 83 | // And remove the timeout. 84 | timeouts_.erase( begin, end ); 85 | 86 | // If there is a remaining timeout, schedule it. 87 | if ( ! timeouts_.empty() ) 88 | { 89 | LOG_DEBUG( timer, this ) 90 | << "schedule remaining timers" << std::endl; 91 | schedule_next_tick( timeouts_.begin()->first ); 92 | } 93 | } 94 | 95 | } // namespace detail 96 | } // namespace kademlia 97 | 98 | -------------------------------------------------------------------------------- /src/kademlia/timer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TIMER_HPP 27 | #define KADEMLIA_TIMER_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace kademlia { 40 | namespace detail { 41 | 42 | /// 43 | class timer final 44 | { 45 | public: 46 | /// 47 | using clock = std::chrono::steady_clock; 48 | 49 | /// 50 | using duration = clock::duration; 51 | 52 | public: 53 | /** 54 | * 55 | */ 56 | explicit 57 | timer 58 | ( boost::asio::io_service & io_service ); 59 | 60 | /** 61 | * 62 | */ 63 | template< typename Callback > 64 | void 65 | expires_from_now 66 | ( duration const& timeout 67 | , Callback const& on_timer_expired ); 68 | 69 | private: 70 | /// 71 | using time_point = clock::time_point; 72 | 73 | /// 74 | using callback = std::function< void ( void ) >; 75 | 76 | /// 77 | using timeouts = std::multimap< time_point, callback >; 78 | 79 | /// 80 | using deadline_timer = boost::asio::basic_waitable_timer< clock >; 81 | 82 | private: 83 | /** 84 | * 85 | */ 86 | void 87 | schedule_next_tick 88 | ( time_point const& expiration_time ); 89 | 90 | /** 91 | * 92 | */ 93 | void 94 | on_fire 95 | ( boost::system::error_code const& failure ); 96 | 97 | private: 98 | /// 99 | deadline_timer timer_; 100 | /// 101 | timeouts timeouts_; 102 | }; 103 | 104 | template< typename Callback > 105 | void 106 | timer::expires_from_now 107 | ( duration const& timeout 108 | , Callback const& on_timer_expired ) 109 | { 110 | auto expiration_time = clock::now() + timeout; 111 | 112 | // If the current expiration time will be the sooner to expires 113 | // then cancel any pending wait and schedule this one instead. 114 | if ( timeouts_.empty() || expiration_time < timeouts_.begin()->first ) 115 | schedule_next_tick( expiration_time ); 116 | 117 | timeouts_.emplace( expiration_time, on_timer_expired ); 118 | } 119 | 120 | } // namespace detail 121 | } // namespace kademlia 122 | 123 | #endif 124 | 125 | -------------------------------------------------------------------------------- /src/kademlia/value_store.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_VALUE_STORE_HPP 27 | #define KADEMLIA_VALUE_STORE_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace kademlia { 40 | namespace detail { 41 | 42 | template< typename Container > 43 | struct value_store_key_hasher 44 | { 45 | using argument_type = Container; 46 | using result_type = std::size_t; 47 | 48 | result_type 49 | operator() 50 | ( argument_type const& key ) 51 | const 52 | { return boost::hash_range( key.begin(), key.end() ); } 53 | }; 54 | 55 | /// 56 | template< typename Key, typename Value > 57 | using value_store = std::unordered_map 58 | < Key 59 | , Value 60 | , value_store_key_hasher< Key > >; 61 | 62 | } // namespace detail 63 | } // namespace kademlia 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014, David Keller 2 | # All rights reserved. 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the University of California, Berkeley nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | add_custom_target(check) 26 | 27 | add_subdirectory(unit_tests) 28 | 29 | -------------------------------------------------------------------------------- /test/unit_tests/captures/pattern_header.out: -------------------------------------------------------------------------------- 1 | ping_request 2 | ping_response 3 | store_request 4 | find_peer_request 5 | find_peer_response 6 | find_value_request 7 | find_value_response 8 | 9 | -------------------------------------------------------------------------------- /test/unit_tests/captures/pattern_id.out: -------------------------------------------------------------------------------- 1 | 0123456789abcdef 2 | -------------------------------------------------------------------------------- /test/unit_tests/common.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "kademlia/log.hpp" 36 | 37 | namespace filesystem = boost::filesystem; 38 | namespace unit_test = boost::unit_test; 39 | 40 | namespace kademlia { 41 | namespace test { 42 | 43 | namespace { 44 | 45 | filesystem::path const tests_directory_{ TESTS_DIR }; 46 | 47 | } 48 | 49 | std::string get_capture_path( std::string const & capture_name ) 50 | { 51 | return ( tests_directory_ / "captures" / capture_name ).string(); 52 | } 53 | 54 | } // namespace test 55 | } // namespace kademlia 56 | 57 | /** 58 | * When we are using boost as a shared (i.e. BOOST_TEST_DYN_LINK 59 | * macro is defined), BOOST_TEST_ALTERNATIVE_INIT_API macro is 60 | * automatically defined by boost unit-test config header. 61 | * Hence don't bother searching this macro definition in 62 | * this project build or source files. 63 | * 64 | * That means with shared version of unit-test library, unit_test_main 65 | * accepts a bool (*)() init function while it uses a 66 | * test_suite * (*)(int, char *[]) when compiled as static. 67 | * 68 | * See http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html/utf/user-guide/test-runners.html 69 | */ 70 | #ifdef BOOST_TEST_ALTERNATIVE_INIT_API 71 | 72 | bool 73 | init_unit_test 74 | ( void ) 75 | { 76 | kademlia::detail::enable_log_for( "*" ); 77 | return true; 78 | } 79 | 80 | #else 81 | 82 | boost::unit_test::test_suite * 83 | init_unit_test_suite 84 | ( int 85 | , char* [] ) 86 | { 87 | kademlia::detail::enable_log_for( "*" ); 88 | return nullptr; 89 | } 90 | 91 | #endif 92 | 93 | /** 94 | * When using shared version of boost unit-test library, main 95 | * function is not defined, hence provide it. 96 | * 97 | * We can assume that BOOST_TEST_ALTERNATIVE_INIT_API is defined 98 | * as the documentation says so when using shared library. 99 | * See http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html/utf/user-guide/test-runners.html 100 | */ 101 | #ifdef BOOST_TEST_DYN_LINK 102 | 103 | int 104 | main 105 | ( int argc 106 | , char * argv[] ) 107 | { return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } 108 | 109 | #endif 110 | 111 | -------------------------------------------------------------------------------- /test/unit_tests/common.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_COMMON_HPP 27 | #define KADEMLIA_TEST_HELPERS_COMMON_HPP 28 | #ifdef __clang__ 29 | # pragma clang diagnostic push 30 | # pragma clang diagnostic ignored "-Wunneeded-internal-declaration" 31 | # pragma clang diagnostic ignored "-Wunused-variable" 32 | #endif 33 | #include 34 | #include 35 | #ifdef __clang__ 36 | # pragma clang diagnostic pop 37 | #endif 38 | 39 | #include 40 | #include 41 | 42 | namespace kademlia { 43 | namespace test { 44 | 45 | std::string 46 | get_capture_path 47 | ( std::string const & capture_name ); 48 | 49 | } // namespace test 50 | } // namespace kademlia 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /test/unit_tests/corrupted_message.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_CORRUPTED_MESSAGE_MOCK_HPP 27 | #define KADEMLIA_TEST_HELPERS_CORRUPTED_MESSAGE_MOCK_HPP 28 | 29 | #include "kademlia/message.hpp" 30 | 31 | namespace kademlia { 32 | namespace test { 33 | 34 | /** 35 | * 36 | */ 37 | template< detail::header::type Type > 38 | struct corrupted_message { }; 39 | 40 | /** 41 | * 42 | */ 43 | template< detail::header::type Type > 44 | void 45 | serialize 46 | ( corrupted_message< Type > const& body 47 | , detail::buffer & b ) 48 | { } 49 | 50 | } // namespace test 51 | 52 | namespace detail { 53 | 54 | /** 55 | * 56 | */ 57 | template< detail::header::type Type > 58 | struct message_traits< test::corrupted_message< Type > > 59 | { static CXX11_CONSTEXPR header::type TYPE_ID = Type; }; 60 | 61 | } // namespace detail 62 | } // namespace kademlia 63 | 64 | #endif // KADEMLIA_TEST_HELPERS_CORRUPTED_MESSAGE_MOCK_HPP 65 | 66 | -------------------------------------------------------------------------------- /test/unit_tests/llvm_gcov.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$1" = "--version" ]; then 4 | @LLVM_COV@ gcov -version | head -n1 5 | else 6 | exec @LLVM_COV@ gcov "$@" 7 | fi 8 | -------------------------------------------------------------------------------- /test/unit_tests/network.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "network.hpp" 27 | 28 | #include 29 | 30 | namespace kademlia { 31 | namespace test { 32 | 33 | void 34 | check_listening 35 | ( std::string const& ip 36 | , std::uint16_t port ) 37 | { 38 | using boost::asio::ip::udp; 39 | auto udp_failure = create_socket< udp::socket >( ip, port ); 40 | BOOST_REQUIRE_EQUAL( boost::system::errc::address_in_use, udp_failure ); 41 | } 42 | 43 | std::uint16_t 44 | get_temporary_listening_port 45 | ( std::uint16_t port ) 46 | { 47 | boost::system::error_code failure; 48 | 49 | do 50 | { 51 | ++ port; 52 | boost::asio::ip::udp::endpoint const e 53 | { boost::asio::ip::udp::v4() , port }; 54 | 55 | boost::asio::io_service io_service; 56 | // Try to open a socket at this address. 57 | boost::asio::ip::udp::socket socket{ io_service, e.protocol() }; 58 | socket.bind( e, failure ); 59 | } 60 | while ( failure == boost::system::errc::address_in_use ); 61 | 62 | return port; 63 | } 64 | 65 | } // namespace test 66 | } // namespace kademlia 67 | 68 | -------------------------------------------------------------------------------- /test/unit_tests/network.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_NETWORK_HPP 27 | #define KADEMLIA_TEST_HELPERS_NETWORK_HPP 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "common.hpp" 36 | 37 | namespace kademlia { 38 | namespace test { 39 | 40 | template< typename Socket > 41 | boost::system::error_code 42 | create_socket 43 | ( std::string const& ip 44 | , std::uint16_t port ) 45 | { 46 | auto const a = boost::asio::ip::address::from_string( ip ); 47 | boost::asio::io_service io_service; 48 | 49 | // Try to create a socket. 50 | typename Socket::endpoint_type endpoint( a, port ); 51 | Socket socket( io_service, endpoint.protocol() ); 52 | 53 | if ( endpoint.address().is_v6() ) 54 | socket.set_option( boost::asio::ip::v6_only{ true } ); 55 | 56 | boost::system::error_code failure; 57 | socket.bind( endpoint, failure ); 58 | 59 | return failure; 60 | } 61 | 62 | void 63 | check_listening 64 | ( std::string const& ip 65 | , std::uint16_t port ); 66 | 67 | std::uint16_t 68 | get_temporary_listening_port 69 | ( std::uint16_t port = 1234 ); 70 | 71 | } // namespace test 72 | } // namespace kademlia 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /test/unit_tests/peer_factory.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_PEER_FACTORY_HPP 27 | #define KADEMLIA_TEST_HELPERS_PEER_FACTORY_HPP 28 | 29 | #include 30 | 31 | #include "kademlia/id.hpp" 32 | #include "kademlia/ip_endpoint.hpp" 33 | #include "kademlia/peer.hpp" 34 | 35 | inline kademlia::detail::ip_endpoint 36 | create_endpoint 37 | ( std::string const& ip = std::string{ "127.0.0.1" } 38 | , std::uint16_t const& service = 12345 ) 39 | { 40 | using endpoint_type = kademlia::detail::ip_endpoint; 41 | 42 | return endpoint_type{ boost::asio::ip::address::from_string( ip ) 43 | , service }; 44 | } 45 | 46 | inline kademlia::detail::peer 47 | create_peer 48 | ( kademlia::detail::id const& id = kademlia::detail::id() 49 | , kademlia::detail::ip_endpoint const& endpoint = create_endpoint() ) 50 | { 51 | using peer_type = kademlia::detail::peer; 52 | 53 | return peer_type{ id, endpoint }; 54 | } 55 | 56 | #endif // KADEMLIA_TEST_HELPERS_PEER_FACTORY_HPP 57 | -------------------------------------------------------------------------------- /test/unit_tests/routing_table_mock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_ROUTING_TABLE_MOCK_HPP 27 | #define KADEMLIA_TEST_HELPERS_ROUTING_TABLE_MOCK_HPP 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "kademlia/message.hpp" 35 | #include "kademlia/ip_endpoint.hpp" 36 | #include "kademlia/peer.hpp" 37 | 38 | namespace kademlia { 39 | namespace test { 40 | 41 | struct routing_table_mock 42 | { 43 | using peer_type = std::pair< detail::id, detail::ip_endpoint >; 44 | using peers_type = std::vector< peer_type >; 45 | using expected_ids_type = std::deque< detail::id >; 46 | 47 | using iterator_type = peers_type::iterator; 48 | 49 | routing_table_mock 50 | ( void ) 51 | : expected_ids_() 52 | , peers_() 53 | , find_call_count_() 54 | { } 55 | 56 | iterator_type 57 | find 58 | ( detail::id const& id ) 59 | { 60 | if ( expected_ids_.empty() || id != expected_ids_.front() ) 61 | throw std::runtime_error( "Unexpected searched id." ); 62 | 63 | expected_ids_.pop_front(); 64 | 65 | ++ find_call_count_; 66 | 67 | return peers_.begin(); 68 | } 69 | 70 | void 71 | push 72 | ( detail::id const& id 73 | , detail::ip_endpoint const& endpoint ) 74 | { peers_.emplace_back( id, endpoint ); } 75 | 76 | iterator_type 77 | end 78 | ( void ) 79 | { return peers_.end(); } 80 | 81 | expected_ids_type expected_ids_; 82 | peers_type peers_; 83 | uint64_t find_call_count_; 84 | }; 85 | 86 | } // namespace test 87 | } // namespace kademlia 88 | 89 | #endif // KADEMLIA_TEST_HELPERS_ROUTING_TABLE_MOCK_HPP 90 | 91 | -------------------------------------------------------------------------------- /test/unit_tests/socket_mock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_SOCKET_MOCK_HPP 27 | #define KADEMLIA_SOCKET_MOCK_HPP 28 | 29 | #ifdef _MSC_VER 30 | # pragma once 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include "kademlia/error_impl.hpp" 43 | 44 | namespace kademlia { 45 | namespace test { 46 | 47 | /** 48 | * 49 | */ 50 | class socket_mock 51 | { 52 | public: 53 | /// 54 | using protocol_type = boost::asio::ip::udp; 55 | 56 | /// 57 | using endpoint_type = protocol_type::endpoint; 58 | 59 | public: 60 | /** 61 | * 62 | */ 63 | socket_mock 64 | ( boost::asio::io_service & io_service 65 | , protocol_type const& ) 66 | { } 67 | 68 | /** 69 | * 70 | */ 71 | socket_mock 72 | ( socket_mock const& o ) 73 | = delete; 74 | 75 | /** 76 | * 77 | */ 78 | socket_mock 79 | ( socket_mock && o ) 80 | { } 81 | 82 | /** 83 | * 84 | */ 85 | socket_mock & 86 | operator= 87 | ( socket_mock const& o ) 88 | = delete; 89 | 90 | /** 91 | * 92 | */ 93 | ~socket_mock 94 | ( void ) 95 | { 96 | boost::system::error_code ignored; 97 | close( ignored ); 98 | } 99 | 100 | /** 101 | * 102 | */ 103 | template< typename Option > 104 | void 105 | set_option 106 | ( Option const& ) 107 | { } 108 | 109 | /** 110 | * 111 | */ 112 | endpoint_type 113 | local_endpoint 114 | ( void ) 115 | const 116 | { return endpoint_type{}; } 117 | 118 | /** 119 | * 120 | */ 121 | boost::system::error_code 122 | bind 123 | ( endpoint_type const& e ) 124 | { return boost::system::error_code{}; } 125 | 126 | /** 127 | * 128 | */ 129 | boost::system::error_code 130 | close 131 | ( boost::system::error_code & failure ) 132 | { return failure; } 133 | 134 | /** 135 | * 136 | */ 137 | template< typename Callback > 138 | void 139 | async_receive_from 140 | ( boost::asio::mutable_buffer const& buffer 141 | , endpoint_type & from 142 | , Callback && callback ) 143 | { } 144 | 145 | /** 146 | * 147 | */ 148 | template< typename Callback > 149 | void 150 | async_send_to 151 | ( boost::asio::const_buffer const& buffer 152 | , endpoint_type const& to 153 | , Callback && callback ) 154 | { } 155 | }; 156 | 157 | } // namespace test 158 | } // namespace kademlia 159 | 160 | #endif 161 | 162 | -------------------------------------------------------------------------------- /test/unit_tests/task_fixture.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef KADEMLIA_TEST_HELPERS_TASK_FIXTURE_HPP 27 | #define KADEMLIA_TEST_HELPERS_TASK_FIXTURE_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "kademlia/peer.hpp" 35 | #include "common.hpp" 36 | #include "tracker_mock.hpp" 37 | #include "routing_table_mock.hpp" 38 | 39 | namespace kademlia { 40 | namespace test { 41 | 42 | struct task_fixture 43 | { 44 | task_fixture 45 | ( void ) 46 | : io_service_() 47 | , io_service_work_( io_service_ ) 48 | , tracker_( io_service_ ) 49 | , failure_() 50 | , routing_table_() 51 | , callback_call_count_() 52 | { } 53 | 54 | detail::peer 55 | create_peer 56 | ( std::string const& ip, detail::id const& id ) 57 | { 58 | auto e = detail::to_ip_endpoint( ip, 5555 ); 59 | 60 | return detail::peer{ id, e }; 61 | } 62 | 63 | detail::peer 64 | create_and_add_peer 65 | ( std::string const& ip, detail::id const& id ) 66 | { 67 | auto p = create_peer( ip, id ); 68 | routing_table_.peers_.emplace_back( p.id_, p.endpoint_ ); 69 | 70 | return p; 71 | } 72 | 73 | boost::asio::io_service io_service_; 74 | boost::asio::io_service::work io_service_work_; 75 | tracker_mock tracker_; 76 | std::error_code failure_; 77 | routing_table_mock routing_table_; 78 | std::size_t callback_call_count_; 79 | }; 80 | 81 | } // namespace test 82 | } // namespace kademlia 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /test/unit_tests/test_boost_to_std_error.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include "common.hpp" 32 | #include "kademlia/boost_to_std_error.hpp" 33 | 34 | namespace k = kademlia; 35 | namespace kd = k::detail; 36 | namespace b = boost; 37 | namespace ba = b::asio; 38 | namespace bs = b::system; 39 | 40 | namespace { 41 | 42 | BOOST_AUTO_TEST_SUITE( boost_to_std_error ) 43 | 44 | BOOST_AUTO_TEST_SUITE( test_usage ) 45 | 46 | BOOST_AUTO_TEST_CASE( can_convert_generic_error ) 47 | { 48 | auto const c = make_error_code( bs::errc::address_in_use ); 49 | auto const e = make_error_code( std::errc::address_in_use ); 50 | BOOST_REQUIRE( kd::boost_to_std_error( c ) == e ); 51 | } 52 | 53 | BOOST_AUTO_TEST_CASE( can_convert_system_error ) 54 | { 55 | bs::error_code const c{ 1000, bs::system_category() }; 56 | std::error_code const e{ 1000, std::system_category() }; 57 | BOOST_REQUIRE( kd::boost_to_std_error( c ) == e ); 58 | } 59 | 60 | BOOST_AUTO_TEST_CASE( cannot_convert_kademlia_error ) 61 | { 62 | bs::error_code const c{ 1000, ba::error::misc_category }; 63 | BOOST_REQUIRE( kd::boost_to_std_error( c ) == k::UNKNOWN_ERROR ); 64 | } 65 | 66 | BOOST_AUTO_TEST_SUITE_END() 67 | 68 | BOOST_AUTO_TEST_SUITE_END() 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /test/unit_tests/test_concurrent_guard.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | #include "kademlia/concurrent_guard.hpp" 28 | 29 | namespace k = kademlia; 30 | namespace kd = k::detail; 31 | 32 | namespace { 33 | 34 | BOOST_AUTO_TEST_SUITE( concurrent_guard ) 35 | 36 | BOOST_AUTO_TEST_SUITE( test_construction ) 37 | 38 | BOOST_AUTO_TEST_CASE( can_be_default_constructed ) 39 | { 40 | kd::concurrent_guard{}; 41 | } 42 | 43 | BOOST_AUTO_TEST_CASE( can_construct_sentry ) 44 | { 45 | kd::concurrent_guard guard{}; 46 | kd::concurrent_guard::sentry{ guard }; 47 | } 48 | 49 | BOOST_AUTO_TEST_CASE( can_detect_concurrent_construction ) 50 | { 51 | kd::concurrent_guard guard; 52 | 53 | { 54 | kd::concurrent_guard::sentry sentry{ guard }; 55 | 56 | BOOST_REQUIRE( sentry ); 57 | 58 | BOOST_REQUIRE( ! kd::concurrent_guard::sentry{ guard } ); 59 | } 60 | 61 | BOOST_REQUIRE( kd::concurrent_guard::sentry{ guard } ); 62 | } 63 | 64 | BOOST_AUTO_TEST_SUITE_END() 65 | 66 | BOOST_AUTO_TEST_SUITE_END() 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /test/unit_tests/test_error.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "common.hpp" 31 | 32 | namespace { 33 | 34 | namespace k = kademlia; 35 | 36 | bool 37 | compare_enum_to_message( char const * name, k::error_type const& error ) 38 | { 39 | auto message = make_error_condition( error ).message(); 40 | 41 | std::replace( message.begin(), message.end(), ' ', '_' ); 42 | std::transform( message.begin() 43 | , message.end(), message.begin(), 44 | ::toupper ); 45 | 46 | return name == message; 47 | } 48 | 49 | BOOST_AUTO_TEST_SUITE( error ) 50 | 51 | BOOST_AUTO_TEST_SUITE( test_usage ) 52 | 53 | #define KADEMLIA_TEST_ERROR( e ) \ 54 | BOOST_REQUIRE( compare_enum_to_message( #e, k:: e ) ) 55 | 56 | BOOST_AUTO_TEST_CASE( error_message_follows_the_error_name ) 57 | { 58 | KADEMLIA_TEST_ERROR( UNKNOWN_ERROR ); 59 | KADEMLIA_TEST_ERROR( RUN_ABORTED ); 60 | KADEMLIA_TEST_ERROR( INITIAL_PEER_FAILED_TO_RESPOND ); 61 | KADEMLIA_TEST_ERROR( MISSING_PEERS ); 62 | KADEMLIA_TEST_ERROR( INVALID_ID ); 63 | KADEMLIA_TEST_ERROR( TRUNCATED_ID ); 64 | KADEMLIA_TEST_ERROR( TRUNCATED_HEADER ); 65 | KADEMLIA_TEST_ERROR( TRUNCATED_ENDPOINT ); 66 | KADEMLIA_TEST_ERROR( TRUNCATED_ADDRESS ); 67 | KADEMLIA_TEST_ERROR( TRUNCATED_SIZE ); 68 | KADEMLIA_TEST_ERROR( UNKNOWN_PROTOCOL_VERSION ); 69 | KADEMLIA_TEST_ERROR( CORRUPTED_BODY ); 70 | KADEMLIA_TEST_ERROR( UNASSOCIATED_MESSAGE_ID ); 71 | KADEMLIA_TEST_ERROR( INVALID_IPV4_ADDRESS ); 72 | KADEMLIA_TEST_ERROR( INVALID_IPV6_ADDRESS ); 73 | KADEMLIA_TEST_ERROR( UNIMPLEMENTED ); 74 | KADEMLIA_TEST_ERROR( VALUE_NOT_FOUND ); 75 | KADEMLIA_TEST_ERROR( TIMER_MALFUNCTION ); 76 | KADEMLIA_TEST_ERROR( ALREADY_RUNNING ); 77 | } 78 | 79 | BOOST_AUTO_TEST_CASE( error_category_is_kademlia ) 80 | { 81 | auto e = make_error_condition( k::UNKNOWN_ERROR ); 82 | BOOST_REQUIRE_EQUAL( "kademlia", e.category().name() ); 83 | } 84 | 85 | #undef KADEMLIA_TEST_ERROR 86 | 87 | BOOST_AUTO_TEST_SUITE_END() 88 | 89 | BOOST_AUTO_TEST_SUITE_END() 90 | 91 | } 92 | 93 | -------------------------------------------------------------------------------- /test/unit_tests/test_first_session.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "common.hpp" 36 | #include "network.hpp" 37 | 38 | namespace { 39 | 40 | namespace k = kademlia; 41 | namespace bo = boost::asio; 42 | 43 | BOOST_AUTO_TEST_SUITE( first_session ) 44 | 45 | BOOST_AUTO_TEST_SUITE( test_construction ) 46 | 47 | BOOST_AUTO_TEST_CASE( first_session_opens_sockets_on_all_interfaces_by_default ) 48 | { 49 | k::first_session s; 50 | 51 | k::test::check_listening( "0.0.0.0", k::first_session::DEFAULT_PORT ); 52 | k::test::check_listening( "::", k::first_session::DEFAULT_PORT ); 53 | } 54 | 55 | BOOST_AUTO_TEST_CASE( first_session_opens_both_ipv4_ipv6_sockets ) 56 | { 57 | // Create listening socket. 58 | std::uint16_t const port1 = k::test::get_temporary_listening_port(); 59 | std::uint16_t const port2 = k::test::get_temporary_listening_port( port1 ); 60 | k::endpoint ipv4_endpoint{ "127.0.0.1", port1 }; 61 | k::endpoint ipv6_endpoint{ "::1", port2 }; 62 | 63 | k::first_session s{ ipv4_endpoint, ipv6_endpoint }; 64 | 65 | k::test::check_listening( "127.0.0.1", port1 ); 66 | k::test::check_listening( "::1", port2 ); 67 | } 68 | 69 | BOOST_AUTO_TEST_CASE( first_session_throw_on_invalid_ipv6_address ) 70 | { 71 | // Create listening socket. 72 | std::uint16_t const port1 = k::test::get_temporary_listening_port(); 73 | std::uint16_t const port2 = k::test::get_temporary_listening_port( port1 ); 74 | k::endpoint ipv4_endpoint{ "127.0.0.1", port1 }; 75 | k::endpoint ipv6_endpoint{ "0.0.0.0", port2 }; 76 | 77 | BOOST_REQUIRE_THROW( k::first_session s( ipv4_endpoint 78 | , ipv6_endpoint ) 79 | , std::exception ); 80 | } 81 | 82 | BOOST_AUTO_TEST_CASE( first_session_throw_on_invalid_ipv4_address ) 83 | { 84 | // Create listening socket. 85 | std::uint16_t const port1 = k::test::get_temporary_listening_port(); 86 | std::uint16_t const port2 = k::test::get_temporary_listening_port( port1 ); 87 | k::endpoint ipv4_endpoint{ "::", port1 }; 88 | k::endpoint ipv6_endpoint{ "::1", port2 }; 89 | 90 | BOOST_REQUIRE_THROW( k::first_session s( ipv4_endpoint 91 | , ipv6_endpoint ) 92 | , std::exception ); 93 | } 94 | 95 | BOOST_AUTO_TEST_SUITE_END() 96 | 97 | BOOST_AUTO_TEST_SUITE( test_usage ) 98 | 99 | BOOST_AUTO_TEST_CASE( first_session_run_can_be_aborted ) 100 | { 101 | k::first_session s; 102 | 103 | auto result = std::async( std::launch::async 104 | , &k::first_session::run, &s ); 105 | s.abort(); 106 | 107 | BOOST_REQUIRE( result.get() == k::RUN_ABORTED ); 108 | } 109 | 110 | BOOST_AUTO_TEST_SUITE_END() 111 | 112 | BOOST_AUTO_TEST_SUITE_END() 113 | 114 | } 115 | 116 | -------------------------------------------------------------------------------- /test/unit_tests/test_ip_endpoint.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | 28 | #include 29 | 30 | #include "kademlia/ip_endpoint.hpp" 31 | 32 | namespace { 33 | 34 | namespace k = kademlia; 35 | namespace kd = k::detail; 36 | namespace ba = boost::asio; 37 | 38 | BOOST_AUTO_TEST_SUITE( ip_endpoint ) 39 | 40 | BOOST_AUTO_TEST_SUITE( test_construction ) 41 | 42 | BOOST_AUTO_TEST_CASE( can_be_default_constructed ) 43 | { 44 | BOOST_REQUIRE_NO_THROW( 45 | kd::ip_endpoint const e{}; 46 | (void)e; 47 | ); 48 | } 49 | 50 | BOOST_AUTO_TEST_CASE( can_be_constructed_with_ip_and_port ) 51 | { 52 | BOOST_REQUIRE_NO_THROW( 53 | auto const e = kd::to_ip_endpoint( "192.168.0.1", 1234 ); 54 | (void)e; 55 | ); 56 | } 57 | 58 | BOOST_AUTO_TEST_SUITE_END() 59 | 60 | BOOST_AUTO_TEST_SUITE( test_usage ) 61 | 62 | BOOST_AUTO_TEST_CASE( can_be_compared) 63 | { 64 | { 65 | auto a = kd::to_ip_endpoint( "192.168.0.1", 1234 ); 66 | auto b = a; 67 | 68 | BOOST_REQUIRE_EQUAL( a, b ); 69 | } 70 | 71 | { 72 | auto a = kd::to_ip_endpoint( "192.168.0.1", 1234 ); 73 | auto b = kd::to_ip_endpoint( "192.168.0.2", 1234 ); 74 | 75 | BOOST_REQUIRE_NE( a, b ); 76 | } 77 | } 78 | 79 | BOOST_AUTO_TEST_SUITE_END() 80 | 81 | BOOST_AUTO_TEST_SUITE( test_print ) 82 | 83 | BOOST_AUTO_TEST_CASE( can_be_printed ) 84 | { 85 | boost::test_tools::output_test_stream out; 86 | 87 | out << kd::to_ip_endpoint( "192.168.0.1", 1234 ); 88 | 89 | BOOST_CHECK( out.is_equal( "192.168.0.1:1234" ) ); 90 | } 91 | 92 | BOOST_AUTO_TEST_SUITE_END() 93 | 94 | BOOST_AUTO_TEST_SUITE_END() 95 | 96 | } 97 | 98 | -------------------------------------------------------------------------------- /test/unit_tests/test_log.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | 28 | #include 29 | #include 30 | 31 | #include "kademlia/log.hpp" 32 | 33 | namespace { 34 | 35 | namespace kd = kademlia::detail; 36 | 37 | struct rdbuf_saver 38 | { 39 | rdbuf_saver 40 | ( std::ostream & stream 41 | , std::streambuf * buffer ) 42 | : stream_( stream ) 43 | , old_buffer_( stream.rdbuf( buffer ) ) 44 | { } 45 | 46 | ~rdbuf_saver 47 | ( void ) 48 | { stream_.rdbuf( old_buffer_ ); } 49 | 50 | std::ostream & stream_; 51 | std::streambuf * old_buffer_; 52 | }; 53 | 54 | BOOST_AUTO_TEST_SUITE( log ) 55 | 56 | BOOST_AUTO_TEST_SUITE( test_usage ) 57 | 58 | BOOST_AUTO_TEST_CASE( can_write_to_debug_log ) 59 | { 60 | boost::test_tools::output_test_stream out; 61 | 62 | { 63 | rdbuf_saver const s{ std::cout, out.rdbuf() }; 64 | auto const ptr = reinterpret_cast< void *>( 0x12345678 ); 65 | kd::get_debug_log( "test", ptr ) << "message" << std::endl; 66 | } 67 | 68 | BOOST_REQUIRE( out.is_equal( "[debug] (test @ 345678) message\n" ) ); 69 | } 70 | 71 | BOOST_AUTO_TEST_CASE( can_write_to_debug_log_using_macro ) 72 | { 73 | boost::test_tools::output_test_stream out; 74 | 75 | { 76 | rdbuf_saver const s{ std::cout, out.rdbuf() }; 77 | auto const ptr = reinterpret_cast< void *>( 0x12345678 ); 78 | LOG_DEBUG( test, ptr ) << "message" << std::endl; 79 | } 80 | 81 | #ifdef KADEMLIA_ENABLE_DEBUG 82 | BOOST_REQUIRE( out.is_equal( "[debug] (test @ 345678) message\n" ) ); 83 | #else 84 | BOOST_REQUIRE( out.is_equal( "" ) ); 85 | #endif 86 | } 87 | 88 | BOOST_AUTO_TEST_CASE( can_enable_log_module ) 89 | { 90 | // By default, unit tests enable log on all modules. 91 | kd::disable_log_for( "*" ); 92 | 93 | BOOST_REQUIRE( ! kd::is_log_enabled( "test1" ) ); 94 | BOOST_REQUIRE( ! kd::is_log_enabled( "test2" ) ); 95 | 96 | kd::enable_log_for( "test1" ); 97 | BOOST_REQUIRE( kd::is_log_enabled( "test1" ) ); 98 | BOOST_REQUIRE( ! kd::is_log_enabled( "test2" ) ); 99 | 100 | kd::enable_log_for( "*" ); 101 | BOOST_REQUIRE( kd::is_log_enabled( "test1" ) ); 102 | BOOST_REQUIRE( kd::is_log_enabled( "test2" ) ); 103 | 104 | } 105 | 106 | BOOST_AUTO_TEST_CASE( can_convert_container_to_string ) 107 | { 108 | { 109 | std::vector< std::uint8_t > const c{ 'a', 'b', 'c' }; 110 | auto const r = kd::to_string( c ); 111 | 112 | BOOST_REQUIRE_EQUAL( "abc", r ); 113 | } 114 | { 115 | std::vector< std::uint8_t > const c{ 1, 2, 3 }; 116 | auto const r = kd::to_string( c ); 117 | 118 | BOOST_REQUIRE_EQUAL( "\\1\\2\\3", r ); 119 | } 120 | } 121 | 122 | BOOST_AUTO_TEST_SUITE_END() 123 | 124 | BOOST_AUTO_TEST_SUITE_END() 125 | 126 | } 127 | 128 | -------------------------------------------------------------------------------- /test/unit_tests/test_message_serializer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | 28 | #include "kademlia/message_serializer.hpp" 29 | #include "kademlia/message.hpp" 30 | 31 | namespace { 32 | 33 | namespace k = kademlia; 34 | namespace kd = k::detail; 35 | 36 | struct fixture 37 | { 38 | fixture 39 | ( void ) 40 | : id_{ "abcd" } 41 | {} 42 | 43 | kd::id id_; 44 | }; 45 | 46 | BOOST_AUTO_TEST_SUITE( message_serializer ) 47 | 48 | BOOST_FIXTURE_TEST_SUITE( test_message_serializer, fixture ) 49 | 50 | BOOST_AUTO_TEST_CASE( can_be_constructed ) 51 | { 52 | kd::message_serializer s{ id_ }; 53 | (void)s; 54 | } 55 | 56 | BOOST_AUTO_TEST_CASE( can_serialize_a_message_with_a_body ) 57 | { 58 | kd::message_serializer s{ id_ }; 59 | kd::id const searched_id{ "1234" }; 60 | kd::id const token{ "ABCD" }; 61 | 62 | kd::find_peer_request_body const expected{ searched_id }; 63 | auto const b = s.serialize( expected, token ); 64 | 65 | auto i = std::begin( b ), e = std::end( b ); 66 | kd::header h; 67 | BOOST_REQUIRE( ! kd::deserialize( i, e, h ) ); 68 | BOOST_REQUIRE_EQUAL( kd::header::V1, h.version_ ); 69 | BOOST_REQUIRE_EQUAL( kd::header::FIND_PEER_REQUEST, h.type_ ); 70 | BOOST_REQUIRE_EQUAL( id_, h.source_id_ ); 71 | BOOST_REQUIRE_EQUAL( token, h.random_token_ ); 72 | 73 | kd::find_peer_request_body actual; 74 | BOOST_REQUIRE( ! kd::deserialize( i, e, actual ) ); 75 | BOOST_REQUIRE( expected.peer_to_find_id_ == actual.peer_to_find_id_ ); 76 | 77 | BOOST_REQUIRE( i == e ); 78 | } 79 | 80 | BOOST_AUTO_TEST_CASE( can_serialize_a_message_without_body ) 81 | { 82 | kd::message_serializer s{ id_ }; 83 | kd::id const searched_id{ "1234" }; 84 | kd::id const token{ "ABCD" }; 85 | 86 | auto const b = s.serialize( kd::header::PING_REQUEST, token ); 87 | 88 | auto i = std::begin( b ), e = std::end( b ); 89 | kd::header h; 90 | BOOST_REQUIRE( ! kd::deserialize( i, e, h ) ); 91 | BOOST_REQUIRE_EQUAL( kd::header::V1, h.version_ ); 92 | BOOST_REQUIRE_EQUAL( kd::header::PING_REQUEST, h.type_ ); 93 | BOOST_REQUIRE_EQUAL( id_, h.source_id_ ); 94 | BOOST_REQUIRE_EQUAL( token, h.random_token_ ); 95 | 96 | BOOST_REQUIRE( i == e ); 97 | } 98 | 99 | BOOST_AUTO_TEST_SUITE_END() 100 | 101 | BOOST_AUTO_TEST_SUITE_END() 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /test/unit_tests/test_message_socket.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include 27 | 28 | #include 29 | 30 | #include "kademlia/ip_endpoint.hpp" 31 | #include "kademlia/message_socket.hpp" 32 | 33 | #include "common.hpp" 34 | #include "network.hpp" 35 | 36 | namespace { 37 | 38 | namespace k = kademlia; 39 | namespace kd = kademlia::detail; 40 | 41 | using message_socket_type = kd::message_socket< boost::asio::ip::udp::socket >; 42 | 43 | BOOST_AUTO_TEST_SUITE( message_socket ) 44 | 45 | BOOST_AUTO_TEST_SUITE( test_construction ) 46 | 47 | BOOST_AUTO_TEST_CASE( faulty_address_are_detected ) 48 | { 49 | boost::asio::io_service io_service; 50 | 51 | { 52 | k::endpoint const endpoint{ "error" 53 | , "27980" }; 54 | 55 | BOOST_REQUIRE_THROW( 56 | message_socket_type::resolve_endpoint( io_service, endpoint ); 57 | , std::exception ); 58 | } 59 | } 60 | 61 | BOOST_AUTO_TEST_CASE( dns_can_be_resolved ) 62 | { 63 | boost::asio::io_service io_service; 64 | 65 | k::endpoint const endpoint{ "localhost" 66 | , "27980" }; 67 | 68 | auto const e = message_socket_type::resolve_endpoint( io_service, endpoint ); 69 | 70 | BOOST_REQUIRE_LE( 1, e.size() ); 71 | } 72 | 73 | BOOST_AUTO_TEST_CASE( ipv4_address_can_be_resolved ) 74 | { 75 | boost::asio::io_service io_service; 76 | 77 | k::endpoint const endpoint{ "127.0.0.1" 78 | , "27980" }; 79 | 80 | auto const e = message_socket_type::resolve_endpoint( io_service, endpoint ); 81 | 82 | BOOST_REQUIRE_EQUAL( 1, e.size() ); 83 | } 84 | 85 | BOOST_AUTO_TEST_CASE( ipv6_address_can_be_resolved ) 86 | { 87 | boost::asio::io_service io_service; 88 | 89 | k::endpoint const endpoint{ "::1" 90 | , "27980" }; 91 | 92 | auto e = message_socket_type::resolve_endpoint( io_service, endpoint ); 93 | BOOST_REQUIRE_EQUAL( 1, e.size() ); 94 | } 95 | 96 | 97 | BOOST_AUTO_TEST_CASE( ipv4_socket_can_be_created ) 98 | { 99 | boost::asio::io_service io_service; 100 | 101 | k::endpoint const endpoint( "127.0.0.1" 102 | , k::test::get_temporary_listening_port() ); 103 | 104 | BOOST_REQUIRE_NO_THROW( 105 | message_socket_type::ipv4( io_service, endpoint ); 106 | ); 107 | } 108 | 109 | BOOST_AUTO_TEST_CASE( ipv6_socket_can_be_created ) 110 | { 111 | boost::asio::io_service io_service; 112 | 113 | k::endpoint const endpoint( "::1" 114 | , k::test::get_temporary_listening_port() ); 115 | 116 | BOOST_REQUIRE_NO_THROW( 117 | message_socket_type::ipv6( io_service, endpoint ); 118 | ); 119 | } 120 | 121 | BOOST_AUTO_TEST_SUITE_END() 122 | 123 | BOOST_AUTO_TEST_SUITE_END() 124 | 125 | } 126 | 127 | -------------------------------------------------------------------------------- /test/unit_tests/test_network.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "kademlia/network.hpp" 27 | 28 | #include 29 | 30 | #include "common.hpp" 31 | #include "socket_mock.hpp" 32 | 33 | namespace { 34 | 35 | namespace k = kademlia; 36 | namespace kd = k::detail; 37 | namespace kt = k::test; 38 | 39 | using socket_type = kd::message_socket< kt::socket_mock >; 40 | using network_type = kd::network< socket_type >; 41 | 42 | struct fixture 43 | { 44 | fixture 45 | ( void ) 46 | : io_service_() 47 | , ipv4_( "172.0.0.1", 1234 ) 48 | , ipv6_( "::1", 1234 ) 49 | { } 50 | 51 | void 52 | on_message_received 53 | ( network_type::endpoint_type const& 54 | , kd::buffer::const_iterator 55 | , kd::buffer::const_iterator ) 56 | { }; 57 | 58 | boost::asio::io_service io_service_; 59 | k::endpoint ipv4_; 60 | k::endpoint ipv6_; 61 | }; 62 | 63 | BOOST_AUTO_TEST_SUITE( network ) 64 | 65 | BOOST_FIXTURE_TEST_SUITE( test_usage, fixture ) 66 | 67 | BOOST_AUTO_TEST_CASE( schedule_receive_on_construction ) 68 | { 69 | using namespace std::placeholders; 70 | network_type m{ io_service_ 71 | , socket_type::ipv4( io_service_, ipv4_ ) 72 | , socket_type::ipv6( io_service_, ipv6_ ) 73 | , std::bind( &fixture::on_message_received 74 | , this 75 | , _1, _2, _3 ) }; 76 | (void)m; 77 | } 78 | 79 | BOOST_AUTO_TEST_SUITE_END() 80 | 81 | BOOST_AUTO_TEST_SUITE_END() 82 | 83 | } 84 | 85 | -------------------------------------------------------------------------------- /test/unit_tests/test_notify_peer_task.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | #include "tracker_mock.hpp" 28 | #include "routing_table_mock.hpp" 29 | #include "task_fixture.hpp" 30 | 31 | #include 32 | #include 33 | 34 | #include "kademlia/id.hpp" 35 | #include "kademlia/peer.hpp" 36 | #include "kademlia/ip_endpoint.hpp" 37 | #include "kademlia/notify_peer_task.hpp" 38 | 39 | namespace { 40 | 41 | namespace k = kademlia; 42 | namespace kd = k::detail; 43 | 44 | using fixture = k::test::task_fixture; 45 | 46 | BOOST_AUTO_TEST_SUITE( notify_peer_task ) 47 | 48 | BOOST_FIXTURE_TEST_SUITE( test_usage, fixture ) 49 | 50 | BOOST_AUTO_TEST_CASE( can_query_known_peer_for_specific_id ) 51 | { 52 | kd::id const my_id{ "a" }; 53 | routing_table_.expected_ids_.emplace_back( my_id ); 54 | auto p1 = create_and_add_peer( "192.168.1.2", kd::id{ "1a" } ); 55 | auto p2 = create_and_add_peer( "192.168.1.3", kd::id{ "2a" } ); 56 | auto p3 = create_and_add_peer( "192.168.1.4", kd::id{ "4a" } ); 57 | 58 | // p1 doesn't know closer peer. 59 | tracker_.add_message_to_receive( p1.endpoint_ 60 | , p1.id_ 61 | , kd::find_peer_response_body{} ); 62 | 63 | // p2 doesn't know closer peer. 64 | tracker_.add_message_to_receive( p2.endpoint_ 65 | , p2.id_ 66 | , kd::find_peer_response_body{} ); 67 | 68 | // p3 doesn't know closer peer. 69 | tracker_.add_message_to_receive( p3.endpoint_ 70 | , p3.id_ 71 | , kd::find_peer_response_body{} ); 72 | 73 | 74 | bool finished = false; 75 | auto on_finish = [ &finished ] { finished = true; }; 76 | 77 | kd::start_notify_peer_task( my_id, tracker_, routing_table_, on_finish ); 78 | 79 | io_service_.poll(); 80 | 81 | // Task queried routing table to find closest known peers. 82 | BOOST_REQUIRE_EQUAL( 1, routing_table_.find_call_count_ ); 83 | 84 | // Task asked p1, p2 & p3 for a closer peer or the value. 85 | kd::find_peer_request_body const fv{ my_id }; 86 | BOOST_REQUIRE( tracker_.has_sent_message( p1.endpoint_, fv ) ); 87 | BOOST_REQUIRE( tracker_.has_sent_message( p2.endpoint_, fv ) ); 88 | BOOST_REQUIRE( tracker_.has_sent_message( p3.endpoint_, fv ) ); 89 | 90 | // Task didn't send any more message. 91 | BOOST_REQUIRE( ! tracker_.has_sent_message() ); 92 | BOOST_REQUIRE( finished ); 93 | } 94 | 95 | BOOST_AUTO_TEST_SUITE_END() 96 | 97 | BOOST_AUTO_TEST_SUITE_END() 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /test/unit_tests/test_peer.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2013-2014, David Keller 3 | // All rights reserved. 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the University of California, Berkeley nor the 13 | // names of its contributors may be used to endorse or promote products 14 | // derived from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 17 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #include 28 | 29 | #include "common.hpp" 30 | #include "kademlia/peer.hpp" 31 | 32 | namespace { 33 | 34 | namespace kd = kademlia::detail; 35 | 36 | struct fixture 37 | { 38 | fixture() 39 | : id_{} 40 | , ip_endpoint_( kd::to_ip_endpoint( "127.0.0.1", 1234 ) ) 41 | { } 42 | 43 | kd::id id_; 44 | kd::ip_endpoint ip_endpoint_; 45 | }; 46 | 47 | BOOST_AUTO_TEST_SUITE( peer ) 48 | 49 | BOOST_FIXTURE_TEST_SUITE( test_usage, fixture ) 50 | 51 | BOOST_AUTO_TEST_CASE( can_be_constructed ) 52 | { 53 | kd::peer const p{ id_, ip_endpoint_ }; 54 | (void)p; 55 | } 56 | 57 | BOOST_AUTO_TEST_CASE( can_be_printed ) 58 | { 59 | boost::test_tools::output_test_stream out; 60 | 61 | out << kd::peer{ id_, ip_endpoint_ }; 62 | 63 | std::ostringstream expected; 64 | expected << id_ << "@" << ip_endpoint_; 65 | BOOST_REQUIRE( out.is_equal( expected.str() ) ); 66 | } 67 | 68 | BOOST_AUTO_TEST_SUITE_END() 69 | 70 | BOOST_AUTO_TEST_SUITE_END() 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /test/unit_tests/test_timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014, David Keller 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above copyright 9 | // notice, this list of conditions and the following disclaimer in the 10 | // documentation and/or other materials provided with the distribution. 11 | // * Neither the name of the University of California, Berkeley nor the 12 | // names of its contributors may be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "common.hpp" 27 | 28 | #include 29 | #include "kademlia/error_impl.hpp" 30 | 31 | #include "kademlia/timer.hpp" 32 | #include "kademlia/log.hpp" 33 | 34 | namespace { 35 | 36 | namespace k = kademlia; 37 | namespace kd = k::detail; 38 | 39 | BOOST_AUTO_TEST_SUITE( timer ) 40 | 41 | BOOST_AUTO_TEST_SUITE( test_construction ) 42 | 43 | BOOST_AUTO_TEST_CASE( can_be_constructed_using_a_reactor ) 44 | { 45 | boost::asio::io_service io_service; 46 | BOOST_REQUIRE_NO_THROW( kd::timer{ io_service } ); 47 | } 48 | 49 | BOOST_AUTO_TEST_SUITE_END() 50 | 51 | struct fixture 52 | { 53 | fixture() 54 | : io_service_{} 55 | , work_{ io_service_ } 56 | , manager_{ io_service_ } 57 | , timeouts_received_{} 58 | { } 59 | 60 | boost::asio::io_service io_service_; 61 | boost::asio::io_service::work work_; 62 | kd::timer manager_; 63 | std::size_t timeouts_received_; 64 | }; 65 | 66 | /** 67 | * 68 | */ 69 | BOOST_AUTO_TEST_SUITE( test_usage ) 70 | 71 | BOOST_FIXTURE_TEST_CASE( multiple_associations_can_be_added, fixture ) 72 | { 73 | BOOST_REQUIRE_EQUAL( 0, io_service_.poll() ); 74 | BOOST_REQUIRE_EQUAL( 0, timeouts_received_ ); 75 | 76 | // Create the association. 77 | auto on_expiration = [ this ] ( void ) 78 | { ++ timeouts_received_; }; 79 | 80 | auto const infinite = std::chrono::hours( 1 ); 81 | manager_.expires_from_now( infinite, on_expiration ); 82 | BOOST_REQUIRE_EQUAL( 0, io_service_.poll() ); 83 | BOOST_REQUIRE_EQUAL( 0, timeouts_received_ ); 84 | 85 | // This new expiration should trigger a cancel of the current 86 | // timeout (infinite), hence one task execution. 87 | auto const immediate = kd::timer::duration::zero(); 88 | manager_.expires_from_now( immediate, on_expiration ); 89 | BOOST_REQUIRE_EQUAL( 1, io_service_.run_one() ); 90 | BOOST_REQUIRE_EQUAL( 0, timeouts_received_ ); 91 | 92 | // Then the task execution of the new timeout (immediate) 93 | // and the call of its associated callback. 94 | BOOST_REQUIRE_EQUAL( 1, io_service_.run_one() ); 95 | BOOST_REQUIRE_EQUAL( 1, timeouts_received_ ); 96 | 97 | BOOST_REQUIRE_EQUAL( 0, io_service_.poll() ); 98 | BOOST_REQUIRE_EQUAL( 1, timeouts_received_ ); 99 | 100 | // A timeout (infinite) is still in flight atm. 101 | } 102 | 103 | BOOST_AUTO_TEST_SUITE_END() 104 | 105 | BOOST_AUTO_TEST_SUITE_END() 106 | 107 | } 108 | 109 | --------------------------------------------------------------------------------