mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-11 22:07:10 +00:00
Compare commits
167
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44822f944b | ||
|
|
406a1c1152 | ||
|
|
f9939ce336 | ||
|
|
d9bced965b | ||
|
|
4d78aea05b | ||
|
|
9b42afa9ca | ||
|
|
aa5b8b84a8 | ||
|
|
d0a8a92a56 | ||
|
|
cf82f74e15 | ||
|
|
a952ddec53 | ||
|
|
fa7efd086f | ||
|
|
8e28e86caf | ||
|
|
65de9622fb | ||
|
|
210c4b2077 | ||
|
|
e8cb635b3a | ||
|
|
f41c8fef99 | ||
|
|
02147b0b16 | ||
|
|
79e266aac6 | ||
|
|
9d75ed14b4 | ||
|
|
fcca618c48 | ||
|
|
73bcebf355 | ||
|
|
057443e4a0 | ||
|
|
99f8c2950b | ||
|
|
4132c63faf | ||
|
|
7f2b5a44ff | ||
|
|
7db0c15483 | ||
|
|
2fc7cc57a9 | ||
|
|
4970a2aee5 | ||
|
|
25b6df5355 | ||
|
|
732479736b | ||
|
|
696ac1bbd5 | ||
|
|
3b2e5a13bf | ||
|
|
26a7aec7cc | ||
|
|
b73a50bace | ||
|
|
70ccbe4e40 | ||
|
|
6bb00ab732 | ||
|
|
2e279852cd | ||
|
|
09b4e71dc5 | ||
|
|
b40713596c | ||
|
|
c5485a795a | ||
|
|
b7c5d4a550 | ||
|
|
0aa1c9e42d | ||
|
|
5823e98c76 | ||
|
|
3c45e1996d | ||
|
|
e2ce496779 | ||
|
|
4540be7460 | ||
|
|
7c85b74de6 | ||
|
|
fccd569059 | ||
|
|
768bfa5d44 | ||
|
|
ff6e38571d | ||
|
|
0a5a609322 | ||
|
|
c424eb9160 | ||
|
|
501ba77ec7 | ||
|
|
dc23ee0c7a | ||
|
|
e98f06e84a | ||
|
|
19c36284dc | ||
|
|
358d8bd7b3 | ||
|
|
c17508862c | ||
|
|
2277a4959c | ||
|
|
d5427df9eb | ||
|
|
36206a80fc | ||
|
|
ab7d175322 | ||
|
|
802528266a | ||
|
|
95d98f4659 | ||
|
|
4176302a03 | ||
|
|
b3119cce13 | ||
|
|
9987485f63 | ||
|
|
b08b2f14f2 | ||
|
|
1e7ba56aeb | ||
|
|
faf23195a4 | ||
|
|
0d66b9435f | ||
|
|
49353e2d5c | ||
|
|
c4d5621f67 | ||
|
|
aa2227bdfc | ||
|
|
34908d573f | ||
|
|
469774037e | ||
|
|
93c5ad7cbc | ||
|
|
03d52e4284 | ||
|
|
9d83ee169b | ||
|
|
43b181ebbf | ||
|
|
ac65ca5177 | ||
|
|
42671be21e | ||
|
|
efa6930de2 | ||
|
|
19c47ec781 | ||
|
|
435cd554e6 | ||
|
|
10c70ebd12 | ||
|
|
7da3ff1bba | ||
|
|
a222e30428 | ||
|
|
bd822fce19 | ||
|
|
cabe9dbeb5 | ||
|
|
99b7a07350 | ||
|
|
756e0bd3d8 | ||
|
|
9b0ce12b5f | ||
|
|
e29c2df002 | ||
|
|
b03a8b5b50 | ||
|
|
32f5175d68 | ||
|
|
7d3a54db57 | ||
|
|
3fb7c2acfe | ||
|
|
bce5d35b51 | ||
|
|
b6dca5ccd6 | ||
|
|
23b2712400 | ||
|
|
63bec73885 | ||
|
|
af5e0c8982 | ||
|
|
5a7c8753e1 | ||
|
|
19fdec96ca | ||
|
|
2208a06232 | ||
|
|
2cfcaf3909 | ||
|
|
620868b5d6 | ||
|
|
e7295bac7b | ||
|
|
38aa86de2a | ||
|
|
fdf476a3f3 | ||
|
|
22f27a6cc0 | ||
|
|
c72ea8ce77 | ||
|
|
ea168353b9 | ||
|
|
79b9c4838e | ||
|
|
d6e86ebcc9 | ||
|
|
197aaa47f0 | ||
|
|
ad234004aa | ||
|
|
a88e6a4c5f | ||
|
|
c776dad96f | ||
|
|
31fedd529b | ||
|
|
e9adff9dc5 | ||
|
|
bfd58a204b | ||
|
|
867bcf1514 | ||
|
|
fb882ee440 | ||
|
|
215d3d2847 | ||
|
|
43a345ba0c | ||
|
|
f73f5e2798 | ||
|
|
3724670fcc | ||
|
|
e7db64bd74 | ||
|
|
9c29b8a29e | ||
|
|
c22f0e4d43 | ||
|
|
4e2b11c24c | ||
|
|
8c34e927ea | ||
|
|
8a5de47aa0 | ||
|
|
7f84c1e397 | ||
|
|
65c915fd9d | ||
|
|
0fd4f73ab1 | ||
|
|
01117567b1 | ||
|
|
d68cc5cf40 | ||
|
|
6db16be2fa | ||
|
|
5166b1add9 | ||
|
|
9fadcc907c | ||
|
|
42171efc3f | ||
|
|
206f12648f | ||
|
|
ecd0573c4d | ||
|
|
2d9f6241a9 | ||
|
|
77ee50f5a6 | ||
|
|
297c37e609 | ||
|
|
9bb1ab43eb | ||
|
|
cd36b13c30 | ||
|
|
5d63084627 | ||
|
|
ab7d1d6582 | ||
|
|
77ea6d8c2f | ||
|
|
b5cd629160 | ||
|
|
39467c8b71 | ||
|
|
87740e3b38 | ||
|
|
19848a9b72 | ||
|
|
36e9998fe2 | ||
|
|
b2529c241e | ||
|
|
83c47037d2 | ||
|
|
125b6f9236 | ||
|
|
e260ba6b78 | ||
|
|
eafb934e85 | ||
|
|
c3d3da20f6 | ||
|
|
6036ccdbaa | ||
|
|
9404a4d069 |
No files matched your search
@@ -0,0 +1,4 @@
|
||||
[submodule "argon2"]
|
||||
path = argon2
|
||||
url = https://github.com/P-H-C/phc-winner-argon2
|
||||
ignore = dirty
|
||||
+56
-13
@@ -1,23 +1,25 @@
|
||||
cmake_minimum_required (VERSION 2.8.6)
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 1)
|
||||
set (opendht_VERSION_MINOR 2.0)
|
||||
set (opendht_VERSION_MINOR 3.2)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
|
||||
include(GNUInstallDirs)
|
||||
set (prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set (exec_prefix "\${prefix}")
|
||||
set (libdir "\${exec_prefix}/lib")
|
||||
set (includedir "\${prefix}/include")
|
||||
set (libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set (includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
option (OPENDHT_STATIC "Build static library" ON)
|
||||
option (OPENDHT_SHARED "Build shared library" ON)
|
||||
option (OPENDHT_LOG "Build with logs" ON)
|
||||
option (OPENDHT_PYTHON "Build Python bindings" OFF)
|
||||
option (OPENDHT_TOOLS "Build DHT tools" ON)
|
||||
option (OPENDHT_ARGON2 "Use included argon2 sources" OFF)
|
||||
option (OPENDHT_LTO "Build with LTO" OFF)
|
||||
|
||||
find_package (GnuTLS 3.3 REQUIRED)
|
||||
@@ -25,8 +27,16 @@ find_package (Msgpack 1.2 REQUIRED)
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
if (NOT OPENDHT_ARGON2)
|
||||
find_package(PkgConfig)
|
||||
pkg_search_module(argon2 libargon2)
|
||||
if (NOT argon2_FOUND)
|
||||
message("Argon2 not found, using included version.")
|
||||
set(OPENDHT_ARGON2 ON)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++11 -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++11 -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
@@ -60,16 +70,12 @@ list (APPEND opendht_SOURCES
|
||||
src/network_engine.cpp
|
||||
src/securedht.cpp
|
||||
src/dhtrunner.cpp
|
||||
src/argon2/argon2.c
|
||||
src/argon2/core.c
|
||||
src/argon2/blake2/blake2b.c
|
||||
src/argon2/thread.c
|
||||
src/argon2/encoding.c
|
||||
src/argon2/ref.c
|
||||
src/indexation/pht.cpp
|
||||
src/log.cpp
|
||||
)
|
||||
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht/def.h
|
||||
include/opendht/utils.h
|
||||
include/opendht/sockaddr.h
|
||||
include/opendht/rng.h
|
||||
@@ -83,6 +89,7 @@ list (APPEND opendht_HEADERS
|
||||
include/opendht/routing_table.h
|
||||
include/opendht/node_cache.h
|
||||
include/opendht/network_engine.h
|
||||
include/opendht/net.h
|
||||
include/opendht/scheduler.h
|
||||
include/opendht/rate_limiter.h
|
||||
include/opendht/securedht.h
|
||||
@@ -98,12 +105,28 @@ configure_file (
|
||||
@ONLY
|
||||
)
|
||||
|
||||
include_directories (
|
||||
include_directories(
|
||||
./
|
||||
include/
|
||||
include/opendht/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
)
|
||||
if(OPENDHT_ARGON2)
|
||||
# make sure argon2 submodule is up to date and initialized
|
||||
message("Initializing Argon2 submodule")
|
||||
execute_process(COMMAND git submodule update --init)
|
||||
|
||||
# add local argon2 files to build
|
||||
list (APPEND opendht_SOURCES
|
||||
argon2/src/argon2.c
|
||||
argon2/src/core.c
|
||||
argon2/src/blake2/blake2b.c
|
||||
argon2/src/thread.c
|
||||
argon2/src/ref.c
|
||||
argon2/src/encoding.c
|
||||
)
|
||||
include_directories(argon2/include/)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(CMAKE_INSTALL_LIBDIR lib)
|
||||
@@ -118,8 +141,14 @@ if (OPENDHT_STATIC)
|
||||
if (OPENDHT_LTO)
|
||||
target_link_libraries(opendht-static -flto -fuse-linker-plugin)
|
||||
endif ()
|
||||
if (OPENDHT_ARGON2)
|
||||
target_include_directories(opendht-static SYSTEM PRIVATE argon2)
|
||||
else ()
|
||||
target_link_libraries(opendht-static ${argon2_LIBRARIES})
|
||||
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
endif ()
|
||||
target_link_libraries(opendht-static gnutls nettle)
|
||||
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_SHARED)
|
||||
@@ -129,11 +158,18 @@ if (OPENDHT_SHARED)
|
||||
)
|
||||
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
|
||||
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
|
||||
if (OPENDHT_LTO)
|
||||
target_link_libraries(opendht -flto -fuse-linker-plugin)
|
||||
endif ()
|
||||
if (OPENDHT_ARGON2)
|
||||
target_include_directories(opendht SYSTEM PRIVATE argon2)
|
||||
else ()
|
||||
target_link_libraries(opendht ${argon2_LIBRARIES})
|
||||
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
endif ()
|
||||
target_link_libraries(opendht gnutls nettle)
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_TOOLS)
|
||||
@@ -145,5 +181,12 @@ if (OPENDHT_PYTHON)
|
||||
add_subdirectory(python)
|
||||
endif ()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake"
|
||||
VERSION ${opendht_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
|
||||
+2
-2
@@ -15,7 +15,6 @@ Release/
|
||||
*.VC.VC.opendb
|
||||
*.VC.db
|
||||
*.db
|
||||
*.filters
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
@@ -245,4 +244,5 @@ _Pvt_Extensions
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
!config.h
|
||||
!config.h
|
||||
contrib/build/
|
||||
+13
-13
@@ -141,22 +141,22 @@
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\argon2\argon2.c" />
|
||||
<ClCompile Include="..\src\argon2\core.c" />
|
||||
<ClCompile Include="..\src\argon2\encoding.c" />
|
||||
<ClCompile Include="..\src\argon2\opt.c" />
|
||||
<ClCompile Include="..\src\argon2\ref.c" />
|
||||
<ClCompile Include="..\src\argon2\thread.c" />
|
||||
<ClCompile Include="..\argon2\argon2.c" />
|
||||
<ClCompile Include="..\argon2\core.c" />
|
||||
<ClCompile Include="..\argon2\encoding.c" />
|
||||
<ClCompile Include="..\argon2\opt.c" />
|
||||
<ClCompile Include="..\argon2\ref.c" />
|
||||
<ClCompile Include="..\argon2\thread.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\argon2\argon2.h" />
|
||||
<ClInclude Include="..\src\argon2\core.h" />
|
||||
<ClInclude Include="..\src\argon2\encoding.h" />
|
||||
<ClInclude Include="..\src\argon2\opt.h" />
|
||||
<ClInclude Include="..\src\argon2\ref.h" />
|
||||
<ClInclude Include="..\src\argon2\thread.h" />
|
||||
<ClInclude Include="..\argon2\argon2.h" />
|
||||
<ClInclude Include="..\argon2\core.h" />
|
||||
<ClInclude Include="..\argon2\encoding.h" />
|
||||
<ClInclude Include="..\argon2\opt.h" />
|
||||
<ClInclude Include="..\argon2\ref.h" />
|
||||
<ClInclude Include="..\argon2\thread.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
+6
-6
@@ -137,15 +137,15 @@
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\argon2\blake2\blake2b.c" />
|
||||
<ClCompile Include="..\argon2\blake2\blake2b.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\argon2\blake2\blake2-impl.h" />
|
||||
<ClInclude Include="..\src\argon2\blake2\blake2.h" />
|
||||
<ClInclude Include="..\src\argon2\blake2\blamka-round-opt.h" />
|
||||
<ClInclude Include="..\src\argon2\blake2\blamka-round-ref.h" />
|
||||
<ClInclude Include="..\argon2\blake2\blake2-impl.h" />
|
||||
<ClInclude Include="..\argon2\blake2\blake2.h" />
|
||||
<ClInclude Include="..\argon2\blake2\blamka-round-opt.h" />
|
||||
<ClInclude Include="..\argon2\blake2\blamka-round-ref.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -0,0 +1,20 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ARGON2_VERSION=1eea0104e7cb2a38c617cf90ffa46ce5db6aceda
|
||||
set ARGON2_URL=https://github.com/P-H-C/phc-winner-argon2/archive/%ARGON2_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ARGON2_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ARGON2_URL%
|
||||
)
|
||||
|
||||
7z -y x %ARGON2_VERSION%.tar.gz && 7z -y x %ARGON2_VERSION%.tar -o%BUILD%
|
||||
del %ARGON2_VERSION%.tar && del %ARGON2_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\phc-winner-argon2-%ARGON2_VERSION% argon2
|
||||
|
||||
cd %BUILD%\argon2
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,23 @@
|
||||
@echo OFF
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
set SRC=%~dp0
|
||||
|
||||
if "%USE_CACHE%"=="" (
|
||||
set USE_CACHE=0
|
||||
)
|
||||
|
||||
set DEPENDENCIES=( ^
|
||||
argon2, ^
|
||||
gmp, ^
|
||||
gnutls, ^
|
||||
iconv, ^
|
||||
msgpack, ^
|
||||
nettle, ^
|
||||
opendht, ^
|
||||
zlib ^
|
||||
)
|
||||
|
||||
for %%I in %DEPENDENCIES% do (
|
||||
call %SRC%\%%I\fetch_and_patch.bat
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set GMP_VERSION=3c8f5a0ae0c2ac9ff0ea31b27f71b152979b556d
|
||||
set GMP_URL=https://github.com/ShiftMediaProject/gmp/archive/%GMP_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%GMP_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %GMP_URL%
|
||||
)
|
||||
|
||||
7z -y x %GMP_VERSION%.tar.gz && 7z -y x %GMP_VERSION%.tar -o%BUILD%
|
||||
del %GMP_VERSION%.tar && del %GMP_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\gmp-%GMP_VERSION% gmp
|
||||
|
||||
cd %BUILD%\gmp
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\gmp\gmp-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,110 @@
|
||||
--- a/SMP/libgmp.vcxproj
|
||||
+++ b/SMP/libgmp.vcxproj
|
||||
@@ -1248,6 +1248,7 @@
|
||||
<ProjectGuid>{02B94302-23D6-43EF-8865-95CDE99D5DC2}</ProjectGuid>
|
||||
<RootNamespace>libgmp</RootNamespace>
|
||||
<ProjectName>libgmp</ProjectName>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -1368,65 +1369,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmpd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmpd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmpd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmpd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--- a/SMP/config.h
|
||||
+++ b/SMP/config.h
|
||||
@@ -202,7 +202,7 @@
|
||||
/* #undef HAVE_NATIVE_mpn_add_n_sub_n */
|
||||
#define HAVE_NATIVE_mpn_add_nc 1
|
||||
#if defined(__x86_64) || defined(_M_X64)
|
||||
-#define HAVE_NATIVE_mpn_addaddmul_1msb0 1
|
||||
+#define HAVE_NATIVE_mpn_addaddmul_1msb0 0
|
||||
#define HAVE_NATIVE_mpn_addlsh1_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh2_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh_n 1
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set GNUTLS_VERSION=f2d0ade53ff644da55244aed79d05eca78d11a2f
|
||||
set GNUTLS_URL=https://github.com/ShiftMediaProject/gnutls/archive/%GNUTLS_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%GNUTLS_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %GNUTLS_URL%
|
||||
)
|
||||
|
||||
7z -y x %GNUTLS_VERSION%.tar.gz && 7z -y x %GNUTLS_VERSION%.tar -o%BUILD%
|
||||
del %GNUTLS_VERSION%.tar && del %GNUTLS_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\gnutls-%GNUTLS_VERSION% gnutls
|
||||
|
||||
cd %BUILD%\gnutls
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-no-egd.patch
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\read-file-limits.h.patch
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,107 @@
|
||||
{a => b}/lib/nettle/Makefile.am | 2 +-
|
||||
{a => b}/lib/nettle/Makefile.in | 11 +++++------
|
||||
{a => b}/lib/nettle/rnd-common.c | 7 +++++--
|
||||
3 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am
|
||||
index e84ed1f..4767663 100644
|
||||
--- a/lib/nettle/Makefile.am
|
||||
+++ b/lib/nettle/Makefile.am
|
||||
@@ -38,7 +38,7 @@ endif
|
||||
|
||||
noinst_LTLIBRARIES = libcrypto.la
|
||||
|
||||
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
|
||||
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
|
||||
gnettle.h rnd-common.h rnd-common.c \
|
||||
rnd.c
|
||||
|
||||
diff --git a/lib/nettle/Makefile.in b/lib/nettle/Makefile.in
|
||||
index 88ae7cf..6ddd536 100644
|
||||
--- a/lib/nettle/Makefile.in
|
||||
+++ b/lib/nettle/Makefile.in
|
||||
@@ -221,8 +221,8 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
libcrypto_la_LIBADD =
|
||||
-am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c egd.c \
|
||||
- egd.h gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
|
||||
+am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c \
|
||||
+ gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
|
||||
int/drbg-aes-self-test.c int/dsa-fips.h \
|
||||
int/dsa-keygen-fips186.c int/dsa-validate.c \
|
||||
int/provable-prime.c int/drbg-aes.c int/drbg-aes.h \
|
||||
@@ -233,7 +233,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
|
||||
@ENABLE_FIPS140_TRUE@ int/dsa-keygen-fips186.lo \
|
||||
@ENABLE_FIPS140_TRUE@ int/dsa-validate.lo int/provable-prime.lo \
|
||||
@ENABLE_FIPS140_TRUE@ int/drbg-aes.lo int/rsa-keygen-fips186.lo
|
||||
-am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo egd.lo \
|
||||
+am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo \
|
||||
rnd-common.lo rnd.lo $(am__objects_1)
|
||||
libcrypto_la_OBJECTS = $(am_libcrypto_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
@@ -1279,8 +1279,8 @@ AM_CPPFLAGS = -I$(srcdir)/int -I$(srcdir)/../../gl \
|
||||
-I$(builddir)/../includes -I$(builddir)/../../gl \
|
||||
-I$(srcdir)/.. $(am__append_1)
|
||||
noinst_LTLIBRARIES = libcrypto.la
|
||||
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
|
||||
- gnettle.h rnd-common.h rnd-common.c rnd.c $(am__append_2)
|
||||
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c gnettle.h \
|
||||
+ rnd-common.h rnd-common.c rnd.c $(am__append_2)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -1355,7 +1355,6 @@ distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@
|
||||
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egd.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi.Plo@am__quote@
|
||||
diff --git a/lib/nettle/rnd-common.c b/lib/nettle/rnd-common.c
|
||||
index c69ff3b..80b5f32 100644
|
||||
--- a/lib/nettle/rnd-common.c
|
||||
+++ b/lib/nettle/rnd-common.c
|
||||
@@ -139,7 +139,7 @@ void _rnd_system_entropy_deinit(void)
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <locks.h>
|
||||
-#include "egd.h"
|
||||
+//#include "egd.h"
|
||||
|
||||
static int _gnutls_urandom_fd = -1;
|
||||
static mode_t _gnutls_urandom_fd_mode = 0;
|
||||
@@ -208,6 +208,7 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if 0
|
||||
static
|
||||
int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
|
||||
{
|
||||
@@ -232,6 +233,7 @@ int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
int _rnd_system_entropy_check(void)
|
||||
{
|
||||
@@ -268,6 +270,7 @@ int _rnd_system_entropy_init(void)
|
||||
|
||||
return 0;
|
||||
fallback:
|
||||
+#if 0
|
||||
_gnutls_urandom_fd = _rndegd_connect_socket();
|
||||
if (_gnutls_urandom_fd < 0) {
|
||||
_gnutls_debug_log("Cannot open egd socket!\n");
|
||||
@@ -281,7 +284,7 @@ fallback:
|
||||
}
|
||||
|
||||
_rnd_get_system_entropy = _rnd_get_system_entropy_egd;
|
||||
-
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,445 @@
|
||||
--- a/SMP/libgnutls.vcxproj
|
||||
+++ b/SMP/libgnutls.vcxproj
|
||||
@@ -743,91 +744,91 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutlsd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -1834,7 +1834,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FloatingPointExceptions>false</FloatingPointExceptions>
|
||||
- <PreprocessorDefinitions>HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <PreprocessorDefinitions>RING_UWP;HAVE_WIN32_LOCKS;HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\;.\lib;..\lib;..\lib\accelerated;..\lib\auth;..\lib\ext;..\lib\extras;..\lib\minitasn1;..\lib\nettle;..\lib\nettle\int;..\lib\openpgp;..\lib\opencdk;..\lib\x509;..\lib\includes;..\gl;$(OutDir)\include;..\lib\accelerated\x86;$(ProjectDir)\..\..\prebuilt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DisableSpecificWarnings>4996;4244;4018;4146;4267;4028;4101;4020;4047;4024;4005;4311;4312;4334;4116;4090;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
@@ -1850,7 +1850,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
- <AdditionalDependencies>Crypt32.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
+ <AdditionalDependencies>bcrypt.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir)\lib\x64\;$(ProjectDir)\..\..\prebuilt\lib\x64\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/IGNORE:4006,4221,4042 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
--- a/lib/nettle/rnd-common.c
|
||||
+++ b/lib/nettle/rnd-common.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
+#include <bcrypt.h>
|
||||
|
||||
/* gnulib wants to claim strerror even if it cannot provide it. WTF */
|
||||
#undef strerror
|
||||
@@ -88,16 +89,25 @@ void _rnd_get_event(struct event_st *e)
|
||||
#include <wincrypt.h>
|
||||
|
||||
static HCRYPTPROV device_fd = 0;
|
||||
+static BCRYPT_ALG_HANDLE bdevice_fd = 0;
|
||||
|
||||
static
|
||||
int _rnd_get_system_entropy_win32(void* rnd, size_t size)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
if (!CryptGenRandom(device_fd, (DWORD) size, rnd)) {
|
||||
_gnutls_debug_log("Error in CryptGenRandom: %d\n",
|
||||
(int)GetLastError());
|
||||
return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
}
|
||||
-
|
||||
+#else
|
||||
+ NTSTATUS ret = BCryptGenRandom(bdevice_fd, rnd, (ULONG) size, 0);
|
||||
+ if (!(BCRYPT_SUCCESS(ret))) {
|
||||
+ _gnutls_debug_log("Error in BCryptGenRandom: %d\n",
|
||||
+ (int)GetLastError());
|
||||
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
+ }
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,7 +121,7 @@ int _rnd_system_entropy_check(void)
|
||||
int _rnd_system_entropy_init(void)
|
||||
{
|
||||
int old;
|
||||
-
|
||||
+#ifndef RING_UWP
|
||||
if (!CryptAcquireContext
|
||||
(&device_fd, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
|
||||
@@ -119,13 +129,26 @@ int _rnd_system_entropy_init(void)
|
||||
("error in CryptAcquireContext!\n");
|
||||
return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
}
|
||||
-
|
||||
+#else
|
||||
+ NTSTATUS ret = BCryptOpenAlgorithmProvider(&bdevice_fd,
|
||||
+ BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER,
|
||||
+ 0);
|
||||
+ if (!(BCRYPT_SUCCESS(ret))) {
|
||||
+ _gnutls_debug_log
|
||||
+ ("error in BCryptOpenAlgorithmProvider!\n");
|
||||
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
+ }
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _rnd_system_entropy_deinit(void)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
CryptReleaseContext(device_fd, 0);
|
||||
+#else
|
||||
+ BCryptCloseAlgorithmProvider(bdevice_fd, 0);
|
||||
+#endif
|
||||
}
|
||||
|
||||
#else /* POSIX */
|
||||
--- a/lib/opencdk/misc.c
|
||||
+++ b/lib/opencdk/misc.c
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <gnutls_int.h>
|
||||
#include <gnutls_str.h>
|
||||
|
||||
-
|
||||
u32 _cdk_buftou32(const byte * buf)
|
||||
{
|
||||
u32 u;
|
||||
@@ -149,6 +148,13 @@ int _cdk_check_args(int overwrite, const char *in, const char *out)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
+#if (_WIN32_WINNT >= 0x0600)
|
||||
+FILE *_cdk_tmpfile(void)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+#else
|
||||
+
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -183,6 +189,7 @@ FILE *_cdk_tmpfile(void)
|
||||
_close(fd);
|
||||
return NULL;
|
||||
}
|
||||
+#endif /*_WIN32*/
|
||||
#else
|
||||
FILE *_cdk_tmpfile(void)
|
||||
{
|
||||
--- a/lib/system-keys-win.c
|
||||
+++ b/lib/system-keys-win.c
|
||||
@@ -20,9 +20,10 @@
|
||||
|
||||
// Before including any Windows header we need to set _WIN32_WINNT to Vista
|
||||
// (or higher) so that the NCRYPT stuff can be used.
|
||||
-#if _WIN32_WINNT < 0x600
|
||||
+#define _WIN32_WINNT 0x0A00
|
||||
+#if _WIN32_WINNT < 0x0600
|
||||
#undef _WIN32_WINNT
|
||||
-#define _WIN32_WINNT 0x600
|
||||
+#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1075,7 +1076,11 @@ int _gnutls_system_key_init(void)
|
||||
int ret;
|
||||
|
||||
#ifdef DYN_NCRYPT
|
||||
- ncrypt_lib = LoadLibraryA("ncrypt.dll");
|
||||
+#if (_WIN32_WINNT < 0x0A00)
|
||||
+ ncrypt_lib = LoadLibrary("ncrypt.dll");
|
||||
+#else
|
||||
+ ncrypt_lib = LoadPackagedLibrary("ncrypt.dll", 0);
|
||||
+#endif
|
||||
if (ncrypt_lib == NULL) {
|
||||
return gnutls_assert_val(GNUTLS_E_CRYPTO_INIT_FAILED);
|
||||
}
|
||||
--- a/lib/system-keys-win.c
|
||||
+++ b/lib/system-keys-win.c
|
||||
@@ -396,7 +396,11 @@ _gnutls_privkey_import_system_url(gnutls_privkey_t pkey,
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store == NULL) {
|
||||
gnutls_assert();
|
||||
ret = GNUTLS_E_FILE_ERROR;
|
||||
@@ -535,7 +539,11 @@ _gnutls_x509_crt_import_system_url(gnutls_x509_crt_t crt, const char *url)
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store == NULL) {
|
||||
gnutls_assert();
|
||||
ret = GNUTLS_E_FILE_ERROR;
|
||||
@@ -776,7 +784,11 @@ gnutls_system_key_iter_get_info(gnutls_system_key_iter_t *iter,
|
||||
if (*iter == NULL)
|
||||
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
||||
|
||||
- (*iter)->store = CertOpenSystemStore(0, "MY");
|
||||
+ (*iter)->store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if ((*iter)->store == NULL) {
|
||||
gnutls_free(*iter);
|
||||
*iter = NULL;
|
||||
@@ -841,7 +853,11 @@ int gnutls_system_key_delete(const char *cert_url, const char *key_url)
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store != NULL) {
|
||||
do {
|
||||
cert = CertFindCertificateInStore(store,
|
||||
--- a/lib/system.c
|
||||
+++ b/lib/system.c
|
||||
@@ -446,9 +446,17 @@ int add_system_trust(gnutls_x509_trust_list_t list, unsigned int tl_flags,
|
||||
gnutls_datum_t data;
|
||||
|
||||
if (i == 0)
|
||||
- store = CertOpenSystemStore(0, "ROOT");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"ROOT");
|
||||
else
|
||||
- store = CertOpenSystemStore(0, "CA");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"CA");
|
||||
|
||||
if (store == NULL)
|
||||
return GNUTLS_E_FILE_ERROR;
|
||||
--- a/lib/accelerated/x86/x86-common.c
|
||||
+++ b/lib/accelerated/x86/x86-common.c
|
||||
@@ -652,6 +652,7 @@ void register_x86_intel_crypto(unsigned capabilities)
|
||||
|
||||
void register_x86_crypto(void)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
unsigned capabilities = 0;
|
||||
char *p;
|
||||
p = secure_getenv("GNUTLS_CPUID_OVERRIDE");
|
||||
@@ -663,5 +664,7 @@ void register_x86_crypto(void)
|
||||
#ifdef ENABLE_PADLOCK
|
||||
register_x86_padlock_crypto(capabilities);
|
||||
#endif
|
||||
+#endif
|
||||
+ register_x86_intel_crypto(0);
|
||||
}
|
||||
|
||||
--- a/lib/gnutls_global.c
|
||||
+++ b/lib/gnutls_global.c
|
||||
@@ -240,7 +240,9 @@ int gnutls_global_init(void)
|
||||
|
||||
_gnutls_switch_lib_state(LIB_STATE_INIT);
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_DEBUG_LEVEL");
|
||||
+#endif
|
||||
if (e != NULL) {
|
||||
level = atoi(e);
|
||||
gnutls_global_set_log_level(level);
|
||||
@@ -473,8 +475,10 @@ const char *e;
|
||||
if (_gnutls_global_init_skip() != 0)
|
||||
return;
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
|
||||
- if (e != NULL) {
|
||||
+#endif
|
||||
+ if (e != NULL) {
|
||||
ret = atoi(e);
|
||||
if (ret == 1)
|
||||
return;
|
||||
@@ -494,7 +498,9 @@ static void _DESTRUCTOR lib_deinit(void)
|
||||
if (_gnutls_global_init_skip() != 0)
|
||||
return;
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
|
||||
+#endif
|
||||
if (e != NULL) {
|
||||
int ret = atoi(e);
|
||||
if (ret == 1)
|
||||
--- a/lib/gnutls_kx.c
|
||||
+++ b/lib/gnutls_kx.c
|
||||
@@ -105,7 +105,9 @@ static void write_nss_key_log(gnutls_session_t session, const gnutls_datum_t *pr
|
||||
|
||||
if (!checked_env) {
|
||||
checked_env = 1;
|
||||
+#ifndef RING_UWP
|
||||
keylogfile = secure_getenv("SSLKEYLOGFILE");
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (keylogfile == NULL)
|
||||
--- a/lib/system.c
|
||||
+++ b/lib/system.c
|
||||
@@ -340,7 +340,11 @@ void gnutls_system_global_deinit(void)
|
||||
*/
|
||||
int _gnutls_find_config_path(char *path, size_t max_size)
|
||||
{
|
||||
- const char *home_dir = secure_getenv("HOME");
|
||||
+#ifndef RING_UWP
|
||||
+ const char *home_dir = secure_getenv("HOME");
|
||||
+#else
|
||||
+ const char *home_dir = NULL;
|
||||
+#endif
|
||||
|
||||
if (home_dir != NULL && home_dir[0] != 0) {
|
||||
snprintf(path, max_size, "%s/" CONFIG_PATH, home_dir);
|
||||
@@ -349,8 +353,13 @@ int _gnutls_find_config_path(char *path, size_t max_size)
|
||||
|
||||
#ifdef _WIN32
|
||||
if (home_dir == NULL || home_dir[0] == '\0') {
|
||||
+#ifndef RING_UWP
|
||||
const char *home_drive = getenv("HOMEDRIVE");
|
||||
const char *home_path = getenv("HOMEPATH");
|
||||
+#else
|
||||
+ const char *home_drive = NULL;
|
||||
+ const char *home_path = NULL;
|
||||
+#endif
|
||||
|
||||
if (home_drive != NULL && home_path != NULL) {
|
||||
snprintf(path, max_size, "%s%s\\" CONFIG_PATH, home_drive, home_path);
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
--- gnutls/gl/read-file.c.orig 2012-03-06 20:59:29.600593329 -0500
|
||||
+++ gnutls/gl/read-file.c 2012-03-06 20:59:44.568593328 -0500
|
||||
@@ -35,6 +35,9 @@
|
||||
/* Get errno. */
|
||||
#include <errno.h>
|
||||
|
||||
+/* Get SIZE_MAX */
|
||||
+#include <limits.h>
|
||||
+
|
||||
/* Read a STREAM and return a newly allocated string with the content,
|
||||
and set *LENGTH to the length of the string. The string is
|
||||
zero-terminated, but the terminating zero byte is not counted in
|
||||
@@ -0,0 +1,22 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ICONV_VERSION=65ab92f7a1699ecc39e37fb81f66e5a42aaa35c4
|
||||
set ICONV_URL=https://github.com/ShiftMediaProject/libiconv/archive/%ICONV_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ICONV_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ICONV_URL%
|
||||
)
|
||||
|
||||
7z -y x %ICONV_VERSION%.tar.gz && 7z -y x %ICONV_VERSION%.tar -o%BUILD%
|
||||
del %ICONV_VERSION%.tar && del %ICONV_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\libiconv-%ICONV_VERSION% libiconv
|
||||
|
||||
cd %BUILD%\libiconv
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\iconv\libiconv-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,99 @@
|
||||
--- a/SMP/libiconv.vcxproj
|
||||
+++ b/SMP/libiconv.vcxproj
|
||||
@@ -45,6 +45,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}</ProjectGuid>
|
||||
<RootNamespace>libiconv</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -164,65 +165,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconvd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconvd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconvd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconvd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set MSGPACK_VERSION=1df97bc37b363a340c5ad06c5cbcc53310aaff80
|
||||
set MSGPACK_URL=https://github.com/msgpack/msgpack-c/archive/%MSGPACK_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%MSGPACK_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %MSGPACK_URL%
|
||||
)
|
||||
|
||||
7z -y x %MSGPACK_VERSION%.tar.gz && 7z -y x %MSGPACK_VERSION%.tar -o%BUILD%
|
||||
del %MSGPACK_VERSION%.tar && del %MSGPACK_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\msgpack-c-%MSGPACK_VERSION% msgpack-c
|
||||
|
||||
cd %BUILD%\msgpack-c
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\msgpack\msgpack-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,221 @@
|
||||
--- /dev/null
|
||||
+++ b/msgpack_vc8.vcxproj
|
||||
@@ -0,0 +1,214 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
+ <ItemGroup Label="ProjectConfigurations">
|
||||
+ <ProjectConfiguration Include="Debug|Win32">
|
||||
+ <Configuration>Debug</Configuration>
|
||||
+ <Platform>Win32</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Debug|x64">
|
||||
+ <Configuration>Debug</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|Win32">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>Win32</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|x64">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ </ItemGroup>
|
||||
+ <PropertyGroup Label="Globals">
|
||||
+ <ProjectName>MessagePack</ProjectName>
|
||||
+ <ProjectGuid>{122A2EA4-B283-4241-9655-786DE78283B2}</ProjectGuid>
|
||||
+ <RootNamespace>MessagePack</RootNamespace>
|
||||
+ <Keyword>Win32Proj</Keyword>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
+ <ImportGroup Label="ExtensionSettings">
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <PropertyGroup Label="UserMacros" />
|
||||
+ <PropertyGroup>
|
||||
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <MinimalRebuild>true</MinimalRebuild>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>MSGPACK_USE_CPP03;WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClCompile Include="src\objectc.c" />
|
||||
+ <ClCompile Include="src\unpack.c" />
|
||||
+ <ClCompile Include="src\version.c" />
|
||||
+ <ClCompile Include="src\vrefbuffer.c" />
|
||||
+ <ClCompile Include="src\zone.c" />
|
||||
+ </ItemGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClInclude Include="include\msgpack.hpp" />
|
||||
+ </ItemGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
+ <ImportGroup Label="ExtensionTargets">
|
||||
+ </ImportGroup>
|
||||
+</Project>
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set NETTLE_VERSION=4e0b2723b76d4163fa37b2b456d41534154ec97c
|
||||
set NETTLE_URL=https://github.com/ShiftMediaProject/nettle/archive/%NETTLE_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%NETTLE_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %NETTLE_URL%
|
||||
)
|
||||
|
||||
7z -y x %NETTLE_VERSION%.tar.gz && 7z -y x %NETTLE_VERSION%.tar -o%BUILD%
|
||||
del %NETTLE_VERSION%.tar && del %NETTLE_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\nettle-%NETTLE_VERSION% nettle
|
||||
|
||||
cd %BUILD%\nettle
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\nettle\nettle-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,228 @@
|
||||
--- a/SMP/libhogweed.vcxproj
|
||||
+++ b/SMP/libhogweed.vcxproj
|
||||
@@ -242,6 +242,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}</ProjectGuid>
|
||||
<RootNamespace>libhogweed</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -405,91 +406,91 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweedd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--- a/SMP/libnettle.vcxproj
|
||||
+++ b/SMP/libnettle.vcxproj
|
||||
@@ -278,6 +278,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}</ProjectGuid>
|
||||
<RootNamespace>libnettle</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -397,65 +398,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettled</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettled</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettled</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettled</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--
|
||||
2.8.1.windows.1
|
||||
@@ -0,0 +1,22 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ZLIB_VERSION=3a062eb61d0c3d4aa30851cd1a6597b977b56597
|
||||
set ZLIB_URL=https://github.com/ShiftMediaProject/zlib/archive/%ZLIB_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ZLIB_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ZLIB_URL%
|
||||
)
|
||||
|
||||
7z -y x %ZLIB_VERSION%.tar.gz && 7z -y x %ZLIB_VERSION%.tar -o%BUILD%
|
||||
del %ZLIB_VERSION%.tar && del %ZLIB_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\zlib-%ZLIB_VERSION% zlib
|
||||
|
||||
cd %BUILD%\zlib
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\zlib\zlib-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -0,0 +1,97 @@
|
||||
--- a/SMP/libzlib.vcxproj
|
||||
+++ b/SMP/libzlib.vcxproj
|
||||
@@ -45,6 +45,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}</ProjectGuid>
|
||||
<RootNamespace>libzlib</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -165,63 +166,63 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlibd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlibd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlibd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlibd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
@@ -147,8 +147,8 @@
|
||||
<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>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</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
@@ -147,8 +147,8 @@
|
||||
<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>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</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
@@ -147,8 +147,8 @@
|
||||
<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>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</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
--- /dev/null
|
||||
+++ b/msgpack_vc8.vcxproj
|
||||
@@ -0,0 +1,214 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
+ <ItemGroup Label="ProjectConfigurations">
|
||||
+ <ProjectConfiguration Include="Debug|Win32">
|
||||
+ <Configuration>Debug</Configuration>
|
||||
+ <Platform>Win32</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Debug|x64">
|
||||
+ <Configuration>Debug</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|Win32">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>Win32</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|x64">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ </ItemGroup>
|
||||
+ <PropertyGroup Label="Globals">
|
||||
+ <ProjectName>MessagePack</ProjectName>
|
||||
+ <ProjectGuid>{122A2EA4-B283-4241-9655-786DE78283B2}</ProjectGuid>
|
||||
+ <RootNamespace>MessagePack</RootNamespace>
|
||||
+ <Keyword>Win32Proj</Keyword>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
+ <ImportGroup Label="ExtensionSettings">
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <PropertyGroup Label="UserMacros" />
|
||||
+ <PropertyGroup>
|
||||
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <MinimalRebuild>true</MinimalRebuild>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>MSGPACK_USE_CPP03;WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClCompile Include="src\objectc.c" />
|
||||
+ <ClCompile Include="src\unpack.c" />
|
||||
+ <ClCompile Include="src\version.c" />
|
||||
+ <ClCompile Include="src\vrefbuffer.c" />
|
||||
+ <ClCompile Include="src\zone.c" />
|
||||
+ </ItemGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClInclude Include="include\msgpack.hpp" />
|
||||
+ </ItemGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
+ <ImportGroup Label="ExtensionTargets">
|
||||
+ </ImportGroup>
|
||||
+</Project>
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<ClCompile Include="..\src\dhtrunner.cpp" />
|
||||
<ClCompile Include="..\src\indexation\pht.cpp" />
|
||||
<ClCompile Include="..\src\infohash.cpp" />
|
||||
<ClCompile Include="..\src\log.cpp" />
|
||||
<ClCompile Include="..\src\network_engine.cpp" />
|
||||
<ClCompile Include="..\src\node.cpp" />
|
||||
<ClCompile Include="..\src\node_cache.cpp" />
|
||||
@@ -207,7 +208,7 @@ 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>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)contrib\build\include;$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)contrib\build\argon2\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\callbacks.cpp" />
|
||||
<ClCompile Include="..\src\crypto.cpp" />
|
||||
<ClCompile Include="..\src\default_types.cpp" />
|
||||
<ClCompile Include="..\src\dht.cpp" />
|
||||
<ClCompile Include="..\src\dhtrunner.cpp" />
|
||||
<ClCompile Include="..\src\indexation\pht.cpp" />
|
||||
<ClCompile Include="..\src\infohash.cpp" />
|
||||
<ClCompile Include="..\src\log.cpp" />
|
||||
<ClCompile Include="..\src\network_engine.cpp" />
|
||||
<ClCompile Include="..\src\node.cpp" />
|
||||
<ClCompile Include="..\src\node_cache.cpp" />
|
||||
<ClCompile Include="..\src\routing_table.cpp" />
|
||||
<ClCompile Include="..\src\securedht.cpp" />
|
||||
<ClCompile Include="..\src\utils.cpp" />
|
||||
<ClCompile Include="..\src\value.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\opendht.h" />
|
||||
<ClInclude Include="..\include\opendht\callbacks.h" />
|
||||
<ClInclude Include="..\include\opendht\crypto.h" />
|
||||
<ClInclude Include="..\include\opendht\default_types.h" />
|
||||
<ClInclude Include="..\include\opendht\dht.h" />
|
||||
<ClInclude Include="..\include\opendht\dhtrunner.h" />
|
||||
<ClInclude Include="..\include\opendht\indexation\pht.h" />
|
||||
<ClInclude Include="..\include\opendht\infohash.h" />
|
||||
<ClInclude Include="..\include\opendht\log.h" />
|
||||
<ClInclude Include="..\include\opendht\log_enable.h" />
|
||||
<ClInclude Include="..\include\opendht\network_engine.h" />
|
||||
<ClInclude Include="..\include\opendht\node.h" />
|
||||
<ClInclude Include="..\include\opendht\node_cache.h" />
|
||||
<ClInclude Include="..\include\opendht\rate_limiter.h" />
|
||||
<ClInclude Include="..\include\opendht\request.h" />
|
||||
<ClInclude Include="..\include\opendht\rng.h" />
|
||||
<ClInclude Include="..\include\opendht\routing_table.h" />
|
||||
<ClInclude Include="..\include\opendht\scheduler.h" />
|
||||
<ClInclude Include="..\include\opendht\securedht.h" />
|
||||
<ClInclude Include="..\include\opendht\utils.h" />
|
||||
<ClInclude Include="..\include\opendht\value.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+71
-304
@@ -5,17 +5,17 @@ VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA} = {2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2} = {122A2EA4-B283-4241-9655-786DE78283B2}
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02} = {6F610EE8-7F59-4191-AB88-F63843267C02}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{71A1A9EC-1104-4335-A87E-AF8749FD5B34}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgmp", "..\..\gmp\MSVC\libgmp.vcxproj", "{02B94302-23D6-43EF-8865-95CDE99D5DC2}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgmp", "contrib\build\gmp\SMP\libgmp.vcxproj", "{02B94302-23D6-43EF-8865-95CDE99D5DC2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "..\..\gnutls\MSVC\libgnutls.vcxproj", "{6F610EE8-7F59-4191-AB88-F63843267C02}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "contrib\build\gnutls\SMP\libgnutls.vcxproj", "{6F610EE8-7F59-4191-AB88-F63843267C02}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
|
||||
@@ -24,25 +24,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "..\..\gnutls\M
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "..\..\libiconv\MSVC\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "contrib\build\libiconv\SMP\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "..\..\nettle\MSVC\libhogweed.vcxproj", "{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "contrib\build\nettle\SMP\libhogweed.vcxproj", "{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnettle", "..\..\nettle\MSVC\libnettle.vcxproj", "{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnettle", "contrib\build\nettle\SMP\libnettle.vcxproj", "{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "..\..\zlib\MSVC\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "contrib\build\zlib\SMP\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "..\..\msgpack-c\msgpack_vc8.vcxproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "argon", "argon.vcxproj", "{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6} = {36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blake", "blake.vcxproj", "{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "contrib\build\msgpack-c\msgpack_vc8.vcxproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{296E2989-CF09-43AC-BBD2-BCF1A4B56D07}"
|
||||
EndProject
|
||||
@@ -61,386 +54,161 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dhtchat", "dhtchat.vcxproj"
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C} = {711397CE-E5D5-467D-9457-8716C047E50C}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2Ref", "contrib\build\argon2\vs2015\Argon2Ref\Argon2Ref.vcxproj", "{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
DebugDLL|x64 = DebugDLL|x64
|
||||
DebugDLL|x86 = DebugDLL|x86
|
||||
DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64
|
||||
DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
ReleaseDLL|x64 = ReleaseDLL|x64
|
||||
ReleaseDLL|x86 = ReleaseDLL|x86
|
||||
ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64
|
||||
ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86
|
||||
ReleaseLTO|x64 = ReleaseLTO|x64
|
||||
ReleaseLTO|x86 = ReleaseLTO|x86
|
||||
ReleaseStatic|x64 = ReleaseStatic|x64
|
||||
ReleaseStatic|x86 = ReleaseStatic|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.Build.0 = Debug|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.ActiveCfg = Release|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.Build.0 = Release|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.Build.0 = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.Build.0 = Debug|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.ActiveCfg = Release|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.Build.0 = Release|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.Build.0 = Release|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.Build.0 = Debug|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.ActiveCfg = Release|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.Build.0 = Release|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.Build.0 = Release|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.Build.0 = Debug|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.Build.0 = Debug|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.ActiveCfg = Release|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.Build.0 = Release|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.ActiveCfg = Release|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.Build.0 = Release|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.Build.0 = Debug|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x64.Build.0 = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x64.ActiveCfg = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x64.Build.0 = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x86.Build.0 = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x64.Build.0 = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x64.ActiveCfg = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x64.Build.0 = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x86.Build.0 = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.Build.0 = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.Build.0 = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.Build.0 = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.Build.0 = Debug|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.ActiveCfg = Release|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.Build.0 = Release|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.Build.0 = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -453,10 +221,9 @@ Global
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,71 +0,0 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
SET UPSTREAMURL=https://github.com/atraczyk
|
||||
SET DEPENDENCIES=( ^
|
||||
gmp, ^
|
||||
gnutls, ^
|
||||
nettle, ^
|
||||
msgpack-c ^
|
||||
)
|
||||
|
||||
SET PASSDEPENDENCIES=%~1
|
||||
|
||||
git status >NUL 2>&1
|
||||
IF %ERRORLEVEL% EQU 128 (
|
||||
git init
|
||||
) ELSE (
|
||||
IF %ERRORLEVEL% EQU 9009 (
|
||||
ECHO git not installed.
|
||||
EXIT /B 1
|
||||
)
|
||||
)
|
||||
|
||||
SET CURRDIR=%~dp1
|
||||
|
||||
cd ..\..
|
||||
FOR %%I IN %DEPENDENCIES% DO (
|
||||
ECHO !PASSDEPENDENCIES! | FINDSTR /C:"%%I" >NUL 2>&1 || (
|
||||
CALL :cloneOrUpdateRepo "%%I" )
|
||||
)
|
||||
cd %CURRDIR% >NUL
|
||||
GOTO exit
|
||||
|
||||
:cloneOrUpdateRepo
|
||||
SET REPONAME=%~1
|
||||
IF NOT EXIST "%REPONAME%" (
|
||||
ECHO %REPONAME%: Existing folder not found. Cloning repository...
|
||||
SET REPOURL=%UPSTREAMURL%/%REPONAME%.git
|
||||
git clone !REPOURL! --quiet
|
||||
cd %REPONAME%
|
||||
git config --local core.autocrlf false
|
||||
git rm --cached -r . --quiet
|
||||
git reset --hard --quiet
|
||||
cd ..\
|
||||
)
|
||||
|
||||
SET PASSDEPENDENCIES=%PASSDEPENDENCIES% %REPONAME%
|
||||
|
||||
IF EXIST "%REPONAME%\MSVC\project_get_dependencies.bat" (
|
||||
ECHO %REPONAME%: Found additional dependencies...
|
||||
ECHO.
|
||||
cd %REPONAME%\MSVC
|
||||
project_get_dependencies.bat "!PASSDEPENDENCIES!" || GOTO exitOnError
|
||||
cd ..\..
|
||||
)
|
||||
ECHO.
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:exitOnError
|
||||
cd %CURRDIR%
|
||||
|
||||
:exit
|
||||
(
|
||||
ENDLOCAL
|
||||
SET PASSDEPENDENCIES=%PASSDEPENDENCIES%
|
||||
)
|
||||
|
||||
ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1
|
||||
IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE
|
||||
|
||||
EXIT /B 0
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
AM_CXXFLAGS = -pthread
|
||||
|
||||
SUBDIRS = src
|
||||
SUBDIRS =
|
||||
|
||||
SUBDIRS += src
|
||||
|
||||
if ENABLE_TOOLS
|
||||
SUBDIRS += tools
|
||||
|
||||
@@ -91,7 +91,7 @@ for r in results:
|
||||
- msgpack-c 1.2+, used for data serialization.
|
||||
- GnuTLS 3.3+, used for cryptographic operations.
|
||||
- Nettle 2.4+, a GnuTLS dependency for crypto.
|
||||
- Build tested with GCC 4.8+ (GNU/Linux, Android, Windows with MinGW), Clang/LLVM (Linux, OS X).
|
||||
- Build tested with GCC 4.8+ (GNU/Linux, Android, Windows with MinGW), Clang/LLVM (Linux, macOS).
|
||||
- Build tested with Microsoft Visual Studio 2015
|
||||
|
||||
## Contact
|
||||
@@ -99,7 +99,7 @@ for r in results:
|
||||
IRC: join us on Freenode at [`#opendht`](https://webchat.freenode.net/?channels=%23opendht).
|
||||
|
||||
## Licence
|
||||
Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
|
||||
OpenDHT 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.
|
||||
|
||||
|
||||
Submodule
+1
Submodule argon2 added at 6f5427fb67.
@@ -1 +1,2 @@
|
||||
git submodule update --init
|
||||
autoreconf --install --verbose -Wall
|
||||
+22
-5
@@ -1,7 +1,7 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 1)
|
||||
m4_define([opendht_minor_version], 2)
|
||||
m4_define([opendht_patch_version], 0)
|
||||
m4_define([opendht_minor_version], 3)
|
||||
m4_define([opendht_patch_version], 2)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
@@ -45,8 +45,8 @@ AC_ARG_ENABLE([python], [AS_HELP_STRING([--disable-python], [Disble python bindi
|
||||
AS_IF([test "x$enable_python" != "xno"], [
|
||||
AM_PATH_PYTHON([3.3],, [:])
|
||||
AS_IF([test -n "$PYTHON"],[
|
||||
AC_CHECK_PROGS([CYTHON], [cython3])
|
||||
AS_IF([test -z "$CYTHON"],[AC_MSG_WARN([Cython not found - continuing without python support])])
|
||||
echo 'import Cython' | $PYTHON
|
||||
AS_IF([test $? == 0],[CYTHON=yes],[AC_MSG_WARN([Cython not found - continuing without python support])])
|
||||
AC_CHECK_PROGS([PIP], [pip3])
|
||||
AS_IF([test -z "$PIP"],[AC_MSG_WARN([pip not found - continuing without python uninstall support])])
|
||||
])
|
||||
@@ -99,6 +99,24 @@ PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
|
||||
dnl Check for Argon2
|
||||
AC_ARG_WITH([argon2], AS_HELP_STRING([--without-argon2], [Use included Argon2]))
|
||||
AS_IF([test "x$with_argon2" != "xno"],
|
||||
[PKG_CHECK_MODULES([Argon2], [libargon2], [have_argon2=yes], [have_argon2=no])],
|
||||
[have_argon2=no])
|
||||
AS_IF([test "x$have_argon2" = "xyes"], [], [
|
||||
AS_IF([test "x$with_argon2" = "xyes"], [
|
||||
AC_MSG_ERROR([Argon2 requested but not found])
|
||||
],[
|
||||
AC_MSG_NOTICE([Using included Argon2])
|
||||
AC_SUBST(Argon2_CFLAGS, "-I\${top_srcdir}/argon2/src -I\${top_srcdir}/argon2/include")
|
||||
AC_SUBST(Argon2_LIBS, "libargon2.la")
|
||||
AC_SUBST(Argon2_LDFLAGS, "-L\${abs_top_srcdir}/argon2/src/.libs")
|
||||
])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([WITH_INCLUDED_ARGON2], [test "x$have_argon2" = "xno"])
|
||||
|
||||
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
|
||||
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
|
||||
AM_COND_IF([ENABLE_TOOLS], [
|
||||
@@ -120,7 +138,6 @@ AM_COND_IF([USE_CYTHON], [
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
src/argon2/Makefile
|
||||
tools/Makefile
|
||||
opendht.pc])
|
||||
AC_OUTPUT
|
||||
@@ -1,9 +1,3 @@
|
||||
FROM ubuntu:16.04
|
||||
FROM ubuntu:17.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools && apt-get clean
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.0.0/msgpack-2.0.0.tar.gz \
|
||||
&& tar -xzf msgpack-2.0.0.tar.gz \
|
||||
&& cd msgpack-2.0.0 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-2.0.0 msgpack-2.0.0.tar.gz
|
||||
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools && apt-get clean
|
||||
@@ -1,13 +1,7 @@
|
||||
FROM ubuntu:16.04
|
||||
FROM ubuntu:17.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools \
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
|
||||
ENV CC cc
|
||||
ENV CXX c++
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.0.0/msgpack-2.0.0.tar.gz \
|
||||
&& tar -xzf msgpack-2.0.0.tar.gz \
|
||||
&& cd msgpack-2.0.0 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-2.0.0 msgpack-2.0.0.tar.gz
|
||||
ENV CXX c++
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,8 +13,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
+25
-12
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -13,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -39,14 +39,24 @@ enum class NodeStatus {
|
||||
Connected // 1+ good nodes
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC NodeStats {
|
||||
unsigned good_nodes,
|
||||
dubious_nodes,
|
||||
cached_nodes,
|
||||
incoming_nodes;
|
||||
unsigned table_depth;
|
||||
unsigned getKnownNodes() const { return good_nodes + dubious_nodes; }
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dht configuration.
|
||||
*/
|
||||
struct Config {
|
||||
struct OPENDHT_PUBLIC Config {
|
||||
/** DHT 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.
|
||||
@@ -55,12 +65,15 @@ struct Config {
|
||||
|
||||
/** For testing purposes only, enables bootstrap mode */
|
||||
bool is_bootstrap;
|
||||
|
||||
/** Makes the DHT responsible to maintain its stored values. Consumes more ressources. */
|
||||
bool maintain_storage;
|
||||
};
|
||||
|
||||
/**
|
||||
* SecureDht configuration.
|
||||
*/
|
||||
struct SecureDhtConfig
|
||||
struct OPENDHT_PUBLIC SecureDhtConfig
|
||||
{
|
||||
Config node_config;
|
||||
crypto::Identity id;
|
||||
@@ -79,8 +92,8 @@ using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::
|
||||
|
||||
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
|
||||
|
||||
GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
|
||||
GetCallback bindGetCb(GetCallbackSimple cb);
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(GetCallbackSimple cb);
|
||||
|
||||
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
|
||||
typedef void (*DoneCallbackRaw)(bool, std::vector<std::shared_ptr<Node>>*, void *user_data);
|
||||
@@ -89,9 +102,9 @@ typedef void (*DoneCallbackSimpleRaw)(bool, void *user_data);
|
||||
|
||||
using DoneCallbackSimple = std::function<void(bool success)>;
|
||||
|
||||
ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
|
||||
DoneCallback bindDoneCb(DoneCallbackSimple donecb);
|
||||
DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
|
||||
DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackSimple donecb);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
|
||||
|
||||
}
|
||||
+271
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,14 +13,14 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "infohash.h"
|
||||
#include "utils.h"
|
||||
#include "rng.h"
|
||||
|
||||
extern "C" {
|
||||
#include <gnutls/gnutls.h>
|
||||
@@ -38,7 +38,7 @@ extern "C" {
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
|
||||
class CryptoException : public std::runtime_error {
|
||||
class OPENDHT_PUBLIC CryptoException : public std::runtime_error {
|
||||
public:
|
||||
CryptoException(const std::string& str) : std::runtime_error(str) {};
|
||||
};
|
||||
@@ -46,20 +46,21 @@ class CryptoException : public std::runtime_error {
|
||||
/**
|
||||
* Exception thrown when a decryption error happened.
|
||||
*/
|
||||
class DecryptError : public CryptoException {
|
||||
class OPENDHT_PUBLIC DecryptError : public CryptoException {
|
||||
public:
|
||||
DecryptError(const std::string& str = "") : CryptoException(str) {};
|
||||
};
|
||||
|
||||
struct PrivateKey;
|
||||
struct Certificate;
|
||||
class RevocationList;
|
||||
|
||||
using Identity = std::pair<std::shared_ptr<PrivateKey>, std::shared_ptr<Certificate>>;
|
||||
|
||||
/**
|
||||
* A public key.
|
||||
*/
|
||||
struct PublicKey
|
||||
struct OPENDHT_PUBLIC PublicKey
|
||||
{
|
||||
PublicKey() {}
|
||||
|
||||
@@ -82,12 +83,15 @@ struct PublicKey
|
||||
PublicKey& operator=(PublicKey&& o) noexcept;
|
||||
|
||||
InfoHash getId() const;
|
||||
PkId getLongId() const;
|
||||
bool checkSignature(const Blob& data, const Blob& signature) const;
|
||||
Blob encrypt(const Blob&) const;
|
||||
|
||||
void pack(Blob& b) const;
|
||||
void unpack(const uint8_t* dat, size_t dat_size);
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
{
|
||||
@@ -109,7 +113,7 @@ private:
|
||||
/**
|
||||
* A private key, including the corresponding public key.
|
||||
*/
|
||||
struct PrivateKey
|
||||
struct OPENDHT_PUBLIC PrivateKey
|
||||
{
|
||||
PrivateKey();
|
||||
//PrivateKey(gnutls_privkey_t k) : key(k) {}
|
||||
@@ -148,6 +152,7 @@ struct PrivateKey
|
||||
* Recommended values: 4096, 8192
|
||||
*/
|
||||
static PrivateKey generate(unsigned key_length = 4096);
|
||||
static PrivateKey generateEC();
|
||||
|
||||
gnutls_privkey_t key {};
|
||||
gnutls_x509_privkey_t x509_key {};
|
||||
@@ -159,7 +164,83 @@ private:
|
||||
//friend dht::crypto::Identity dht::crypto::generateIdentity(const std::string&, dht::crypto::Identity, unsigned key_length);
|
||||
};
|
||||
|
||||
struct Certificate {
|
||||
|
||||
class OPENDHT_PUBLIC RevocationList
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
using time_point = clock::time_point;
|
||||
using duration = clock::duration;
|
||||
public:
|
||||
RevocationList();
|
||||
RevocationList(const Blob& b);
|
||||
RevocationList(RevocationList&& o) : crl(o.crl) { o.crl = nullptr; }
|
||||
~RevocationList();
|
||||
|
||||
RevocationList& operator=(RevocationList&& o) { crl = o.crl; o.crl = nullptr; return *this; }
|
||||
|
||||
void pack(Blob& b) const;
|
||||
void unpack(const uint8_t* dat, size_t dat_size);
|
||||
Blob getPacked() const {
|
||||
Blob b;
|
||||
pack(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
{
|
||||
Blob b = getPacked();
|
||||
p.pack_bin(b.size());
|
||||
p.pack_bin_body((const char*)b.data(), b.size());
|
||||
}
|
||||
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
|
||||
void revoke(const Certificate& crt, time_point t = time_point::min());
|
||||
|
||||
bool isRevoked(const Certificate& crt) const;
|
||||
|
||||
/**
|
||||
* Sign this revocation list using provided key and certificate.
|
||||
* Validity_period sets the duration until next update (default to no next update).
|
||||
*/
|
||||
void sign(const PrivateKey&, const Certificate&, duration validity_period = {});
|
||||
void sign(const Identity& id) { sign(*id.first, *id.second); }
|
||||
|
||||
bool isSignedBy(const Certificate& issuer) const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
* Read the CRL number extension field.
|
||||
*/
|
||||
Blob getNumber() const;
|
||||
|
||||
/** Read CRL issuer Common Name (CN) */
|
||||
std::string getIssuerName() const;
|
||||
|
||||
/** Read CRL issuer User ID (UID) */
|
||||
std::string getIssuerUID() const;
|
||||
|
||||
time_point getUpdateTime() const;
|
||||
time_point getNextUpdateTime() const;
|
||||
|
||||
gnutls_x509_crl_t get() { return crl; }
|
||||
gnutls_x509_crl_t getCopy() const {
|
||||
auto copy = RevocationList(getPacked());
|
||||
gnutls_x509_crl_t ret = copy.crl;
|
||||
copy.crl = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
gnutls_x509_crl_t crl {};
|
||||
RevocationList(const RevocationList&) = delete;
|
||||
RevocationList& operator=(const RevocationList&) = delete;
|
||||
};
|
||||
|
||||
|
||||
struct OPENDHT_PUBLIC Certificate {
|
||||
Certificate() {}
|
||||
|
||||
/**
|
||||
@@ -174,7 +255,10 @@ struct Certificate {
|
||||
* ordered from subject to issuer
|
||||
*/
|
||||
Certificate(const Blob& crt);
|
||||
Certificate(const uint8_t* dat, size_t dat_size) {
|
||||
Certificate(const std::string& pem) : cert(nullptr) {
|
||||
unpack((const uint8_t*)pem.data(), pem.size());
|
||||
}
|
||||
Certificate(const uint8_t* dat, size_t dat_size) : cert(nullptr) {
|
||||
unpack(dat, dat_size);
|
||||
}
|
||||
|
||||
@@ -278,6 +362,7 @@ struct Certificate {
|
||||
|
||||
/** Same as getPublicKey().getId() */
|
||||
InfoHash getId() const;
|
||||
PkId getLongId() const;
|
||||
|
||||
/** Read certificate Common Name (CN) */
|
||||
std::string getName() const;
|
||||
@@ -296,8 +381,11 @@ struct Certificate {
|
||||
/** Read certificate alternative names */
|
||||
std::vector<std::pair<NameType, std::string>> getAltNames() const;
|
||||
|
||||
std::chrono::system_clock::time_point getExpiration() const;
|
||||
|
||||
/**
|
||||
* Returns true if the certificate is marked as a Certificate Authority.
|
||||
* Returns true if the certificate is marked as a Certificate Authority
|
||||
* and has necessary key usage flags to sign certificates.
|
||||
*/
|
||||
bool isCA() const;
|
||||
|
||||
@@ -307,15 +395,180 @@ struct Certificate {
|
||||
*/
|
||||
std::string toString(bool chain = true) const;
|
||||
|
||||
std::string print() const;
|
||||
|
||||
void revoke(const PrivateKey&, const Certificate&);
|
||||
std::vector<std::shared_ptr<RevocationList>> getRevocationLists() const;
|
||||
void addRevocationList(RevocationList&&);
|
||||
void addRevocationList(std::shared_ptr<RevocationList>);
|
||||
|
||||
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", Identity ca = {}, bool is_ca = false);
|
||||
|
||||
gnutls_x509_crt_t getCopy() const {
|
||||
auto copy = Certificate(getPacked());
|
||||
gnutls_x509_crt_t ret = copy.cert;
|
||||
copy.cert = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<gnutls_x509_crt_t>
|
||||
getChain(bool copy = false) const
|
||||
{
|
||||
std::vector<gnutls_x509_crt_t> crts;
|
||||
auto c = this;
|
||||
do {
|
||||
crts.emplace_back(copy ? c->getCopy() : c->cert);
|
||||
c = c->issuer.get();
|
||||
} while (c);
|
||||
return crts;
|
||||
}
|
||||
|
||||
std::pair<
|
||||
std::vector<gnutls_x509_crt_t>,
|
||||
std::vector<gnutls_x509_crl_t>
|
||||
>
|
||||
getChainWithRevocations(bool copy = false) const
|
||||
{
|
||||
std::vector<gnutls_x509_crt_t> crts;
|
||||
std::vector<gnutls_x509_crl_t> crls;
|
||||
auto c = this;
|
||||
do {
|
||||
crts.emplace_back(copy ? c->getCopy() : c->cert);
|
||||
crls.reserve(crls.size() + c->revocation_lists.size());
|
||||
for (const auto& crl : c->revocation_lists)
|
||||
crls.emplace_back(copy ? crl->getCopy() : crl->get());
|
||||
c = c->issuer.get();
|
||||
} while (c);
|
||||
return {crts, crls};
|
||||
}
|
||||
|
||||
gnutls_x509_crt_t cert {};
|
||||
std::shared_ptr<Certificate> issuer {};
|
||||
private:
|
||||
Certificate(const Certificate&) = delete;
|
||||
Certificate& operator=(const Certificate&) = delete;
|
||||
|
||||
struct crlNumberCmp {
|
||||
bool operator() (const std::shared_ptr<RevocationList>& lhs, const std::shared_ptr<RevocationList>& rhs) const {
|
||||
return lhs->getNumber() < rhs->getNumber();
|
||||
}
|
||||
};
|
||||
|
||||
std::set<std::shared_ptr<RevocationList>, crlNumberCmp> revocation_lists;
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC TrustList
|
||||
{
|
||||
struct VerifyResult {
|
||||
int ret;
|
||||
unsigned result;
|
||||
bool hasError() const { return ret < 0; }
|
||||
bool isValid() const { return !hasError() and !(result & GNUTLS_CERT_INVALID); }
|
||||
explicit operator bool() const { return isValid(); }
|
||||
std::string toString() const;
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const VerifyResult& h);
|
||||
};
|
||||
|
||||
TrustList();
|
||||
TrustList(TrustList&& o) : trust(std::move(o.trust)) {
|
||||
o.trust = nullptr;
|
||||
}
|
||||
TrustList& operator=(TrustList&& o);
|
||||
~TrustList();
|
||||
void add(const Certificate& crt);
|
||||
void add(const RevocationList& crl);
|
||||
void remove(const Certificate& crt, bool parents = true);
|
||||
VerifyResult verify(const Certificate& crt) const;
|
||||
|
||||
private:
|
||||
TrustList(const TrustList& o) = delete;
|
||||
TrustList& operator=(const TrustList& o) = delete;
|
||||
gnutls_x509_trust_list_t trust;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class OPENDHT_PUBLIC secure_vector
|
||||
{
|
||||
public:
|
||||
secure_vector() {}
|
||||
secure_vector(secure_vector<T> const&) = default;
|
||||
secure_vector(secure_vector<T> &&) = default;
|
||||
explicit secure_vector(unsigned size): data_(size) {}
|
||||
explicit secure_vector(unsigned size, T _item): data_(size, _item) {}
|
||||
explicit secure_vector(const std::vector<T>& c): data_(c) {}
|
||||
secure_vector(std::vector<T>&& c): data_(std::move(c)) {}
|
||||
~secure_vector() { clean(); }
|
||||
|
||||
static secure_vector<T> getRandom(size_t size) {
|
||||
secure_vector<T> ret(size/sizeof(T));
|
||||
crypto::random_device rdev;
|
||||
std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
std::generate_n((uint8_t*)ret.data_.data(), ret.size()*sizeof(T), std::bind(rand_byte, std::ref(rdev)));
|
||||
return ret;
|
||||
}
|
||||
secure_vector<T>& operator=(const secure_vector<T>& c) {
|
||||
if (&c == this)
|
||||
return *this;
|
||||
clean();
|
||||
data_ = c.data_;
|
||||
return *this;
|
||||
}
|
||||
secure_vector<T>& operator=(secure_vector<T>&& c) {
|
||||
if (&c == this)
|
||||
return *this;
|
||||
clean();
|
||||
data_ = std::move(c.data_);
|
||||
return *this;
|
||||
}
|
||||
secure_vector<T>& operator=(std::vector<T>&& c) {
|
||||
clean();
|
||||
data_ = std::move(c);
|
||||
return *this;
|
||||
}
|
||||
std::vector<T>& writable() { clean(); return data_; }
|
||||
const std::vector<T>& makeInsecure() const { return data_; }
|
||||
const uint8_t* data() const { return data_.data(); }
|
||||
|
||||
void clean() {
|
||||
clean(data_.begin(), data_.end());
|
||||
}
|
||||
|
||||
void clear() { clean(); data_.clear(); }
|
||||
|
||||
size_t size() const { return data_.size(); }
|
||||
bool empty() const { return data_.empty(); }
|
||||
|
||||
void swap(secure_vector<T>& other) { data_.swap(other.data_); }
|
||||
void resize(size_t s) {
|
||||
if (s == data_.size()) return;
|
||||
if (s < data_.size()) {
|
||||
//shrink
|
||||
clean(data_.begin()+s, data_.end());
|
||||
data_.resize(s);
|
||||
} else {
|
||||
//grow
|
||||
auto data = std::move(data_); // move protected data
|
||||
clear();
|
||||
data_.resize(s);
|
||||
std::copy(data.begin(), data.end(), data_.begin());
|
||||
clean(data.begin(), data.end());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Securely wipe memory
|
||||
*/
|
||||
static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j) {
|
||||
volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
|
||||
volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
|
||||
std::fill(b, e, 0);
|
||||
}
|
||||
|
||||
std::vector<T> data_;
|
||||
};
|
||||
|
||||
using SecureBlob = secure_vector<uint8_t>;
|
||||
|
||||
/**
|
||||
* Generate an RSA key pair (4096 bits) and a certificate.
|
||||
@@ -324,8 +577,8 @@ private:
|
||||
* If not set, the generated certificate will be a self-signed CA.
|
||||
* @param key_length stength of the generated private key (bits).
|
||||
*/
|
||||
Identity generateIdentity(const std::string& name, Identity ca, unsigned key_length, bool is_ca);
|
||||
Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {}, unsigned key_length = 4096);
|
||||
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name, Identity ca, unsigned key_length, bool is_ca);
|
||||
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {}, unsigned key_length = 4096);
|
||||
|
||||
|
||||
/**
|
||||
@@ -336,7 +589,7 @@ Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {},
|
||||
* will use SHA256 for hash_length up to 32 bytes,
|
||||
* will use SHA512 for hash_length of 33 bytes and more.
|
||||
*/
|
||||
Blob hash(const Blob& data, size_t hash_length = 512/8);
|
||||
OPENDHT_PUBLIC Blob hash(const Blob& data, size_t hash_length = 512/8);
|
||||
|
||||
/**
|
||||
* Generates an encryption key from a text password,
|
||||
@@ -345,19 +598,19 @@ Blob hash(const Blob& data, size_t hash_length = 512/8);
|
||||
* that can be transmitted in clear, and will be generated if
|
||||
* not provided (32 bytes).
|
||||
*/
|
||||
Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
|
||||
OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
|
||||
|
||||
/**
|
||||
* AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
|
||||
*/
|
||||
Blob aesEncrypt(const Blob& data, const Blob& key);
|
||||
Blob aesEncrypt(const Blob& data, const std::string& password);
|
||||
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const Blob& key);
|
||||
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
|
||||
|
||||
/**
|
||||
* AES-GCM decryption.
|
||||
*/
|
||||
Blob aesDecrypt(const Blob& data, const Blob& key);
|
||||
Blob aesDecrypt(const Blob& data, const std::string& password);
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const Blob& key);
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const std::string& password);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
// Generic helper definitions for shared library support
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#define OPENDHT_IMPORT __declspec(dllimport)
|
||||
#define OPENDHT_EXPORT __declspec(dllexport)
|
||||
#define OPENDHT_HIDDEN
|
||||
#else
|
||||
#define OPENDHT_IMPORT __attribute__ ((visibility ("default")))
|
||||
#define OPENDHT_EXPORT __attribute__ ((visibility ("default")))
|
||||
#define OPENDHT_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
|
||||
// Now we use the generic helper definitions above to define OPENDHT_PUBLIC and OPENDHT_LOCAL.
|
||||
// OPENDHT_PUBLIC is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
|
||||
// OPENDHT_LOCAL is used for non-api symbols.
|
||||
|
||||
#ifdef opendht_EXPORTS // defined if OpenDHT is compiled as a shared library
|
||||
#ifdef OPENDHT_BUILD // defined if we are building the OpenDHT shared library (instead of using it)
|
||||
#define OPENDHT_PUBLIC OPENDHT_EXPORT
|
||||
#else
|
||||
#define OPENDHT_PUBLIC OPENDHT_IMPORT
|
||||
#endif // OPENDHT_BUILD
|
||||
#define OPENDHT_LOCAL OPENDHT_HIDDEN
|
||||
#else // opendht_EXPORTS is not defined: this means OpenDHT is a static lib.
|
||||
#define OPENDHT_PUBLIC
|
||||
#define OPENDHT_LOCAL
|
||||
#endif // opendht_EXPORTS
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,16 +13,13 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "value.h"
|
||||
|
||||
MSGPACK_ADD_ENUM(dht::Value::Field)
|
||||
|
||||
namespace dht {
|
||||
enum class ImStatus : uint8_t {
|
||||
NONE = 0,
|
||||
@@ -35,7 +32,7 @@ MSGPACK_ADD_ENUM(dht::ImStatus)
|
||||
|
||||
namespace dht {
|
||||
|
||||
class DhtMessage : public Value::Serializable<DhtMessage>
|
||||
class OPENDHT_PUBLIC DhtMessage : public Value::Serializable<DhtMessage>
|
||||
{
|
||||
public:
|
||||
static const ValueType TYPE;
|
||||
@@ -61,7 +58,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SignedValue : public Value::Serializable<T>
|
||||
class OPENDHT_PUBLIC SignedValue : public Value::Serializable<T>
|
||||
{
|
||||
private:
|
||||
using BaseClass = Value::Serializable<T>;
|
||||
@@ -81,7 +78,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class EncryptedValue : public SignedValue<T>
|
||||
class OPENDHT_PUBLIC EncryptedValue : public SignedValue<T>
|
||||
{
|
||||
public:
|
||||
using BaseClass = SignedValue<T>;
|
||||
@@ -105,7 +102,7 @@ public:
|
||||
|
||||
|
||||
|
||||
class ImMessage : public SignedValue<ImMessage>
|
||||
class OPENDHT_PUBLIC ImMessage : public SignedValue<ImMessage>
|
||||
{
|
||||
private:
|
||||
using BaseClass = SignedValue<ImMessage>;
|
||||
@@ -123,7 +120,7 @@ public:
|
||||
}
|
||||
|
||||
dht::InfoHash to;
|
||||
dht::Value::Id id;
|
||||
dht::Value::Id id {0};
|
||||
std::string msg;
|
||||
long date {0};
|
||||
ImStatus status {ImStatus::NONE};
|
||||
@@ -131,7 +128,7 @@ public:
|
||||
MSGPACK_DEFINE_MAP(id, msg, date, status)
|
||||
};
|
||||
|
||||
class TrustRequest : public EncryptedValue<TrustRequest>
|
||||
class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
|
||||
{
|
||||
private:
|
||||
using BaseClass = EncryptedValue<TrustRequest>;
|
||||
@@ -149,10 +146,11 @@ public:
|
||||
|
||||
std::string service;
|
||||
Blob payload;
|
||||
MSGPACK_DEFINE(service, payload)
|
||||
bool confirm {false};
|
||||
MSGPACK_DEFINE_MAP(service, payload, confirm)
|
||||
};
|
||||
|
||||
class IceCandidates : public EncryptedValue<IceCandidates>
|
||||
class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
|
||||
{
|
||||
private:
|
||||
using BaseClass = EncryptedValue<IceCandidates>;
|
||||
@@ -192,13 +190,13 @@ public:
|
||||
ice_data = unpackBlob(o.via.array.ptr[1]);
|
||||
}
|
||||
|
||||
Value::Id id;
|
||||
Value::Id id {0};
|
||||
Blob ice_data;
|
||||
};
|
||||
|
||||
/* "Peer" announcement
|
||||
*/
|
||||
class IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
|
||||
class OPENDHT_PUBLIC IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
|
||||
{
|
||||
private:
|
||||
using BaseClass = Value::Serializable<IpServiceAnnouncement>;
|
||||
@@ -224,7 +222,7 @@ public:
|
||||
void msgpack_pack(Packer& pk) const
|
||||
{
|
||||
pk.pack_array(2);
|
||||
pk.pack(getPort());
|
||||
pk.pack(reinterpret_cast<const sockaddr_in*>(&ss)->sin_port);
|
||||
if (ss.ss_family == AF_INET) {
|
||||
pk.pack_bin(sizeof(in_addr));
|
||||
pk.pack_bin_body((const char*)&reinterpret_cast<const sockaddr_in*>(&ss)->sin_addr, sizeof(in_addr));
|
||||
@@ -238,7 +236,7 @@ public:
|
||||
{
|
||||
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
|
||||
if (o.via.array.size < 2) throw msgpack::type_error();
|
||||
setPort(o.via.array.ptr[0].as<in_port_t>());
|
||||
reinterpret_cast<sockaddr_in*>(&ss)->sin_port = o.via.array.ptr[0].as<in_port_t>();
|
||||
auto ip_dat = o.via.array.ptr[1].as<Blob>();
|
||||
if (ip_dat.size() == sizeof(in_addr))
|
||||
std::copy(ip_dat.begin(), ip_dat.end(), (char*)&reinterpret_cast<sockaddr_in*>(&ss)->sin_addr);
|
||||
@@ -273,8 +271,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
|
||||
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
|
||||
|
||||
extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
|
||||
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
|
||||
|
||||
}
|
||||
+67
-57
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -41,7 +41,9 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
namespace net {
|
||||
struct Request;
|
||||
} /* namespace net */
|
||||
|
||||
/**
|
||||
* Main Dht class.
|
||||
@@ -50,7 +52,7 @@ struct Request;
|
||||
* Must be given open UDP sockets and ::periodic must be
|
||||
* called regularly.
|
||||
*/
|
||||
class Dht {
|
||||
class OPENDHT_PUBLIC Dht {
|
||||
public:
|
||||
|
||||
// [[deprecated]]
|
||||
@@ -173,12 +175,12 @@ public:
|
||||
/**
|
||||
* Get locally stored data for the given hash.
|
||||
*/
|
||||
std::vector<std::shared_ptr<Value>> getLocal(const InfoHash& key, Value::Filter f = Value::AllFilter()) const;
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& key, Value::Filter f = Value::AllFilter()) const;
|
||||
|
||||
/**
|
||||
* Get locally stored data for the given key and value id.
|
||||
*/
|
||||
std::shared_ptr<Value> getLocalById(const InfoHash& key, Value::Id vid) const;
|
||||
Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const;
|
||||
|
||||
/**
|
||||
* Announce a value on all available protocols (IPv4, IPv6).
|
||||
@@ -187,12 +189,12 @@ public:
|
||||
* The done callback will be called once, when the first announce succeeds, or fails.
|
||||
*/
|
||||
void put(const InfoHash& key,
|
||||
std::shared_ptr<Value>,
|
||||
Sp<Value>,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false);
|
||||
void put(const InfoHash& key,
|
||||
const std::shared_ptr<Value>& v,
|
||||
const Sp<Value>& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
@@ -220,12 +222,12 @@ public:
|
||||
/**
|
||||
* Get data currently being put at the given hash.
|
||||
*/
|
||||
std::vector<std::shared_ptr<Value>> getPut(const InfoHash&);
|
||||
std::vector<Sp<Value>> getPut(const InfoHash&);
|
||||
|
||||
/**
|
||||
* Get data currently being put at the given hash with the given id.
|
||||
*/
|
||||
std::shared_ptr<Value> getPut(const InfoHash&, const Value::Id&);
|
||||
Sp<Value> getPut(const InfoHash&, const Value::Id&);
|
||||
|
||||
/**
|
||||
* Stop any put/announce operation at the given location,
|
||||
@@ -268,8 +270,8 @@ public:
|
||||
std::vector<ValuesExport> exportValues() const;
|
||||
void importValues(const std::vector<ValuesExport>&);
|
||||
|
||||
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return,
|
||||
unsigned *incoming_return) const;
|
||||
NodeStats getNodesStats(sa_family_t af) const;
|
||||
|
||||
std::string getStorageLog() const;
|
||||
std::string getStorageLog(const InfoHash&) const;
|
||||
|
||||
@@ -344,9 +346,9 @@ private:
|
||||
/* Timeout for listen */
|
||||
static constexpr std::chrono::seconds LISTEN_EXPIRE_TIME {30};
|
||||
|
||||
static constexpr std::chrono::seconds REANNOUNCE_MARGIN {5};
|
||||
static constexpr std::chrono::seconds REANNOUNCE_MARGIN {10};
|
||||
|
||||
static constexpr size_t TOKEN_SIZE {64};
|
||||
static constexpr size_t TOKEN_SIZE {32};
|
||||
|
||||
// internal structures
|
||||
struct SearchNode;
|
||||
@@ -355,6 +357,7 @@ private:
|
||||
struct LocalListener;
|
||||
struct Search;
|
||||
struct ValueStorage;
|
||||
class StorageBucket;
|
||||
struct Listener;
|
||||
struct Storage;
|
||||
|
||||
@@ -375,17 +378,19 @@ private:
|
||||
// Only nodes running only as bootstrap nodes should
|
||||
// be put in bootstrap mode.
|
||||
const bool is_bootstrap {false};
|
||||
const bool maintain_storage {false};
|
||||
|
||||
// the stuff
|
||||
RoutingTable buckets4 {};
|
||||
RoutingTable buckets6 {};
|
||||
|
||||
std::map<InfoHash, Storage> store;
|
||||
std::map<SockAddr, StorageBucket, SockAddr::ipCmp> store_quota;
|
||||
size_t total_values {0};
|
||||
size_t total_store_size {0};
|
||||
size_t max_store_size {DEFAULT_STORAGE_LIMIT};
|
||||
|
||||
using SearchMap = std::map<InfoHash, std::shared_ptr<Search>>;
|
||||
using SearchMap = std::map<InfoHash, Sp<Search>>;
|
||||
SearchMap searches4 {};
|
||||
SearchMap searches6 {};
|
||||
uint16_t search_id {0};
|
||||
@@ -397,11 +402,11 @@ private:
|
||||
|
||||
// timing
|
||||
Scheduler scheduler;
|
||||
std::shared_ptr<Scheduler::Job> nextNodesConfirmation {};
|
||||
std::shared_ptr<Scheduler::Job> nextStorageMaintenance {};
|
||||
Sp<Scheduler::Job> nextNodesConfirmation {};
|
||||
Sp<Scheduler::Job> nextStorageMaintenance {};
|
||||
time_point mybucket_grow_time {time_point::min()}, mybucket6_grow_time {time_point::min()};
|
||||
|
||||
NetworkEngine network_engine;
|
||||
net::NetworkEngine network_engine;
|
||||
unsigned pending_pings4 {0};
|
||||
unsigned pending_pings6 {0};
|
||||
|
||||
@@ -416,11 +421,15 @@ private:
|
||||
void reportedAddr(const SockAddr&);
|
||||
|
||||
// Storage
|
||||
void storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, size_t tid, Query&& = {});
|
||||
bool storageStore(const InfoHash& id, const std::shared_ptr<Value>& value, time_point created);
|
||||
void expireStorage();
|
||||
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {});
|
||||
bool storageStore(const InfoHash& id, const Sp<Value>& value, time_point created, const SockAddr* sa = nullptr);
|
||||
void expireStore();
|
||||
void expireStorage(InfoHash h);
|
||||
void expireStore(decltype(store)::iterator);
|
||||
|
||||
void storageChanged(const InfoHash& id, Storage& st, ValueStorage&);
|
||||
std::string printStorageLog(const decltype(store)::value_type&) const;
|
||||
void printStorageQuota(std::ostream& out, const decltype(store_quota)::value_type& ip) const;
|
||||
|
||||
/**
|
||||
* For a given storage, if values don't belong there anymore because this
|
||||
@@ -456,10 +465,10 @@ private:
|
||||
void dumpBucket(const Bucket& b, std::ostream& out) const;
|
||||
|
||||
// Nodes
|
||||
void onNewNode(const std::shared_ptr<Node>& node, int confirm);
|
||||
std::shared_ptr<Node> findNode(const InfoHash& id, sa_family_t af);
|
||||
const std::shared_ptr<Node> findNode(const InfoHash& id, sa_family_t af) const;
|
||||
bool trySearchInsert(const std::shared_ptr<Node>& node);
|
||||
void onNewNode(const Sp<Node>& node, int confirm);
|
||||
Sp<Node> findNode(const InfoHash& id, sa_family_t af);
|
||||
const Sp<Node> findNode(const InfoHash& id, sa_family_t af) const;
|
||||
bool trySearchInsert(const Sp<Node>& node);
|
||||
|
||||
// Searches
|
||||
|
||||
@@ -470,10 +479,10 @@ private:
|
||||
* Low-level method that will perform a search on the DHT for the specified
|
||||
* infohash (id), using the specified IP version (IPv4 or IPv6).
|
||||
*/
|
||||
std::shared_ptr<Search> search(const InfoHash& id, sa_family_t af, GetCallback = {}, QueryCallback = {}, DoneCallback = {}, Value::Filter = {}, Query q = {});
|
||||
Sp<Search> search(const InfoHash& id, sa_family_t af, GetCallback = {}, QueryCallback = {}, DoneCallback = {}, Value::Filter = {}, Query q = {});
|
||||
|
||||
void announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created=time_point::max(), bool permanent = false);
|
||||
size_t listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter f = Value::AllFilter(), const std::shared_ptr<Query>& q = {});
|
||||
void announce(const InfoHash& id, sa_family_t af, Sp<Value> value, DoneCallback callback, time_point created=time_point::max(), bool permanent = false);
|
||||
size_t listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter f = Value::AllFilter(), const Sp<Query>& q = {});
|
||||
|
||||
/**
|
||||
* Refill the search with good nodes if possible.
|
||||
@@ -483,8 +492,6 @@ private:
|
||||
* @return the number inserted nodes.
|
||||
*/
|
||||
unsigned refill(Search& sr);
|
||||
|
||||
Search *findSearch(unsigned short tid, sa_family_t af);
|
||||
void expireSearches();
|
||||
|
||||
void confirmNodes();
|
||||
@@ -498,10 +505,10 @@ private:
|
||||
* @param ws A weak pointer to the search concerned by the request.
|
||||
* @param query The query sent to the node.
|
||||
*/
|
||||
void searchNodeGetDone(const Request& status,
|
||||
NetworkEngine::RequestAnswer&& answer,
|
||||
void searchNodeGetDone(const net::Request& status,
|
||||
net::NetworkEngine::RequestAnswer&& answer,
|
||||
std::weak_ptr<Search> ws,
|
||||
std::shared_ptr<Query> query);
|
||||
Sp<Query> query);
|
||||
|
||||
/**
|
||||
* Generic function to execute when a 'get' request expires.
|
||||
@@ -512,7 +519,7 @@ private:
|
||||
* @param ws A weak pointer to the search concerned by the request.
|
||||
* @param query The query sent to the node.
|
||||
*/
|
||||
void searchNodeGetExpired(const Request& status, bool over, std::weak_ptr<Search> ws, std::shared_ptr<Query> query);
|
||||
void searchNodeGetExpired(const net::Request& status, bool over, std::weak_ptr<Search> ws, Sp<Query> query);
|
||||
|
||||
/**
|
||||
* This method recovers sends individual request for values per id.
|
||||
@@ -521,12 +528,12 @@ private:
|
||||
* @param query The initial query passed through the API.
|
||||
* @param n The node to which send the requests.
|
||||
*/
|
||||
void paginate(std::weak_ptr<Search> ws, std::shared_ptr<Query> query, SearchNode* n);
|
||||
void paginate(std::weak_ptr<Search> ws, Sp<Query> query, SearchNode* n);
|
||||
|
||||
/**
|
||||
* If update is true, this method will also send message to synced but non-updated search nodes.
|
||||
*/
|
||||
SearchNode* searchSendGetValues(std::shared_ptr<Search> sr, SearchNode *n = nullptr, bool update = true);
|
||||
SearchNode* searchSendGetValues(Sp<Search> sr, SearchNode *n = nullptr, bool update = true);
|
||||
|
||||
/**
|
||||
* Forwards an 'announce' request for a list of nodes to the network engine.
|
||||
@@ -534,7 +541,7 @@ private:
|
||||
* @param sr The search for which we want to announce a value.
|
||||
* @param announce The 'announce' structure.
|
||||
*/
|
||||
void searchSendAnnounceValue(const std::shared_ptr<Search>& sr);
|
||||
void searchSendAnnounceValue(const Sp<Search>& sr);
|
||||
|
||||
/**
|
||||
* Main process of a Search's operations. This function will demand the
|
||||
@@ -543,51 +550,54 @@ private:
|
||||
*
|
||||
* @param sr The search to execute its operations.
|
||||
*/
|
||||
void searchStep(std::shared_ptr<Search> sr);
|
||||
void searchStep(Sp<Search> sr);
|
||||
void dumpSearch(const Search& sr, std::ostream& out) const;
|
||||
|
||||
bool neighbourhoodMaintenance(RoutingTable&);
|
||||
|
||||
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr&);
|
||||
|
||||
void onError(std::shared_ptr<Request> node, DhtProtocolException e);
|
||||
void onError(Sp<net::Request> node, net::DhtProtocolException e);
|
||||
/* when our address is reported by a distant peer. */
|
||||
void onReportedAddr(const InfoHash& id, const SockAddr&);
|
||||
/* when we receive a ping request */
|
||||
NetworkEngine::RequestAnswer onPing(std::shared_ptr<Node> node);
|
||||
net::NetworkEngine::RequestAnswer onPing(Sp<Node> node);
|
||||
/* when we receive a "find node" request */
|
||||
NetworkEngine::RequestAnswer onFindNode(std::shared_ptr<Node> node, const InfoHash& hash, want_t want);
|
||||
void onFindNodeDone(const Request& status, NetworkEngine::RequestAnswer& a, std::shared_ptr<Search> sr);
|
||||
net::NetworkEngine::RequestAnswer onFindNode(Sp<Node> node, const InfoHash& hash, want_t want);
|
||||
void onFindNodeDone(const Sp<Node>& status,
|
||||
net::NetworkEngine::RequestAnswer& a,
|
||||
Sp<Search> sr);
|
||||
/* when we receive a "get values" request */
|
||||
NetworkEngine::RequestAnswer onGetValues(std::shared_ptr<Node> node,
|
||||
net::NetworkEngine::RequestAnswer onGetValues(Sp<Node> node,
|
||||
const InfoHash& hash,
|
||||
want_t want,
|
||||
const Query& q);
|
||||
void onGetValuesDone(const Request& status,
|
||||
NetworkEngine::RequestAnswer& a,
|
||||
std::shared_ptr<Search>& sr,
|
||||
const std::shared_ptr<Query>& orig_query);
|
||||
void onGetValuesDone(const Sp<Node>& status,
|
||||
net::NetworkEngine::RequestAnswer& a,
|
||||
Sp<Search>& sr,
|
||||
const Sp<Query>& orig_query);
|
||||
/* when we receive a listen request */
|
||||
NetworkEngine::RequestAnswer onListen(std::shared_ptr<Node> node,
|
||||
net::NetworkEngine::RequestAnswer onListen(Sp<Node> node,
|
||||
const InfoHash& hash,
|
||||
const Blob& token,
|
||||
size_t rid,
|
||||
size_t socket_id,
|
||||
const Query& query);
|
||||
void onListenDone(const Request& status,
|
||||
NetworkEngine::RequestAnswer& a,
|
||||
std::shared_ptr<Search>& sr,
|
||||
const std::shared_ptr<Query>& orig_query);
|
||||
void onListenDone(const Sp<Node>& status,
|
||||
net::NetworkEngine::RequestAnswer& a,
|
||||
Sp<Search>& sr);
|
||||
/* when we receive an announce request */
|
||||
NetworkEngine::RequestAnswer onAnnounce(std::shared_ptr<Node> node,
|
||||
net::NetworkEngine::RequestAnswer onAnnounce(Sp<Node> node,
|
||||
const InfoHash& hash,
|
||||
const Blob& token,
|
||||
const std::vector<std::shared_ptr<Value>>& v,
|
||||
const std::vector<Sp<Value>>& v,
|
||||
const time_point& created);
|
||||
NetworkEngine::RequestAnswer onRefresh(std::shared_ptr<Node> node,
|
||||
net::NetworkEngine::RequestAnswer onRefresh(Sp<Node> node,
|
||||
const InfoHash& hash,
|
||||
const Blob& token,
|
||||
const Value::Id& vid);
|
||||
void onAnnounceDone(const Request& status, NetworkEngine::RequestAnswer& a, std::shared_ptr<Search>& sr);
|
||||
void onAnnounceDone(const Sp<Node>& status,
|
||||
net::NetworkEngine::RequestAnswer& a,
|
||||
Sp<Search>& sr);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -26,6 +25,7 @@
|
||||
#include "callbacks.h"
|
||||
#include "sockaddr.h"
|
||||
#include "log_enable.h"
|
||||
#include "def.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@@ -48,7 +48,7 @@ struct SecureDhtConfig;
|
||||
* either wait for (expectedly frequent) calls to ::loop() or start an internal
|
||||
* thread that will update the DHT when appropriate.
|
||||
*/
|
||||
class DhtRunner {
|
||||
class OPENDHT_PUBLIC DhtRunner {
|
||||
|
||||
public:
|
||||
typedef std::function<void(NodeStatus, NodeStatus)> StatusCallback;
|
||||
@@ -203,6 +203,7 @@ public:
|
||||
* Usefull to restart a node and get things running fast without putting load on the network.
|
||||
*/
|
||||
void bootstrap(const std::vector<std::pair<sockaddr_storage, socklen_t>>& nodes, DoneCallbackSimple&& cb={});
|
||||
void bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb={});
|
||||
|
||||
/**
|
||||
* Insert known nodes to the routing table, without necessarly ping them.
|
||||
@@ -275,14 +276,15 @@ public:
|
||||
return running;
|
||||
}
|
||||
|
||||
int getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
|
||||
NodeStats getNodesStats(sa_family_t af) const;
|
||||
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
|
||||
|
||||
std::vector<unsigned> getNodeMessageStats(bool in = false) const;
|
||||
std::string getStorageLog() const;
|
||||
std::string getStorageLog(const InfoHash&) const;
|
||||
std::string getRoutingTablesLog(sa_family_t af) const;
|
||||
std::string getSearchesLog(sa_family_t af = AF_UNSPEC) const;
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC);
|
||||
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC);
|
||||
|
||||
@@ -309,7 +311,8 @@ public:
|
||||
/*.node_config = */{
|
||||
/*.node_id = */{},
|
||||
/*.network = */network,
|
||||
/*.is_bootstrap = */false
|
||||
/*.is_bootstrap = */false,
|
||||
/*.maintain_storage*/false
|
||||
},
|
||||
/*.id = */identity
|
||||
},
|
||||
@@ -368,7 +371,7 @@ private:
|
||||
* nodes so that the DHT node can recover quickly from losing connection
|
||||
* with the network.
|
||||
*/
|
||||
void tryBootstrapCoutinuously();
|
||||
void tryBootstrapContinuously();
|
||||
|
||||
void doRun(const sockaddr_in* sin4, const sockaddr_in6* sin6, SecureDhtConfig config);
|
||||
time_point loop_();
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Nicolas Reynaud <nicolas.reynaud@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 <string>
|
||||
@@ -26,7 +46,7 @@ namespace indexation {
|
||||
* the node in question is a leaf, *the label is a prefix of all the keys
|
||||
* contained in the leaf*.
|
||||
*/
|
||||
struct Prefix {
|
||||
struct OPENDHT_PUBLIC Prefix {
|
||||
Prefix() {}
|
||||
Prefix(InfoHash h) : size_(h.size() * 8), content_(h.begin(), h.end()) { }
|
||||
Prefix(const Blob& d, const Blob& f={}) : size_(d.size()*8), flags_(f), content_(d) { }
|
||||
@@ -245,7 +265,7 @@ private:
|
||||
};
|
||||
|
||||
using Value = std::pair<InfoHash, dht::Value::Id>;
|
||||
struct IndexEntry : public dht::Value::Serializable<IndexEntry> {
|
||||
struct OPENDHT_PUBLIC IndexEntry : public dht::Value::Serializable<IndexEntry> {
|
||||
static const ValueType TYPE;
|
||||
|
||||
virtual void unpackValue(const dht::Value& v) {
|
||||
@@ -265,7 +285,7 @@ struct IndexEntry : public dht::Value::Serializable<IndexEntry> {
|
||||
MSGPACK_DEFINE_MAP(prefix, value)
|
||||
};
|
||||
|
||||
class Pht {
|
||||
class OPENDHT_PUBLIC Pht {
|
||||
static constexpr const char* INVALID_KEY = "Key does not match the PHT key spec.";
|
||||
|
||||
/* Prefixes the user_type for all dht values put on the DHT */
|
||||
@@ -284,13 +304,13 @@ public:
|
||||
/* Specifications of the keys. It defines the number, the length and the
|
||||
* serialization order of fields. */
|
||||
using KeySpec = std::map<std::string, size_t>;
|
||||
using LookupCallback = std::function<void(std::vector<std::shared_ptr<Value>>& values, Prefix p)>;
|
||||
using LookupCallback = std::function<void(std::vector<std::shared_ptr<Value>>& values, const Prefix& p)>;
|
||||
|
||||
typedef void (*LookupCallbackRaw)(std::vector<std::shared_ptr<Value>>* values, Prefix* p, void *user_data);
|
||||
static LookupCallback
|
||||
bindLookupCb(LookupCallbackRaw raw_cb, void* user_data) {
|
||||
if (not raw_cb) return {};
|
||||
return [=](std::vector<std::shared_ptr<Value>>& values, Prefix p) {
|
||||
return [=](std::vector<std::shared_ptr<Value>>& values, const Prefix& p) {
|
||||
raw_cb((std::vector<std::shared_ptr<Value>>*) &values, (Prefix*) &p, user_data);
|
||||
};
|
||||
}
|
||||
@@ -353,7 +373,7 @@ private:
|
||||
* @param done_cb : Callback to call when the insert is done
|
||||
*/
|
||||
|
||||
void insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
|
||||
void insert(const Prefix& kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
|
||||
bool check_split, DoneCallbackSimple done_cb = {});
|
||||
|
||||
class Cache {
|
||||
@@ -396,8 +416,8 @@ private:
|
||||
};
|
||||
|
||||
/* Callback used for insert value by using the pht */
|
||||
using RealInsertCallback = std::function<void(std::shared_ptr<Prefix> p, IndexEntry entry)>;
|
||||
using LookupCallbackWrapper = std::function<void(std::vector<std::shared_ptr<IndexEntry>>& values, Prefix p)>;
|
||||
using RealInsertCallback = std::function<void(const Prefix& p, IndexEntry entry)>;
|
||||
using LookupCallbackWrapper = std::function<void(std::vector<std::shared_ptr<IndexEntry>>& values, const Prefix& p)>;
|
||||
|
||||
/**
|
||||
* Performs a step in the lookup operation. Each steps are performed
|
||||
@@ -446,7 +466,7 @@ private:
|
||||
* @param entry The entry to put at the prefix p
|
||||
* @param end_cb Callback to use at the end of counting
|
||||
*/
|
||||
void getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertCallback end_cb );
|
||||
void getRealPrefix(const std::shared_ptr<Prefix>& p, IndexEntry entry, RealInsertCallback end_cb );
|
||||
|
||||
/**
|
||||
* Looking where to put the data cause if there is free space on the node
|
||||
@@ -465,12 +485,11 @@ private:
|
||||
* @param vals : The vector of values to compare with comapred
|
||||
* @return position compared diverge from all others
|
||||
*/
|
||||
size_t foundSplitLocation(Prefix compared, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals) {
|
||||
static size_t findSplitLocation(const Prefix& compared, const std::vector<std::shared_ptr<IndexEntry>>& vals) {
|
||||
for ( size_t i = 0; i < compared.content_.size() * 8 - 1; i++ )
|
||||
for ( auto const& v : *vals)
|
||||
for ( auto const& v : vals)
|
||||
if ( Prefix(v->prefix).isContentBitActive(i) != compared.isContentBitActive(i) )
|
||||
return i + 1;
|
||||
|
||||
return compared.content_.size() * 8 - 1;
|
||||
}
|
||||
|
||||
@@ -482,7 +501,7 @@ private:
|
||||
* @param entry : Entry to put on the pht
|
||||
* @param end_cb : Callback to apply to the insert prefi (here does the insert)
|
||||
*/
|
||||
void split(Prefix insert, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals, IndexEntry entry, RealInsertCallback end_cb);
|
||||
void split(const Prefix& insert, const std::vector<std::shared_ptr<IndexEntry>>& vals, IndexEntry entry, RealInsertCallback end_cb);
|
||||
|
||||
/**
|
||||
* Tells if the key is valid according to the key spec.
|
||||
|
||||
+92
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,12 +13,13 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -40,6 +41,7 @@ typedef uint16_t in_port_t;
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@@ -48,12 +50,93 @@ typedef uint16_t in_port_t;
|
||||
|
||||
namespace dht {
|
||||
|
||||
using byte = uint8_t;
|
||||
|
||||
template <size_t N>
|
||||
class OPENDHT_PUBLIC Hash
|
||||
{
|
||||
public:
|
||||
Hash() {
|
||||
data_.fill(0);
|
||||
}
|
||||
Hash(const msgpack::object& o) {
|
||||
msgpack_unpack(o);
|
||||
}
|
||||
byte* data() {
|
||||
return data_.data();
|
||||
}
|
||||
const byte* data() const {
|
||||
return data_.data();
|
||||
}
|
||||
constexpr size_t size() const { return data_.size(); }
|
||||
explicit operator bool() const { return std::any_of(data_.begin(), data_.end(), [](byte _b) { return _b != 0; }); }
|
||||
bool operator==(Hash const& _c) const { return data_ == _c.data_; }
|
||||
bool operator!=(Hash const& _c) const { return data_ != _c.data_; }
|
||||
bool operator<(Hash const& _c) const { for (unsigned i = 0; i < N; ++i) if (data_[i] < _c.data_[i]) return true; else if (data_[i] > _c.data_[i]) return false; return false; }
|
||||
bool operator>=(Hash const& _c) const { return !operator<(_c); }
|
||||
bool operator<=(Hash const& _c) const { return operator==(_c) || operator<(_c); }
|
||||
bool operator>(Hash const& _c) const { return !operator<=(_c); }
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& pk) const
|
||||
{
|
||||
pk.pack_bin(N);
|
||||
pk.pack_bin_body((char*)data_.data(), N);
|
||||
}
|
||||
void msgpack_unpack(msgpack::object o) {
|
||||
if (o.type != msgpack::type::BIN or o.via.bin.size != N)
|
||||
throw msgpack::type_error();
|
||||
std::copy_n(o.via.bin.ptr, N, data_.data());
|
||||
}
|
||||
|
||||
template <size_t M>
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
|
||||
|
||||
template <size_t M>
|
||||
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, Hash<M>& h);
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<byte, N> data_;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
std::ostream& operator<< (std::ostream& s, const Hash<N>& h)
|
||||
{
|
||||
s << std::hex;
|
||||
for (unsigned i=0; i<h.size(); i++)
|
||||
s << std::setfill('0') << std::setw(2) << (unsigned)h.data_[i];
|
||||
s << std::dec;
|
||||
return s;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
std::istream& operator>> (std::istream& s, Hash<N>& h)
|
||||
{
|
||||
std::array<char, h.size()*2> dat;
|
||||
s.exceptions(std::istream::eofbit | std::istream::failbit);
|
||||
s.read(&(*dat.begin()), dat.size());
|
||||
for (size_t i = 0; i < h.size(); i++) {
|
||||
unsigned res = 0;
|
||||
sscanf(dat.data() + 2*i, "%02x", &res);
|
||||
h[i] = res;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
using h256 = Hash<32>;
|
||||
using PkId = h256;
|
||||
|
||||
/**
|
||||
* Represents an InfoHash.
|
||||
* An InfoHash is a byte array of HASH_LEN bytes.
|
||||
* InfoHashes identify nodes and values in the Dht.
|
||||
*/
|
||||
class InfoHash final : public std::array<uint8_t, HASH_LEN> {
|
||||
class OPENDHT_PUBLIC InfoHash final : public std::array<uint8_t, HASH_LEN> {
|
||||
public:
|
||||
constexpr InfoHash() : std::array<uint8_t, HASH_LEN>() {}
|
||||
constexpr InfoHash(const std::array<uint8_t, HASH_LEN>& h) : std::array<uint8_t, HASH_LEN>(h) {}
|
||||
@@ -96,11 +179,7 @@ public:
|
||||
* Forget about the ``XOR-metric''. An id is just a path from the
|
||||
* root of the tree, so bits are numbered from the start.
|
||||
*/
|
||||
#ifdef WIN32_NATIVE
|
||||
static inline int cmp(const InfoHash& __restrict id1, const InfoHash& __restrict id2) {
|
||||
#else
|
||||
static inline int cmp(const InfoHash& __restrict__ id1, const InfoHash& __restrict__ id2) {
|
||||
#endif
|
||||
static inline int cmp(const InfoHash& id1, const InfoHash& id2) {
|
||||
return std::memcmp(id1.data(), id2.data(), HASH_LEN);
|
||||
}
|
||||
|
||||
@@ -196,8 +275,10 @@ public:
|
||||
|
||||
static InfoHash getRandom();
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& s, const InfoHash& h);
|
||||
friend std::istream& operator>> (std::istream& s, InfoHash& h);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const InfoHash& h);
|
||||
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, InfoHash& h);
|
||||
|
||||
const char* to_c_str() const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
+10
-52
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -62,58 +61,17 @@ constexpr const Color::Modifier yellow(Color::FG_YELLOW);
|
||||
/**
|
||||
* Print va_list to std::ostream (used for logging).
|
||||
*/
|
||||
void
|
||||
printLog(std::ostream& s, char const* m, va_list args) {
|
||||
// print log to buffer
|
||||
std::array<char, 8192> buffer;
|
||||
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
|
||||
if (ret < 0)
|
||||
return;
|
||||
OPENDHT_PUBLIC void
|
||||
printLog(std::ostream &s, char const *m, va_list args);
|
||||
|
||||
// write timestamp
|
||||
using namespace std::chrono;
|
||||
using log_precision = microseconds;
|
||||
constexpr auto den = log_precision::period::den;
|
||||
auto micro = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
|
||||
s << "[" << std::setfill('0') << std::setw(6) << micro / den << "."
|
||||
<< std::setfill('0') << std::setw(6) << micro % den << "]" << " ";
|
||||
OPENDHT_PUBLIC void
|
||||
enableLogging(dht::DhtRunner &dht);
|
||||
|
||||
// write log
|
||||
s.write(buffer.data(), std::min((size_t)ret, buffer.size()));
|
||||
if ((size_t)ret >= buffer.size())
|
||||
s << "[[TRUNCATED]]";
|
||||
s.put('\n');
|
||||
}
|
||||
OPENDHT_PUBLIC void
|
||||
enableFileLogging(dht::DhtRunner &dht, const std::string &path);
|
||||
|
||||
void
|
||||
enableLogging(dht::DhtRunner& dht)
|
||||
{
|
||||
dht.setLoggers(
|
||||
[](char const* m, va_list args){ std::cerr << red; printLog(std::cerr, m, args); std::cerr << def; },
|
||||
[](char const* m, va_list args){ std::cout << yellow; printLog(std::cout, m, args); 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>();
|
||||
logfile->open(path, std::ios::out);
|
||||
|
||||
dht.setLoggers(
|
||||
[=](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); }
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
disableLogging(dht::DhtRunner& dht)
|
||||
{
|
||||
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
|
||||
}
|
||||
OPENDHT_PUBLIC void
|
||||
disableLogging(dht::DhtRunner &dht);
|
||||
|
||||
} /* log */
|
||||
} /* dht */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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 <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
struct TransPrefix : public std::array<uint8_t, 2> {
|
||||
TransPrefix(const std::string& str) : std::array<uint8_t, 2>({{(uint8_t)str[0], (uint8_t)str[1]}}) {}
|
||||
static const TransPrefix PING;
|
||||
static const TransPrefix FIND_NODE;
|
||||
static const TransPrefix GET_VALUES;
|
||||
static const TransPrefix ANNOUNCE_VALUES;
|
||||
static const TransPrefix REFRESH;
|
||||
static const TransPrefix LISTEN;
|
||||
};
|
||||
|
||||
/* Transaction-ids are 4-bytes long, with the first two bytes identifying
|
||||
* the kind of request, and the remaining two a sequence number in
|
||||
* host order.
|
||||
*/
|
||||
struct TransId final : public std::array<uint8_t, 4> {
|
||||
static const constexpr uint16_t INVALID {0};
|
||||
|
||||
TransId() { std::fill_n(begin(), 4, 0); }
|
||||
TransId(const std::array<char, 4>& o) { std::copy(o.begin(), o.end(), begin()); }
|
||||
TransId(const TransPrefix prefix, uint16_t seqno = 0) {
|
||||
std::copy_n(prefix.begin(), prefix.size(), begin());
|
||||
*reinterpret_cast<uint16_t*>(data()+prefix.size()) = seqno;
|
||||
}
|
||||
|
||||
TransId(const char* q, size_t l) : array<uint8_t, 4>() {
|
||||
if (l > 4) {
|
||||
length = 0;
|
||||
} else {
|
||||
std::copy_n(q, l, begin());
|
||||
length = l;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getTid() const {
|
||||
return *reinterpret_cast<const uint16_t*>(&(*this)[2]);
|
||||
}
|
||||
|
||||
uint32_t toInt() const {
|
||||
return *reinterpret_cast<const uint32_t*>(&(*this)[0]);
|
||||
}
|
||||
|
||||
bool matches(const TransPrefix prefix, uint16_t* tid = nullptr) const {
|
||||
if (std::equal(begin(), begin()+2, prefix.begin())) {
|
||||
if (tid)
|
||||
*tid = getTid();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned length {4};
|
||||
};
|
||||
|
||||
} /* namespace net */
|
||||
} /* dht */
|
||||
+244
-186
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "utils.h"
|
||||
#include "rng.h"
|
||||
#include "rate_limiter.h"
|
||||
#include "net.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -37,6 +38,10 @@
|
||||
#include <queue>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
struct Request;
|
||||
struct Socket;
|
||||
|
||||
#ifndef MSG_CONFIRM
|
||||
#define MSG_CONFIRM 0
|
||||
@@ -96,56 +101,7 @@ struct ParsedMessage;
|
||||
*/
|
||||
class NetworkEngine final
|
||||
{
|
||||
struct TransPrefix : public std::array<uint8_t, 2> {
|
||||
TransPrefix(const std::string& str) : std::array<uint8_t, 2>({{(uint8_t)str[0], (uint8_t)str[1]}}) {}
|
||||
static const TransPrefix PING;
|
||||
static const TransPrefix FIND_NODE;
|
||||
static const TransPrefix GET_VALUES;
|
||||
static const TransPrefix ANNOUNCE_VALUES;
|
||||
static const TransPrefix REFRESH;
|
||||
static const TransPrefix LISTEN;
|
||||
};
|
||||
public:
|
||||
|
||||
/* Transaction-ids are 4-bytes long, with the first two bytes identifying
|
||||
* the kind of request, and the remaining two a sequence number in
|
||||
* host order.
|
||||
*/
|
||||
struct TransId final : public std::array<uint8_t, 4> {
|
||||
static const constexpr uint16_t INVALID {0};
|
||||
|
||||
TransId() {}
|
||||
TransId(const std::array<char, 4>& o) { std::copy(o.begin(), o.end(), begin()); }
|
||||
TransId(const TransPrefix prefix, uint16_t seqno = 0) {
|
||||
std::copy_n(prefix.begin(), prefix.size(), begin());
|
||||
*reinterpret_cast<uint16_t*>(data()+prefix.size()) = seqno;
|
||||
}
|
||||
|
||||
TransId(const char* q, size_t l) : array<uint8_t, 4>() {
|
||||
if (l > 4) {
|
||||
length = 0;
|
||||
} else {
|
||||
std::copy_n(q, l, begin());
|
||||
length = l;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getTid() const {
|
||||
return *reinterpret_cast<const uint16_t*>(&(*this)[2]);
|
||||
}
|
||||
|
||||
bool matches(const TransPrefix prefix, uint16_t* tid = nullptr) const {
|
||||
if (std::equal(begin(), begin()+2, prefix.begin())) {
|
||||
if (tid)
|
||||
*tid = getTid();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned length {4};
|
||||
};
|
||||
|
||||
/*!
|
||||
* @class RequestAnswer
|
||||
* @brief Answer for a request.
|
||||
@@ -156,121 +112,101 @@ public:
|
||||
struct RequestAnswer {
|
||||
Blob ntoken {};
|
||||
Value::Id vid {};
|
||||
std::vector<std::shared_ptr<Value>> values {};
|
||||
std::vector<std::shared_ptr<FieldValueIndex>> fields {};
|
||||
std::vector<std::shared_ptr<Node>> nodes4 {};
|
||||
std::vector<std::shared_ptr<Node>> nodes6 {};
|
||||
std::vector<Sp<Value>> values {};
|
||||
std::vector<Sp<FieldValueIndex>> fields {};
|
||||
std::vector<Sp<Node>> nodes4 {};
|
||||
std::vector<Sp<Node>> nodes6 {};
|
||||
RequestAnswer() {}
|
||||
RequestAnswer(ParsedMessage&& msg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cancel a request. Setting req->cancelled = true is not enough in the case
|
||||
* a request is "persistent".
|
||||
*/
|
||||
void cancelRequest(std::shared_ptr<Request>& req);
|
||||
|
||||
void connectivityChanged(sa_family_t);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Called when we receive an error message.
|
||||
*/
|
||||
std::function<void(Sp<Request>, DhtProtocolException)> onError;
|
||||
|
||||
/**
|
||||
* @brief when we receive an error message.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Request>) the associated request for
|
||||
* which we got an error;
|
||||
*/
|
||||
std::function<void(std::shared_ptr<Request>, DhtProtocolException)> onError;
|
||||
/**
|
||||
* @brief when a new node happens.
|
||||
*
|
||||
* Called for every packets received for handling new nodes contacting us.
|
||||
*
|
||||
* @param id (type: InfoHash) id of the node.
|
||||
* @param saddr (type: sockaddr*) sockaddr* pointer containing address ip information.
|
||||
* @param saddr_len (type: socklen_t) lenght of the sockaddr struct.
|
||||
* @param confirm (type: int) 1 if the node sent a message, 2 if it sent us a reply.
|
||||
* @param node: the node
|
||||
* @param confirm: 1 if the node sent a message, 2 if it sent us a reply.
|
||||
*/
|
||||
std::function<void(const std::shared_ptr<Node>&, int)> onNewNode;
|
||||
std::function<void(const Sp<Node>&, int)> onNewNode;
|
||||
/**
|
||||
* @brief when an addres is reported from a distant node.
|
||||
* Called when an addres is reported from a requested node.
|
||||
*
|
||||
* @param id (type: InfoHash) id of the node.
|
||||
* @param saddr (type: sockaddr*) sockaddr* pointer containing address ip information.
|
||||
* @param h: id
|
||||
* @param saddr_len (type: socklen_t) lenght of the sockaddr struct.
|
||||
*/
|
||||
std::function<void(const InfoHash&, const SockAddr&)> onReportedAddr;
|
||||
/**
|
||||
* @brief on ping request callback.
|
||||
* Called on ping reception.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>)> onPing {};
|
||||
std::function<RequestAnswer(Sp<Node>)> onPing {};
|
||||
/**
|
||||
* @brief on find node request callback.
|
||||
* Called on find node request.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param vhash (type: InfoHash) hash of the value of interest.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
* @param h (type: InfoHash) hash of the value of interest.
|
||||
* @param want (type: want_t) states if nodes sent in the response are ipv4
|
||||
* or ipv6.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>,
|
||||
const InfoHash&,
|
||||
want_t)> onFindNode {};
|
||||
std::function<RequestAnswer(Sp<Node>, const InfoHash&, want_t)> onFindNode {};
|
||||
/**
|
||||
* @brief on "get values" request callback.
|
||||
* Called on "get values" request.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param vhash (type: InfoHash) hash of the value of interest.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
* @param h (type: InfoHash) hash of the value of interest.
|
||||
* @param want (type: want_t) states if nodes sent in the response are ipv4
|
||||
* or ipv6.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>,
|
||||
const InfoHash&,
|
||||
want_t,
|
||||
const Query&)> onGetValues {};
|
||||
std::function<RequestAnswer(Sp<Node>, const InfoHash&, want_t, const Query&)> onGetValues {};
|
||||
/**
|
||||
* @brief on listen request callback.
|
||||
* Called on listen request.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param vhash (type: InfoHash) hash of the value of interest.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
* @param h (type: InfoHash) hash of the value of interest.
|
||||
* @param token (type: Blob) security token.
|
||||
* @param rid (type: uint16_t) request id.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>,
|
||||
std::function<RequestAnswer(Sp<Node>,
|
||||
const InfoHash&,
|
||||
const Blob&,
|
||||
uint16_t,
|
||||
uint32_t,
|
||||
const Query&)> onListen {};
|
||||
/**
|
||||
* @brief on announce request callback.
|
||||
* Called on announce request.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param vhash (type: InfoHash) hash of the value of interest.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
* @param h (type: InfoHash) hash of the value of interest.
|
||||
* @param token (type: Blob) security token.
|
||||
* @param values (type: std::vector<std::shared_ptr<Value>>) values to store.
|
||||
* @param values (type: std::vector<Sp<Value>>) values to store.
|
||||
* @param created (type: time_point) time when the value was created.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>,
|
||||
std::function<RequestAnswer(Sp<Node>,
|
||||
const InfoHash&,
|
||||
const Blob&,
|
||||
const std::vector<std::shared_ptr<Value>>&,
|
||||
const std::vector<Sp<Value>>&,
|
||||
const time_point&)> onAnnounce {};
|
||||
/**
|
||||
* @brief on refresh request callback.
|
||||
* Called on refresh request.
|
||||
*
|
||||
* @param node (type: std::shared_ptr<Node>) the requesting node.
|
||||
* @param vhash (type: InfoHash) hash of the value of interest.
|
||||
* @param node (type: Sp<Node>) the requesting node.
|
||||
* @param h (type: InfoHash) hash of the value of interest.
|
||||
* @param token (type: Blob) security token.
|
||||
* @param vid (type: Value::id) the value id.
|
||||
*/
|
||||
std::function<RequestAnswer(std::shared_ptr<Node>,
|
||||
std::function<RequestAnswer(Sp<Node>,
|
||||
const InfoHash&,
|
||||
const Blob&,
|
||||
const Value::Id&)> onRefresh {};
|
||||
|
||||
public:
|
||||
using SocketCb = std::function<void(const Sp<Node>&, RequestAnswer&&)>;
|
||||
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
|
||||
using RequestExpiredCb = std::function<void(const Request&, bool)>;
|
||||
|
||||
@@ -293,67 +229,186 @@ public:
|
||||
/**
|
||||
* Sends values (with closest nodes) to a listenner.
|
||||
*
|
||||
* @param sa The address of the listenner.
|
||||
* @param sslen The length of the sockaddr structure.
|
||||
* @param rid The request id of the initial listen request.
|
||||
* @param hash The hash key of the value.
|
||||
* @param want Wether to send ipv4 and/or ipv6 nodes.
|
||||
* @param ntoken Listen security token.
|
||||
* @param nodes The ipv4 closest nodes.
|
||||
* @param nodes6 The ipv6 closest nodes.
|
||||
* @param values The values to send.
|
||||
* @param sa The address of the listenner.
|
||||
* @param sslen The length of the sockaddr structure.
|
||||
* @param socket_id The tid to use to write to the request socket.
|
||||
* @param hash The hash key of the value.
|
||||
* @param want Wether to send ipv4 and/or ipv6 nodes.
|
||||
* @param ntoken Listen security token.
|
||||
* @param nodes The ipv4 closest nodes.
|
||||
* @param nodes6 The ipv6 closest nodes.
|
||||
* @param values The values to send.
|
||||
*/
|
||||
void tellListener(std::shared_ptr<Node> n, uint16_t rid, const InfoHash& hash, want_t want, const Blob& ntoken,
|
||||
std::vector<std::shared_ptr<Node>>&& nodes, std::vector<std::shared_ptr<Node>>&& nodes6,
|
||||
std::vector<std::shared_ptr<Value>>&& values, const Query& q);
|
||||
void tellListener(Sp<Node> n, uint32_t socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
|
||||
std::vector<Sp<Node>>&& nodes, std::vector<Sp<Node>>&& nodes6,
|
||||
std::vector<Sp<Value>>&& values, const Query& q);
|
||||
|
||||
bool isRunning(sa_family_t af) const;
|
||||
inline want_t want () const { return dht_socket >= 0 && dht_socket6 >= 0 ? (WANT4 | WANT6) : -1; }
|
||||
|
||||
/**
|
||||
* Cancel a request. Setting req->cancelled = true is not enough in the case
|
||||
* a request is "persistent".
|
||||
*/
|
||||
void cancelRequest(Sp<Request>& req);
|
||||
|
||||
void connectivityChanged(sa_family_t);
|
||||
|
||||
/**************
|
||||
* Requests *
|
||||
**************/
|
||||
std::shared_ptr<Request>
|
||||
sendPing(std::shared_ptr<Node> n, RequestCb on_done, RequestExpiredCb on_expired);
|
||||
std::shared_ptr<Request>
|
||||
sendPing(const sockaddr* sa, socklen_t salen, RequestCb on_done, RequestExpiredCb on_expired) {
|
||||
return sendPing(std::make_shared<Node>(zeroes, sa, salen), on_done, on_expired);
|
||||
|
||||
/**
|
||||
* Send a "ping" request to a given node.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request>
|
||||
sendPing(Sp<Node> n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "ping" request to a given node.
|
||||
*
|
||||
* @param sa The node's ip sockaddr info.
|
||||
* @param salen The associated sockaddr struct length.
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request>
|
||||
sendPing(const sockaddr* sa, socklen_t salen, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
return sendPing(std::make_shared<Node>(zeroes, sa, salen),
|
||||
std::forward<RequestCb>(on_done),
|
||||
std::forward<RequestExpiredCb>(on_expired));
|
||||
}
|
||||
std::shared_ptr<Request>
|
||||
sendFindNode(std::shared_ptr<Node> n,
|
||||
const InfoHash& target,
|
||||
want_t want,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired);
|
||||
std::shared_ptr<Request>
|
||||
sendGetValues(std::shared_ptr<Node> n,
|
||||
const InfoHash& info_hash,
|
||||
const Query& query,
|
||||
want_t want,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired);
|
||||
std::shared_ptr<Request>
|
||||
sendListen(std::shared_ptr<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const Query& query,
|
||||
const Blob& token,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired);
|
||||
std::shared_ptr<Request>
|
||||
sendAnnounceValue(std::shared_ptr<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const std::shared_ptr<Value>& v,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired);
|
||||
std::shared_ptr<Request>
|
||||
sendRefreshValue(std::shared_ptr<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const Value::Id& vid,
|
||||
const Blob& token,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired);
|
||||
/**
|
||||
* Send a "find node" request to a given node.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param target The target hash.
|
||||
* @param want Indicating wether IPv4 or IPv6 are wanted in response.
|
||||
* Use NetworkEngine::want()
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendFindNode(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
want_t want,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "get" request to a given node.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param hash The target hash.
|
||||
* @param query The query describing filters.
|
||||
* @param token A security token.
|
||||
* @param want Indicating wether IPv4 or IPv6 are wanted in response.
|
||||
* Use NetworkEngine::want()
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendGetValues(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
const Query& query,
|
||||
want_t want,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "listen" request to a given node.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param hash The storage's hash.
|
||||
* @param query The query describing filters.
|
||||
* @param token A security token.
|
||||
* @param previous The previous request "listen" sent to this node.
|
||||
* @param socket **UNUSED** The socket for further response.
|
||||
*
|
||||
* For backward compatibility purpose, sendListen has to
|
||||
* handle creation of the socket. Therefor, you cannot
|
||||
* use openSocket yourself. TODO: Once we don't support
|
||||
* the old "listen" negociation, sendListen shall not
|
||||
* create the socket itself.
|
||||
*
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
* @param socket_cb Callback to execute each time new updates arrive on
|
||||
* the socket.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendListen(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
const Query& query,
|
||||
const Blob& token,
|
||||
Sp<Request> previous,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired,
|
||||
SocketCb&& socket_cb);
|
||||
/**
|
||||
* Send a "announce" request to a given node.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param hash The target hash.
|
||||
* @param created The time when the value was created (avoiding extended
|
||||
* value lifetime)
|
||||
* @param token A security token.
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendAnnounceValue(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
const Sp<Value>& v,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "refresh" request to a given node. Asks a node to keep the
|
||||
* associated value Value.type.expiration more minutes in its storage.
|
||||
*
|
||||
* @param n The node.
|
||||
* @param hash The target hash.
|
||||
* @param vid The value id.
|
||||
* @param token A security token.
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendRefreshValue(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
const Value::Id& vid,
|
||||
const Blob& token,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Opens a socket on which a node will be able allowed to write for further
|
||||
* additionnal updates following the response to a previous request.
|
||||
*
|
||||
* @param node The node which will be allowed to write on this socket.
|
||||
* @param cb The callback to execute once updates arrive on the socket.
|
||||
*
|
||||
* @return the socket.
|
||||
*/
|
||||
Sp<Socket> openSocket(const Sp<Node>& node, TransPrefix tp, SocketCb&& cb);
|
||||
|
||||
/**
|
||||
* Closes a socket so that no further data will be red on that socket.
|
||||
*
|
||||
* @param socket The socket to close.
|
||||
*/
|
||||
void closeSocket(Sp<Socket> socket);
|
||||
|
||||
/**
|
||||
* Parses a message and calls appropriate callbacks.
|
||||
@@ -366,7 +421,7 @@ public:
|
||||
*/
|
||||
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr& addr);
|
||||
|
||||
std::shared_ptr<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
|
||||
Sp<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
|
||||
auto n = cache.getNode(myid, addr, scheduler.time(), 0);
|
||||
onNewNode(n, 0);
|
||||
return n;
|
||||
@@ -379,9 +434,9 @@ public:
|
||||
return stats;
|
||||
}
|
||||
|
||||
void blacklistNode(const std::shared_ptr<Node>& n);
|
||||
void blacklistNode(const Sp<Node>& n);
|
||||
|
||||
std::vector<std::shared_ptr<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count) {
|
||||
std::vector<Sp<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count) {
|
||||
return cache.getCachedNodes(id, sa_f, count);
|
||||
}
|
||||
|
||||
@@ -394,9 +449,9 @@ private:
|
||||
***************/
|
||||
static constexpr long unsigned MAX_REQUESTS_PER_SEC {1600};
|
||||
/* the length of a node info buffer in ipv4 format */
|
||||
static const constexpr size_t NODE4_INFO_BUF_LEN {26};
|
||||
static const constexpr size_t NODE4_INFO_BUF_LEN {HASH_LEN + sizeof(in_addr) + sizeof(in_port_t)};
|
||||
/* the length of a node info buffer in ipv6 format */
|
||||
static const constexpr size_t NODE6_INFO_BUF_LEN {38};
|
||||
static const constexpr size_t NODE6_INFO_BUF_LEN {HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t)};
|
||||
/* after a UDP reply, the period during which we tell the link layer about it */
|
||||
static constexpr std::chrono::seconds UDP_REPLY_TIME {15};
|
||||
|
||||
@@ -421,13 +476,13 @@ private:
|
||||
static bool isMartian(const SockAddr& addr);
|
||||
bool isNodeBlacklisted(const SockAddr& addr) const;
|
||||
|
||||
void requestStep(std::shared_ptr<Request> req);
|
||||
void requestStep(Sp<Request> req);
|
||||
|
||||
/**
|
||||
* Sends a request to a node. Request::MAX_ATTEMPT_COUNT attempts will
|
||||
* be made before the request expires.
|
||||
*/
|
||||
void sendRequest(std::shared_ptr<Request>& request);
|
||||
void sendRequest(Sp<Request>& request);
|
||||
|
||||
/**
|
||||
* Generates a new request id, skipping the invalid id.
|
||||
@@ -440,20 +495,20 @@ private:
|
||||
}
|
||||
|
||||
struct MessageStats {
|
||||
unsigned ping {0};
|
||||
unsigned find {0};
|
||||
unsigned get {0};
|
||||
unsigned put {0};
|
||||
unsigned listen {0};
|
||||
unsigned ping {0};
|
||||
unsigned find {0};
|
||||
unsigned get {0};
|
||||
unsigned put {0};
|
||||
unsigned listen {0};
|
||||
unsigned refresh {0};
|
||||
};
|
||||
|
||||
|
||||
// basic wrapper for socket sendto function
|
||||
int send(const char *buf, size_t len, int flags, const SockAddr& addr);
|
||||
void send(const char *buf, size_t len, int flags, const SockAddr& addr);
|
||||
|
||||
void sendValueParts(TransId tid, const std::vector<Blob>& svals, const SockAddr& addr);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<std::shared_ptr<Value>>&);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
|
||||
void maintainRxBuffer(const TransId& tid);
|
||||
|
||||
/*************
|
||||
@@ -466,16 +521,16 @@ private:
|
||||
TransId tid,
|
||||
const Blob& nodes,
|
||||
const Blob& nodes6,
|
||||
const std::vector<std::shared_ptr<Value>>& st,
|
||||
const std::vector<Sp<Value>>& st,
|
||||
const Query& query,
|
||||
const Blob& token);
|
||||
Blob bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes);
|
||||
Blob bufferNodes(sa_family_t af, const InfoHash& id, std::vector<Sp<Node>>& nodes);
|
||||
|
||||
std::pair<Blob, Blob> bufferNodes(sa_family_t af,
|
||||
const InfoHash& id,
|
||||
want_t want,
|
||||
std::vector<std::shared_ptr<Node>>& nodes,
|
||||
std::vector<std::shared_ptr<Node>>& nodes6);
|
||||
std::vector<Sp<Node>>& nodes,
|
||||
std::vector<Sp<Node>>& nodes6);
|
||||
/* answer to a listen request */
|
||||
void sendListenConfirmation(const SockAddr& addr, TransId tid);
|
||||
/* answer to put request */
|
||||
@@ -487,7 +542,7 @@ private:
|
||||
const std::string& message,
|
||||
bool include_id=false);
|
||||
|
||||
void deserializeNodes(ParsedMessage& msg);
|
||||
void deserializeNodes(ParsedMessage& msg, const SockAddr& from);
|
||||
|
||||
/* DHT info */
|
||||
const InfoHash& myid;
|
||||
@@ -528,18 +583,21 @@ private:
|
||||
};
|
||||
// global limiting should be triggered by at least 8 different IPs
|
||||
using IpLimiter = RateLimiter<MAX_REQUESTS_PER_SEC/8>;
|
||||
using IpLimiterMap = std::map<SockAddr, IpLimiter, cmpSockAddr>;
|
||||
using IpLimiterMap = std::map<SockAddr, IpLimiter, SockAddr::ipCmp>;
|
||||
IpLimiterMap address_rate_limiter {};
|
||||
RateLimiter<MAX_REQUESTS_PER_SEC> rate_limiter {};
|
||||
|
||||
// requests handling
|
||||
uint16_t transaction_id {1};
|
||||
std::map<uint16_t, std::shared_ptr<Request>> requests {};
|
||||
std::map<TransId, Sp<Request>> requests {};
|
||||
std::map<TransId, PartialMessage> partial_messages;
|
||||
std::map<TransId, Sp<Socket>> opened_sockets {};
|
||||
|
||||
MessageStats in_stats {}, out_stats {};
|
||||
std::set<SockAddr> blacklist {};
|
||||
|
||||
Scheduler& scheduler;
|
||||
};
|
||||
|
||||
}
|
||||
} /* namespace net */
|
||||
} /* namespace dht */
|
||||
+10
-9
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -28,7 +27,9 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
namespace net {
|
||||
struct Request;
|
||||
} /* namespace net */
|
||||
|
||||
struct Node {
|
||||
InfoHash id;
|
||||
@@ -72,8 +73,8 @@ struct Node {
|
||||
|
||||
void update(const SockAddr&);
|
||||
|
||||
void requested(std::shared_ptr<Request>& req);
|
||||
void received(time_point now, std::shared_ptr<Request> req);
|
||||
void requested(std::shared_ptr<net::Request>& req);
|
||||
void received(time_point now, std::shared_ptr<net::Request> req);
|
||||
|
||||
void setExpired();
|
||||
|
||||
@@ -84,7 +85,7 @@ struct Node {
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& s, const Node& h);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Node& h);
|
||||
|
||||
static constexpr const std::chrono::minutes NODE_GOOD_TIME {120};
|
||||
|
||||
@@ -98,12 +99,12 @@ private:
|
||||
/* Number of times we accept authentication errors from this node. */
|
||||
static const constexpr unsigned MAX_AUTH_ERRORS {3};
|
||||
|
||||
std::list<std::weak_ptr<Request>> requests_ {};
|
||||
std::list<std::weak_ptr<net::Request>> requests_ {};
|
||||
unsigned auth_errors {0};
|
||||
bool expired_ {false};
|
||||
|
||||
void clearPendingQueue() {
|
||||
requests_.remove_if([](std::weak_ptr<Request>& w) {
|
||||
requests_.remove_if([](std::weak_ptr<net::Request>& w) {
|
||||
return w.expired();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 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
|
||||
@@ -13,8 +13,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
+44
-18
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,15 +14,40 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net.h"
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
class NetworkEngine;
|
||||
struct ParsedMessage;
|
||||
|
||||
/*!
|
||||
* @class Socket
|
||||
* @brief Open route to a node for continous incoming packets.
|
||||
* @details
|
||||
* A socket lets a remote node send us continuous packets treated using a
|
||||
* given callback. This is intended to provide an easy management of
|
||||
* specific updates nodes can send. For e.g, this is used in the case of the
|
||||
* "listen" operation for treating updates a node has for a given storage.
|
||||
*/
|
||||
struct Socket {
|
||||
Socket() {}
|
||||
Socket(std::shared_ptr<Node> node,
|
||||
TransId id,
|
||||
std::function<void(const std::shared_ptr<Node>&, ParsedMessage&&)> on_receive) :
|
||||
node(node), id(id), on_receive(on_receive) {}
|
||||
|
||||
std::shared_ptr<Node> node;
|
||||
TransId id;
|
||||
std::function<void(const std::shared_ptr<Node>&, ParsedMessage&&)> on_receive {};
|
||||
};
|
||||
|
||||
/*!
|
||||
* @class Request
|
||||
* @brief An atomic request destined to a node.
|
||||
@@ -32,7 +57,8 @@ struct ParsedMessage;
|
||||
* request is done.
|
||||
*/
|
||||
struct Request {
|
||||
friend class dht::NetworkEngine;
|
||||
friend class dht::net::NetworkEngine;
|
||||
|
||||
std::shared_ptr<Node> node {}; /* the node to whom the request is destined. */
|
||||
time_point reply_time {time_point::min()}; /* time when we received the response to the request. */
|
||||
|
||||
@@ -51,14 +77,14 @@ struct Request {
|
||||
bool over() const { return not pending(); }
|
||||
State getState() const { return state_; }
|
||||
|
||||
Request() {}
|
||||
Request(uint16_t tid,
|
||||
Request(State state = State::PENDING) : state_(state) {}
|
||||
Request(TransId tid,
|
||||
std::shared_ptr<Node> node,
|
||||
Blob&& msg,
|
||||
std::function<void(const Request& req_status, ParsedMessage&&)> on_done,
|
||||
std::function<void(const Request& req_status, bool)> on_expired,
|
||||
bool persistent = false) :
|
||||
node(node), on_done(on_done), on_expired(on_expired), tid(tid), msg(std::move(msg)), persistent(persistent) { }
|
||||
std::function<void(const Request&, ParsedMessage&&)> on_done,
|
||||
std::function<void(const Request&, bool)> on_expired,
|
||||
std::shared_ptr<Socket> socket = {}) :
|
||||
node(node), on_done(on_done), on_expired(on_expired), tid(tid), msg(std::move(msg)), socket(socket) { }
|
||||
|
||||
void setExpired() {
|
||||
if (pending()) {
|
||||
@@ -68,11 +94,10 @@ struct Request {
|
||||
}
|
||||
}
|
||||
void setDone(ParsedMessage&& msg) {
|
||||
if (pending() or persistent) {
|
||||
if (pending()) {
|
||||
state_ = Request::State::COMPLETED;
|
||||
on_done(*this, std::forward<ParsedMessage>(msg));
|
||||
if (not persistent)
|
||||
clear();
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,12 +127,13 @@ private:
|
||||
time_point start {time_point::min()}; /* time when the request is created. */
|
||||
time_point last_try {time_point::min()}; /* time of the last attempt to process the request. */
|
||||
|
||||
std::function<void(const Request& req_status, ParsedMessage&&)> on_done {};
|
||||
std::function<void(const Request& req_status, bool)> on_expired {};
|
||||
std::function<void(const Request&, ParsedMessage&&)> on_done {};
|
||||
std::function<void(const Request&, bool)> on_expired {};
|
||||
|
||||
const uint16_t tid {0}; /* the request id. */
|
||||
Blob msg {}; /* the serialized message. */
|
||||
const bool persistent {false}; /* the request is not erased upon completion. */
|
||||
const TransId tid; /* the request id. */
|
||||
Blob msg {}; /* the serialized message. */
|
||||
std::shared_ptr<Socket> socket; /* the socket used for further reponses. */
|
||||
};
|
||||
|
||||
} /* namespace net */
|
||||
}
|
||||
+14
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,13 +13,14 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
@@ -107,4 +108,14 @@ using random_device = std::random_device;
|
||||
using random_device = std::random_device;
|
||||
#endif
|
||||
|
||||
template<class T = std::mt19937, std::size_t N = T::state_size>
|
||||
auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
|
||||
typename T::result_type random_data[N];
|
||||
random_device source;
|
||||
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
|
||||
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
|
||||
T seededEngine (seeds);
|
||||
return seededEngine;
|
||||
}
|
||||
|
||||
}} // dht::crypto
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -13,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -31,12 +31,12 @@ struct Bucket {
|
||||
: af(af), first(f), time(t), cached() {}
|
||||
sa_family_t af {0};
|
||||
InfoHash first {};
|
||||
time_point time {time_point::min()}; /* time of last reply in this bucket */
|
||||
std::list<std::shared_ptr<Node>> nodes {};
|
||||
std::shared_ptr<Node> cached; /* the address of a likely candidate */
|
||||
time_point time {time_point::min()}; /* time of last reply in this bucket */
|
||||
std::list<Sp<Node>> nodes {};
|
||||
Sp<Node> cached; /* the address of a likely candidate */
|
||||
|
||||
/** Return a random node in a bucket. */
|
||||
std::shared_ptr<Node> randomNode();
|
||||
Sp<Node> randomNode();
|
||||
};
|
||||
|
||||
class RoutingTable : public std::list<Bucket> {
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
InfoHash middle(const RoutingTable::const_iterator&) const;
|
||||
|
||||
std::vector<std::shared_ptr<Node>> findClosestNodes(const InfoHash id, time_point now, size_t count = TARGET_NODES) const;
|
||||
std::vector<Sp<Node>> findClosestNodes(const InfoHash id, time_point now, size_t count = TARGET_NODES) const;
|
||||
|
||||
RoutingTable::iterator findBucket(const InfoHash& id);
|
||||
RoutingTable::const_iterator findBucket(const InfoHash& id) const;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -52,7 +51,7 @@ public:
|
||||
*
|
||||
* @return pointer to the newly scheduled job.
|
||||
*/
|
||||
std::shared_ptr<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
|
||||
Sp<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
|
||||
auto job = std::make_shared<Job>(std::move(job_func));
|
||||
if (t != time_point::max())
|
||||
timers.emplace(std::move(t), job);
|
||||
@@ -67,7 +66,7 @@ public:
|
||||
*
|
||||
* @return pointer to the newly scheduled job.
|
||||
*/
|
||||
void edit(std::shared_ptr<Scheduler::Job>& job, time_point t) {
|
||||
void edit(Sp<Scheduler::Job>& job, time_point t) {
|
||||
if (not job) {
|
||||
DHT_LOG.ERR("editing an empty job");
|
||||
return;
|
||||
@@ -118,7 +117,7 @@ public:
|
||||
|
||||
private:
|
||||
time_point now {clock::now()};
|
||||
std::multimap<time_point, std::shared_ptr<Job>> timers {}; /* the jobs ordered by time */
|
||||
std::multimap<time_point, Sp<Job>> timers {}; /* the jobs ordered by time */
|
||||
const Logger& DHT_LOG;
|
||||
};
|
||||
|
||||
|
||||
+22
-30
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -13,19 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify this program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, Savoir-faire Linux Inc.
|
||||
* grants you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -40,7 +29,7 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
class SecureDht : public Dht {
|
||||
class OPENDHT_PUBLIC SecureDht : public Dht {
|
||||
public:
|
||||
|
||||
typedef std::function<void(bool)> SignatureCheckCallback;
|
||||
@@ -62,6 +51,9 @@ public:
|
||||
InfoHash getId() const {
|
||||
return key_ ? key_->getPublicKey().getId() : InfoHash();
|
||||
}
|
||||
PkId getLongId() const {
|
||||
return key_ ? key_->getPublicKey().getLongId() : PkId();
|
||||
}
|
||||
|
||||
ValueType secureType(ValueType&& type);
|
||||
|
||||
@@ -101,7 +93,7 @@ public:
|
||||
/**
|
||||
* Will take ownership of the value, sign it using our private key and put it in the DHT.
|
||||
*/
|
||||
void putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
|
||||
void putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, bool permanent = false);
|
||||
void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback, bool permanent = false) {
|
||||
putSigned(hash, std::make_shared<Value>(std::move(v)), callback, permanent);
|
||||
}
|
||||
@@ -111,7 +103,7 @@ public:
|
||||
* and put it in the DHT.
|
||||
* The operation will be immediate if the recipient' public key is known (otherwise it will be retrived first).
|
||||
*/
|
||||
void putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
|
||||
void putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
|
||||
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
|
||||
}
|
||||
@@ -125,14 +117,14 @@ public:
|
||||
|
||||
Value decrypt(const Value& v);
|
||||
|
||||
void findCertificate(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::Certificate>)> cb);
|
||||
void findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<const crypto::PublicKey>)> cb);
|
||||
void findCertificate(const InfoHash& node, std::function<void(const Sp<crypto::Certificate>)> cb);
|
||||
void findPublicKey(const InfoHash& node, std::function<void(const Sp<const crypto::PublicKey>)> cb);
|
||||
|
||||
const std::shared_ptr<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
void registerCertificate(std::shared_ptr<crypto::Certificate>& cert);
|
||||
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
void registerCertificate(Sp<crypto::Certificate>& cert);
|
||||
|
||||
const std::shared_ptr<crypto::Certificate> getCertificate(const InfoHash& node) const;
|
||||
const std::shared_ptr<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
|
||||
const Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
|
||||
const Sp<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
|
||||
|
||||
/**
|
||||
* Allows to set a custom callback called by the library to find a locally-stored certificate.
|
||||
@@ -150,23 +142,23 @@ private:
|
||||
|
||||
GetCallback getCallbackFilter(GetCallback, Value::Filter&&);
|
||||
|
||||
std::shared_ptr<crypto::PrivateKey> key_ {};
|
||||
std::shared_ptr<crypto::Certificate> certificate_ {};
|
||||
Sp<crypto::PrivateKey> key_ {};
|
||||
Sp<crypto::Certificate> certificate_ {};
|
||||
|
||||
// method to query the local certificate store
|
||||
CertificateStoreQuery localQueryMethod_ {};
|
||||
|
||||
// our certificate cache
|
||||
std::map<InfoHash, std::shared_ptr<crypto::Certificate>> nodesCertificates_ {};
|
||||
std::map<InfoHash, std::shared_ptr<const crypto::PublicKey>> nodesPubKeys_ {};
|
||||
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
|
||||
std::map<InfoHash, Sp<const crypto::PublicKey>> nodesPubKeys_ {};
|
||||
|
||||
std::uniform_int_distribution<Value::Id> rand_id {};
|
||||
};
|
||||
|
||||
const ValueType CERTIFICATE_TYPE = {
|
||||
8, "Certificate", std::chrono::hours(24 * 7),
|
||||
// A certificate can only be stored at it's public key ID.
|
||||
[](InfoHash id, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t) {
|
||||
// A certificate can only be stored at its public key ID.
|
||||
[](InfoHash id, Sp<Value>& v, InfoHash, const sockaddr*, socklen_t) {
|
||||
try {
|
||||
crypto::Certificate crt(v->data);
|
||||
// TODO check certificate signature
|
||||
@@ -174,7 +166,7 @@ const ValueType CERTIFICATE_TYPE = {
|
||||
} catch (const std::exception& e) {}
|
||||
return false;
|
||||
},
|
||||
[](InfoHash, const std::shared_ptr<Value>& o, std::shared_ptr<Value>& n, InfoHash, const sockaddr*, socklen_t) {
|
||||
[](InfoHash, const Sp<Value>& o, Sp<Value>& n, InfoHash, const sockaddr*, socklen_t) {
|
||||
try {
|
||||
return crypto::Certificate(o->data).getPublicKey().getId() == crypto::Certificate(n->data).getPublicKey().getId();
|
||||
} catch (const std::exception& e) {}
|
||||
|
||||
@@ -13,13 +13,19 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __ANDROID__
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
#else
|
||||
#include <iso646.h>
|
||||
#include <ws2def.h>
|
||||
@@ -30,10 +36,10 @@ typedef uint16_t in_port_t;
|
||||
|
||||
namespace dht {
|
||||
|
||||
std::string print_addr(const sockaddr* sa, socklen_t slen);
|
||||
std::string print_addr(const sockaddr_storage& ss, socklen_t sslen);
|
||||
OPENDHT_PUBLIC std::string print_addr(const sockaddr* sa, socklen_t slen);
|
||||
OPENDHT_PUBLIC std::string print_addr(const sockaddr_storage& ss, socklen_t sslen);
|
||||
|
||||
struct SockAddr : public std::pair<sockaddr_storage, socklen_t> {
|
||||
struct OPENDHT_PUBLIC SockAddr : public std::pair<sockaddr_storage, socklen_t> {
|
||||
public:
|
||||
SockAddr() : pair<sockaddr_storage, socklen_t>::pair({},0) {}
|
||||
SockAddr(const SockAddr& o) : pair<sockaddr_storage, socklen_t>::pair({},o.second) {
|
||||
@@ -66,10 +72,97 @@ public:
|
||||
return print_addr(first, second);
|
||||
}
|
||||
sa_family_t getFamily() const { return second > sizeof(sa_family_t) ? first.ss_family : AF_UNSPEC; }
|
||||
void setFamily(sa_family_t af) {
|
||||
first.ss_family = af;
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
second = sizeof(sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
second = sizeof(sockaddr_in6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in_port_t getPort() const {
|
||||
switch(getFamily()) {
|
||||
case AF_INET:
|
||||
return ntohs(getIPv4().sin_port);
|
||||
case AF_INET6:
|
||||
return ntohs(getIPv6().sin6_port);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void setPort(in_port_t p) {
|
||||
switch(getFamily()) {
|
||||
case AF_INET:
|
||||
getIPv4().sin_port = htons(p);
|
||||
break;
|
||||
case AF_INET6:
|
||||
getIPv6().sin6_port = htons(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const sockaddr_in& getIPv4() const {
|
||||
return *reinterpret_cast<const sockaddr_in*>(&first);
|
||||
}
|
||||
const sockaddr_in6& getIPv6() const {
|
||||
return *reinterpret_cast<const sockaddr_in6*>(&first);
|
||||
}
|
||||
sockaddr_in& getIPv4() {
|
||||
return *reinterpret_cast<sockaddr_in*>(&first);
|
||||
}
|
||||
sockaddr_in6& getIPv6() {
|
||||
return *reinterpret_cast<sockaddr_in6*>(&first);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if address is a loopback IP address.
|
||||
*/
|
||||
bool isLoopback() const;
|
||||
|
||||
/**
|
||||
* Return true if address is not a public IP address.
|
||||
*/
|
||||
bool isPrivate() const;
|
||||
|
||||
bool isUnspecified() const;
|
||||
|
||||
/**
|
||||
* A comparator to classify IP addresses, only considering the
|
||||
* first 64 bits in IPv6.
|
||||
*/
|
||||
struct ipCmp {
|
||||
bool operator()(const SockAddr& a, const SockAddr& b) const {
|
||||
if (a.second != b.second)
|
||||
return a.second < b.second;
|
||||
socklen_t start, len;
|
||||
switch(a.getFamily()) {
|
||||
case AF_INET:
|
||||
start = offsetof(sockaddr_in, sin_addr);
|
||||
len = sizeof(in_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
start = offsetof(sockaddr_in6, sin6_addr);
|
||||
// don't consider more than 64 bits (IPv6)
|
||||
len = 8;
|
||||
break;
|
||||
default:
|
||||
start = 0;
|
||||
len = a.second;
|
||||
break;
|
||||
}
|
||||
|
||||
return std::memcmp((uint8_t*)&a.first+start, (uint8_t*)&b.first+start, len) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
bool operator==(const SockAddr& a, const SockAddr& b);
|
||||
OPENDHT_PUBLIC bool operator==(const SockAddr& a, const SockAddr& b);
|
||||
|
||||
std::string printAddr(const SockAddr& addr);
|
||||
OPENDHT_PUBLIC std::string printAddr(const SockAddr& addr);
|
||||
|
||||
}
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,13 +13,12 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define WANT4 1
|
||||
#define WANT6 2
|
||||
#include "def.h"
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
@@ -30,11 +29,18 @@
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#define WANT4 1
|
||||
#define WANT6 2
|
||||
|
||||
namespace dht {
|
||||
|
||||
using NetId = uint32_t;
|
||||
using want_t = int_fast8_t;
|
||||
|
||||
// shortcut for std::shared_ptr
|
||||
template<class T>
|
||||
using Sp = std::shared_ptr<T>;
|
||||
|
||||
template <typename Key, typename Item, typename Condition>
|
||||
void erase_if(std::map<Key, Item>& map, const Condition& condition)
|
||||
{
|
||||
@@ -45,13 +51,12 @@ void erase_if(std::map<Key, Item>& map, const Condition& condition)
|
||||
}
|
||||
}
|
||||
|
||||
class DhtException : public std::runtime_error {
|
||||
class OPENDHT_PUBLIC DhtException : public std::runtime_error {
|
||||
public:
|
||||
DhtException(const std::string &str = "") :
|
||||
std::runtime_error("DhtException occurred: " + str) {}
|
||||
};
|
||||
|
||||
|
||||
// Time related definitions and utility functions
|
||||
|
||||
using clock = std::chrono::steady_clock;
|
||||
@@ -70,9 +75,6 @@ print_dt(DT d) {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
|
||||
}
|
||||
|
||||
static /*constexpr*/ const time_point TIME_INVALID = {time_point::min()};
|
||||
static /*constexpr*/ const time_point TIME_MAX {time_point::max()};
|
||||
|
||||
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>;
|
||||
@@ -96,7 +98,7 @@ using Blob = std::vector<uint8_t>;
|
||||
/**
|
||||
* Provides backward compatibility with msgpack 1.0
|
||||
*/
|
||||
Blob unpackBlob(msgpack::object& o);
|
||||
OPENDHT_PUBLIC Blob unpackBlob(msgpack::object& o);
|
||||
|
||||
template <typename Type>
|
||||
Blob
|
||||
|
||||
+19
-47
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -72,7 +71,7 @@ using EditPolicy = std::function<bool(InfoHash key, const std::shared_ptr<Value>
|
||||
|
||||
static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
|
||||
|
||||
struct ValueType {
|
||||
struct OPENDHT_PUBLIC ValueType {
|
||||
typedef uint16_t Id;
|
||||
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t);
|
||||
@@ -114,7 +113,7 @@ struct ValueType {
|
||||
* Values are stored at a given InfoHash in the Dht, but also have a
|
||||
* unique ID to distinguish between values stored at the same location.
|
||||
*/
|
||||
struct Value
|
||||
struct OPENDHT_PUBLIC Value
|
||||
{
|
||||
enum class Field : int {
|
||||
None = 0,
|
||||
@@ -409,7 +408,7 @@ struct Value
|
||||
}
|
||||
|
||||
/** print value for debugging */
|
||||
friend std::ostream& operator<< (std::ostream& s, const Value& v);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Value& v);
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
@@ -553,7 +552,7 @@ using ValuesExport = std::pair<InfoHash, Blob>;
|
||||
* This structure holds the value for a specified field. It's type can either be
|
||||
* uint64_t, InfoHash or Blob.
|
||||
*/
|
||||
struct FieldValue
|
||||
struct OPENDHT_PUBLIC FieldValue
|
||||
{
|
||||
FieldValue() {}
|
||||
FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
|
||||
@@ -630,30 +629,6 @@ private:
|
||||
Blob blobValue {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct FieldSelectorDescription
|
||||
* @brief Describes a selection.
|
||||
* @details
|
||||
* This is meant to narrow data to a set of specified fields. This structure is
|
||||
* used to construct a Select structure.
|
||||
*/
|
||||
struct FieldSelectorDescription
|
||||
{
|
||||
FieldSelectorDescription() {}
|
||||
FieldSelectorDescription(Value::Field f) : field(f) {}
|
||||
|
||||
Value::Field getField() const { return field; }
|
||||
|
||||
bool operator==(const FieldSelectorDescription& fd) const { return field == fd.field; }
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const { p.pack(static_cast<uint8_t>(field)); }
|
||||
void msgpack_unpack(msgpack::object msg) { field = static_cast<Value::Field>(msg.as<int>()); }
|
||||
private:
|
||||
Value::Field field {Value::Field::None};
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Select
|
||||
* @brief Serializable Value field selection.
|
||||
@@ -661,7 +636,7 @@ private:
|
||||
* This is a container for a list of FieldSelectorDescription instances. It
|
||||
* describes a complete SELECT query for dht::Value.
|
||||
*/
|
||||
struct Select
|
||||
struct OPENDHT_PUBLIC Select
|
||||
{
|
||||
Select() { }
|
||||
Select(const std::string& q_str);
|
||||
@@ -686,23 +661,18 @@ struct Select
|
||||
* @return the set of fields.
|
||||
*/
|
||||
std::set<Value::Field> getSelection() const {
|
||||
std::set<Value::Field> fields {};
|
||||
for (const auto& f : fieldSelection_) {
|
||||
fields.insert(f.getField());
|
||||
}
|
||||
return fields;
|
||||
return {fieldSelection_.begin(), fieldSelection_.end()};
|
||||
}
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& pk) const { pk.pack(fieldSelection_); }
|
||||
void msgpack_unpack(const msgpack::object& o) {
|
||||
fieldSelection_.clear();
|
||||
fieldSelection_ = o.as<decltype(fieldSelection_)>();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
|
||||
private:
|
||||
std::vector<FieldSelectorDescription> fieldSelection_ {};
|
||||
std::vector<Value::Field> fieldSelection_ {};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -712,7 +682,7 @@ private:
|
||||
* This is container for a list of FieldValue instances. It describes a
|
||||
* complete WHERE query for dht::Value.
|
||||
*/
|
||||
struct Where
|
||||
struct OPENDHT_PUBLIC Where
|
||||
{
|
||||
Where() { }
|
||||
Where(const std::string& q_str);
|
||||
@@ -802,7 +772,7 @@ struct Where
|
||||
filters_ = o.as<decltype(filters_)>();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const dht::Where& q);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Where& q);
|
||||
|
||||
private:
|
||||
std::vector<FieldValue> filters_;
|
||||
@@ -816,7 +786,7 @@ private:
|
||||
* itselves to include in the peer response to a GET operation. See
|
||||
* FieldValue.
|
||||
*/
|
||||
struct Query
|
||||
struct OPENDHT_PUBLIC Query
|
||||
{
|
||||
static const std::string QUERY_PARSE_ERROR;
|
||||
|
||||
@@ -864,7 +834,7 @@ struct Query
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
|
||||
return s << "Query[" << q.select << " " << q.where << "]";
|
||||
}
|
||||
|
||||
@@ -880,7 +850,7 @@ struct Query
|
||||
* This structures is meant to manipulate a subset of fields normally contained
|
||||
* in Value.
|
||||
*/
|
||||
struct FieldValueIndex {
|
||||
struct OPENDHT_PUBLIC FieldValueIndex {
|
||||
FieldValueIndex() {}
|
||||
FieldValueIndex(const Value& v, Select s = {});
|
||||
/**
|
||||
@@ -891,7 +861,7 @@ struct FieldValueIndex {
|
||||
*/
|
||||
bool containedIn(const FieldValueIndex& other) const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const FieldValueIndex& fvi);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& os, const FieldValueIndex& fvi);
|
||||
|
||||
void msgpack_unpack_fields(const std::set<Value::Field>& fields,
|
||||
const msgpack::object& o,
|
||||
@@ -953,3 +923,5 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MSGPACK_ADD_ENUM(dht::Value::Field)
|
||||
+153
-10
@@ -25,7 +25,7 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OpenDHT Python Wrapper. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from libcpp.map cimport map as map
|
||||
from libcpp cimport bool
|
||||
@@ -125,6 +125,23 @@ cdef class InfoHash(_WithID):
|
||||
h._infohash = cpp.InfoHash.getRandom()
|
||||
return h
|
||||
|
||||
cdef class SockAddr(object):
|
||||
cdef cpp.SockAddr _addr
|
||||
def toString(SockAddr self):
|
||||
return self._addr.toString()
|
||||
def getPort(SockAddr self):
|
||||
return self._addr.getPort()
|
||||
def getFamily(SockAddr self):
|
||||
return self._addr.getFamily()
|
||||
def setPort(SockAddr self, cpp.in_port_t port):
|
||||
return self._addr.setPort(port)
|
||||
def setFamily(SockAddr self, cpp.sa_family_t af):
|
||||
return self._addr.setFamily(af)
|
||||
def __str__(self):
|
||||
return self.toString().decode()
|
||||
def __repr__(self):
|
||||
return "<%s '%s'>" % (self.__class__.__name__, str(self))
|
||||
|
||||
cdef class Node(_WithID):
|
||||
cdef shared_ptr[cpp.Node] _node
|
||||
def getId(self):
|
||||
@@ -224,19 +241,100 @@ cdef class NodeSet(object):
|
||||
def __iter__(self):
|
||||
return NodeSetIter(self)
|
||||
|
||||
cdef class PrivateKey(_WithID):
|
||||
cdef shared_ptr[cpp.PrivateKey] _key
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.get().getPublicKey().getId()
|
||||
return h
|
||||
def getPublicKey(self):
|
||||
pk = PublicKey()
|
||||
pk._key = self._key.get().getPublicKey()
|
||||
return pk
|
||||
def decrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
|
||||
cdef cpp.Blob decrypted = self._key.get().decrypt(indat)
|
||||
cdef char* decrypted_c_str = <char *>decrypted.data()
|
||||
cdef Py_ssize_t length = decrypted.size()
|
||||
return decrypted_c_str[:length]
|
||||
def __str__(self):
|
||||
return self.getId().toString().decode()
|
||||
@staticmethod
|
||||
def generate():
|
||||
k = PrivateKey()
|
||||
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generate())
|
||||
return k
|
||||
@staticmethod
|
||||
def generateEC():
|
||||
k = PrivateKey()
|
||||
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generateEC())
|
||||
return k
|
||||
|
||||
cdef class PublicKey(_WithID):
|
||||
cdef cpp.PublicKey _key
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.getId()
|
||||
return h
|
||||
def encrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
|
||||
cdef cpp.Blob encrypted = self._key.encrypt(indat)
|
||||
cdef char* encrypted_c_str = <char *>encrypted.data()
|
||||
cdef Py_ssize_t length = encrypted.size()
|
||||
return encrypted_c_str[:length]
|
||||
|
||||
cdef class Certificate(_WithID):
|
||||
cdef shared_ptr[cpp.Certificate] _cert
|
||||
def __init__(self, bytes dat = None):
|
||||
if dat:
|
||||
self._cert = cpp.make_shared[cpp.Certificate](<cpp.string>dat)
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._cert.get().getId()
|
||||
if self._cert:
|
||||
h._infohash = self._cert.get().getId()
|
||||
return h
|
||||
def toString(self):
|
||||
return self._cert.get().toString().decode()
|
||||
def getName(self):
|
||||
return self._cert.get().getName()
|
||||
def revoke(self, PrivateKey k, Certificate c):
|
||||
self._cert.get().revoke(deref(k._key.get()), deref(c._cert.get()));
|
||||
def __bytes__(self):
|
||||
return self._cert.get().toString() if self._cert else b''
|
||||
property issuer:
|
||||
def __get__(self):
|
||||
c = Certificate()
|
||||
c._cert = self._cert.get().issuer
|
||||
return c;
|
||||
@staticmethod
|
||||
def generate(PrivateKey k, str name, Identity i = Identity(), bool is_ca = False):
|
||||
c = Certificate()
|
||||
c._cert = cpp.make_shared[cpp.Certificate](cpp.Certificate.generate(deref(k._key.get()), name.encode(), i._id, is_ca))
|
||||
return c
|
||||
|
||||
cdef class VerifyResult(object):
|
||||
cdef cpp.TrustListVerifyResult _result
|
||||
def __bool__(self):
|
||||
return self._result.isValid()
|
||||
def __str(self):
|
||||
return self._result.toString()
|
||||
|
||||
cdef class TrustList(object):
|
||||
cdef cpp.TrustList _trust
|
||||
def add(self, Certificate cert):
|
||||
self._trust.add(deref(cert._cert.get()))
|
||||
def remove(self, Certificate cert):
|
||||
self._trust.remove(deref(cert._cert.get()))
|
||||
def verify(self, Certificate cert):
|
||||
r = VerifyResult()
|
||||
r._result = self._trust.verify(deref(cert._cert.get()))
|
||||
return r
|
||||
|
||||
cdef class ListenToken(object):
|
||||
cdef cpp.InfoHash _h
|
||||
@@ -245,18 +343,31 @@ cdef class ListenToken(object):
|
||||
|
||||
cdef class Identity(object):
|
||||
cdef cpp.Identity _id
|
||||
def generate(self, str name = "pydht", Identity ca = Identity(), unsigned bits = 4096):
|
||||
self._id = cpp.generateIdentity(name.encode(), ca._id, bits)
|
||||
property PublicKey:
|
||||
def __init__(self, PrivateKey k = None, Certificate c = None):
|
||||
if k:
|
||||
self._id.first = k._key
|
||||
if c:
|
||||
self._id.second = c._cert
|
||||
@staticmethod
|
||||
def generate(str name = "pydht", Identity ca = Identity(), unsigned bits = 4096):
|
||||
i = Identity()
|
||||
i._id = cpp.generateIdentity(name.encode(), ca._id, bits)
|
||||
return i
|
||||
property publickey:
|
||||
def __get__(self):
|
||||
k = PublicKey()
|
||||
k._key = self._id.first.get().getPublicKey()
|
||||
return k
|
||||
property Certificate:
|
||||
property certificate:
|
||||
def __get__(self):
|
||||
c = Certificate()
|
||||
c._cert = self._id.second
|
||||
return c
|
||||
property key:
|
||||
def __get__(self):
|
||||
k = PrivateKey()
|
||||
k._key = self._id.first
|
||||
return k
|
||||
|
||||
cdef class DhtConfig(object):
|
||||
cdef cpp.DhtRunnerConfig _config
|
||||
@@ -269,6 +380,10 @@ cdef class DhtConfig(object):
|
||||
self._config.dht_config.node_config.is_bootstrap = bootstrap
|
||||
def setNodeId(self, InfoHash id):
|
||||
self._config.dht_config.node_config.node_id = id._infohash
|
||||
def setNetwork(self, unsigned netid):
|
||||
self._config.dht_config.node_config.network = netid
|
||||
def setMaintainStorage(self, bool maintain_storage):
|
||||
self._config.dht_config.node_config.maintain_storage = maintain_storage
|
||||
|
||||
cdef class DhtRunner(_WithID):
|
||||
cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
|
||||
@@ -276,12 +391,36 @@ cdef class DhtRunner(_WithID):
|
||||
self.thisptr.reset(new cpp.DhtRunner())
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self.thisptr.get().getId()
|
||||
if self.thisptr:
|
||||
h._infohash = self.thisptr.get().getId()
|
||||
return h
|
||||
def getNodeId(self):
|
||||
return self.thisptr.get().getNodeId().toString()
|
||||
def bootstrap(self, str host, str port):
|
||||
self.thisptr.get().bootstrap(host.encode(), port.encode())
|
||||
def ping(self, SockAddr addr, done_cb=None):
|
||||
if done_cb:
|
||||
cb_obj = {'done':done_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
self.thisptr.get().bootstrap(addr._addr, cpp.bindDoneCbSimple(done_callback_simple, <void*>cb_obj))
|
||||
else:
|
||||
lock = threading.Condition()
|
||||
pending = 0
|
||||
ok = False
|
||||
def tmp_done(ok_ret):
|
||||
nonlocal pending, ok, lock
|
||||
with lock:
|
||||
ok = ok_ret
|
||||
pending -= 1
|
||||
lock.notify()
|
||||
with lock:
|
||||
pending += 1
|
||||
self.ping(addr, done_cb=tmp_done)
|
||||
while pending > 0:
|
||||
lock.wait()
|
||||
return ok
|
||||
def bootstrap(self, str host, str port=None):
|
||||
host_bytes = host.encode()
|
||||
port_bytes = port.encode() if port else b'4222'
|
||||
self.thisptr.get().bootstrap(<cpp.const_char*>host_bytes, <cpp.const_char*>port_bytes)
|
||||
def run(self, Identity id=None, is_bootstrap=False, cpp.in_port_t port=0, str ipv4="", str ipv6="", DhtConfig config=DhtConfig()):
|
||||
if id:
|
||||
config.setIdentity(id)
|
||||
@@ -302,9 +441,13 @@ cdef class DhtRunner(_WithID):
|
||||
def disableLogging(self):
|
||||
cpp.disableLogging(self.thisptr.get()[0])
|
||||
def enableFileLogging(self, str path):
|
||||
cpp.enableFileLogging(self.thisptr.get()[0], path)
|
||||
cpp.enableFileLogging(self.thisptr.get()[0], path.encode())
|
||||
def isRunning(self):
|
||||
return self.thisptr.get().isRunning()
|
||||
def getBound(self, cpp.sa_family_t af = 0):
|
||||
s = SockAddr()
|
||||
s._addr = self.thisptr.get().getBound(af)
|
||||
return s
|
||||
def getStorageLog(self):
|
||||
return self.thisptr.get().getStorageLog().decode()
|
||||
def getRoutingTablesLog(self, cpp.sa_family_t af):
|
||||
|
||||
+46
-3
@@ -13,7 +13,7 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# along with this program; If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from libc.stdint cimport *
|
||||
from libcpp cimport bool
|
||||
@@ -21,6 +21,7 @@ from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.utility cimport pair
|
||||
from libcpp.map cimport map
|
||||
from libc.string cimport const_char, const_uchar
|
||||
|
||||
ctypedef uint16_t in_port_t
|
||||
ctypedef unsigned short int sa_family_t;
|
||||
@@ -31,7 +32,9 @@ cdef extern from "<memory>" namespace "std" nogil:
|
||||
shared_ptr(T*) except +
|
||||
T* get()
|
||||
T operator*()
|
||||
bool operator bool() const
|
||||
void reset(T*)
|
||||
shared_ptr[T] make_shared[T](...) except +
|
||||
|
||||
cdef extern from "<functional>" namespace "std" nogil:
|
||||
cdef cppclass hash[T]:
|
||||
@@ -65,6 +68,17 @@ cdef extern from "opendht/infohash.h" namespace "dht":
|
||||
bool operator==(InfoHash)
|
||||
bool operator<(InfoHash)
|
||||
|
||||
cdef extern from "opendht/sockaddr.h" namespace "dht":
|
||||
cdef cppclass SockAddr:
|
||||
SockAddr() except +
|
||||
string toString() const
|
||||
in_port_t getPort() const
|
||||
void setPort(in_port_t p)
|
||||
sa_family_t getFamily() const
|
||||
void setFamily(sa_family_t f)
|
||||
|
||||
ctypedef vector[uint8_t] Blob
|
||||
|
||||
cdef extern from "opendht/crypto.h" namespace "dht::crypto":
|
||||
ctypedef pair[shared_ptr[PrivateKey], shared_ptr[Certificate]] Identity
|
||||
cdef Identity generateIdentity(string name, Identity ca, unsigned bits)
|
||||
@@ -72,14 +86,39 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
|
||||
cdef cppclass PrivateKey:
|
||||
PrivateKey()
|
||||
PublicKey getPublicKey() const
|
||||
Blob decrypt(Blob data) const
|
||||
@staticmethod
|
||||
PrivateKey generate()
|
||||
@staticmethod
|
||||
PrivateKey generateEC()
|
||||
|
||||
cdef cppclass PublicKey:
|
||||
PublicKey()
|
||||
InfoHash getId() const
|
||||
Blob encrypt(Blob data) const
|
||||
|
||||
cdef cppclass Certificate:
|
||||
Certificate()
|
||||
Certificate(string pem)
|
||||
InfoHash getId() const
|
||||
string toString() const
|
||||
string getName() const
|
||||
void revoke(PrivateKey key, Certificate cert)
|
||||
@staticmethod
|
||||
Certificate generate(PrivateKey key, string name, Identity ca, bool is_ca)
|
||||
shared_ptr[Certificate] issuer
|
||||
|
||||
cdef cppclass TrustList:
|
||||
cppclass VerifyResult:
|
||||
bool operator bool() const
|
||||
bool isValid() const
|
||||
string toString() const
|
||||
TrustList()
|
||||
void add(Certificate)
|
||||
void remove(Certificate)
|
||||
VerifyResult verify(Certificate);
|
||||
|
||||
ctypedef TrustList.VerifyResult TrustListVerifyResult
|
||||
|
||||
cdef extern from "opendht/value.h" namespace "dht":
|
||||
cdef cppclass Value:
|
||||
@@ -123,7 +162,9 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
|
||||
|
||||
cppclass Config:
|
||||
InfoHash node_id
|
||||
uint32_t network
|
||||
bool is_bootstrap
|
||||
bool maintain_storage
|
||||
cppclass SecureDhtConfig:
|
||||
Config node_config
|
||||
Identity id
|
||||
@@ -138,12 +179,14 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
|
||||
bool threaded
|
||||
InfoHash getId() const
|
||||
InfoHash getNodeId() const
|
||||
void bootstrap(const char*, const char*)
|
||||
void bootstrap(const_char*, const_char*)
|
||||
void bootstrap(const SockAddr&, DoneCallbackSimple done_cb)
|
||||
void run(in_port_t, Config config)
|
||||
void run(const char*, const char*, const char*, Config config)
|
||||
void run(const_char*, const_char*, const_char*, Config config)
|
||||
void join()
|
||||
void shutdown(ShutdownCallback)
|
||||
bool isRunning()
|
||||
SockAddr getBound(sa_family_t af) const
|
||||
string getStorageLog() const
|
||||
string getRoutingTablesLog(sa_family_t af) const
|
||||
string getSearchesLog(sa_family_t af) const
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2015-2017 Savoir-faire Linux Inc.
|
||||
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
@@ -18,7 +18,7 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OpenDHT Python Wrapper. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from setuptools import setup, Extension
|
||||
@@ -27,7 +27,7 @@ from Cython.Distutils import build_ext
|
||||
|
||||
setup(name="opendht",
|
||||
version="@PACKAGE_VERSION@",
|
||||
description="Python wrapper for opendht",
|
||||
description="Python wrapper for OpenDHT",
|
||||
url='https://github.com/savoirfairelinux/opendht',
|
||||
author="Adrien Béraud, Guillaume Roguez, Simon Désaulniers",
|
||||
license="GPLv3",
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import unittest
|
||||
import opendht as dht
|
||||
|
||||
class OpenDhtTester(unittest.TestCase):
|
||||
|
||||
# test that DhtRunner can be instatiated and deleted without throwing
|
||||
def test_instance(self):
|
||||
for i in range(10):
|
||||
r = dht.DhtRunner()
|
||||
r.run()
|
||||
del r
|
||||
|
||||
# test that bootstraping works (raw address)
|
||||
def test_bootstrap(self):
|
||||
a = dht.DhtRunner()
|
||||
a.run()
|
||||
b = dht.DhtRunner()
|
||||
b.run()
|
||||
self.assertTrue(b.ping(a.getBound()))
|
||||
|
||||
def test_crypto(self):
|
||||
i = dht.Identity.generate("id")
|
||||
message = dht.InfoHash.getRandom().toString()
|
||||
encrypted = i.publickey.encrypt(message)
|
||||
decrypted = i.key.decrypt(encrypted)
|
||||
self.assertTrue(message == decrypted)
|
||||
|
||||
def test_crypto_ec(self):
|
||||
key = dht.PrivateKey.generateEC()
|
||||
cert = dht.Certificate.generate(key, "CA", is_ca=True)
|
||||
ca_id = dht.Identity(key, cert)
|
||||
self.assertTrue(cert.getId() == key.getPublicKey().getId())
|
||||
key2 = dht.PrivateKey.generateEC()
|
||||
cert2 = dht.Certificate.generate(key2, "cert", ca_id)
|
||||
trust = dht.TrustList()
|
||||
trust.add(cert)
|
||||
self.assertTrue(trust.verify(cert2))
|
||||
|
||||
def test_trust(self):
|
||||
main_id = dht.Identity.generate("id_1")
|
||||
sub_id1 = dht.Identity.generate("sid_1", main_id)
|
||||
sub_id2 = dht.Identity.generate("sid_2", main_id)
|
||||
main_id.certificate.revoke(main_id.key, sub_id2.certificate)
|
||||
main_id2 = dht.Identity.generate("id_2")
|
||||
trust = dht.TrustList()
|
||||
trust.add(main_id.certificate)
|
||||
self.assertTrue(trust.verify(main_id.certificate))
|
||||
self.assertTrue(trust.verify(sub_id1.certificate))
|
||||
self.assertFalse(trust.verify(sub_id2.certificate))
|
||||
self.assertFalse(trust.verify(main_id2.certificate))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -186,6 +186,7 @@ if __name__ == '__main__':
|
||||
wb = WorkBench(args.ifname, args.virtual_locs, args.node_num, loss=args.loss,
|
||||
delay=args.delay, disable_ipv4=args.disable_ipv4,
|
||||
disable_ipv6=args.disable_ipv6)
|
||||
wb.create_virtual_net()
|
||||
bootstrap = wb.get_bootstrap()
|
||||
|
||||
bs_dht_log_enabled = False
|
||||
@@ -203,7 +204,6 @@ if __name__ == '__main__':
|
||||
bs_dht_log_enabled = True
|
||||
bootstrap.front().enableLogging()
|
||||
|
||||
wb.create_virtual_net()
|
||||
bootstrap.resize(1)
|
||||
print("Launching", wb.node_num, "nodes (", wb.clusters, "clusters of", wb.node_per_loc, "nodes)")
|
||||
|
||||
|
||||
Executable
+265
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, sys, time, cmd
|
||||
import subprocess
|
||||
import signal
|
||||
import argparse
|
||||
import threading
|
||||
|
||||
import opendht as dht
|
||||
|
||||
class NodeCluster(object):
|
||||
nodes = []
|
||||
node_uid = 0
|
||||
|
||||
@staticmethod
|
||||
def run_node(ip4, ip6, p, bootstrap=None, is_bootstrap=False, logfile=None):
|
||||
print("run_node", ip4, ip6, p, bootstrap, logfile)
|
||||
n = dht.DhtRunner()
|
||||
n.run(ipv4=ip4 if ip4 else "", ipv6=ip6 if ip6 else "", port=p, is_bootstrap=is_bootstrap)
|
||||
if logfile:
|
||||
n.enableFileLogging(logfile)
|
||||
if bootstrap:
|
||||
n.bootstrap(bootstrap[0], bootstrap[1])
|
||||
time.sleep(.01)
|
||||
return ((ip4, ip6, p), n, id)
|
||||
|
||||
@staticmethod
|
||||
def find_ip(iface):
|
||||
if not iface or iface == 'any':
|
||||
return ('0.0.0.0','')
|
||||
|
||||
if_ip4 = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
|
||||
if_ip6 = netifaces.ifaddresses(iface)[netifaces.AF_INET6][0]['addr']
|
||||
return (if_ip4, if_ip6)
|
||||
|
||||
def __init__(self, iface=None, ip4=None, ip6=None, port=4000, bootstrap=None, first_bootstrap=False, logfile=None):
|
||||
NodeCluster.iface = iface
|
||||
self.port = port
|
||||
ips = NodeCluster.find_ip(iface)
|
||||
self.logfile = logfile
|
||||
self.ip4 = ip4 if ip4 else ips[0]
|
||||
self.ip6 = ip6 if ip6 else ips[1]
|
||||
self.bootstrap = bootstrap
|
||||
if bootstrap:
|
||||
self.bootstrap = (bootstrap.hostname, str(bootstrap.port) if bootstrap.port else "4222")
|
||||
else:
|
||||
print("Using fallback bootstrap", self.ip4, self.port)
|
||||
self.bootstrap = ((self.ip4, str(self.port)))
|
||||
if first_bootstrap:
|
||||
print("Starting bootstrap node")
|
||||
self.nodes.append(NodeCluster.run_node(self.ip4, self.ip6, self.port, self.bootstrap, is_bootstrap=True))
|
||||
self.bootstrap = ((self.ip4, str(self.port)))
|
||||
self.port += 1
|
||||
#print(self.ip4, self.ip6, self.port)
|
||||
|
||||
def front(self):
|
||||
if len(self.nodes) == 0:
|
||||
return None
|
||||
return self.nodes[0][1]
|
||||
|
||||
def get(self, i=None):
|
||||
if not self.nodes:
|
||||
return None
|
||||
|
||||
if i is None:
|
||||
l = list(self.nodes)
|
||||
random.shuffle(l)
|
||||
return l[0][1]
|
||||
else:
|
||||
return self.nodes[i][1]
|
||||
|
||||
def getNodeInfoById(self, id=None):
|
||||
if id:
|
||||
for n in self.nodes:
|
||||
if n[1].getNodeId() == id:
|
||||
return n
|
||||
return None
|
||||
|
||||
def launch_node(self):
|
||||
node_logfile = (self.logfile + str(self.node_uid) + '.log') if self.logfile else None
|
||||
n = NodeCluster.run_node(self.ip4, self.ip6, self.port, self.bootstrap, logfile=node_logfile)
|
||||
self.nodes.append(n)
|
||||
self.port += 1
|
||||
self.node_uid += 1
|
||||
return n
|
||||
|
||||
def end_node(self, id=None, shutdown=False, last_msg_stats=None):
|
||||
"""
|
||||
Ends a running node.
|
||||
|
||||
@param id: The 40 hex chars id of the node.
|
||||
@type id: bytes
|
||||
|
||||
@return: If a node was deleted or not.
|
||||
@rtype : boolean
|
||||
"""
|
||||
lock = threading.Condition()
|
||||
def shutdown_cb():
|
||||
nonlocal lock
|
||||
NodeCluster.Log.log('Done.')
|
||||
with lock:
|
||||
lock.notify()
|
||||
|
||||
if not self.nodes:
|
||||
return
|
||||
elif id:
|
||||
n = self.getNodeInfoById(id)
|
||||
if n:
|
||||
if shutdown:
|
||||
with lock:
|
||||
print('Waiting for node to shutdown... ')
|
||||
n[1].shutdown(shutdown_cb)
|
||||
lock.wait()
|
||||
if last_msg_stats:
|
||||
last_msg_stats.append(self.getMessageStats())
|
||||
n[1].join()
|
||||
self.nodes.remove(n)
|
||||
print(id, 'deleted !')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
n = self.nodes.pop()
|
||||
n[1].join()
|
||||
return True
|
||||
|
||||
def replace_node(self, id=None, shutdown=False, last_msg_stats=None):
|
||||
random.shuffle(self.nodes)
|
||||
deleted = self.end_node(id=id, shutdown=shutdown, last_msg_stats=last_msg_stats)
|
||||
if deleted:
|
||||
self.launch_node()
|
||||
|
||||
def resize(self, n):
|
||||
n = min(n, 500)
|
||||
l = len(self.nodes)
|
||||
if n == l:
|
||||
return
|
||||
if n > l:
|
||||
print("Launching", n-l, "nodes", self.ip4, self.ip6)
|
||||
for i in range(l, n):
|
||||
self.launch_node()
|
||||
else:
|
||||
print("Ending", l-n, "nodes", self.ip4, self.ip6)
|
||||
#random.shuffle(self.nodes)
|
||||
for i in range(n, l):
|
||||
self.end_node()
|
||||
|
||||
def close(self):
|
||||
self.resize(0)
|
||||
|
||||
def getMessageStats(self):
|
||||
stats = np.array([0,0,0,0,0])
|
||||
for n in self.nodes:
|
||||
stats += np.array(n[1].getNodeMessageStats())
|
||||
stats_list = [len(self.nodes)]
|
||||
stats_list.extend(stats.tolist())
|
||||
return stats_list
|
||||
|
||||
class ClusterShell(cmd.Cmd):
|
||||
intro = 'Welcome to the OpenDHT node cluster control. Type help or ? to list commands.\n'
|
||||
prompt = '>> '
|
||||
net = None
|
||||
node = None
|
||||
log = False
|
||||
def __init__(self, network):
|
||||
super(ClusterShell, self).__init__()
|
||||
self.net = network
|
||||
def setNode(self, node=None, num=0):
|
||||
if node == self.node:
|
||||
return
|
||||
if self.node:
|
||||
self.node.disableLogging()
|
||||
self.node = node
|
||||
if self.node:
|
||||
self.prompt = '('+str(num)+') >> '
|
||||
if self.log:
|
||||
self.node.enableLogging()
|
||||
else:
|
||||
self.prompt = '>> '
|
||||
def do_exit(self, arg):
|
||||
self.close()
|
||||
return True
|
||||
def do_node(self, arg):
|
||||
if not arg:
|
||||
setNode()
|
||||
else:
|
||||
nodenum = int(arg)
|
||||
if nodenum > len(self.net.nodes) or nodenum < 1:
|
||||
print("Invalid node number:", nodenum, " (accepted: 1-", len(self.net.nodes), ")")
|
||||
else:
|
||||
self.setNode(self.net.nodes[nodenum-1][1], nodenum)
|
||||
def do_ll(self, arg):
|
||||
if self.node:
|
||||
print('Node', self.node.getNodeId().decode())
|
||||
else:
|
||||
print(len(self.net.nodes), 'nodes running.')
|
||||
def do_ls(self, arg):
|
||||
if self.node:
|
||||
print(self.node.getSearchesLog(0))
|
||||
else:
|
||||
print('No node selected.')
|
||||
def do_log(self, arg):
|
||||
if self.node:
|
||||
self.log = not self.log
|
||||
if self.log:
|
||||
self.node.enableLogging()
|
||||
else:
|
||||
self.node.disableLogging()
|
||||
def do_EOF(self, line):
|
||||
self.close()
|
||||
return True
|
||||
def close(self):
|
||||
if self.net:
|
||||
self.net.close()
|
||||
self.net = None
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
from urllib.parse import urlparse
|
||||
net = None
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
|
||||
parser.add_argument('-n', '--node-num', help='number of dht nodes to run', type=int, default=32)
|
||||
parser.add_argument('-I', '--iface', help='local interface to bind', default='any')
|
||||
parser.add_argument('-p', '--port', help='start of port range (port, port+node_num)', type=int, default=4000)
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address')
|
||||
parser.add_argument('-d', '--daemonize', help='daemonize process', action='store_true')
|
||||
parser.add_argument('-l', '--log', help='log file prefix')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.bootstrap:
|
||||
args.bootstrap = urlparse('dht://'+args.bootstrap)
|
||||
|
||||
net = NodeCluster(iface=args.iface, port=args.port, bootstrap=args.bootstrap, logfile=args.log)
|
||||
net.resize(args.node_num)
|
||||
if args.daemonize:
|
||||
import daemon, lockfile
|
||||
#pidfile=lockfile.FileLock('/var/run/dhtcluster.'+str(args.port))
|
||||
with daemon.DaemonContext():
|
||||
while True:
|
||||
time.sleep(2)
|
||||
else:
|
||||
ClusterShell(net).cmdloop()
|
||||
except Exception as e:
|
||||
traceback.print_tb(e.__traceback__)
|
||||
print(type(e).__name__+':', e, file=sys.stderr)
|
||||
finally:
|
||||
if net:
|
||||
net.resize(0)
|
||||
@@ -11,6 +11,7 @@ import string
|
||||
import time
|
||||
import subprocess
|
||||
import re
|
||||
import traceback
|
||||
import collections
|
||||
|
||||
from matplotlib.ticker import FuncFormatter
|
||||
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from twisted.web import server, resource
|
||||
from twisted.internet import reactor, endpoints
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import opendht as dht
|
||||
import base64, json
|
||||
|
||||
class DhtServer(resource.Resource):
|
||||
isLeaf = True
|
||||
node = dht.DhtRunner()
|
||||
|
||||
def __init__(self, port, bootstrap):
|
||||
self.node.run(port=port)
|
||||
b_url = urlparse('//'+bootstrap)
|
||||
self.node.bootstrap(b_url.hostname, str(b_url.port) if b_url.port else '4222')
|
||||
|
||||
def render_GET(self, req):
|
||||
uri = req.uri[1:]
|
||||
h = dht.InfoHash(uri) if len(uri) == 40 else dht.InfoHash.get(uri.decode())
|
||||
print('GET', '"'+uri.decode()+'"', h)
|
||||
res = self.node.get(h)
|
||||
req.setHeader(b"content-type", b"application/json")
|
||||
return json.dumps({'{:x}'.format(v.id):{'base64':base64.b64encode(v.data).decode()} for v in res}).encode()
|
||||
|
||||
def render_POST(self, req):
|
||||
uri = req.uri[1:]
|
||||
data = req.args[b'data'][0] if b'data' in req.args else None
|
||||
if not data and b'base64' in req.args:
|
||||
data = base64.b64decode(req.args[b'base64'][0])
|
||||
h = dht.InfoHash(uri) if len(uri) == 40 else dht.InfoHash.get(uri.decode())
|
||||
print('POST', h, data)
|
||||
req.setHeader(b"content-type", b"application/json")
|
||||
if data:
|
||||
self.node.put(h, dht.Value(data))
|
||||
return json.dumps({'success':True}).encode()
|
||||
else:
|
||||
req.setResponseCode(400)
|
||||
return json.dumps({'success':False, 'error':'no data parameter'}).encode()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description='Launch an OpenDHT node with an HTTP control interface')
|
||||
parser.add_argument('-p', '--port', help='OpenDHT port to bind', type=int, default=4222)
|
||||
parser.add_argument('-hp', '--http-port', help='HTTP port to bind', type=int, default=8080)
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default="bootstrap.ring.cx:4222")
|
||||
args = parser.parse_args()
|
||||
endpoints.serverFromString(reactor, "tcp:"+str(args.http_port)).listen(server.Site(DhtServer(args.port, args.bootstrap)))
|
||||
reactor.run()
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2016 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import time
|
||||
import argparse
|
||||
import time
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
import opendht as dht
|
||||
|
||||
parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default='bootstrap.ring.cx')
|
||||
parser.add_argument('-n', '--num-ops', help='number of concurrent operations on the DHT', type=int, default=8)
|
||||
parser.add_argument('-p', '--period', help='duration between each test (seconds)', type=int, default=60)
|
||||
parser.add_argument('-t', '--timeout', help='timeout for a test to complete (seconds)', type=float, default=15)
|
||||
args = parser.parse_args()
|
||||
|
||||
node1 = dht.DhtRunner()
|
||||
node1.run()
|
||||
|
||||
node2 = dht.DhtRunner()
|
||||
node2.run()
|
||||
|
||||
node1.bootstrap(args.bootstrap)
|
||||
node2.bootstrap(args.bootstrap)
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
pending_tests = {}
|
||||
keys = [dht.InfoHash.getRandom() for _ in range(args.num_ops)]
|
||||
|
||||
def listen_cb(key, val):
|
||||
global pending_tests
|
||||
kstr = str(key)
|
||||
if kstr in pending_tests:
|
||||
if pending_tests[kstr]['v'].id == val.id:
|
||||
pending_tests.pop(kstr, None)
|
||||
else:
|
||||
print("Expected vid", val.id, "got", pending_tests[kstr]['v'].id)
|
||||
return True
|
||||
|
||||
def listen(key):
|
||||
node1.listen(key, lambda v: loop.call_soon_threadsafe(listen_cb, key, v))
|
||||
|
||||
for key in keys:
|
||||
listen(key)
|
||||
|
||||
next_test = time.time()
|
||||
while True:
|
||||
start = time.time()
|
||||
#print(datetime.fromtimestamp(start).strftime('%Y-%m-%d %H:%M:%S'), 'Test started')
|
||||
for key in keys:
|
||||
val = dht.Value(str(dht.InfoHash.getRandom()).encode())
|
||||
pending_tests[str(key)] = {'v':val, 'c':0}
|
||||
node2.put(key, val, lambda ok, nodes: ok)
|
||||
while len(pending_tests):
|
||||
loop.stop()
|
||||
loop.run_forever()
|
||||
time.sleep(1)
|
||||
if time.time()-start > args.timeout:
|
||||
print('Test timeout !')
|
||||
exit(1)
|
||||
|
||||
end = time.time()
|
||||
print(datetime.fromtimestamp(end).strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'Test completed successfully in', end-start)
|
||||
next_test += args.period
|
||||
if next_test > end:
|
||||
time.sleep(next_test-end)
|
||||
+23
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2017 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,41 +13,50 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# along with this program; If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import opendht as dht
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
ping_node = dht.DhtRunner()
|
||||
ping_node.run(port = 5632)
|
||||
ping_node.run()
|
||||
#ping_node.enableLogging()
|
||||
#ping_node.bootstrap("bootstrap.ring.cx", "4222")
|
||||
|
||||
pong_node = dht.DhtRunner()
|
||||
pong_node.run(port = 5633)
|
||||
pong_node.run()
|
||||
#pong_node.enableLogging()
|
||||
pong_node.bootstrap("192.168.49.55", "5632");
|
||||
#pong_node.bootstrap("192.168.49.55", "5632");
|
||||
pong_node.ping(ping_node.getBound());
|
||||
|
||||
loc_ping = dht.InfoHash.get("toto99")
|
||||
loc_pong = dht.InfoHash.get(str(loc_ping))
|
||||
|
||||
i = 0
|
||||
MAX = 8192
|
||||
MAX = 2048
|
||||
|
||||
def pong(node, h):
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
def done(h, ok):
|
||||
print(h, "over", ok)
|
||||
|
||||
def ping(node, h):
|
||||
global i
|
||||
print("got ping", h, i)
|
||||
time.sleep(0.0075)
|
||||
time.sleep(0.0075)
|
||||
i += 1
|
||||
if i < MAX:
|
||||
node.put(h, dht.Value(b"hey"), lambda ok, nodes: print("over", ok))
|
||||
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
|
||||
else:
|
||||
loop.stop()
|
||||
|
||||
def pong(node, h):
|
||||
print(node.getNodeId().decode(), "got ping", h, i)
|
||||
loop.call_soon_threadsafe(ping, node, h);
|
||||
return True
|
||||
|
||||
ping_node.listen(loc_ping, lambda v: pong(pong_node, loc_pong))
|
||||
pong_node.listen(loc_pong, lambda v: pong(ping_node, loc_ping))
|
||||
|
||||
pong_node.put(loc_pong, dht.Value(b"hey"), lambda ok, nodes: print("i over", ok))
|
||||
ping(pong_node, loc_ping)
|
||||
|
||||
while (i < MAX):
|
||||
time.sleep(1)
|
||||
loop.run_forever()
|
||||
@@ -18,7 +18,7 @@
|
||||
import time, sys, os
|
||||
from pprint import pprint
|
||||
from math import cos, sin, pi
|
||||
from urllib import request
|
||||
import urllib3
|
||||
import gzip
|
||||
import asyncio
|
||||
|
||||
@@ -35,6 +35,8 @@ from mpl_toolkits.basemap import Basemap
|
||||
|
||||
import GeoIP
|
||||
|
||||
http = urllib3.PoolManager()
|
||||
|
||||
done = 0
|
||||
all_nodes = NodeSet()
|
||||
|
||||
@@ -72,7 +74,7 @@ def check_dl(fname, url):
|
||||
if os.path.isfile(fname):
|
||||
return
|
||||
print('downloading', url)
|
||||
ghandle = gzip.GzipFile(fileobj=request.urlopen(url))
|
||||
ghandle = gzip.GzipFile(fileobj=http.request('GET', url, headers={'User-Agent': 'Mozilla/5.0'}, preload_content=False))
|
||||
with open(fname, 'wb') as out:
|
||||
for line in ghandle:
|
||||
out.write(line)
|
||||
@@ -224,7 +226,7 @@ def update_plot():
|
||||
del collection
|
||||
collection = None
|
||||
collection = ringx.add_collection(RegularPolyCollection(
|
||||
fig.dpi, 6, sizes=(10,), facecolors=colors,
|
||||
int(fig.dpi), 6, sizes=(10,), facecolors=colors,
|
||||
offsets = xys, transOffset = ringx.transData))
|
||||
|
||||
node_ip4s, node_ip6s = generate_set()
|
||||
|
||||
+39
-9
@@ -1,13 +1,9 @@
|
||||
SUBDIRS = argon2
|
||||
|
||||
lib_LTLIBRARIES = libopendht.la
|
||||
|
||||
AM_CPPFLAGS = -I../include/opendht
|
||||
libopendht_la_CXXFLAGS = @CXXFLAGS@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@
|
||||
libopendht_la_LIBADD = ./argon2/libargon2.la
|
||||
|
||||
libopendht_la_SOURCES = \
|
||||
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@
|
||||
libopendht_la_LIBADD = @Argon2_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@
|
||||
libopendht_la_SOURCES = \
|
||||
dht.cpp \
|
||||
node_cache.cpp \
|
||||
callbacks.cpp \
|
||||
@@ -21,7 +17,8 @@ libopendht_la_SOURCES = \
|
||||
securedht.cpp \
|
||||
dhtrunner.cpp \
|
||||
default_types.cpp \
|
||||
indexation/pht.cpp
|
||||
indexation/pht.cpp \
|
||||
log.cpp
|
||||
|
||||
if WIN32
|
||||
libopendht_la_SOURCES += rng.cpp
|
||||
@@ -29,11 +26,13 @@ endif
|
||||
|
||||
nobase_include_HEADERS = \
|
||||
../include/opendht.h \
|
||||
../include/opendht/def.h \
|
||||
../include/opendht/dht.h \
|
||||
../include/opendht/callbacks.h \
|
||||
../include/opendht/node_cache.h \
|
||||
../include/opendht/routing_table.h \
|
||||
../include/opendht/network_engine.h \
|
||||
../include/opendht/net.h \
|
||||
../include/opendht/scheduler.h \
|
||||
../include/opendht/rate_limiter.h \
|
||||
../include/opendht/utils.h \
|
||||
@@ -52,3 +51,34 @@ nobase_include_HEADERS = \
|
||||
|
||||
nobase_noinst_HEADERS = \
|
||||
../include/opendht/request.h
|
||||
|
||||
clean-local:
|
||||
rm -rf libargon2.la
|
||||
|
||||
######################
|
||||
# ARGON2 submodule #
|
||||
######################
|
||||
|
||||
if WITH_INCLUDED_ARGON2
|
||||
noinst_LTLIBRARIES = libargon2.la
|
||||
libopendht_la_DEPENDENCIES = libargon2.la
|
||||
|
||||
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall -I@top_builddir@/argon2/include -I@top_builddir@/argon2/src
|
||||
libargon2_la_SOURCES = \
|
||||
@top_builddir@/argon2/src/argon2.c \
|
||||
@top_builddir@/argon2/src/core.c \
|
||||
@top_builddir@/argon2/src/blake2/blake2b.c \
|
||||
@top_builddir@/argon2/src/thread.c \
|
||||
@top_builddir@/argon2/src/ref.c \
|
||||
@top_builddir@/argon2/src/encoding.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
@top_builddir@/argon2/include/argon2.h \
|
||||
@top_builddir@/argon2/src/blake2/blake2.h \
|
||||
@top_builddir@/argon2/src/blake2/blake2-impl.h \
|
||||
@top_builddir@/argon2/src/blake2/blamka-round-ref.h \
|
||||
@top_builddir@/argon2/src/core.h \
|
||||
@top_builddir@/argon2/src/encoding.h \
|
||||
@top_builddir@/argon2/src/thread.h
|
||||
endif
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
|
||||
|
||||
the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
|
||||
moral rights retained by the original author(s) and/or performer(s);
|
||||
publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
|
||||
rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
|
||||
rights protecting the extraction, dissemination, use and reuse of data in a Work;
|
||||
database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
|
||||
other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
|
||||
Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
|
||||
Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
|
||||
Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
noinst_LTLIBRARIES = libargon2.la
|
||||
|
||||
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall
|
||||
|
||||
libargon2_la_SOURCES = \
|
||||
argon2.c \
|
||||
core.c \
|
||||
blake2/blake2b.c \
|
||||
thread.c \
|
||||
encoding.c \
|
||||
ref.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
argon2.h \
|
||||
core.h \
|
||||
blake2/blake2.h \
|
||||
blake2/blake2-impl.h \
|
||||
blake2/blamka-round-ref.h \
|
||||
blake2/blamka-round-opt.h \
|
||||
thread.h \
|
||||
encoding.h \
|
||||
opt.h \
|
||||
ref.h
|
||||
@@ -1,447 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
const char *argon2_type2string(argon2_type type, int uppercase) {
|
||||
switch (type) {
|
||||
case Argon2_d:
|
||||
return uppercase ? "Argon2d" : "argon2d";
|
||||
case Argon2_i:
|
||||
return uppercase ? "Argon2i" : "argon2i";
|
||||
case Argon2_id:
|
||||
return uppercase ? "Argon2id" : "argon2id";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs(context);
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
/* 2. Align memory size */
|
||||
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
||||
memory_blocks = context->m_cost;
|
||||
|
||||
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
|
||||
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
||||
}
|
||||
|
||||
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
|
||||
/* Ensure that all segments have equal length */
|
||||
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
||||
|
||||
instance.version = context->version;
|
||||
instance.memory = NULL;
|
||||
instance.passes = context->t_cost;
|
||||
instance.memory_blocks = memory_blocks;
|
||||
instance.segment_length = segment_length;
|
||||
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
||||
instance.lanes = context->lanes;
|
||||
instance.threads = context->threads;
|
||||
instance.type = type;
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
*/
|
||||
result = initialize(&instance, context);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 4. Filling memory */
|
||||
result = fill_memory_blocks(&instance);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
/* 5. Finalization */
|
||||
finalize(context, &instance);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt, const size_t saltlen,
|
||||
void *hash, const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type,
|
||||
const uint32_t version){
|
||||
|
||||
argon2_context context;
|
||||
int result;
|
||||
uint8_t *out;
|
||||
|
||||
if (hashlen > ARGON2_MAX_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
if (hashlen < ARGON2_MIN_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
out = malloc(hashlen);
|
||||
if (!out) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
context.out = (uint8_t *)out;
|
||||
context.outlen = (uint32_t)hashlen;
|
||||
context.pwd = CONST_CAST(uint8_t *)pwd;
|
||||
context.pwdlen = (uint32_t)pwdlen;
|
||||
context.salt = CONST_CAST(uint8_t *)salt;
|
||||
context.saltlen = (uint32_t)saltlen;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = parallelism;
|
||||
context.threads = parallelism;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
context.version = version;
|
||||
|
||||
result = argon2_ctx(&context, type);
|
||||
|
||||
if (result != ARGON2_OK) {
|
||||
secure_wipe_memory(out, hashlen);
|
||||
free(out);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* if raw hash requested, write it */
|
||||
if (hash) {
|
||||
memcpy(hash, out, hashlen);
|
||||
}
|
||||
|
||||
/* if encoding requested, write it */
|
||||
if (encoded && encodedlen) {
|
||||
if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
|
||||
secure_wipe_memory(out, hashlen); /* wipe buffers if error */
|
||||
secure_wipe_memory(encoded, encodedlen);
|
||||
free(out);
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
}
|
||||
secure_wipe_memory(out, hashlen);
|
||||
free(out);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_i,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_d,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_id,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_id,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
|
||||
size_t i;
|
||||
uint8_t d = 0U;
|
||||
|
||||
for (i = 0U; i < len; i++) {
|
||||
d |= b1[i] ^ b2[i];
|
||||
}
|
||||
return (int)((1 & ((d - 1) >> 8)) - 1);
|
||||
}
|
||||
|
||||
int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
argon2_type type) {
|
||||
|
||||
argon2_context ctx;
|
||||
uint8_t *out;
|
||||
int ret;
|
||||
int decode_result;
|
||||
uint32_t encoded_len;
|
||||
size_t encoded_len_tmp;
|
||||
|
||||
if(encoded == NULL) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
encoded_len_tmp = strlen(encoded);
|
||||
/* max values, to be updated in decode_string */
|
||||
if (UINT32_MAX < encoded_len_tmp) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
encoded_len = (uint32_t)encoded_len_tmp;
|
||||
ctx.adlen = encoded_len;
|
||||
ctx.saltlen = encoded_len;
|
||||
ctx.outlen = encoded_len;
|
||||
ctx.allocate_cbk = NULL;
|
||||
ctx.free_cbk = NULL;
|
||||
ctx.secret = NULL;
|
||||
ctx.secretlen = 0;
|
||||
ctx.pwdlen = 0;
|
||||
ctx.pwd = NULL;
|
||||
ctx.ad = malloc(ctx.adlen);
|
||||
ctx.salt = malloc(ctx.saltlen);
|
||||
ctx.out = malloc(ctx.outlen);
|
||||
if (!ctx.out || !ctx.salt || !ctx.ad) {
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
free(ctx.out);
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
out = malloc(ctx.outlen);
|
||||
if (!out) {
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
free(ctx.out);
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
decode_result = decode_string(&ctx, encoded, type);
|
||||
if (decode_result != ARGON2_OK) {
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
free(ctx.out);
|
||||
free(out);
|
||||
return decode_result;
|
||||
}
|
||||
|
||||
ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen,
|
||||
ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type,
|
||||
ctx.version);
|
||||
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
|
||||
if (ret == ARGON2_OK && argon2_compare(out, ctx.out, ctx.outlen)) {
|
||||
ret = ARGON2_VERIFY_MISMATCH;
|
||||
}
|
||||
free(out);
|
||||
free(ctx.out);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
|
||||
}
|
||||
|
||||
int argon2d_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2i_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2id_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_id);
|
||||
}
|
||||
|
||||
int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type) {
|
||||
int result;
|
||||
if (0 == context->outlen || NULL == hash) {
|
||||
return ARGON2_OUT_PTR_MISMATCH;
|
||||
}
|
||||
|
||||
result = argon2_ctx(context, type);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0 == memcmp(hash, context->out, context->outlen);
|
||||
}
|
||||
|
||||
int argon2d_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2i_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2id_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_id);
|
||||
}
|
||||
|
||||
const char *argon2_error_message(int error_code) {
|
||||
switch (error_code) {
|
||||
case ARGON2_OK:
|
||||
return "OK";
|
||||
case ARGON2_OUTPUT_PTR_NULL:
|
||||
return "Output pointer is NULL";
|
||||
case ARGON2_OUTPUT_TOO_SHORT:
|
||||
return "Output is too short";
|
||||
case ARGON2_OUTPUT_TOO_LONG:
|
||||
return "Output is too long";
|
||||
case ARGON2_PWD_TOO_SHORT:
|
||||
return "Password is too short";
|
||||
case ARGON2_PWD_TOO_LONG:
|
||||
return "Password is too long";
|
||||
case ARGON2_SALT_TOO_SHORT:
|
||||
return "Salt is too short";
|
||||
case ARGON2_SALT_TOO_LONG:
|
||||
return "Salt is too long";
|
||||
case ARGON2_AD_TOO_SHORT:
|
||||
return "Associated data is too short";
|
||||
case ARGON2_AD_TOO_LONG:
|
||||
return "Associated data is too long";
|
||||
case ARGON2_SECRET_TOO_SHORT:
|
||||
return "Secret is too short";
|
||||
case ARGON2_SECRET_TOO_LONG:
|
||||
return "Secret is too long";
|
||||
case ARGON2_TIME_TOO_SMALL:
|
||||
return "Time cost is too small";
|
||||
case ARGON2_TIME_TOO_LARGE:
|
||||
return "Time cost is too large";
|
||||
case ARGON2_MEMORY_TOO_LITTLE:
|
||||
return "Memory cost is too small";
|
||||
case ARGON2_MEMORY_TOO_MUCH:
|
||||
return "Memory cost is too large";
|
||||
case ARGON2_LANES_TOO_FEW:
|
||||
return "Too few lanes";
|
||||
case ARGON2_LANES_TOO_MANY:
|
||||
return "Too many lanes";
|
||||
case ARGON2_PWD_PTR_MISMATCH:
|
||||
return "Password pointer is NULL, but password length is not 0";
|
||||
case ARGON2_SALT_PTR_MISMATCH:
|
||||
return "Salt pointer is NULL, but salt length is not 0";
|
||||
case ARGON2_SECRET_PTR_MISMATCH:
|
||||
return "Secret pointer is NULL, but secret length is not 0";
|
||||
case ARGON2_AD_PTR_MISMATCH:
|
||||
return "Associated data pointer is NULL, but ad length is not 0";
|
||||
case ARGON2_MEMORY_ALLOCATION_ERROR:
|
||||
return "Memory allocation error";
|
||||
case ARGON2_FREE_MEMORY_CBK_NULL:
|
||||
return "The free memory callback is NULL";
|
||||
case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
|
||||
return "The allocate memory callback is NULL";
|
||||
case ARGON2_INCORRECT_PARAMETER:
|
||||
return "Argon2_Context context is NULL";
|
||||
case ARGON2_INCORRECT_TYPE:
|
||||
return "There is no such version of Argon2";
|
||||
case ARGON2_OUT_PTR_MISMATCH:
|
||||
return "Output pointer mismatch";
|
||||
case ARGON2_THREADS_TOO_FEW:
|
||||
return "Not enough threads";
|
||||
case ARGON2_THREADS_TOO_MANY:
|
||||
return "Too many threads";
|
||||
case ARGON2_MISSING_ARGS:
|
||||
return "Missing arguments";
|
||||
case ARGON2_ENCODING_FAIL:
|
||||
return "Encoding failed";
|
||||
case ARGON2_DECODING_FAIL:
|
||||
return "Decoding failed";
|
||||
case ARGON2_THREAD_FAIL:
|
||||
return "Threading failure";
|
||||
case ARGON2_DECODING_LENGTH_FAIL:
|
||||
return "Some of encoded parameters are too long or too short";
|
||||
case ARGON2_VERIFY_MISMATCH:
|
||||
return "The password does not match the supplied hash";
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
}
|
||||
|
||||
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
|
||||
uint32_t saltlen, uint32_t hashlen, argon2_type type) {
|
||||
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
|
||||
numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
|
||||
b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
|
||||
}
|
||||
@@ -1,430 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_H
|
||||
#define ARGON2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Symbols visibility control */
|
||||
#ifdef A2_VISCTL
|
||||
#define ARGON2_PUBLIC __attribute__((visibility("default")))
|
||||
#elif _MSC_VER
|
||||
#define ARGON2_PUBLIC __declspec(dllexport)
|
||||
#else
|
||||
#define ARGON2_PUBLIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Argon2 input parameter restrictions
|
||||
*/
|
||||
|
||||
/* Minimum and maximum number of lanes (degree of parallelism) */
|
||||
#define ARGON2_MIN_LANES UINT32_C(1)
|
||||
#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
|
||||
|
||||
/* Minimum and maximum number of threads */
|
||||
#define ARGON2_MIN_THREADS UINT32_C(1)
|
||||
#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
|
||||
|
||||
/* Number of synchronization points between lanes per pass */
|
||||
#define ARGON2_SYNC_POINTS UINT32_C(4)
|
||||
|
||||
/* Minimum and maximum digest size in bytes */
|
||||
#define ARGON2_MIN_OUTLEN UINT32_C(4)
|
||||
#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
|
||||
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
|
||||
|
||||
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
|
||||
#define ARGON2_MAX_MEMORY_BITS \
|
||||
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
|
||||
#define ARGON2_MAX_MEMORY \
|
||||
ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
#define ARGON2_MIN_TIME UINT32_C(1)
|
||||
#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum password length in bytes */
|
||||
#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
|
||||
#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum associated data length in bytes */
|
||||
#define ARGON2_MIN_AD_LENGTH UINT32_C(0)
|
||||
#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum salt length in bytes */
|
||||
#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
|
||||
#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum key length in bytes */
|
||||
#define ARGON2_MIN_SECRET UINT32_C(0)
|
||||
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
|
||||
|
||||
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
|
||||
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
|
||||
#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)
|
||||
#define ARGON2_DEFAULT_FLAGS (ARGON2_FLAG_CLEAR_MEMORY)
|
||||
|
||||
/* Error codes */
|
||||
typedef enum Argon2_ErrorCodes {
|
||||
ARGON2_OK = 0,
|
||||
|
||||
ARGON2_OUTPUT_PTR_NULL = -1,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = -2,
|
||||
ARGON2_OUTPUT_TOO_LONG = -3,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = -4,
|
||||
ARGON2_PWD_TOO_LONG = -5,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = -6,
|
||||
ARGON2_SALT_TOO_LONG = -7,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = -8,
|
||||
ARGON2_AD_TOO_LONG = -9,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = -10,
|
||||
ARGON2_SECRET_TOO_LONG = -11,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = -12,
|
||||
ARGON2_TIME_TOO_LARGE = -13,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = -14,
|
||||
ARGON2_MEMORY_TOO_MUCH = -15,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = -16,
|
||||
ARGON2_LANES_TOO_MANY = -17,
|
||||
|
||||
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
|
||||
ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
|
||||
ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
|
||||
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = -22,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = -23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = -25,
|
||||
ARGON2_INCORRECT_TYPE = -26,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = -27,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = -28,
|
||||
ARGON2_THREADS_TOO_MANY = -29,
|
||||
|
||||
ARGON2_MISSING_ARGS = -30,
|
||||
|
||||
ARGON2_ENCODING_FAIL = -31,
|
||||
|
||||
ARGON2_DECODING_FAIL = -32,
|
||||
|
||||
ARGON2_THREAD_FAIL = -33,
|
||||
|
||||
ARGON2_DECODING_LENGTH_FAIL = -34,
|
||||
|
||||
ARGON2_VERIFY_MISMATCH = -35
|
||||
} argon2_error_codes;
|
||||
|
||||
/* Memory allocator types --- for external allocation */
|
||||
typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
|
||||
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
|
||||
|
||||
/* Argon2 external data structures */
|
||||
|
||||
/*
|
||||
*****
|
||||
* Context: structure to hold Argon2 inputs:
|
||||
* output array and its length,
|
||||
* password and its length,
|
||||
* salt and its length,
|
||||
* secret and its length,
|
||||
* associated data and its length,
|
||||
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
|
||||
* number of parallel threads that will be run.
|
||||
* All the parameters above affect the output hash value.
|
||||
* Additionally, two function pointers can be provided to allocate and
|
||||
* deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* Also, three flags indicate whether to erase password, secret as soon as they
|
||||
* are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
*****
|
||||
* Simplest situation: you have output array out[8], password is stored in
|
||||
* pwd[32], salt is stored in salt[16], you do not have keys nor associated
|
||||
* data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
|
||||
* 4 parallel lanes.
|
||||
* You want to erase the password, but you're OK with last pass not being
|
||||
* erased. You want to use the default memory allocator.
|
||||
* Then you initialize:
|
||||
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)
|
||||
*/
|
||||
typedef struct Argon2_Context {
|
||||
uint8_t *out; /* output array */
|
||||
uint32_t outlen; /* digest length */
|
||||
|
||||
uint8_t *pwd; /* password array */
|
||||
uint32_t pwdlen; /* password length */
|
||||
|
||||
uint8_t *salt; /* salt array */
|
||||
uint32_t saltlen; /* salt length */
|
||||
|
||||
uint8_t *secret; /* key array */
|
||||
uint32_t secretlen; /* key length */
|
||||
|
||||
uint8_t *ad; /* associated data array */
|
||||
uint32_t adlen; /* associated data length */
|
||||
|
||||
uint32_t t_cost; /* number of passes */
|
||||
uint32_t m_cost; /* amount of memory requested (KB) */
|
||||
uint32_t lanes; /* number of lanes */
|
||||
uint32_t threads; /* maximum number of threads */
|
||||
|
||||
uint32_t version; /* version number */
|
||||
|
||||
allocate_fptr allocate_cbk; /* pointer to memory allocator */
|
||||
deallocate_fptr free_cbk; /* pointer to memory deallocator */
|
||||
|
||||
uint32_t flags; /* array of bool options */
|
||||
} argon2_context;
|
||||
|
||||
/* Argon2 primitive type */
|
||||
typedef enum Argon2_type {
|
||||
Argon2_d = 0,
|
||||
Argon2_i = 1,
|
||||
Argon2_id = 2
|
||||
} argon2_type;
|
||||
|
||||
/* Version of the algorithm */
|
||||
typedef enum Argon2_version {
|
||||
ARGON2_VERSION_10 = 0x10,
|
||||
ARGON2_VERSION_13 = 0x13,
|
||||
ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
|
||||
} argon2_version;
|
||||
|
||||
/*
|
||||
* Function that gives the string representation of an argon2_type.
|
||||
* @param type The argon2_type that we want the string for
|
||||
* @param uppercase Whether the string should have the first letter uppercase
|
||||
* @return NULL if invalid type, otherwise the string representation.
|
||||
*/
|
||||
ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase);
|
||||
|
||||
/*
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type);
|
||||
|
||||
/**
|
||||
* Hashes a password with Argon2i, producing an encoded hash
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Sets memory usage to m_cost kibibytes
|
||||
* @param parallelism Number of threads and compute lanes
|
||||
* @param pwd Pointer to password
|
||||
* @param pwdlen Password size in bytes
|
||||
* @param salt Pointer to salt
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hashlen Desired length of the hash in bytes
|
||||
* @param encoded Buffer where to write the encoded hash
|
||||
* @param encodedlen Size of the buffer (thus max size of the encoded hash)
|
||||
* @pre Different parallelism levels will give different results
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
/**
|
||||
* Hashes a password with Argon2i, producing a raw hash by allocating memory at
|
||||
* @hash
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Sets memory usage to m_cost kibibytes
|
||||
* @param parallelism Number of threads and compute lanes
|
||||
* @param pwd Pointer to password
|
||||
* @param pwdlen Password size in bytes
|
||||
* @param salt Pointer to salt
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hash Buffer where to write the raw hash - updated by the function
|
||||
* @param hashlen Desired length of the hash in bytes
|
||||
* @pre Different parallelism levels will give different results
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type,
|
||||
const uint32_t version);
|
||||
|
||||
/**
|
||||
* Verifies a password against an encoded string
|
||||
* Encoded string is restricted as in validate_inputs()
|
||||
* @param encoded String encoding parameters, salt, hash
|
||||
* @param pwd Pointer to password
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen, argon2_type type);
|
||||
|
||||
/**
|
||||
* Argon2d: Version of Argon2 that picks memory blocks depending
|
||||
* on the password and salt. Only for side-channel-free
|
||||
* environment!!
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Argon2i: Version of Argon2 that picks memory blocks
|
||||
* independent on the password and salt. Good for side-channels,
|
||||
* but worse w.r.t. tradeoff attacks if only one pass is used.
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Argon2id: Version of Argon2 where the first half-pass over memory is
|
||||
* password-independent, the rest are password-dependent (on the password and
|
||||
* salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
|
||||
* better with w.r.t. tradeoff attacks (similar to Argon2d).
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2id_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2d hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2i hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2id hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context,
|
||||
const char *hash);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type);
|
||||
|
||||
/**
|
||||
* Get the associated error message for given error code
|
||||
* @return The error message associated with the given error code
|
||||
*/
|
||||
ARGON2_PUBLIC const char *argon2_error_message(int error_code);
|
||||
|
||||
/**
|
||||
* Returns the encoded hash length for the given input parameters
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Memory usage in kibibytes
|
||||
* @param parallelism Number of threads; used to compute lanes
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hashlen Hash size in bytes
|
||||
* @return The encoded hash length in bytes
|
||||
*/
|
||||
ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
|
||||
uint32_t parallelism, uint32_t saltlen,
|
||||
uint32_t hashlen, argon2_type type);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef PORTABLE_BLAKE2_IMPL_H
|
||||
#define PORTABLE_BLAKE2_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define BLAKE2_INLINE __inline
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define BLAKE2_INLINE __inline__
|
||||
#else
|
||||
#define BLAKE2_INLINE
|
||||
#endif
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
/*
|
||||
Not an exhaustive list, but should cover the majority of modern platforms
|
||||
Additionally, the code will always be correct---this is only a performance
|
||||
tweak.
|
||||
*/
|
||||
#if (defined(__BYTE_ORDER__) && \
|
||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
|
||||
defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
|
||||
defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
|
||||
defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
|
||||
defined(_M_ARM)
|
||||
#define NATIVE_LITTLE_ENDIAN
|
||||
#endif
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
static BLAKE2_INLINE uint32_t load32(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint32_t w = *p++;
|
||||
w |= (uint32_t)(*p++) << 8;
|
||||
w |= (uint32_t)(*p++) << 16;
|
||||
w |= (uint32_t)(*p++) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load64(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint64_t w = *p++;
|
||||
w |= (uint64_t)(*p++) << 8;
|
||||
w |= (uint64_t)(*p++) << 16;
|
||||
w |= (uint64_t)(*p++) << 24;
|
||||
w |= (uint64_t)(*p++) << 32;
|
||||
w |= (uint64_t)(*p++) << 40;
|
||||
w |= (uint64_t)(*p++) << 48;
|
||||
w |= (uint64_t)(*p++) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store32(void *dst, uint32_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store64(void *dst, uint64_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load48(const void *src) {
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint64_t w = *p++;
|
||||
w |= (uint64_t)(*p++) << 8;
|
||||
w |= (uint64_t)(*p++) << 16;
|
||||
w |= (uint64_t)(*p++) << 24;
|
||||
w |= (uint64_t)(*p++) << 32;
|
||||
w |= (uint64_t)(*p++) << 40;
|
||||
return w;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store48(void *dst, uint64_t w) {
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (32 - c));
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (64 - c));
|
||||
}
|
||||
|
||||
void secure_wipe_memory(void *v, size_t n);
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef PORTABLE_BLAKE2_H
|
||||
#define PORTABLE_BLAKE2_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2b_constant {
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct __blake2b_param {
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint32_t leaf_length; /* 8 */
|
||||
uint64_t node_offset; /* 16 */
|
||||
uint8_t node_depth; /* 17 */
|
||||
uint8_t inner_length; /* 18 */
|
||||
uint8_t reserved[14]; /* 32 */
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
|
||||
} blake2b_param;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct __blake2b_state {
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
unsigned buflen;
|
||||
unsigned outlen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
/* Ensure param structs have not been wrongly padded */
|
||||
/* Poor man's static_assert */
|
||||
enum {
|
||||
blake2_size_check_0 = 1 / !!(CHAR_BIT == 8),
|
||||
blake2_size_check_2 =
|
||||
1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT)
|
||||
};
|
||||
|
||||
/* Streaming API */
|
||||
int blake2b_init(blake2b_state *S, size_t outlen);
|
||||
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
|
||||
size_t keylen);
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
|
||||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen);
|
||||
int blake2b_final(blake2b_state *S, void *out, size_t outlen);
|
||||
|
||||
/* Simple API */
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *key, size_t keylen);
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,389 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] = {
|
||||
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
|
||||
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
|
||||
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
|
||||
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
|
||||
|
||||
static const unsigned int blake2b_sigma[12][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
};
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
|
||||
S->f[1] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
|
||||
if (S->last_node) {
|
||||
blake2b_set_lastnode(S);
|
||||
}
|
||||
S->f[0] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
|
||||
uint64_t inc) {
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
|
||||
secure_wipe_memory(S, sizeof(*S)); /* wipe */
|
||||
blake2b_set_lastblock(S); /* invalidate for further use */
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
|
||||
memset(S, 0, sizeof(*S));
|
||||
memcpy(S->h, blake2b_IV, sizeof(S->h));
|
||||
}
|
||||
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
|
||||
const unsigned char *p = (const unsigned char *)P;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == P || NULL == S) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_init0(S);
|
||||
/* IV XOR Parameter Block */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
|
||||
}
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sequential blake2b initialization */
|
||||
int blake2b_init(blake2b_state *S, size_t outlen) {
|
||||
blake2b_param P;
|
||||
|
||||
if (S == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup Parameter Block for unkeyed BLAKE2 */
|
||||
P.digest_length = (uint8_t)outlen;
|
||||
P.key_length = 0;
|
||||
P.fanout = 1;
|
||||
P.depth = 1;
|
||||
P.leaf_length = 0;
|
||||
P.node_offset = 0;
|
||||
P.node_depth = 0;
|
||||
P.inner_length = 0;
|
||||
memset(P.reserved, 0, sizeof(P.reserved));
|
||||
memset(P.salt, 0, sizeof(P.salt));
|
||||
memset(P.personal, 0, sizeof(P.personal));
|
||||
|
||||
return blake2b_init_param(S, &P);
|
||||
}
|
||||
|
||||
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
|
||||
size_t keylen) {
|
||||
blake2b_param P;
|
||||
|
||||
if (S == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup Parameter Block for keyed BLAKE2 */
|
||||
P.digest_length = (uint8_t)outlen;
|
||||
P.key_length = (uint8_t)keylen;
|
||||
P.fanout = 1;
|
||||
P.depth = 1;
|
||||
P.leaf_length = 0;
|
||||
P.node_offset = 0;
|
||||
P.node_depth = 0;
|
||||
P.inner_length = 0;
|
||||
memset(P.reserved, 0, sizeof(P.reserved));
|
||||
memset(P.salt, 0, sizeof(P.salt));
|
||||
memset(P.personal, 0, sizeof(P.personal));
|
||||
|
||||
if (blake2b_init_param(S, &P) < 0) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset(block, 0, BLAKE2B_BLOCKBYTES);
|
||||
memcpy(block, key, keylen);
|
||||
blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
|
||||
secure_wipe_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
unsigned int i, r;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
m[i] = load64(block + i * sizeof(m[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[8] = blake2b_IV[0];
|
||||
v[9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||
v[13] = blake2b_IV[5] ^ S->t[1];
|
||||
v[14] = blake2b_IV[6] ^ S->f[0];
|
||||
v[15] = blake2b_IV[7] ^ S->f[1];
|
||||
|
||||
#define G(r, i, a, b, c, d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r, 0, v[0], v[4], v[8], v[12]); \
|
||||
G(r, 1, v[1], v[5], v[9], v[13]); \
|
||||
G(r, 2, v[2], v[6], v[10], v[14]); \
|
||||
G(r, 3, v[3], v[7], v[11], v[15]); \
|
||||
G(r, 4, v[0], v[5], v[10], v[15]); \
|
||||
G(r, 5, v[1], v[6], v[11], v[12]); \
|
||||
G(r, 6, v[2], v[7], v[8], v[13]); \
|
||||
G(r, 7, v[3], v[4], v[9], v[14]); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
for (r = 0; r < 12; ++r) {
|
||||
ROUND(r);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
}
|
||||
|
||||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
|
||||
const uint8_t *pin = (const uint8_t *)in;
|
||||
|
||||
if (inlen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
if (S == NULL || in == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is this a reused state? */
|
||||
if (S->f[0] != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
|
||||
/* Complete current block */
|
||||
size_t left = S->buflen;
|
||||
size_t fill = BLAKE2B_BLOCKBYTES - left;
|
||||
memcpy(&S->buf[left], pin, fill);
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf);
|
||||
S->buflen = 0;
|
||||
inlen -= fill;
|
||||
pin += fill;
|
||||
/* Avoid buffer copies when possible */
|
||||
while (inlen > BLAKE2B_BLOCKBYTES) {
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, pin);
|
||||
inlen -= BLAKE2B_BLOCKBYTES;
|
||||
pin += BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy(&S->buf[S->buflen], pin, inlen);
|
||||
S->buflen += (unsigned int)inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
unsigned int i;
|
||||
|
||||
/* Sanity checks */
|
||||
if (S == NULL || out == NULL || outlen < S->outlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is this a reused state? */
|
||||
if (S->f[0] != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_increment_counter(S, S->buflen);
|
||||
blake2b_set_lastblock(S);
|
||||
memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
|
||||
blake2b_compress(S, S->buf);
|
||||
|
||||
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
|
||||
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
|
||||
}
|
||||
|
||||
memcpy(out, buffer, S->outlen);
|
||||
secure_wipe_memory(buffer, sizeof(buffer));
|
||||
secure_wipe_memory(S->buf, sizeof(S->buf));
|
||||
secure_wipe_memory(S->h, sizeof(S->h));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *key, size_t keylen) {
|
||||
blake2b_state S;
|
||||
int ret = -1;
|
||||
|
||||
/* Verify parameters */
|
||||
if (NULL == in && inlen > 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (keylen > 0) {
|
||||
if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if (blake2b_init(&S, outlen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (blake2b_update(&S, in, inlen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
ret = blake2b_final(&S, out, outlen);
|
||||
|
||||
fail:
|
||||
secure_wipe_memory(&S, sizeof(S));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
|
||||
uint8_t *out = (uint8_t *)pout;
|
||||
blake2b_state blake_state;
|
||||
uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
|
||||
int ret = -1;
|
||||
|
||||
if (outlen > UINT32_MAX) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Ensure little-endian byte order! */
|
||||
store32(outlen_bytes, (uint32_t)outlen);
|
||||
|
||||
#define TRY(statement) \
|
||||
do { \
|
||||
ret = statement; \
|
||||
if (ret < 0) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
|
||||
if (outlen <= BLAKE2B_OUTBYTES) {
|
||||
TRY(blake2b_init(&blake_state, outlen));
|
||||
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
|
||||
TRY(blake2b_update(&blake_state, in, inlen));
|
||||
TRY(blake2b_final(&blake_state, out, outlen));
|
||||
} else {
|
||||
uint32_t toproduce;
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
|
||||
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
|
||||
TRY(blake2b_update(&blake_state, in, inlen));
|
||||
TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
|
||||
|
||||
while (toproduce > BLAKE2B_OUTBYTES) {
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
|
||||
BLAKE2B_OUTBYTES, NULL, 0));
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
|
||||
0));
|
||||
memcpy(out, out_buffer, toproduce);
|
||||
}
|
||||
fail:
|
||||
secure_wipe_memory(&blake_state, sizeof(blake_state));
|
||||
return ret;
|
||||
#undef TRY
|
||||
}
|
||||
/* Argon2 Team - End Code */
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef BLAKE_ROUND_MKA_OPT_H
|
||||
#define BLAKE_ROUND_MKA_OPT_H
|
||||
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#include <emmintrin.h>
|
||||
#if defined(__SSSE3__)
|
||||
#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
|
||||
#endif
|
||||
|
||||
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__XOP__)
|
||||
#if defined(__SSSE3__)
|
||||
#define r16 \
|
||||
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 \
|
||||
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
#else /* defined(__SSE2__) */
|
||||
#define _mm_roti_epi64(r, c) \
|
||||
_mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c))))
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
|
||||
const __m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -32); \
|
||||
D1 = _mm_roti_epi64(D1, -32); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -24); \
|
||||
B1 = _mm_roti_epi64(B1, -24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -16); \
|
||||
D1 = _mm_roti_epi64(D1, -16); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -63); \
|
||||
B1 = _mm_roti_epi64(B1, -63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
#else /* SSE2 */
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = D0; \
|
||||
__m128i t1 = B0; \
|
||||
D0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = D0; \
|
||||
D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
|
||||
D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0, t1; \
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
t0 = B0; \
|
||||
t1 = D0; \
|
||||
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
|
||||
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
#endif
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef BLAKE_ROUND_MKA_H
|
||||
#define BLAKE_ROUND_MKA_H
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
/*designed by the Lyra PHC team */
|
||||
static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) {
|
||||
const uint64_t m = UINT64_C(0xFFFFFFFF);
|
||||
const uint64_t xy = (x & m) * (y & m);
|
||||
return x + y + 2 * xy;
|
||||
}
|
||||
|
||||
#define G(a, b, c, d) \
|
||||
do { \
|
||||
a = fBlaMka(a, b); \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = fBlaMka(a, b); \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
|
||||
v12, v13, v14, v15) \
|
||||
do { \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#endif
|
||||
@@ -1,610 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
/*For memory wiping*/
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* For SecureZeroMemory */
|
||||
#endif
|
||||
#if defined __STDC_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#define VC_GE_2005(version) (version >= 1400)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "thread.h"
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
#ifdef GENKAT
|
||||
#include "genkat.h"
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_attribute(optnone)
|
||||
#define NOT_OPTIMIZED __attribute__((optnone))
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION >= 40400
|
||||
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NOT_OPTIMIZED
|
||||
#define NOT_OPTIMIZED
|
||||
#endif
|
||||
|
||||
/***************Instance and Position constructors**********/
|
||||
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void xor_block(block *dst, const block *src) {
|
||||
int i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_block(block *dst, const void *input) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void store_block(void *output, const block *src) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************Memory allocators*****************/
|
||||
int allocate_memory(block **memory, uint32_t m_cost) {
|
||||
if (memory != NULL) {
|
||||
size_t memory_size = sizeof(block) * m_cost;
|
||||
if (m_cost != 0 &&
|
||||
memory_size / m_cost !=
|
||||
sizeof(block)) { /*1. Check for multiplication overflow*/
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
*memory = (block *)malloc(memory_size); /*2. Try to allocate*/
|
||||
|
||||
if (!*memory) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return ARGON2_OK;
|
||||
} else {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
|
||||
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
|
||||
SecureZeroMemory(v, n);
|
||||
#elif defined memset_s
|
||||
memset_s(v, n, 0, n);
|
||||
#elif defined(__OpenBSD__)
|
||||
explicit_bzero(v, n);
|
||||
#else
|
||||
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
|
||||
memset_sec(v, 0, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********Memory functions*/
|
||||
|
||||
void clear_memory(argon2_instance_t *instance, int clear) {
|
||||
if (instance->memory != NULL && clear) {
|
||||
secure_wipe_memory(instance->memory,
|
||||
sizeof(block) * instance->memory_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
void free_memory(block *memory) { free(memory); }
|
||||
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance) {
|
||||
if (context != NULL && instance != NULL) {
|
||||
block blockhash;
|
||||
uint32_t l;
|
||||
|
||||
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
|
||||
|
||||
/* XOR the last blocks */
|
||||
for (l = 1; l < instance->lanes; ++l) {
|
||||
uint32_t last_block_in_lane =
|
||||
l * instance->lane_length + (instance->lane_length - 1);
|
||||
xor_block(&blockhash, instance->memory + last_block_in_lane);
|
||||
}
|
||||
|
||||
/* Hash the result */
|
||||
{
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
store_block(blockhash_bytes, &blockhash);
|
||||
blake2b_long(context->out, context->outlen, blockhash_bytes,
|
||||
ARGON2_BLOCK_SIZE);
|
||||
secure_wipe_memory(blockhash.v,
|
||||
ARGON2_BLOCK_SIZE); /* clear blockhash */
|
||||
secure_wipe_memory(blockhash_bytes,
|
||||
ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
|
||||
}
|
||||
|
||||
#ifdef GENKAT
|
||||
print_tag(context->out, context->outlen);
|
||||
#endif
|
||||
|
||||
/* Clear memory */
|
||||
clear_memory(instance, context->flags & ARGON2_FLAG_CLEAR_PASSWORD);
|
||||
|
||||
/* Deallocate the memory */
|
||||
if (NULL != context->free_cbk) {
|
||||
context->free_cbk((uint8_t *)instance->memory,
|
||||
instance->memory_blocks * sizeof(block));
|
||||
} else {
|
||||
free_memory(instance->memory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane) {
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
uint64_t relative_position;
|
||||
uint32_t start_position, absolute_position;
|
||||
|
||||
if (0 == position->pass) {
|
||||
/* First pass */
|
||||
if (0 == position->slice) {
|
||||
/* First slice */
|
||||
reference_area_size =
|
||||
position->index - 1; /* all but the previous */
|
||||
} else {
|
||||
if (same_lane) {
|
||||
/* The same lane => add current segment */
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
position->index - 1;
|
||||
} else {
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Second pass */
|
||||
if (same_lane) {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length + position->index -
|
||||
1;
|
||||
} else {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
|
||||
* relative position */
|
||||
relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position = reference_area_size - 1 -
|
||||
(reference_area_size * relative_position >> 32);
|
||||
|
||||
/* 1.2.5 Computing starting position */
|
||||
start_position = 0;
|
||||
|
||||
if (0 != position->pass) {
|
||||
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
|
||||
? 0
|
||||
: (position->slice + 1) * instance->segment_length;
|
||||
}
|
||||
|
||||
/* 1.2.6. Computing absolute position */
|
||||
absolute_position = (start_position + relative_position) %
|
||||
instance->lane_length; /* absolute position */
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static unsigned __stdcall fill_segment_thr(void *thread_data)
|
||||
#else
|
||||
static void *fill_segment_thr(void *thread_data)
|
||||
#endif
|
||||
{
|
||||
argon2_thread_data *my_data = (argon2_thread_data *)thread_data;
|
||||
fill_segment(my_data->instance_ptr, my_data->pos);
|
||||
argon2_thread_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
uint32_t r, s;
|
||||
argon2_thread_handle_t *thread = NULL;
|
||||
argon2_thread_data *thr_data = NULL;
|
||||
int rc = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || instance->lanes == 0) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 1. Allocating space for threads */
|
||||
thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
|
||||
if (thread == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
|
||||
if (thr_data == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (r = 0; r < instance->passes; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
uint32_t l;
|
||||
|
||||
/* 2. Calling threads */
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position;
|
||||
|
||||
/* 2.1 Join a thread if limit is exceeded */
|
||||
if (l >= instance->threads) {
|
||||
if (argon2_thread_join(thread[l - instance->threads])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2.2 Create thread */
|
||||
position.pass = r;
|
||||
position.lane = l;
|
||||
position.slice = (uint8_t)s;
|
||||
position.index = 0;
|
||||
thr_data[l].instance_ptr =
|
||||
instance; /* preparing the thread input */
|
||||
memcpy(&(thr_data[l].pos), &position,
|
||||
sizeof(argon2_position_t));
|
||||
if (argon2_thread_create(&thread[l], &fill_segment_thr,
|
||||
(void *)&thr_data[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* fill_segment(instance, position); */
|
||||
/*Non-thread equivalent of the lines above */
|
||||
}
|
||||
|
||||
/* 3. Joining remaining threads */
|
||||
for (l = instance->lanes - instance->threads; l < instance->lanes;
|
||||
++l) {
|
||||
if (argon2_thread_join(thread[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GENKAT
|
||||
internal_kat(instance, r); /* Print all memory blocks */
|
||||
#endif
|
||||
}
|
||||
|
||||
fail:
|
||||
if (thread != NULL) {
|
||||
free(thread);
|
||||
}
|
||||
if (thr_data != NULL) {
|
||||
free(thr_data);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int validate_inputs(const argon2_context *context) {
|
||||
if (NULL == context) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
|
||||
if (NULL == context->out) {
|
||||
return ARGON2_OUTPUT_PTR_NULL;
|
||||
}
|
||||
|
||||
/* Validate output length */
|
||||
if (ARGON2_MIN_OUTLEN > context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_OUTLEN < context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate password length */
|
||||
if (NULL == context->pwd) {
|
||||
if (0 != context->pwdlen) {
|
||||
return ARGON2_PWD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate salt length */
|
||||
if (NULL == context->salt) {
|
||||
if (0 != context->saltlen) {
|
||||
return ARGON2_SALT_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
|
||||
return ARGON2_SALT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate secret length */
|
||||
if (NULL == context->secret) {
|
||||
if (0 != context->secretlen) {
|
||||
return ARGON2_SECRET_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SECRET > context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_SECRET < context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate associated data */
|
||||
if (NULL == context->ad) {
|
||||
if (0 != context->adlen) {
|
||||
return ARGON2_AD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_AD_LENGTH > context->adlen) {
|
||||
return ARGON2_AD_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_AD_LENGTH < context->adlen) {
|
||||
return ARGON2_AD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate memory cost */
|
||||
if (ARGON2_MIN_MEMORY > context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_MEMORY < context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_MUCH;
|
||||
}
|
||||
|
||||
if (context->m_cost < 8 * context->lanes) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Validate time cost */
|
||||
if (ARGON2_MIN_TIME > context->t_cost) {
|
||||
return ARGON2_TIME_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_TIME < context->t_cost) {
|
||||
return ARGON2_TIME_TOO_LARGE;
|
||||
}
|
||||
|
||||
/* Validate lanes */
|
||||
if (ARGON2_MIN_LANES > context->lanes) {
|
||||
return ARGON2_LANES_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_LANES < context->lanes) {
|
||||
return ARGON2_LANES_TOO_MANY;
|
||||
}
|
||||
|
||||
/* Validate threads */
|
||||
if (ARGON2_MIN_THREADS > context->threads) {
|
||||
return ARGON2_THREADS_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_THREADS < context->threads) {
|
||||
return ARGON2_THREADS_TOO_MANY;
|
||||
}
|
||||
|
||||
if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
|
||||
return ARGON2_FREE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
|
||||
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
uint32_t l;
|
||||
/* Make the first and second block in each lane as G(H0||i||0) or
|
||||
G(H0||i||1) */
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 0],
|
||||
blockhash_bytes);
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 1],
|
||||
blockhash_bytes);
|
||||
}
|
||||
secure_wipe_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type) {
|
||||
blake2b_state BlakeHash;
|
||||
uint8_t value[sizeof(uint32_t)];
|
||||
|
||||
if (NULL == context || NULL == blockhash) {
|
||||
return;
|
||||
}
|
||||
|
||||
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
store32(&value, context->lanes);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->outlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->m_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->t_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->version);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, (uint32_t)type);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->pwdlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->pwd != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
|
||||
context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
secure_wipe_memory(context->pwd, context->pwdlen);
|
||||
context->pwdlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->saltlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->salt != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
context->saltlen);
|
||||
}
|
||||
|
||||
store32(&value, context->secretlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->secret != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
|
||||
context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
secure_wipe_memory(context->secret, context->secretlen);
|
||||
context->secretlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->adlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->ad != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
|
||||
context->adlen);
|
||||
}
|
||||
|
||||
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context) {
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || context == NULL)
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
|
||||
/* 1. Memory allocation */
|
||||
|
||||
if (NULL != context->allocate_cbk) {
|
||||
uint8_t *p;
|
||||
result = context->allocate_cbk(&p, instance->memory_blocks *
|
||||
ARGON2_BLOCK_SIZE);
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
instance->memory = (block *)p;
|
||||
} else {
|
||||
result = allocate_memory(&(instance->memory), instance->memory_blocks);
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. Initial hashing */
|
||||
/* H_0 + 8 extra bytes to produce the first blocks */
|
||||
/* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
|
||||
/* Hashing all inputs */
|
||||
initial_hash(blockhash, context, instance->type);
|
||||
/* Zeroing 8 extra bytes */
|
||||
secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
|
||||
ARGON2_PREHASH_SEED_LENGTH -
|
||||
ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
#ifdef GENKAT
|
||||
initial_kat(blockhash, context, instance->type);
|
||||
#endif
|
||||
|
||||
/* 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
*/
|
||||
fill_first_blocks(blockhash, instance);
|
||||
/* Clearing the hash */
|
||||
secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_CORE_H
|
||||
#define ARGON2_CORE_H
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(n) __declspec(align(16))
|
||||
#elif defined(__GNUC__) || defined(__clang)
|
||||
#define ALIGN(x) __attribute__((__aligned__(x)))
|
||||
#else
|
||||
#define ALIGN(x)
|
||||
#endif
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
/*************************Argon2 internal
|
||||
* constants**************************************************/
|
||||
|
||||
enum argon2_core_constants {
|
||||
/* Memory block size in bytes */
|
||||
ARGON2_BLOCK_SIZE = 1024,
|
||||
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
||||
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
|
||||
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i
|
||||
to
|
||||
generate reference block positions */
|
||||
ARGON2_ADDRESSES_IN_BLOCK = 128,
|
||||
|
||||
/* Pre-hashing digest length and its extension*/
|
||||
ARGON2_PREHASH_DIGEST_LENGTH = 64,
|
||||
ARGON2_PREHASH_SEED_LENGTH = 72
|
||||
};
|
||||
|
||||
/*************************Argon2 internal data
|
||||
* types**************************************************/
|
||||
|
||||
/*
|
||||
* Structure for the (1KB) memory block implemented as 128 64-bit words.
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
||||
* bounds checking).
|
||||
*/
|
||||
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
|
||||
|
||||
/*****************Functions that work with the block******************/
|
||||
|
||||
/* Initialize each byte of the block with @in */
|
||||
void init_block_value(block *b, uint8_t in);
|
||||
|
||||
/* Copy block @src to block @dst */
|
||||
void copy_block(block *dst, const block *src);
|
||||
|
||||
/* XOR @src onto @dst bytewise */
|
||||
void xor_block(block *dst, const block *src);
|
||||
|
||||
/*
|
||||
* Argon2 instance: memory pointer, number of passes, amount of memory, type,
|
||||
* and derived values.
|
||||
* Used to evaluate the number and location of blocks to construct in each
|
||||
* thread
|
||||
*/
|
||||
typedef struct Argon2_instance_t {
|
||||
block *memory; /* Memory pointer */
|
||||
uint32_t version;
|
||||
uint32_t passes; /* Number of passes */
|
||||
uint32_t memory_blocks; /* Number of blocks in memory */
|
||||
uint32_t segment_length;
|
||||
uint32_t lane_length;
|
||||
uint32_t lanes;
|
||||
uint32_t threads;
|
||||
argon2_type type;
|
||||
int print_internals; /* whether to print the memory blocks */
|
||||
} argon2_instance_t;
|
||||
|
||||
/*
|
||||
* Argon2 position: where we construct the block right now. Used to distribute
|
||||
* work between threads.
|
||||
*/
|
||||
typedef struct Argon2_position_t {
|
||||
uint32_t pass;
|
||||
uint32_t lane;
|
||||
uint8_t slice;
|
||||
uint32_t index;
|
||||
} argon2_position_t;
|
||||
|
||||
/*Struct that holds the inputs for thread handling FillSegment*/
|
||||
typedef struct Argon2_thread_data {
|
||||
argon2_instance_t *instance_ptr;
|
||||
argon2_position_t pos;
|
||||
} argon2_thread_data;
|
||||
|
||||
/*************************Argon2 core
|
||||
* functions**************************************************/
|
||||
|
||||
/* Allocates memory to the given pointer
|
||||
* @param memory pointer to the pointer to the memory
|
||||
* @param m_cost number of blocks to allocate in the memory
|
||||
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
|
||||
*/
|
||||
int allocate_memory(block **memory, uint32_t m_cost);
|
||||
|
||||
/* Function that securely cleans the memory
|
||||
* @param mem Pointer to the memory
|
||||
* @param s Memory size in bytes
|
||||
*/
|
||||
void secure_wipe_memory(void *v, size_t n);
|
||||
|
||||
/* Clears memory
|
||||
* @param instance pointer to the current instance
|
||||
* @param clear_memory indicates if we clear the memory with zeros.
|
||||
*/
|
||||
void clear_memory(argon2_instance_t *instance, int clear);
|
||||
|
||||
/* Deallocates memory
|
||||
* @param memory pointer to the blocks
|
||||
*/
|
||||
void free_memory(block *memory);
|
||||
|
||||
/*
|
||||
* Computes absolute position of reference block in the lane following a skewed
|
||||
* distribution and using a pseudo-random value as input
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
|
||||
* @param same_lane Indicates if the block will be taken from the current lane.
|
||||
* If so we can reference the current segment
|
||||
* @pre All pointers must be valid
|
||||
*/
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane);
|
||||
|
||||
/*
|
||||
* Function that validates all inputs against predefined restrictions and return
|
||||
* an error code
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return ARGON2_OK if everything is all right, otherwise one of error codes
|
||||
* (all defined in <argon2.h>
|
||||
*/
|
||||
int validate_inputs(const argon2_context *context);
|
||||
|
||||
/*
|
||||
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
|
||||
* password and secret if needed
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param blockhash Buffer for pre-hashing digest
|
||||
* @param type Argon2 type
|
||||
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
|
||||
* allocated
|
||||
*/
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Function creates first 2 blocks per lane
|
||||
* @param instance Pointer to the current instance
|
||||
* @param blockhash Pointer to the pre-hashing digest
|
||||
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
|
||||
*/
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function allocates memory, hashes the inputs with Blake, and creates first
|
||||
* two blocks. Returns the pointer to the main memory with 2 blocks per lane
|
||||
* initialized
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param instance Current Argon2 instance
|
||||
* @return Zero if successful, -1 if memory failed to allocate. @context->state
|
||||
* will be modified if successful.
|
||||
*/
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context);
|
||||
|
||||
/*
|
||||
* XORing the last block of each lane, hashing it, making the tag. Deallocates
|
||||
* the memory.
|
||||
* @param context Pointer to current Argon2 context (use only the out parameters
|
||||
* from it)
|
||||
* @param instance Pointer to current instance of Argon2
|
||||
* @pre instance->state must point to necessary amount of memory
|
||||
* @pre context->out must point to outlen bytes of memory
|
||||
* @pre if context->free_cbk is not NULL, it should point to a function that
|
||||
* deallocates memory
|
||||
*/
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
/*
|
||||
* Function that fills the entire memory t_cost times based on the first two
|
||||
* blocks in each lane
|
||||
* @param instance Pointer to the current instance
|
||||
* @return ARGON2_OK if successful, @context->state
|
||||
*/
|
||||
int fill_memory_blocks(argon2_instance_t *instance);
|
||||
|
||||
#endif
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* Example code for a decoder and encoder of "hash strings", with Argon2
|
||||
* parameters.
|
||||
*
|
||||
* This code comprises three sections:
|
||||
*
|
||||
* -- The first section contains generic Base64 encoding and decoding
|
||||
* functions. It is conceptually applicable to any hash function
|
||||
* implementation that uses Base64 to encode and decode parameters,
|
||||
* salts and outputs. It could be made into a library, provided that
|
||||
* the relevant functions are made public (non-static) and be given
|
||||
* reasonable names to avoid collisions with other functions.
|
||||
*
|
||||
* -- The second section is specific to Argon2. It encodes and decodes
|
||||
* the parameters, salts and outputs. It does not compute the hash
|
||||
* itself.
|
||||
*
|
||||
* -- The third section is test code, with a main() function. With
|
||||
* this section, the whole file compiles as a stand-alone program
|
||||
* that exercises the encoding and decoding functions with some
|
||||
* test vectors.
|
||||
*
|
||||
* The code was originally written by Thomas Pornin <pornin@bolet.org>,
|
||||
* to whom comments and remarks may be sent. It is released under what
|
||||
* should amount to Public Domain or its closest equivalent; the
|
||||
* following mantra is supposed to incarnate that fact with all the
|
||||
* proper legal rituals:
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
* This file is provided under the terms of Creative Commons CC0 1.0
|
||||
* Public Domain Dedication. To the extent possible under law, the
|
||||
* author (Thomas Pornin) has waived all copyright and related or
|
||||
* neighboring rights to this file. This work is published from: Canada.
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2015 Thomas Pornin
|
||||
*/
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Common code; could be shared between different hash functions.
|
||||
*
|
||||
* Note: the Base64 functions below assume that uppercase letters (resp.
|
||||
* lowercase letters) have consecutive numerical codes, that fit on 8
|
||||
* bits. All modern systems use ASCII-compatible charsets, where these
|
||||
* properties are true. If you are stuck with a dinosaur of a system
|
||||
* that still defaults to EBCDIC then you already have much bigger
|
||||
* interoperability issues to deal with.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert character c to the corresponding 6-bit value. If character c
|
||||
* is not a Base64 character, then 0xFF (255) is returned.
|
||||
*/
|
||||
static unsigned b64_char_to_byte(int c) {
|
||||
unsigned x;
|
||||
|
||||
x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
|
||||
(GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
|
||||
(GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
|
||||
(EQ(c, '/') & 63);
|
||||
return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
|
||||
* of the output buffer 'dst'; if that buffer is not large enough to
|
||||
* receive the result (including the terminating 0), then (size_t)-1
|
||||
* is returned. Otherwise, the zero-terminated Base64 string is written
|
||||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
size_t src_len) {
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode Base64 chars into bytes. The '*dst_len' value must initially
|
||||
* contain the length of the output buffer '*dst'; when the decoding
|
||||
* ends, the actual number of decoded bytes is written back in
|
||||
* '*dst_len'.
|
||||
*
|
||||
* Decoding stops when a non-Base64 character is encountered, or when
|
||||
* the output buffer capacity is exceeded. If an error occurred (output
|
||||
* buffer is too small, invalid last characters leading to unprocessed
|
||||
* buffered bits), then NULL is returned; otherwise, the returned value
|
||||
* points to the first non-Base64 character in the source stream, which
|
||||
* may be the terminating zero.
|
||||
*/
|
||||
static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
buf = (unsigned char *)dst;
|
||||
len = 0;
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
for (;;) {
|
||||
unsigned d;
|
||||
|
||||
d = b64_char_to_byte(*src);
|
||||
if (d == 0xFF) {
|
||||
break;
|
||||
}
|
||||
src++;
|
||||
acc = (acc << 6) + d;
|
||||
acc_len += 6;
|
||||
if (acc_len >= 8) {
|
||||
acc_len -= 8;
|
||||
if ((len++) >= *dst_len) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (acc >> acc_len) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the input length is equal to 1 modulo 4 (which is
|
||||
* invalid), then there will remain 6 unprocessed bits;
|
||||
* otherwise, only 0, 2 or 4 bits are buffered. The buffered
|
||||
* bits must also all be zero.
|
||||
*/
|
||||
if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
*dst_len = len;
|
||||
return src;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode decimal integer from 'str'; the value is written in '*v'.
|
||||
* Returned value is a pointer to the next non-decimal character in the
|
||||
* string. If there is no digit at all, or the value encoding is not
|
||||
* minimal (extra leading zeros), or the value does not fit in an
|
||||
* 'unsigned long', then NULL is returned.
|
||||
*/
|
||||
static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
const char *orig;
|
||||
unsigned long acc;
|
||||
|
||||
acc = 0;
|
||||
for (orig = str;; str++) {
|
||||
int c;
|
||||
|
||||
c = *str;
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
c -= '0';
|
||||
if (acc > (ULONG_MAX / 10)) {
|
||||
return NULL;
|
||||
}
|
||||
acc *= 10;
|
||||
if ((unsigned long)c > (ULONG_MAX - acc)) {
|
||||
return NULL;
|
||||
}
|
||||
acc += (unsigned long)c;
|
||||
}
|
||||
if (str == orig || (*orig == '0' && str != (orig + 1))) {
|
||||
return NULL;
|
||||
}
|
||||
*v = acc;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2.
|
||||
*
|
||||
* The code below applies the following format:
|
||||
*
|
||||
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
|
||||
*
|
||||
* where <T> is either 'd' or 'i', <num> is a decimal integer (positive, fits in
|
||||
* an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
|
||||
* characters, no newline or whitespace).
|
||||
* The "keyid" is a binary identifier for a key (up to 8 bytes);
|
||||
* "data" is associated data (up to 32 bytes). When the 'keyid'
|
||||
* (resp. the 'data') is empty, then it is ommitted from the output.
|
||||
*
|
||||
* The last two binary chunks (encoded in Base64) are, in that order,
|
||||
* the salt and the output. Both are optional, but you cannot have an
|
||||
* output without a salt. The binary salt length is between 8 and 48 bytes.
|
||||
* The output length is always exactly 32 bytes.
|
||||
*/
|
||||
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
|
||||
/* check for prefix */
|
||||
#define CC(prefix) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) != 0) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
str += cc_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* prefix checking with supplied code */
|
||||
#define CC_opt(prefix, code) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) == 0) { \
|
||||
str += cc_len; \
|
||||
{ code; } \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* Decoding prefix into decimal */
|
||||
#define DECIMAL(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = dec_x; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BIN(buf, max_len, len) \
|
||||
do { \
|
||||
size_t bin_len = (max_len); \
|
||||
str = from_base64(buf, &bin_len, str); \
|
||||
if (str == NULL || bin_len > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(len) = (uint32_t)bin_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
size_t maxadlen = ctx->adlen;
|
||||
size_t maxsaltlen = ctx->saltlen;
|
||||
size_t maxoutlen = ctx->outlen;
|
||||
int validation_result;
|
||||
const char* type_string;
|
||||
|
||||
ctx->adlen = 0;
|
||||
ctx->saltlen = 0;
|
||||
ctx->outlen = 0;
|
||||
ctx->pwdlen = 0;
|
||||
|
||||
/* We should start with the argon2_type we are using */
|
||||
CC("$");
|
||||
type_string = argon2_type2string(type, 0);
|
||||
if (type_string) {
|
||||
CC(type_string);
|
||||
} else {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
/* Reading the version number if the default is suppressed */
|
||||
ctx->version = ARGON2_VERSION_10;
|
||||
CC_opt("$v=", DECIMAL(ctx->version));
|
||||
|
||||
CC("$m=");
|
||||
DECIMAL(ctx->m_cost);
|
||||
CC(",t=");
|
||||
DECIMAL(ctx->t_cost);
|
||||
CC(",p=");
|
||||
DECIMAL(ctx->lanes);
|
||||
ctx->threads = ctx->lanes;
|
||||
|
||||
CC_opt(",data=", BIN(ctx->ad, maxadlen, ctx->adlen));
|
||||
if (*str == 0) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
CC("$");
|
||||
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
|
||||
if (*str == 0) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
CC("$");
|
||||
BIN(ctx->out, maxoutlen, ctx->outlen);
|
||||
validation_result = validate_inputs(ctx);
|
||||
if (validation_result != ARGON2_OK) {
|
||||
return validation_result;
|
||||
}
|
||||
if (*str == 0) {
|
||||
return ARGON2_OK;
|
||||
} else {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
#undef CC
|
||||
#undef CC_opt
|
||||
#undef DECIMAL
|
||||
#undef BIN
|
||||
}
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
const char* type_string = argon2_type2string(type, 0);
|
||||
SS("$");
|
||||
if (type_string) {
|
||||
SS(type_string);
|
||||
} else {
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
|
||||
if (validate_inputs(ctx) != ARGON2_OK) {
|
||||
return validate_inputs(ctx);
|
||||
}
|
||||
|
||||
SS("$v=");
|
||||
SX(ctx->version);
|
||||
SS("$m=");
|
||||
SX(ctx->m_cost);
|
||||
SS(",t=");
|
||||
SX(ctx->t_cost);
|
||||
SS(",p=");
|
||||
SX(ctx->lanes);
|
||||
|
||||
if (ctx->adlen > 0) {
|
||||
SS(",data=");
|
||||
SB(ctx->ad, ctx->adlen);
|
||||
}
|
||||
|
||||
if (ctx->saltlen == 0)
|
||||
return ARGON2_OK;
|
||||
|
||||
SS("$");
|
||||
SB(ctx->salt, ctx->saltlen);
|
||||
|
||||
if (ctx->outlen == 0)
|
||||
return ARGON2_OK;
|
||||
|
||||
SS("$");
|
||||
SB(ctx->out, ctx->outlen);
|
||||
return ARGON2_OK;
|
||||
|
||||
#undef SS
|
||||
#undef SX
|
||||
#undef SB
|
||||
}
|
||||
|
||||
size_t b64len(uint32_t len) {
|
||||
size_t olen = ((size_t)len / 3) << 2;
|
||||
|
||||
switch (len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return olen;
|
||||
}
|
||||
|
||||
size_t numlen(uint32_t num) {
|
||||
size_t len = 1;
|
||||
while (num >= 10) {
|
||||
++len;
|
||||
num = num / 10;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ENCODING_H
|
||||
#define ENCODING_H
|
||||
#include "argon2.h"
|
||||
|
||||
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
|
||||
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
|
||||
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
|
||||
|
||||
/*
|
||||
* encode an Argon2 hash string into the provided buffer. 'dst_len'
|
||||
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
||||
* is less than the number of required characters (including the
|
||||
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
|
||||
*
|
||||
* if ctx->outlen is 0, then the hash string will be a salt string
|
||||
* (no output). if ctx->saltlen is also 0, then the string will be a
|
||||
* parameter-only string (no salt and no output).
|
||||
*
|
||||
* on success, ARGON2_OK is returned.
|
||||
*
|
||||
* No other parameters are checked
|
||||
*/
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
||||
* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out
|
||||
* length values that are allowed; invalid input string causes an error.
|
||||
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
|
||||
*/
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
||||
|
||||
/* Returns the length of the encoded byte stream with length len */
|
||||
size_t b64len(uint32_t len);
|
||||
|
||||
/* Returns the length of the encoded number num */
|
||||
size_t numlen(uint32_t num);
|
||||
|
||||
#endif
|
||||
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "opt.h"
|
||||
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blamka-round-opt.h"
|
||||
|
||||
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
|
||||
uint8_t *next_block) {
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
||||
block_XY[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i])));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block address_block, input_block, tmp_block;
|
||||
uint32_t i;
|
||||
|
||||
init_block_value(&address_block, 0);
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
if (instance != NULL && position != NULL) {
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
|
||||
for (i = 0; i < instance->segment_length; ++i) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
/*Temporary zero-initialized blocks*/
|
||||
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
memset(zero_block, 0, sizeof(zero_block));
|
||||
memset(zero2_block, 0, sizeof(zero2_block));
|
||||
init_block_value(&address_block, 0);
|
||||
init_block_value(&tmp_block, 0);
|
||||
/*Increasing index counter*/
|
||||
input_block.v[6]++;
|
||||
/*First iteration of G*/
|
||||
fill_block_with_xor(zero_block, (uint8_t *)&input_block.v,
|
||||
(uint8_t *)&tmp_block.v);
|
||||
/*Second iteration of G*/
|
||||
fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v,
|
||||
(uint8_t *)&address_block.v);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position) {
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index, i;
|
||||
__m128i state[64];
|
||||
int data_independent_addressing;
|
||||
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
uint64_t *pseudo_rands = NULL;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing =
|
||||
(instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
if (pseudo_rands == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
if (ARGON2_VERSION_10 == instance->version) {
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
fill_block(state, (uint8_t *)ref_block->v,
|
||||
(uint8_t *)curr_block->v);
|
||||
} else {
|
||||
if(0 == position.pass) {
|
||||
fill_block(state, (uint8_t *)ref_block->v,
|
||||
(uint8_t *)curr_block->v);
|
||||
} else {
|
||||
fill_block_with_xor(state, (uint8_t *)ref_block->v,
|
||||
(uint8_t *)curr_block->v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_OPT_H
|
||||
#define ARGON2_OPT_H
|
||||
|
||||
#include "core.h"
|
||||
#include <emmintrin.h>
|
||||
|
||||
/*
|
||||
* Function fills a new memory block by XORing the new block over the old one. Memory must be initialized.
|
||||
* After finishing, @state is identical to @next_block
|
||||
* @param state Pointer to the just produced block. Content will be updated(!)
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
||||
|
||||
/* LEGACY CODE: version 1.2.1 and earlier
|
||||
* Function fills a new memory block by overwriting @next_block.
|
||||
* @param state Pointer to the just produced block. Content will be updated(!)
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
||||
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
#endif /* ARGON2_OPT_H */
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "ref.h"
|
||||
|
||||
#include "blake2/blamka-round-ref.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
#include "blake2/blake2.h"
|
||||
|
||||
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR, block_tmp;
|
||||
unsigned i;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
copy_block(&block_tmp, &blockR);
|
||||
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block */
|
||||
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
(16,17,..31)... finally (112,113,...127) */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
|
||||
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
|
||||
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
|
||||
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
||||
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
|
||||
blockR.v[16 * i + 15]);
|
||||
}
|
||||
|
||||
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
||||
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
|
||||
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
|
||||
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
|
||||
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
||||
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
|
||||
blockR.v[2 * i + 113]);
|
||||
}
|
||||
|
||||
copy_block(next_block, &block_tmp);
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
|
||||
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR, block_tmp;
|
||||
unsigned i;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
copy_block(&block_tmp, &blockR);
|
||||
xor_block(&block_tmp, next_block); /*Saving the next block contents for XOR over*/
|
||||
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block*/
|
||||
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
(16,17,..31)... finally (112,113,...127) */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
|
||||
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
|
||||
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
|
||||
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
||||
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
|
||||
blockR.v[16 * i + 15]);
|
||||
}
|
||||
|
||||
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
||||
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
|
||||
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
|
||||
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
|
||||
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
||||
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
|
||||
blockR.v[2 * i + 113]);
|
||||
}
|
||||
|
||||
copy_block(next_block, &block_tmp);
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block zero_block, input_block, address_block,tmp_block;
|
||||
uint32_t i;
|
||||
|
||||
init_block_value(&zero_block, 0);
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
if (instance != NULL && position != NULL) {
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
|
||||
for (i = 0; i < instance->segment_length; ++i) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
input_block.v[6]++;
|
||||
init_block_value(&tmp_block, 0);
|
||||
init_block_value(&address_block, 0);
|
||||
fill_block_with_xor(&zero_block, &input_block, &tmp_block);
|
||||
fill_block_with_xor(&zero_block, &tmp_block, &address_block);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position) {
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index;
|
||||
uint32_t i;
|
||||
int data_independent_addressing;
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
uint64_t *pseudo_rands = NULL;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing =
|
||||
(instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
|
||||
|
||||
if (pseudo_rands == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
if (ARGON2_VERSION_10 == instance->version) {
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
fill_block(instance->memory + prev_offset, ref_block, curr_block);
|
||||
} else {
|
||||
if(0 == position.pass) {
|
||||
fill_block(instance->memory + prev_offset, ref_block,
|
||||
curr_block);
|
||||
} else {
|
||||
fill_block_with_xor(instance->memory + prev_offset, ref_block,
|
||||
curr_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_REF_H
|
||||
#define ARGON2_REF_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* Function fills a new memory block by XORing over @next_block. @next_block must be initialized
|
||||
* @param prev_block Pointer to the previous block
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
||||
block *next_block);
|
||||
|
||||
/* LEGACY CODE: version 1.2.1 and earlier
|
||||
* Function fills a new memory block by overwriting @next_block.
|
||||
* @param prev_block Pointer to the previous block
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block);
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
#endif /* ARGON2_REF_H */
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args) {
|
||||
if (NULL == handle || func == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
*handle = _beginthreadex(NULL, 0, func, args, 0, NULL);
|
||||
return *handle != 0 ? 0 : -1;
|
||||
#else
|
||||
return pthread_create(handle, NULL, func, args);
|
||||
#endif
|
||||
}
|
||||
|
||||
int argon2_thread_join(argon2_thread_handle_t handle) {
|
||||
#if defined(_WIN32)
|
||||
if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) {
|
||||
return CloseHandle((HANDLE)handle) != 0 ? 0 : -1;
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
return pthread_join(handle, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void argon2_thread_exit(void) {
|
||||
#if defined(_WIN32)
|
||||
_endthreadex(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_THREAD_H
|
||||
#define ARGON2_THREAD_H
|
||||
/*
|
||||
Here we implement an abstraction layer for the simpĺe requirements
|
||||
of the Argon2 code. We only require 3 primitives---thread creation,
|
||||
joining, and termination---so full emulation of the pthreads API
|
||||
is unwarranted. Currently we wrap pthreads and Win32 threads.
|
||||
|
||||
The API defines 2 types: the function pointer type,
|
||||
argon2_thread_func_t,
|
||||
and the type of the thread handle---argon2_thread_handle_t.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <process.h>
|
||||
typedef unsigned(__stdcall *argon2_thread_func_t)(void *);
|
||||
typedef uintptr_t argon2_thread_handle_t;
|
||||
#else
|
||||
#include <pthread.h>
|
||||
typedef void *(*argon2_thread_func_t)(void *);
|
||||
typedef pthread_t argon2_thread_handle_t;
|
||||
#endif
|
||||
|
||||
/* Creates a thread
|
||||
* @param handle pointer to a thread handle, which is the output of this
|
||||
* function. Must not be NULL.
|
||||
* @param func A function pointer for the thread's entry point. Must not be
|
||||
* NULL.
|
||||
* @param args Pointer that is passed as an argument to @func. May be NULL.
|
||||
* @return 0 if @handle and @func are valid pointers and a thread is successfuly
|
||||
* created.
|
||||
*/
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args);
|
||||
|
||||
/* Waits for a thread to terminate
|
||||
* @param handle Handle to a thread created with argon2_thread_create.
|
||||
* @return 0 if @handle is a valid handle, and joining completed successfully.
|
||||
*/
|
||||
int argon2_thread_join(argon2_thread_handle_t handle);
|
||||
|
||||
/* Terminate the current thread. Must be run inside a thread created by
|
||||
* argon2_thread_create.
|
||||
*/
|
||||
void argon2_thread_exit(void);
|
||||
|
||||
#endif
|
||||
+14
-1
@@ -55,4 +55,17 @@ bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
std::string
|
||||
NodeStats::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Known nodes: " << good_nodes << " good, " << dubious_nodes << " dubious, " << incoming_nodes << " incoming." << std::endl;
|
||||
if (table_depth > 1) {
|
||||
ss << "Routing table depth: " << table_depth << std::endl;
|
||||
unsigned long tot_nodes = 8 * std::exp2(table_depth);
|
||||
ss << "Network size estimation: " << tot_nodes << " nodes" << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
+473
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,8 +13,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "crypto.h"
|
||||
@@ -27,7 +26,7 @@ extern "C" {
|
||||
#include <nettle/gcm.h>
|
||||
#include <nettle/aes.h>
|
||||
|
||||
#include "argon2/argon2.h"
|
||||
#include <argon2.h>
|
||||
}
|
||||
|
||||
#include <random>
|
||||
@@ -184,7 +183,7 @@ Blob aesDecrypt(const Blob& data, const Blob& key)
|
||||
Blob aesDecrypt(const Blob& data, const std::string& password)
|
||||
{
|
||||
if (data.size() <= PASSWORD_SALT_LENGTH)
|
||||
throw DecryptError("Wrong data size");
|
||||
throw DecryptError("Wrong data size");
|
||||
Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH};
|
||||
Blob key = stretchKey(password, salt, 256/8);
|
||||
Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()};
|
||||
@@ -208,7 +207,7 @@ Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
|
||||
|
||||
Blob hash(const Blob& data, size_t hash_len)
|
||||
{
|
||||
auto algo = gnutlsHashAlgo(hash_len);
|
||||
auto algo = gnutlsHashAlgo(hash_len);
|
||||
size_t res_size = gnutlsHashSize(algo);
|
||||
Blob res;
|
||||
res.resize(res_size);
|
||||
@@ -239,7 +238,7 @@ PrivateKey::PrivateKey(const Blob& import, const std::string& password)
|
||||
|
||||
const gnutls_datum_t dt {(uint8_t*)import.data(), static_cast<unsigned>(import.size())};
|
||||
const char* password_ptr = password.empty() ? nullptr : password.c_str();
|
||||
int flags = password.empty() ? GNUTLS_PKCS_PLAIN
|
||||
int flags = password.empty() ? GNUTLS_PKCS_PLAIN
|
||||
: ( GNUTLS_PKCS_PBES2_AES_128 | GNUTLS_PKCS_PBES2_AES_192 | GNUTLS_PKCS_PBES2_AES_256
|
||||
| GNUTLS_PKCS_PKCS12_3DES | GNUTLS_PKCS_PKCS12_ARCFOUR | GNUTLS_PKCS_PKCS12_RC2_40);
|
||||
|
||||
@@ -426,6 +425,22 @@ PublicKey::unpack(const uint8_t* data, size_t data_size)
|
||||
throw CryptoException(std::string("Could not read public key: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
std::string
|
||||
PublicKey::toString() const
|
||||
{
|
||||
std::string ret;
|
||||
size_t sz = ret.size();
|
||||
int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_PEM, (void*)ret.data(), &sz);
|
||||
if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
|
||||
ret.resize(sz);
|
||||
int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_PEM, (void*)ret.data(), &sz);
|
||||
if (err != GNUTLS_E_SUCCESS)
|
||||
throw CryptoException(std::string("Could not print public key: ") + gnutls_strerror(err));
|
||||
} else if (err != GNUTLS_E_SUCCESS)
|
||||
throw CryptoException(std::string("Could not print public key: ") + gnutls_strerror(err));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
PublicKey::msgpack_unpack(msgpack::object o)
|
||||
{
|
||||
@@ -510,13 +525,35 @@ PublicKey::encrypt(const Blob& data) const
|
||||
InfoHash
|
||||
PublicKey::getId() const
|
||||
{
|
||||
if (not pk)
|
||||
return {};
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
|
||||
return {};
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get public key ID: wrong output length.");
|
||||
return id;
|
||||
}
|
||||
|
||||
PkId
|
||||
PublicKey::getLongId() const
|
||||
{
|
||||
if (not pk)
|
||||
return {};
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
throw CryptoException("Can't get 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
|
||||
#else
|
||||
PkId h;
|
||||
size_t sz = h.size();
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != h.size())
|
||||
throw CryptoException("Can't get 256 bits public key ID: wrong output length.");
|
||||
return h;
|
||||
#endif
|
||||
}
|
||||
|
||||
Certificate::Certificate(const Blob& certData) : cert(nullptr)
|
||||
{
|
||||
unpack(certData.data(), certData.size());
|
||||
@@ -616,11 +653,31 @@ Certificate::getId() const
|
||||
return {};
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
|
||||
throw CryptoException("Can't get certificate public key ID.");
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate public key ID: wrong output length.");
|
||||
return id;
|
||||
}
|
||||
|
||||
PkId
|
||||
Certificate::getLongId() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
|
||||
#else
|
||||
PkId id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
|
||||
return id;
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string
|
||||
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
|
||||
{
|
||||
@@ -631,7 +688,7 @@ getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
|
||||
? gnutls_x509_crt_get_issuer_dn_by_oid(cert, oid, 0, 0, &(*dn.begin()), &dn_sz)
|
||||
: gnutls_x509_crt_get_dn_by_oid( cert, oid, 0, 0, &(*dn.begin()), &dn_sz);
|
||||
if (ret != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
return {};
|
||||
dn.resize(dn_sz);
|
||||
return dn;
|
||||
}
|
||||
@@ -700,7 +757,20 @@ bool
|
||||
Certificate::isCA() const
|
||||
{
|
||||
unsigned critical;
|
||||
return gnutls_x509_crt_get_ca_status(cert, &critical) > 0;
|
||||
bool ca_flag = gnutls_x509_crt_get_ca_status(cert, &critical) > 0;
|
||||
if (ca_flag) {
|
||||
unsigned usage;
|
||||
auto ret = gnutls_x509_crt_get_key_usage(cert, &usage, &critical);
|
||||
/* Conforming CAs MUST include this extension in certificates that
|
||||
contain public keys that are used to validate digital signatures on
|
||||
other public key certificates or CRLs. */
|
||||
if (ret < 0)
|
||||
return false;
|
||||
if (not critical)
|
||||
return true;
|
||||
return usage & GNUTLS_KEY_KEY_CERT_SIGN;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -725,6 +795,51 @@ Certificate::toString(bool chain) const
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
Certificate::print() const
|
||||
{
|
||||
gnutls_datum_t out;
|
||||
gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &out);
|
||||
std::string ret(out.data, out.data+out.size);
|
||||
gnutls_free(out.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
Certificate::revoke(const PrivateKey& key, const Certificate& to_revoke)
|
||||
{
|
||||
if (revocation_lists.empty())
|
||||
revocation_lists.emplace(std::make_shared<RevocationList>());
|
||||
auto& list = *(*revocation_lists.begin());
|
||||
list.revoke(to_revoke);
|
||||
list.sign(key, *this);
|
||||
}
|
||||
|
||||
void
|
||||
Certificate::addRevocationList(RevocationList&& list)
|
||||
{
|
||||
addRevocationList(std::make_shared<RevocationList>(std::forward<RevocationList>(list)));
|
||||
}
|
||||
|
||||
void
|
||||
Certificate::addRevocationList(std::shared_ptr<RevocationList> list)
|
||||
{
|
||||
if (revocation_lists.find(list) != revocation_lists.end())
|
||||
return; // Already in the list
|
||||
if (not list->isSignedBy(*this))
|
||||
throw CryptoException("CRL is not signed by this certificate");
|
||||
revocation_lists.emplace(std::move(list));
|
||||
}
|
||||
|
||||
std::chrono::system_clock::time_point
|
||||
Certificate::getExpiration() const
|
||||
{
|
||||
auto t = gnutls_x509_crt_get_expiration_time(cert);
|
||||
if (t == (time_t)-1)
|
||||
return std::chrono::system_clock::time_point::min();
|
||||
return std::chrono::system_clock::from_time_t(t);
|
||||
}
|
||||
|
||||
PrivateKey
|
||||
PrivateKey::generate(unsigned key_length)
|
||||
{
|
||||
@@ -739,6 +854,20 @@ PrivateKey::generate(unsigned key_length)
|
||||
return PrivateKey{key};
|
||||
}
|
||||
|
||||
PrivateKey
|
||||
PrivateKey::generateEC()
|
||||
{
|
||||
gnutls_x509_privkey_t key;
|
||||
if (gnutls_x509_privkey_init(&key) != GNUTLS_E_SUCCESS)
|
||||
throw CryptoException("Can't initialize private key.");
|
||||
int err = gnutls_x509_privkey_generate(key, GNUTLS_PK_EC, gnutls_sec_param_to_pk_bits(GNUTLS_PK_EC, GNUTLS_SEC_PARAM_ULTRA), 0);
|
||||
if (err != GNUTLS_E_SUCCESS) {
|
||||
gnutls_x509_privkey_deinit(key);
|
||||
throw CryptoException(std::string("Can't generate EC key pair: ") + gnutls_strerror(err));
|
||||
}
|
||||
return PrivateKey{key};
|
||||
}
|
||||
|
||||
Identity
|
||||
generateIdentity(const std::string& name, crypto::Identity ca, unsigned key_length, bool is_ca)
|
||||
{
|
||||
@@ -795,6 +924,10 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
|
||||
gnutls_x509_crt_set_key_usage(cert, key_usage);
|
||||
|
||||
if (ca.first && ca.second) {
|
||||
if (not ca.second->isCA()) {
|
||||
// Signing certificate must be CA.
|
||||
return {};
|
||||
}
|
||||
//if (gnutls_x509_crt_sign2(cert, ca.second->cert, ca.first->x509_key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
|
||||
if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when signing certificate" << std::endl;
|
||||
@@ -809,8 +942,335 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
|
||||
}
|
||||
}
|
||||
|
||||
return ret.getPacked();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<RevocationList>>
|
||||
Certificate::getRevocationLists() const
|
||||
{
|
||||
std::vector<std::shared_ptr<RevocationList>> ret;
|
||||
ret.reserve(revocation_lists.size());
|
||||
for (const auto& crl : revocation_lists)
|
||||
ret.emplace_back(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RevocationList::RevocationList()
|
||||
{
|
||||
gnutls_x509_crl_init(&crl);
|
||||
}
|
||||
|
||||
RevocationList::RevocationList(const Blob& b)
|
||||
{
|
||||
gnutls_x509_crl_init(&crl);
|
||||
try {
|
||||
unpack(b.data(), b.size());
|
||||
} catch (const std::exception& e) {
|
||||
gnutls_x509_crl_deinit(crl);
|
||||
crl = nullptr;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
RevocationList::~RevocationList()
|
||||
{
|
||||
if (crl) {
|
||||
gnutls_x509_crl_deinit(crl);
|
||||
crl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RevocationList::pack(Blob& b) const
|
||||
{
|
||||
gnutls_datum_t gdat {nullptr, 0};
|
||||
if (auto err = gnutls_x509_crl_export2(crl, GNUTLS_X509_FMT_DER, &gdat)) {
|
||||
throw CryptoException(std::string("Can't export CRL: ") + gnutls_strerror(err));
|
||||
}
|
||||
b.insert(b.end(), gdat.data, gdat.data + gdat.size);
|
||||
gnutls_free(gdat.data);
|
||||
}
|
||||
|
||||
void
|
||||
RevocationList::unpack(const uint8_t* dat, size_t dat_size)
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() < dat_size)
|
||||
throw CryptoException("Can't load CRL: too large!");
|
||||
const gnutls_datum_t gdat {(uint8_t*)dat, (unsigned)dat_size};
|
||||
if (auto err_pem = gnutls_x509_crl_import(crl, &gdat, GNUTLS_X509_FMT_PEM))
|
||||
if (auto err_der = gnutls_x509_crl_import(crl, &gdat, GNUTLS_X509_FMT_DER)) {
|
||||
throw CryptoException(std::string("Can't load CRL: PEM: ") + gnutls_strerror(err_pem)
|
||||
+ " DER: " + gnutls_strerror(err_der));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RevocationList::msgpack_unpack(msgpack::object o)
|
||||
{
|
||||
try {
|
||||
if (o.type == msgpack::type::BIN)
|
||||
unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
|
||||
else {
|
||||
Blob dat = unpackBlob(o);
|
||||
unpack(dat.data(), dat.size());
|
||||
}
|
||||
} catch (...) {
|
||||
throw msgpack::type_error();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RevocationList::isRevoked(const Certificate& crt) const
|
||||
{
|
||||
auto ret = gnutls_x509_crt_check_revocation(crt.cert, &crl, 1);
|
||||
if (ret < 0)
|
||||
throw CryptoException(std::string("Can't check certificate revocation status: ") + gnutls_strerror(ret));
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
void
|
||||
RevocationList::revoke(const Certificate& crt, std::chrono::system_clock::time_point t)
|
||||
{
|
||||
if (t == time_point::min())
|
||||
t = clock::now();
|
||||
if (auto err = gnutls_x509_crl_set_crt(crl, crt.cert, std::chrono::system_clock::to_time_t(t)))
|
||||
throw CryptoException(std::string("Can't revoke certificate: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
static std::string
|
||||
getCRLIssuerDN(gnutls_x509_crl_t cert, const char* oid)
|
||||
{
|
||||
std::string dn;
|
||||
dn.resize(512);
|
||||
size_t dn_sz = dn.size();
|
||||
int ret = gnutls_x509_crl_get_issuer_dn_by_oid(cert, oid, 0, 0, &(*dn.begin()), &dn_sz);
|
||||
if (ret != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
dn.resize(dn_sz);
|
||||
return dn;
|
||||
}
|
||||
|
||||
std::string
|
||||
RevocationList::getIssuerName() const
|
||||
{
|
||||
return getCRLIssuerDN(crl, GNUTLS_OID_X520_COMMON_NAME);
|
||||
}
|
||||
|
||||
/** Read CRL issuer User ID (UID) */
|
||||
std::string
|
||||
RevocationList::getIssuerUID() const
|
||||
{
|
||||
return getCRLIssuerDN(crl, GNUTLS_OID_LDAP_UID);
|
||||
}
|
||||
|
||||
RevocationList::time_point
|
||||
RevocationList::getNextUpdateTime() const
|
||||
{
|
||||
auto t = gnutls_x509_crl_get_next_update(crl);
|
||||
if (t == (time_t)-1)
|
||||
return std::chrono::system_clock::time_point::min();
|
||||
return std::chrono::system_clock::from_time_t(t);
|
||||
}
|
||||
|
||||
RevocationList::time_point
|
||||
RevocationList::getUpdateTime() const
|
||||
{
|
||||
auto t = gnutls_x509_crl_get_this_update(crl);
|
||||
if (t == (time_t)-1)
|
||||
return std::chrono::system_clock::time_point::min();
|
||||
return std::chrono::system_clock::from_time_t(t);
|
||||
}
|
||||
|
||||
enum class Endian : uint32_t
|
||||
{
|
||||
LITTLE = 0,
|
||||
BIG = 1
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T endian(T w, Endian endian = Endian::BIG)
|
||||
{
|
||||
// this gets optimized out into if (endian == host_endian) return w;
|
||||
union { uint64_t quad; uint32_t islittle; } t;
|
||||
t.quad = 1;
|
||||
if (t.islittle ^ (uint32_t)endian) return w;
|
||||
T r = 0;
|
||||
|
||||
// decent compilers will unroll this (gcc)
|
||||
// or even convert straight into single bswap (clang)
|
||||
for (size_t i = 0; i < sizeof(r); i++) {
|
||||
r <<= 8;
|
||||
r |= w & 0xff;
|
||||
w >>= 8;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
RevocationList::sign(const PrivateKey& key, const Certificate& ca, duration validity)
|
||||
{
|
||||
if (auto err = gnutls_x509_crl_set_version(crl, 2))
|
||||
throw CryptoException(std::string("Can't set CRL version: ") + gnutls_strerror(err));
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto next_update = (validity == duration{}) ? ca.getExpiration() : now + validity;
|
||||
if (auto err = gnutls_x509_crl_set_this_update(crl, std::chrono::system_clock::to_time_t(now)))
|
||||
throw CryptoException(std::string("Can't set CRL update time: ") + gnutls_strerror(err));
|
||||
if (auto err = gnutls_x509_crl_set_next_update(crl, std::chrono::system_clock::to_time_t(next_update)))
|
||||
throw CryptoException(std::string("Can't set CRL next update time: ") + gnutls_strerror(err));
|
||||
uint64_t number {0};
|
||||
size_t number_sz {sizeof(number)};
|
||||
unsigned critical {0};
|
||||
gnutls_x509_crl_get_number(crl, &number, &number_sz, &critical);
|
||||
if (number == 0) {
|
||||
// initialize to a random number
|
||||
number_sz = sizeof(number);
|
||||
random_device rdev;
|
||||
std::generate_n((uint8_t*)&number, sizeof(number), std::bind(rand_byte, std::ref(rdev)));
|
||||
} else
|
||||
number = endian(endian(number) + 1);
|
||||
if (auto err = gnutls_x509_crl_set_number(crl, &number, sizeof(number)))
|
||||
throw CryptoException(std::string("Can't set CRL update time: ") + gnutls_strerror(err));
|
||||
if (auto err = gnutls_x509_crl_sign2(crl, ca.cert, key.x509_key, GNUTLS_DIG_SHA512, 0))
|
||||
throw CryptoException(std::string("Can't sign certificate revocation list: ") + gnutls_strerror(err));
|
||||
// to be able to actually use the CRL we need to serialize/deserialize it
|
||||
auto packed = getPacked();
|
||||
unpack(packed.data(), packed.size());
|
||||
}
|
||||
|
||||
bool
|
||||
RevocationList::isSignedBy(const Certificate& issuer) const
|
||||
{
|
||||
unsigned result {0};
|
||||
auto err = gnutls_x509_crl_verify(crl, &issuer.cert, 1, 0, &result);
|
||||
if (err < 0) {
|
||||
//std::cout << "Can't verify CRL: " << err << " " << result << " " << gnutls_strerror(err) << std::endl;
|
||||
return false;
|
||||
}
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
|
||||
Blob
|
||||
RevocationList::getNumber() const
|
||||
{
|
||||
Blob number(20);
|
||||
size_t number_sz {number.size()};
|
||||
unsigned critical {0};
|
||||
gnutls_x509_crl_get_number(crl, number.data(), &number_sz, &critical);
|
||||
if (number_sz != number.size())
|
||||
number.resize(number_sz);
|
||||
return number;
|
||||
}
|
||||
|
||||
std::string
|
||||
RevocationList::toString() const
|
||||
{
|
||||
gnutls_datum_t out;
|
||||
gnutls_x509_crl_print(crl, GNUTLS_CRT_PRINT_FULL, &out);
|
||||
std::string ret(out.data, out.data+out.size);
|
||||
gnutls_free(out.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
TrustList::TrustList() {
|
||||
gnutls_x509_trust_list_init(&trust, 0);
|
||||
}
|
||||
|
||||
TrustList::~TrustList() {
|
||||
gnutls_x509_trust_list_deinit(trust, 1);
|
||||
}
|
||||
|
||||
TrustList&
|
||||
TrustList::operator=(TrustList&& o)
|
||||
{
|
||||
if (trust)
|
||||
gnutls_x509_trust_list_deinit(trust, true);
|
||||
trust = std::move(o.trust);
|
||||
o.trust = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TrustList::add(const Certificate& crt)
|
||||
{
|
||||
auto chain = crt.getChainWithRevocations(true);
|
||||
gnutls_x509_trust_list_add_cas(trust, chain.first.data(), chain.first.size(), GNUTLS_TL_NO_DUPLICATES);
|
||||
if (not chain.second.empty())
|
||||
gnutls_x509_trust_list_add_crls(
|
||||
trust,
|
||||
chain.second.data(), chain.second.size(),
|
||||
GNUTLS_TL_VERIFY_CRL | GNUTLS_TL_NO_DUPLICATES, 0);
|
||||
}
|
||||
|
||||
void TrustList::add(const RevocationList& crl)
|
||||
{
|
||||
auto copy = crl.getCopy();
|
||||
gnutls_x509_trust_list_add_crls(trust, ©, 1, GNUTLS_TL_VERIFY_CRL | GNUTLS_TL_NO_DUPLICATES, 0);
|
||||
}
|
||||
|
||||
void TrustList::remove(const Certificate& crt, bool parents)
|
||||
{
|
||||
gnutls_x509_trust_list_remove_cas(trust, &crt.cert, 1);
|
||||
if (parents) {
|
||||
for (auto c = crt.issuer; c; c = c->issuer)
|
||||
gnutls_x509_trust_list_remove_cas(trust, &c->cert, 1);
|
||||
}
|
||||
}
|
||||
|
||||
TrustList::VerifyResult
|
||||
TrustList::verify(const Certificate& crt) const
|
||||
{
|
||||
auto chain = crt.getChain();
|
||||
VerifyResult ret;
|
||||
ret.ret = gnutls_x509_trust_list_verify_crt2(
|
||||
trust,
|
||||
chain.data(), chain.size(),
|
||||
nullptr, 0,
|
||||
GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM),
|
||||
&ret.result, nullptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string
|
||||
TrustList::VerifyResult::toString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& o, const TrustList::VerifyResult& h)
|
||||
{
|
||||
if (h.ret < 0) {
|
||||
o << "Error verifying certificate: " << gnutls_strerror(h.ret) << std::endl;
|
||||
} else if (h.result & GNUTLS_CERT_INVALID) {
|
||||
o << "Certificate check failed with code: " << h.result << std::endl;
|
||||
if (h.result & GNUTLS_CERT_SIGNATURE_FAILURE)
|
||||
o << "* The signature verification failed." << std::endl;
|
||||
if (h.result & GNUTLS_CERT_REVOKED)
|
||||
o << "* Certificate is revoked" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_SIGNER_NOT_FOUND)
|
||||
o << "* Certificate's issuer is not known" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_SIGNER_NOT_CA)
|
||||
o << "* Certificate's issuer not a CA" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
|
||||
o << "* Certificate's signer constraints were violated" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_INSECURE_ALGORITHM)
|
||||
o << "* Certificate was signed using an insecure algorithm" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_NOT_ACTIVATED)
|
||||
o << "* Certificate is not yet activated" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_EXPIRED)
|
||||
o << "* Certificate has expired" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_UNEXPECTED_OWNER)
|
||||
o << "* The owner is not the expected one" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_PURPOSE_MISMATCH)
|
||||
o << "* Certificate or an intermediate does not match the intended purpose" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_MISMATCH)
|
||||
o << "* Certificate presented isn't the expected one" << std::endl;
|
||||
} else {
|
||||
o << "Certificate is valid" << std::endl;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,8 +13,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "default_types.h"
|
||||
|
||||
+581
-398
File diff suppressed because it is too large.
Load diff
+34
-9
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,8 +14,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dhtrunner.h"
|
||||
@@ -233,11 +232,27 @@ DhtRunner::importValues(const std::vector<ValuesExport>& values) {
|
||||
dht_->importValues(values);
|
||||
}
|
||||
|
||||
int
|
||||
unsigned
|
||||
DhtRunner::getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return dht_->getNodesStats(af, good_return, dubious_return, cached_return, incoming_return);
|
||||
const auto stats = dht_->getNodesStats(af);
|
||||
if (good_return)
|
||||
*good_return = stats.good_nodes;
|
||||
if (dubious_return)
|
||||
*dubious_return = stats.dubious_nodes;
|
||||
if (cached_return)
|
||||
*cached_return = stats.cached_nodes;
|
||||
if (incoming_return)
|
||||
*incoming_return = stats.incoming_nodes;
|
||||
return stats.good_nodes + stats.dubious_nodes;
|
||||
}
|
||||
|
||||
NodeStats
|
||||
DhtRunner::getNodesStats(sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return dht_->getNodesStats(af);
|
||||
}
|
||||
|
||||
std::vector<unsigned>
|
||||
@@ -348,7 +363,7 @@ DhtRunner::loop_()
|
||||
// We have lost connection with the DHT. Try to recover using bootstrap nodes.
|
||||
std::unique_lock<std::mutex> lck(bootstrap_mtx);
|
||||
bootstrap_nodes = bootstrap_nodes_all;
|
||||
tryBootstrapCoutinuously();
|
||||
tryBootstrapContinuously();
|
||||
} else {
|
||||
std::unique_lock<std::mutex> lck(bootstrap_mtx);
|
||||
bootstrap_nodes.clear();
|
||||
@@ -618,7 +633,7 @@ DhtRunner::putEncrypted(const std::string& key, InfoHash to, Value&& value, Done
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::tryBootstrapCoutinuously()
|
||||
DhtRunner::tryBootstrapContinuously()
|
||||
{
|
||||
if (bootstrap_thread.joinable()) {
|
||||
if (bootstraping)
|
||||
@@ -707,7 +722,7 @@ DhtRunner::bootstrap(const std::string& host, const std::string& service)
|
||||
std::lock_guard<std::mutex> lck(bootstrap_mtx);
|
||||
bootstrap_nodes_all.emplace_back(host, service);
|
||||
bootstrap_nodes.emplace_back(host, service);
|
||||
tryBootstrapCoutinuously();
|
||||
tryBootstrapContinuously();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -735,6 +750,16 @@ DhtRunner::bootstrap(const std::vector<std::pair<sockaddr_storage, socklen_t>>&
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops_prio.emplace([addr,cb](SecureDht& dht) mutable {
|
||||
dht.pingNode((const sockaddr*)&addr.first, addr.second, std::move(cb));
|
||||
});
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::bootstrap(const std::vector<NodeExport>& nodes)
|
||||
{
|
||||
|
||||
+54
-34
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Nicolas Reynaud <nicolas.reynaud@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 "indexation/pht.h"
|
||||
#include "rng.h"
|
||||
|
||||
@@ -276,7 +296,7 @@ void Pht::lookup(Key k, Pht::LookupCallback cb, DoneCallbackSimple done_cb, bool
|
||||
std::shared_ptr<unsigned> max_common_prefix_len = not exact_match ? std::make_shared<unsigned>(0) : nullptr;
|
||||
|
||||
lookupStep(prefix, lo, hi, values,
|
||||
[=](std::vector<std::shared_ptr<IndexEntry>>& entries, Prefix p) {
|
||||
[=](std::vector<std::shared_ptr<IndexEntry>>& entries, const Prefix& p) {
|
||||
std::vector<std::shared_ptr<Value>> vals(entries.size());
|
||||
|
||||
std::transform(entries.begin(), entries.end(), vals.begin(),
|
||||
@@ -309,7 +329,7 @@ void Pht::updateCanary(Prefix p) {
|
||||
}
|
||||
}
|
||||
|
||||
void Pht::insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
|
||||
void Pht::insert(const Prefix& kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
|
||||
bool check_split, DoneCallbackSimple done_cb) {
|
||||
|
||||
if (time_p + ValueType::USER_DATA.expiration < clock::now()) return;
|
||||
@@ -327,26 +347,25 @@ void Pht::insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shar
|
||||
done_cb(false);
|
||||
} else {
|
||||
|
||||
RealInsertCallback real_insert = [=]( std::shared_ptr<Prefix> p, IndexEntry entry) {
|
||||
updateCanary(*p);
|
||||
checkPhtUpdate(*p, entry, time_p);
|
||||
cache_.insert(*p);
|
||||
dht_->put(p->hash(), std::move(entry), done_cb , time_p);
|
||||
RealInsertCallback real_insert = [=](const Prefix& p, IndexEntry entry) {
|
||||
updateCanary(p);
|
||||
checkPhtUpdate(p, entry, time_p);
|
||||
cache_.insert(p);
|
||||
dht_->put(p.hash(), std::move(entry), done_cb , time_p);
|
||||
};
|
||||
|
||||
if ( not check_split or final_prefix->size_ == kp.size_ ) {
|
||||
real_insert(final_prefix, std::move(entry));
|
||||
real_insert(*final_prefix, std::move(entry));
|
||||
} else {
|
||||
if ( vals->size() < MAX_NODE_ENTRY_COUNT ) {
|
||||
getRealPrefix(final_prefix, std::move(entry), real_insert);
|
||||
}
|
||||
else {
|
||||
split(*final_prefix, vals, entry, real_insert);
|
||||
split(*final_prefix, *vals, entry, real_insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, nullptr, cache_.lookup(kp), true
|
||||
);
|
||||
}, nullptr, cache_.lookup(kp), true);
|
||||
}
|
||||
|
||||
Prefix Pht::zcurve(const std::vector<Prefix>& all_prefix) const {
|
||||
@@ -420,43 +439,44 @@ Prefix Pht::linearize(Key k) const {
|
||||
return zcurve(all_prefix);
|
||||
}
|
||||
|
||||
void Pht::getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertCallback end_cb ) {
|
||||
|
||||
void Pht::getRealPrefix(const std::shared_ptr<Prefix>& p, IndexEntry entry, RealInsertCallback end_cb )
|
||||
{
|
||||
if ( p->size_ == 0 ) {
|
||||
end_cb(p, std::move(entry));
|
||||
end_cb(*p, std::move(entry));
|
||||
return;
|
||||
}
|
||||
|
||||
auto total = std::make_shared<unsigned int>(0); /* Will contains the total number of data on 3 nodes */
|
||||
auto ended = std::make_shared<unsigned int>(0); /* Just indicate how many have end */
|
||||
|
||||
auto parent = std::make_shared<Prefix>(p->getPrefix(-1));
|
||||
auto sibling = std::make_shared<Prefix>(p->getSibling());
|
||||
struct OpState {
|
||||
unsigned entry_count {0}; /* Total number of data on 3 nodes */
|
||||
unsigned ended {0}; /* How many ops have ended */
|
||||
Prefix parent;
|
||||
OpState(Prefix p) : parent(p) {}
|
||||
};
|
||||
auto op_state = std::make_shared<OpState>(p->getPrefix(-1));
|
||||
|
||||
auto pht_filter = [&](const dht::Value& v) {
|
||||
return v.user_type.compare(0, name_.size(), name_) == 0;
|
||||
};
|
||||
|
||||
/* Lambda will count total number of data node */
|
||||
auto count = [=]( const std::shared_ptr<dht::Value> value ) {
|
||||
if ( value->user_type != canary_)
|
||||
(*total)++;
|
||||
|
||||
auto count = [=]( const std::shared_ptr<dht::Value>& value ) {
|
||||
if (value->user_type != canary_)
|
||||
op_state->entry_count++;
|
||||
return true;
|
||||
};
|
||||
|
||||
auto on_done = [=] ( bool ) {
|
||||
(*ended)++;
|
||||
op_state->ended++;
|
||||
/* Only the last one do the CallBack*/
|
||||
if ( *ended == 3 ) {
|
||||
if ( *total < MAX_NODE_ENTRY_COUNT )
|
||||
end_cb(parent, std::move(entry));
|
||||
if (op_state->ended == 3) {
|
||||
if (op_state->entry_count < MAX_NODE_ENTRY_COUNT)
|
||||
end_cb(op_state->parent, std::move(entry));
|
||||
else
|
||||
end_cb(p, std::move(entry));
|
||||
end_cb(*p, std::move(entry));
|
||||
}
|
||||
};
|
||||
|
||||
dht_->get(parent->hash(),
|
||||
dht_->get(op_state->parent.hash(),
|
||||
count,
|
||||
on_done,
|
||||
pht_filter
|
||||
@@ -468,7 +488,7 @@ void Pht::getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertC
|
||||
pht_filter
|
||||
);
|
||||
|
||||
dht_->get(sibling->hash(),
|
||||
dht_->get(p->getSibling().hash(),
|
||||
count,
|
||||
on_done,
|
||||
pht_filter
|
||||
@@ -500,11 +520,11 @@ void Pht::checkPhtUpdate(Prefix p, IndexEntry entry, time_point time_p) {
|
||||
);
|
||||
}
|
||||
|
||||
void Pht::split(Prefix insert, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals, IndexEntry entry, RealInsertCallback end_cb ) {
|
||||
auto full = Prefix(entry.prefix);
|
||||
void Pht::split(const Prefix& insert, const std::vector<std::shared_ptr<IndexEntry>>& vals, IndexEntry entry, RealInsertCallback end_cb ) {
|
||||
const auto full = Prefix(entry.prefix);
|
||||
|
||||
auto loc = foundSplitLocation(full, vals);
|
||||
auto prefix_to_insert = std::make_shared<Prefix>(full.getPrefix(loc));
|
||||
auto loc = findSplitLocation(full, vals);
|
||||
const auto prefix_to_insert = full.getPrefix(loc);
|
||||
|
||||
for(;loc != insert.size_ - 1; loc--) {
|
||||
updateCanary(full.getPrefix(loc));
|
||||
|
||||
+34
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,8 +13,7 @@
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "infohash.h"
|
||||
@@ -57,7 +56,7 @@ InfoHash::get(const uint8_t* data, size_t data_len)
|
||||
int rc = gnutls_fingerprint(algo, &gnudata, h.data(), &s);
|
||||
if (rc == 0 && s == HASH_LEN)
|
||||
return h;
|
||||
throw std::string("Error while hashing");
|
||||
throw std::runtime_error(std::string("Error hashing: ") + gnutls_strerror(rc));
|
||||
}
|
||||
|
||||
InfoHash
|
||||
@@ -65,29 +64,47 @@ InfoHash::getRandom()
|
||||
{
|
||||
InfoHash h;
|
||||
crypto::random_device rdev;
|
||||
#ifdef _WIN32
|
||||
static std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
|
||||
#else
|
||||
static std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
#endif
|
||||
std::generate(h.begin(), h.end(), std::bind(rand_byte, std::ref(rdev)));
|
||||
std::uniform_int_distribution<uint32_t> rand_int;
|
||||
auto a = reinterpret_cast<uint32_t*>(&(*h.begin()));
|
||||
auto b = reinterpret_cast<uint32_t*>(&(*h.end()));
|
||||
std::generate(a, b, std::bind(rand_int, std::ref(rdev)));
|
||||
return h;
|
||||
}
|
||||
|
||||
struct HexMap : public std::array<std::array<char, 2>, 256> {
|
||||
HexMap() {
|
||||
for (size_t i=0; i<size(); i++) {
|
||||
auto& e = (*this)[i];
|
||||
e[0] = hex_digits[(i >> 4) & 0x0F];
|
||||
e[1] = hex_digits[i & 0x0F];
|
||||
}
|
||||
}
|
||||
private:
|
||||
static constexpr const char* hex_digits = "0123456789abcdef";
|
||||
};
|
||||
|
||||
const char*
|
||||
InfoHash::to_c_str() const
|
||||
{
|
||||
static const HexMap map;
|
||||
thread_local std::array<char, HASH_LEN*2+1> buf;
|
||||
for (size_t i=0; i<HASH_LEN; i++) {
|
||||
auto b = buf.data()+i*2;
|
||||
const auto& m = map[(*this)[i]];
|
||||
*((uint16_t*)b) = *((uint16_t*)&m);
|
||||
}
|
||||
return buf.data();
|
||||
}
|
||||
|
||||
std::string
|
||||
InfoHash::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
return std::string(to_c_str(), HASH_LEN*2);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, const InfoHash& h)
|
||||
{
|
||||
s << std::hex;
|
||||
for (unsigned i=0; i<HASH_LEN; i++)
|
||||
s << std::setfill('0') << std::setw(2) << (unsigned)h[i];
|
||||
s << std::dec;
|
||||
s.write(h.to_c_str(), HASH_LEN*2);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 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 "log.h"
|
||||
|
||||
namespace dht {
|
||||
namespace log {
|
||||
|
||||
/**
|
||||
* Print va_list to std::ostream (used for logging).
|
||||
*/
|
||||
void
|
||||
printLog(std::ostream& s, char const *m, va_list args) {
|
||||
// print log to buffer
|
||||
std::array<char, 8192> buffer;
|
||||
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
// write timestamp
|
||||
using namespace std::chrono;
|
||||
using log_precision = microseconds;
|
||||
constexpr auto den = log_precision::period::den;
|
||||
auto micro = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
|
||||
s << "[" << std::setfill('0') << std::setw(6) << micro / den << "."
|
||||
<< std::setfill('0') << std::setw(6) << micro % den << "]" << " ";
|
||||
|
||||
// write log
|
||||
s.write(buffer.data(), std::min((size_t) ret, buffer.size()));
|
||||
if ((size_t) ret >= buffer.size())
|
||||
s << "[[TRUNCATED]]";
|
||||
s << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
enableLogging(dht::DhtRunner &dht) {
|
||||
dht.setLoggers(
|
||||
[](char const *m, va_list args) {
|
||||
std::cerr << red;
|
||||
printLog(std::cerr, m, args);
|
||||
std::cerr << def;
|
||||
},
|
||||
[](char const *m, va_list args) {
|
||||
std::cout << yellow;
|
||||
printLog(std::cout, m, args);
|
||||
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>();
|
||||
logfile->open(path, std::ios::out);
|
||||
|
||||
dht.setLoggers(
|
||||
[=](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); }
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
disableLogging(dht::DhtRunner &dht) {
|
||||
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+218
-145
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
* Simon Désaulniers <simon.desaulniers@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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <msgpack.hpp>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
const std::string DhtProtocolException::GET_NO_INFOHASH {"Get_values with no info_hash"};
|
||||
const std::string DhtProtocolException::LISTEN_NO_INFOHASH {"Listen with no info_hash"};
|
||||
@@ -40,15 +41,15 @@ constexpr std::chrono::seconds NetworkEngine::RX_MAX_PACKET_TIME;
|
||||
constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
|
||||
|
||||
const std::string NetworkEngine::my_v {"RNG1"};
|
||||
const constexpr uint16_t NetworkEngine::TransId::INVALID;
|
||||
const constexpr uint16_t TransId::INVALID;
|
||||
std::mt19937 NetworkEngine::rd_device {dht::crypto::random_device{}()};
|
||||
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::PING = {"pn"};
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::FIND_NODE = {"fn"};
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::GET_VALUES = {"gt"};
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::ANNOUNCE_VALUES = {"pt"};
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::REFRESH = {"rf"};
|
||||
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::LISTEN = {"lt"};
|
||||
const TransPrefix TransPrefix::PING = {"pn"};
|
||||
const TransPrefix TransPrefix::FIND_NODE = {"fn"};
|
||||
const TransPrefix TransPrefix::GET_VALUES = {"gt"};
|
||||
const TransPrefix TransPrefix::ANNOUNCE_VALUES = {"pt"};
|
||||
const TransPrefix TransPrefix::REFRESH = {"rf"};
|
||||
const TransPrefix TransPrefix::LISTEN = {"lt"};
|
||||
constexpr long unsigned NetworkEngine::MAX_REQUESTS_PER_SEC;
|
||||
|
||||
static const uint8_t v4prefix[16] = {
|
||||
@@ -80,7 +81,9 @@ struct ParsedMessage {
|
||||
/* target id around which to find nodes */
|
||||
InfoHash target;
|
||||
/* transaction id */
|
||||
NetworkEngine::TransId tid;
|
||||
TransId tid;
|
||||
/* tid for packets going through request socket */
|
||||
TransId socket_id;
|
||||
/* security token */
|
||||
Blob token;
|
||||
/* the value id (announce confirmation) */
|
||||
@@ -89,11 +92,11 @@ struct ParsedMessage {
|
||||
time_point created { time_point::max() };
|
||||
/* IPv4 nodes in response to a 'find' request */
|
||||
Blob nodes4_raw, nodes6_raw;
|
||||
std::vector<std::shared_ptr<Node>> nodes4, nodes6;
|
||||
std::vector<Sp<Node>> nodes4, nodes6;
|
||||
/* values to store or retreive request */
|
||||
std::vector<std::shared_ptr<Value>> values;
|
||||
std::vector<Sp<Value>> values;
|
||||
/* index for fields values */
|
||||
std::vector<std::shared_ptr<FieldValueIndex>> fields;
|
||||
std::vector<Sp<FieldValueIndex>> fields;
|
||||
/** When part of the message header: {index -> (total size, {})}
|
||||
* When part of partial value data: {index -> (offset, part_data)} */
|
||||
std::map<unsigned, std::pair<unsigned, Blob>> value_parts;
|
||||
@@ -120,7 +123,7 @@ struct NetworkEngine::PartialMessage {
|
||||
};
|
||||
|
||||
std::vector<Blob>
|
||||
serializeValues(const std::vector<std::shared_ptr<Value>>& st)
|
||||
serializeValues(const std::vector<Sp<Value>>& st)
|
||||
{
|
||||
std::vector<Blob> svals;
|
||||
svals.reserve(st.size());
|
||||
@@ -156,15 +159,14 @@ NetworkEngine::~NetworkEngine() {
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, const InfoHash& hash, want_t want,
|
||||
const Blob& ntoken, std::vector<std::shared_ptr<Node>>&& nodes,
|
||||
std::vector<std::shared_ptr<Node>>&& nodes6, std::vector<std::shared_ptr<Value>>&& values,
|
||||
NetworkEngine::tellListener(Sp<Node> node, uint32_t socket_id, const InfoHash& hash, want_t want,
|
||||
const Blob& ntoken, std::vector<Sp<Node>>&& nodes,
|
||||
std::vector<Sp<Node>>&& nodes6, std::vector<Sp<Value>>&& values,
|
||||
const Query& query)
|
||||
{
|
||||
auto nnodes = bufferNodes(node->getFamily(), hash, want, nodes, nodes6);
|
||||
try {
|
||||
sendNodesValues(node->addr, TransId {TransPrefix::GET_VALUES, (uint16_t)rid}, nnodes.first, nnodes.second,
|
||||
values, query, ntoken);
|
||||
sendNodesValues(node->addr, TransId((char*)&socket_id, 4), nnodes.first, nnodes.second, values, query, ntoken);
|
||||
} catch (const std::overflow_error& e) {
|
||||
DHT_LOG.e("Can't send value: buffer not large enough !");
|
||||
}
|
||||
@@ -185,11 +187,29 @@ NetworkEngine::isRunning(sa_family_t af) const
|
||||
}
|
||||
}
|
||||
|
||||
Sp<Socket>
|
||||
NetworkEngine::openSocket(const Sp<Node>& node, TransPrefix tp, SocketCb&& cb)
|
||||
{
|
||||
auto tid = TransId {tp, getNewTid()};
|
||||
auto s = opened_sockets.emplace(tid, std::make_shared<Socket>(node, tid, cb));
|
||||
if (not s.second)
|
||||
DHT_LOG.e(node->id, "[node %s] socket (tid: %d) already opened!", node->id.toString().c_str(), tid.toInt());
|
||||
return s.first->second;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::cancelRequest(std::shared_ptr<Request>& req)
|
||||
NetworkEngine::closeSocket(Sp<Socket> socket)
|
||||
{
|
||||
if (socket)
|
||||
opened_sockets.erase(socket->id);
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::cancelRequest(Sp<Request>& req)
|
||||
{
|
||||
if (req) {
|
||||
req->cancel();
|
||||
closeSocket(req->socket);
|
||||
requests.erase(req->tid);
|
||||
}
|
||||
}
|
||||
@@ -209,7 +229,7 @@ NetworkEngine::connectivityChanged(sa_family_t af)
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::requestStep(std::shared_ptr<Request> sreq)
|
||||
NetworkEngine::requestStep(Sp<Request> sreq)
|
||||
{
|
||||
auto& req = *sreq;
|
||||
if (not req.pending()) {
|
||||
@@ -246,7 +266,7 @@ NetworkEngine::requestStep(std::shared_ptr<Request> sreq)
|
||||
* be made before the request expires.
|
||||
*/
|
||||
void
|
||||
NetworkEngine::sendRequest(std::shared_ptr<Request>& request)
|
||||
NetworkEngine::sendRequest(Sp<Request>& request)
|
||||
{
|
||||
request->start = scheduler.time();
|
||||
auto e = requests.emplace(request->tid, request);
|
||||
@@ -255,7 +275,7 @@ NetworkEngine::sendRequest(std::shared_ptr<Request>& request)
|
||||
// Try to handle this scenario as well as we can
|
||||
e.first->second->setExpired();
|
||||
e.first->second = request;
|
||||
DHT_LOG.e(request->node->id, "Request already existed (tid: %d)!", request->tid);
|
||||
DHT_LOG.e(request->node->id, "Request already existed (tid: %d)!", request->tid.getTid());
|
||||
}
|
||||
request->node->requested(request);
|
||||
requestStep(request);
|
||||
@@ -287,32 +307,25 @@ NetworkEngine::rateLimit(const SockAddr& addr)
|
||||
bool
|
||||
NetworkEngine::isMartian(const SockAddr& addr)
|
||||
{
|
||||
// Check that sa_family can be accessed safely
|
||||
if (addr.second < sizeof(sockaddr_in))
|
||||
if (addr.getPort() == 0)
|
||||
return true;
|
||||
|
||||
switch(addr.first.ss_family) {
|
||||
switch(addr.getFamily()) {
|
||||
case AF_INET: {
|
||||
sockaddr_in *sin = (sockaddr_in*)&addr.first;
|
||||
const uint8_t *address = (const uint8_t*)&sin->sin_addr;
|
||||
return sin->sin_port == 0 ||
|
||||
(address[0] == 0) ||
|
||||
(address[0] == 127) ||
|
||||
((address[0] & 0xE0) == 0xE0);
|
||||
const auto& sin = addr.getIPv4();
|
||||
const uint8_t* address = (const uint8_t*)&sin.sin_addr;
|
||||
return (address[0] == 0) ||
|
||||
((address[0] & 0xE0) == 0xE0);
|
||||
}
|
||||
case AF_INET6: {
|
||||
if (addr.second < sizeof(sockaddr_in6))
|
||||
return true;
|
||||
sockaddr_in6 *sin6 = (sockaddr_in6*)&addr.first;
|
||||
const uint8_t *address = (const uint8_t*)&sin6->sin6_addr;
|
||||
return sin6->sin6_port == 0 ||
|
||||
(address[0] == 0xFF) ||
|
||||
(address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
|
||||
(memcmp(address, zeroes.data(), 15) == 0 &&
|
||||
(address[15] == 0 || address[15] == 1)) ||
|
||||
(memcmp(address, v4prefix, 12) == 0);
|
||||
const auto& sin6 = addr.getIPv6();
|
||||
const uint8_t* address = (const uint8_t*)&sin6.sin6_addr;
|
||||
return address[0] == 0xFF ||
|
||||
(address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
|
||||
memcmp(address, zeroes.data(), 16) == 0 ||
|
||||
memcmp(address, v4prefix, 12) == 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@@ -321,7 +334,7 @@ NetworkEngine::isMartian(const SockAddr& addr)
|
||||
/* The internal blacklist is an LRU cache of nodes that have sent
|
||||
incorrect messages. */
|
||||
void
|
||||
NetworkEngine::blacklistNode(const std::shared_ptr<Node>& n)
|
||||
NetworkEngine::blacklistNode(const Sp<Node>& n)
|
||||
{
|
||||
n->setExpired();
|
||||
for (auto rit = requests.begin(); rit != requests.end();) {
|
||||
@@ -435,19 +448,22 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
if (msg->type == MessageType::Error or msg->type == MessageType::Reply) {
|
||||
auto reqp = requests.find(msg->tid.getTid());
|
||||
if (reqp == requests.end()) {
|
||||
/* either response for a request or data for an opened socket */
|
||||
auto req_it = requests.find(msg->tid);
|
||||
auto rsocket_it = opened_sockets.end();
|
||||
if (req_it == requests.end())
|
||||
rsocket_it = opened_sockets.find(msg->tid);
|
||||
if (req_it == requests.end() and rsocket_it == opened_sockets.end())
|
||||
throw DhtProtocolException {DhtProtocolException::UNKNOWN_TID, "Can't find transaction", msg->id};
|
||||
}
|
||||
auto req = reqp->second;
|
||||
auto node = req->node;
|
||||
|
||||
auto req = req_it != requests.end() ? req_it->second : nullptr;
|
||||
auto rsocket = rsocket_it != opened_sockets.end() ? rsocket_it->second : nullptr;
|
||||
|
||||
auto& node = req ? req->node : rsocket->node;
|
||||
if (node->id != msg->id) {
|
||||
bool unknown_node = node->id == zeroes;
|
||||
node = cache.getNode(msg->id, from, now, true);
|
||||
if (unknown_node) {
|
||||
// received reply to a message sent when we didn't know the node ID.
|
||||
req->node = node;
|
||||
} else {
|
||||
if (node->id == zeroes) // received reply to a message sent when we didn't know the node ID.
|
||||
node = cache.getNode(msg->id, from, now, true);
|
||||
else {
|
||||
// received reply from unexpected node
|
||||
node->received(now, req);
|
||||
onNewNode(node, 2);
|
||||
@@ -456,14 +472,15 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
}
|
||||
} else
|
||||
node->update(from);
|
||||
|
||||
node->received(now, req);
|
||||
|
||||
onNewNode(node, 2);
|
||||
onReportedAddr(msg->id, msg->addr);
|
||||
|
||||
if (req->cancelled() or req->expired() or (req->completed() and not req->persistent)) {
|
||||
if (req and (req->cancelled() or req->expired() or req->completed())) {
|
||||
DHT_LOG.w(node->id, "[node %s] response to expired, cancelled or completed request", node->toString().c_str());
|
||||
requests.erase(reqp);
|
||||
requests.erase(req_it);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -474,8 +491,8 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
(msg->error_code == DhtProtocolException::UNAUTHORIZED and (msg->tid.matches(TransPrefix::ANNOUNCE_VALUES)
|
||||
or msg->tid.matches(TransPrefix::LISTEN)))))
|
||||
{
|
||||
req->last_try = TIME_INVALID;
|
||||
req->reply_time = TIME_INVALID;
|
||||
req->last_try = time_point::min();
|
||||
req->reply_time = time_point::min();
|
||||
onError(req, DhtProtocolException {msg->error_code});
|
||||
} else {
|
||||
DHT_LOG.w(msg->id, "[node %s %s] received unknown error message %u",
|
||||
@@ -484,17 +501,21 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
break;
|
||||
}
|
||||
case MessageType::Reply:
|
||||
if (msg->type == MessageType::AnnounceValue or msg->type == MessageType::Listen)
|
||||
req->node->authSuccess();
|
||||
if (req) { /* request reply */
|
||||
if (msg->type == MessageType::AnnounceValue or msg->type == MessageType::Listen)
|
||||
req->node->authSuccess();
|
||||
|
||||
// erase before calling callback to make sure iterator is still valid
|
||||
if (not req->persistent)
|
||||
requests.erase(reqp);
|
||||
req->reply_time = scheduler.time();
|
||||
// erase before calling callback to make sure iterator is still valid
|
||||
requests.erase(req_it);
|
||||
req->reply_time = scheduler.time();
|
||||
|
||||
deserializeNodes(*msg);
|
||||
req->setDone(std::move(*msg));
|
||||
break;
|
||||
deserializeNodes(*msg, from);
|
||||
req->setDone(std::move(*msg));
|
||||
break;
|
||||
} else { /* request socket data */
|
||||
deserializeNodes(*msg, from);
|
||||
rsocket->on_receive(rsocket->node, std::move(*msg));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -548,7 +569,9 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
case MessageType::Listen: {
|
||||
DHT_LOG.d(msg->info_hash, node->id, "[node %s] got 'listen' request for %s", node->toString().c_str(), msg->info_hash.toString().c_str());
|
||||
++in_stats.listen;
|
||||
RequestAnswer answer = onListen(node, msg->info_hash, msg->token, msg->tid.getTid(), std::move(msg->query));
|
||||
/* TODO: backward compatibility check to remove in a few versions (see ::sendListen doc) */
|
||||
auto socket_id = msg->socket_id.getTid() ? msg->socket_id : TransId { TransPrefix::GET_VALUES, msg->tid.getTid() };
|
||||
RequestAnswer answer = onListen(node, msg->info_hash, msg->token, socket_id.toInt(), std::move(msg->query));
|
||||
sendListenConfirmation(from, msg->tid);
|
||||
break;
|
||||
}
|
||||
@@ -564,7 +587,7 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
}
|
||||
|
||||
void
|
||||
packToken(msgpack::packer<msgpack::sbuffer>& pk, Blob token)
|
||||
packToken(msgpack::packer<msgpack::sbuffer>& pk, const Blob& token)
|
||||
{
|
||||
pk.pack_bin(token.size());
|
||||
pk.pack_bin_body((char*)token.data(), token.size());
|
||||
@@ -582,11 +605,11 @@ insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const SockAddr& addr)
|
||||
pk.pack_bin_body((char*)addr_ptr, addr_len);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr)
|
||||
{
|
||||
if (addr.second == 0)
|
||||
return -1;
|
||||
return;
|
||||
|
||||
int s;
|
||||
if (addr.getFamily() == AF_INET)
|
||||
@@ -597,12 +620,13 @@ NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr
|
||||
s = -1;
|
||||
|
||||
if (s < 0)
|
||||
return -1;
|
||||
return sendto(s, buf, len, flags, (const sockaddr*)&addr.first, addr.second);
|
||||
return;
|
||||
if (sendto(s, buf, len, flags, (const sockaddr*)&addr.first, addr.second) == -1)
|
||||
DHT_LOG.e("Can't send message to %s: %s", addr.toString().c_str(), strerror(errno));
|
||||
}
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestExpiredCb on_expired) {
|
||||
Sp<Request>
|
||||
NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
auto tid = TransId {TransPrefix::PING, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
@@ -620,8 +644,8 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), node, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, node,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&&) {
|
||||
DHT_LOG.d(req_status.node->id, "[node %s] got pong !", req_status.node->toString().c_str());
|
||||
if (on_done) {
|
||||
@@ -633,7 +657,7 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
sendRequest(req);
|
||||
++out_stats.ping;
|
||||
return req;
|
||||
@@ -660,9 +684,9 @@ NetworkEngine::sendPong(const SockAddr& addr, TransId tid) {
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
}
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, want_t want,
|
||||
RequestCb on_done, RequestExpiredCb on_expired) {
|
||||
Sp<Request>
|
||||
NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
|
||||
RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
auto tid = TransId {TransPrefix::FIND_NODE, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
@@ -687,8 +711,8 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
|
||||
if (on_done) {
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
@@ -699,16 +723,16 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
sendRequest(req);
|
||||
++out_stats.find;
|
||||
return req;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash, const Query& query, want_t want,
|
||||
RequestCb on_done, RequestExpiredCb on_expired) {
|
||||
Sp<Request>
|
||||
NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query& query, want_t want,
|
||||
RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
auto tid = TransId {TransPrefix::GET_VALUES, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
@@ -736,8 +760,8 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
|
||||
if (on_done) {
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
@@ -748,31 +772,49 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
sendRequest(req);
|
||||
++out_stats.get;
|
||||
return req;
|
||||
}
|
||||
|
||||
SockAddr deserializeIPv4(const uint8_t* ni) {
|
||||
SockAddr addr;
|
||||
auto& sin = addr.getIPv4();
|
||||
std::fill_n((uint8_t*)&sin, sizeof(sockaddr_in), 0);
|
||||
addr.setFamily(AF_INET);
|
||||
memcpy(&sin.sin_addr, ni, 4);
|
||||
memcpy(&sin.sin_port, ni + 4, 2);
|
||||
return addr;
|
||||
}
|
||||
SockAddr deserializeIPv6(const uint8_t* ni) {
|
||||
SockAddr addr;
|
||||
auto& sin6 = addr.getIPv6();
|
||||
std::fill_n((uint8_t*)&sin6, sizeof(sockaddr_in6), 0);
|
||||
addr.setFamily(AF_INET6);
|
||||
memcpy(&sin6.sin6_addr, ni, 16);
|
||||
memcpy(&sin6.sin6_port, ni + 16, 2);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::deserializeNodes(ParsedMessage& msg) {
|
||||
NetworkEngine::deserializeNodes(ParsedMessage& msg, const SockAddr& from) {
|
||||
if (msg.nodes4_raw.size() % NODE4_INFO_BUF_LEN != 0 || msg.nodes6_raw.size() % NODE6_INFO_BUF_LEN != 0) {
|
||||
throw DhtProtocolException {DhtProtocolException::WRONG_NODE_INFO_BUF_LEN};
|
||||
} else {
|
||||
// deserialize nodes
|
||||
const auto& now = scheduler.time();
|
||||
SockAddr addr;
|
||||
for (unsigned i = 0; i < msg.nodes4_raw.size() / NODE4_INFO_BUF_LEN; i++) {
|
||||
uint8_t *ni = msg.nodes4_raw.data() + i * NODE4_INFO_BUF_LEN;
|
||||
const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni);
|
||||
if (ni_id == myid)
|
||||
continue;
|
||||
auto sin = (sockaddr_in*)&addr.first;
|
||||
std::fill_n((uint8_t*)sin, sizeof(sockaddr_in), 0);
|
||||
sin->sin_family = AF_INET;
|
||||
memcpy(&sin->sin_addr, ni + ni_id.size(), 4);
|
||||
memcpy(&sin->sin_port, ni + ni_id.size() + 4, 2);
|
||||
addr.second = sizeof(sockaddr_in);
|
||||
SockAddr addr = deserializeIPv4(ni + ni_id.size());
|
||||
if (addr.isLoopback() and from.getFamily() == AF_INET) {
|
||||
auto port = addr.getPort();
|
||||
addr = from;
|
||||
addr.setPort(port);
|
||||
}
|
||||
if (isMartian(addr) || isNodeBlacklisted(addr))
|
||||
continue;
|
||||
msg.nodes4.emplace_back(cache.getNode(ni_id, addr, now, false));
|
||||
@@ -783,12 +825,12 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) {
|
||||
const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni);
|
||||
if (ni_id == myid)
|
||||
continue;
|
||||
auto sin6 = (sockaddr_in6*)&addr.first;
|
||||
std::fill_n((uint8_t*)sin6, sizeof(sockaddr_in6), 0);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
memcpy(&sin6->sin6_addr, ni + HASH_LEN, 16);
|
||||
memcpy(&sin6->sin6_port, ni + HASH_LEN + 16, 2);
|
||||
addr.second = sizeof(sockaddr_in6);
|
||||
SockAddr addr = deserializeIPv6(ni + ni_id.size());
|
||||
if (addr.isLoopback() and from.getFamily() == AF_INET6) {
|
||||
auto port = addr.getPort();
|
||||
addr = from;
|
||||
addr.setPort(port);
|
||||
}
|
||||
if (isMartian(addr) || isNodeBlacklisted(addr))
|
||||
continue;
|
||||
msg.nodes6.emplace_back(cache.getNode(ni_id, addr, now, false));
|
||||
@@ -798,7 +840,7 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) {
|
||||
}
|
||||
|
||||
std::vector<Blob>
|
||||
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<std::shared_ptr<Value>>& st)
|
||||
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<Sp<Value>>& st)
|
||||
{
|
||||
auto svals = serializeValues(st);
|
||||
size_t total_size = 0;
|
||||
@@ -853,7 +895,8 @@ NetworkEngine::sendValueParts(TransId tid, const std::vector<Blob>& svals, const
|
||||
|
||||
void
|
||||
NetworkEngine::sendNodesValues(const SockAddr& addr, TransId tid, const Blob& nodes, const Blob& nodes6,
|
||||
const std::vector<std::shared_ptr<Value>>& st, const Query& query, const Blob& token) {
|
||||
const std::vector<Sp<Value>>& st, const Query& query, const Blob& token)
|
||||
{
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
@@ -909,34 +952,32 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, TransId tid, const Blob& no
|
||||
}
|
||||
|
||||
Blob
|
||||
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes)
|
||||
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<Sp<Node>>& nodes)
|
||||
{
|
||||
std::sort(nodes.begin(), nodes.end(), [&](const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b){
|
||||
std::sort(nodes.begin(), nodes.end(), [&](const Sp<Node>& a, const Sp<Node>& b){
|
||||
return id.xorCmp(a->id, b->id) < 0;
|
||||
});
|
||||
size_t nnode = std::min<size_t>(SEND_NODES, nodes.size());
|
||||
Blob bnodes;
|
||||
if (af == AF_INET) {
|
||||
bnodes.resize(NODE4_INFO_BUF_LEN * nnode);
|
||||
const constexpr size_t size = HASH_LEN + sizeof(in_addr) + sizeof(in_port_t); // 26
|
||||
for (size_t i=0; i<nnode; i++) {
|
||||
const Node& n = *nodes[i];
|
||||
sockaddr_in *sin = (sockaddr_in*)&n.addr.first;
|
||||
auto dest = bnodes.data() + size * i;
|
||||
auto dest = bnodes.data() + NODE4_INFO_BUF_LEN * i;
|
||||
memcpy(dest, n.id.data(), HASH_LEN);
|
||||
memcpy(dest + HASH_LEN, &sin->sin_addr, sizeof(in_addr));
|
||||
memcpy(dest + HASH_LEN + sizeof(in_addr), &sin->sin_port, 2);
|
||||
memcpy(dest + HASH_LEN + sizeof(in_addr), &sin->sin_port, sizeof(in_port_t));
|
||||
}
|
||||
} else if (af == AF_INET6) {
|
||||
bnodes.resize(NODE6_INFO_BUF_LEN * nnode);
|
||||
const constexpr size_t size = HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t); // 38
|
||||
for (size_t i=0; i<nnode; i++) {
|
||||
const Node& n = *nodes[i];
|
||||
sockaddr_in6 *sin6 = (sockaddr_in6*)&n.addr.first;
|
||||
auto dest = bnodes.data() + size * i;
|
||||
auto dest = bnodes.data() + NODE6_INFO_BUF_LEN * i;
|
||||
memcpy(dest, n.id.data(), HASH_LEN);
|
||||
memcpy(dest + HASH_LEN, &sin6->sin6_addr, sizeof(in6_addr));
|
||||
memcpy(dest + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, 2);
|
||||
memcpy(dest + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, sizeof(in_port_t));
|
||||
}
|
||||
}
|
||||
return bnodes;
|
||||
@@ -944,7 +985,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::
|
||||
|
||||
std::pair<Blob, Blob>
|
||||
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
|
||||
std::vector<std::shared_ptr<Node>>& nodes4, std::vector<std::shared_ptr<Node>>& nodes6)
|
||||
std::vector<Sp<Node>>& nodes4, std::vector<Sp<Node>>& nodes6)
|
||||
{
|
||||
if (want < 0)
|
||||
want = af == AF_INET ? WANT4 : WANT6;
|
||||
@@ -960,19 +1001,47 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
|
||||
return {std::move(bnodes4), std::move(bnodes6)};
|
||||
}
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, const Query& query, const Blob& token,
|
||||
RequestCb on_done, RequestExpiredCb on_expired) {
|
||||
auto tid = TransId {TransPrefix::LISTEN, getNewTid()};
|
||||
Sp<Request>
|
||||
NetworkEngine::sendListen(Sp<Node> n,
|
||||
const InfoHash& hash,
|
||||
const Query& query,
|
||||
const Blob& token,
|
||||
Sp<Request> previous,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired,
|
||||
SocketCb&& socket_cb)
|
||||
{
|
||||
Sp<Socket> socket;
|
||||
auto tid = TransId { TransPrefix::LISTEN, previous ? previous->tid.getTid() : getNewTid() };
|
||||
if (previous and previous->node == n) {
|
||||
socket = previous->socket;
|
||||
} else {
|
||||
if (previous)
|
||||
DHT_LOG.e(hash, "[node %s] trying refresh listen contract with wrong node", previous->node->toString().c_str());
|
||||
/* TODO: Manually creating a socket for "listen" backward compatibility.
|
||||
* As soon as this is not an issue anymore, switch to using
|
||||
* ::createSocket function! */
|
||||
auto sid = TransId {TransPrefix::GET_VALUES, tid.getTid()};
|
||||
socket = std::make_shared<Socket>(n, sid, socket_cb);
|
||||
opened_sockets.emplace(sid, socket);
|
||||
}
|
||||
|
||||
if (not socket) {
|
||||
DHT_LOG.e(hash, "[node %s] unable to get a valid socket for listen. Aborting listen", n->toString().c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
auto has_query = query.where.getFilter() or not query.select.getSelection().empty();
|
||||
pk.pack(std::string("a")); pk.pack_map(3 + has_query);
|
||||
pk.pack(std::string("a")); pk.pack_map(4 + has_query);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("h")); pk.pack(infohash);
|
||||
pk.pack(std::string("h")); pk.pack(hash);
|
||||
pk.pack(std::string("token")); packToken(pk, token);
|
||||
pk.pack(std::string("sid")); pk.pack_bin(socket->id.size());
|
||||
pk.pack_bin_body((const char*)socket->id.data(), socket->id.size());
|
||||
if (has_query) {
|
||||
pk.pack(std::string("q")); pk.pack(query);
|
||||
}
|
||||
@@ -986,8 +1055,8 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
|
||||
if (on_done)
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
@@ -996,8 +1065,8 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
|
||||
if (on_expired)
|
||||
on_expired(req_status, done);
|
||||
},
|
||||
true
|
||||
});
|
||||
socket
|
||||
);
|
||||
sendRequest(req);
|
||||
++out_stats.listen;
|
||||
return req;
|
||||
@@ -1024,14 +1093,14 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, TransId tid) {
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
}
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
|
||||
Sp<Request>
|
||||
NetworkEngine::sendAnnounceValue(Sp<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const std::shared_ptr<Value>& value,
|
||||
const Sp<Value>& value,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired)
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired)
|
||||
{
|
||||
auto tid = TransId {TransPrefix::ANNOUNCE_VALUES, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
@@ -1057,8 +1126,8 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
|
||||
if (msg.value_id == Value::INVALID_ID) {
|
||||
DHT_LOG.d(infohash, "Unknown search or announce!");
|
||||
@@ -1075,7 +1144,7 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
sendRequest(req);
|
||||
if (not v.empty())
|
||||
sendValueParts(tid, v, n->addr);
|
||||
@@ -1083,13 +1152,13 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
|
||||
return req;
|
||||
}
|
||||
|
||||
std::shared_ptr<Request>
|
||||
NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
|
||||
Sp<Request>
|
||||
NetworkEngine::sendRefreshValue(Sp<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const Value::Id& vid,
|
||||
const Blob& token,
|
||||
RequestCb on_done,
|
||||
RequestExpiredCb on_expired)
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired)
|
||||
{
|
||||
auto tid = TransId {TransPrefix::REFRESH, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
@@ -1111,8 +1180,8 @@ NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
auto req = std::make_shared<Request>(tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
|
||||
if (msg.value_id == Value::INVALID_ID) {
|
||||
DHT_LOG.d(infohash, "Unknown search or announce!");
|
||||
@@ -1129,11 +1198,10 @@ NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
sendRequest(req);
|
||||
++out_stats.refresh;
|
||||
return req;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1163,7 +1231,8 @@ NetworkEngine::sendError(const SockAddr& addr,
|
||||
TransId tid,
|
||||
uint16_t code,
|
||||
const std::string& message,
|
||||
bool include_id) {
|
||||
bool include_id)
|
||||
{
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4 + (include_id?1:0));
|
||||
@@ -1260,6 +1329,9 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
error_code = e->via.array.ptr[0].as<uint16_t>();
|
||||
}
|
||||
|
||||
if (auto t = findMapValue(req, "sid"))
|
||||
socket_id = {t->as<std::array<char, 4>>()};
|
||||
|
||||
if (auto rid = findMapValue(req, "id"))
|
||||
id = {*rid};
|
||||
|
||||
@@ -1369,9 +1441,9 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
void
|
||||
NetworkEngine::maintainRxBuffer(const TransId& tid)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
auto msg = partial_messages.find(tid);
|
||||
if (msg != partial_messages.end()) {
|
||||
const auto& now = scheduler.time();
|
||||
if (msg->second.start + RX_MAX_PACKET_TIME < now
|
||||
|| msg->second.last_part + RX_TIMEOUT < now) {
|
||||
DHT_LOG.w("Dropping expired partial message from %s", msg->second.from.toString().c_str());
|
||||
@@ -1419,4 +1491,5 @@ ParsedMessage::complete()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} /* namespace net */
|
||||
} /* namespace dht */
|
||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user