Compare commits

..
95 Commits
Author SHA1 Message Date
Adrien Béraud 297a23fb1f dhtrunner: run shutdown on op queue 2019-07-02 12:09:31 -04:00
Adrien Béraud 0d641161e8 dhtrunner: fix minor warning 2019-07-01 23:22:00 -04:00
Adrien Béraud 27b3c0d47e dhtrunner: add appropriate lock to setProxyServer 2019-07-01 23:20:03 -04:00
Adrien Béraud 149b33ef57 dht: simplify error message to avoid use-after-move 2019-07-01 15:07:10 -04:00
Adrien Béraud 150e62de0b sockaddr: fix npe if address is not set 2019-07-01 14:08:41 -04:00
Adrien Béraud 89bdfce840 dhtrunner: add proper locks for push notification 2019-07-01 12:10:51 -04:00
Adrien Béraud bce41ecd69 proxy client: fix build with push notifications 2019-07-01 01:12:21 -04:00
Adrien Béraud 4374d206ab op_cache: simplify addListener 2019-07-01 00:34:05 -04:00
Adrien Béraud b64820af59 proxy client: remove unneeded filter
Filters are applied at the SearchCache level
2019-07-01 00:34:05 -04:00
Adrien Béraud be0baefee8 net: recompute selectFd in case of rebind 2019-06-22 22:51:56 -04:00
Adrien Béraud 2ac5157ab8 net: attempt to use the same port for IPv4 and IPv6 if 0 2019-06-22 21:30:49 -04:00
Adrien Béraud fbe8834e04 net: compute selectFd once 2019-06-22 18:49:50 -04:00
Adrien Béraud 89ff131750 tools: close stdin on sigint 2019-06-22 18:37:58 -04:00
Adrien Béraud feb498305f network engine: convert mapped IPv4 2019-06-22 18:37:58 -04:00
Adrien Béraud d438d4ef1b sockaddr: add getMappedIPv6 2019-06-21 11:00:48 -04:00
Adrien Béraud 738424b1ae dhtrunner: use default values for config 2019-06-19 19:27:54 -04:00
Adrien Béraud 86088b043b thread pool: getShared returns shared_future instead of shared_ptr<future> 2019-06-14 13:06:06 -04:00
Adrien Béraud 96e12e88c3 dhtproxytester: add more checks, cleanup 2019-06-09 23:34:38 -04:00
Adrien Béraud 8da933c01a dhtrunner: use threaded mode by default 2019-06-09 23:31:40 -04:00
Adrien Béraud 20c0069867 dhtrunner/peerdiscovery: only advertise bound address families 2019-06-09 23:15:31 -04:00
Adrien Béraud 8942e0d00e dht: init parent class with logger 2019-06-09 19:07:04 -04:00
Adrien Béraud bc760f9348 Update README.md 2019-06-09 19:06:44 -04:00
Adrien Béraud 59702190a7 update to version 1.10.0 2019-06-09 09:06:36 -04:00
Adrien Béraud cb3e94d0be dhtnode: improve manpage 2019-06-08 13:28:52 -04:00
Adrien Béraud ab7b8f6027 dhtnode: improve manpage 2019-06-08 12:59:57 -04:00
Adrien Béraud 6e5231047b dhtrunnner: properly lock mutex in run & join 2019-06-08 10:20:25 -04:00
Adrien Béraud 777505434c tools: always handle signals, don't block in signal handling 2019-06-08 09:23:34 -04:00
Adrien Béraud 18c3161261 tools: allow to use existing certificate/private key 2019-06-08 01:43:07 -04:00
Adrien Béraud a63c5d172b build: install network utils 2019-06-07 14:41:10 -04:00
Adrien Béraud 9c6de8cc16 net: add logger support for UdpSocket 2019-06-07 14:14:15 -04:00
Adrien Béraud fe9de44867 dhtrunner: stop socket after dht 2019-06-07 14:14:15 -04:00
Adrien Béraud 4bfd6bb545 dhtrunner: add pluggable transport 2019-06-07 14:14:15 -04:00
Adrien Béraud 120c017399 net: add DatagramSocket, UdpSocket transport 2019-06-07 14:14:15 -04:00
Mingrui Zhang d6ad67d8e2 peerdiscovery: change comment 2019-06-04 15:30:45 -04:00
Mingrui Zhang 19d0aa55f7 Test: change ip multicast address to organization local 2019-06-04 15:30:45 -04:00
Adrien Béraud 941e53425f update to version 1.9.5 2019-06-04 09:54:02 -04:00
Adrien Béraud baf811bfe9 dhtrunner: don't override statusCallback if not provided 2019-05-31 19:29:59 -04:00
Adrien Béraud 76f0672e63 context: add statusCallback, certificateStore 2019-05-31 10:12:42 -04:00
Adrien Béraud ff6be81929 peer discovery: add default port 2019-05-23 10:39:43 -04:00
Adrien Béraud e4516772ee dht: log cleanup 2019-05-22 11:20:27 -04:00
Adrien Béraud c7e2483160 dht: add logger to constructor 2019-05-22 00:47:25 -04:00
Adrien Béraud 37b12c114d dht: cleanup 2019-05-22 00:17:18 -04:00
MingruiZhangW 77bd34ad9c Merge pull request #405 from savoirfairelinux/context
dhtrunner: add context
2019-05-21 16:21:45 -04:00
Adrien Béraud 44490bd9ca dhtrunner: add context 2019-05-21 13:43:55 -04:00
Adrien Béraud ca01568824 dhtrunner: add API to access PeerDiscovery instance 2019-05-20 10:21:35 -04:00
Adrien Béraud 2b259639d2 peer discovery: fix occasional use-after-free in unit test 2019-05-20 10:21:26 -04:00
Adrien Béraud 84d322e428 peer discovery: check running before select 2019-05-20 10:21:26 -04:00
Sébastien Blin d807af3951 Merge pull request #402 from MingruiZhangW/peerdiscovery_fix_bind
peerdiscovery: bind socket problem fix
2019-05-16 17:19:02 -04:00
Mingrui Zhang 29003700db peerdiscovery: fix the issue where bind() can be interrupted after calling publish() first 2019-05-15 15:42:32 -04:00
Sébastien Blin b143bc459d default_types: add metadatas map into ImMessage
Give the ability to store more datas into an ImMessage

Issue: #345
2019-05-03 14:54:43 -04:00
Adrien Béraud 4d6e5ab877 peer discovery: fix warning 2019-05-03 10:13:05 -04:00
Adrien Béraud 248d2e3f73 update to version 1.9.4 2019-05-02 12:44:27 -04:00
Adrien Béraud 0692bd9bc9 proxy server: fix warning when building without push notifications 2019-04-30 17:47:40 -04:00
Adrien Béraud 7f48c4808b network engine: minor cleanup 2019-04-30 17:47:40 -04:00
Adrien Béraud 32a443a1d8 thread pool: add unit test 2019-04-30 17:47:40 -04:00
Adrien Béraud 6d0fcba3b5 thread pool: add Executor 2019-04-30 17:47:40 -04:00
Adrien Béraud 76e2efb19b peerdiscovery: undef write macro after use 2019-04-26 11:50:25 -04:00
Adrien Béraud bbe1b9233f dhtrunner: use recv instead of recvfrom for stoppipe 2019-04-26 02:29:49 -04:00
Adrien Béraud 7558ca0dca peerdiscovery: unit test cleanup 2019-04-26 02:29:49 -04:00
Adrien Béraud 38141322f1 peerdiscovery: stop threads when stopping services 2019-04-26 02:29:49 -04:00
Adrien Béraud 6c5ea125ca peerdiscovery: add automatic template serialization 2019-04-26 02:29:49 -04:00
Adrien Béraud d0362e58e0 dhtnode: update dht instance name
Avoid confusion with the namespace
2019-04-25 23:33:22 -04:00
Adrien Béraud 1b3a40f345 dhtrunner: clear stop file descriptor if still running 2019-04-25 22:12:28 -04:00
Adrien Béraud 38d854e6f4 dhtrunner: read correct size from buffer 2019-04-25 22:11:20 -04:00
Adrien Béraud e0241ccfbd dhtrunner: drop older packets in batch 2019-04-25 22:10:46 -04:00
Adrien Béraud d4311925b4 dhtrunner: shutdown: return if not running 2019-04-25 21:38:52 -04:00
Adrien Béraud 9aa56dd464 dhtnode/systemd: use simple service mode 2019-04-25 21:32:35 -04:00
Adrien Béraud ec3b259ead dhtnode/systemd: update default bootstrap 2019-04-25 21:18:11 -04:00
Adrien Béraud 332cab10ef tools: don't chdir to / when deamonizing 2019-04-25 21:17:44 -04:00
Adrien Béraud 85f2b618c7 logs: use ofstream for file logging 2019-04-25 14:31:06 -04:00
Adrien Béraud bcf18fda53 update to version 1.9.3 2019-04-25 11:10:42 -04:00
Adrien Béraud 6b78a4cad6 peerdiscovery: catch parsing errors 2019-04-25 10:25:36 -04:00
Adrien Béraud 66d3a8aeaa dhtrunner: cleanup 2019-04-24 14:51:43 -04:00
Adrien Béraud 958cb250a3 dhtnode: show both IPv4, IPv6 bound ports 2019-04-23 12:13:53 -04:00
Adrien Béraud 6a5724a868 peerdiscovery: allow per-domain publish, cleanup 2019-04-23 12:09:08 -04:00
Adrien Béraud 11ac84de54 Merge pull request #392 from MingruiZhangW/peer_discovery_version_2
peerdiscovery: modify to add support for sending and receiving msgpack
2019-04-23 11:20:18 -04:00
MingruiZhangW f65e8c1a1f Merge branch 'master' into peer_discovery_version_2 2019-04-22 09:13:17 -04:00
Adrien Béraud c2fdf6ae92 dhtnode: show grouped get results, improve duration display 2019-04-21 21:39:54 -04:00
Adrien Béraud 91a81f64ac thread pool: make public 2019-04-21 21:39:54 -04:00
Adrien Béraud 17b772e6cc proxy client: close all sockets before joining 2019-04-20 22:38:36 -04:00
Adrien Béraud 75738ac28b proxy client: don't hold lock while calling callback 2019-04-20 22:07:48 -04:00
Adrien Béraud 84a2d771c1 dht: add some missing override 2019-04-20 22:07:48 -04:00
Adrien Béraud f6273f9efc tools/dhtnode: improve documentation 2019-04-20 17:30:39 -04:00
Adrien Béraud 5881c91510 utils: include config.h 2019-04-19 20:24:01 -04:00
Adrien Béraud e09c55ca42 update to version 1.9.2 2019-04-19 16:15:56 -04:00
Andreas Traczyk c737e4690e update visual studio build 2019-04-19 15:53:42 -04:00
Adrien Béraud 35a9d1f612 proxy client: catch exception in Http::close() 2019-04-18 17:38:00 -04:00
Mingrui Zhang 0f3396cd66 peerdiscovery: make nested classes to hide ip versions 2019-04-18 12:20:17 -04:00
Mingrui Zhang 98cd6cc61e peerdiscovery: fix memory leakage cased by sbuffer release 2019-04-18 10:20:00 -04:00
Mingrui Zhang 092cb9551e peerdiscovery: add testpack into tester to verify the possibility of sending & receiving 2 packages simultaneously (including stop functions) 2019-04-18 09:33:15 -04:00
Mingrui Zhang a2bbca792c peerdiscovery: add dmtx_ to distinguish send & listen shared resources, add stopDiscovery, stoplisten to stop listen or discover certain type of service 2019-04-17 10:26:49 -04:00
Mingrui Zhang 0f51115f44 peerdiscovery: modify maps to handle more services in one instance 2019-04-16 15:11:07 -04:00
Mingrui Zhang 18aa6ddb7b peerdiscovery: modify function signatures to make service consistent 2019-04-15 18:24:15 -04:00
Mingrui Zhang 0a436e17b0 peerdiscovery: modifications on tester fit for the updates 2019-04-15 17:26:59 -04:00
Mingrui Zhang 763ffddf51 peerdiscovery: modify to add support for sending and receiving msgpack 2019-04-15 16:50:48 -04:00
49 changed files with 2015 additions and 1096 deletions

No files matched your search

+8 -21
View File
@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 3.1)
project (opendht)
set (opendht_VERSION_MAJOR 1)
set (opendht_VERSION_MINOR 9.1)
set (opendht_VERSION_MINOR 10.0)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
@@ -62,9 +62,6 @@ if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
if (NOT Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
pkg_search_module(SSL libssl)
pkg_search_module(Crypto libcrypto)
pkg_search_module(Tls libtls)
endif()
# Build flags
@@ -109,20 +106,8 @@ endif ()
if (Jsoncpp_INCLUDE_DIRS)
include_directories (SYSTEM "${Jsoncpp_INCLUDE_DIRS}")
endif ()
if (SSL_INCLUDE_DIRS)
include_directories (SYSTEM "${SSL_INCLUDE_DIRS}")
endif ()
if (Crypto_INCLUDE_DIRS)
include_directories (SYSTEM "${Crypto_INCLUDE_DIRS}")
endif ()
if (Tls_INCLUDE_DIRS)
include_directories (SYSTEM "${Tls_INCLUDE_DIRS}")
endif ()
link_directories (${Nettle_LIBRARY_DIRS})
link_directories (${Jsoncpp_LIBRARY_DIRS})
link_directories (${SSL_LIBRARY_DIRS})
link_directories (${Crypto_LIBRARY_DIRS})
link_directories (${Tls_LIBRARY_DIRS})
include_directories (
./
include/
@@ -166,8 +151,8 @@ list (APPEND opendht_SOURCES
src/dhtrunner.cpp
src/log.cpp
src/peer_discovery.cpp
src/network_utils.h
src/network_utils.cpp
src/thread_pool.cpp
)
list (APPEND opendht_HEADERS
@@ -192,6 +177,8 @@ list (APPEND opendht_HEADERS
include/opendht/log.h
include/opendht/log_enable.h
include/opendht/peer_discovery.h
include/opendht/thread_pool.h
include/opendht/network_utils.h
include/opendht.h
)
@@ -214,8 +201,6 @@ if (OPENDHT_PROXY_SERVER)
include/opendht/dht_proxy_server.h
)
list (APPEND opendht_SOURCES
src/thread_pool.h
src/thread_pool.cpp
src/dht_proxy_server.cpp
)
endif ()
@@ -270,7 +255,7 @@ if (OPENDHT_STATIC)
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht-static
PRIVATE ${Restbed_LIBRARY} ${argon2_LIBRARIES} ${SSL_LIBRARIES} ${Crypto_LIBRARIES} ${Tls_LIBRARIES}
PRIVATE ${Restbed_LIBRARY} ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES} ${Jsoncpp_LIBRARIES})
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
@@ -289,7 +274,7 @@ if (OPENDHT_SHARED)
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES} ${Restbed_LIBRARY} ${Jsoncpp_LIBRARIES} ${SSL_LIBRARIES} ${Crypto_LIBRARIES} ${Tls_LIBRARIES})
target_link_libraries(opendht PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES} ${Restbed_LIBRARY} ${Jsoncpp_LIBRARIES})
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
@@ -336,6 +321,8 @@ if (OPENDHT_TESTS)
tests/dhtrunnertester.cpp
tests/peerdiscoverytester.h
tests/peerdiscoverytester.cpp
tests/threadpooltester.h
tests/threadpooltester.cpp
)
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
list (APPEND test_FILES
+22 -22
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,32 +21,32 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}</ProjectGuid>
<RootNamespace>dhtchat</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
@@ -86,14 +86,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -102,14 +102,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -120,16 +120,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -140,16 +140,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
+22 -22
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,32 +21,32 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}</ProjectGuid>
<RootNamespace>dhtnode</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
@@ -86,14 +86,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -102,14 +102,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -120,16 +120,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -140,16 +140,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
+22 -22
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,32 +21,32 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{78443BCD-4689-4007-A246-F8F34B27F561}</ProjectGuid>
<RootNamespace>dhtscanner</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
@@ -86,14 +86,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -102,14 +102,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -120,16 +120,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -140,16 +140,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
+50 -35
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -19,6 +19,17 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\dht_proxy_client.cpp" />
<ClCompile Include="..\src\network_utils.cpp" />
<ClCompile Include="..\src\op_cache.cpp" />
<ClCompile Include="..\src\peer_discovery.cpp" />
<ClCompile Include="..\src\rng.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\src\thread_pool.cpp" />
<ClCompile Include="wingetopt.c" />
<ClCompile Include="..\src\base64.cpp" />
<ClCompile Include="..\src\callbacks.cpp" />
@@ -39,6 +50,8 @@
<ClCompile Include="..\src\value.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\network_utils.h" />
<ClInclude Include="..\src\thread_pool.h" />
<ClInclude Include="unistd.h" />
<ClInclude Include="wingetopt.h" />
<ClInclude Include="..\include\opendht.h" />
@@ -75,32 +88,32 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{711397CE-E5D5-467D-9457-8716C047E50C}</ProjectGuid>
<RootNamespace>opendht</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
@@ -123,33 +136,34 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)..\..\</OutDir>
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>opendhtd</TargetName>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)..\..\</OutDir>
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>opendht</TargetName>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)..\..\</OutDir>
<TargetName>opendhtd</TargetName>
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)..\..\</OutDir>
<TargetName>opendht</TargetName>
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<SuppressStartupBanner>false</SuppressStartupBanner>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
@@ -160,7 +174,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -168,10 +182,11 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
@@ -182,7 +197,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -192,11 +207,11 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -211,7 +226,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
</Lib>
</ItemDefinitionGroup>
@@ -222,11 +237,11 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)contrib\build\include;$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)contrib\build\argon2\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -241,7 +256,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
+36 -4
View File
@@ -53,12 +53,26 @@
<Filter>Source Files\indexation</Filter>
</ClCompile>
<ClCompile Include="wingetopt.c" />
<ClCompile Include="..\src\rng.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\op_cache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dht_proxy_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\peer_discovery.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\network_utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thread_pool.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\opendht\def.h" />
<ClInclude Include="..\include\opendht\sockaddr.h" />
<ClInclude Include="..\src\net.h" />
<ClInclude Include="..\src\parsed_message.h" />
<ClInclude Include="..\src\base64.h">
<Filter>Source Files</Filter>
</ClInclude>
@@ -139,6 +153,24 @@
</ClInclude>
<ClInclude Include="unistd.h" />
<ClInclude Include="wingetopt.h" />
<ClInclude Include="..\include\opendht\def.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\net.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\parsed_message.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\sockaddr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\network_utils.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\src\thread_pool.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
+1 -1
View File
@@ -33,7 +33,7 @@ g++ main.cpp -std=c++11 -lopendht -lgnutls
## Examples
### C++ example
The `tools` directory includes simple example programs :
* `dhtnode`, a command line tool, mostly used for debuging, allowing to perform operations supported by the library (get, put etc.) with text values.
* `dhtnode`, a command line tool, allowing to run a DHT node and perform operations supported by the library (get, put etc.) with text values.
* `dhtchat`, a very simple IM client working over the dht.
Example program launching a DHT node, connecting to the network and performing some basic operations:
+2 -2
View File
@@ -1,7 +1,7 @@
dnl define macros
m4_define([opendht_major_version], 1)
m4_define([opendht_minor_version], 9)
m4_define([opendht_patch_version], 1)
m4_define([opendht_minor_version], 10)
m4_define([opendht_patch_version], 0)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
+57 -35
View File
@@ -1,22 +1,24 @@
.TH DHTNODE 1 2016-07-29
.TH DHTNODE 1 2019-06-08
.SH NAME
.B dhtnode
- a simple OpenDHT command line node runner.
.SH SYNOPSIS
.B dhtnode [-h]
.B dhtnode [-v [-l \fIlogfile\fP]] [-i] [-d] [-n \fInetwork_id\fP] [-p \fIlocal_port\fP] [-b \fIbootstrap_host\fP[:\fIport\fP]]
.B dhtnode
[\fB\-h\fR]
[\fB\-v\fR [\fB\-l\fR \fIlogfile\fR] [\fB\-L\fR]]
[\fB\-i\fR [\fB\-\-save\-identity\fR \fIfile\fR]]
[\fB\-d\fR] [\fB\-s\fR]
[\fB\-n\fR \fInetwork_id\fR]
[\fB\-p\fR \fIlocal_port\fR]
[\fB\-b\fR \fIbootstrap_host\fR[:\fIport\fR]]
[\fB\-\-certificate\fR \fIfile\fR]
[\fB\-\-privkey\fR \fIfile\fR]
[\fB\-\-privkey\-password\fR \fIpassword\fR]
[\fB\-\-proxyserver\fR \fIport\fR]
[\fB\-\-proxyclient\fR \fIserver\fR]
.SH DESCRIPTION
This program runs a simple OpenDHT node in an interactive way. If you rather
want to run the node in daemon mode, option \fB'-d'\fP is provided. When running
in the interactive shell, you benefit from the readline capabilities for writing
your commands such as command history. Here are the available commands in the
interactive shell:
Runs an OpenDHT node, with a CLI (default) or as a daemon (with \fB'-d'\fP or \fB'-s'\fP).
Commands available in the interactive shell are:
.EE
h, help Print this help message.
q, quit Quit the program.
@@ -37,43 +39,63 @@ interactive shell:
private key.
e [key] [dest] [str] Put string value at [key], encrypted for [dest] with
its public key (if found).
.SH OPTIONS
.TP
\fB-h\fP
\fB\-h\fP
Prints some help.
.TP
\fB-v\fP
Enable the verbose mode (log to stdout by default)
\fB\-v\fP
Enable the verbose mode (log to stdout/stderr by default)
.TP
\fB-l\fP \fIlog_file\fP
Write log to file instead of stdout
\fB\-l\fP \fIlog_file\fP
Write log to file instead of stdout/stderr
.TP
\fB-i\fP
\fB\-L\fP
Write log to syslog instead of stdout/stderr
.TP
\fB\-i\fP
Generate cryptographic identity for the node.
.TP
\fB-d\fP
\fB\-\-save\-identity\fP \fIfile\fP
Save generated identity (certificate and private key) to given file prefix.
.TP
\fB\-\-certificate\fP \fIfile\fP
Load identity certificate from given file.
.TP
\fB\-\-privkey\fP \fIfile\fP
Load identity private key from given file.
.TP
\fB\-\-privkey\-password\fP \fIpassword\fP
Password to use for private key encryption or decryption (optional).
.TP
\fB\-d\fP
Run the program in daemon mode (will fork in the background).
.TP
\fB-n\fP \fInetwork_id\fP
\fB\-s\fP
Run the program in service mode (non\-forking daemon).
.TP
\fB\-D\fP
Enables multicast automatic local peer discovery.
.TP
\fB\-f\fP \fIfile\fP
Specify a file path to persist/load the node state.
.TP
\fB\-n\fP \fInetwork_id\fP
Specify the network id. This let you connect to distinct networks and prevents
the merge of two different networks (available since OpenDHT v0.6.1).
.TP
\fB-p\fP \fIlocal_port\fP
Use port \fIlocal_port\fP for the program to bind to.
\fB\-p\fP \fIlocal_port\fP
Use UDP port \fIlocal_port\fP for the program to bind to.
.TP
\fB-b\fP \fIbootstrap_host\fP[:\fIport\fP]
\fB\-b\fP \fIbootstrap_host\fP[:\fIport\fP]
The program needs to be given a node to connect to the network. You use this
option to provide the ip address of that node.
.TP
\fB\-\-proxyserver\fP \fIlocal_port\fP
Run a proxy server bound to this DHT node on HTTP port \fIlocal_port\fP
.TP
\fB\-\-proxyclient\fP \fIserver\fP
Run this DHT node in proxy client mode, and connect to \fIserver\fP
.SH AUTHORS
.TP
Program written by
-1
View File
@@ -22,7 +22,6 @@
#ifdef OPENDHT_PROXY_SERVER
#include "opendht/dht_proxy_server.h"
#endif
#include "opendht/log.h"
#include "opendht/default_types.h"
#ifdef OPENDHT_INDEXATION
#include "opendht/indexation/pht.h"
+7 -7
View File
@@ -89,23 +89,23 @@ struct OPENDHT_PUBLIC NodeInfo {
*/
struct OPENDHT_PUBLIC Config {
/** DHT node ID */
InfoHash node_id;
InfoHash node_id {};
/**
* DHT network ID. A node will only talk with other nodes having
* the same network ID.
* Network ID 0 (default) represents the main public network.
*/
NetId network;
NetId network {0};
/** For testing purposes only, enables bootstrap mode */
bool is_bootstrap;
bool is_bootstrap {false};
/** Makes the DHT responsible to maintain its stored values. Consumes more ressources. */
bool maintain_storage;
bool maintain_storage {false};
/** If set, the dht will load its state from this file on start and save its state in this file on shutdown */
std::string persist_path;
std::string persist_path {};
};
/**
@@ -113,8 +113,8 @@ struct OPENDHT_PUBLIC Config {
*/
struct OPENDHT_PUBLIC SecureDhtConfig
{
Config node_config;
crypto::Identity id;
Config node_config {};
crypto::Identity id {};
};
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
+1
View File
@@ -654,6 +654,7 @@ OPENDHT_PUBLIC Identity generateIdentity(const std::string& name = "dhtnode", co
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name, const Identity& ca, bool is_ca);
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name = "dhtnode", const Identity& ca = {});
OPENDHT_PUBLIC void saveIdentity(const Identity& id, const std::string& path, const std::string& privkey_password = {});
/**
* Performs SHA512, SHA256 or SHA1, depending on hash_length.
+5 -2
View File
@@ -114,8 +114,10 @@ public:
ImMessage() {}
ImMessage(dht::Value::Id id, std::string&& m, long d = 0)
: id(id), msg(std::move(m)), date(d) {}
ImMessage(dht::Value::Id id, std::string&& dt, std::string&& m, long d = 0)
ImMessage(dht::Value::Id id, std::string &&dt, std::string &&m, long d = 0)
: id(id), msg(std::move(m)), datatype(std::move(dt)), date(d) {}
ImMessage(dht::Value::Id id, std::string &&dt, std::string &&m, std::map<std::string, std::string> &&md, long d = 0)
: id(id), msg(std::move(m)), datatype(std::move(dt)), metadatas(std::move(md)), date(d) {}
virtual void unpackValue(const Value& v) override {
to = v.recipient;
@@ -126,10 +128,11 @@ public:
dht::Value::Id id {0};
std::string msg;
std::string datatype;
std::map<std::string, std::string> metadatas;
long date {0};
ImStatus status {ImStatus::NONE};
MSGPACK_DEFINE_MAP(id, msg, date, status, datatype)
MSGPACK_DEFINE_MAP(id, msg, date, status, datatype, metadatas)
};
class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
+14 -20
View File
@@ -68,7 +68,7 @@ public:
* Initialise the Dht with two open sockets (for IPv4 and IP6)
* and an ID for the node.
*/
Dht(const int& s, const int& s6, const Config& config);
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l = {});
virtual ~Dht();
/**
@@ -85,6 +85,8 @@ public:
return std::max(getStatus(AF_INET), getStatus(AF_INET6));
}
net::DatagramSocket* getSocket() const override { return network_engine.getSocket(); };
/**
* Performs final operations before quitting.
*/
@@ -120,7 +122,7 @@ public:
void pingNode(const sockaddr*, socklen_t, DoneCallbackSimple&& cb={}) override;
time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr&) override;
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) override;
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
return periodic(buf, buflen, SockAddr(from, fromlen));
}
@@ -274,19 +276,19 @@ public:
std::string getStorageLog() const override;
std::string getStorageLog(const InfoHash&) const override;
std::string getRoutingTablesLog(sa_family_t) const;
std::string getSearchesLog(sa_family_t) const;
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
std::string getRoutingTablesLog(sa_family_t) const override;
std::string getSearchesLog(sa_family_t) const override;
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const override;
void dumpTables() const;
std::vector<unsigned> getNodeMessageStats(bool in = false) {
void dumpTables() const override;
std::vector<unsigned> getNodeMessageStats(bool in = false) override {
return network_engine.getNodeMessageStats(in);
}
/**
* Set the in-memory storage limit in bytes
*/
void setStorageLimit(size_t limit = DEFAULT_STORAGE_LIMIT) {
void setStorageLimit(size_t limit = DEFAULT_STORAGE_LIMIT) override {
max_store_size = limit;
}
@@ -294,7 +296,7 @@ public:
* Returns the total memory usage of stored values and the number
* of stored values.
*/
std::pair<size_t, size_t> getStoreSize() const {
std::pair<size_t, size_t> getStoreSize() const override {
return {total_store_size, total_values};
}
@@ -436,17 +438,9 @@ private:
RoutingTable& buckets(sa_family_t af) { return af == AF_INET ? buckets4 : buckets6; }
const RoutingTable& buckets(sa_family_t af) const { return af == AF_INET ? buckets4 : buckets6; }
Bucket* findBucket(const InfoHash& id, sa_family_t af) {
RoutingTable::iterator b;
switch (af) {
case AF_INET:
b = buckets4.findBucket(id);
return b == buckets4.end() ? nullptr : &(*b);
case AF_INET6:
b = buckets6.findBucket(id);
return b == buckets6.end() ? nullptr : &(*b);
default:
return nullptr;
}
auto& b = buckets(af);
auto it = b.findBucket(id);
return it == b.end() ? nullptr : &(*it);
}
const Bucket* findBucket(const InfoHash& id, sa_family_t af) const {
return const_cast<Dht*>(this)->findBucket(id, af);
+15 -5
View File
@@ -23,9 +23,14 @@
namespace dht {
namespace net {
class DatagramSocket;
}
class OPENDHT_PUBLIC DhtInterface {
public:
DhtInterface() = default;
DhtInterface(const Logger& l) : DHT_LOG(l) {};
virtual ~DhtInterface() = default;
// [[deprecated]]
@@ -39,6 +44,8 @@ public:
virtual NodeStatus getStatus(sa_family_t af) const = 0;
virtual NodeStatus getStatus() const = 0;
virtual net::DatagramSocket* getSocket() const { return {}; };
/**
* Get the ID of the DHT node.
*/
@@ -72,7 +79,7 @@ public:
virtual void pingNode(const sockaddr*, socklen_t, DoneCallbackSimple&& cb={}) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr&) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) = 0;
/**
@@ -214,13 +221,18 @@ public:
/**
* Enable or disable logging of DHT internal messages
*/
virtual void setLoggers(LogMethod error = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG)
{
virtual void setLoggers(LogMethod error = {}, LogMethod warn = {}, LogMethod debug = {}) {
DHT_LOG.DBG = debug;
DHT_LOG.WARN = warn;
DHT_LOG.ERR = error;
}
virtual void setLogger(const Logger& l) {
DHT_LOG.DBG = l.DBG;
DHT_LOG.WARN = l.WARN;
DHT_LOG.ERR = l.ERR;
}
/**
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
*/
@@ -238,8 +250,6 @@ public:
virtual void pushNotificationReceived(const std::map<std::string, std::string>& data) = 0;
protected:
bool logFilerEnable_ {};
InfoHash logFiler_ {};
Logger DHT_LOG;
};
+3 -3
View File
@@ -44,7 +44,7 @@ public:
DhtProxyClient();
explicit DhtProxyClient(std::function<void()> loopSignal, const std::string& serverHost, const std::string& pushClientId = "");
explicit DhtProxyClient(std::function<void()> loopSignal, const std::string& serverHost, const std::string& pushClientId = "", const Logger& = {});
virtual void setPushNotificationToken(const std::string& token) {
#ifdef OPENDHT_PUSH_NOTIFICATIONS
@@ -180,7 +180,7 @@ public:
*/
void pushNotificationReceived(const std::map<std::string, std::string>& notification);
time_point periodic(const uint8_t*, size_t, const SockAddr&);
time_point periodic(const uint8_t*, size_t, SockAddr);
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) {
return periodic(buf, buflen, SockAddr(from, fromlen));
}
@@ -283,7 +283,7 @@ private:
RESUBSCRIBE,
};
void sendListen(const std::shared_ptr<restbed::Request> &request,
const ValueCallback &, const Value::Filter &filter,
const ValueCallback &,
const Sp<ListenState> &state,
ListenMethod method = ListenMethod::LISTEN);
+37 -60
View File
@@ -20,12 +20,13 @@
#pragma once
#include "def.h"
#include "infohash.h"
#include "value.h"
#include "callbacks.h"
#include "sockaddr.h"
#include "log_enable.h"
#include "def.h"
#include "network_utils.h"
#include <thread>
#include <mutex>
@@ -52,15 +53,24 @@ struct SecureDhtConfig;
class OPENDHT_PUBLIC DhtRunner {
public:
typedef std::function<void(NodeStatus, NodeStatus)> StatusCallback;
using StatusCallback = std::function<void(NodeStatus, NodeStatus)>;
struct Config {
SecureDhtConfig dht_config;
bool threaded;
std::string proxy_server;
std::string push_node_id;
bool peer_discovery;
bool peer_publish;
SecureDhtConfig dht_config {};
bool threaded {true};
std::string proxy_server {};
std::string push_node_id {};
bool peer_discovery {false};
bool peer_publish {false};
};
struct Context {
std::unique_ptr<Logger> logger {};
std::unique_ptr<net::DatagramSocket> sock;
std::shared_ptr<PeerDiscovery> peerDiscovery {};
StatusCallback statusChangedCallback {};
CertificateStoreQuery certificateStore {};
Context() {}
};
DhtRunner();
@@ -296,9 +306,7 @@ public:
* Returns the currently bound address.
* @param f: address family of the bound address to retreive.
*/
const SockAddr& getBound(sa_family_t f = AF_INET) const {
return (f == AF_INET) ? bound4 : bound6;
}
SockAddr getBound(sa_family_t f = AF_INET) const;
/**
* Returns the currently bound port, in host byte order.
@@ -316,7 +324,8 @@ public:
std::vector<ValuesExport> exportValues() const;
void setLoggers(LogMethod err = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG);
void setLogger(const Logger& logger = {});
void setLoggers(LogMethod err = {}, LogMethod warn = {}, LogMethod debug = {});
/**
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
@@ -356,26 +365,14 @@ public:
* @param threaded: If false, ::loop() must be called periodically. Otherwise a thread is launched.
* @param cb: Optional callback to receive general state information.
*/
void run(in_port_t port = 4222, const crypto::Identity identity = {}, bool threaded = false, NetId network = 0) {
run(port, {
/*.dht_config = */{
/*.node_config = */{
/*.node_id = */{},
/*.network = */network,
/*.is_bootstrap = */false,
/*.maintain_storage = */false,
/*.persist_path = */{}
},
/*.id = */identity
},
/*.threaded = */threaded,
/*.proxy_server = */"",
/*.push_node_id = */"",
/*.peer_discovery = */true,
/*.peer_publish = */true,
});
void run(in_port_t port = 4222, const crypto::Identity& identity = {}, bool threaded = true, NetId network = 0) {
Config config;
config.dht_config.node_config.network = network;
config.dht_config.id = identity;
config.threaded = threaded;
run(port, config);
}
void run(in_port_t port, const Config& config);
void run(in_port_t port, const Config& config, Context&& context = {});
/**
* @param local4: Local IPv4 address and port to bind. Can be null.
@@ -385,12 +382,14 @@ public:
* @param threaded: If false, loop() must be called periodically. Otherwise a thread is launched.
* @param cb: Optional callback to receive general state information.
*/
void run(const SockAddr& local4, const SockAddr& local6, const Config& config);
void run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context = {});
/**
* Same as @run(sockaddr_in, sockaddr_in6, Identity, bool, StatusCallback), but with string IP addresses and service (port).
*/
void run(const char* ip4, const char* ip6, const char* service, const Config& config);
void run(const char* ip4, const char* ip6, const char* service, const Config& config, Context&& context = {});
void run(const Config& config, Context&& context);
void setOnStatusChanged(StatusCallback&& cb) {
statusCb = std::move(cb);
@@ -403,13 +402,7 @@ public:
*/
time_point loop() {
std::lock_guard<std::mutex> lck(dht_mtx);
time_point wakeup = time_point::min();
try {
wakeup = loop_();
} catch (const dht::SocketException& e) {
startNetwork(bound4, bound6);
}
return wakeup;
return loop_();
}
/**
@@ -424,6 +417,8 @@ public:
*/
void join();
std::shared_ptr<PeerDiscovery> getPeerDiscovery() const { return peerDiscovery_; };
void setProxyServer(const std::string& proxy, const std::string& pushNodeId = "");
/**
@@ -459,8 +454,6 @@ private:
*/
void tryBootstrapContinuously();
void stopNetwork();
void startNetwork(const SockAddr sin4, const SockAddr sin6);
time_point loop_();
NodeStatus getStatus() const {
@@ -498,16 +491,8 @@ private:
mutable std::mutex dht_mtx {};
std::thread dht_thread {};
std::condition_variable cv {};
std::thread rcv_thread {};
std::mutex sock_mtx {};
struct ReceivedPacket {
Blob data;
SockAddr from;
time_point received;
};
std::queue<ReceivedPacket> rcv {};
std::queue<std::unique_ptr<net::ReceivedPacket>> rcv {};
/** true if currently actively boostraping */
std::atomic_bool bootstraping {false};
@@ -515,7 +500,6 @@ private:
std::vector<std::pair<std::string,std::string>> bootstrap_nodes_all {};
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
std::thread bootstrap_thread {};
/** protects bootstrap_nodes, bootstrap_thread */
std::mutex bootstrap_mtx {};
std::condition_variable bootstrap_cv {};
@@ -524,23 +508,16 @@ private:
std::mutex storage_mtx {};
std::atomic_bool running {false};
std::atomic_bool running_network {false};
NodeStatus status4 {NodeStatus::Disconnected},
status6 {NodeStatus::Disconnected};
StatusCallback statusCb {nullptr};
int stop_writefd {-1};
int s4 {-1}, s6 {-1};
SockAddr bound4 {};
SockAddr bound6 {};
/** Push notification token */
std::string pushToken_;
/** PeerDiscovery Parameters */
std::unique_ptr<PeerDiscovery> peerDiscovery4_;
std::unique_ptr<PeerDiscovery> peerDiscovery6_;
std::shared_ptr<PeerDiscovery> peerDiscovery_;
};
}
+9
View File
@@ -66,6 +66,15 @@ constexpr const Color::Modifier yellow(Color::FG_YELLOW);
OPENDHT_PUBLIC void
printLog(std::ostream &s, char const *m, va_list args);
OPENDHT_PUBLIC
std::unique_ptr<Logger> getStdLogger();
OPENDHT_PUBLIC
std::unique_ptr<Logger> getFileLogger(const std::string &path);
OPENDHT_PUBLIC
std::unique_ptr<Logger> getSyslogLogger(const char* name);
OPENDHT_PUBLIC void
enableLogging(dht::DhtRunner &dht);
+7 -8
View File
@@ -32,11 +32,6 @@ namespace dht {
// Logging related utility functions
/**
* Dummy function used to disable logging
*/
inline void NOLOG(char const*, va_list) {}
/**
* Wrapper for logging methods
*/
@@ -85,9 +80,13 @@ private:
};
struct Logger {
LogMethod DBG = NOLOG;
LogMethod WARN = NOLOG;
LogMethod ERR = NOLOG;
LogMethod DBG = {};
LogMethod WARN = {};
LogMethod ERR = {};
Logger() = default;
Logger(LogMethod&& err, LogMethod&& warn, LogMethod&& dbg)
: DBG(std::move(dbg)), WARN(std::move(warn)), ERR(std::move(err)) {}
void setFilter(const InfoHash& f) {
filter_ = f;
filterEnable_ = static_cast<bool>(filter_);
+10 -8
View File
@@ -28,6 +28,7 @@
#include "rng.h"
#include "rate_limiter.h"
#include "log_enable.h"
#include "network_utils.h"
#include <vector>
#include <string>
@@ -205,8 +206,8 @@ public:
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
using RequestExpiredCb = std::function<void(const Request&, bool)>;
NetworkEngine(Logger& log, Scheduler& scheduler, const int& s = -1, const int& s6 = -1);
NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock);
NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
decltype(NetworkEngine::onError)&& onError,
decltype(NetworkEngine::onNewNode)&& onNewNode,
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
@@ -217,7 +218,9 @@ public:
decltype(NetworkEngine::onAnnounce)&& onAnnounce,
decltype(NetworkEngine::onRefresh)&& onRefresh);
virtual ~NetworkEngine();
~NetworkEngine();
net::DatagramSocket* getSocket() const { return dht_socket.get(); };
void clear();
@@ -242,7 +245,7 @@ public:
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
bool isRunning(sa_family_t af) const;
inline want_t want () const { return dht_socket >= 0 && dht_socket6 >= 0 ? (WANT4 | WANT6) : -1; }
inline want_t want () const { return dht_socket->hasIPv4() and dht_socket->hasIPv6() ? (WANT4 | WANT6) : -1; }
void connectivityChanged(sa_family_t);
@@ -394,7 +397,7 @@ public:
* @param fromlen The length of the corresponding sockaddr structure.
* @param now The time to adjust the clock in the network engine.
*/
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr& addr);
void processMessage(const uint8_t *buf, size_t buflen, SockAddr addr);
Sp<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
auto n = cache.getNode(myid, addr, scheduler.time(), 0);
@@ -469,7 +472,7 @@ private:
// basic wrapper for socket sendto function
int send(const char *buf, size_t len, int flags, const SockAddr& addr);
int send(const SockAddr& addr, const char *buf, size_t len, bool confirmed = false);
void sendValueParts(const TransId& tid, const std::vector<Blob>& svals, const SockAddr& addr);
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
@@ -511,8 +514,7 @@ private:
/* DHT info */
const InfoHash& myid;
const NetId network {0};
const int& dht_socket;
const int& dht_socket6;
const std::unique_ptr<DatagramSocket> dht_socket;
const Logger& DHT_LOG;
NodeCache cache {};
+115
View File
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "def.h"
#include "sockaddr.h"
#include "utils.h"
#include "log_enable.h"
#ifdef _WIN32
#include <ws2tcpip.h>
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
#include <functional>
#include <thread>
#include <atomic>
#include <iostream>
namespace dht {
namespace net {
int bindSocket(const SockAddr& addr, SockAddr& bound);
bool setNonblocking(int fd, bool nonblocking = true);
#ifdef _WIN32
void udpPipe(int fds[2]);
#endif
struct ReceivedPacket {
Blob data;
SockAddr from;
time_point received;
};
class OPENDHT_PUBLIC DatagramSocket {
public:
using OnReceive = std::function<void(std::unique_ptr<ReceivedPacket>&& packet)>;
virtual ~DatagramSocket() {};
virtual int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) = 0;
inline void setOnReceive(OnReceive&& cb) {
rx_callback = std::move(cb);
}
virtual const SockAddr& getBound(sa_family_t family = AF_UNSPEC) const = 0;
virtual bool hasIPv4() const = 0;
virtual bool hasIPv6() const = 0;
in_port_t getPort(sa_family_t family = AF_UNSPEC) const {
return getBound(family).getPort();
}
virtual void stop() = 0;
protected:
inline void onReceived(std::unique_ptr<ReceivedPacket>&& packet) {
if (rx_callback)
rx_callback(std::move(packet));
}
private:
OnReceive rx_callback;
};
class OPENDHT_PUBLIC UdpSocket : public DatagramSocket {
public:
UdpSocket(in_port_t port, const Logger& l = {});
UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const Logger& l = {});
~UdpSocket();
int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) override;
const SockAddr& getBound(sa_family_t family = AF_UNSPEC) const override {
return (family == AF_INET6) ? bound6 : bound4;
}
bool hasIPv4() const override { return s4 != -1; }
bool hasIPv6() const override { return s6 != -1; }
void stop() override;
private:
Logger logger;
int s4 {-1};
int s6 {-1};
int stopfd {-1};
SockAddr bound4, bound6;
std::thread rcv_thread {};
std::atomic_bool running {false};
void openSockets(const SockAddr& bind4, const SockAddr& bind6);
};
}
}
+36 -60
View File
@@ -31,27 +31,53 @@ namespace dht {
class OPENDHT_PUBLIC PeerDiscovery
{
public:
static constexpr in_port_t DEFAULT_PORT = 8888;
using ServiceDiscoveredCallback = std::function<void(msgpack::object&&, SockAddr&&)>;
using PeerDiscoveredCallback = std::function<void(const InfoHash&, const SockAddr&)>;
PeerDiscovery(sa_family_t domain, in_port_t port);
PeerDiscovery(in_port_t port = DEFAULT_PORT);
~PeerDiscovery();
/**
* startDiscovery - Keep Listening data from the sender until node is joinned or stop is called
*/
void startDiscovery(PeerDiscoveredCallback callback);
void startDiscovery(const std::string &type, ServiceDiscoveredCallback callback);
template<typename T>
void startDiscovery(const std::string &type, std::function<void(T&&, SockAddr&&)> cb) {
startDiscovery(type, [cb](msgpack::object&& ob, SockAddr&& addr) {
cb(ob.as<T>(), std::move(addr));
});
}
/**
* startPublish - Keeping sending data until node is joinned or stop is called
* startPublish - Keeping sending data until node is joinned or stop is called - msgpack
*/
void startPublish(const dht::InfoHash &nodeId, in_port_t port_to_send);
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
void startPublish(sa_family_t domain, const std::string &type, const msgpack::sbuffer &pack_buf);
template<typename T>
void startPublish(const std::string &type, const T& object) {
msgpack::sbuffer buf;
msgpack::pack(buf, object);
startPublish(type, buf);
}
/**
* Thread Stopper
*/
void stop();
/**
* Remove possible callBack to discovery
*/
bool stopDiscovery(const std::string &type);
/**
* Remove different serivce message to send
*/
bool stopPublish(const std::string &type);
bool stopPublish(sa_family_t domain, const std::string &type);
/**
* Configure the sockopt to be able to listen multicast group
*/
@@ -60,62 +86,12 @@ public:
/**
* Join the threads
*/
void join() {
if(running_listen.joinable()) running_listen.join();
if(running_send.joinable()) running_send.join();
}
void join();
private:
std::mutex mtx_;
std::condition_variable cv_;
bool running_ {true};
sa_family_t domain_ {AF_UNSPEC};
int port_;
int sockfd_ {-1};
int stop_writefd_ {-1};
SockAddr sockAddrSend_;
std::array<uint8_t,dht::InfoHash::size() + sizeof(in_port_t)> data_send_;
//Thread export to be joined
std::thread running_listen;
std::thread running_send;
dht::InfoHash nodeId_;
/**
* Multicast Socket Initialization, accept IPV4, IPV6
*/
static int initialize_socket(sa_family_t domain);
/**
* Send messages
*/
void sendTo(uint8_t *buf,size_t buf_size);
/**
* Receive messages
*/
SockAddr recvFrom(uint8_t *buf, size_t &buf_size);
/**
* Send thread loop
*/
void sender_thread();
/**
* Listener thread loop
*/
void listener_thread(PeerDiscoveredCallback callback);
/**
* Listener Parameters Setup
*/
void listener_setup();
/**
* Sender Parameters Setup
*/
void sender_setup(const dht::InfoHash& nodeId, in_port_t port_to_send);
class DomainPeerDiscovery;
std::unique_ptr<DomainPeerDiscovery> peerDiscovery4_;
std::unique_ptr<DomainPeerDiscovery> peerDiscovery6_;
};
}
+8 -6
View File
@@ -195,8 +195,8 @@ public:
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override {
return dht_->getPublicAddress(family);
}
time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr& sa) override {
return dht_->periodic(buf, buflen, sa);
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr sa) override {
return dht_->periodic(buf, buflen, std::move(sa));
}
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
return dht_->periodic(buf, buflen, from, fromlen);
@@ -207,6 +207,9 @@ public:
NodeStatus getStatus() const override {
return dht_->getStatus();
}
net::DatagramSocket* getSocket() const override {
return dht_->getSocket();
};
bool isRunning(sa_family_t af = 0) const override {
return dht_->isRunning(af);
}
@@ -311,10 +314,9 @@ public:
dht_->pushNotificationReceived(notification);
}
void setLoggers(LogMethod error = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG) override
{
DhtInterface::setLoggers(error, warn, debug);
dht_->setLoggers(error, warn, debug);
void setLogger(const Logger& logger) override {
DhtInterface::setLogger(logger);
dht_->setLogger(logger);
}
/**
+5 -4
View File
@@ -59,7 +59,7 @@ public:
SockAddr(const SockAddr& o) {
set(o.get(), o.getLength());
}
SockAddr(SockAddr&& o) noexcept : len(o.len), addr(std::move(o.addr)) {
SockAddr(SockAddr&& o) noexcept : addr(std::move(o.addr)), len(o.len) {
o.len = 0;
}
@@ -119,7 +119,7 @@ public:
/**
* Returns the address family or AF_UNSPEC if the address is not set.
*/
sa_family_t getFamily() const { return len > sizeof(sa_family_t) ? addr->sa_family : AF_UNSPEC; }
sa_family_t getFamily() const { return len ? addr->sa_family : AF_UNSPEC; }
/**
* Resize the managed structure to the appropriate size (if needed),
@@ -248,7 +248,8 @@ public:
bool isUnspecified() const;
bool isMappedIPv4() const;
SockAddr getMappedIPv4() const;
SockAddr getMappedIPv4();
SockAddr getMappedIPv6();
/**
* A comparator to classify IP addresses, only considering the
@@ -279,9 +280,9 @@ public:
}
};
private:
socklen_t len {0};
struct free_delete { void operator()(void* p) { ::free(p); } };
std::unique_ptr<sockaddr, free_delete> addr {};
socklen_t len {0};
void set(const sockaddr* sa, socklen_t length) {
if (len != length) {
@@ -19,6 +19,8 @@
#pragma once
#include "def.h"
#include <condition_variable>
#include <vector>
#include <queue>
@@ -27,7 +29,7 @@
namespace dht {
class ThreadPool {
class OPENDHT_PUBLIC ThreadPool {
public:
static ThreadPool& computation();
static ThreadPool& io();
@@ -47,8 +49,8 @@ public:
return ret->get_future();
}
template<class T>
std::shared_ptr<std::future<T>> getShared(std::function<T()>&& cb) {
return std::make_shared<std::future<T>>(get(std::move(cb)));
std::shared_future<T> getShared(std::function<T()>&& cb) {
return get(std::move(cb));
}
void stop();
@@ -66,4 +68,23 @@ private:
bool running_ {true};
};
class OPENDHT_PUBLIC Executor : public std::enable_shared_from_this<Executor> {
public:
Executor(ThreadPool& pool, unsigned maxConcurrent = 1)
: threadPool_(pool), maxConcurrent_(maxConcurrent)
{}
void run(std::function<void()>&& task);
private:
std::reference_wrapper<ThreadPool> threadPool_;
const unsigned maxConcurrent_ {1};
std::mutex lock_ {};
unsigned current_ {0};
std::queue<std::function<void()>> tasks_ {};
void run_(std::function<void()>&& task);
void schedule();
};
}
+12
View File
@@ -92,6 +92,18 @@ print_dt(DT d) {
return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
}
template <class DT>
static std::string
print_duration(DT d) {
if (d < std::chrono::milliseconds(1)) {
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) + " us";
} else if (d < std::chrono::seconds(1)) {
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) + " ms";
} else {
return std::to_string(print_dt(d)) + " s";
}
}
template <typename Duration = duration>
class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> {
using Base = std::uniform_int_distribution<typename Duration::rep>;
+6 -4
View File
@@ -28,8 +28,8 @@ libopendht_la_SOURCES = \
default_types.cpp \
log.cpp \
peer_discovery.cpp \
network_utils.h \
network_utils.cpp
network_utils.cpp \
thread_pool.cpp
if WIN32
libopendht_la_SOURCES += rng.cpp
@@ -57,10 +57,12 @@ nobase_include_HEADERS = \
../include/opendht/log.h \
../include/opendht/log_enable.h \
../include/opendht/peer_discovery.h \
../include/opendht/rng.h
../include/opendht/network_utils.h \
../include/opendht/rng.h \
../include/opendht/thread_pool.h
if ENABLE_PROXY_SERVER
libopendht_la_SOURCES += dht_proxy_server.cpp thread_pool.h thread_pool.cpp
libopendht_la_SOURCES += dht_proxy_server.cpp
nobase_include_HEADERS += ../include/opendht/dht_proxy_server.h
endif
+16
View File
@@ -31,6 +31,7 @@ extern "C" {
#include <random>
#include <sstream>
#include <fstream>
#include <stdexcept>
#include <cassert>
@@ -1043,6 +1044,21 @@ generateEcIdentity(const std::string& name, const Identity& ca) {
return generateEcIdentity(name, ca, !ca.first || !ca.second);
}
void
saveIdentity(const Identity& id, const std::string& path, const std::string& privkey_password)
{
{
auto ca_key_data = id.first->serialize(privkey_password);
std::ofstream key_file(path + ".pem");
key_file.write((char*)ca_key_data.data(), ca_key_data.size());
}
{
auto ca_key_data = id.second->getPacked();
std::ofstream crt_file(path + ".crt");
crt_file.write((char*)ca_key_data.data(), ca_key_data.size());
}
}
void
setValidityPeriod(gnutls_x509_crt_t cert, int64_t validity)
{
+14 -15
View File
@@ -1689,11 +1689,11 @@ Dht::~Dht()
s.second->clear();
}
Dht::Dht() : store(), network_engine(DHT_LOG, scheduler) {}
Dht::Dht() : store(), network_engine(DHT_LOG, scheduler, {}) {}
Dht::Dht(const int& s, const int& s6, const Config& config)
: myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
network_engine(myid, config.network, s, s6, DHT_LOG, scheduler,
Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l)
: DhtInterface(l), myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
network_engine(myid, config.network, std::move(sock), DHT_LOG, scheduler,
std::bind(&Dht::onError, this, _1, _2),
std::bind(&Dht::onNewNode, this, _1, _2),
std::bind(&Dht::onReportedAddr, this, _1, _2),
@@ -1708,13 +1708,14 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
maintain_storage(config.maintain_storage)
{
scheduler.syncTime();
if (s < 0 && s6 < 0)
return;
if (s >= 0) {
auto s = network_engine.getSocket();
if (not s or (not s->hasIPv4() and not s->hasIPv6()))
throw DhtException("Opened socket required");
if (s->hasIPv4()) {
buckets4 = {Bucket {AF_INET}};
buckets4.is_client = config.is_bootstrap;
}
if (s6 >= 0) {
if (s->hasIPv6()) {
buckets6 = {Bucket {AF_INET6}};
buckets6.is_client = config.is_bootstrap;
}
@@ -1722,9 +1723,7 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
search_id = std::uniform_int_distribution<decltype(search_id)>{}(rd);
uniform_duration_distribution<> time_dis {std::chrono::seconds(3), std::chrono::seconds(5)};
auto confirm_nodes_time = scheduler.time() + time_dis(rd);
DHT_LOG.d(myid, "Scheduling %s", myid.toString().c_str());
nextNodesConfirmation = scheduler.add(confirm_nodes_time, std::bind(&Dht::confirmNodes, this));
nextNodesConfirmation = scheduler.add(scheduler.time() + time_dis(rd), std::bind(&Dht::confirmNodes, this));
// Fill old secret
{
@@ -1735,7 +1734,7 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
expire();
DHT_LOG.d("DHT initialised with node ID %s", myid.toString().c_str());
DHT_LOG.d("DHT node initialised with ID %s", myid.toString().c_str());
if (not persistPath.empty())
loadState(persistPath);
@@ -1902,14 +1901,14 @@ Dht::maintainStorage(decltype(store)::value_type& storage, bool force, const Don
}
time_point
Dht::periodic(const uint8_t *buf, size_t buflen, const SockAddr& from)
Dht::periodic(const uint8_t *buf, size_t buflen, SockAddr from)
{
scheduler.syncTime();
if (buflen) {
try {
network_engine.processMessage(buf, buflen, from);
network_engine.processMessage(buf, buflen, std::move(from));
} catch (const std::exception& e) {
DHT_LOG.e("Can't process message from %s: %s", from.toString().c_str(), e.what());
DHT_LOG.e("Can't process message: %s", e.what());
}
}
return scheduler.run();
+131 -76
View File
@@ -45,14 +45,13 @@ struct DhtProxyClient::Listener
{
OpValueCache cache;
ValueCallback cb;
Value::Filter filter;
Sp<restbed::Request> req;
std::thread thread;
unsigned callbackId;
Sp<ListenState> state;
Sp<Scheduler::Job> refreshJob;
Listener(OpValueCache&& c, const Sp<restbed::Request>& r, Value::Filter&& f)
: cache(std::move(c)), filter(std::move(f)),req(r) {}
Listener(OpValueCache&& c, const Sp<restbed::Request>& r)
: cache(std::move(c)), req(r) {}
};
struct PermanentPut {
@@ -72,8 +71,8 @@ struct DhtProxyClient::ProxySearch {
DhtProxyClient::DhtProxyClient() {}
DhtProxyClient::DhtProxyClient(std::function<void()> signal, const std::string& serverHost, const std::string& pushClientId)
: serverHost_(serverHost), pushClientId_(pushClientId), loopSignal_(signal)
DhtProxyClient::DhtProxyClient(std::function<void()> signal, const std::string& serverHost, const std::string& pushClientId, const Logger& l)
: DhtInterface(l), serverHost_(serverHost), pushClientId_(pushClientId), loopSignal_(signal)
{
if (serverHost_.find("://") == std::string::npos)
serverHost_ = proxy::HTTP_PROTO + serverHost_;
@@ -135,7 +134,14 @@ DhtProxyClient::cancelAllOperations()
while (operation != operations_.end()) {
if (operation->thread.joinable()) {
// Close connection to stop operation?
restbed::Http::close(operation->req);
if (operation->req) {
try {
restbed::Http::close(operation->req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
operation->req.reset();
}
operation->thread.join();
operation = operations_.erase(operation);
} else {
@@ -157,8 +163,14 @@ DhtProxyClient::cancelAllListeners()
if (l->second.thread.joinable()) {
// Close connection to stop listener?
l->second.state->cancel = true;
if (l->second.req)
restbed::Http::close(l->second.req);
if (l->second.req) {
try {
restbed::Http::close(l->second.req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
l->second.req.reset();
}
l->second.thread.join();
}
s.second.listeners.erase(token);
@@ -206,16 +218,19 @@ DhtProxyClient::isRunning(sa_family_t af) const
}
time_point
DhtProxyClient::periodic(const uint8_t*, size_t, const SockAddr&)
DhtProxyClient::periodic(const uint8_t*, size_t, SockAddr)
{
// Exec all currently stored callbacks
scheduler.syncTime();
if (!callbacks_.empty()) {
decltype(callbacks_) callbacks;
{
std::lock_guard<std::mutex> lock(lockCallbacks);
for (auto& callback : callbacks_)
callback();
callbacks_.clear();
callbacks = std::move(callbacks_);
}
for (auto& callback : callbacks)
callback();
callbacks.clear();
// Remove finished operations
{
std::lock_guard<std::mutex> lock(lockOperations_);
@@ -224,7 +239,14 @@ DhtProxyClient::periodic(const uint8_t*, size_t, const SockAddr&)
if (*(operation->finished)) {
if (operation->thread.joinable()) {
// Close connection to stop operation?
restbed::Http::close(operation->req);
if (operation->req) {
try {
restbed::Http::close(operation->req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
operation->req.reset();
}
operation->thread.join();
}
operation = operations_.erase(operation);
@@ -277,11 +299,13 @@ DhtProxyClient::get(const InfoHash& key, GetCallback cb, DoneCallback donecb, Va
if (reader->parse(char_data, char_data + body.size(), &json, &err)) {
auto value = std::make_shared<Value>(json);
if ((not filter or filter(*value)) and cb) {
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([cb, value, state]() {
if (not state->stop and not cb({value}))
state->stop = true;
});
{
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([cb, value, state]() {
if (not state->stop and not cb({value}))
state->stop = true;
});
}
loopSignal_();
}
} else {
@@ -297,11 +321,13 @@ DhtProxyClient::get(const InfoHash& key, GetCallback cb, DoneCallback donecb, Va
state->ok = false;
}
if (donecb) {
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([=](){
donecb(state->ok, {});
state->stop = true;
});
{
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([=](){
donecb(state->ok, {});
state->stop = true;
});
}
loopSignal_();
}
if (!state->ok) {
@@ -423,10 +449,12 @@ DhtProxyClient::doPut(const InfoHash& key, Sp<Value> val, DoneCallback cb, time_
*ok = false;
}
if (cb) {
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([=](){
cb(*ok, {});
});
{
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([=](){
cb(*ok, {});
});
}
loopSignal_();
}
if (!ok) {
@@ -661,11 +689,12 @@ size_t
DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filter, Where where) {
DHT_LOG.d(key, "[search %s]: listen", key.to_c_str());
auto& search = searches_[key];
auto query = std::make_shared<Query>(Select{}, where);
auto token = search.ops.listen(cb, query, filter, [this, key, filter](Sp<Query> /*q*/, ValueCallback cb, SyncCallback /*scb*/) -> size_t {
auto query = std::make_shared<Query>(Select{}, std::move(where));
auto token = search.ops.listen(cb, query, filter, [this, key](Sp<Query> /*q*/, ValueCallback cb, SyncCallback /*scb*/) -> size_t {
scheduler.syncTime();
restbed::Uri uri(serverHost_ + "/" + key.toString());
std::lock_guard<std::mutex> lock(searchLock_);
// Find search
auto search = searches_.find(key);
if (search == searches_.end()) {
DHT_LOG.e(key, "[search %s] listen: search not found", key.to_c_str());
@@ -673,19 +702,21 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
}
DHT_LOG.d(key, "[search %s] sending %s", key.to_c_str(), deviceKey_.empty() ? "listen" : "subscribe");
// Add listener
auto req = std::make_shared<restbed::Request>(uri);
auto token = ++listenerToken_;
auto l = search->second.listeners.find(token);
if (l == search->second.listeners.end()) {
auto f = filter;
l = search->second.listeners.emplace(std::piecewise_construct,
std::forward_as_tuple(token),
std::forward_as_tuple(std::move(cb), req, std::move(f))).first;
std::forward_as_tuple(std::move(cb), req)).first;
} else {
if (l->second.state)
l->second.state->cancel = true;
l->second.req = req;
}
// Add callback
auto state = std::make_shared<ListenState>();
l->second.state = state;
l->second.cb = [this,key,token,state](const std::vector<Sp<Value>>& values, bool expired) {
@@ -693,18 +724,16 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
return false;
std::lock_guard<std::mutex> lock(searchLock_);
auto s = searches_.find(key);
if (s == searches_.end()) {
return false;
if (s != searches_.end()) {
auto l = s->second.listeners.find(token);
if (l != s->second.listeners.end()) {
return l->second.cache.onValue(values, expired);
}
}
auto l = s->second.listeners.find(token);
if (l == s->second.listeners.end()) {
return false;
}
return l->second.cache.onValue(values, expired);
return false;
};
auto vcb = l->second.cb;
l->second.req = req;
if (not deviceKey_.empty()) {
// Relaunch push listeners even if a timeout is not received (if the proxy crash for any reason)
@@ -721,8 +750,10 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
}
});
}
l->second.thread = std::thread([this, req, vcb, filter, state]() {
sendListen(req, vcb, filter, state,
// Send listen to servers
l->second.thread = std::thread([this, req, vcb, state]() {
sendListen(req, vcb, state,
deviceKey_.empty() ? ListenMethod::LISTEN : ListenMethod::SUBSCRIBE);
});
return token;
@@ -759,7 +790,6 @@ DhtProxyClient::cancelListen(const InfoHash& key, size_t gtoken) {
void DhtProxyClient::sendListen(const std::shared_ptr<restbed::Request> &req,
const ValueCallback &cb,
const Value::Filter &filter,
const Sp<ListenState> &state,
ListenMethod method) {
auto settings = std::make_shared<restbed::Settings>();
@@ -776,7 +806,7 @@ void DhtProxyClient::sendListen(const std::shared_ptr<restbed::Request> &req,
fillBody(req, method == ListenMethod::RESUBSCRIBE);
#endif
restbed::Http::async(req,
[this, filter, cb, state](const std::shared_ptr<restbed::Request>& req,
[this, cb, state](const std::shared_ptr<restbed::Request>& req,
const std::shared_ptr<restbed::Response>& reply)
{
auto code = reply->get_status_code();
@@ -801,12 +831,14 @@ void DhtProxyClient::sendListen(const std::shared_ptr<restbed::Request> &req,
}
auto expired = json.get("expired", Json::Value(false)).asBool();
auto value = std::make_shared<Value>(json);
if ((not filter or filter(*value)) and cb) {
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([cb, value, state, expired]() {
if (not state->cancel and not cb({value}, expired))
state->cancel = true;
});
if (cb) {
{
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([cb, value, state, expired]() {
if (not state->cancel and not cb({value}, expired))
state->cancel = true;
});
}
loopSignal_();
}
}
@@ -875,8 +907,14 @@ DhtProxyClient::doCancelListen(const InfoHash& key, size_t ltoken)
// Just stop the request
if (listener.thread.joinable()) {
// Close connection to stop listener
if (listener.req)
restbed::Http::close(listener.req);
if (listener.req) {
try {
restbed::Http::close(listener.req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
listener.req.reset();
}
listener.thread.join();
}
}
@@ -936,27 +974,38 @@ DhtProxyClient::restartListeners()
return;
}
DHT_LOG.d("Restarting listeners");
for (auto& search: searches_) {
for (auto& l: search.second.listeners) {
auto& listener = l.second;
if (auto state = listener.state)
state->cancel = true;
if (listener.req) {
try {
restbed::Http::close(listener.req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
listener.req.reset();
}
}
}
for (auto& search: searches_) {
for (auto& l: search.second.listeners) {
auto& listener = l.second;
auto state = listener.state;
if (listener.thread.joinable()) {
state->cancel = true;
if (listener.req)
restbed::Http::close(listener.req);
listener.thread.join();
}
// Redo listen
state->cancel = false;
state->ok = true;
auto filter = listener.filter;
auto cb = listener.cb;
restbed::Uri uri(serverHost_ + "/" + search.first.toString());
auto req = std::make_shared<restbed::Request>(uri);
req->set_method("LISTEN");
listener.req = req;
listener.thread = std::thread([this, req, cb, filter, state]() {
sendListen(req, cb, filter, state);
listener.thread = std::thread([this, req, cb, state]() {
sendListen(req, cb, state);
});
}
}
@@ -1003,14 +1052,13 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
auto state = list.second.state;
if (expired == notification.end()) {
auto cb = list.second.cb;
auto filter = list.second.filter;
auto oldValues = list.second.cache.getValues();
get(key, [cb](const std::vector<Sp<Value>>& vals) {
return cb(vals, false);
}, [cb, oldValues](bool /*ok*/) {
// Decrement old values refcount to expire values not present in the new list
cb(oldValues, true);
}, std::move(filter));
});
} else {
std::stringstream ss(expired->second);
std::vector<Value::Id> ids;
@@ -1019,17 +1067,19 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
getline(ss, substr, ',');
ids.emplace_back(std::stoull(substr));
}
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([this, key, token, state, ids]() {
if (state->cancel) return;
std::lock_guard<std::mutex> lock(searchLock_);
auto s = searches_.find(key);
if (s == searches_.end()) return;
auto l = s->second.listeners.find(token);
if (l == s->second.listeners.end()) return;
if (not state->cancel and not l->second.cache.onValuesExpired(ids))
state->cancel = true;
});
{
std::lock_guard<std::mutex> lock(lockCallbacks);
callbacks_.emplace_back([this, key, token, state, ids]() {
if (state->cancel) return;
std::lock_guard<std::mutex> lock(searchLock_);
auto s = searches_.find(key);
if (s == searches_.end()) return;
auto l = s->second.listeners.find(token);
if (l == s->second.listeners.end()) return;
if (not state->cancel and not l->second.cache.onValuesExpired(ids))
state->cancel = true;
});
}
loopSignal_();
}
}
@@ -1053,8 +1103,14 @@ DhtProxyClient::resubscribe(const InfoHash& key, Listener& listener)
auto state = listener.state;
if (listener.thread.joinable()) {
state->cancel = true;
if (listener.req)
restbed::Http::close(listener.req);
if (listener.req) {
try {
restbed::Http::close(listener.req);
} catch (const std::exception& e) {
DHT_LOG.w("Error closing socket: %s", e.what());
}
listener.req.reset();
}
listener.thread.join();
}
state->cancel = false;
@@ -1064,9 +1120,8 @@ DhtProxyClient::resubscribe(const InfoHash& key, Listener& listener)
listener.req = req;
scheduler.edit(listener.refreshJob, scheduler.time() + proxy::OP_TIMEOUT - proxy::OP_MARGIN);
auto vcb = listener.cb;
auto filter = listener.filter;
listener.thread = std::thread([this, req, vcb, filter, state]() {
sendListen(req, vcb, filter, state, ListenMethod::RESUBSCRIBE);
listener.thread = std::thread([this, req, vcb, state]() {
sendListen(req, vcb, state, ListenMethod::RESUBSCRIBE);
});
#else
(void) key;
+1 -1
View File
@@ -669,7 +669,6 @@ DhtProxyServer::put(const std::shared_ptr<restbed::Session>& session)
clientId = pVal["client_id"].asString();
platform = pVal["platform"].asString();
}
bool isAndroid = platform == "android";
std::unique_lock<std::mutex> lock(schedulerLock_);
scheduler_.syncTime();
auto timeout = scheduler_.time() + proxy::OP_TIMEOUT;
@@ -684,6 +683,7 @@ DhtProxyServer::put(const std::shared_ptr<restbed::Session>& session)
});
#ifdef OPENDHT_PUSH_NOTIFICATIONS
if (not pushToken.empty()) {
bool isAndroid = platform == "android";
pput.expireNotifyJob = scheduler_.add(timeout - proxy::OP_MARGIN,
[this, infoHash, vid, pushToken, clientId, isAndroid]
{
+147 -215
View File
@@ -37,7 +37,8 @@ namespace dht {
constexpr std::chrono::seconds DhtRunner::BOOTSTRAP_PERIOD;
static constexpr size_t RX_QUEUE_MAX_SIZE = 1024 * 16;
static constexpr in_port_t PEER_DISCOVERY_PORT = 8888;
static constexpr std::chrono::milliseconds RX_QUEUE_MAX_DELAY(500);
static const std::string PEER_DISCOVERY_DHT_SERVICE = "dht";
struct DhtRunner::Listener {
size_t tokenClassicDht {0};
@@ -48,6 +49,13 @@ struct DhtRunner::Listener {
Where w;
};
struct NodeInsertionPack {
dht::InfoHash nodeId;
in_port_t port;
dht::NetId net;
MSGPACK_DEFINE(nodeId, port, net)
};
DhtRunner::DhtRunner() : dht_()
#ifdef OPENDHT_PROXY_CLIENT
, dht_via_proxy_()
@@ -69,7 +77,7 @@ DhtRunner::~DhtRunner()
}
void
DhtRunner::run(in_port_t port, const DhtRunner::Config& config)
DhtRunner::run(in_port_t port, const Config& config, Context&& context)
{
SockAddr sin4;
sin4.setFamily(AF_INET);
@@ -77,45 +85,73 @@ DhtRunner::run(in_port_t port, const DhtRunner::Config& config)
SockAddr sin6;
sin6.setFamily(AF_INET6);
sin6.setPort(port);
run(sin4, sin6, config);
run(sin4, sin6, config, std::move(context));
}
void
DhtRunner::run(const char* ip4, const char* ip6, const char* service, const DhtRunner::Config& config)
DhtRunner::run(const char* ip4, const char* ip6, const char* service, const Config& config, Context&& context)
{
auto res4 = SockAddr::resolve(ip4, service);
auto res6 = SockAddr::resolve(ip6, service);
run(res4.empty() ? SockAddr() : res4.front(),
res6.empty() ? SockAddr() : res6.front(), config);
res6.empty() ? SockAddr() : res6.front(), config, std::move(context));
}
void
DhtRunner::run(const SockAddr& local4, const SockAddr& local6, const DhtRunner::Config& config)
DhtRunner::run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context)
{
if (not running) {
if (not context.sock)
context.sock.reset(new net::UdpSocket(local4, local6, context.logger ? *context.logger : Logger{}));
run(config, std::move(context));
}
}
void
DhtRunner::run(const Config& config, Context&& context)
{
std::lock_guard<std::mutex> lck(dht_mtx);
if (running)
return;
startNetwork(local4, local6);
auto dht = std::unique_ptr<DhtInterface>(new Dht(s4, s6, SecureDht::getConfig(config.dht_config)));
context.sock->setOnReceive([&] (std::unique_ptr<net::ReceivedPacket>&& pkt) {
{
std::lock_guard<std::mutex> lck(sock_mtx);
if (rcv.size() >= RX_QUEUE_MAX_SIZE) {
std::cerr << "Dropping packet: queue is full!" << std::endl;
rcv.pop();
}
rcv.emplace(std::move(pkt));
}
cv.notify_all();
});
auto dht = std::unique_ptr<DhtInterface>(new Dht(std::move(context.sock), SecureDht::getConfig(config.dht_config)));
dht_ = std::unique_ptr<SecureDht>(new SecureDht(std::move(dht), config.dht_config));
#ifdef OPENDHT_PROXY_CLIENT
config_ = config;
#endif
enableProxy(not config.proxy_server.empty());
if (context.logger and dht_via_proxy_) {
dht_via_proxy_->setLogger(*context.logger);
}
if (context.statusChangedCallback) {
statusCb = std::move(context.statusChangedCallback);
}
if (context.certificateStore) {
dht_->setLocalCertificateStore(std::move(context.certificateStore));
if (dht_via_proxy_)
dht_via_proxy_->setLocalCertificateStore(std::move(context.certificateStore));
}
running = true;
if (not config.threaded)
return;
dht_thread = std::thread([this, local4, local6]() {
dht_thread = std::thread([this]() {
while (running) {
std::unique_lock<std::mutex> lk(dht_mtx);
time_point wakeup;
try {
wakeup = loop_();
} catch (const dht::SocketException& e) {
startNetwork(local4, local6);
}
time_point wakeup = loop_();
auto hasJobToDo = [this]() {
if (not running)
@@ -143,44 +179,55 @@ DhtRunner::run(const SockAddr& local4, const SockAddr& local6, const DhtRunner::
});
if (config.peer_discovery or config.peer_publish) {
try {
peerDiscovery4_.reset(new PeerDiscovery(AF_INET, PEER_DISCOVERY_PORT));
} catch(const std::exception& e){
std::cerr << "Can't start peer discovery (IPv4): " << e.what() << std::endl;
}
try {
peerDiscovery6_.reset(new PeerDiscovery(AF_INET6, PEER_DISCOVERY_PORT));
} catch(const std::exception& e) {
std::cerr << "Can't start peer discovery (IPv6): " << e.what() << std::endl;
}
peerDiscovery_ = context.peerDiscovery ?
std::move(context.peerDiscovery) :
std::make_shared<PeerDiscovery>();
}
if (config.peer_discovery) {
using sig = void (DhtRunner::*)(const InfoHash&, const SockAddr&);
if (peerDiscovery4_)
peerDiscovery4_->startDiscovery(std::bind(static_cast<sig>(&DhtRunner::bootstrap), this,
std::placeholders::_1,std::placeholders::_2));
if (peerDiscovery6_)
peerDiscovery6_->startDiscovery(std::bind(static_cast<sig>(&DhtRunner::bootstrap), this,
std::placeholders::_1,std::placeholders::_2));
auto netId = config.dht_config.node_config.network;
if (config.peer_discovery) {
peerDiscovery_->startDiscovery<NodeInsertionPack>(PEER_DISCOVERY_DHT_SERVICE, [this, netId](NodeInsertionPack&& v, SockAddr&& addr){
addr.setPort(v.port);
if (v.nodeId != dht_->getNodeId() && netId == v.net){
bootstrap(v.nodeId, addr);
}
});
}
if (config.peer_publish) {
if (peerDiscovery4_)
peerDiscovery4_->startPublish(dht_->getNodeId(), getBoundPort(AF_INET));
if (peerDiscovery6_)
peerDiscovery6_->startPublish(dht_->getNodeId(), getBoundPort(AF_INET6));
msgpack::sbuffer sbuf_node;
NodeInsertionPack adc;
adc.net = netId;
adc.nodeId = dht_->getNodeId();
// IPv4
if (auto bound4 = dht_->getSocket()->getBound(AF_INET)) {
adc.port = bound4.getPort();
msgpack::pack(sbuf_node, adc);
peerDiscovery_->startPublish(AF_INET, PEER_DISCOVERY_DHT_SERVICE, sbuf_node);
}
// IPv6
if (auto bound6 = dht_->getSocket()->getBound(AF_INET6)) {
adc.port = bound6.getPort();
sbuf_node.clear();
msgpack::pack(sbuf_node, adc);
peerDiscovery_->startPublish(AF_INET6, PEER_DISCOVERY_DHT_SERVICE, sbuf_node);
}
}
}
void
DhtRunner::shutdown(ShutdownCallback cb) {
#ifdef OPENDHT_PROXY_CLIENT
if (dht_via_proxy_)
dht_via_proxy_->shutdown(cb);
#endif
if (not running) {
cb();
return;
}
std::lock_guard<std::mutex> lck(storage_mtx);
pending_ops_prio.emplace([=](SecureDht& dht) mutable {
dht.shutdown(cb);
pending_ops_prio.emplace([=](SecureDht&) mutable {
#ifdef OPENDHT_PROXY_CLIENT
if (dht_via_proxy_)
dht_via_proxy_->shutdown(cb);
#endif
if (dht_)
dht_->shutdown(cb);
});
cv.notify_all();
}
@@ -188,22 +235,28 @@ DhtRunner::shutdown(ShutdownCallback cb) {
void
DhtRunner::join()
{
stopNetwork();
running = false;
cv.notify_all();
bootstrap_cv.notify_all();
if (peerDiscovery4_) peerDiscovery4_->stop();
if (peerDiscovery6_) peerDiscovery6_->stop();
if (peerDiscovery_)
peerDiscovery_->stop();
{
std::lock_guard<std::mutex> lck(dht_mtx);
running = false;
cv.notify_all();
bootstrap_cv.notify_all();
if (dht_)
if (auto sock = dht_->getSocket())
sock->stop();
}
if (dht_thread.joinable())
dht_thread.join();
if (bootstrap_thread.joinable())
bootstrap_thread.join();
if (rcv_thread.joinable())
rcv_thread.join();
if (peerDiscovery4_) peerDiscovery4_->join();
if (peerDiscovery6_) peerDiscovery6_->join();
if (peerDiscovery_) {
peerDiscovery_->join();
}
{
std::lock_guard<std::mutex> lck(storage_mtx);
@@ -218,6 +271,15 @@ DhtRunner::join()
}
}
SockAddr
DhtRunner::getBound(sa_family_t af) const {
std::lock_guard<std::mutex> lck(dht_mtx);
if (dht_)
if (auto sock = dht_->getSocket())
return sock->getBound(af);
return SockAddr{};
}
void
DhtRunner::dumpTables() const
{
@@ -275,16 +337,22 @@ DhtRunner::exportValues() const {
}
void
DhtRunner::setLoggers(LogMethod error, LogMethod warn, LogMethod debug) {
DhtRunner::setLogger(const Logger& logger) {
std::lock_guard<std::mutex> lck(dht_mtx);
if (dht_)
dht_->setLoggers(error, warn, debug);
dht_->setLogger(logger);
#ifdef OPENDHT_PROXY_CLIENT
if (dht_via_proxy_)
dht_via_proxy_->setLoggers(error, warn, debug);
dht_via_proxy_->setLogger(logger);
#endif
}
void
DhtRunner::setLoggers(LogMethod error, LogMethod warn, LogMethod debug) {
Logger logger {std::move(error), std::move(warn), std::move(debug)};
setLogger(logger);
}
void
DhtRunner::setLogFilter(const InfoHash& f) {
std::lock_guard<std::mutex> lck(dht_mtx);
@@ -439,20 +507,35 @@ DhtRunner::loop_()
// move to stack
received = std::move(rcv);
}
// Discard old packets
size_t dropped {0};
if (not received.empty()) {
auto now = clock::now();
while (not received.empty() and now - received.front()->received > RX_QUEUE_MAX_DELAY) {
received.pop();
dropped++;
}
}
// Handle packets
if (not received.empty()) {
while (not received.empty()) {
auto& pck = received.front();
auto delay = clock::now() - pck.received;
if (delay > std::chrono::milliseconds(500))
std::cerr << "Dropping packet with high delay: " << print_dt(delay) << std::endl;
if (clock::now() - pck->received > RX_QUEUE_MAX_DELAY)
dropped++;
else
wakeup = dht->periodic(pck.data.data(), pck.data.size()-1, pck.from);
wakeup = dht->periodic(pck->data.data(), pck->data.size(), std::move(pck->from));
received.pop();
}
} else {
// Or just run the scheduler
wakeup = dht->periodic(nullptr, 0, nullptr, 0);
}
if (dropped)
std::cerr << "Dropped " << dropped << " packets with high delay" << std::endl;
NodeStatus nstatus4 = dht->getStatus(AF_INET);
NodeStatus nstatus6 = dht->getStatus(AF_INET6);
if (nstatus4 != status4 || nstatus6 != status6) {
@@ -474,159 +557,6 @@ DhtRunner::loop_()
return wakeup;
}
int bindSocket(const SockAddr& addr, SockAddr& bound)
{
bool is_ipv6 = addr.getFamily() == AF_INET6;
int sock = socket(is_ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
if (sock < 0)
throw DhtException(std::string("Can't open socket: ") + strerror(sock));
int set = 1;
#ifdef SO_NOSIGPIPE
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&set, sizeof(set));
#endif
if (is_ipv6)
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&set, sizeof(set));
net::set_nonblocking(sock);
int rc = bind(sock, addr.get(), addr.getLength());
if(rc < 0) {
rc = errno;
close(sock);
throw DhtException("Can't bind socket on " + addr.toString() + " " + strerror(rc));
}
sockaddr_storage ss;
socklen_t ss_len = sizeof(ss);
getsockname(sock, (sockaddr*)&ss, &ss_len);
bound = {ss, ss_len};
return sock;
}
void
DhtRunner::stopNetwork()
{
running_network = false;
if (stop_writefd != -1) {
if (write(stop_writefd, "\0", 1) == -1) {
perror("write");
}
}
}
void
DhtRunner::startNetwork(const SockAddr sin4, const SockAddr sin6)
{
stopNetwork();
if (rcv_thread.joinable())
rcv_thread.join();
int stopfds[2];
#ifndef _WIN32
auto status = pipe(stopfds);
if (status == -1) {
throw DhtException(std::string("Can't open pipe: ") + strerror(errno));
}
#else
net::udpPipe(stopfds);
#endif
int stop_readfd = stopfds[0];
stop_writefd = stopfds[1];
s4 = -1;
s6 = -1;
bound4 = {};
if (sin4) {
try {
s4 = bindSocket(sin4, bound4);
} catch (const DhtException& e) {
std::cerr << "Can't bind inet socket: " << e.what() << std::endl;
}
}
#if 1
bound6 = {};
if (sin6) {
try {
s6 = bindSocket(sin6, bound6);
} catch (const DhtException& e) {
std::cerr << "Can't bind inet6 socket: " << e.what() << std::endl;
}
}
#endif
if (s4 == -1 && s6 == -1) {
throw DhtException("Can't bind socket");
}
running_network = true;
rcv_thread = std::thread([this, stop_readfd]() {
try {
while (running_network) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(stop_readfd, &readfds);
if(s4 >= 0)
FD_SET(s4, &readfds);
if(s6 >= 0)
FD_SET(s6, &readfds);
int selectFd = std::max({s4, s6, stop_readfd}) + 1;
int rc = select(selectFd, &readfds, nullptr, nullptr, nullptr);
if(rc < 0) {
if(errno != EINTR) {
perror("select");
std::this_thread::sleep_for( std::chrono::seconds(1) );
}
}
if (not running_network)
break;
if(rc > 0) {
std::array<uint8_t, 1024 * 64> buf;
sockaddr_storage from;
socklen_t from_len = sizeof(from);
if(s4 >= 0 && FD_ISSET(s4, &readfds))
rc = recvfrom(s4, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
else if(s6 >= 0 && FD_ISSET(s6, &readfds))
rc = recvfrom(s6, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
else
continue;
if (rc > 0) {
{
std::lock_guard<std::mutex> lck(sock_mtx);
if (rcv.size() >= RX_QUEUE_MAX_SIZE) {
std::cerr << "Dropping packet: queue is full!" << std::endl;
rcv.pop();
}
rcv.emplace(ReceivedPacket {Blob {buf.begin(), buf.begin()+rc+1}, SockAddr(from, from_len), clock::now()});
}
cv.notify_all();
}
}
}
} catch (const std::exception& e) {
std::cerr << "Error in DHT networking thread: " << e.what() << std::endl;
}
if (s4 >= 0)
close(s4);
if (s6 >= 0)
close(s6);
s4 = -1;
s6 = -1;
bound4 = {};
bound6 = {};
if (stop_readfd != -1)
close(stop_readfd);
if (stop_writefd != -1)
close(stop_writefd);
stop_writefd = -1;
});
}
void
DhtRunner::get(InfoHash hash, GetCallback vcb, DoneCallback dcb, Value::Filter f, Where w)
{
@@ -988,8 +918,7 @@ DhtRunner::findCertificate(InfoHash hash, std::function<void(const std::shared_p
void
DhtRunner::resetDht()
{
peerDiscovery4_.reset();
peerDiscovery6_.reset();
peerDiscovery_.reset();
#ifdef OPENDHT_PROXY_CLIENT
listeners_.clear();
dht_via_proxy_.reset();
@@ -1011,6 +940,7 @@ void
DhtRunner::setProxyServer(const std::string& proxy, const std::string& pushNodeId)
{
#ifdef OPENDHT_PROXY_CLIENT
std::lock_guard<std::mutex> lck(dht_mtx);
if (config_.proxy_server == proxy and config_.push_node_id == pushNodeId)
return;
config_.proxy_server = proxy;
@@ -1076,6 +1006,7 @@ DhtRunner::enableProxy(bool proxify)
void
DhtRunner::forwardAllMessages(bool forward)
{
std::lock_guard<std::mutex> lck(dht_mtx);
#ifdef OPENDHT_PROXY_SERVER
#ifdef OPENDHT_PROXY_CLIENT
if (dht_via_proxy_)
@@ -1093,6 +1024,7 @@ DhtRunner::forwardAllMessages(bool forward)
*/
void
DhtRunner::setPushNotificationToken(const std::string& token) {
std::lock_guard<std::mutex> lck(dht_mtx);
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
pushToken_ = token;
if (dht_via_proxy_)
+31 -14
View File
@@ -55,9 +55,9 @@ printLog(std::ostream& s, char const *m, va_list args) {
s << std::endl;
}
void
enableLogging(dht::DhtRunner &dht) {
dht.setLoggers(
std::unique_ptr<Logger>
getStdLogger() {
return std::unique_ptr<Logger>(new Logger(
[](char const *m, va_list args) {
std::cerr << red;
printLog(std::cerr, m, args);
@@ -69,23 +69,23 @@ enableLogging(dht::DhtRunner &dht) {
std::cout << def;
},
[](char const *m, va_list args) { printLog(std::cout, m, args); }
);
));
}
void
enableFileLogging(dht::DhtRunner &dht, const std::string &path) {
auto logfile = std::make_shared<std::fstream>();
std::unique_ptr<Logger>
getFileLogger(const std::string &path) {
auto logfile = std::make_shared<std::ofstream>();
logfile->open(path, std::ios::out);
dht.setLoggers(
return std::unique_ptr<Logger>(new Logger(
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
[=](char const *m, va_list args) { printLog(*logfile, m, args); }
);
));
}
OPENDHT_PUBLIC void
enableSyslog(dht::DhtRunner &dht, const char* name) {
std::unique_ptr<Logger>
getSyslogLogger(const char* name) {
#ifndef _WIN32
struct Syslog {
Syslog(const char* n) {
@@ -102,17 +102,34 @@ enableSyslog(dht::DhtRunner &dht, const char* name) {
logfile = std::make_shared<Syslog>(name);
opened_logfile = logfile;
}
dht.setLoggers(
return std::unique_ptr<Logger>(new Logger(
[logfile](char const *m, va_list args) { vsyslog(LOG_ERR, m, args); },
[logfile](char const *m, va_list args) { vsyslog(LOG_WARNING, m, args); },
[logfile](char const *m, va_list args) { vsyslog(LOG_INFO, m, args); }
);
));
#else
return std::unique_ptr<Logger>(new Logger());
#endif
}
void
enableLogging(dht::DhtRunner &dht) {
dht.setLogger(*getStdLogger());
}
void
enableFileLogging(dht::DhtRunner &dht, const std::string &path) {
dht.setLogger(*getFileLogger(path));
}
OPENDHT_PUBLIC void
enableSyslog(dht::DhtRunner &dht, const char* name) {
dht.setLogger(*getSyslogLogger(name));
}
void
disableLogging(dht::DhtRunner &dht) {
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
dht.setLogger({});
}
}
+24 -51
View File
@@ -43,9 +43,7 @@ constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
const std::string NetworkEngine::my_v {"RNG1"};
constexpr size_t NetworkEngine::MAX_REQUESTS_PER_SEC;
static constexpr uint8_t v4prefix[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
};
static constexpr uint8_t v4prefix[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
constexpr unsigned SEND_NODES {8};
@@ -101,11 +99,11 @@ RequestAnswer::RequestAnswer(ParsedMessage&& msg)
nodes6(std::move(msg.nodes6))
{}
NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, const int& s, const int& s6)
: myid(zeroes), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock)
: myid(zeroes), dht_socket(std::move(sock)), DHT_LOG(log), scheduler(scheduler)
{}
NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
decltype(NetworkEngine::onError)&& onError,
decltype(NetworkEngine::onNewNode)&& onNewNode,
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
@@ -124,7 +122,7 @@ NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, const int& s, const int&
onListen(std::move(onListen)),
onAnnounce(std::move(onAnnounce)),
onRefresh(std::move(onRefresh)),
myid(myid), network(net), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
myid(myid), network(net), dht_socket(std::move(sock)), DHT_LOG(log), scheduler(scheduler)
{}
NetworkEngine::~NetworkEngine() {
@@ -172,7 +170,7 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
}
// send response
send(buffer.data(), buffer.size(), 0, n->getAddr());
send(n->getAddr(), buffer.data(), buffer.size());
}
void
@@ -202,7 +200,7 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
}
// send response
send(buffer.data(), buffer.size(), 0, n->getAddr());
send(n->getAddr(), buffer.data(), buffer.size());
}
@@ -211,11 +209,11 @@ NetworkEngine::isRunning(sa_family_t af) const
{
switch (af) {
case 0:
return dht_socket >= 0 || dht_socket6 >= 0;
return dht_socket->hasIPv4() or dht_socket->hasIPv6();
case AF_INET:
return dht_socket >= 0;
return dht_socket->hasIPv4();
case AF_INET6:
return dht_socket6 >= 0;
return dht_socket->hasIPv6();
default:
return false;
}
@@ -256,9 +254,7 @@ NetworkEngine::requestStep(Sp<Request> sreq)
req.on_expired(req, false);
}
auto err = send((char*)req.msg.data(), req.msg.size(),
(node.getReplyTime() >= now - UDP_REPLY_TIME) ? 0 : MSG_CONFIRM,
node.getAddr());
auto err = send(node.getAddr(), (char*)req.msg.data(), req.msg.size(), node.getReplyTime() < now - UDP_REPLY_TIME);
if (err == ENETUNREACH ||
err == EHOSTUNREACH ||
err == EAFNOSUPPORT ||
@@ -288,11 +284,11 @@ NetworkEngine::requestStep(Sp<Request> sreq)
void
NetworkEngine::sendRequest(const Sp<Request>& request)
{
auto& node = request->node;
if (not node->id)
auto& node = *request->node;
if (not node.id)
requests.emplace(request->tid, request);
request->start = scheduler.time();
node->requested(request);
node.requested(request);
requestStep(request);
}
@@ -361,8 +357,9 @@ NetworkEngine::isNodeBlacklisted(const SockAddr& addr) const
}
void
NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const SockAddr& from)
NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
{
auto from = f.getMappedIPv4();
if (isMartian(from)) {
DHT_LOG.w("Received packet from martian node %s", from.toString().c_str());
return;
@@ -612,33 +609,9 @@ insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const SockAddr& addr)
}
int
NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr)
NetworkEngine::send(const SockAddr& addr, const char *buf, size_t len, bool confirmed)
{
if (not addr)
return EFAULT;
int s;
if (addr.getFamily() == AF_INET)
s = dht_socket;
else if (addr.getFamily() == AF_INET6)
s = dht_socket6;
else
s = -1;
if (s < 0)
return EAFNOSUPPORT;
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
if (sendto(s, buf, len, flags, addr.get(), addr.getLength()) == -1) {
int err = errno;
DHT_LOG.e("Can't send message to %s: %s", addr.toString().c_str(), strerror(err));
if (err == EPIPE) {
throw SocketException(EPIPE);
}
return err;
}
return 0;
return dht_socket ? dht_socket->sendTo(addr, (const uint8_t*)buf, len, confirmed) : ENOTCONN;
}
Sp<Request>
@@ -698,7 +671,7 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
pk.pack(KEY_NETID); pk.pack(network);
}
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
}
Sp<Request>
@@ -900,7 +873,7 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals
pk.pack(std::string("o")); pk.pack(start);
pk.pack(std::string("d")); pk.pack_bin(end-start);
pk.pack_bin_body((const char*)v.data()+start, end-start);
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
start = end;
} while (start != v.size());
i++;
@@ -959,7 +932,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
}
// send response
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
// send parts
if (not svals.empty())
@@ -1102,7 +1075,7 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
pk.pack(KEY_NETID); pk.pack(network);
}
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
}
Sp<Request>
@@ -1236,7 +1209,7 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid)
pk.pack(KEY_NETID); pk.pack(network);
}
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
}
void
@@ -1268,7 +1241,7 @@ NetworkEngine::sendError(const SockAddr& addr,
pk.pack(KEY_NETID); pk.pack(network);
}
send(buffer.data(), buffer.size(), 0, addr);
send(addr, buffer.data(), buffer.size());
}
void
+254 -2
View File
@@ -20,7 +20,6 @@
#ifdef _WIN32
#include "utils.h"
#include "sockaddr.h"
#include <io.h>
#include <string>
#include <cstring>
@@ -30,11 +29,40 @@
#include <fcntl.h>
#endif
#include <iostream>
namespace dht {
namespace net {
int
bindSocket(const SockAddr& addr, SockAddr& bound)
{
bool is_ipv6 = addr.getFamily() == AF_INET6;
int sock = socket(is_ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
if (sock < 0)
throw DhtException(std::string("Can't open socket: ") + strerror(sock));
int set = 1;
#ifdef SO_NOSIGPIPE
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&set, sizeof(set));
#endif
if (is_ipv6)
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&set, sizeof(set));
net::setNonblocking(sock);
int rc = bind(sock, addr.get(), addr.getLength());
if (rc < 0) {
rc = errno;
close(sock);
throw DhtException("Can't bind socket on " + addr.toString() + " " + strerror(rc));
}
sockaddr_storage ss;
socklen_t ss_len = sizeof(ss);
getsockname(sock, (sockaddr*)&ss, &ss_len);
bound = {ss, ss_len};
return sock;
}
bool
set_nonblocking(int fd, bool nonblocking)
setNonblocking(int fd, bool nonblocking)
{
#ifdef _WIN32
unsigned long mode = !!nonblocking;
@@ -77,5 +105,229 @@ void udpPipe(int fds[2])
}
#endif
UdpSocket::UdpSocket(in_port_t port, const Logger& l) : logger(l) {
SockAddr bind4;
bind4.setFamily(AF_INET);
bind4.setPort(port);
SockAddr bind6;
bind6.setFamily(AF_INET6);
bind6.setPort(port);
openSockets(bind4, bind6);
}
UdpSocket::UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const Logger& l) : logger(l)
{
openSockets(bind4, bind6);
}
UdpSocket::~UdpSocket() {
stop();
if (rcv_thread.joinable())
rcv_thread.join();
}
int
UdpSocket::sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) {
if (not dest)
return EFAULT;
int s;
switch (dest.getFamily()) {
case AF_INET: s = s4; break;
case AF_INET6: s = s6; break;
default: s = -1; break;
}
if (s < 0)
return EAFNOSUPPORT;
int flags = 0;
#ifdef MSG_CONFIRM
if (replied)
flags |= MSG_CONFIRM;
#endif
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
if (sendto(s, data, size, flags, dest.get(), dest.getLength()) == -1) {
int err = errno;
logger.d("Can't send message to %s: %s", dest.toString().c_str(), strerror(err));
if (err == EPIPE || err == ENOTCONN || err == ECONNRESET) {
auto bind4 = std::move(bound4), bind6 = std::move(bound6);
openSockets(bind4, bind6);
return sendTo(dest, data, size, false);
}
return err;
}
return 0;
}
void
UdpSocket::openSockets(const SockAddr& bind4, const SockAddr& bind6)
{
stop();
if (rcv_thread.joinable())
rcv_thread.join();
int stopfds[2];
#ifndef _WIN32
auto status = pipe(stopfds);
if (status == -1) {
throw DhtException(std::string("Can't open pipe: ") + strerror(errno));
}
#else
udpPipe(stopfds);
#endif
int stop_readfd = stopfds[0];
stopfd = stopfds[1];
s4 = -1;
s6 = -1;
bound4 = {};
if (bind4) {
try {
s4 = bindSocket(bind4, bound4);
} catch (const DhtException& e) {
logger.e("Can't bind inet socket: %s", e.what());
}
}
#if 1
bound6 = {};
if (bind6) {
if (bind6.getPort() == 0) {
// Attempt to use the same port as IPv4 with IPv6
if (auto p4 = bound4.getPort()) {
auto b6 = bind6;
b6.setPort(p4);
try {
s6 = bindSocket(b6, bound6);
} catch (const DhtException& e) {
logger.e("Can't bind inet6 socket: %s", e.what());
}
}
}
if (s6 == -1) {
try {
s6 = bindSocket(bind6, bound6);
} catch (const DhtException& e) {
logger.e("Can't bind inet6 socket: %s", e.what());
}
}
}
#endif
if (s4 == -1 && s6 == -1) {
throw DhtException("Can't bind socket");
}
running = true;
rcv_thread = std::thread([this, stop_readfd]() {
int selectFd = std::max({s4, s6, stop_readfd}) + 1;
try {
while (running) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(stop_readfd, &readfds);
if(s4 >= 0)
FD_SET(s4, &readfds);
if(s6 >= 0)
FD_SET(s6, &readfds);
int rc = select(selectFd, &readfds, nullptr, nullptr, nullptr);
if (rc < 0) {
if (errno != EINTR) {
logger.e("Select error: %s", strerror(errno));
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
if (not running)
break;
if (rc > 0) {
std::array<uint8_t, 1024 * 64> buf;
sockaddr_storage from;
socklen_t from_len = sizeof(from);
if (FD_ISSET(stop_readfd, &readfds)) {
if (recv(stop_readfd, (char*)buf.data(), buf.size(), 0) < 0) {
logger.e("Got stop packet error: %s", strerror(errno));
break;
}
}
else if (s4 >= 0 && FD_ISSET(s4, &readfds))
rc = recvfrom(s4, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
else if (s6 >= 0 && FD_ISSET(s6, &readfds))
rc = recvfrom(s6, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
else
continue;
if (rc > 0) {
auto pkt = std::unique_ptr<ReceivedPacket>(new ReceivedPacket);
pkt->data = {buf.begin(), buf.begin()+rc};
pkt->from = {from, from_len};
pkt->received = clock::now();
onReceived(std::move(pkt));
} else if (rc == -1) {
logger.e("Error receiving packet: %s", strerror(errno));
int err = errno;
if (err == EPIPE || err == ENOTCONN || err == ECONNRESET) {
if (s4 >= 0) {
close(s4);
try {
s4 = bindSocket(bound4, bound4);
} catch (const DhtException& e) {
logger.e("Can't bind inet socket: %s", e.what());
}
}
if (s6 >= 0) {
close(s6);
try {
s6 = bindSocket(bound6, bound6);
} catch (const DhtException& e) {
logger.e("Can't bind inet6 socket: %s", e.what());
}
}
if (s4 < 0 && s6 < 0)
break;
selectFd = std::max({s4, s6, stop_readfd}) + 1;
}
}
}
}
} catch (const std::exception& e) {
logger.e("Error in UdpSocket rx thread: %s", e.what());
}
if (s4 >= 0)
close(s4);
if (s6 >= 0)
close(s6);
s4 = -1;
s6 = -1;
bound4 = {};
bound6 = {};
if (stop_readfd != -1)
close(stop_readfd);
if (stopfd != -1)
close(stopfd);
stopfd = -1;
});
}
void
UdpSocket::stop()
{
if (running.exchange(false)) {
auto sfd = stopfd;
if (sfd != -1 && write(sfd, "\0", 1) == -1) {
logger.e("Can't write to stop fd");
}
}
}
}
}
+3 -6
View File
@@ -105,14 +105,11 @@ public:
void onValuesExpired(const std::vector<Sp<Value>>& vals);
bool addListener(size_t token, const ValueCallback& cb, const Sp<Query>& q, const Value::Filter& filter) {
listeners.emplace(token, LocalListener{q, filter, cb});
auto cached = cache.get(filter);
if (not cached.empty()) {
auto ret = cb(cached, false);
if (not ret)
listeners.erase(token);
return ret;
if (not cached.empty() and not cb(cached, false)) {
return false;
}
listeners.emplace(token, LocalListener{q, filter, cb});
return true;
}
+371 -111
View File
@@ -18,32 +18,145 @@
#include "peer_discovery.h"
#include "network_utils.h"
#include "utils.h"
#ifdef _WIN32
#include <Ws2tcpip.h> // needed for ip_mreq definition for multicast
#include <Windows.h>
#include <cstring>
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
#define close(x) closesocket(x)
#define write(s, b, f) send(s, b, (int)strlen(b), 0)
#else
#include <sys/types.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#ifndef IPV6_JOIN_GROUP
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
namespace dht {
constexpr char MULTICAST_ADDRESS_IPV4[10] = "224.0.0.1";
constexpr char MULTICAST_ADDRESS_IPV6[8] = "ff05::2"; // Site-local multicast
// Organization-local Scope multicast
constexpr char MULTICAST_ADDRESS_IPV4[12] = "239.192.0.1";
constexpr char MULTICAST_ADDRESS_IPV6[10] = "ff08::101";
PeerDiscovery::PeerDiscovery(sa_family_t domain, in_port_t port)
class PeerDiscovery::DomainPeerDiscovery
{
public:
DomainPeerDiscovery(sa_family_t domain, in_port_t port);
~DomainPeerDiscovery();
/**
* startDiscovery - Keep Listening data from the sender until node is joinned or stop is called
*/
void startDiscovery(const std::string &type, ServiceDiscoveredCallback callback);
/**
* startPublish - Keeping sending data until node is joinned or stop is called - msgpack
*/
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
/**
* Thread Stopper
*/
void stop();
/**
* Remove possible callBack to discovery
*/
bool stopDiscovery(const std::string &type);
/**
* Remove different serivce message to send
*/
bool stopPublish(const std::string &type);
/**
* Configure the sockopt to be able to listen multicast group
*/
static void socketJoinMulticast(int sockfd, sa_family_t family);
/**
* Join the threads
*/
void join() {
if(running_listen_.joinable()) running_listen_.join();
if(running_send_.joinable()) running_send_.join();
}
private:
//dmtx_ for callbackmap_ and drunning_ (write)
std::mutex dmtx_;
//mtx_ for messages_ and lrunning (listen)
std::mutex mtx_;
std::condition_variable cv_;
bool lrunning_ {false};
bool drunning_ {false};
sa_family_t domain_ {AF_UNSPEC};
int port_;
int sockfd_ {-1};
int stop_writefd_ {-1};
SockAddr sockAddrSend_;
//Thread export to be joined
std::thread running_listen_;
std::thread running_send_;
msgpack::sbuffer sbuf_;
std::map<std::string, msgpack::sbuffer> messages_;
std::map<std::string, ServiceDiscoveredCallback> callbackmap_;
/**
* Multicast Socket Initialization, accept IPV4, IPV6
*/
static int initialize_socket(sa_family_t domain);
/**
* Receive messages
*/
std::pair<SockAddr, msgpack::object_handle> recvFrom();
/**
* Listener pack thread loop
*/
void listenerpack_thread();
/**
* Listener Parameters Setup
*/
void listener_setup();
/**
* Sender Parameters Setup
*/
void sender_setup();
/**
* Sender Parameters Setup
*/
void messages_reload();
void stopDiscovery();
void stopPublish();
};
PeerDiscovery::DomainPeerDiscovery::DomainPeerDiscovery(sa_family_t domain, in_port_t port)
: domain_(domain), port_(port), sockfd_(initialize_socket(domain))
{
socketJoinMulticast(sockfd_, domain);
listener_setup();
sender_setup();
}
PeerDiscovery::~PeerDiscovery()
PeerDiscovery::DomainPeerDiscovery::~DomainPeerDiscovery()
{
stop();
join();
if (sockfd_ != -1)
close(sockfd_);
@@ -53,7 +166,7 @@ PeerDiscovery::~PeerDiscovery()
}
int
PeerDiscovery::initialize_socket(sa_family_t domain)
PeerDiscovery::DomainPeerDiscovery::initialize_socket(sa_family_t domain)
{
#ifdef _WIN32
WSADATA wsaData;
@@ -66,12 +179,12 @@ PeerDiscovery::initialize_socket(sa_family_t domain)
if (sockfd < 0) {
throw std::runtime_error(std::string("Socket Creation Error: ") + strerror(errno));
}
net::set_nonblocking(sockfd);
net::setNonblocking(sockfd);
return sockfd;
}
void
PeerDiscovery::listener_setup()
PeerDiscovery::DomainPeerDiscovery::listener_setup()
{
SockAddr sockAddrListen_;
sockAddrListen_.setFamily(domain_);
@@ -79,12 +192,14 @@ PeerDiscovery::listener_setup()
sockAddrListen_.setAny();
unsigned int opt = 1;
if (setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
if (setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0) {
std::cerr << "setsockopt SO_REUSEADDR failed: " << strerror(errno) << std::endl;
}
if (setsockopt(sockfd_, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
#ifdef SO_REUSEPORT
if (setsockopt(sockfd_, SOL_SOCKET, SO_REUSEPORT, (char*)&opt, sizeof(opt)) < 0) {
std::cerr << "setsockopt SO_REUSEPORT failed: " << strerror(errno) << std::endl;
}
#endif
// bind to receive address
if (bind(sockfd_, sockAddrListen_.get(), sockAddrListen_.getLength()) < 0){
@@ -93,7 +208,7 @@ PeerDiscovery::listener_setup()
}
void
PeerDiscovery::socketJoinMulticast(int sockfd, sa_family_t family)
PeerDiscovery::DomainPeerDiscovery::socketJoinMulticast(int sockfd, sa_family_t family)
{
switch (family)
{
@@ -103,14 +218,14 @@ PeerDiscovery::socketJoinMulticast(int sockfd, sa_family_t family)
//This option can be used to set the interface for sending outbound
//multicast datagrams from the sockets application.
config_ipv4.imr_interface.s_addr = htonl(INADDR_ANY);
if( setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &config_ipv4.imr_interface, sizeof( struct in_addr )) < 0 ) {
if( setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, (char*)&config_ipv4.imr_interface, sizeof( struct in_addr )) < 0 ) {
throw std::runtime_error(std::string("Bound Network Interface IPv4 Error: ") + strerror(errno));
}
//The IP_MULTICAST_TTL socket option allows the application to primarily
//limit the lifetime of the packet in the Internet and prevent it from circulating indefinitely
unsigned char ttl4 = 20;
if( setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl4, sizeof( ttl4 )) < 0 ) {
if( setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl4, sizeof( ttl4 )) < 0 ) {
throw std::runtime_error(std::string("TTL Sockopt Error: ") + strerror(errno));
}
@@ -131,13 +246,13 @@ PeerDiscovery::socketJoinMulticast(int sockfd, sa_family_t family)
} */
unsigned int ttl6 = 20;
if( setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl6, sizeof( ttl6 )) < 0 ) {
if( setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl6, sizeof( ttl6 )) < 0 ) {
throw std::runtime_error(std::string("Hop Count Set Error: ") + strerror(errno));
}
config_ipv6.ipv6mr_interface = 0;
inet_pton(AF_INET6, MULTICAST_ADDRESS_IPV6, &config_ipv6.ipv6mr_multiaddr);
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &config_ipv6, sizeof(config_ipv6)) < 0){
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&config_ipv6, sizeof(config_ipv6)) < 0){
throw std::runtime_error(std::string("Member Addition IPv6 Error: ") + strerror(errno));
}
break;
@@ -146,78 +261,39 @@ PeerDiscovery::socketJoinMulticast(int sockfd, sa_family_t family)
}
void
PeerDiscovery::sendTo(uint8_t *buf, size_t buf_size)
PeerDiscovery::DomainPeerDiscovery::startDiscovery(const std::string &type, ServiceDiscoveredCallback callback)
{
ssize_t nbytes = sendto(
sockfd_,
buf,
buf_size,
0,
sockAddrSend_.get(),
sockAddrSend_.getLength()
);
if (nbytes < 0) {
throw std::runtime_error(std::string("Error sending packet: ") + strerror(errno));
std::unique_lock<std::mutex> lck(dmtx_);
callbackmap_[type] = callback;
if (not drunning_) {
if (running_listen_.joinable())
running_listen_.join();
drunning_ = true;
running_listen_ = std::thread(&DomainPeerDiscovery::listenerpack_thread, this);
}
}
SockAddr
PeerDiscovery::recvFrom(uint8_t *buf, size_t& buf_size)
std::pair<SockAddr, msgpack::object_handle>
PeerDiscovery::DomainPeerDiscovery::recvFrom()
{
sockaddr_storage storeage_recv;
socklen_t sa_len = sizeof(storeage_recv);
sockaddr_storage sa;
socklen_t sa_len = sizeof(sa);
std::array<uint8_t, 64 * 1024> buf;
ssize_t nbytes = recvfrom(
sockfd_,
buf,
buf_size,
(char*)buf.data(), buf.size(),
0,
(sockaddr*)&storeage_recv,
&sa_len
(sockaddr*)&sa, &sa_len
);
if (nbytes < 0) {
if (nbytes < 0)
throw std::runtime_error(std::string("Error receiving packet: ") + strerror(errno));
}
buf_size = nbytes;
SockAddr ret {storeage_recv, sa_len};
return ret;
return { SockAddr { sa, sa_len }, msgpack::unpack(reinterpret_cast<char*>(buf.data()), nbytes) };
}
void
PeerDiscovery::sender_setup(const dht::InfoHash& nodeId, in_port_t port_to_send)
{
nodeId_ = nodeId;
// Setup sender address
sockAddrSend_.setFamily(domain_);
sockAddrSend_.setAddress(domain_ == AF_INET ? MULTICAST_ADDRESS_IPV4 : MULTICAST_ADDRESS_IPV6);
sockAddrSend_.setPort(port_);
// Setup sent data
std::copy_n(nodeId.cbegin(), nodeId.size(), data_send_.begin());
auto portAddr = reinterpret_cast<in_port_t*>(data_send_.data() + dht::InfoHash::size());
*portAddr = htons(port_to_send);
}
void
PeerDiscovery::sender_thread()
{
while(true) {
try {
sendTo(data_send_.data(), data_send_.size());
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
{
std::unique_lock<std::mutex> lck(mtx_);
if (cv_.wait_for(lck,std::chrono::seconds(3),[&]{ return !running_; }))
break;
}
}
}
void
PeerDiscovery::listener_thread(PeerDiscoveredCallback callback)
PeerDiscovery::DomainPeerDiscovery::listenerpack_thread()
{
int stopfds_pipe[2];
#ifndef _WIN32
@@ -229,18 +305,24 @@ PeerDiscovery::listener_thread(PeerDiscoveredCallback callback)
int stop_readfd = stopfds_pipe[0];
stop_writefd_ = stopfds_pipe[1];
while(true) {
while (true) {
{
std::lock_guard<std::mutex> lck(dmtx_);
if (not drunning_)
break;
}
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(stop_readfd, &readfds);
FD_SET(sockfd_, &readfds);
int data_coming = select(sockfd_ > stop_readfd ? sockfd_ + 1 : stop_readfd + 1, &readfds, nullptr, nullptr, nullptr);
int data_coming = select(std::max(sockfd_, stop_readfd) + 1, &readfds, nullptr, nullptr, nullptr);
{
std::unique_lock<std::mutex> lck(mtx_);
if (not running_)
std::lock_guard<std::mutex> lck(dmtx_);
if (not drunning_)
break;
}
@@ -249,31 +331,35 @@ PeerDiscovery::listener_thread(PeerDiscoveredCallback callback)
perror("Select Error");
std::this_thread::sleep_for( std::chrono::seconds(1) );
}
}
if (data_coming > 0) {
} else if (data_coming > 0) {
if (FD_ISSET(stop_readfd, &readfds)) {
std::array<uint8_t, 64 * 1024> buf;
recv(stop_readfd, buf.data(), buf.size(), 0);
recv(stop_readfd, (char*)buf.data(), buf.size(), 0);
}
std::array<uint8_t,dht::InfoHash::size() + sizeof(in_port_t)> data_receive;
size_t data_receive_size = data_receive.size();
auto from = recvFrom(data_receive.data(), data_receive_size);
try {
auto rcv = recvFrom();
msgpack::object obj = rcv.second.get();
// Data_receive_size as a value-result member will hlep to filter packs
if(data_receive_size != data_receive.size()){
// std::cerr << "Received invalid peer discovery packet" << std::endl;
continue;
}
dht::InfoHash nodeId;
std::copy_n(data_receive.begin(), dht::InfoHash::size(), nodeId.begin());
auto portAddr = reinterpret_cast<in_port_t*>(data_receive.data() + dht::InfoHash::size());
auto port = ntohs(*portAddr);
if (nodeId != nodeId_){
from.setPort(port);
callback(nodeId, from);
if (obj.type != msgpack::type::MAP)
continue;
for (unsigned i = 0; i < obj.via.map.size; i++) {
auto& o = obj.via.map.ptr[i];
if (o.key.type != msgpack::type::STR)
continue;
auto key = o.key.as<std::string>();
ServiceDiscoveredCallback cb;
{
std::lock_guard<std::mutex> lck(dmtx_);
auto callback = callbackmap_.find(key);
if (callback != callbackmap_.end())
cb = callback->second;
}
if (cb)
cb(std::move(o.val), std::move(rcv.first));
}
} catch (const std::exception& e) {
std::cerr << "Error receiving packet: " << e.what() << std::endl;
}
}
}
@@ -286,32 +372,206 @@ PeerDiscovery::listener_thread(PeerDiscoveredCallback callback)
}
void
PeerDiscovery::startDiscovery(PeerDiscoveredCallback callback)
PeerDiscovery::DomainPeerDiscovery::sender_setup()
{
listener_setup();
running_listen = std::thread(&PeerDiscovery::listener_thread, this, callback);
// Setup sender address
sockAddrSend_.setFamily(domain_);
sockAddrSend_.setAddress(domain_ == AF_INET ? MULTICAST_ADDRESS_IPV4 : MULTICAST_ADDRESS_IPV6);
sockAddrSend_.setPort(port_);
}
void
PeerDiscovery::startPublish(const dht::InfoHash& nodeId, in_port_t port_to_send)
PeerDiscovery::DomainPeerDiscovery::startPublish(const std::string &type, const msgpack::sbuffer &pack_buf)
{
sender_setup(nodeId, port_to_send);
running_send = std::thread(&PeerDiscovery::sender_thread, this);
//Set up New Sending pack
msgpack::sbuffer pack_buf_c;
pack_buf_c.write(pack_buf.data(),pack_buf.size());
std::unique_lock<std::mutex> lck(mtx_);
messages_[type] = std::move(pack_buf_c);
messages_reload();
if (not lrunning_) {
if (running_send_.joinable())
running_send_.join();
lrunning_ = true;
running_send_ = std::thread([this](){
std::unique_lock<std::mutex> lck(mtx_);
while (lrunning_) {
ssize_t nbytes = sendto(
sockfd_,
sbuf_.data(),
sbuf_.size(),
0,
sockAddrSend_.get(),
sockAddrSend_.getLength()
);
if (nbytes < 0) {
std::cerr << "Error sending packet: " << strerror(errno) << std::endl;
}
if (cv_.wait_for(lck,std::chrono::seconds(3),[&]{ return !lrunning_; }))
break;
}
});
}
}
bool
PeerDiscovery::DomainPeerDiscovery::stopDiscovery(const std::string &type)
{
std::lock_guard<std::mutex> lck(dmtx_);
if (callbackmap_.erase(type) > 0) {
if (callbackmap_.empty())
stopDiscovery();
return true;
}
return false;
}
bool
PeerDiscovery::DomainPeerDiscovery::stopPublish(const std::string &type)
{
std::lock_guard<std::mutex> lck(mtx_);
if (messages_.erase(type) > 0) {
if (messages_.empty())
stopPublish();
else
messages_reload();
return true;
}
return false;
}
void
PeerDiscovery::DomainPeerDiscovery::stopDiscovery()
{
#ifdef _WIN32
#define write(s, b, f) send((s), (b), (f), 0)
#endif
if (drunning_) {
drunning_ = false;
if (stop_writefd_ != -1) {
if (write(stop_writefd_, "\0", 1) == -1) {
std::cerr << "Can't send stop message: " << strerror(errno) << std::endl;
}
}
}
#ifdef _WIN32
#undef write
#endif
}
void
PeerDiscovery::DomainPeerDiscovery::stopPublish()
{
if (lrunning_) {
lrunning_ = false;
cv_.notify_all();
}
}
void
PeerDiscovery::DomainPeerDiscovery::stop()
{
{
std::unique_lock<std::mutex> lck(dmtx_);
stopDiscovery();
}
{
std::unique_lock<std::mutex> lck(mtx_);
stopPublish();
}
}
void
PeerDiscovery::DomainPeerDiscovery::messages_reload()
{
sbuf_.clear();
msgpack::packer<msgpack::sbuffer> pk(&sbuf_);
pk.pack_map(messages_.size());
for (const auto& m : messages_) {
pk.pack(m.first);
sbuf_.write(m.second.data(), m.second.size());
}
}
PeerDiscovery::PeerDiscovery(in_port_t port)
{
try {
peerDiscovery4_.reset(new DomainPeerDiscovery(AF_INET, port));
} catch(const std::exception& e){
std::cerr << "Can't start peer discovery (IPv4): " << e.what() << std::endl;
}
try {
peerDiscovery6_.reset(new DomainPeerDiscovery(AF_INET6, port));
} catch(const std::exception& e) {
std::cerr << "Can't start peer discovery (IPv6): " << e.what() << std::endl;
}
}
PeerDiscovery::~PeerDiscovery(){}
void
PeerDiscovery::startDiscovery(const std::string &type, ServiceDiscoveredCallback callback)
{
if(peerDiscovery4_) peerDiscovery4_->startDiscovery(type, callback);
if(peerDiscovery6_) peerDiscovery6_->startDiscovery(type, callback);
}
void
PeerDiscovery::startPublish(const std::string &type, const msgpack::sbuffer &pack_buf)
{
if(peerDiscovery4_) peerDiscovery4_->startPublish(type, pack_buf);
if(peerDiscovery6_) peerDiscovery6_->startPublish(type, pack_buf);
}
void
PeerDiscovery::startPublish(sa_family_t domain, const std::string &type, const msgpack::sbuffer &pack_buf)
{
if (domain == AF_INET) {
if (peerDiscovery4_) peerDiscovery4_->startPublish(type, pack_buf);
} else if (domain == AF_INET6) {
if (peerDiscovery6_) peerDiscovery6_->startPublish(type, pack_buf);
}
}
void
PeerDiscovery::stop()
{
{
std::unique_lock<std::mutex> lck(mtx_);
running_ = false;
}
cv_.notify_all();
if (stop_writefd_ != -1) {
if (write(stop_writefd_, "\0", 1) == -1) {
perror("write");
}
if(peerDiscovery4_) peerDiscovery4_->stop();
if(peerDiscovery6_) peerDiscovery6_->stop();
}
bool
PeerDiscovery::stopDiscovery(const std::string &type)
{
bool stopped4 = peerDiscovery4_ and peerDiscovery4_->stopDiscovery(type);
bool stopped6 = peerDiscovery6_ and peerDiscovery6_->stopDiscovery(type);
return stopped4 or stopped6;
}
bool
PeerDiscovery::stopPublish(const std::string &type)
{
bool stopped4 = peerDiscovery4_ and peerDiscovery4_->stopPublish(type);
bool stopped6 = peerDiscovery6_ and peerDiscovery6_->stopPublish(type);
return stopped4 or stopped6;
}
bool
PeerDiscovery::stopPublish(sa_family_t domain, const std::string &type)
{
if (domain == AF_INET) {
return peerDiscovery4_ and peerDiscovery4_->stopPublish(type);
} else if (domain == AF_INET6) {
return peerDiscovery6_ and peerDiscovery6_->stopPublish(type);
}
return false;
}
void
PeerDiscovery::join() {
if(peerDiscovery4_) peerDiscovery4_->join();
if(peerDiscovery6_) peerDiscovery6_->join();
}
}
+19 -19
View File
@@ -54,9 +54,9 @@ SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf)
CERTIFICATE_TYPE,
*certificate_,
1
}, [this](bool ok) {
}, [this, certId](bool ok) {
if (ok)
DHT_LOG.DBG("SecureDht: public key announced successfully");
DHT_LOG.d(certId, "SecureDht: public key announced successfully");
}, {}, true);
}
}
@@ -73,7 +73,7 @@ SecureDht::secureType(ValueType&& type)
v->signatureValid = v->owner and v->owner->checkSignature(v->getToSign(), v->signature);
}
if (!v->signatureValid) {
DHT_LOG.WARN("Signature verification failed");
DHT_LOG.w("Signature verification failed");
return false;
}
}
@@ -83,7 +83,7 @@ SecureDht::secureType(ValueType&& type)
if (!o->isSigned())
return type.editPolicy(id, o, n, nid, a);
if (o->owner != n->owner) {
DHT_LOG.WARN("Edition forbidden: owner changed.");
DHT_LOG.w("Edition forbidden: owner changed.");
return false;
}
if (!n->signatureChecked) {
@@ -91,14 +91,14 @@ SecureDht::secureType(ValueType&& type)
n->signatureValid = o->owner and o->owner->checkSignature(n->getToSign(), n->signature);
}
if (!n->signatureValid) {
DHT_LOG.WARN("Edition forbidden: signature verification failed.");
DHT_LOG.w("Edition forbidden: signature verification failed.");
return false;
}
if (o->seq == n->seq) {
// If the data is exactly the same,
// it can be reannounced, possibly by someone else.
if (o->getToSign() != n->getToSign()) {
DHT_LOG.WARN("Edition forbidden: sequence number must be increasing.");
DHT_LOG.w("Edition forbidden: sequence number must be increasing.");
return false;
}
}
@@ -144,7 +144,7 @@ SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
}
InfoHash h = crt->getPublicKey().getId();
if (node == h) {
DHT_LOG.DBG("Registering certificate for %s", h.toString().c_str());
DHT_LOG.d("Registering certificate for %s", h.toString().c_str());
auto it = nodesCertificates_.find(h);
if (it == nodesCertificates_.end())
std::tie(it, std::ignore) = nodesCertificates_.emplace(h, std::move(crt));
@@ -152,7 +152,7 @@ SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
it->second = std::move(crt);
return it->second;
} else {
DHT_LOG.WARN("Certificate %s for node %s does not match node id !", h.toString().c_str(), node.toString().c_str());
DHT_LOG.w("Certificate %s for node %s does not match node id !", h.toString().c_str(), node.toString().c_str());
return nullptr;
}
}
@@ -169,7 +169,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
{
Sp<crypto::Certificate> b = getCertificate(node);
if (b && *b) {
DHT_LOG.DBG("Using certificate from cache for %s", node.toString().c_str());
DHT_LOG.d("Using certificate from cache for %s", node.toString().c_str());
if (cb)
cb(b);
return;
@@ -177,7 +177,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
if (localQueryMethod_) {
auto res = localQueryMethod_(node);
if (not res.empty()) {
DHT_LOG.DBG("Registering certificate from local store for %s", node.toString().c_str());
DHT_LOG.d("Registering certificate from local store for %s", node.toString().c_str());
nodesCertificates_.emplace(node, res.front());
if (cb)
cb(res.front());
@@ -192,7 +192,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
DHT_LOG.DBG("Found certificate for %s", node.toString().c_str());
DHT_LOG.d("Found certificate for %s", node.toString().c_str());
if (cb)
cb(cert);
return false;
@@ -210,7 +210,7 @@ SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp
{
auto pk = getPublicKey(node);
if (pk && *pk) {
DHT_LOG.DBG("Found public key from cache for %s", node.toString().c_str());
DHT_LOG.d("Found public key from cache for %s", node.toString().c_str());
if (cb)
cb(pk);
return;
@@ -254,7 +254,7 @@ SecureDht::checkValue(const Sp<Value>& v)
}
// Ignore values belonging to other people
} catch (const std::exception& e) {
DHT_LOG.WARN("Could not decrypt value %s : %s", v->toString().c_str(), e.what());
DHT_LOG.w("Could not decrypt value %s : %s", v->toString().c_str(), e.what());
}
}
// Check signed values
@@ -269,7 +269,7 @@ SecureDht::checkValue(const Sp<Value>& v)
return v;
}
else
DHT_LOG.WARN("Signature verification failed for %s", v->toString().c_str());
DHT_LOG.w("Signature verification failed for %s", v->toString().c_str());
}
// Forward normal values
else {
@@ -352,12 +352,12 @@ SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback,
// Check if data already exists on the dht
get(hash,
[val,this] (const std::vector<Sp<Value>>& vals) {
DHT_LOG.DBG("Found online previous value being announced.");
DHT_LOG.d("Found online previous value being announced.");
for (const auto& v : vals) {
if (!v->isSigned())
DHT_LOG.ERR("Existing non-signed value seems to exists at this location.");
DHT_LOG.e("Existing non-signed value seems to exists at this location.");
else if (not v->owner or v->owner->getId() != getId())
DHT_LOG.ERR("Existing signed value belonging to someone else seems to exists at this location.");
DHT_LOG.e("Existing signed value belonging to someone else seems to exists at this location.");
else if (val->seq <= v->seq)
val->seq = v->seq + 1;
}
@@ -381,11 +381,11 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val,
callback(false, {});
return;
}
DHT_LOG.WARN("Encrypting data for PK: %s", pk->getId().toString().c_str());
DHT_LOG.w("Encrypting data for PK: %s", pk->getId().toString().c_str());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
DHT_LOG.ERR("Error putting encrypted data: %s", e.what());
DHT_LOG.e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
+42 -1
View File
@@ -21,7 +21,7 @@
#include <atomic>
#include <thread>
#include <iostream>
#include <ciso646> // fix windows compiler bug
namespace dht {
@@ -97,6 +97,7 @@ ThreadPool::run(std::function<void()>&& cb)
task();
} catch (const std::exception& e) {
// LOG_ERR("Exception running task: %s", e.what());
std::cerr << "Exception running task: " << e.what() << std::endl;
}
}
});
@@ -131,4 +132,44 @@ ThreadPool::join()
threads_.clear();
}
void
Executor::run(std::function<void()>&& task)
{
std::lock_guard<std::mutex> l(lock_);
if (current_ < maxConcurrent_) {
run_(std::move(task));
} else {
tasks_.emplace(std::move(task));
}
}
void
Executor::run_(std::function<void()>&& task)
{
current_++;
std::weak_ptr<Executor> w = shared_from_this();
threadPool_.get().run([w,task] {
try {
task();
} catch (const std::exception& e) {
std::cerr << "Exception running task: " << e.what() << std::endl;
}
if (auto sthis = w.lock()) {
auto& this_ = *sthis;
std::lock_guard<std::mutex> l(this_.lock_);
this_.current_--;
this_.schedule();
}
});
}
void
Executor::schedule()
{
if (not tasks_.empty() and current_ < maxConcurrent_) {
run_(std::move(tasks_.front()));
tasks_.pop();
}
}
}
+27 -5
View File
@@ -16,6 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "utils.h"
#include "sockaddr.h"
#include "default_types.h"
@@ -93,9 +97,11 @@ SockAddr::setAddress(const char* address)
case AF_INET6:
addr = &getIPv6().sin6_addr;
break;
default:
throw std::runtime_error("Unknown address family");
}
if (not addr or inet_pton(family, address, addr) <= 0)
throw std::runtime_error("Can't parse IP address");
if (inet_pton(family, address, addr) <= 0)
throw std::runtime_error(std::string("Can't parse IP address: ") + strerror(errno));
}
std::string
@@ -104,7 +110,7 @@ print_addr(const sockaddr* sa, socklen_t slen)
char hbuf[NI_MAXHOST];
char sbuf[NI_MAXSERV];
std::stringstream out;
if (!getnameinfo(sa, slen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
if (sa and slen and !getnameinfo(sa, slen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
if (sa->sa_family == AF_INET6)
out << "[" << hbuf << "]";
else
@@ -195,10 +201,10 @@ SockAddr::isMappedIPv4() const
}
SockAddr
SockAddr::getMappedIPv4() const
SockAddr::getMappedIPv4()
{
if (not isMappedIPv4())
return *this;
return std::move(*this);
SockAddr ret;
ret.setFamily(AF_INET);
ret.setPort(getPort());
@@ -209,6 +215,22 @@ SockAddr::getMappedIPv4() const
return ret;
}
SockAddr
SockAddr::getMappedIPv6()
{
auto family = getFamily();
if (family != AF_INET)
return std::move(*this);
SockAddr ret;
ret.setFamily(AF_INET6);
ret.setPort(getPort());
auto addr4 = reinterpret_cast<const uint8_t*>(&getIPv4().sin_addr);
auto addr6 = reinterpret_cast<uint8_t*>(&ret.getIPv6().sin6_addr);
std::copy(MAPPED_IPV4_PREFIX.begin(), MAPPED_IPV4_PREFIX.end(), addr6);
std::copy_n(addr4, sizeof(in_addr), addr6 + MAPPED_IPV4_PREFIX.size());
return ret;
}
bool operator==(const SockAddr& a, const SockAddr& b) {
return a.equals(b);
}
+33 -25
View File
@@ -32,15 +32,15 @@ CPPUNIT_TEST_SUITE_REGISTRATION(DhtProxyTester);
void
DhtProxyTester::setUp() {
nodePeer.run(42222, {}, true);
nodePeer.run(0);
nodeProxy = std::make_shared<dht::DhtRunner>();
nodeClient = std::make_shared<dht::DhtRunner>();
nodeProxy->run(42232, {}, true);
nodeProxy->run(0);
nodeProxy->bootstrap(nodePeer.getBound());
server = std::unique_ptr<dht::DhtProxyServer>(new dht::DhtProxyServer(nodeProxy, 8080));
nodeClient->run(42242, {}, true);
nodeClient->run(0);
nodeClient->bootstrap(nodePeer.getBound());
nodeClient->setProxyServer("127.0.0.1:8080");
nodeClient->enableProxy(true);
@@ -65,12 +65,15 @@ DhtProxyTester::testGetPut() {
dht::Value val {"Hey! It's been a long time. How have you been?"};
auto val_data = val.data;
nodePeer.put(key, std::move(val), [&](bool) {
done = true;
cv.notify_all();
});
std::unique_lock<std::mutex> lk(cv_m);
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
{
std::unique_lock<std::mutex> lk(cv_m);
nodePeer.put(key, std::move(val), [&](bool) {
std::lock_guard<std::mutex> lk(cv_m);
done = true;
cv.notify_all();
});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
}
auto vals = nodeClient->get(key).get();
CPPUNIT_ASSERT(not vals.empty());
@@ -79,33 +82,37 @@ DhtProxyTester::testGetPut() {
void
DhtProxyTester::testListen() {
bool done = false;
std::condition_variable cv;
std::mutex cv_m;
std::unique_lock<std::mutex> lk(cv_m);
auto key = dht::InfoHash::get("GLaDOs");
bool done = false;
// If a peer send a value, the listen operation from the client
// should retrieve this value
dht::Value firstVal {"Hey! It's been a long time. How have you been?"};
auto firstVal_data = firstVal.data;
nodePeer.put(key, std::move(firstVal), [&](bool) {
nodePeer.put(key, std::move(firstVal), [&](bool ok) {
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(cv_m);
done = true;
cv.notify_all();
});
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
done = false;
auto values = std::vector<dht::Blob>();
nodeClient->listen(key, [&](const std::vector<std::shared_ptr<dht::Value>>& v, bool) {
for (const auto& value : v)
values.emplace_back(value->data);
done = true;
cv.notify_all();
std::vector<dht::Blob> values;
auto token = nodeClient->listen(key, [&](const std::vector<std::shared_ptr<dht::Value>>& v, bool expired) {
if (not expired) {
std::lock_guard<std::mutex> lk(cv_m);
for (const auto& value : v)
values.emplace_back(value->data);
done = true;
cv.notify_all();
}
return true;
});
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
done = false;
// Here values should contains 1 values
CPPUNIT_ASSERT_EQUAL(static_cast<int>(values.size()), 1);
@@ -116,7 +123,8 @@ DhtProxyTester::testListen() {
dht::Value secondVal {"You're a monster"};
auto secondVal_data = secondVal.data;
nodePeer.put(key, std::move(secondVal));
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
nodeClient->cancelListen(key, std::move(token));
// Here values should contains 2 values
CPPUNIT_ASSERT_EQUAL(static_cast<int>(values.size()), 2);
CPPUNIT_ASSERT(values.back() == secondVal_data);
@@ -137,10 +145,11 @@ DhtProxyTester::testResubscribeGetValues() {
dht::Value firstVal {"Hey! It's been a long time. How have you been?"};
auto firstVal_data = firstVal.data;
nodePeer.put(key, std::move(firstVal), [&](bool) {
std::lock_guard<std::mutex> lk(cv_m);
done = true;
cv.notify_all();
});
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
done = false;
// Send a first subscribe, the value is sent via a push notification
@@ -166,16 +175,15 @@ DhtProxyTester::testResubscribeGetValues() {
for (const auto& value : v)
values.emplace_back(value->data);
done = true;
cv.notify_all();
}
cv.notify_all();
return true;
});
cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; });
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]{ return done; }));
auto token = ftoken.get();
CPPUNIT_ASSERT(token);
nodeClient->cancelListen(key, token);
done = false;
// Here values should still contains 1 values
CPPUNIT_ASSERT_EQUAL((size_t)1u, values.size());
CPPUNIT_ASSERT(firstVal_data == values.front());
+71 -50
View File
@@ -18,71 +18,92 @@
*/
#include "peerdiscoverytester.h"
#include "opendht/value.h"
namespace test {
struct NodeInsertion {
dht::InfoHash nodeid;
in_port_t node_port;
dht::NetId nid;
MSGPACK_DEFINE(nodeid, node_port, nid)
};
struct TestPack {
int num;
char cha;
std::string str;
MSGPACK_DEFINE(num, cha, str)
};
CPPUNIT_TEST_SUITE_REGISTRATION(PeerDiscoveryTester);
void PeerDiscoveryTester::setUp(){}
void PeerDiscoveryTester::testTransmission_ipv4(){
void PeerDiscoveryTester::testTransmission()
{
// Node for getnode id
dht::InfoHash data_n = dht::InfoHash::get("applepin");
int port = 2222;
in_port_t port_n = 50000;
try{
dht::PeerDiscovery test_n(AF_INET, port);
dht::PeerDiscovery test_s(AF_INET, port);
try{
test_s.startDiscovery([&](const dht::InfoHash& node, const dht::SockAddr& addr){
CPPUNIT_ASSERT_EQUAL(data_n, node);
CPPUNIT_ASSERT_EQUAL(port_n, addr.getPort());
});
const std::string type {"dht"};
const std::string test_type {"pdd"};
constexpr int MULTICAST_PORT = 2222;
test_n.startPublish(data_n,port_n);
NodeInsertion adc;
adc.nid = 10;
adc.node_port = 50000;
adc.nodeid = dht::InfoHash::get("applepin");
std::this_thread::sleep_for(std::chrono::seconds(5));
test_n.stop();
test_s.stop();
test_n.join();
test_s.join();
} catch(std::exception &exception){
perror(exception.what());
CPPUNIT_ASSERT(false);
}
} catch(std::exception &exception){
perror(exception.what());
}
}
TestPack pdd;
pdd.num = 100;
pdd.cha = 'a';
pdd.str = "apple";
void PeerDiscoveryTester::testTransmission_ipv6(){
std::mutex lock;
std::condition_variable cv;
unsigned count_node {0};
unsigned count_test {0};
// Node for getnode id
dht::InfoHash data_n = dht::InfoHash::get("applepin");
int port = 3333;
in_port_t port_n = 50001;
try{
dht::PeerDiscovery test_n(AF_INET6, port);
dht::PeerDiscovery test_s(AF_INET6, port);
{
std::unique_lock<std::mutex> l(lock);
dht::PeerDiscovery test_n(MULTICAST_PORT);
dht::PeerDiscovery test_s(MULTICAST_PORT);
try{
test_s.startDiscovery([&](const dht::InfoHash& node, const dht::SockAddr& addr){
CPPUNIT_ASSERT_EQUAL(data_n, node);
CPPUNIT_ASSERT_EQUAL(port_n, addr.getPort());
});
test_s.startDiscovery<NodeInsertion>(type,[&](NodeInsertion&& v, dht::SockAddr&& add){
CPPUNIT_ASSERT_EQUAL(adc.node_port, v.node_port);
CPPUNIT_ASSERT_EQUAL(adc.nodeid, v.nodeid);
CPPUNIT_ASSERT_EQUAL(adc.nid, v.nid);
{
std::lock_guard<std::mutex> l(lock);
count_node++;
}
cv.notify_all();
});
test_n.startPublish(data_n,port_n);
test_s.startDiscovery(test_type,[&](msgpack::object&& obj, dht::SockAddr&& add){
auto v = obj.as<TestPack>();
CPPUNIT_ASSERT_EQUAL(pdd.num, v.num);
CPPUNIT_ASSERT_EQUAL(pdd.cha, v.cha);
CPPUNIT_ASSERT_EQUAL(pdd.str, v.str);
{
std::lock_guard<std::mutex> l(lock);
count_test++;
}
cv.notify_all();
});
std::this_thread::sleep_for(std::chrono::seconds(5));
test_n.stop();
test_s.stop();
test_n.join();
test_s.join();
} catch(std::exception &exception){
CPPUNIT_ASSERT(false);
}
} catch(std::exception &exception) {
test_n.startPublish(type, adc);
CPPUNIT_ASSERT(cv.wait_for(l, std::chrono::seconds(5), [&]{
return count_node > 0;
}));
test_n.startPublish(test_type, pdd);
CPPUNIT_ASSERT(cv.wait_for(l, std::chrono::seconds(5), [&]{
return count_node > 1 and count_test > 0;
}));
l.unlock();
test_n.stopPublish(type);
test_n.stopPublish(test_type);
test_s.stopDiscovery(type);
test_s.stopDiscovery(test_type);
}
}
+3 -9
View File
@@ -26,11 +26,10 @@
namespace test {
class PeerDiscoveryTester : public CppUnit::TestFixture {
class OPENDHT_PUBLIC PeerDiscoveryTester : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(PeerDiscoveryTester);
CPPUNIT_TEST(testTransmission_ipv4);
CPPUNIT_TEST(testTransmission_ipv6);
CPPUNIT_TEST(testTransmission);
CPPUNIT_TEST_SUITE_END();
public:
@@ -45,12 +44,7 @@ class PeerDiscoveryTester : public CppUnit::TestFixture {
/**
* Test Multicast Transmission Ipv4
*/
void testTransmission_ipv4();
/**
* Test Multicast Transmission Ipv6
*/
void testTransmission_ipv6();
void testTransmission();
};
} // namespace test
+90
View File
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "threadpooltester.h"
#include "opendht/thread_pool.h"
#include <atomic>
namespace test {
CPPUNIT_TEST_SUITE_REGISTRATION(ThreadPoolTester);
using clock = std::chrono::steady_clock;
void
ThreadPoolTester::setUp() {
}
void
ThreadPoolTester::testThreadPool() {
dht::ThreadPool pool(16);
constexpr unsigned N = 64 * 1024;
std::atomic_uint count {0};
for (unsigned i=0; i<N; i++)
pool.run([&] {
count++;
});
auto start = clock::now();
while (count.load() != N && clock::now() - start < std::chrono::seconds(10))
std::this_thread::sleep_for(std::chrono::milliseconds(10));
pool.join();
CPPUNIT_ASSERT(count.load() == N);
}
void
ThreadPoolTester::testExecutor()
{
dht::ThreadPool pool(8);
auto executor1 = std::make_shared<dht::Executor>(pool, 1);
auto executor4 = std::make_shared<dht::Executor>(pool, 4);
auto executor8 = std::make_shared<dht::Executor>(pool, 8);
constexpr unsigned N = 64 * 1024;
std::atomic_uint count1 {0};
std::atomic_uint count4 {0};
std::atomic_uint count8 {0};
for (unsigned i=0; i<N; i++) {
executor1->run([&] { count1++; });
executor4->run([&] { count4++; });
executor8->run([&] { count8++; });
}
auto start = clock::now();
while ((count1.load() != N ||
count4.load() != N ||
count8.load() != N) && clock::now() - start < std::chrono::seconds(20))
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
executor1.reset();
executor4.reset();
executor8.reset();
CPPUNIT_ASSERT_EQUAL(N, count1.load());
CPPUNIT_ASSERT_EQUAL(N, count4.load());
CPPUNIT_ASSERT_EQUAL(N, count8.load());
}
void
ThreadPoolTester::tearDown() {
}
} // namespace test
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,29 +16,33 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef _WIN32
#include <ws2tcpip.h>
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
// cppunit
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#ifndef IPV6_JOIN_GROUP
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
namespace test {
namespace dht {
namespace net {
class ThreadPoolTester : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ThreadPoolTester);
CPPUNIT_TEST(testThreadPool);
CPPUNIT_TEST(testExecutor);
CPPUNIT_TEST_SUITE_END();
bool set_nonblocking(int fd, bool nonblocking = true);
public:
/**
* Method automatically called before each test by CppUnit
*/
void setUp();
/**
* Method automatically called after each test CppUnit
*/
void tearDown();
#ifdef _WIN32
void udpPipe(int fds[2]);
#endif
void testThreadPool();
void testExecutor();
};
}
}
} // namespace test
+94 -85
View File
@@ -48,10 +48,16 @@ void print_id_req() {
std::cout << "An identity is required to perform this operation (run with -i)" << std::endl;
}
void print_node_info(const std::shared_ptr<DhtRunner>& dht, const dht_params& params) {
std::cout << "OpenDHT node " << dht->getNodeId() << " running on port " << dht->getBoundPort() << std::endl;
if (params.generate_identity)
std::cout << "Public key ID " << dht->getId() << std::endl;
void print_node_info(const std::shared_ptr<DhtRunner>& node, const dht_params& params) {
std::cout << "OpenDHT node " << node->getNodeId() << " running on ";
auto port4 = node->getBoundPort(AF_INET);
auto port6 = node->getBoundPort(AF_INET6);
if (port4 == port6)
std::cout << "port " << port4 << std::endl;
else
std::cout << "IPv4 port " << port4 << ", IPv6 port " << port6 << std::endl;
if (params.id.first)
std::cout << "Public key ID " << node->getId() << std::endl;
}
void print_help() {
@@ -110,13 +116,13 @@ void print_help() {
#endif
}
void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params
#ifdef OPENDHT_PROXY_SERVER
, std::map<in_port_t, std::unique_ptr<DhtProxyServer>>& proxies
#endif
)
{
print_node_info(dht, params);
print_node_info(node, params);
std::cout << " (type 'h' or 'help' for a list of possible commands)" << std::endl << std::endl;
#ifndef WIN32_NATIVE
@@ -145,11 +151,11 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
print_help();
continue;
} else if (op == "ll") {
print_node_info(dht, params);
print_node_info(node, params);
std::cout << "IPv4 stats:" << std::endl;
std::cout << dht->getNodesStats(AF_INET).toString() << std::endl;
std::cout << node->getNodesStats(AF_INET).toString() << std::endl;
std::cout << "IPv6 stats:" << std::endl;
std::cout << dht->getNodesStats(AF_INET6).toString() << std::endl;
std::cout << node->getNodesStats(AF_INET6).toString() << std::endl;
#ifdef OPENDHT_PROXY_SERVER
for (const auto& proxy : proxies) {
std::cout << "Stats for proxy on port " << proxy.first << std::endl;
@@ -159,29 +165,29 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
continue;
} else if (op == "lr") {
std::cout << "IPv4 routing table:" << std::endl;
std::cout << dht->getRoutingTablesLog(AF_INET) << std::endl;
std::cout << node->getRoutingTablesLog(AF_INET) << std::endl;
std::cout << "IPv6 routing table:" << std::endl;
std::cout << dht->getRoutingTablesLog(AF_INET6) << std::endl;
std::cout << node->getRoutingTablesLog(AF_INET6) << std::endl;
continue;
} else if (op == "ld") {
iss >> idstr;
InfoHash filter(idstr);
if (filter)
std::cout << dht->getStorageLog(filter) << std::endl;
std::cout << node->getStorageLog(filter) << std::endl;
else
std::cout << dht->getStorageLog() << std::endl;
std::cout << node->getStorageLog() << std::endl;
continue;
} else if (op == "ls") {
iss >> idstr;
InfoHash filter(idstr);
if (filter)
std::cout << dht->getSearchLog(filter) << std::endl;
std::cout << node->getSearchLog(filter) << std::endl;
else
std::cout << dht->getSearchesLog() << std::endl;
std::cout << node->getSearchesLog() << std::endl;
continue;
} else if (op == "la") {
std::cout << "Reported public addresses:" << std::endl;
auto addrs = dht->getPublicAddressStr();
auto addrs = node->getPublicAddressStr();
for (const auto& addr : addrs)
std::cout << addr << std::endl;
continue;
@@ -191,7 +197,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
auto addr = splitPort(idstr);
if (not addr.first.empty() and addr.second.empty())
addr.second = std::to_string(DHT_DEFAULT_PORT);
dht->bootstrap(addr.first.c_str(), addr.second.c_str());
node->bootstrap(addr.first.c_str(), addr.second.c_str());
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
@@ -199,15 +205,15 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
} else if (op == "log") {
iss >> idstr;
InfoHash filter(idstr);
params.log = filter == InfoHash{} ? !params.log : true;
params.log = filter ? true : !params.log;
if (params.log)
log::enableLogging(*dht);
log::enableLogging(*node);
else
log::disableLogging(*dht);
dht->setLogFilter(filter);
log::disableLogging(*node);
node->setLogFilter(filter);
continue;
} else if (op == "cc") {
dht->connectivityChanged();
node->connectivityChanged();
continue;
}
#ifdef OPENDHT_PROXY_SERVER
@@ -220,9 +226,9 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
try {
unsigned int port = std::stoi(idstr);
#ifdef OPENDHT_PUSH_NOTIFICATIONS
proxies.emplace(port, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(dht, port, pushServer)));
proxies.emplace(port, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(node, port, pushServer)));
#else
proxies.emplace(port, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(dht, port)));
proxies.emplace(port, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(node, port)));
#endif // OPENDHT_PUSH_NOTIFICATIONS
} catch (...) { }
continue;
@@ -238,16 +244,16 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
#endif //OPENDHT_PROXY_SERVER
#ifdef OPENDHT_PROXY_CLIENT
else if (op == "stt") {
dht->enableProxy(true);
node->enableProxy(true);
continue;
} else if (op == "stp") {
dht->enableProxy(false);
node->enableProxy(false);
continue;
}
#ifdef OPENDHT_PUSH_NOTIFICATIONS
else if (op == "rp") {
iss >> value;
dht->pushNotificationReceived({{"to", "dhtnode"}, {"token", value}});
node->pushNotificationReceived({{"to", "dhtnode"}, {"token", value}});
continue;
}
#endif // OPENDHT_PUSH_NOTIFICATIONS
@@ -284,7 +290,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
std::transform(key.begin(), key.end(), std::inserter(ks, ks.end()), [](Pht::Key::value_type& f) {
return std::make_pair(f.first, f.second.size());
});
indexes.emplace(index, Pht {index, std::move(ks), dht});
indexes.emplace(index, Pht {index, std::move(ks), node});
} catch (std::invalid_argument& e) { std::cout << e.what() << std::endl; }
}
}
@@ -308,35 +314,36 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
if (op == "g") {
std::string rem;
std::getline(iss, rem);
dht->get(id, [start](std::shared_ptr<Value> value) {
node->get(id, [start](const std::vector<std::shared_ptr<Value>>& values) {
auto now = std::chrono::high_resolution_clock::now();
std::cout << "Get: found value (after " << print_dt(now-start) << "s)" << std::endl;
std::cout << "\t" << *value << std::endl;
std::cout << "Get: found " << values.size() << " value(s) after " << print_duration(now-start) << std::endl;
for (const auto& value : values)
std::cout << "\t" << *value << std::endl;
return true;
}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Get: " << (ok ? "completed" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Get: " << (ok ? "completed" : "failure") << ", took " << print_duration(end-start) << std::endl;
}, {}, dht::Where {rem});
}
else if (op == "q") {
std::string rem;
std::getline(iss, rem);
dht->query(id, [start](const std::vector<std::shared_ptr<FieldValueIndex>>& field_value_indexes) {
node->query(id, [start](const std::vector<std::shared_ptr<FieldValueIndex>>& field_value_indexes) {
auto now = std::chrono::high_resolution_clock::now();
for (auto& index : field_value_indexes) {
std::cout << "Query: found field value index (after " << print_dt(now-start) << "s)" << std::endl;
std::cout << "Query: found field value index after " << print_duration(now-start) << std::endl;
std::cout << "\t" << *index << std::endl;
}
return true;
}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Query: " << (ok ? "completed" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Query: " << (ok ? "completed" : "failure") << ", took " << print_duration(end-start) << std::endl;
}, dht::Query {rem});
}
else if (op == "l") {
std::string rem;
std::getline(iss, rem);
auto token = dht->listen(id, [](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
auto token = node->listen(id, [](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
std::cout << "Listen: found " << values.size() << " values" << (expired ? " expired" : "") << std::endl;
for (const auto& value : values)
std::cout << "\t" << *value << std::endl;
@@ -355,17 +362,17 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
std::cerr << "Syntax: cl [key] [token]" << std::endl;
continue;
}
dht->cancelListen(id, token);
node->cancelListen(id, token);
}
else if (op == "p") {
std::string v;
iss >> v;
dht->put(id, dht::Value {
node->put(id, dht::Value {
dht::ValueType::USER_DATA.id,
std::vector<uint8_t> {v.begin(), v.end()}
}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Put: " << (ok ? "success" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Put: " << (ok ? "success" : "failure") << ", took " << print_duration(end-start) << std::endl;
});
}
else if (op == "pp") {
@@ -375,55 +382,55 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
dht::ValueType::USER_DATA.id,
std::vector<uint8_t> {v.begin(), v.end()}
);
dht->put(id, value, [start,value](bool ok) {
node->put(id, value, [start,value](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
auto flags(std::cout.flags());
std::cout << "Put: " << (ok ? "success" : "failure") << " (took " << print_dt(end-start) << "s). Value ID: " << std::hex << value->id << std::endl;
std::cout << "Put: " << (ok ? "success" : "failure") << ", took " << print_duration(end-start) << ". Value ID: " << std::hex << value->id << std::endl;
std::cout.flags(flags);
}, time_point::max(), true);
}
else if (op == "cpp") {
std::string rem;
iss >> rem;
dht->cancelPut(id, std::stoul(rem, nullptr, 16));
node->cancelPut(id, std::stoul(rem, nullptr, 16));
}
else if (op == "s") {
if (not params.generate_identity) {
if (not params.id.first) {
print_id_req();
continue;
}
std::string v;
iss >> v;
dht->putSigned(id, dht::Value {
node->putSigned(id, dht::Value {
dht::ValueType::USER_DATA.id,
std::vector<uint8_t> {v.begin(), v.end()}
}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Put signed: " << (ok ? "success" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Put signed: " << (ok ? "success" : "failure") << " (took " << print_duration(end-start) << "s)" << std::endl;
});
}
else if (op == "e") {
if (not params.generate_identity) {
if (not params.id.first) {
print_id_req();
continue;
}
std::string tostr;
std::string v;
iss >> tostr >> v;
dht->putEncrypted(id, InfoHash(tostr), dht::Value {
node->putEncrypted(id, InfoHash(tostr), dht::Value {
dht::ValueType::USER_DATA.id,
std::vector<uint8_t> {v.begin(), v.end()}
}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Put encrypted: " << (ok ? "success" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Put encrypted: " << (ok ? "success" : "failure") << " (took " << print_duration(end-start) << std::endl;
});
}
else if (op == "a") {
in_port_t port;
iss >> port;
dht->put(id, dht::Value {dht::IpServiceAnnouncement::TYPE.id, dht::IpServiceAnnouncement(port)}, [start](bool ok) {
node->put(id, dht::Value {dht::IpServiceAnnouncement::TYPE.id, dht::IpServiceAnnouncement(port)}, [start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Announce: " << (ok ? "success" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
std::cout << "Announce: " << (ok ? "success" : "failure") << " (took " << print_duration(end-start) << std::endl;
});
}
#ifdef OPENDHT_INDEXATION
@@ -446,7 +453,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
[start](bool ok) {
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Pht::lookup: " << (ok ? "done." : "failed.")
<< " took " << print_dt(end-start) << "s)" << std::endl;
<< " took " << print_duration(end-start) << std::endl;
}, exact_match.size() != 0 and exact_match == "false" ? false : true
);
@@ -484,59 +491,61 @@ main(int argc, char **argv)
#ifdef WIN32_NATIVE
gnutls_global_init();
#endif
auto params = parseArgs(argc, argv);
if (params.help) {
print_usage();
return 0;
}
if (params.version) {
print_version();
return 0;
}
auto dht = std::make_shared<DhtRunner>();
if (params.daemonize) {
daemonize();
}
setupSignals();
auto node = std::make_shared<DhtRunner>();
try {
auto params = parseArgs(argc, argv);
if (params.help) {
print_usage();
return 0;
}
if (params.version) {
print_version();
return 0;
}
if (params.daemonize) {
daemonize();
} else if (params.service) {
setupSignals();
}
dht::crypto::Identity crt {};
if (params.generate_identity) {
if (not params.id.first and params.generate_identity) {
auto ca_tmp = dht::crypto::generateEcIdentity("DHT Node CA");
crt = dht::crypto::generateIdentity("DHT Node", ca_tmp);
params.id = dht::crypto::generateIdentity("DHT Node", ca_tmp);
if (not params.save_identity.empty()) {
dht::crypto::saveIdentity(ca_tmp, params.save_identity + "_ca", params.privkey_pwd);
dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd);
}
}
dht::DhtRunner::Config config {};
config.dht_config.node_config.network = params.network;
config.dht_config.node_config.maintain_storage = false;
config.dht_config.node_config.persist_path = params.persist_path;
config.dht_config.id = crt;
config.dht_config.id = params.id;
config.threaded = true;
config.proxy_server = params.proxyclient;
config.push_node_id = "dhtnode";
config.peer_discovery = params.peer_discovery;
config.peer_publish = params.peer_discovery;
if (not params.proxyclient.empty())
dht->setPushNotificationToken(params.devicekey);
dht->run(params.port, config);
node->setPushNotificationToken(params.devicekey);
dht::DhtRunner::Context context {};
if (params.log) {
if (params.syslog or (params.daemonize and params.logfile.empty()))
log::enableSyslog(*dht, "dhtnode");
context.logger = log::getSyslogLogger("dhtnode");
else if (not params.logfile.empty())
log::enableFileLogging(*dht, params.logfile);
context.logger = log::getFileLogger(params.logfile);
else
log::enableLogging(*dht);
context.logger = log::getStdLogger();
}
node->run(params.port, config, std::move(context));
if (not params.bootstrap.first.empty()) {
//std::cout << "Bootstrap: " << params.bootstrap.first << ":" << params.bootstrap.second << std::endl;
dht->bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
node->bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
}
#ifdef OPENDHT_PROXY_SERVER
@@ -544,7 +553,7 @@ main(int argc, char **argv)
#endif
if (params.proxyserver != 0) {
#ifdef OPENDHT_PROXY_SERVER
proxies.emplace(params.proxyserver, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(dht, params.proxyserver, params.pushserver)));
proxies.emplace(params.proxyserver, std::unique_ptr<DhtProxyServer>(new DhtProxyServer(node, params.proxyserver, params.pushserver)));
#else
std::cerr << "DHT proxy server requested but OpenDHT built without proxy server support." << std::endl;
exit(EXIT_FAILURE);
@@ -554,7 +563,7 @@ main(int argc, char **argv)
if (params.daemonize or params.service)
while (runner.wait());
else
cmd_loop(dht, params
cmd_loop(node, params
#ifdef OPENDHT_PROXY_SERVER
, proxies
#endif
@@ -566,9 +575,9 @@ main(int argc, char **argv)
std::condition_variable cv;
std::mutex m;
std::atomic_bool done {false};
bool done {false};
dht->shutdown([&]()
node->shutdown([&]()
{
std::lock_guard<std::mutex> lk(m);
done = true;
@@ -577,9 +586,9 @@ main(int argc, char **argv)
// wait for shutdown
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [&](){ return done.load(); });
cv.wait(lk, [&](){ return done; });
dht->join();
node->join();
#ifdef WIN32_NATIVE
gnutls_global_deinit();
#endif
+1 -1
View File
@@ -1 +1 @@
DHT_ARGS=-b bootstrap.ring.cx -p 4222 -v
DHT_ARGS=-b bootstrap.jami.net -p 4222 -v
+3 -3
View File
@@ -1,13 +1,13 @@
[Unit]
Description=OpenDHT standalone node
After=network.target
[Service]
EnvironmentFile=@sysconfdir@/dhtnode.conf
ExecStart=@bindir@/dhtnode -d $DHT_ARGS
ExecStart=@bindir@/dhtnode -s $DHT_ARGS
KillMode=process
Restart=on-failure
Type=forking
Type=simple
DynamicUser=yes
[Install]
+81 -32
View File
@@ -22,6 +22,8 @@
#pragma once
#include <opendht.h>
#include <opendht/log.h>
#include <opendht/crypto.h>
#ifndef WIN32_NATIVE
#include <getopt.h>
#include <readline/readline.h>
@@ -86,53 +88,79 @@ bool isInfoHash(const dht::InfoHash& h) {
return true;
}
std::vector<uint8_t>
loadFile(const std::string& path)
{
std::vector<uint8_t> buffer;
std::ifstream file(path, std::ios::binary);
if (!file)
throw std::runtime_error("Can't read file: "+path);
file.seekg(0, std::ios::end);
auto size = file.tellg();
if (size > std::numeric_limits<unsigned>::max())
throw std::runtime_error("File is too big: "+path);
buffer.resize(size);
file.seekg(0, std::ios::beg);
if (!file.read((char*)buffer.data(), size))
throw std::runtime_error("Can't load file: "+path);
return buffer;
}
static const constexpr in_port_t DHT_DEFAULT_PORT = 4222;
struct dht_params {
bool help {false}; // print help and exit
bool version {false};
bool log {false};
std::string logfile {};
bool syslog {false};
in_port_t port {0};
dht::NetId network {0};
bool generate_identity {false};
bool daemonize {false};
bool service {false};
bool peer_discovery {false};
bool log {false};
bool syslog {false};
std::string logfile {};
std::pair<std::string, std::string> bootstrap {};
dht::NetId network {0};
in_port_t port {0};
in_port_t proxyserver {0};
std::string proxyclient {};
std::string pushserver {};
std::string devicekey {};
std::string persist_path {};
dht::crypto::Identity id {};
std::string privkey_pwd {};
std::string save_identity {};
};
static const constexpr struct option long_options[] = {
{"help", no_argument , nullptr, 'h'},
{"port", required_argument, nullptr, 'p'},
{"net", required_argument, nullptr, 'n'},
{"bootstrap", required_argument, nullptr, 'b'},
{"identity", no_argument , nullptr, 'i'},
{"verbose", no_argument , nullptr, 'v'},
{"daemonize", no_argument , nullptr, 'd'},
{"service", no_argument , nullptr, 's'},
{"peer-discovery", no_argument , nullptr, 'D'},
{"persist", required_argument, nullptr, 'f'},
{"logfile", required_argument, nullptr, 'l'},
{"syslog", no_argument , nullptr, 'L'},
{"proxyserver", required_argument, nullptr, 'S'},
{"proxyclient", required_argument, nullptr, 'C'},
{"pushserver", required_argument, nullptr, 'y'},
{"devicekey", required_argument, nullptr, 'z'},
{"version", no_argument , nullptr, 'V'},
{nullptr, 0 , nullptr, 0}
{"help", no_argument , nullptr, 'h'},
{"port", required_argument, nullptr, 'p'},
{"net", required_argument, nullptr, 'n'},
{"bootstrap", required_argument, nullptr, 'b'},
{"identity", no_argument , nullptr, 'i'},
{"save-identity", required_argument, nullptr, 'I'},
{"certificate", required_argument, nullptr, 'c'},
{"privkey", required_argument, nullptr, 'k'},
{"privkey-password", required_argument, nullptr, 'm'},
{"verbose", no_argument , nullptr, 'v'},
{"daemonize", no_argument , nullptr, 'd'},
{"service", no_argument , nullptr, 's'},
{"peer-discovery", no_argument , nullptr, 'D'},
{"persist", required_argument, nullptr, 'f'},
{"logfile", required_argument, nullptr, 'l'},
{"syslog", no_argument , nullptr, 'L'},
{"proxyserver", required_argument, nullptr, 'S'},
{"proxyclient", required_argument, nullptr, 'C'},
{"pushserver", required_argument, nullptr, 'y'},
{"devicekey", required_argument, nullptr, 'z'},
{"version", no_argument , nullptr, 'V'},
{nullptr, 0 , nullptr, 0}
};
dht_params
parseArgs(int argc, char **argv) {
dht_params params;
int opt;
std::string privkey;
while ((opt = getopt_long(argc, argv, "hidsvDp:n:b:f:l:", long_options, nullptr)) != -1) {
switch (opt) {
case 'p': {
@@ -200,10 +228,36 @@ parseArgs(int argc, char **argv) {
case 's':
params.service = true;
break;
case 'c': {
try {
params.id.second = std::make_shared<dht::crypto::Certificate>(loadFile(optarg));
} catch (const std::exception& e) {
throw std::runtime_error(std::string("Error loading certificate: ") + e.what());
}
break;
}
case 'k':
privkey = optarg;
break;
case 'm':
params.privkey_pwd = optarg;
break;
case 'I':
params.save_identity = optarg;
break;
default:
break;
}
}
if (not privkey.empty()) {
try {
params.id.first = std::make_shared<dht::crypto::PrivateKey>(loadFile(privkey), params.privkey_pwd);
} catch (const std::exception& e) {
throw std::runtime_error(std::string("Error loading private key: ") + e.what());
}
}
if (params.save_identity.empty())
params.privkey_pwd.clear();
return params;
}
@@ -228,18 +282,17 @@ readLine(const char* prefix = PROMPT)
struct ServiceRunner {
bool wait() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&]{return terminate;});
cv.wait(lock, [&]{return terminate.load();});
return !terminate;
}
void kill() {
std::lock_guard<std::mutex> lock(m);
terminate = true;
cv.notify_all();
}
private:
std::condition_variable cv;
std::mutex m;
bool terminate = false;
std::atomic_bool terminate {false};
};
ServiceRunner runner;
@@ -250,6 +303,8 @@ void signal_handler(int sig)
case SIGHUP:
break;
case SIGINT:
close(STDIN_FILENO);
// fall through
case SIGTERM:
runner.kill();
break;
@@ -283,14 +338,8 @@ void daemonize()
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0) {
exit(EXIT_FAILURE);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
setupSignals();
#endif
}