mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 20:37:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83f8a92e5e | ||
|
|
f41685b864 | ||
|
|
84adbddd6f | ||
|
|
fa9730dd07 | ||
|
|
33f29e95f4 | ||
|
|
fdfa10bd2e | ||
|
|
f200f9dfc2 | ||
|
|
9615774114 | ||
|
|
c6b0e531c2 | ||
|
|
8e5f12dbf1 | ||
|
|
5bcf1da505 | ||
|
|
97d88fcfed | ||
|
|
963dd6779e | ||
|
|
54a4327039 | ||
|
|
10e5439048 | ||
|
|
dcca94aab7 | ||
|
|
173a9ee642 | ||
|
|
ed1ca6db8f | ||
|
|
7367158284 | ||
|
|
cf8d9ccd0d | ||
|
|
fdbdc91d55 | ||
|
|
cf9c63abb7 | ||
|
|
475b26048f | ||
|
|
df1615e8d1 | ||
|
|
9e461e0960 | ||
|
|
9411fe4e51 | ||
|
|
3a42846f98 | ||
|
|
5ca04b1da4 | ||
|
|
c831ec8f16 | ||
|
|
bd08506146 | ||
|
|
d44c59016e | ||
|
|
4d75f64576 | ||
|
|
c70d5d7b97 | ||
|
|
d0cebaa002 | ||
|
|
564e97fce7 | ||
|
|
172b1089fb | ||
|
|
6cdc242b6e | ||
|
|
ac23464044 | ||
|
|
ce162a39c6 | ||
|
|
db376aa0a2 | ||
|
|
8da15ad450 | ||
|
|
5f1b79e6de | ||
|
|
0e7dda680a | ||
|
|
22958342f1 | ||
|
|
e9094f8f22 | ||
|
|
ff2193dcc6 | ||
|
|
855b69710d | ||
|
|
d93657d6f9 | ||
|
|
2b57c8109a | ||
|
|
84578f7820 | ||
|
|
14cf0b3142 | ||
|
|
18ec3086ee | ||
|
|
f7e01da20d | ||
|
|
a032f50a27 | ||
|
|
8ee0d83ad7 | ||
|
|
f46043069d | ||
|
|
16290961fb | ||
|
|
bad53219c6 | ||
|
|
fc6e884b54 | ||
|
|
9d7f6d287a | ||
|
|
17d57ba04a | ||
|
|
9ad21d5c5d | ||
|
|
891969f5eb | ||
|
|
e68a2fd967 | ||
|
|
cc18afd818 | ||
|
|
467fdef892 | ||
|
|
50678f6d44 | ||
|
|
4622a82847 | ||
|
|
bd72c6468f | ||
|
|
db6c301084 |
No files matched your search
+5
-31
@@ -1,44 +1,18 @@
|
||||
sudo: false
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libgnutls28-dev
|
||||
- cmake
|
||||
|
||||
before_install:
|
||||
- if [ $TRAVIS_OS_NAME == linux ] && [ $CXX == g++ ]; then export CXX=/usr/bin/g++-6 && export CC=/usr/bin/gcc-6; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then git clone https://github.com/msgpack/msgpack-c.git; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then cd msgpack-c && git checkout cpp-1.2.0 && mkdir build && mkdir -p $HOME/usr && cd build; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then cmake -DCMAKE_INSTALL_PREFIX=$HOME/usr -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF .. && make -j && make install && cd ../.. && pwd; fi
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install llvm36 && brew install msgpack && brew install gnutls && brew link --force llvm36; fi
|
||||
|
||||
before_script:
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then travis_retry ./autogen.sh && ./configure --prefix=$HOME/usr; fi
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then travis_retry ./autogen.sh && ./configure; fi
|
||||
- docker pull aberaud/opendht-deps
|
||||
- docker pull aberaud/opendht-deps-llvm
|
||||
|
||||
script:
|
||||
- make -j
|
||||
- docker build -f docker/DockerfileTravis .
|
||||
- docker build -f docker/DockerfileTravisLlvm .
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- adrien.beraud@savoirfairelinux.com
|
||||
|
||||
env:
|
||||
- LANG="en_US.UTF-8"
|
||||
|
||||
os:
|
||||
- osx
|
||||
+3
-2
@@ -1,9 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.8.6)
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 0)
|
||||
set (opendht_VERSION_MINOR 6.0)
|
||||
set (opendht_VERSION_MINOR 6.1)
|
||||
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")
|
||||
|
||||
@@ -120,7 +121,7 @@ if (OPENDHT_SHARED)
|
||||
${opendht_HEADERS}
|
||||
)
|
||||
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
|
||||
#set_target_properties (opendht PROPERTIES SOVERSION 1 VERSION 1.0.0)
|
||||
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
if (OPENDHT_LTO)
|
||||
target_link_libraries(opendht -flto -fuse-linker-plugin)
|
||||
endif ()
|
||||
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
#output directories
|
||||
DebugLib/
|
||||
Debug/
|
||||
ReleaseLib/
|
||||
Release/
|
||||
.config/
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.VC.VC.opendb
|
||||
*.VC.db
|
||||
*.db
|
||||
*.filters
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
!config.h
|
||||
@@ -0,0 +1,257 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
|
||||
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
|
||||
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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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|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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.Build.0 = Release|x64
|
||||
{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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.Build.0 = Release|x64
|
||||
{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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{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|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,224 @@
|
||||
<?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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<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\infohash.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\infohash.h" />
|
||||
<ClInclude Include="..\include\opendht\log.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\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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{711397CE-E5D5-467D-9457-8716C047E50C}</ProjectGuid>
|
||||
<RootNamespace>opendht</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>opendhtd</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>opendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<TargetName>opendhtd</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<TargetName>opendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\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>
|
||||
<ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\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>
|
||||
<ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,292 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2} = {122A2EA4-B283-4241-9655-786DE78283B2}
|
||||
{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}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "..\..\gnutls\MSVC\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}
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C} = {200F3D3C-8B84-46D8-953A-6C0EBD283B5C}
|
||||
{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}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "..\..\nettle\MSVC\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}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "..\..\zlib\MSVC\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
|
||||
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
|
||||
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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
{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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{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}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,71 @@
|
||||
@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
|
||||
@@ -70,33 +70,37 @@ int main()
|
||||
```python
|
||||
import opendht as dht
|
||||
|
||||
r = dht.DhtRunner()
|
||||
r.run()
|
||||
node = dht.DhtRunner()
|
||||
node.run()
|
||||
|
||||
# Join the network through any running node,
|
||||
# here using a known bootstrap node.
|
||||
r.bootstrap("bootstrap.ring.cx", "4222")
|
||||
|
||||
r.put(dht.InfoHash.get("unique_key"), dht.Value(b'some binary data'))
|
||||
node.bootstrap("bootstrap.ring.cx", "4222")
|
||||
|
||||
# blocking call (provide callback arguments to make the call non-blocking)
|
||||
results = r.get(dht.InfoHash.get("unique_key"))
|
||||
node.put(dht.InfoHash.get("unique_key"), dht.Value(b'some binary data'))
|
||||
|
||||
results = node.get(dht.InfoHash.get("unique_key"))
|
||||
for r in results:
|
||||
print(r)
|
||||
```
|
||||
|
||||
Licence
|
||||
-
|
||||
Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
|
||||
Licenced under the GNU General Public License version 3, though the core routing library (dht.cpp) is licenced under the MIT licence.
|
||||
|
||||
This project is independent from another project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
|
||||
|
||||
Dependencies
|
||||
-
|
||||
- msgpack-c 1.2+, used for data serialization.
|
||||
- GnuTLS 3.1+, 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 Microsoft Visual Studio 2015
|
||||
|
||||
Licence
|
||||
-
|
||||
Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
|
||||
Licenced under the GNU General Public License version 3 (see COPYING for the full licence).
|
||||
|
||||
This project is independent from another project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
|
||||
|
||||
Donations
|
||||
-
|
||||
We gratefully accept Bitcoin donations to support OpenDHT development at: `bitcoin:3EykSd1An888efq4Bq3KaV3hJ3JQ4FPnwm`.
|
||||
+9
-9
@@ -1,4 +1,4 @@
|
||||
AC_INIT(opendht, 0.6.0)
|
||||
AC_INIT(opendht, 0.6.1)
|
||||
AC_CONFIG_AUX_DIR(ac)
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -14,11 +14,11 @@ AC_PROG_CXX
|
||||
AM_PROG_AR
|
||||
|
||||
dnl Check for Doxygen
|
||||
AC_ARG_ENABLE([doc], [AS_HELP_STRING([--disable-doc], [Disable documentation generation (doxygen)])])
|
||||
AS_IF([test "x$enable_doc" != "xno"], [
|
||||
AC_ARG_ENABLE([doc], AS_HELP_STRING([--enable-doc], [Enable documentation generation (doxygen)]))
|
||||
AS_IF([test "x$enable_doc" = "xyes"], [
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
AS_IF([test -z "$DOXYGEN"],[AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])])
|
||||
])
|
||||
AS_IF([test -z "$DOXYGEN"], [AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
|
||||
|
||||
dnl Check for Python
|
||||
@@ -72,12 +72,12 @@ AS_IF([test "x$SYS" = "xandroid"],
|
||||
LT_INIT()
|
||||
LT_LANG(C++)
|
||||
|
||||
AX_CXX_COMPILE_STDCXX(14,[noext],[mandatory])
|
||||
AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
|
||||
|
||||
PKG_PROG_PKG_CONFIG()
|
||||
PKG_CHECK_MODULES([nettle], [nettle >= 2.4])
|
||||
PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.1])
|
||||
PKG_CHECK_MODULES([msgpack], [msgpack >= 1.2])
|
||||
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
|
||||
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.1])
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
|
||||
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM ubuntu:16.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
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-1.4.2/msgpack-1.4.2.tar.gz \
|
||||
&& tar -xzf msgpack-1.4.2.tar.gz \
|
||||
&& cd msgpack-1.4.2 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-1.4.2
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-1.4.2/msgpack-1.4.2.tar.gz \
|
||||
&& tar -xzf msgpack-1.4.2.tar.gz \
|
||||
&& cd msgpack-1.4.2 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-1.4.2
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps-llvm
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps-llvm
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
class Node;
|
||||
struct Node;
|
||||
|
||||
enum class NodeStatus {
|
||||
Disconnected, // 0 nodes
|
||||
|
||||
@@ -31,6 +31,10 @@ extern "C" {
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <iso646.h>
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ private:
|
||||
|
||||
public:
|
||||
virtual void unpackValue(const Value& v) override {
|
||||
from = v.owner.getId();
|
||||
if (v.owner)
|
||||
from = v.owner->getId();
|
||||
BaseClass::unpackValue(v);
|
||||
}
|
||||
|
||||
|
||||
+36
-13
@@ -39,6 +39,10 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <iso646.h>
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
|
||||
struct Request;
|
||||
@@ -98,7 +102,7 @@ public:
|
||||
/**
|
||||
* Enable or disable logging of DHT internal messages
|
||||
*/
|
||||
void setLoggers(LogMethod&& error = NOLOG, LogMethod&& warn = NOLOG, LogMethod&& debug = NOLOG);
|
||||
void setLoggers(LogMethod error = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG);
|
||||
|
||||
virtual void registerType(const ValueType& type) {
|
||||
types[type.id] = type;
|
||||
@@ -163,16 +167,35 @@ public:
|
||||
* reannounced on a regular basis.
|
||||
* User can call #cancelPut(InfoHash, Value::Id) to cancel a put operation.
|
||||
*/
|
||||
void put(const InfoHash& key, std::shared_ptr<Value>, DoneCallback cb=nullptr, time_point created=time_point::max());
|
||||
void put(const InfoHash& key, const std::shared_ptr<Value>& v, DoneCallbackSimple cb, time_point created=time_point::max()) {
|
||||
put(key, v, bindDoneCb(cb), created);
|
||||
void put(const InfoHash& key,
|
||||
std::shared_ptr<Value>,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false);
|
||||
void put(const InfoHash& key,
|
||||
const std::shared_ptr<Value>& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
{
|
||||
put(key, v, bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
|
||||
void put(const InfoHash& key, Value&& v, DoneCallback cb=nullptr, time_point created=time_point::max()) {
|
||||
put(key, std::make_shared<Value>(std::move(v)), cb, created);
|
||||
void put(const InfoHash& key,
|
||||
Value&& v,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
{
|
||||
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
|
||||
}
|
||||
void put(const InfoHash& key, Value&& v, DoneCallbackSimple cb, time_point created=time_point::max()) {
|
||||
put(key, std::forward<Value>(v), bindDoneCb(cb), created);
|
||||
void put(const InfoHash& key,
|
||||
Value&& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
{
|
||||
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,10 +286,10 @@ private:
|
||||
static constexpr unsigned SEARCH_REQUESTS {4};
|
||||
|
||||
/* Number of listening nodes */
|
||||
static constexpr unsigned LISTEN_NODES {3};
|
||||
static constexpr unsigned LISTEN_NODES {4};
|
||||
|
||||
/* The maximum number of values we store for a given hash. */
|
||||
static constexpr unsigned MAX_VALUES {2048};
|
||||
static constexpr unsigned MAX_VALUES {1024};
|
||||
|
||||
/* The maximum number of hashes we're willing to track. */
|
||||
static constexpr unsigned MAX_HASHES {16384};
|
||||
@@ -302,6 +325,7 @@ private:
|
||||
* A single "put" operation data
|
||||
*/
|
||||
struct Announce {
|
||||
bool permanent;
|
||||
std::shared_ptr<Value> value;
|
||||
time_point created;
|
||||
DoneCallback callback;
|
||||
@@ -440,7 +464,7 @@ private:
|
||||
void dumpBucket(const Bucket& b, std::ostream& out) const;
|
||||
|
||||
// Nodes
|
||||
std::shared_ptr<Node> newNode(const std::shared_ptr<Node>& node, int confirm);
|
||||
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);
|
||||
@@ -453,10 +477,9 @@ private:
|
||||
* The values can be filtered by an arbitrary provided filter.
|
||||
*/
|
||||
std::shared_ptr<Search> search(const InfoHash& id, sa_family_t af, GetCallback = nullptr, DoneCallback = nullptr, Value::Filter = Value::AllFilter());
|
||||
void announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created=time_point::max());
|
||||
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());
|
||||
|
||||
std::shared_ptr<Search> newSearch(InfoHash id, sa_family_t af);
|
||||
void bootstrapSearch(Search& sr);
|
||||
Search *findSearch(unsigned short tid, sa_family_t af);
|
||||
void expireSearches();
|
||||
|
||||
+14
-14
@@ -156,16 +156,16 @@ public:
|
||||
void cancelListen(InfoHash h, size_t token);
|
||||
void cancelListen(InfoHash h, std::shared_future<size_t> token);
|
||||
|
||||
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={});
|
||||
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
|
||||
put(hash, value, bindDoneCb(cb));
|
||||
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
|
||||
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
put(hash, value, bindDoneCb(cb), permanent);
|
||||
}
|
||||
|
||||
void put(InfoHash hash, Value&& value, DoneCallback cb={});
|
||||
void put(InfoHash hash, Value&& value, DoneCallbackSimple cb) {
|
||||
put(hash, std::forward<Value>(value), bindDoneCb(cb));
|
||||
void put(InfoHash hash, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
void put(InfoHash hash, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
put(hash, std::forward<Value>(value), bindDoneCb(cb), permanent);
|
||||
}
|
||||
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={});
|
||||
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={}, bool permanent = false);
|
||||
|
||||
void cancelPut(const InfoHash& h, const Value::Id& id);
|
||||
|
||||
@@ -232,7 +232,7 @@ public:
|
||||
|
||||
std::vector<ValuesExport> exportValues() const;
|
||||
|
||||
void setLoggers(LogMethod&& error = NOLOG, LogMethod&& warn = NOLOG, LogMethod&& debug = NOLOG);
|
||||
void setLoggers(LogMethod err = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG);
|
||||
|
||||
void registerType(const ValueType& type);
|
||||
|
||||
@@ -270,14 +270,14 @@ public:
|
||||
*/
|
||||
void run(in_port_t port, const crypto::Identity identity, bool threaded = false, bool is_bootstrap = false) {
|
||||
run(port, {
|
||||
.dht_config = {
|
||||
.node_config = {
|
||||
.node_id = {},
|
||||
.is_bootstrap = is_bootstrap
|
||||
/*.dht_config = */{
|
||||
/*.node_config = */{
|
||||
/*.node_id = */{},
|
||||
/*.is_bootstrap = */is_bootstrap
|
||||
},
|
||||
.id = identity
|
||||
/*.id = */identity
|
||||
},
|
||||
.threaded = threaded
|
||||
/*.threaded = */threaded
|
||||
});
|
||||
}
|
||||
void run(in_port_t port, Config config);
|
||||
|
||||
@@ -21,6 +21,19 @@
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#ifdef __ANDROID__
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
#else
|
||||
#include <iso646.h>
|
||||
#include <ws2tcpip.h>
|
||||
typedef uint16_t sa_family_t;
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <array>
|
||||
@@ -29,6 +42,7 @@
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
// bytes
|
||||
#define HASH_LEN 20u
|
||||
|
||||
@@ -82,7 +96,11 @@ 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
|
||||
return std::memcmp(id1.data(), id2.data(), HASH_LEN);
|
||||
}
|
||||
|
||||
@@ -197,12 +215,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
static constexpr InfoHash zeroes {};
|
||||
static constexpr InfoHash ones = {std::array<uint8_t, HASH_LEN>{{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF
|
||||
}}};
|
||||
static constexpr const InfoHash zeroes {};
|
||||
|
||||
struct NodeExport {
|
||||
InfoHash id;
|
||||
|
||||
@@ -187,7 +187,7 @@ private:
|
||||
* @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.
|
||||
*/
|
||||
std::function<std::shared_ptr<Node>(const std::shared_ptr<Node>&, int)> onNewNode;
|
||||
std::function<void(const std::shared_ptr<Node>&, int)> onNewNode;
|
||||
/**
|
||||
* @brief when an addres is reported from a distant node.
|
||||
*
|
||||
|
||||
+15
-17
@@ -18,38 +18,34 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "infohash.h" // includes socket structures
|
||||
#include "utils.h"
|
||||
#include "infohash.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace dht {
|
||||
|
||||
class Request;
|
||||
struct Request;
|
||||
|
||||
struct Node {
|
||||
friend class NetworkEngine;
|
||||
|
||||
InfoHash id {};
|
||||
sockaddr_storage ss;
|
||||
InfoHash id;
|
||||
|
||||
socklen_t sslen {0};
|
||||
sockaddr_storage ss;
|
||||
|
||||
time_point time {time_point::min()}; /* last time eared about */
|
||||
time_point reply_time {time_point::min()}; /* time of last correct reply received */
|
||||
|
||||
Node() : ss() {
|
||||
std::fill_n((uint8_t*)&ss, sizeof(ss), 0);
|
||||
}
|
||||
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen)
|
||||
: id(id), ss(), sslen(salen) {
|
||||
std::copy_n((const uint8_t*)sa, salen, (uint8_t*)&ss);
|
||||
if ((unsigned)salen < sizeof(ss))
|
||||
std::fill_n((uint8_t*)&ss+salen, sizeof(ss)-salen, 0);
|
||||
}
|
||||
: id(id), sslen(salen), ss() {
|
||||
std::copy_n((const uint8_t*)sa, salen, (uint8_t*)&ss);
|
||||
if ((unsigned)salen < sizeof(ss))
|
||||
std::fill_n((uint8_t*)&ss+salen, sizeof(ss)-salen, 0);
|
||||
}
|
||||
InfoHash getId() const {
|
||||
return id;
|
||||
}
|
||||
@@ -61,7 +57,9 @@ struct Node {
|
||||
}
|
||||
bool isExpired() const { return expired_; }
|
||||
bool isGood(time_point now) const;
|
||||
bool isMessagePending() const;
|
||||
bool isPendingMessage() const;
|
||||
size_t getPendingMessageCount() const;
|
||||
|
||||
NodeExport exportNode() const { return NodeExport {id, ss, sslen}; }
|
||||
sa_family_t getFamily() const { return ss.ss_family; }
|
||||
|
||||
@@ -87,7 +85,7 @@ struct Node {
|
||||
static constexpr const std::chrono::minutes NODE_EXPIRE_TIME {10};
|
||||
|
||||
/* Time for a request to timeout */
|
||||
static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {3};
|
||||
static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {1};
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace dht {
|
||||
|
||||
class NetworkEngine;
|
||||
class ParsedMessage;
|
||||
struct ParsedMessage;
|
||||
|
||||
/*!
|
||||
* @class Request
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
|
||||
#ifndef WIN32_NATIVE
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
@@ -99,6 +102,9 @@ private:
|
||||
|
||||
using random_device = std::random_device;
|
||||
|
||||
#endif
|
||||
#else
|
||||
using random_device = std::random_device;
|
||||
#endif
|
||||
|
||||
}} // dht::crypto
|
||||
@@ -37,8 +37,7 @@ namespace dht {
|
||||
class Scheduler {
|
||||
public:
|
||||
struct Job {
|
||||
bool done;
|
||||
bool cancelled;
|
||||
Job(std::function<void()>&& f) : do_(std::forward<std::function<void()>>(f)) {}
|
||||
std::function<void()> do_;
|
||||
};
|
||||
|
||||
@@ -50,9 +49,8 @@ public:
|
||||
*
|
||||
* @return pointer to the newly scheduled job.
|
||||
*/
|
||||
std::shared_ptr<Scheduler::Job> add(time_point t, std::function<void()> job_func) {
|
||||
//std::cout << "Scheduler: adding " << (job_func ? "" : "empty") << " job in " << print_dt(t - clock::now()) << std::endl;
|
||||
auto job = std::make_shared<Job>(Job {false, false, std::move(job_func)});
|
||||
std::shared_ptr<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
|
||||
auto job = std::make_shared<Job>(std::forward<std::function<void()>>(job_func));
|
||||
if (t != time_point::max())
|
||||
timers.emplace(std::move(t), job);
|
||||
return job;
|
||||
@@ -68,15 +66,12 @@ public:
|
||||
*/
|
||||
void edit(std::shared_ptr<Scheduler::Job>& job, time_point t) {
|
||||
if (not job) {
|
||||
std::cout << "editing an empty job" << std::endl;
|
||||
std::cerr << "editing an empty job" << std::endl;
|
||||
return;
|
||||
}
|
||||
job->cancelled = true;
|
||||
job = add(t, std::move(job->do_));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Runs the jobs to do up to now.
|
||||
*
|
||||
@@ -94,12 +89,9 @@ public:
|
||||
if (timer->first > now)
|
||||
break;
|
||||
|
||||
auto& job = timer->second;
|
||||
if (not job->cancelled and job->do_) {
|
||||
job->do_();
|
||||
//job->do_ = {};
|
||||
job->done = true;
|
||||
}
|
||||
const auto& job = *timer->second;
|
||||
if (job.do_)
|
||||
job.do_();
|
||||
timers.erase(timer);
|
||||
}
|
||||
return getNextJobTime();
|
||||
@@ -108,7 +100,7 @@ public:
|
||||
inline time_point getNextJobTime() const {
|
||||
//if (not timers.empty())
|
||||
// std::cout << "Next job in " << print_dt(timers.begin()->first - clock::now()) << std::endl;
|
||||
return not timers.empty() ? timers.begin()->first : time_point::max();
|
||||
return timers.empty() ? time_point::max() : timers.begin()->first;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,9 +101,9 @@ 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);
|
||||
void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback) {
|
||||
putSigned(hash, std::make_shared<Value>(std::move(v)), callback);
|
||||
void putSigned(const InfoHash& hash, std::shared_ptr<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,9 +111,9 @@ 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);
|
||||
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback) {
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback);
|
||||
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, Value&& v, DoneCallback callback, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,14 +126,13 @@ 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);
|
||||
|
||||
const std::shared_ptr<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
void registerCertificate(std::shared_ptr<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;
|
||||
|
||||
/**
|
||||
* Allows to set a custom callback called by the library to find a locally-stored certificate.
|
||||
@@ -159,6 +158,7 @@ private:
|
||||
|
||||
// our certificate cache
|
||||
std::map<InfoHash, std::shared_ptr<crypto::Certificate>> nodesCertificates_ {};
|
||||
std::map<InfoHash, std::shared_ptr<const crypto::PublicKey>> nodesPubKeys_ {};
|
||||
|
||||
std::uniform_int_distribution<Value::Id> rand_id {};
|
||||
};
|
||||
|
||||
@@ -24,6 +24,13 @@
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#include <ws2def.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
#include <functional>
|
||||
@@ -122,7 +129,7 @@ struct LogMethod {
|
||||
void logPrintable(const uint8_t *buf, size_t buflen) const {
|
||||
std::string buf_clean(buflen, '\0');
|
||||
for (size_t i=0; i<buflen; i++)
|
||||
buf_clean[i] = std::isprint(buf[i]) ? buf[i] : '.';
|
||||
buf_clean[i] = isprint(buf[i]) ? buf[i] : '.';
|
||||
(*this)("%s", buf_clean.c_str());
|
||||
}
|
||||
private:
|
||||
@@ -132,7 +139,7 @@ private:
|
||||
struct Logger {
|
||||
LogMethod DEBUG = NOLOG;
|
||||
LogMethod WARN = NOLOG;
|
||||
LogMethod ERROR = NOLOG;
|
||||
LogMethod ERR = NOLOG;
|
||||
};
|
||||
|
||||
// Serialization related definitions and utility functions
|
||||
|
||||
+59
-25
@@ -26,18 +26,6 @@
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#ifdef __ANDROID__
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
typedef uint16_t sa_family_t;
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <bitset>
|
||||
@@ -80,17 +68,23 @@ using StorePolicy = std::function<bool(InfoHash key, std::shared_ptr<Value>& val
|
||||
*/
|
||||
using EditPolicy = std::function<bool(InfoHash key, const std::shared_ptr<Value>& old_val, std::shared_ptr<Value>& new_val, InfoHash from, const sockaddr* from_addr, socklen_t from_len)>;
|
||||
|
||||
static constexpr const size_t MAX_VALUE_SIZE {1024 * 56};
|
||||
static constexpr const size_t MAX_VALUE_SIZE {1024 * 14};
|
||||
|
||||
struct ValueType {
|
||||
typedef uint16_t Id;
|
||||
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t);
|
||||
static bool DEFAULT_EDIT_POLICY(InfoHash, const std::shared_ptr<Value>&, std::shared_ptr<Value>&, InfoHash, const sockaddr*, socklen_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueType () {}
|
||||
|
||||
ValueType (Id id, std::string name, duration e = std::chrono::minutes(10))
|
||||
: id(id), name(name), expiration(e) {}
|
||||
|
||||
ValueType (Id id, std::string name, duration e, StorePolicy&& sp, EditPolicy&& ep)
|
||||
: id(id), name(name), expiration(e), storePolicy(std::move(sp)), editPolicy(std::move(ep)) {}
|
||||
ValueType (Id id, std::string name, duration e, StorePolicy sp, EditPolicy ep = DEFAULT_EDIT_POLICY)
|
||||
: id(id), name(name), expiration(e), storePolicy(sp), editPolicy(ep) {}
|
||||
|
||||
virtual ~ValueType() {}
|
||||
|
||||
@@ -101,10 +95,6 @@ struct ValueType {
|
||||
// Generic value type
|
||||
static const ValueType USER_DATA;
|
||||
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t);
|
||||
static bool DEFAULT_EDIT_POLICY(InfoHash, const std::shared_ptr<Value>&, std::shared_ptr<Value>&, InfoHash, const sockaddr*, socklen_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Id id {0};
|
||||
std::string name {};
|
||||
@@ -255,7 +245,44 @@ struct Value
|
||||
return not cypher.empty();
|
||||
}
|
||||
bool isSigned() const {
|
||||
return not signature.empty();
|
||||
return owner and not signature.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign the value using the provided private key.
|
||||
* Afterward, checkSignature() will return true and owner will
|
||||
* be set to the corresponding public key.
|
||||
*/
|
||||
void sign(const crypto::PrivateKey& key) {
|
||||
if (isEncrypted())
|
||||
throw DhtException("Can't sign encrypted data.");
|
||||
owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
|
||||
signature = key.sign(getToSign());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the value is signed and that the signature matches.
|
||||
* If true, the owner field will contain the signer public key.
|
||||
*/
|
||||
bool checkSignature() const {
|
||||
return isSigned() and owner->checkSignature(getToSign(), signature);
|
||||
}
|
||||
|
||||
std::shared_ptr<const crypto::PublicKey> getOwner() const {
|
||||
return std::static_pointer_cast<const crypto::PublicKey>(owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign the value with from and returns the encrypted version for to.
|
||||
*/
|
||||
Value encrypt(const crypto::PrivateKey& from, const crypto::PublicKey& to) {
|
||||
if (isEncrypted())
|
||||
throw DhtException("Data is already encrypted.");
|
||||
setRecipient(to.getId());
|
||||
sign(from);
|
||||
Value nv {id};
|
||||
nv.setCypher(to.encrypt(getToEncrypt()));
|
||||
return nv;
|
||||
}
|
||||
|
||||
Value() {}
|
||||
@@ -301,7 +328,7 @@ struct Value
|
||||
inline bool operator== (const Value& o) {
|
||||
return id == o.id &&
|
||||
(isEncrypted() ? cypher == o.cypher :
|
||||
(owner == o.owner && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature));
|
||||
((owner == o.owner || *owner == *o.owner) && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature));
|
||||
}
|
||||
|
||||
void setRecipient(const InfoHash& r) {
|
||||
@@ -347,10 +374,11 @@ struct Value
|
||||
template <typename Packer>
|
||||
void msgpack_pack_to_sign(Packer& pk) const
|
||||
{
|
||||
pk.pack_map((user_type.empty()?0:1) + (owner?(recipient == InfoHash() ? 4 : 5):2));
|
||||
if (owner) { // isSigned
|
||||
bool has_owner = owner && *owner;
|
||||
pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient == InfoHash() ? 4 : 5):2));
|
||||
if (has_owner) { // isSigned
|
||||
pk.pack(std::string("seq")); pk.pack(seq);
|
||||
pk.pack(std::string("owner")); owner.msgpack_pack(pk);
|
||||
pk.pack(std::string("owner")); owner->msgpack_pack(pk);
|
||||
if (recipient != InfoHash()) {
|
||||
pk.pack(std::string("to")); pk.pack(recipient);
|
||||
}
|
||||
@@ -389,13 +417,19 @@ struct Value
|
||||
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
void msgpack_unpack_body(const msgpack::object& o);
|
||||
Blob getPacked() const {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack(*this);
|
||||
return {buffer.data(), buffer.data()+buffer.size()};
|
||||
}
|
||||
|
||||
Id id {INVALID_ID};
|
||||
|
||||
/**
|
||||
* Public key of the signer.
|
||||
*/
|
||||
crypto::PublicKey owner {};
|
||||
std::shared_ptr<const crypto::PublicKey> owner {};
|
||||
|
||||
/**
|
||||
* Hash of the recipient (optional).
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXX and CXXCPP to enable
|
||||
# support.
|
||||
#
|
||||
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
|
||||
# macro with the version set to C++11. The two optional arguments are
|
||||
# forwarded literally as the second and third argument respectively.
|
||||
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
|
||||
# more information. If you want to use this macro, you also need to
|
||||
# download the ax_cxx_compile_stdcxx.m4 file.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 17
|
||||
|
||||
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])])
|
||||
@@ -1,34 +0,0 @@
|
||||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_14.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_14([ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++14
|
||||
# standard; if necessary, add switches to CXX and CXXCPP to enable
|
||||
# support.
|
||||
#
|
||||
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
|
||||
# macro with the version set to C++14. The two optional arguments are
|
||||
# forwarded literally as the second and third argument respectively.
|
||||
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
|
||||
# more information. If you want to use this macro, you also need to
|
||||
# download the ax_cxx_compile_stdcxx.m4 file.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 4
|
||||
|
||||
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_14], [AX_CXX_COMPILE_STDCXX([14], [$1], [$2])])
|
||||
@@ -6,4 +6,6 @@ Name: OpenDHT
|
||||
Description: C++ Distributed Hash Table library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lopendht
|
||||
Libs.private: -lpthread
|
||||
Requires.private: gnutls >= 3.1
|
||||
Cflags: -I${includedir}
|
||||
@@ -8,4 +8,4 @@ add_custom_target(python ALL
|
||||
COMMAND python3 setup.py build
|
||||
DEPENDS opendht opendht_cpp.pxd opendht.pyx)
|
||||
|
||||
install(CODE "execute_process(COMMAND python3 setup.py install WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
|
||||
install(CODE "execute_process(COMMAND python3 setup.py install --root=\$ENV{DESTDIR}/ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
|
||||
+1
-1
@@ -13,7 +13,7 @@ clean-local:
|
||||
rm -rf $(builddir)/build $(builddir)/*.so $(PYTHON_INSTALL_RECORD)
|
||||
|
||||
install-exec-local:
|
||||
$(PYTHON) setup.py install --record $(PYTHON_INSTALL_RECORD)
|
||||
$(PYTHON) setup.py install --root=$(DESTDIR)/ --record $(PYTHON_INSTALL_RECORD)
|
||||
rm -rf $(builddir)/build
|
||||
|
||||
if HAVE_PIP
|
||||
|
||||
+24
-4
@@ -139,7 +139,7 @@ cdef class Value(object):
|
||||
property owner:
|
||||
def __get__(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._value.get().owner.getId()
|
||||
h._infohash = self._value.get().owner.get().getId()
|
||||
return h
|
||||
property recipient:
|
||||
def __get__(self):
|
||||
@@ -158,6 +158,9 @@ cdef class Value(object):
|
||||
return self._value.get().id
|
||||
def __set__(self, cpp.uint64_t value):
|
||||
self._value.get().id = value
|
||||
property size:
|
||||
def __get__(self):
|
||||
return self._value.get().size()
|
||||
|
||||
cdef class NodeSetIter(object):
|
||||
cdef map[cpp.InfoHash, cpp.shared_ptr[cpp.Node]]* _nodes
|
||||
@@ -335,9 +338,26 @@ cdef class DhtRunner(_WithID):
|
||||
val -- the value to put on the DHT
|
||||
done_cb -- optional callback called when the operation is completed.
|
||||
"""
|
||||
cb_obj = {'done':done_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
self.thisptr.put(key._infohash, val._value, cpp.bindDoneCb(done_callback, <void*>cb_obj))
|
||||
if done_cb:
|
||||
cb_obj = {'done':done_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
self.thisptr.put(key._infohash, val._value, cpp.bindDoneCb(done_callback, <void*>cb_obj))
|
||||
else:
|
||||
lock = threading.Condition()
|
||||
pending = 0
|
||||
ok = False
|
||||
def tmp_done(ok_ret, nodes):
|
||||
nonlocal pending, ok, lock
|
||||
with lock:
|
||||
ok = ok_ret
|
||||
pending -= 1
|
||||
lock.notify()
|
||||
with lock:
|
||||
pending += 1
|
||||
self.put(key, val, done_cb=tmp_done)
|
||||
while pending > 0:
|
||||
lock.wait()
|
||||
return ok
|
||||
def listen(self, InfoHash key, get_cb):
|
||||
t = ListenToken()
|
||||
t._h = key._infohash
|
||||
|
||||
@@ -85,8 +85,9 @@ cdef extern from "opendht/value.h" namespace "dht":
|
||||
Value(vector[uint8_t]) except +
|
||||
Value(const uint8_t* dat_ptr, size_t dat_len) except +
|
||||
string toString() const
|
||||
size_t size() const
|
||||
uint64_t id
|
||||
PublicKey owner
|
||||
shared_ptr[PublicKey] owner
|
||||
InfoHash recipient
|
||||
vector[uint8_t] data
|
||||
string user_type
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# Benchmark
|
||||
|
||||
The `benchmark.py` script is used for testing OpenDHT in various cases. If you
|
||||
run `benchmark.py --help`, you should find the following text:
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--performance Launches performance benchmark test. Available args
|
||||
for "-t" are: gets.
|
||||
--data-persistence Launches data persistence benchmark test. Available
|
||||
args for "-t" are: delete, replace, mult_time.
|
||||
Available args for "-o" are : dump_str_log,
|
||||
keep_alive, trigger, traffic_plot, op_plot. Use "-m"
|
||||
to specify the number of producers on the DHT.Use "-e"
|
||||
to specify the number of values to put on the DHT.
|
||||
|
||||
These options specify the feature to be tested. Each feature has its own tests.
|
||||
You specify the test by using `-t` flag (see `benchmark.py --help` for full
|
||||
help).
|
||||
|
||||
## Python dependencies
|
||||
|
||||
- pyroute2 >=0.3.14
|
||||
- matplotlib
|
||||
- GeoIP (used by `scanner.py` for drawing map of the world)
|
||||
- ipaddress
|
||||
- netifaces
|
||||
- networkx
|
||||
- numpy
|
||||
|
||||
## Usage
|
||||
|
||||
Before running the script, you have to build and install OpenDHT and its cython
|
||||
wrapper (`cython3` has to be installed) on the system so that it can be found by
|
||||
the benchmark script.
|
||||
|
||||
$ cd $OPENDHT_SRC_DIR
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make && sudo make install
|
||||
|
||||
Then, you can use the script like so:
|
||||
|
||||
$ cd $OPENDHT_SRC_DIR/python/tools/
|
||||
$ python3 benchmark.py --performance -t gets -n 2048
|
||||
@@ -273,13 +273,11 @@ class DhtNetwork(object):
|
||||
@staticmethod
|
||||
def run_node(ip4, ip6, p, bootstrap=[], is_bootstrap=False):
|
||||
DhtNetwork.log("run_node", ip4, ip6, p, bootstrap)
|
||||
id = Identity()
|
||||
#id.generate("dhtbench"+str(p), Identity(), 1024)
|
||||
n = DhtRunner()
|
||||
n.run(id, ipv4=ip4 if ip4 else "", ipv6=ip6 if ip6 else "", port=p, is_bootstrap=is_bootstrap)
|
||||
n.run(ipv4=ip4 if ip4 else "", ipv6=ip6 if ip6 else "", port=p, is_bootstrap=is_bootstrap)
|
||||
for b in bootstrap:
|
||||
n.bootstrap(b[0], b[1])
|
||||
#plt.pause(0.02)
|
||||
time.sleep(.01)
|
||||
return ((ip4, ip6, p), n, id)
|
||||
|
||||
@staticmethod
|
||||
@@ -387,11 +385,11 @@ class DhtNetwork(object):
|
||||
if n == l:
|
||||
return
|
||||
if n > l:
|
||||
DhtNetwork.log("Launching", n-l, "nodes")
|
||||
DhtNetwork.log("Launching", n-l, "nodes", self.ip4, self.ip6)
|
||||
for i in range(l, n):
|
||||
self.launch_node()
|
||||
else:
|
||||
DhtNetwork.log("Ending", l-n, "nodes")
|
||||
DhtNetwork.log("Ending", l-n, "nodes", self.ip4, self.ip6)
|
||||
#random.shuffle(self.nodes)
|
||||
for i in range(n, l):
|
||||
self.end_node()
|
||||
|
||||
+22
-16
@@ -208,23 +208,23 @@ class DhtFeatureTest(FeatureTest):
|
||||
FeatureTest.lock.notify()
|
||||
|
||||
def _dhtPut(self, producer, _hash, *values):
|
||||
for val in values:
|
||||
with FeatureTest.lock:
|
||||
vstr = val.__str__()[:100]
|
||||
DhtNetwork.log('[PUT]:', _hash.toString(), '->', vstr + ("..." if len(vstr) > 100 else ""))
|
||||
FeatureTest.done += 1
|
||||
while FeatureTest.done > 0:
|
||||
with FeatureTest.lock:
|
||||
for val in values:
|
||||
vstr = val.__str__()[:100]
|
||||
DhtNetwork.log('[PUT]:', _hash.toString(), '->', vstr + ("..." if len(vstr) > 100 else ""))
|
||||
FeatureTest.done += 1
|
||||
producer.put(_hash, val, DhtFeatureTest.putDoneCb)
|
||||
FeatureTest.lock.wait()
|
||||
while FeatureTest.done > 0:
|
||||
FeatureTest.lock.wait()
|
||||
|
||||
def _dhtGet(self, consumer, _hash):
|
||||
DhtFeatureTest.foreignValues = []
|
||||
DhtFeatureTest.foreignNodes = []
|
||||
with FeatureTest.lock:
|
||||
FeatureTest.done += 1
|
||||
DhtNetwork.log('[GET]:', _hash.toString())
|
||||
consumer.get(_hash, DhtFeatureTest.getcb, DhtFeatureTest.getDoneCb)
|
||||
while FeatureTest.done > 0:
|
||||
DhtNetwork.log('[GET]:', _hash.toString())
|
||||
consumer.get(_hash, DhtFeatureTest.getcb, DhtFeatureTest.getDoneCb)
|
||||
FeatureTest.lock.wait()
|
||||
|
||||
def _gottaGetThemAllPokeNodes(self, consumer, hashes, nodes=None):
|
||||
@@ -356,7 +356,7 @@ class PersistenceTest(DhtFeatureTest):
|
||||
bootstrap = self.bootstrap
|
||||
# Value representing an ICE packet. Each ICE packet is around 1KB.
|
||||
VALUE_SIZE = 1024
|
||||
NUM_VALUES = self._num_values/wb.node_num if self._num_values else 50
|
||||
NUM_VALUES = self._num_values/wb.node_num if self._num_values else 5
|
||||
nr_values = NUM_VALUES * wb.node_num
|
||||
nr_nodes = wb.node_num
|
||||
nr_nodes_cv = threading.Condition()
|
||||
@@ -365,8 +365,11 @@ class PersistenceTest(DhtFeatureTest):
|
||||
hashes = [random_hash() for _ in range(wb.node_num)]
|
||||
|
||||
# initial set of values
|
||||
i = 0
|
||||
for h in hashes:
|
||||
self._dhtPut(bootstrap.front(), h, *[Value(v) for v in values])
|
||||
print("at: ", i)
|
||||
i += 1
|
||||
|
||||
def normalBehavior(do, t, log=None):
|
||||
nonlocal nr_values
|
||||
@@ -636,7 +639,7 @@ class PerformanceTest(DhtFeatureTest):
|
||||
hax.set_ylim(0, 2)
|
||||
|
||||
# let the network stabilise
|
||||
plt.pause(60)
|
||||
plt.pause(20)
|
||||
|
||||
#start = time.time()
|
||||
times = []
|
||||
@@ -649,7 +652,7 @@ class PerformanceTest(DhtFeatureTest):
|
||||
DhtNetwork.log("found", v)
|
||||
return True
|
||||
|
||||
def donecb(ok, nodes):
|
||||
def donecb(ok, nodes, start):
|
||||
nonlocal bootstrap, lock, done, times
|
||||
t = time.time()-start
|
||||
with lock:
|
||||
@@ -665,7 +668,10 @@ class PerformanceTest(DhtFeatureTest):
|
||||
l = lines.pop()
|
||||
l.remove()
|
||||
del l
|
||||
lines = plt.plot(times, color='blue')
|
||||
if len(times) > 1:
|
||||
n, bins, lines = hax.hist(times, 100, normed=1, histtype='stepfilled', color='g')
|
||||
hax.set_ylim(min(n), max(n))
|
||||
lines.extend(lax.plot(times, color='blue'))
|
||||
plt.draw()
|
||||
|
||||
def run_get():
|
||||
@@ -686,12 +692,12 @@ class PerformanceTest(DhtFeatureTest):
|
||||
DhtNetwork.log("Getting 50 random hashes succesively.")
|
||||
for i in range(50):
|
||||
with lock:
|
||||
done += 1
|
||||
start = time.time()
|
||||
bootstrap.front().get(InfoHash.getRandom(), getcb, donecb)
|
||||
for _ in range(1):
|
||||
run_get()
|
||||
while done > 0:
|
||||
lock.wait()
|
||||
update_plot()
|
||||
plt.pause(.1)
|
||||
update_plot()
|
||||
print("Took", np.sum(times), "mean", np.mean(times), "std", np.std(times), "min", np.min(times), "max", np.max(times))
|
||||
|
||||
|
||||
+2
-3
@@ -3,8 +3,7 @@ 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_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@
|
||||
libopendht_la_LIBADD = ./argon2/libargon2.la
|
||||
|
||||
libopendht_la_SOURCES = \
|
||||
@@ -31,7 +30,7 @@ nobase_include_HEADERS = \
|
||||
../include/opendht/dht.h \
|
||||
../include/opendht/callbacks.h \
|
||||
../include/opendht/node_cache.h \
|
||||
../include/opendht/routing_table.h \
|
||||
../include/opendht/routing_table.h \
|
||||
../include/opendht/network_engine.h \
|
||||
../include/opendht/scheduler.h \
|
||||
../include/opendht/utils.h \
|
||||
|
||||
@@ -35,7 +35,11 @@ extern "C" {
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
#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
|
||||
|
||||
static gnutls_digest_algorithm_t get_dig_for_pub(gnutls_pubkey_t pubkey)
|
||||
{
|
||||
|
||||
@@ -83,8 +83,8 @@ IpServiceAnnouncement::storePolicy(InfoHash h, std::shared_ptr<Value>& v, InfoHa
|
||||
return false;
|
||||
}
|
||||
|
||||
const ValueType DhtMessage::TYPE = {1, "DHT message", std::chrono::minutes(5), DhtMessage::storePolicy, ValueType::DEFAULT_EDIT_POLICY};
|
||||
const ValueType IpServiceAnnouncement::TYPE = {2, "Internet Service Announcement", std::chrono::minutes(15), IpServiceAnnouncement::storePolicy, ValueType::DEFAULT_EDIT_POLICY};
|
||||
const ValueType DhtMessage::TYPE(1, "DHT message", std::chrono::minutes(5), DhtMessage::storePolicy);
|
||||
const ValueType IpServiceAnnouncement::TYPE(2, "Internet Service Announcement", std::chrono::minutes(15), IpServiceAnnouncement::storePolicy);
|
||||
const ValueType ImMessage::TYPE = {3, "IM message", std::chrono::minutes(5)};
|
||||
const ValueType TrustRequest::TYPE = {4, "Certificate trust request", std::chrono::hours(24*7)};
|
||||
const ValueType IceCandidates::TYPE = {5, "ICE candidates", std::chrono::minutes(5)};
|
||||
|
||||
+254
-217
@@ -38,7 +38,12 @@ extern "C" {
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <cstring>
|
||||
|
||||
@@ -69,7 +74,11 @@ set_nonblocking(int fd, int nonblocking)
|
||||
#endif
|
||||
|
||||
static std::mt19937 rd {dht::crypto::random_device{}()};
|
||||
#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
|
||||
|
||||
namespace dht {
|
||||
|
||||
@@ -92,7 +101,7 @@ struct Dht::Storage {
|
||||
Storage() {}
|
||||
Storage(InfoHash id, time_point now) : id(id), maintenance_time(now+MAX_STORAGE_MAINTENANCE_EXPIRE_TIME) {}
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 || defined(_WIN32)
|
||||
// GCC-bug: remove me when support of GCC < 4.9.2 is abandoned
|
||||
Storage(Storage&& o) noexcept
|
||||
: id(std::move(o.id))
|
||||
@@ -161,9 +170,9 @@ private:
|
||||
size_t total_size {};
|
||||
};
|
||||
|
||||
|
||||
struct Dht::SearchNode {
|
||||
SearchNode(std::shared_ptr<Node> node) : node(node) {}
|
||||
SearchNode() : node() {}
|
||||
SearchNode(const std::shared_ptr<Node>& node) : node(node) {}
|
||||
|
||||
using AnnounceStatusMap = std::map<Value::Id, std::shared_ptr<Request>>;
|
||||
|
||||
@@ -174,6 +183,11 @@ struct Dht::SearchNode {
|
||||
return not node->isExpired() and
|
||||
not token.empty() and last_get_reply >= now - Node::NODE_EXPIRE_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Could a "get" request be sent to this node now ?
|
||||
* update: time of the last "get" op for the search.
|
||||
*/
|
||||
bool canGet(time_point now, time_point update) const {
|
||||
return not node->isExpired() and
|
||||
(now > last_get_reply + Node::NODE_EXPIRE_TIME or update > last_get_reply)
|
||||
@@ -194,6 +208,9 @@ struct Dht::SearchNode {
|
||||
return listenStatus->reply_time + LISTEN_EXPIRE_TIME > now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumng the node is synced, should a "put" request be sent to this node now ?
|
||||
*/
|
||||
time_point getAnnounceTime(AnnounceStatusMap::const_iterator ack, const ValueType& type) const {
|
||||
if (ack == acked.end() or not ack->second)
|
||||
return time_point::min();
|
||||
@@ -204,12 +221,19 @@ struct Dht::SearchNode {
|
||||
return getAnnounceTime(acked.find(vid), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumng the node is synced, should a "listen" request be sent to this node now ?
|
||||
*/
|
||||
time_point getListenTime() const {
|
||||
if (not listenStatus)
|
||||
return time_point::min();
|
||||
|
||||
return listenStatus->pending() ? time_point::max() : listenStatus->reply_time + LISTEN_EXPIRE_TIME - REANNOUNCE_MARGIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this node expired or candidate
|
||||
*/
|
||||
bool isBad() const {
|
||||
return !node || node->isExpired() || candidate;
|
||||
}
|
||||
@@ -256,7 +280,7 @@ struct Dht::Search {
|
||||
/**
|
||||
* @returns true if the node was not present and added to the search
|
||||
*/
|
||||
bool insertNode(std::shared_ptr<Node> n, time_point now, const Blob& token={});
|
||||
bool insertNode(const std::shared_ptr<Node>& n, time_point now, const Blob& token={});
|
||||
unsigned insertBucket(const Bucket&, time_point now);
|
||||
|
||||
SearchNode* getNode(const std::shared_ptr<Node>& n) {
|
||||
@@ -270,7 +294,7 @@ struct Dht::Search {
|
||||
unsigned currentGetRequests() const {
|
||||
unsigned count = 0;
|
||||
for (const auto& n : nodes)
|
||||
if (n.getStatus and n.getStatus->pending())
|
||||
if (not n.isBad() and n.getStatus and n.getStatus->pending())
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
@@ -280,6 +304,10 @@ struct Dht::Search {
|
||||
*/
|
||||
bool isSynced(time_point now) const;
|
||||
|
||||
/**
|
||||
* Get the time of the last "get" operation performed on this search,
|
||||
* or time_point::min() if no such operation have been performed.
|
||||
*/
|
||||
time_point getLastGetTime() const;
|
||||
|
||||
/**
|
||||
@@ -295,20 +323,26 @@ struct Dht::Search {
|
||||
/**
|
||||
* @return The number of non-good search nodes.
|
||||
*/
|
||||
unsigned getNumberOfBadNodes();
|
||||
unsigned getNumberOfBadNodes() const;
|
||||
|
||||
/**
|
||||
* ret = 0 : no announce required.
|
||||
* ret > 0 : (re-)announce required at time ret.
|
||||
* Returns the time of the next "announce" event for this search,
|
||||
* or time_point::max() if no such event is planned.
|
||||
* Only makes sense when the search is synced.
|
||||
*/
|
||||
time_point getAnnounceTime(const std::map<ValueType::Id, ValueType>& types, time_point now) const;
|
||||
|
||||
/**
|
||||
* ret = 0 : no listen required.
|
||||
* ret > 0 : (re-)announce required at time ret.
|
||||
* Returns the time of the next "listen" event for this search,
|
||||
* or time_point::max() if no such event is planned.
|
||||
* Only makes sense when the search is synced.
|
||||
*/
|
||||
time_point getListenTime(time_point now) const;
|
||||
|
||||
/**
|
||||
* Returns the time of the next event for this search,
|
||||
* or time_point::max() if no such event is planned.
|
||||
*/
|
||||
time_point getNextStepTime(const std::map<ValueType::Id, ValueType>& types, time_point now) const;
|
||||
|
||||
bool removeExpiredNode(time_point now);
|
||||
@@ -322,16 +356,16 @@ struct Dht::Search {
|
||||
callbacks.clear();
|
||||
listeners.clear();
|
||||
nodes.clear();
|
||||
nextSearchStep = {};
|
||||
nextSearchStep.reset();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
Dht::setLoggers(LogMethod&& error, LogMethod&& warn, LogMethod&& debug)
|
||||
Dht::setLoggers(LogMethod error, LogMethod warn, LogMethod debug)
|
||||
{
|
||||
DHT_LOG.DEBUG = std::move(debug);
|
||||
DHT_LOG.WARN = std::move(warn);
|
||||
DHT_LOG.ERROR = std::move(error);
|
||||
DHT_LOG.DEBUG = debug;
|
||||
DHT_LOG.WARN = warn;
|
||||
DHT_LOG.ERR = error;
|
||||
}
|
||||
|
||||
NodeStatus
|
||||
@@ -430,10 +464,10 @@ Dht::trySearchInsert(const std::shared_ptr<Node>& node)
|
||||
auto family = node->getFamily();
|
||||
auto& srs = family == AF_INET ? searches4 : searches6;
|
||||
for (auto& srp : srs) {
|
||||
auto& s = srp.second;
|
||||
if (s->insertNode(node, now)) {
|
||||
auto& s = *srp.second;
|
||||
if (s.insertNode(node, now)) {
|
||||
inserted = true;
|
||||
scheduler.edit(s->nextSearchStep, s->getNextStepTime(types, now));
|
||||
scheduler.edit(s.nextSearchStep, s.getNextStepTime(types, now));
|
||||
}
|
||||
}
|
||||
return inserted;
|
||||
@@ -455,19 +489,19 @@ Dht::reportedAddr(const sockaddr *sa, socklen_t sa_len)
|
||||
|
||||
/* We just learnt about a node, not necessarily a new one. Confirm is 1 if
|
||||
the node sent a message, 2 if it sent us a reply. */
|
||||
std::shared_ptr<Node>
|
||||
Dht::newNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
void
|
||||
Dht::onNewNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
{
|
||||
auto& list = node->getFamily() == AF_INET ? buckets : buckets6;
|
||||
auto b = list.findBucket(node->id);
|
||||
if (b == list.end())
|
||||
return {};
|
||||
return;
|
||||
|
||||
for (auto& n : b->nodes) {
|
||||
if (n == node) {
|
||||
if (confirm)
|
||||
trySearchInsert(node);
|
||||
return n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +524,7 @@ Dht::newNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
if (not n->isExpired())
|
||||
continue;
|
||||
n = node;
|
||||
return n;
|
||||
return;
|
||||
}
|
||||
|
||||
if (b->nodes.size() >= TARGET_NODES) {
|
||||
@@ -503,7 +537,7 @@ Dht::newNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
of bad nodes fast. */
|
||||
if (not n->isGood(now)) {
|
||||
dubious = true;
|
||||
if (not n->isMessagePending()) {
|
||||
if (not n->isPendingMessage()) {
|
||||
DHT_LOG.DEBUG("Sending ping to dubious node %s.", n->toString().c_str());
|
||||
network_engine.sendPing(n, nullptr, nullptr);
|
||||
break;
|
||||
@@ -515,7 +549,8 @@ Dht::newNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
DHT_LOG.DEBUG("Splitting from depth %u", list.depth(b));
|
||||
sendCachedPing(*b);
|
||||
list.split(b);
|
||||
return newNode(node, 0);
|
||||
onNewNode(node, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* No space for this node. Cache it away for later. */
|
||||
@@ -525,8 +560,6 @@ Dht::newNode(const std::shared_ptr<Node>& node, int confirm)
|
||||
/* Create a new node. */
|
||||
b->nodes.emplace_front(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Called periodically to purge known-bad nodes. Note that we're very
|
||||
@@ -569,56 +602,78 @@ Dht::Search::removeExpiredNode(time_point now)
|
||||
target. We just got a new candidate, insert it at the right spot or
|
||||
discard it. */
|
||||
bool
|
||||
Dht::Search::insertNode(std::shared_ptr<Node> node, time_point now, const Blob& token)
|
||||
Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, const Blob& token)
|
||||
{
|
||||
if (expired and nodes.empty())
|
||||
return false;
|
||||
auto& node = *snode;
|
||||
const auto& nid = node.id;
|
||||
|
||||
if (node->getFamily() != af) {
|
||||
//DHT_LOG.DEBUG("Attempted to insert node in the wrong family.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& nid = node->id;
|
||||
|
||||
// Fast track for the case where the node is not relevant for this search
|
||||
if (nodes.size() >= SEARCH_NODES && id.xorCmp(nid, nodes.back().node->id) > 0)
|
||||
if (node.getFamily() != af)
|
||||
return false;
|
||||
|
||||
bool found = false;
|
||||
auto n = std::find_if(nodes.begin(), nodes.end(), [&](const SearchNode& sn) {
|
||||
if (sn.node == node) {
|
||||
auto n = nodes.end();
|
||||
while (n != nodes.begin()) {
|
||||
--n;
|
||||
if (n->node == snode) {
|
||||
found = true;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return id.xorCmp(nid, sn.node->id) < 0;
|
||||
});
|
||||
if (id.xorCmp(nid, n->node->id) > 0) {
|
||||
++n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool new_search_node = false;
|
||||
if (!found) {
|
||||
// Be more restricitve if there are
|
||||
// too many nodes in this search,
|
||||
if (nodes.size() >= SEARCH_NODES && n == nodes.end())
|
||||
return false;
|
||||
// find if and where to trim excessive nodes
|
||||
auto t = nodes.cend();
|
||||
size_t bad = 0; // number of bad nodes (if search is not expired)
|
||||
bool full {false}; // is the search full (has the maximum nodes)
|
||||
if (expired) {
|
||||
// if the search is expired, trim to SEARCH_NODES nodes
|
||||
if (nodes.size() >= SEARCH_NODES) {
|
||||
full = true;
|
||||
t = nodes.begin() + SEARCH_NODES;
|
||||
}
|
||||
} else {
|
||||
// otherwise, trim to SEARCH_NODES nodes, not counting bad nodes
|
||||
bad = getNumberOfBadNodes();
|
||||
full = nodes.size() - bad >= SEARCH_NODES;
|
||||
while (std::distance(nodes.cbegin(), t) - bad > SEARCH_NODES) {
|
||||
--t;
|
||||
if (t->isBad())
|
||||
bad--;
|
||||
}
|
||||
}
|
||||
|
||||
if (full) {
|
||||
if (t != nodes.cend())
|
||||
nodes.resize(std::distance(nodes.cbegin(), t));
|
||||
if (n >= t)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset search timer if the search is empty
|
||||
else if (nodes.empty()) {
|
||||
if (nodes.empty()) {
|
||||
step_time = TIME_INVALID;
|
||||
}
|
||||
|
||||
n = nodes.insert(n, SearchNode(node));
|
||||
node->time = now;
|
||||
n = nodes.insert(n, SearchNode(snode));
|
||||
node.time = now;
|
||||
new_search_node = true;
|
||||
if (node.isExpired()) {
|
||||
if (not expired)
|
||||
bad++;
|
||||
} else if (expired) {
|
||||
bad = nodes.size() - 1;
|
||||
expired = false;
|
||||
}
|
||||
|
||||
// trim nodes
|
||||
while (nodes.size() > SEARCH_NODES) {
|
||||
auto to_remove = std::prev(nodes.end());
|
||||
if (to_remove->getStatus and to_remove->getStatus->pending()) {
|
||||
to_remove->getStatus->cancel();
|
||||
}
|
||||
nodes.erase(to_remove);
|
||||
while (nodes.size() - bad > SEARCH_NODES) {
|
||||
if (not expired and nodes.back().isBad())
|
||||
bad--;
|
||||
nodes.pop_back();
|
||||
}
|
||||
expired = false;
|
||||
}
|
||||
if (not token.empty()) {
|
||||
n->candidate = false;
|
||||
@@ -627,6 +682,9 @@ Dht::Search::insertNode(std::shared_ptr<Node> node, time_point now, const Blob&
|
||||
n->token = token;
|
||||
expired = false;
|
||||
}
|
||||
if (new_search_node) {
|
||||
removeExpiredNode(now);
|
||||
}
|
||||
return new_search_node;
|
||||
}
|
||||
|
||||
@@ -645,10 +703,11 @@ Dht::expireSearches()
|
||||
{
|
||||
auto t = scheduler.time() - SEARCH_EXPIRE_TIME;
|
||||
auto expired = [&](std::pair<const InfoHash, std::shared_ptr<Search>>& srp) {
|
||||
auto& sr = srp.second;
|
||||
auto b = sr->callbacks.empty() && sr->announce.empty() && sr->listeners.empty() && sr->step_time < t;
|
||||
auto& sr = *srp.second;
|
||||
auto b = sr.callbacks.empty() && sr.announce.empty() && sr.listeners.empty() && sr.step_time < t;
|
||||
if (b) {
|
||||
DHT_LOG.DEBUG("Removing search %s ", srp.first.toString().c_str());
|
||||
DHT_LOG.DEBUG("Removing search %s", srp.first.toString().c_str());
|
||||
sr.clear();
|
||||
return b;
|
||||
} else { return false; }
|
||||
};
|
||||
@@ -695,14 +754,8 @@ Dht::searchSendGetValues(std::shared_ptr<Search> sr, SearchNode* pn, bool update
|
||||
auto onExpired =
|
||||
[this,ws](const Request& status, bool over) mutable {
|
||||
if (auto sr = ws.lock()) {
|
||||
auto srn = sr->getNode(status.node);
|
||||
if (srn and not srn->candidate) {
|
||||
/*DHT_LOG.DEBUG("[search %s IPv%c] [node %s] 'get' expired",
|
||||
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6',
|
||||
srn->node->toString().c_str());*/
|
||||
if (not over)
|
||||
srn->candidate = true;
|
||||
}
|
||||
if (auto srn = sr->getNode(status.node))
|
||||
srn->candidate = not over;
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
}
|
||||
};
|
||||
@@ -726,15 +779,11 @@ Dht::searchStep(std::shared_ptr<Search> sr)
|
||||
DHT_LOG.DEBUG("[search %s IPv%c] step (%d requests)", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', sr->currentGetRequests());
|
||||
sr->step_time = now;
|
||||
|
||||
/*
|
||||
* The accurate delay between two refills has not been strongly determined.
|
||||
* TODO: Emprical analysis over refill timeout.
|
||||
*/
|
||||
if (sr->refill_time + Node::NODE_EXPIRE_TIME < now and sr->nodes.size()-sr->getNumberOfBadNodes() < SEARCH_NODES) {
|
||||
auto added = sr->refill(sr->af == AF_INET ? buckets : buckets6, now);
|
||||
if (added)
|
||||
if (auto added = sr->refill(sr->af == AF_INET ? buckets : buckets6, now)) {
|
||||
sr->refill_time = now;
|
||||
DHT_LOG.WARN("[search %s IPv%c] refilled with %u nodes", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', added);
|
||||
DHT_LOG.DEBUG("[search %s IPv%c] refilled with %u nodes", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', added);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the first TARGET_NODES (8) live nodes have replied. */
|
||||
@@ -761,9 +810,9 @@ Dht::searchStep(std::shared_ptr<Search> sr)
|
||||
DHT_LOG.DEBUG("[search %s IPv%c] synced%s", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', in ? ", in" : "");
|
||||
|
||||
if (not sr->listeners.empty()) {
|
||||
unsigned i = 0, t = 0;
|
||||
unsigned i = 0;
|
||||
for (auto& n : sr->nodes) {
|
||||
if (not n.isSynced(now) or (n.candidate and t >= LISTEN_NODES))
|
||||
if (not n.isSynced(now))
|
||||
continue;
|
||||
if (n.getListenTime() <= now) {
|
||||
DHT_LOG.WARN("[search %s IPv%c] [node %s] sending 'listen'",
|
||||
@@ -779,66 +828,73 @@ Dht::searchStep(std::shared_ptr<Search> sr)
|
||||
[this,ws,ls](const Request& status,
|
||||
NetworkEngine::RequestAnswer&& answer) mutable
|
||||
{ /* on done */
|
||||
// cancel previous request
|
||||
network_engine.cancelRequest(ls);
|
||||
if (auto sr = ws.lock()) {
|
||||
onListenDone(status, answer, sr);
|
||||
searchStep(sr);
|
||||
}
|
||||
},
|
||||
[this,ws,ls](const Request&, bool) mutable
|
||||
[this,ws,ls](const Request&, bool over) mutable
|
||||
{ /* on expired */
|
||||
network_engine.cancelRequest(ls);
|
||||
if (auto sr = ws.lock()) {
|
||||
searchStep(sr);
|
||||
if (over) {
|
||||
network_engine.cancelRequest(ls);
|
||||
if (auto sr = ws.lock())
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
t++;
|
||||
if (not n.candidate and ++i == LISTEN_NODES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Announce requests
|
||||
for (auto& a : sr->announce) {
|
||||
for (auto ait = sr->announce.begin(); ait != sr->announce.end();) {
|
||||
auto& a = *ait;
|
||||
if (!a.value) continue;
|
||||
unsigned i = 0, t = 0;
|
||||
auto vid = a.value->id;
|
||||
const auto& type = getType(a.value->type);
|
||||
if (in) {
|
||||
/*DHT_LOG.WARN("[search %s IPv%c] [value %lu] storing locally",
|
||||
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', vid);*/
|
||||
storageStore(sr->id, a.value, a.created);
|
||||
}
|
||||
for (auto& n : sr->nodes) {
|
||||
if (not n.isSynced(now) or (n.candidate and t >= TARGET_NODES))
|
||||
if (sr->isAnnounced(vid, type, now)) {
|
||||
if (a.callback) {
|
||||
a.callback(true, sr->getNodes());
|
||||
a.callback = nullptr;
|
||||
}
|
||||
if (not a.permanent) {
|
||||
ait = sr->announce.erase(ait);
|
||||
continue;
|
||||
auto at = n.getAnnounceTime(vid, type);
|
||||
if ( at <= now ) {
|
||||
}
|
||||
}
|
||||
if (in) storageStore(sr->id, a.value, a.created);
|
||||
unsigned i = 0;
|
||||
for (auto& n : sr->nodes) {
|
||||
if (not n.isSynced(now))
|
||||
continue;
|
||||
if (n.getAnnounceTime(vid, type) <= now) {
|
||||
DHT_LOG.WARN("[search %s IPv%c] [node %s] sending 'put' (vid: %d)",
|
||||
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', n.node->toString().c_str(), vid);
|
||||
//std::cout << "Sending announce_value to " << n.node->id << " " << print_addr(n.node->ss, n.node->sslen) << std::endl;
|
||||
|
||||
std::weak_ptr<Search> ws = sr;
|
||||
n.acked[vid] = network_engine.sendAnnounceValue(n.node, sr->id, *a.value, a.created, n.token,
|
||||
[this,ws](const Request& status, NetworkEngine::RequestAnswer&& answer) mutable
|
||||
[this,ws](const Request& status, NetworkEngine::RequestAnswer&& answer)
|
||||
{ /* on done */
|
||||
if (auto sr = ws.lock()) {
|
||||
onAnnounceDone(status, answer, sr);
|
||||
searchStep(sr);
|
||||
}
|
||||
},
|
||||
[this,ws](const Request&, bool) mutable
|
||||
[this,ws](const Request&, bool over)
|
||||
{ /* on expired */
|
||||
if (auto sr = ws.lock()) { searchStep(sr); }
|
||||
if (over)
|
||||
if (auto sr = ws.lock())
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
}
|
||||
);
|
||||
}
|
||||
t++;
|
||||
if (not n.candidate and ++i == TARGET_NODES)
|
||||
break;
|
||||
}
|
||||
++ait;
|
||||
}
|
||||
if (sr->callbacks.empty() && sr->announce.empty() && sr->listeners.empty())
|
||||
sr->done = true;
|
||||
@@ -878,50 +934,27 @@ Dht::searchStep(std::shared_ptr<Search> sr)
|
||||
{
|
||||
std::vector<DoneCallback> a_cbs;
|
||||
a_cbs.reserve(sr->announce.size());
|
||||
for (const auto& a : sr->announce)
|
||||
if (a.callback)
|
||||
a_cbs.emplace_back(std::move(a.callback));
|
||||
for (auto ait = sr->announce.begin() ; ait != sr->announce.end(); ) {
|
||||
if (ait->callback)
|
||||
a_cbs.emplace_back(std::move(ait->callback));
|
||||
if (not ait->permanent)
|
||||
ait = sr->announce.erase(ait);
|
||||
else
|
||||
ait++;
|
||||
}
|
||||
for (const auto& a : a_cbs)
|
||||
a(false, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//dumpSearch(*sr, std::cout);
|
||||
|
||||
/* periodic searchStep scheduling. */
|
||||
if (not sr->done)
|
||||
scheduler.edit(sr->nextSearchStep, sr->getNextStepTime(types, now));
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Dht::Search>
|
||||
Dht::newSearch(InfoHash id, sa_family_t af)
|
||||
{
|
||||
auto& srs = af == AF_INET ? searches4 : searches6;
|
||||
const auto& o = std::min_element(srs.begin(), srs.end(),
|
||||
[](std::pair<const InfoHash, std::shared_ptr<Search>>& lsr, std::pair<const InfoHash, std::shared_ptr<Search>>& rsr) {
|
||||
return lsr.second->done && rsr.second->step_time > lsr.second->step_time;
|
||||
});
|
||||
auto oldest = o != srs.end() ? o->second : nullptr;
|
||||
|
||||
/* The oldest slot is expired. */
|
||||
if (oldest && oldest->announce.empty() && oldest->listeners.empty()
|
||||
&& oldest->step_time < scheduler.time() - SEARCH_EXPIRE_TIME)
|
||||
{
|
||||
DHT_LOG.WARN("Reusing expired search %s", oldest->id.toString().c_str());
|
||||
return oldest;
|
||||
}
|
||||
|
||||
/* Allocate a new slot. */
|
||||
if (searches4.size() + searches6.size() < MAX_SEARCHES) {
|
||||
auto sr = std::make_shared<Search>();
|
||||
srs[id] = sr;
|
||||
return sr;
|
||||
}
|
||||
|
||||
/* Oh, well, never mind. Reuse the oldest slot. */
|
||||
return oldest;
|
||||
}
|
||||
|
||||
/* Insert the contents of a bucket into a search structure. */
|
||||
unsigned
|
||||
Dht::Search::insertBucket(const Bucket& b, time_point now)
|
||||
@@ -939,7 +972,7 @@ Dht::Search::isSynced(time_point now) const
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (const auto& n : nodes) {
|
||||
if (n.node->isExpired() or n.candidate)
|
||||
if (n.isBad())
|
||||
continue;
|
||||
if (not n.isSynced(now))
|
||||
return false;
|
||||
@@ -949,11 +982,10 @@ Dht::Search::isSynced(time_point now) const
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
unsigned Dht::Search::getNumberOfBadNodes() {
|
||||
unsigned Dht::Search::getNumberOfBadNodes() const {
|
||||
return std::count_if(nodes.begin(), nodes.end(),
|
||||
[=](const SearchNode& sn) {
|
||||
return sn.isBad();
|
||||
});
|
||||
[=](const SearchNode& sn) { return sn.isBad(); }
|
||||
);
|
||||
}
|
||||
|
||||
time_point
|
||||
@@ -971,7 +1003,7 @@ Dht::Search::isDone(const Get& get, time_point now) const
|
||||
unsigned i = 0;
|
||||
const auto limit = std::max(get.start, now - Node::NODE_EXPIRE_TIME);
|
||||
for (const auto& sn : nodes) {
|
||||
if (sn.node->isExpired() or sn.candidate)
|
||||
if (sn.isBad())
|
||||
continue;
|
||||
if (sn.last_get_reply < limit)
|
||||
return false;
|
||||
@@ -1020,7 +1052,7 @@ Dht::Search::isAnnounced(Value::Id id, const ValueType& type, time_point now) co
|
||||
return false;
|
||||
unsigned i = 0;
|
||||
for (const auto& n : nodes) {
|
||||
if (n.candidate or n.node->isExpired())
|
||||
if (n.isBad())
|
||||
continue;
|
||||
if (not n.isAnnounced(id, type, now))
|
||||
return false;
|
||||
@@ -1037,7 +1069,7 @@ Dht::Search::isListening(time_point now) const
|
||||
return false;
|
||||
unsigned i = 0;
|
||||
for (const auto& n : nodes) {
|
||||
if (n.candidate or n.node->isExpired())
|
||||
if (n.isBad())
|
||||
continue;
|
||||
if (!n.isListening(now))
|
||||
return false;
|
||||
@@ -1130,7 +1162,7 @@ Dht::bootstrapSearch(Dht::Search& sr)
|
||||
return;
|
||||
auto b = list.findBucket(sr.id);
|
||||
if (b == list.end()) {
|
||||
DHT_LOG.ERROR("No bucket");
|
||||
DHT_LOG.ERR("No bucket");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1173,7 +1205,7 @@ std::shared_ptr<Dht::Search>
|
||||
Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallback done_callback, Value::Filter filter)
|
||||
{
|
||||
if (!isRunning(af)) {
|
||||
DHT_LOG.ERROR("[search %s IPv%c] unsupported protocol", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
DHT_LOG.ERR("[search %s IPv%c] unsupported protocol", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
if (done_callback)
|
||||
done_callback(false, {});
|
||||
return {};
|
||||
@@ -1188,9 +1220,20 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallba
|
||||
sr->done = false;
|
||||
sr->expired = false;
|
||||
} else {
|
||||
sr = newSearch(id, af);
|
||||
if (not sr)
|
||||
return {};
|
||||
if (searches4.size() + searches6.size() < MAX_SEARCHES) {
|
||||
sr = std::make_shared<Search>();
|
||||
srs.emplace(id, sr);
|
||||
} else {
|
||||
for (auto it = srs.begin(); it!=srs.end();) {
|
||||
auto& s = *it->second;
|
||||
if ((s.done or s.expired) and s.announce.empty() and s.listeners.empty()) {
|
||||
sr = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not sr)
|
||||
throw DhtException("Can't create search");
|
||||
}
|
||||
sr->af = af;
|
||||
sr->tid = search_id++;
|
||||
sr->step_time = TIME_INVALID;
|
||||
@@ -1205,7 +1248,7 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallba
|
||||
}
|
||||
|
||||
if (callback)
|
||||
sr->callbacks.push_back({.start=scheduler.time(), .filter=filter, .get_cb=callback, .done_cb=done_callback});
|
||||
sr->callbacks.push_back({/*.start=*/scheduler.time(), /*.filter=*/filter, /*.get_cb=*/callback, /*.done_cb=*/done_callback});
|
||||
bootstrapSearch(*sr);
|
||||
|
||||
if (sr->nextSearchStep)
|
||||
@@ -1216,7 +1259,8 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallba
|
||||
}
|
||||
|
||||
void
|
||||
Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created)
|
||||
Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback,
|
||||
time_point created, bool permanent)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
if (!value) {
|
||||
@@ -1238,15 +1282,15 @@ Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value,
|
||||
return a.value->id == value->id;
|
||||
});
|
||||
if (a_sr == sr->announce.end()) {
|
||||
sr->announce.emplace_back(Announce {value, std::min(now, created), callback});
|
||||
sr->announce.emplace_back(Announce {permanent, value, std::min(now, created), callback});
|
||||
for (auto& n : sr->nodes)
|
||||
n.acked[value->id] = {};
|
||||
n.acked[value->id].reset();
|
||||
}
|
||||
else {
|
||||
if (a_sr->value != value) {
|
||||
a_sr->value = value;
|
||||
for (auto& n : sr->nodes)
|
||||
n.acked[value->id] = {};
|
||||
n.acked[value->id].reset();
|
||||
}
|
||||
if (sr->isAnnounced(value->id, getType(value->type), now)) {
|
||||
if (a_sr->callback)
|
||||
@@ -1262,10 +1306,10 @@ Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value,
|
||||
a_sr->callback = callback;
|
||||
}
|
||||
}
|
||||
scheduler.edit(sr->nextSearchStep, sr->getNextStepTime(types, now));
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
//TODO
|
||||
//if (tm < search_time) {
|
||||
// DHT_LOG.ERROR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(),l
|
||||
// DHT_LOG.ERR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(),l
|
||||
// (sr->af == AF_INET) ? '4' : '6', print_dt(tm-clock::now()));
|
||||
// search_time = tm;
|
||||
//}
|
||||
@@ -1277,7 +1321,7 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter
|
||||
const auto& now = scheduler.time();
|
||||
if (!isRunning(af))
|
||||
return 0;
|
||||
// DHT_LOG.ERROR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_dt(tm-clock::now()));
|
||||
// DHT_LOG.ERR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_dt(tm-clock::now()));
|
||||
|
||||
//DHT_LOG.WARN("listenTo %s", id.toString().c_str());
|
||||
auto& srs = af == AF_INET ? searches4 : searches6;
|
||||
@@ -1285,7 +1329,7 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter
|
||||
std::shared_ptr<Search> sr = (srp == srs.end()) ? search(id, af, nullptr, nullptr) : srp->second;
|
||||
if (!sr)
|
||||
throw DhtException("Can't create search");
|
||||
DHT_LOG.ERROR("[search %s IPv%c] listen", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
DHT_LOG.ERR("[search %s IPv%c] listen", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
sr->done = false;
|
||||
auto token = ++sr->listener_token;
|
||||
sr->listeners.emplace(token, LocalListener{f, cb});
|
||||
@@ -1377,8 +1421,13 @@ Dht::cancelListen(const InfoHash& id, size_t token)
|
||||
if (af_token == 0)
|
||||
continue;
|
||||
s->listeners.erase(af_token);
|
||||
for (auto& sn : s->nodes) // also erase requests for all searchnodes.
|
||||
network_engine.cancelRequest(sn.listenStatus);
|
||||
if (s->listeners.empty()) {
|
||||
for (auto& sn : s->nodes) {
|
||||
// also erase requests for all searchnodes.
|
||||
network_engine.cancelRequest(sn.listenStatus);
|
||||
sn.listenStatus.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
searches_cancel_listen(searches4);
|
||||
@@ -1388,7 +1437,7 @@ Dht::cancelListen(const InfoHash& id, size_t token)
|
||||
}
|
||||
|
||||
void
|
||||
Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback, time_point created)
|
||||
Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback, time_point created, bool permanent)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
|
||||
@@ -1406,7 +1455,7 @@ Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback,
|
||||
auto done6 = std::make_shared<bool>(false);
|
||||
auto donecb = [=](const std::vector<std::shared_ptr<Node>>& nodes) {
|
||||
// Callback as soon as the value is announced on one of the available networks
|
||||
if (callback && !*done && (*ok || (*done4 && *done6))) {
|
||||
if (callback && !*done && (*done4 && *done6)) {
|
||||
callback(*ok, nodes);
|
||||
*done = true;
|
||||
}
|
||||
@@ -1416,13 +1465,13 @@ Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback,
|
||||
*done4 = true;
|
||||
*ok |= ok4;
|
||||
donecb(nodes);
|
||||
}, created);
|
||||
}, created, permanent);
|
||||
announce(id, AF_INET6, val, [=](bool ok6, const std::vector<std::shared_ptr<Node>>& nodes) {
|
||||
DHT_LOG.DEBUG("Announce done IPv6 %d", ok6);
|
||||
*done6 = true;
|
||||
*ok |= ok6;
|
||||
donecb(nodes);
|
||||
}, created);
|
||||
}, created, permanent);
|
||||
}
|
||||
|
||||
struct OpStatus {
|
||||
@@ -1438,6 +1487,7 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
|
||||
auto status = std::make_shared<OpStatus>();
|
||||
auto status4 = std::make_shared<OpStatus>();
|
||||
auto status6 = std::make_shared<OpStatus>();
|
||||
|
||||
auto vals = std::make_shared<std::vector<std::shared_ptr<Value>>>();
|
||||
auto all_nodes = std::make_shared<std::vector<std::shared_ptr<Node>>>();
|
||||
|
||||
@@ -1591,8 +1641,7 @@ Dht::findStorage(const InfoHash& id) const
|
||||
void
|
||||
Dht::storageChanged(Storage& st, ValueStorage& v)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
{
|
||||
if (not st.local_listeners.empty()) {
|
||||
std::vector<std::pair<GetCallback, std::vector<std::shared_ptr<Value>>>> cbs;
|
||||
DHT_LOG.DEBUG("Storage changed. Sending update to %lu local listeners.", st.local_listeners.size());
|
||||
for (const auto& l : st.local_listeners) {
|
||||
@@ -1612,9 +1661,7 @@ Dht::storageChanged(Storage& st, ValueStorage& v)
|
||||
std::vector<std::shared_ptr<Value>> vals;
|
||||
vals.push_back(v.data);
|
||||
Blob ntoken = makeToken((const sockaddr*)&l.first->ss, false);
|
||||
network_engine.tellListener(l.first, l.second.rid, st.id, WANT4 | WANT6, ntoken,
|
||||
buckets.findClosestNodes(st.id, now, TARGET_NODES), buckets6.findClosestNodes(st.id, now, TARGET_NODES),
|
||||
vals);
|
||||
network_engine.tellListener(l.first, l.second.rid, st.id, 0, ntoken, {}, {}, vals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1766,7 +1813,7 @@ Dht::connectivityChanged()
|
||||
auto stop_listen = [&](std::map<InfoHash, std::shared_ptr<Search>> srs) {
|
||||
for (auto& sp : srs)
|
||||
for (auto& sn : sp.second->nodes)
|
||||
sn.listenStatus = {};
|
||||
sn.listenStatus.reset();
|
||||
};
|
||||
stop_listen(searches4);
|
||||
stop_listen(searches6);
|
||||
@@ -1896,15 +1943,17 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
using namespace std::chrono;
|
||||
out << std::endl << "Search IPv" << (sr.af == AF_INET6 ? '6' : '4') << ' ' << sr.id << " G" << sr.callbacks.size();
|
||||
out << " age " << duration_cast<seconds>(now - sr.step_time).count() << "s sync ops: " << sr.currentGetRequests();
|
||||
out << std::endl << "Search IPv" << (sr.af == AF_INET6 ? '6' : '4') << ' ' << sr.id << " gets: " << sr.callbacks.size();
|
||||
out << ", age: " << duration_cast<seconds>(now - sr.step_time).count() << " s";
|
||||
if (sr.done)
|
||||
out << " [done]";
|
||||
if (sr.expired)
|
||||
out << " [expired]";
|
||||
bool synced = sr.isSynced(now);
|
||||
out << (synced ? " [synced]" : " [not synced]");
|
||||
if (synced && sr.isListening(now)) {
|
||||
auto lt = sr.getListenTime(now);
|
||||
out << " [listening, next in " << duration_cast<minutes>(lt-now).count() << " min]";
|
||||
out << " [listening, next in " << duration_cast<seconds>(lt-now).count() << " s]";
|
||||
}
|
||||
out << std::endl;
|
||||
|
||||
@@ -1913,46 +1962,37 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
out << "Announcement: " << *n.value << (announced ? " [announced]" : "") << std::endl;
|
||||
}
|
||||
|
||||
out << " Common bits InfoHash Conn. Get Put IP" << std::endl;
|
||||
out << " Common bits InfoHash Conn. Get Ops IP" << std::endl;
|
||||
unsigned i = 0;
|
||||
auto last_get = sr.getLastGetTime();
|
||||
for (const auto& n : sr.nodes) {
|
||||
i++;
|
||||
out << std::setfill (' ') << std::setw(3) << InfoHash::commonBits(sr.id, n.node->id) << ' ' << n.node->id;
|
||||
out << ' ' << (findNode(n.node->id, AF_INET) || findNode(n.node->id, AF_INET6) ? '*' : ' ');
|
||||
out << ' ' << (n.candidate ? 'c' : ' ');
|
||||
out << " ["
|
||||
<< (n.node->isMessagePending() ? 'f':' ');
|
||||
out << ' ';
|
||||
out << ' ' << (findNode(n.node->id, sr.af) ? '*' : ' ');
|
||||
out << " [";
|
||||
if (auto pendingCount = n.node->getPendingMessageCount())
|
||||
out << pendingCount;
|
||||
else
|
||||
out << ' ';
|
||||
out << (n.node->isExpired() ? 'x' : ' ') << "]";
|
||||
|
||||
// Get status
|
||||
{
|
||||
bool pending {false}, expired {false};
|
||||
if (n.getStatus) {
|
||||
pending = n.getStatus->pending();
|
||||
expired = n.getStatus->expired();
|
||||
}
|
||||
out << " ["
|
||||
<< (pending ? 'f' : (expired ? 'x' : ' ')) << (n.isSynced(now) ? 's' : '-')
|
||||
<< ((n.last_get_reply > last_get) ? 'u' : '-') << "] ";
|
||||
char g_i = (n.getStatus && n.getStatus->pending()) ? (n.candidate ? 'c' : 'f') : ' ';
|
||||
char s_i = n.isSynced(now) ? (n.last_get_reply > last_get ? 'u' : 's') : '-';
|
||||
out << " [" << s_i << g_i << "] ";
|
||||
}
|
||||
|
||||
{
|
||||
bool pending {false}, expired {false};
|
||||
if (n.listenStatus) {
|
||||
pending = n.listenStatus->pending();
|
||||
expired = n.listenStatus->expired();
|
||||
}
|
||||
if (not sr.listeners.empty() and n.listenStatus) {
|
||||
/*if (!n.listenStatus)
|
||||
out << " ";
|
||||
else*/
|
||||
out << "["
|
||||
<< (pending ? 'f' : (expired ? 'x' : ' '))
|
||||
<< (n.isListening(now) ? 'l' : '-') << "] ";
|
||||
}
|
||||
// Listen status
|
||||
if (not sr.listeners.empty()) {
|
||||
if (not n.listenStatus)
|
||||
out << " ";
|
||||
else
|
||||
out << "["
|
||||
<< (n.isListening(now) ? 'l' : (n.listenStatus->pending() ? 'f' : ' ')) << "] ";
|
||||
}
|
||||
|
||||
// Announce status
|
||||
if (not sr.announce.empty()) {
|
||||
if (n.acked.empty()) {
|
||||
out << " ";
|
||||
@@ -1962,18 +2002,13 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
out << "[";
|
||||
for (const auto& a : sr.announce) {
|
||||
auto ack = n.acked.find(a.value->id);
|
||||
if (ack == n.acked.end()) {
|
||||
if (ack == n.acked.end() or not ack->second) {
|
||||
out << ' ';
|
||||
} else {
|
||||
auto& astatus = ack->second;
|
||||
if (astatus and astatus->reply_time + getType(a.value->type).expiration > now)
|
||||
if (ack->second->reply_time + getType(a.value->type).expiration > now)
|
||||
out << 'a';
|
||||
else if (astatus and astatus->pending())
|
||||
else if (ack->second->pending())
|
||||
out << 'f';
|
||||
else if (astatus and astatus->expired())
|
||||
out << 'x';
|
||||
else
|
||||
out << ' ';
|
||||
}
|
||||
}
|
||||
out << "] ";
|
||||
@@ -2018,7 +2053,8 @@ Dht::getStorageLog() const
|
||||
std::stringstream out;
|
||||
for (const auto& st : store) {
|
||||
out << "Storage " << st.id << " " << st.listeners.size() << " list., " << st.valueCount() << " values (" << st.totalSize() << " bytes)" << std::endl;
|
||||
out << " " << st.local_listeners.size() << " local listeners" << std::endl;
|
||||
if (not st.local_listeners.empty())
|
||||
out << " " << st.local_listeners.size() << " local listeners" << std::endl;
|
||||
for (const auto& l : st.listeners) {
|
||||
out << " " << "Listener " << l.first->toString();
|
||||
auto since = duration_cast<seconds>(now - l.second.time);
|
||||
@@ -2068,7 +2104,7 @@ Dht::Dht(int s, int s6, Config config)
|
||||
: myid(config.node_id), is_bootstrap(config.is_bootstrap), store(),
|
||||
network_engine(myid, s, s6, DHT_LOG, scheduler,
|
||||
std::bind(&Dht::onError, this, _1, _2),
|
||||
std::bind(&Dht::newNode, this, _1, _2),
|
||||
std::bind(&Dht::onNewNode, this, _1, _2),
|
||||
std::bind(&Dht::onReportedAddr, this, _1, _2, _3),
|
||||
std::bind(&Dht::onPing, this, _1),
|
||||
std::bind(&Dht::onFindNode, this, _1, _2, _3),
|
||||
@@ -2268,8 +2304,8 @@ Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, soc
|
||||
|
||||
try {
|
||||
network_engine.processMessage(buf, buflen, from, fromlen);
|
||||
} catch (DhtProtocolException& e) {
|
||||
DHT_LOG.ERROR("Can't parse message from %s: %s", e.getNodeId().toString().c_str(), e.what());
|
||||
} catch (const std::exception& e) {
|
||||
DHT_LOG.ERR("Can't parse message from %s: %s", print_addr(from, fromlen).c_str(), e.what());
|
||||
//auto code = e.getCode();
|
||||
//if (code == DhtProtocolException::INVALID_TID_SIZE or code == DhtProtocolException::WRONG_NODE_INFO_BUF_LEN) {
|
||||
/* This is really annoying, as it means that we will
|
||||
@@ -2386,7 +2422,7 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
val_time = time_point{time_point::duration{valel.via.array.ptr[0].as<time_point::duration::rep>()}};
|
||||
tmp_val.msgpack_unpack(valel.via.array.ptr[1]);
|
||||
} catch (const std::exception&) {
|
||||
DHT_LOG.ERROR("Error reading value at %s", h.first.toString().c_str());
|
||||
DHT_LOG.ERR("Error reading value at %s", h.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
if (val_time + getType(tmp_val.type).expiration < scheduler.time()) {
|
||||
@@ -2396,7 +2432,7 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
storageStore(h.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
DHT_LOG.ERROR("Error reading values at %s", h.first.toString().c_str());
|
||||
DHT_LOG.ERR("Error reading values at %s", h.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2463,7 +2499,7 @@ Dht::onError(std::shared_ptr<Request> req, DhtProtocolException e) {
|
||||
auto& sr = srp.second;
|
||||
for (auto& n : sr->nodes) {
|
||||
if (n.node != req->node) continue;
|
||||
network_engine.cancelRequest(n.getStatus);
|
||||
n.token.clear();
|
||||
n.last_get_reply = time_point::min();
|
||||
cleared++;
|
||||
searchSendGetValues(sr);
|
||||
@@ -2691,7 +2727,7 @@ Dht::onAnnounceDone(const Request&, NetworkEngine::RequestAnswer& answer,
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
DHT_LOG.DEBUG("[search %s IPv%c] got reply to put!",
|
||||
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', answer.values.size());
|
||||
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6');
|
||||
|
||||
searchSendGetValues(sr);
|
||||
|
||||
@@ -2706,7 +2742,8 @@ Dht::onAnnounceDone(const Request&, NetworkEngine::RequestAnswer& answer,
|
||||
a.callback(true, sr->getNodes());
|
||||
a.callback = nullptr;
|
||||
}
|
||||
return true;
|
||||
if (not a.permanent)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}), sr->announce.end());
|
||||
|
||||
+13
-9
@@ -21,7 +21,11 @@
|
||||
#include "dhtrunner.h"
|
||||
#include "securedht.h"
|
||||
|
||||
#include <unistd.h> // close(fd)
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
@@ -199,7 +203,7 @@ DhtRunner::exportValues() const {
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setLoggers(LogMethod&& error, LogMethod&& warn, LogMethod&& debug) {
|
||||
DhtRunner::setLoggers(LogMethod error, LogMethod warn, LogMethod debug) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
dht_->setLoggers(std::forward<LogMethod>(error), std::forward<LogMethod>(warn), std::forward<LogMethod>(debug));
|
||||
}
|
||||
@@ -374,7 +378,7 @@ DhtRunner::doRun(const sockaddr_in* sin4, const sockaddr_in6* sin6, SecureDht::C
|
||||
rcv_thread = std::thread([this,s4,s6]() {
|
||||
try {
|
||||
while (true) {
|
||||
struct timeval tv {.tv_sec = 0, .tv_usec = 250000};
|
||||
struct timeval tv {/*.tv_sec = */0, /*.tv_usec = */250000};
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
@@ -480,30 +484,30 @@ DhtRunner::cancelListen(InfoHash h, std::shared_future<size_t> token)
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::put(InfoHash hash, Value&& value, DoneCallback cb)
|
||||
DhtRunner::put(InfoHash hash, Value&& value, DoneCallback cb, bool permanent)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
auto sv = std::make_shared<Value>(std::move(value));
|
||||
pending_ops.emplace([=](SecureDht& dht) {
|
||||
dht.put(hash, sv, cb);
|
||||
dht.put(hash, sv, cb, {}, permanent);
|
||||
});
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb)
|
||||
DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops.emplace([=](SecureDht& dht) {
|
||||
dht.put(hash, value, cb);
|
||||
dht.put(hash, value, cb, {}, permanent);
|
||||
});
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::put(const std::string& key, Value&& value, DoneCallbackSimple cb)
|
||||
DhtRunner::put(const std::string& key, Value&& value, DoneCallbackSimple cb, bool permanent)
|
||||
{
|
||||
put(InfoHash::get(key), std::forward<Value>(value), cb);
|
||||
put(InfoHash::get(key), std::forward<Value>(value), cb, permanent);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+5
-1
@@ -65,7 +65,11 @@ InfoHash::getRandom()
|
||||
{
|
||||
InfoHash h;
|
||||
crypto::random_device rdev;
|
||||
std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
#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)));
|
||||
return h;
|
||||
}
|
||||
|
||||
+41
-27
@@ -92,7 +92,7 @@ NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, InfoHash h
|
||||
sendNodesValues((const sockaddr*)&node->ss, node->sslen, TransId {TransPrefix::GET_VALUES, (uint16_t)rid}, nnodes.first, nnodes.second,
|
||||
values, ntoken);
|
||||
} catch (const std::overflow_error& e) {
|
||||
DHT_LOG.ERROR("Can't send value: buffer not large enough !");
|
||||
DHT_LOG.ERR("Can't send value: buffer not large enough !");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ NetworkEngine::requestStep(std::shared_ptr<Request> req)
|
||||
|
||||
auto now = scheduler.time();
|
||||
if (req->isExpired(now)) {
|
||||
DHT_LOG.ERR("[node %s] expired !", req->node->toString().c_str());
|
||||
req->node->setExpired();
|
||||
requests.erase(req->tid);
|
||||
return;
|
||||
@@ -175,7 +176,7 @@ NetworkEngine::sendRequest(std::shared_ptr<Request>& request)
|
||||
request->start = scheduler.time();
|
||||
auto e = requests.emplace(request->tid, request);
|
||||
if (!e.second) {
|
||||
DHT_LOG.ERROR("Request already existed !");
|
||||
DHT_LOG.ERR("Request already existed !");
|
||||
}
|
||||
request->node->requested(request);
|
||||
requestStep(request);
|
||||
@@ -237,9 +238,10 @@ NetworkEngine::isMartian(const sockaddr* sa, socklen_t len)
|
||||
void
|
||||
NetworkEngine::blacklistNode(const std::shared_ptr<Node>& n)
|
||||
{
|
||||
n->setExpired();
|
||||
for (auto rit = requests.begin(); rit != requests.end();) {
|
||||
if (rit->second->node == n) {
|
||||
rit->second->cancel();
|
||||
//rit->second->cancel();
|
||||
requests.erase(rit++);
|
||||
} else {
|
||||
++rit;
|
||||
@@ -269,11 +271,13 @@ NetworkEngine::isNodeBlacklisted(const sockaddr *sa, socklen_t salen) const
|
||||
void
|
||||
NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen)
|
||||
{
|
||||
if (isMartian(from, fromlen))
|
||||
if (isMartian(from, fromlen)) {
|
||||
DHT_LOG.WARN("Received packet from martian node %s", print_addr(from, fromlen).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNodeBlacklisted(from, fromlen)) {
|
||||
DHT_LOG.DEBUG("Received packet from blacklisted node.");
|
||||
DHT_LOG.WARN("Received packet from blacklisted node %s", print_addr(from, fromlen).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -289,7 +293,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr*
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.id == myid) {
|
||||
if (msg.id == myid || msg.id == zeroes) {
|
||||
DHT_LOG.DEBUG("Received message from self.");
|
||||
return;
|
||||
}
|
||||
@@ -305,8 +309,8 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr*
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
if (msg.tid.length != 4) {
|
||||
DHT_LOG.ERROR("Broken node truncates transaction ids (len: %d): ", msg.tid.length);
|
||||
DHT_LOG.ERROR.logPrintable(buf, buflen);
|
||||
DHT_LOG.ERR("Broken node truncates transaction ids (len: %d): ", msg.tid.length);
|
||||
DHT_LOG.ERR.logPrintable(buf, buflen);
|
||||
blacklistNode(cache.getNode(msg.id, from, fromlen, now, 1));
|
||||
return;
|
||||
}
|
||||
@@ -319,19 +323,29 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr*
|
||||
}
|
||||
auto req = reqp->second;
|
||||
|
||||
auto node = req->node;//cache.getNode(msg.id, from, fromlen, now, 2);
|
||||
node->received(now, req);
|
||||
if (node->id == zeroes) {
|
||||
// reply to a message sent when we didn't know the node ID.
|
||||
auto node = req->node;
|
||||
if (node->id != msg.id) {
|
||||
bool unknown_node = node->id == zeroes;
|
||||
node = cache.getNode(msg.id, from, fromlen, now, 2);
|
||||
req->node = node;
|
||||
if (unknown_node) {
|
||||
// received reply to a message sent when we didn't know the node ID.
|
||||
req->node = node;
|
||||
} else {
|
||||
// received reply from unexpected node
|
||||
node->received(now, req);
|
||||
onNewNode(node, 2);
|
||||
DHT_LOG.WARN("Message received from unexpected ndoe %s", node->toString().c_str());
|
||||
return;
|
||||
}
|
||||
} else
|
||||
node->update(from, fromlen);
|
||||
node->received(now, req);
|
||||
|
||||
onNewNode(node, 2);
|
||||
onReportedAddr(msg.id, (sockaddr*)&msg.addr.first, msg.addr.second);
|
||||
|
||||
if (req->cancelled() or req->expired() or (req->completed() and not req->persistent)) {
|
||||
DHT_LOG.WARN("[node %s] response to expired, cancelled or completed request", node->toString().c_str());
|
||||
requests.erase(reqp);
|
||||
return;
|
||||
}
|
||||
@@ -422,7 +436,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr*
|
||||
break;
|
||||
}
|
||||
} catch (const std::overflow_error& e) {
|
||||
DHT_LOG.ERROR("Can't send value: buffer not large enough !");
|
||||
DHT_LOG.ERR("Can't send value: buffer not large enough !");
|
||||
} catch (DhtProtocolException& e) {
|
||||
sendError(from, fromlen, msg.tid, e.getCode(), e.getMsg().c_str(), true);
|
||||
}
|
||||
@@ -490,9 +504,9 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
|
||||
on_done(req_status, {});
|
||||
}
|
||||
},
|
||||
[=](const Request& req_status, bool) { /* on expired */
|
||||
[=](const Request& req_status, bool done) { /* on expired */
|
||||
if (on_expired) {
|
||||
on_expired(req_status, {});
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -551,9 +565,9 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
}
|
||||
},
|
||||
[=](const Request& req_status, bool) { /* on expired */
|
||||
[=](const Request& req_status, bool done) { /* on expired */
|
||||
if (on_expired) {
|
||||
on_expired(req_status, {});
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -594,9 +608,9 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
}
|
||||
},
|
||||
[=](const Request& req_status, bool) { /* on expired */
|
||||
[=](const Request& req_status, bool done) { /* on expired */
|
||||
if (on_expired) {
|
||||
on_expired(req_status, {});
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -693,9 +707,9 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid,
|
||||
pk.pack_array(subset.size());
|
||||
for (const auto& b : subset)
|
||||
buffer.write((const char*)b.data(), b.size());
|
||||
}
|
||||
|
||||
DHT_LOG.DEBUG("sending closest nodes (%d+%d nodes.)", nodes.size(), nodes6.size());
|
||||
DHT_LOG.DEBUG("sending closest nodes (%d+%d nodes.), %lu bytes of values", nodes.size(), nodes6.size(), total_size);
|
||||
} else
|
||||
DHT_LOG.DEBUG("sending closest nodes (%d+%d nodes.)", nodes.size(), nodes6.size());
|
||||
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
@@ -783,9 +797,9 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
|
||||
if (on_done)
|
||||
on_done(req_status, {std::forward<ParsedMessage>(msg)});
|
||||
},
|
||||
[=](const Request& req_status, bool) { /* on expired */
|
||||
[=](const Request& req_status, bool done) { /* on expired */
|
||||
if (on_expired)
|
||||
on_expired(req_status, {});
|
||||
on_expired(req_status, done);
|
||||
},
|
||||
true
|
||||
});
|
||||
@@ -849,9 +863,9 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n, const InfoHash& infoha
|
||||
}
|
||||
}
|
||||
},
|
||||
[=](const Request& req_status, bool) { /* on expired */
|
||||
[=](const Request& req_status, bool done) { /* on expired */
|
||||
if (on_expired) {
|
||||
on_expired(req_status, {});
|
||||
on_expired(req_status, done);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+14
-1
@@ -40,7 +40,7 @@ Node::isGood(time_point now) const
|
||||
}
|
||||
|
||||
bool
|
||||
Node::isMessagePending() const
|
||||
Node::isPendingMessage() const
|
||||
{
|
||||
for (auto w : requests_) {
|
||||
if (auto r = w.lock()) {
|
||||
@@ -51,6 +51,19 @@ Node::isMessagePending() const
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
Node::getPendingMessageCount() const
|
||||
{
|
||||
size_t count {0};
|
||||
for (auto w : requests_) {
|
||||
if (auto r = w.lock()) {
|
||||
if (r->pending())
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
Node::update(const sockaddr* sa, socklen_t salen)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@ NodeCache::getNode(const InfoHash& id, sa_family_t family) {
|
||||
|
||||
std::shared_ptr<Node>
|
||||
NodeCache::getNode(const InfoHash& id, const sockaddr* sa, socklen_t sa_len, time_point now, int confirm) {
|
||||
if (id == zeroes)
|
||||
return std::make_shared<Node>(id, sa, sa_len);
|
||||
return (sa->sa_family == AF_INET ? cache_4 : cache_6).getNode(id, sa, sa_len, now, confirm);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
static std::mt19937 rd {dht::crypto::random_device{}()};
|
||||
static std::mt19937 rd{ dht::crypto::random_device{}() };
|
||||
#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::shared_ptr<Node>
|
||||
Bucket::randomNode()
|
||||
|
||||
+58
-33
@@ -77,8 +77,8 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf)
|
||||
if (ok)
|
||||
DHT_LOG.DEBUG("SecureDht: public key announced successfully");
|
||||
else
|
||||
DHT_LOG.ERROR("SecureDht: error while announcing public key!");
|
||||
});
|
||||
DHT_LOG.ERR("SecureDht: error while announcing public key!");
|
||||
}, {}, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ SecureDht::secureType(ValueType&& type)
|
||||
{
|
||||
type.storePolicy = [this,type](InfoHash id, std::shared_ptr<Value>& v, InfoHash nid, const sockaddr* a, socklen_t al) {
|
||||
if (v->isSigned()) {
|
||||
if (!v->owner.checkSignature(v->getToSign(), v->signature)) {
|
||||
if (!v->owner or !v->owner->checkSignature(v->getToSign(), v->signature)) {
|
||||
DHT_LOG.WARN("Signature verification failed");
|
||||
return false;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ SecureDht::secureType(ValueType&& type)
|
||||
DHT_LOG.WARN("Edition forbidden: owner changed.");
|
||||
return false;
|
||||
}
|
||||
if (!o->owner.checkSignature(n->getToSign(), n->signature)) {
|
||||
if (!o->owner or !o->owner->checkSignature(n->getToSign(), n->signature)) {
|
||||
DHT_LOG.WARN("Edition forbidden: signature verification failed.");
|
||||
return false;
|
||||
}
|
||||
@@ -141,6 +141,18 @@ SecureDht::getCertificate(const InfoHash& node) const
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const crypto::PublicKey>
|
||||
SecureDht::getPublicKey(const InfoHash& node) const
|
||||
{
|
||||
if (node == getId())
|
||||
return std::make_shared<crypto::PublicKey>(certificate_->getPublicKey());
|
||||
auto it = nodesPubKeys_.find(node);
|
||||
if (it == nodesPubKeys_.end())
|
||||
return nullptr;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const std::shared_ptr<crypto::Certificate>
|
||||
SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
|
||||
{
|
||||
@@ -152,7 +164,7 @@ SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
|
||||
}
|
||||
InfoHash h = crt->getPublicKey().getId();
|
||||
if (node == h) {
|
||||
DHT_LOG.DEBUG("Registering public key for %s", h.toString().c_str());
|
||||
DHT_LOG.DEBUG("Registering certificate for %s", h.toString().c_str());
|
||||
auto it = nodesCertificates_.find(h);
|
||||
if (it == nodesCertificates_.end())
|
||||
std::tie(it, std::ignore) = nodesCertificates_.emplace(h, std::move(crt));
|
||||
@@ -177,7 +189,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s
|
||||
{
|
||||
std::shared_ptr<crypto::Certificate> b = getCertificate(node);
|
||||
if (b && *b) {
|
||||
DHT_LOG.DEBUG("Using public key from cache for %s", node.toString().c_str());
|
||||
DHT_LOG.DEBUG("Using certificate from cache for %s", node.toString().c_str());
|
||||
if (cb)
|
||||
cb(b);
|
||||
return;
|
||||
@@ -185,7 +197,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s
|
||||
if (localQueryMethod_) {
|
||||
auto res = localQueryMethod_(node);
|
||||
if (not res.empty()) {
|
||||
DHT_LOG.DEBUG("Registering public key from local store for %s", node.toString().c_str());
|
||||
DHT_LOG.DEBUG("Registering certificate from local store for %s", node.toString().c_str());
|
||||
nodesCertificates_.emplace(node, res.front());
|
||||
if (cb)
|
||||
cb(res.front());
|
||||
@@ -200,7 +212,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s
|
||||
for (const auto& v : vals) {
|
||||
if (auto cert = registerCertificate(node, v->data)) {
|
||||
*found = true;
|
||||
DHT_LOG.DEBUG("Found public key for %s", node.toString().c_str());
|
||||
DHT_LOG.DEBUG("Found certificate for %s", node.toString().c_str());
|
||||
if (cb)
|
||||
cb(cert);
|
||||
return false;
|
||||
@@ -213,6 +225,26 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s
|
||||
}, Value::TypeFilter(CERTIFICATE_TYPE));
|
||||
}
|
||||
|
||||
void
|
||||
SecureDht::findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<const crypto::PublicKey>)> cb)
|
||||
{
|
||||
auto pk = getPublicKey(node);
|
||||
if (pk && *pk) {
|
||||
DHT_LOG.DEBUG("Found public key from cache for %s", node.toString().c_str());
|
||||
if (cb)
|
||||
cb(pk);
|
||||
return;
|
||||
}
|
||||
findCertificate(node, [=](const std::shared_ptr<crypto::Certificate> crt) {
|
||||
if (crt && *crt) {
|
||||
auto pk = std::make_shared<crypto::PublicKey>(crt->getPublicKey());
|
||||
nodesPubKeys_[pk->getId()] = pk;
|
||||
if (cb) cb(pk);
|
||||
} else {
|
||||
if (cb) cb(nullptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GetCallback
|
||||
SecureDht::getCallbackFilter(GetCallback cb, Value::Filter&& filter)
|
||||
@@ -227,6 +259,7 @@ SecureDht::getCallbackFilter(GetCallback cb, Value::Filter&& filter)
|
||||
try {
|
||||
Value decrypted_val (decrypt(*v));
|
||||
if (decrypted_val.recipient == getId()) {
|
||||
nodesPubKeys_[decrypted_val.owner->getId()] = decrypted_val.owner;
|
||||
if (not filter or filter(decrypted_val))
|
||||
tmpvals.push_back(std::make_shared<Value>(std::move(decrypted_val)));
|
||||
}
|
||||
@@ -237,7 +270,8 @@ SecureDht::getCallbackFilter(GetCallback cb, Value::Filter&& filter)
|
||||
}
|
||||
// Check signed values
|
||||
else if (v->isSigned()) {
|
||||
if (v->owner.checkSignature(v->getToSign(), v->signature)) {
|
||||
if (v->owner and v->owner->checkSignature(v->getToSign(), v->signature)) {
|
||||
nodesPubKeys_[v->owner->getId()] = v->owner;
|
||||
if (not filter or filter(*v))
|
||||
tmpvals.push_back(v);
|
||||
}
|
||||
@@ -269,7 +303,7 @@ SecureDht::listen(const InfoHash& id, GetCallback cb, Value::Filter&& f)
|
||||
}
|
||||
|
||||
void
|
||||
SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback)
|
||||
SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback, bool permanent)
|
||||
{
|
||||
if (val->id == Value::INVALID_ID) {
|
||||
crypto::random_device rdev;
|
||||
@@ -289,36 +323,36 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb
|
||||
DHT_LOG.DEBUG("Found online previous value being announced.");
|
||||
for (const auto& v : vals) {
|
||||
if (!v->isSigned())
|
||||
DHT_LOG.ERROR("Existing non-signed value seems to exists at this location.");
|
||||
else if (v->owner.getId() != getId())
|
||||
DHT_LOG.ERROR("Existing signed value belonging to someone else seems to exists at this location.");
|
||||
DHT_LOG.ERR("Existing non-signed value seems to exists at this location.");
|
||||
else if (not v->owner or v->owner->getId() != getId())
|
||||
DHT_LOG.ERR("Existing signed value belonging to someone else seems to exists at this location.");
|
||||
else if (val->seq <= v->seq)
|
||||
val->seq = v->seq + 1;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[hash,val,this,callback] (bool /* ok */) {
|
||||
[hash,val,this,callback,permanent] (bool /* ok */) {
|
||||
sign(*val);
|
||||
put(hash, val, callback);
|
||||
put(hash, val, callback, {}, permanent);
|
||||
},
|
||||
Value::IdFilter(val->id)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback)
|
||||
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent)
|
||||
{
|
||||
findCertificate(to, [=](const std::shared_ptr<crypto::Certificate> crt) {
|
||||
if(!crt || !*crt) {
|
||||
findPublicKey(to, [=](const std::shared_ptr<const crypto::PublicKey> pk) {
|
||||
if(!pk || !*pk) {
|
||||
if (callback)
|
||||
callback(false, {});
|
||||
return;
|
||||
}
|
||||
DHT_LOG.WARN("Encrypting data for PK: %s", crt->getPublicKey().getId().toString().c_str());
|
||||
DHT_LOG.WARN("Encrypting data for PK: %s", pk->getId().toString().c_str());
|
||||
try {
|
||||
put(hash, encrypt(*val, crt->getPublicKey()), callback);
|
||||
put(hash, encrypt(*val, *pk), callback, {}, permanent);
|
||||
} catch (const std::exception& e) {
|
||||
DHT_LOG.ERROR("Error putting encrypted data: %s", e.what());
|
||||
DHT_LOG.ERR("Error putting encrypted data: %s", e.what());
|
||||
if (callback)
|
||||
callback(false, {});
|
||||
}
|
||||
@@ -328,22 +362,13 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_pt
|
||||
void
|
||||
SecureDht::sign(Value& v) const
|
||||
{
|
||||
if (v.isEncrypted())
|
||||
throw DhtException("Can't sign encrypted data.");
|
||||
v.owner = key_->getPublicKey();
|
||||
v.signature = key_->sign(v.getToSign());
|
||||
v.sign(*key_);
|
||||
}
|
||||
|
||||
Value
|
||||
SecureDht::encrypt(Value& v, const crypto::PublicKey& to) const
|
||||
{
|
||||
if (v.isEncrypted())
|
||||
throw DhtException("Data is already encrypted.");
|
||||
v.setRecipient(to.getId());
|
||||
sign(v);
|
||||
Value nv {v.id};
|
||||
nv.setCypher(to.encrypt(v.getToEncrypt()));
|
||||
return nv;
|
||||
return v.encrypt(*key_, to);
|
||||
}
|
||||
|
||||
Value
|
||||
@@ -360,7 +385,7 @@ SecureDht::decrypt(const Value& v)
|
||||
|
||||
if (ret.recipient != getId())
|
||||
throw crypto::DecryptError("Recipient mismatch");
|
||||
if (not ret.owner.checkSignature(ret.getToSign(), ret.signature))
|
||||
if (not ret.owner or not ret.owner->checkSignature(ret.getToSign(), ret.signature))
|
||||
throw crypto::DecryptError("Signature mismatch");
|
||||
|
||||
return ret;
|
||||
|
||||
+3
-1
@@ -142,7 +142,9 @@ Value::msgpack_unpack_body(const msgpack::object& o)
|
||||
seq = rseq->as<decltype(seq)>();
|
||||
else
|
||||
throw msgpack::type_error();
|
||||
owner.msgpack_unpack(*rowner);
|
||||
crypto::PublicKey new_owner;
|
||||
new_owner.msgpack_unpack(*rowner);
|
||||
owner = std::make_shared<const crypto::PublicKey>(std::move(new_owner));
|
||||
if (auto rrecipient = findMapValue(*rbody, "to")) {
|
||||
recipient = rrecipient->as<InfoHash>();
|
||||
}
|
||||
|
||||
+3
-3
@@ -3,10 +3,10 @@ bin_PROGRAMS = dhtnode dhtchat dhtscanner
|
||||
AM_CPPFLAGS = -I../include
|
||||
|
||||
dhtnode_SOURCES = dhtnode.cpp
|
||||
dhtnode_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
|
||||
dhtnode_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
|
||||
|
||||
dhtchat_SOURCES = dhtchat.cpp
|
||||
dhtchat_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
|
||||
dhtchat_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
|
||||
|
||||
dhtscanner_SOURCES = dhtscanner.cpp
|
||||
dhtscanner_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
|
||||
dhtscanner_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
|
||||
Reference in new issue
Block a user