Compare commits

...
Author SHA1 Message Date
Adrien Beraud 44822f944b update to version 1.3.2
* crypto API improvements
* python bindings improvements
* implement first python unit tests
* minor bug fixes
2017-05-11 14:05:38 -04:00
Adrien Béraud 406a1c1152 Merge pull request #192 from atraczyk/master
MSVC: decouple argon2 dependency
2017-05-03 11:30:01 -04:00
atraczyk f9939ce336 decouple argon2 dependency 2017-05-03 11:26:45 -04:00
Adrien Beraud d9bced965b crypto: add TrustList move operator, prevent copy 2017-05-01 16:26:12 -04:00
Adrien Beraud 4d78aea05b unit tests: add crypto unit tests 2017-04-27 04:46:08 +02:00
Adrien Beraud 9b42afa9ca implement first simple unit tests 2017-04-27 04:45:59 +02:00
Adrien Beraud aa5b8b84a8 python: add TrustList wrapper 2017-04-27 04:45:59 +02:00
Adrien Beraud d0a8a92a56 crypto: add GnuTLS trust list wrapper 2017-04-27 04:45:59 +02:00
Adrien Beraud cf82f74e15 python: add PrivateKey::generateEC support 2017-04-27 04:45:59 +02:00
Adrien Beraud a952ddec53 python: add crypto encrypt/decrypt 2017-04-27 03:34:04 +02:00
Adrien Beraud fa7efd086f python: add Identity PrivateKey getter
Refactor Identity and PrivateKey to use
shared_ptr<PrivateKey> and retrieve the
key from Identity.
2017-04-27 03:34:04 +02:00
Adrien Beraud 8e28e86caf python: improve wrapper for crypto::Certificate
Add Certificate issuer, getName and revoke
2017-04-27 03:34:04 +02:00
Adrien Beraud 65de9622fb crypto: add Certificate::getChainWithRevocations 2017-04-26 16:43:06 +02:00
Adrien Beraud 210c4b2077 crypto: fix memory leak in RevocationList::getPacked() 2017-04-26 16:42:33 +02:00
Adrien Beraud e8cb635b3a crypto: add getChain() 2017-04-22 19:48:32 +02:00
Adrien Beraud f41c8fef99 crypto: unify API across GnuTLS versions
Throw an exception if GnuTLS is too old
instead of not providing the API.

Also consistently throw in case of hash error,
and return 0 for an empty hash, for both
PublicKey and Certificate.
2017-04-20 17:07:21 +02:00
Adrien Beraud 02147b0b16 update to version 1.3.1 2017-04-14 17:12:54 +02:00
Adrien Beraud 79e266aac6 crypto: don't build getLongID() with old gnutls 2017-04-14 16:57:58 +02:00
Adrien Beraud 9d75ed14b4 infohash: add to_c_str(), improve toString() performance 2017-04-10 15:48:04 +02:00
Adrien Beraud fcca618c48 infohash: improve getRandom performance
Generate random hash in 32 bits chunks
instead of 8 bits chunks.
2017-04-10 15:48:04 +02:00
Adrien Beraud 73bcebf355 license cleanup 2017-04-10 01:43:20 +02:00
Adrien Beraud 057443e4a0 python/tools: update pingpong 2017-04-10 01:12:31 +02:00
Adrien Beraud 99f8c2950b python: rename bootstrap(sockaddr) to ping 2017-04-10 01:12:00 +02:00
Adrien Beraud 4132c63faf def: fix typo 2017-04-09 17:22:18 +02:00
Adrien Béraud 7f2b5a44ff Merge pull request #186 from sim590/search-step-after-announce
dht: fix searchstep not scheduled after announcing
2017-04-05 20:12:23 +02:00
Adrien Beraud 7db0c15483 tools: catch exceptions 2017-04-05 18:35:19 +02:00
Adrien Beraud 2fc7cc57a9 default types: fix uninitialized fields 2017-04-05 18:15:34 +02:00
Adrien Beraud 4970a2aee5 infohash: throw exception with error message 2017-04-05 18:15:02 +02:00
Adrien Beraud 25b6df5355 removeExpiredNode: cleanup 2017-04-05 17:52:34 +02:00
Adrien Beraud 732479736b select: cleanup 2017-04-05 17:52:34 +02:00
Adrien Beraud 696ac1bbd5 network engine: print error if send fails
for now just print an error
2017-04-05 17:52:34 +02:00
Adrien Béraud 3b2e5a13bf Merge pull request #185 from savoirfairelinux/feature/pht
pht: prevent unneeded use of shared_ptr
2017-04-04 16:31:44 +02:00
Simon Désaulniers 26a7aec7cc dht: fix searchstep not scheduled after announcing 2017-04-03 17:39:15 -04:00
Adrien Beraud b73a50bace pht: prevent unneeded use of shared_ptr
Prefer a const reference instead of shared_ptr if the shared_ptr
is not used and argument type is not changed in the method.

This allows to prevent useless shared_ptr allocations.

In getRealPrefix, use OpState to track state instead of using many
different shared_ptr.
2017-04-03 19:10:49 +02:00
Adrien Beraud 70ccbe4e40 value: remove FieldSelectorDescription
FieldSelectorDescription is just Value::Field and
adds nothing on top of it.

Remove it in favor of Value::Field.
2017-04-03 19:10:01 +02:00
Adrien Beraud 6bb00ab732 Merge pull request #175 from sim590/argon2-submodule
argon2: use as submodule (reverted from commit c424eb9160) (reverted from commit 3c45e1996d)
2017-03-30 21:24:49 +02:00
Adrien Béraud 2e279852cd Merge pull request #178 from sim590/benchmark-ifname-error
benchmark: fix invalid ifname error
2017-03-30 17:06:03 +02:00
Adrien Béraud 09b4e71dc5 Merge pull request #182 from atraczyk/master
fixes the contrib paths for the Visual Studio build
2017-03-30 00:48:02 +02:00
atraczyk b40713596c ignore MSVC\contrib\build and add argon2 path to project 2017-03-29 18:25:10 -04:00
atraczyk c5485a795a Merge branch 'master' of github.com:atraczyk/opendht 2017-03-29 17:57:19 -04:00
atraczyk b7c5d4a550 clean up solution 2017-03-29 17:55:18 -04:00
Adrien Beraud 0aa1c9e42d argon2: try to fix build on MSVC 2017-03-29 18:27:19 +02:00
Adrien Beraud 5823e98c76 rng: add missing header 2017-03-29 03:07:09 +02:00
Adrien Beraud 3c45e1996d Merge pull request #175 from sim590/argon2-submodule
argon2: use as submodule (reverted from commit c424eb9160)
2017-03-29 02:51:06 +02:00
Adrien Beraud e2ce496779 crypto: add Certificate::getCopy() 2017-03-29 00:22:19 +02:00
Adrien Beraud 4540be7460 python: add more crypto bindings 2017-03-28 17:33:04 +02:00
Adrien Beraud 7c85b74de6 sockaddr: convert port to network/host byte order 2017-03-28 16:38:28 +02:00
Adrien Beraud fccd569059 python: allow to get bound address for any family 2017-03-28 16:32:55 +02:00
Adrien Beraud 768bfa5d44 python: add SockAddr support 2017-03-28 16:25:17 +02:00
Adrien Beraud ff6e38571d dhtrunner: add method to bootstrap with a single SockAddr 2017-03-28 15:44:09 +02:00
Simon Désaulniers 0a5a609322 benchmark: fix invalid ifname error
Two instructions were mutually misordered.
2017-03-27 23:35:55 -04:00
Adrien Béraud c424eb9160 Merge pull request #175 from sim590/argon2-submodule
argon2: use as submodule
2017-03-27 15:46:55 +02:00
Adrien Beraud 501ba77ec7 docker: add missing dep 2017-03-24 13:42:18 +01:00
Adrien Beraud dc23ee0c7a docker: update dependencies 2017-03-24 03:51:43 +01:00
Adrien Beraud e98f06e84a python: fix scanner 2017-03-24 03:51:15 +01:00
Simon Désaulniers 19c36284dc argon2: use as submodule 2017-03-22 17:18:23 -04:00
Adrien Béraud 358d8bd7b3 Merge pull request #176 from sim590/tools-help
tools: add help -h flag for dhtscanner, dhtchat
2017-03-16 03:20:22 +01:00
Simon Désaulniers c17508862c tools: add help -h flag for dhtscanner, dhtchat 2017-03-15 22:11:25 -04:00
Adrien Beraud 2277a4959c crypto: pack/unpack certificate after generation
make sure the certificate can be fully used after generation
2017-03-15 19:08:06 +01:00
Adrien Beraud d5427df9eb build: allow to use argon2 system library
allow to use system argon2 library, use system library by default:
* add --with(out)-argon2 configure options
* add -DOPENDHT_ARGON2=(On/Off) cmake option

also bump argon2 to latest git
2017-03-13 14:58:25 +01:00
Adrien Beraud 36206a80fc rng: add missing include 2017-03-08 17:50:26 +01:00
Adrien Beraud ab7d175322 network engine: make buffer length depend on HASH_LEN 2017-03-07 23:14:25 +01:00
Adrien Beraud 802528266a crypto: add secure_vector and SecureBlob 2017-03-07 23:00:10 +01:00
Adrien Beraud 95d98f4659 rng: add getSeededRandomEngine
Add a routine to seed a pseudo-engine to
use the full range of possible internal states
by using seed_seq.
2017-03-07 17:08:46 +01:00
Adrien Beraud 4176302a03 crypto: add PublicKey::toString() 2017-03-07 17:08:46 +01:00
Adrien Béraud b3119cce13 Update README.md 2017-03-07 16:14:58 +01:00
atraczyk 9987485f63 clean up solution 2017-02-17 18:15:54 -05:00
Adrien Béraud b08b2f14f2 sockaddr: add missing header and typedef 2017-02-17 12:09:33 -05:00
Adrien Béraud 1e7ba56aeb Merge pull request #174 from sim590/announce-status-fix
dht: standardize announce status check
2017-02-16 23:01:10 +01:00
Simon Désaulniers faf23195a4 dht: standardize announce status check
Fixes a bug where some callbacks wouldn't be called when a dummy request was
inserted to cancel some operation while not using the
net::Request::State::COMPLETED flag as per 19c47ec.
2017-02-16 16:29:21 -05:00
Adrien Béraud 0d66b9435f dht: print IPv6 search log 2017-02-16 11:49:38 -05:00
Adrien Béraud 49353e2d5c dht: replace expired node only when bucket is full 2017-02-10 00:38:51 -05:00
Adrien Béraud c4d5621f67 network: treat loopback address as sender address
When learning about nodes in an answer,
we used to drop nodes with loopback address.
Address is now replaced by the packet sender
address and the port is preserved.
2017-02-10 00:10:11 -05:00
Adrien Béraud aa2227bdfc SockAddr: add utility methods 2017-02-09 23:49:06 -05:00
Adrien Béraud 34908d573f network engine: use make_shared 2017-02-08 14:14:06 -05:00
Adrien Béraud 469774037e Merge pull request #169 from savoirfairelinux/crypto_checks
crypto: make Certificate::isCA() more restrictive
2017-02-07 23:27:15 +01:00
Adrien Béraud 93c5ad7cbc crypto: make Certificate::isCA() more restrictive 2017-02-07 16:51:16 -05:00
Adrien Béraud 03d52e4284 Merge pull request #170 from sim590/dht-random-id
dht: randomize id in Dht layer
2017-02-07 22:08:57 +01:00
Simon Désaulniers 9d83ee169b dht: randomize id in Dht layer 2017-02-07 15:58:04 -05:00
Adrien Béraud 43b181ebbf python: add bindings for network, maintain_storage 2017-01-25 11:57:42 -05:00
Adrien Béraud ac65ca5177 add shortcut Sp for std::shared_ptr 2017-01-24 23:38:31 -05:00
Adrien Béraud 42671be21e Merge pull request #168 from sim590/announce-op-fixes
Announce op fixes
2017-01-20 11:19:33 -05:00
Simon Désaulniers efa6930de2 dht: fix multiple put on a single search segfault
"Iterators pointing to an element between the new logical end and the physical
end of the range are still dereferenceable, but the elements themselves have
unspecified values (as per MoveAssignable post-condition)."

- http://en.cppreference.com/w/cpp/algorithm/remove
2017-01-20 02:40:05 -05:00
Simon Désaulniers 19c47ec781 dht: correctly tell if value is announced
* A value should be considered announced if all good nodes up to a count of
  TARGET_NODES have been tried in the search .
* Bug fix where SearchNode::isAnnounced criteria was not consistent with
  announce operation.
2017-01-20 02:39:59 -05:00
Adrien Béraud 435cd554e6 securedht: add getLongId() 2017-01-19 12:09:12 -05:00
Adrien Béraud 10c70ebd12 hash: add string I/O 2017-01-19 12:08:49 -05:00
Adrien Béraud 7da3ff1bba hash: add support for SHA256 public key fingerprints 2017-01-18 16:08:31 -05:00
Adrien Béraud a222e30428 update to version 1.3.0 2017-01-17 16:44:02 -05:00
Adrien Béraud bd822fce19 dht: don't stop node insertion on expired search 2017-01-17 16:43:32 -05:00
Adrien Béraud cabe9dbeb5 dht: declare StorageBucket as class 2017-01-16 17:53:21 -05:00
Adrien Béraud 99b7a07350 sockaddr: make ipCmp comparator const 2017-01-16 17:51:59 -05:00
Adrien Béraud 756e0bd3d8 dht: cleanup paginate
Reduce indentation level by 4,
add code documentation,
remain under 120 chars wide.
2017-01-15 19:02:15 -05:00
Adrien Béraud 9b0ce12b5f Update README.md 2017-01-15 02:18:37 -05:00
Adrien Béraud e29c2df002 Merge pull request #166 from sim590/license-notice
update license notice (2017)
2017-01-15 02:15:10 -05:00
Simon Désaulniers b03a8b5b50 update license notice (2017) 2017-01-13 17:27:29 -05:00
Adrien Béraud 32f5175d68 dht: expire storage just on time 2017-01-13 16:06:46 -05:00
Adrien Béraud 7d3a54db57 dht: storage rate limiting 2017-01-13 16:06:46 -05:00
Adrien Béraud 3fb7c2acfe Merge pull request #165 from atraczyk/master
msvc: change contrib repo sources
2017-01-11 14:48:56 -05:00
atraczyk bce5d35b51 msvc: change contrib repo sources 2017-01-11 14:37:22 -05:00
Adrien Béraud b6dca5ccd6 dht: use new NodeStats structure to provide stats 2017-01-10 23:34:56 -05:00
Adrien Béraud 23b2712400 dht: use SHA265 instead of SHA512 for the op token
The op token is renewed regularly (around every 30 minutes),
so SHA256 provides enough security for this non-sensitive token.
SHA256 takes 32 bytes instead of 64 bytes for SHA512,
and the token is included in every listen requests,
renewed every 30 seconds, and every answer to get.
In the context of limited bandwith usage, using SHA256 seems more appropriate.
This change is backward and forward compatible.
2017-01-10 23:34:56 -05:00
Adrien Béraud 63bec73885 default types: make TrustRequest a map, add confirm field 2017-01-10 14:24:42 -05:00
Simon Désaulniers af5e0c8982 node: remove expired flag when a node reaches us 2017-01-09 14:40:42 -05:00
Adrien Béraud 5a7c8753e1 python/tools: use asyncio in pingpong test 2017-01-09 14:40:06 -05:00
Adrien Béraud 19fdec96ca dht: remove getStatus with get 2017-01-09 14:38:51 -05:00
Adrien Béraud 2208a06232 dht: clear acked with announce
Clear the search node acked when clearing
the corresponding announce, after checking
the announce status for all announces.
2017-01-09 00:06:54 -05:00
Adrien Béraud 2cfcaf3909 Merge pull request #164 from sim590/connectivity-changes
routing_table: complete connecting state resolution
2017-01-04 14:04:37 -05:00
Simon Désaulniers 620868b5d6 routing_table: complete connecting state resolution
After a connectivity change, the DHT would enter the "connecting" state in order
to try to resolve good nodes. However, the previous algorithm would
probabilistically increase time for completion each time a node would fail to
resolve. We now avoid this by prioritizing non-expired nodes in the process.
Also, a subtle error would sensibly stop the process for 30 minutes due to using
the Node::NODE_EXPIRE_TIME constant instead of Node::MAX_RESPONSE_TIME.
2017-01-03 17:48:40 -05:00
Adrien Béraud e7295bac7b crypto: prevent signing certificates with a non-CA certificate 2017-01-02 16:16:28 -05:00
Adrien Béraud 38aa86de2a crypto/crl: add getIssuerName, getIssuerUID 2016-12-29 11:19:27 -05:00
Adrien Béraud fdf476a3f3 cmake: generate opendhtConfigVersion.cmake 2016-12-29 11:18:45 -05:00
Adrien Béraud 22f27a6cc0 cmake: generate opendhtConfig.cmake 2016-12-28 18:19:16 -05:00
Adrien Béraud c72ea8ce77 tools/scanner: don't use a certificate 2016-12-09 02:41:40 -05:00
Adrien Béraud ea168353b9 tools/scanner: use urllib3 streaming 2016-12-09 02:41:12 -05:00
Adrien Béraud 79b9c4838e Merge pull request #161 from savoirfairelinux/yomgui1-patch-1
remove InfoHash::toCString()
2016-12-06 18:35:56 -05:00
Guillaume Roguez d6e86ebcc9 remove InfoHash::toCString()
Implementation of InfoHash::toCString() is broken
2016-12-06 18:28:14 -05:00
Adrien Béraud 197aaa47f0 crypto: prevent duplicate CRLs, reimport after signing 2016-12-06 16:59:54 -05:00
Adrien Béraud ad234004aa crypto: store CRLs in a set 2016-12-05 15:43:00 -05:00
Adrien Béraud a88e6a4c5f crypto: make CRL default expiration same as certificate 2016-12-02 12:59:03 -05:00
Adrien Béraud c776dad96f crypto: add Certificate::getExpiration() 2016-12-02 12:58:10 -05:00
Adrien Béraud 31fedd529b crypto: add CRL msgpack serialization 2016-12-01 18:42:26 -05:00
Adrien Béraud e9adff9dc5 crypto: add CRL move operator, export as DER 2016-11-30 17:30:09 -05:00
Adrien Béraud bfd58a204b crypto: add CRL import/export methods 2016-11-30 16:31:29 -05:00
Adrien Béraud 867bcf1514 crypto: add EC key generation 2016-11-29 18:04:25 -05:00
Adrien Béraud fb882ee440 crypto: add revocation list 2016-11-29 18:03:49 -05:00
Adrien Béraud 215d3d2847 http server: add cmd arguments 2016-11-29 13:31:40 -05:00
Adrien Béraud 43a345ba0c python: add HTTP server to access the DHT 2016-11-29 12:08:33 -05:00
Adrien Béraud f73f5e2798 log: cosmetics 2016-11-29 01:27:42 -05:00
Istvan 3724670fcc Log.cpp added to src/MakeFile.am 2016-11-29 00:50:47 -05:00
Istvan e7db64bd74 Log functions are moved to log.cpp
Log functions are moved to the log.cpp
in order to avoid multiple definitions
of the logger functions.
2016-11-29 00:50:47 -05:00
Adrien Béraud 9c29b8a29e Merge pull request #160 from sim590/fix-include-dep
buildtools: add def.h to include files
2016-11-28 01:49:30 -05:00
Adrien Béraud c22f0e4d43 Update Makefile.am 2016-11-28 01:48:26 -05:00
Adrien Béraud 4e2b11c24c Update CMakeLists.txt 2016-11-28 01:47:33 -05:00
Simon Désaulniers 8c34e927ea buildtools: add def.h to include files 2016-11-27 23:28:23 -05:00
Adrien Béraud 8a5de47aa0 hide symbols by default (#140) 2016-11-23 18:27:24 -05:00
Adrien Béraud 7f84c1e397 utils: remove useless definitions 2016-11-23 15:12:37 -05:00
Adrien Béraud 65c915fd9d value: print hex value data contiguously 2016-11-23 11:01:14 -05:00
Adrien Béraud 0fd4f73ab1 network monitor: access proper dictionary key 2016-11-23 11:00:11 -05:00
Adrien Béraud 01117567b1 cmake: adapt pkg-config paths to GNUInstallDirs 2016-11-22 10:43:01 -05:00
Adrien Béraud d68cc5cf40 Merge pull request #156 from sim590/cython-robust-check
autoconf: robustly check for cython3
2016-11-21 15:10:40 -05:00
Simon Désaulniers 6db16be2fa autoconf: robustly check for cython3 2016-11-14 21:07:36 -05:00
Adrien Béraud 5166b1add9 tools: add network monitor
The network monitor allows to regularly
check the status of an OpenDHT network,
by performing listen and put operations at
random places on the DHT.

This first version exit with status code 1
if the test fails.
2016-11-10 01:03:29 -05:00
Adrien Béraud 9fadcc907c python: add default port for bootstrap 2016-11-10 00:58:35 -05:00
Adrien Béraud 42171efc3f dht: send values to all sockets for a node
We used to send values once to a given node,
however the receiving node may have canceled
or dropped the request since then,
so we now send the values for every socket and
the optimization will happen on the sending side.
2016-11-09 21:53:43 -05:00
Adrien Béraud 206f12648f Merge pull request #155 from aviau/patch-1
Multi-Arch support
2016-11-09 13:10:08 -05:00
Alexandre Viau ecd0573c4d Multi-Arch support 2016-11-09 11:30:17 -05:00
Simon Désaulniers 2d9f6241a9 net: don't close socket on listen renew 2016-11-08 16:07:15 -05:00
Adrien Béraud 77ee50f5a6 Merge pull request #154 from savoirfairelinux/c_str
infohash: add helper to C string format conversion
2016-11-08 15:48:05 -05:00
Guillaume Roguez 297c37e609 infohash: add helper to C string format conversion
This const void* convertion method helps a lot with programs
that need to print the hash with a printf() like function.
2016-11-08 15:26:13 -05:00
Simon Désaulniers 9bb1ab43eb net.h: moved to include/opendht/ 2016-11-08 14:52:09 -05:00
Adrien Béraud cd36b13c30 dht: prevent infinite loop in expireStorage() 2016-11-07 16:56:08 -05:00
Adrien Béraud 5d63084627 Merge pull request #152 from sim590/listen-consistency
Listen consistency
2016-11-07 10:33:05 -05:00
Simon Désaulniers ab7d1d6582 dht,net: introduce socket, support multiple listen
Since the initial implementation of listen operation, multiple listen requests
from a single node on a same hash was not possible without singular
inconsistencies. The flaw was coming from the fact that nodes receiving listen
request could not differentiate between listen refresh request and a new
independent listen request.

This patch introduces the new net::Socket structure which in time will enable
remote nodes to send update for a storage while differentiating between
concurrent listen requests. A socket has a unique identifier which consists of a
transaction id as defined in the OpenDHT protocol.
2016-11-07 06:44:15 -05:00
Simon Désaulniers 77ea6d8c2f net: create net namespace, moving relevant structs 2016-11-05 19:29:00 -04:00
Simon Désaulniers b5cd629160 dht: callback if no storage maintenance 2016-11-04 09:15:10 -04:00
Adrien Béraud 39467c8b71 tools: add python cluster runner commands 2016-11-02 02:32:06 -04:00
Adrien Béraud 87740e3b38 tools: add python node cluster runner 2016-11-01 03:14:26 -04:00
Adrien Béraud 19848a9b72 python: encode log file name 2016-11-01 03:13:56 -04:00
Adrien Béraud 36e9998fe2 scanner: use urllib3 2016-11-01 03:13:56 -04:00
Adrien Béraud b2529c241e log: flush on new line 2016-11-01 03:13:56 -04:00
Adrien Béraud 83c47037d2 dht: remove unimplemented declaration 2016-11-01 03:13:56 -04:00
Adrien Béraud 125b6f9236 dht: make storage maintenance optional, default disabled 2016-10-31 14:43:56 -04:00
Adrien Béraud e260ba6b78 infohash: remove misused restrict 2016-10-31 12:35:50 -04:00
Simon Désaulniers eafb934e85 bump version to 1.2.1 2016-10-28 18:49:09 -04:00
Adrien Béraud c3d3da20f6 Merge pull request #146 from sim590/permanent-put-enhancement
dht: make reannounce margin bigger, safer
2016-10-28 16:24:07 -04:00
Adrien Béraud 6036ccdbaa dht: try inserting new nodes smarter (#150)
Attempt closest search and nearby searches
until we are too far instead of trying every
search.
2016-10-28 15:46:27 -04:00
Simon Désaulniers 9404a4d069 dht: make reannounce margin bigger, safer
Reannouncing margin going from 5 seconds to 10 seconds.
2016-10-28 15:24:09 -04:00
113 changed files with 5576 additions and 5647 deletions

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
[submodule "argon2"]
path = argon2
url = https://github.com/P-H-C/phc-winner-argon2
ignore = dirty
+56 -13
View File
@@ -1,23 +1,25 @@
cmake_minimum_required (VERSION 2.8.6)
project (opendht)
set (opendht_VERSION_MAJOR 1)
set (opendht_VERSION_MINOR 2.0)
set (opendht_VERSION_MINOR 3.2)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(GNUInstallDirs)
set (prefix ${CMAKE_INSTALL_PREFIX})
set (exec_prefix "\${prefix}")
set (libdir "\${exec_prefix}/lib")
set (includedir "\${prefix}/include")
set (libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
set (includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
option (OPENDHT_STATIC "Build static library" ON)
option (OPENDHT_SHARED "Build shared library" ON)
option (OPENDHT_LOG "Build with logs" ON)
option (OPENDHT_PYTHON "Build Python bindings" OFF)
option (OPENDHT_TOOLS "Build DHT tools" ON)
option (OPENDHT_ARGON2 "Use included argon2 sources" OFF)
option (OPENDHT_LTO "Build with LTO" OFF)
find_package (GnuTLS 3.3 REQUIRED)
@@ -25,8 +27,16 @@ find_package (Msgpack 1.2 REQUIRED)
if (OPENDHT_TOOLS)
find_package (Readline 6 REQUIRED)
endif ()
if (NOT OPENDHT_ARGON2)
find_package(PkgConfig)
pkg_search_module(argon2 libargon2)
if (NOT argon2_FOUND)
message("Argon2 not found, using included version.")
set(OPENDHT_ARGON2 ON)
endif()
endif ()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++11 -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++11 -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
@@ -60,16 +70,12 @@ list (APPEND opendht_SOURCES
src/network_engine.cpp
src/securedht.cpp
src/dhtrunner.cpp
src/argon2/argon2.c
src/argon2/core.c
src/argon2/blake2/blake2b.c
src/argon2/thread.c
src/argon2/encoding.c
src/argon2/ref.c
src/indexation/pht.cpp
src/log.cpp
)
list (APPEND opendht_HEADERS
include/opendht/def.h
include/opendht/utils.h
include/opendht/sockaddr.h
include/opendht/rng.h
@@ -83,6 +89,7 @@ list (APPEND opendht_HEADERS
include/opendht/routing_table.h
include/opendht/node_cache.h
include/opendht/network_engine.h
include/opendht/net.h
include/opendht/scheduler.h
include/opendht/rate_limiter.h
include/opendht/securedht.h
@@ -98,12 +105,28 @@ configure_file (
@ONLY
)
include_directories (
include_directories(
./
include/
include/opendht/
${CMAKE_CURRENT_BINARY_DIR}/include/
)
if(OPENDHT_ARGON2)
# make sure argon2 submodule is up to date and initialized
message("Initializing Argon2 submodule")
execute_process(COMMAND git submodule update --init)
# add local argon2 files to build
list (APPEND opendht_SOURCES
argon2/src/argon2.c
argon2/src/core.c
argon2/src/blake2/blake2b.c
argon2/src/thread.c
argon2/src/ref.c
argon2/src/encoding.c
)
include_directories(argon2/include/)
endif()
if (NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR lib)
@@ -118,8 +141,14 @@ if (OPENDHT_STATIC)
if (OPENDHT_LTO)
target_link_libraries(opendht-static -flto -fuse-linker-plugin)
endif ()
if (OPENDHT_ARGON2)
target_include_directories(opendht-static SYSTEM PRIVATE argon2)
else ()
target_link_libraries(opendht-static ${argon2_LIBRARIES})
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht-static gnutls nettle)
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR})
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
if (OPENDHT_SHARED)
@@ -129,11 +158,18 @@ if (OPENDHT_SHARED)
)
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
if (OPENDHT_LTO)
target_link_libraries(opendht -flto -fuse-linker-plugin)
endif ()
if (OPENDHT_ARGON2)
target_include_directories(opendht SYSTEM PRIVATE argon2)
else ()
target_link_libraries(opendht ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht gnutls nettle)
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR})
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
if (OPENDHT_TOOLS)
@@ -145,5 +181,12 @@ if (OPENDHT_PYTHON)
add_subdirectory(python)
endif ()
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake"
VERSION ${opendht_VERSION}
COMPATIBILITY AnyNewerVersion
)
install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
+2 -2
View File
@@ -15,7 +15,6 @@ Release/
*.VC.VC.opendb
*.VC.db
*.db
*.filters
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -245,4 +244,5 @@ _Pvt_Extensions
# FAKE - F# Make
.fake/
!config.h
!config.h
contrib/build/
+13 -13
View File
@@ -141,22 +141,22 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\argon2\argon2.c" />
<ClCompile Include="..\src\argon2\core.c" />
<ClCompile Include="..\src\argon2\encoding.c" />
<ClCompile Include="..\src\argon2\opt.c" />
<ClCompile Include="..\src\argon2\ref.c" />
<ClCompile Include="..\src\argon2\thread.c" />
<ClCompile Include="..\argon2\argon2.c" />
<ClCompile Include="..\argon2\core.c" />
<ClCompile Include="..\argon2\encoding.c" />
<ClCompile Include="..\argon2\opt.c" />
<ClCompile Include="..\argon2\ref.c" />
<ClCompile Include="..\argon2\thread.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\argon2\argon2.h" />
<ClInclude Include="..\src\argon2\core.h" />
<ClInclude Include="..\src\argon2\encoding.h" />
<ClInclude Include="..\src\argon2\opt.h" />
<ClInclude Include="..\src\argon2\ref.h" />
<ClInclude Include="..\src\argon2\thread.h" />
<ClInclude Include="..\argon2\argon2.h" />
<ClInclude Include="..\argon2\core.h" />
<ClInclude Include="..\argon2\encoding.h" />
<ClInclude Include="..\argon2\opt.h" />
<ClInclude Include="..\argon2\ref.h" />
<ClInclude Include="..\argon2\thread.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+6 -6
View File
@@ -137,15 +137,15 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\argon2\blake2\blake2b.c" />
<ClCompile Include="..\argon2\blake2\blake2b.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\argon2\blake2\blake2-impl.h" />
<ClInclude Include="..\src\argon2\blake2\blake2.h" />
<ClInclude Include="..\src\argon2\blake2\blamka-round-opt.h" />
<ClInclude Include="..\src\argon2\blake2\blamka-round-ref.h" />
<ClInclude Include="..\argon2\blake2\blake2-impl.h" />
<ClInclude Include="..\argon2\blake2\blake2.h" />
<ClInclude Include="..\argon2\blake2\blamka-round-opt.h" />
<ClInclude Include="..\argon2\blake2\blamka-round-ref.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
@@ -0,0 +1,20 @@
set BUILD=%SRC%..\build
set ARGON2_VERSION=1eea0104e7cb2a38c617cf90ffa46ce5db6aceda
set ARGON2_URL=https://github.com/P-H-C/phc-winner-argon2/archive/%ARGON2_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%ARGON2_VERSION%.tar.gz %cd%
) else (
wget %ARGON2_URL%
)
7z -y x %ARGON2_VERSION%.tar.gz && 7z -y x %ARGON2_VERSION%.tar -o%BUILD%
del %ARGON2_VERSION%.tar && del %ARGON2_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\phc-winner-argon2-%ARGON2_VERSION% argon2
cd %BUILD%\argon2
cd %SRC%
+23
View File
@@ -0,0 +1,23 @@
@echo OFF
SETLOCAL EnableDelayedExpansion
set SRC=%~dp0
if "%USE_CACHE%"=="" (
set USE_CACHE=0
)
set DEPENDENCIES=( ^
argon2, ^
gmp, ^
gnutls, ^
iconv, ^
msgpack, ^
nettle, ^
opendht, ^
zlib ^
)
for %%I in %DEPENDENCIES% do (
call %SRC%\%%I\fetch_and_patch.bat
)
+22
View File
@@ -0,0 +1,22 @@
set BUILD=%SRC%..\build
set GMP_VERSION=3c8f5a0ae0c2ac9ff0ea31b27f71b152979b556d
set GMP_URL=https://github.com/ShiftMediaProject/gmp/archive/%GMP_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%GMP_VERSION%.tar.gz %cd%
) else (
wget %GMP_URL%
)
7z -y x %GMP_VERSION%.tar.gz && 7z -y x %GMP_VERSION%.tar -o%BUILD%
del %GMP_VERSION%.tar && del %GMP_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\gmp-%GMP_VERSION% gmp
cd %BUILD%\gmp
git apply --reject --whitespace=fix %SRC%\gmp\gmp-uwp.patch
cd %SRC%
+110
View File
@@ -0,0 +1,110 @@
--- a/SMP/libgmp.vcxproj
+++ b/SMP/libgmp.vcxproj
@@ -1248,6 +1248,7 @@
<ProjectGuid>{02B94302-23D6-43EF-8865-95CDE99D5DC2}</ProjectGuid>
<RootNamespace>libgmp</RootNamespace>
<ProjectName>libgmp</ProjectName>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -1368,65 +1369,65 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmpd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmpd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gmpd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gmpd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmp</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmp</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmp</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgmp</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gmp</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gmp</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
--- a/SMP/config.h
+++ b/SMP/config.h
@@ -202,7 +202,7 @@
/* #undef HAVE_NATIVE_mpn_add_n_sub_n */
#define HAVE_NATIVE_mpn_add_nc 1
#if defined(__x86_64) || defined(_M_X64)
-#define HAVE_NATIVE_mpn_addaddmul_1msb0 1
+#define HAVE_NATIVE_mpn_addaddmul_1msb0 0
#define HAVE_NATIVE_mpn_addlsh1_n 1
#define HAVE_NATIVE_mpn_addlsh2_n 1
#define HAVE_NATIVE_mpn_addlsh_n 1
--
2.8.1.windows.1
@@ -0,0 +1,24 @@
set BUILD=%SRC%..\build
set GNUTLS_VERSION=f2d0ade53ff644da55244aed79d05eca78d11a2f
set GNUTLS_URL=https://github.com/ShiftMediaProject/gnutls/archive/%GNUTLS_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%GNUTLS_VERSION%.tar.gz %cd%
) else (
wget %GNUTLS_URL%
)
7z -y x %GNUTLS_VERSION%.tar.gz && 7z -y x %GNUTLS_VERSION%.tar -o%BUILD%
del %GNUTLS_VERSION%.tar && del %GNUTLS_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\gnutls-%GNUTLS_VERSION% gnutls
cd %BUILD%\gnutls
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-no-egd.patch
git apply --reject --whitespace=fix %SRC%\gnutls\read-file-limits.h.patch
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-uwp.patch
cd %SRC%
+107
View File
@@ -0,0 +1,107 @@
{a => b}/lib/nettle/Makefile.am | 2 +-
{a => b}/lib/nettle/Makefile.in | 11 +++++------
{a => b}/lib/nettle/rnd-common.c | 7 +++++--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am
index e84ed1f..4767663 100644
--- a/lib/nettle/Makefile.am
+++ b/lib/nettle/Makefile.am
@@ -38,7 +38,7 @@ endif
noinst_LTLIBRARIES = libcrypto.la
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
gnettle.h rnd-common.h rnd-common.c \
rnd.c
diff --git a/lib/nettle/Makefile.in b/lib/nettle/Makefile.in
index 88ae7cf..6ddd536 100644
--- a/lib/nettle/Makefile.in
+++ b/lib/nettle/Makefile.in
@@ -221,8 +221,8 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcrypto_la_LIBADD =
-am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c egd.c \
- egd.h gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
+am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c \
+ gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
int/drbg-aes-self-test.c int/dsa-fips.h \
int/dsa-keygen-fips186.c int/dsa-validate.c \
int/provable-prime.c int/drbg-aes.c int/drbg-aes.h \
@@ -233,7 +233,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
@ENABLE_FIPS140_TRUE@ int/dsa-keygen-fips186.lo \
@ENABLE_FIPS140_TRUE@ int/dsa-validate.lo int/provable-prime.lo \
@ENABLE_FIPS140_TRUE@ int/drbg-aes.lo int/rsa-keygen-fips186.lo
-am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo egd.lo \
+am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo \
rnd-common.lo rnd.lo $(am__objects_1)
libcrypto_la_OBJECTS = $(am_libcrypto_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -1279,8 +1279,8 @@ AM_CPPFLAGS = -I$(srcdir)/int -I$(srcdir)/../../gl \
-I$(builddir)/../includes -I$(builddir)/../../gl \
-I$(srcdir)/.. $(am__append_1)
noinst_LTLIBRARIES = libcrypto.la
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
- gnettle.h rnd-common.h rnd-common.c rnd.c $(am__append_2)
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c gnettle.h \
+ rnd-common.h rnd-common.c rnd.c $(am__append_2)
all: all-am
.SUFFIXES:
@@ -1355,7 +1355,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi.Plo@am__quote@
diff --git a/lib/nettle/rnd-common.c b/lib/nettle/rnd-common.c
index c69ff3b..80b5f32 100644
--- a/lib/nettle/rnd-common.c
+++ b/lib/nettle/rnd-common.c
@@ -139,7 +139,7 @@ void _rnd_system_entropy_deinit(void)
#include <sys/time.h>
#include <fcntl.h>
#include <locks.h>
-#include "egd.h"
+//#include "egd.h"
static int _gnutls_urandom_fd = -1;
static mode_t _gnutls_urandom_fd_mode = 0;
@@ -208,6 +208,7 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
return 0;
}
+#if 0
static
int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
{
@@ -232,6 +233,7 @@ int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
return 0;
}
+#endif
int _rnd_system_entropy_check(void)
{
@@ -268,6 +270,7 @@ int _rnd_system_entropy_init(void)
return 0;
fallback:
+#if 0
_gnutls_urandom_fd = _rndegd_connect_socket();
if (_gnutls_urandom_fd < 0) {
_gnutls_debug_log("Cannot open egd socket!\n");
@@ -281,7 +284,7 @@ fallback:
}
_rnd_get_system_entropy = _rnd_get_system_entropy_egd;
-
+#endif
return 0;
}
+445
View File
@@ -0,0 +1,445 @@
--- a/SMP/libgnutls.vcxproj
+++ b/SMP/libgnutls.vcxproj
@@ -743,91 +744,91 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutlsd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutlsd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutlsd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutlsd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutlsd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutlsd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutls</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutls</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutls</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libgnutls</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutls</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutls</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutls</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>gnutls</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -1834,7 +1834,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointExceptions>false</FloatingPointExceptions>
- <PreprocessorDefinitions>HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>RING_UWP;HAVE_WIN32_LOCKS;HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.\;.\lib;..\lib;..\lib\accelerated;..\lib\auth;..\lib\ext;..\lib\extras;..\lib\minitasn1;..\lib\nettle;..\lib\nettle\int;..\lib\openpgp;..\lib\opencdk;..\lib\x509;..\lib\includes;..\gl;$(OutDir)\include;..\lib\accelerated\x86;$(ProjectDir)\..\..\prebuilt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<DisableSpecificWarnings>4996;4244;4018;4146;4267;4028;4101;4020;4047;4024;4005;4311;4312;4334;4116;4090;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -1850,7 +1850,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
<TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
- <AdditionalDependencies>Crypt32.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>bcrypt.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)\lib\x64\;$(ProjectDir)\..\..\prebuilt\lib\x64\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>/IGNORE:4006,4221,4042 %(AdditionalOptions)</AdditionalOptions>
</Lib>
--- a/lib/nettle/rnd-common.c
+++ b/lib/nettle/rnd-common.c
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <bcrypt.h>
/* gnulib wants to claim strerror even if it cannot provide it. WTF */
#undef strerror
@@ -88,16 +89,25 @@ void _rnd_get_event(struct event_st *e)
#include <wincrypt.h>
static HCRYPTPROV device_fd = 0;
+static BCRYPT_ALG_HANDLE bdevice_fd = 0;
static
int _rnd_get_system_entropy_win32(void* rnd, size_t size)
{
+#ifndef RING_UWP
if (!CryptGenRandom(device_fd, (DWORD) size, rnd)) {
_gnutls_debug_log("Error in CryptGenRandom: %d\n",
(int)GetLastError());
return GNUTLS_E_RANDOM_DEVICE_ERROR;
}
-
+#else
+ NTSTATUS ret = BCryptGenRandom(bdevice_fd, rnd, (ULONG) size, 0);
+ if (!(BCRYPT_SUCCESS(ret))) {
+ _gnutls_debug_log("Error in BCryptGenRandom: %d\n",
+ (int)GetLastError());
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+#endif
return 0;
}
@@ -111,7 +121,7 @@ int _rnd_system_entropy_check(void)
int _rnd_system_entropy_init(void)
{
int old;
-
+#ifndef RING_UWP
if (!CryptAcquireContext
(&device_fd, NULL, NULL, PROV_RSA_FULL,
CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
@@ -119,13 +129,26 @@ int _rnd_system_entropy_init(void)
("error in CryptAcquireContext!\n");
return GNUTLS_E_RANDOM_DEVICE_ERROR;
}
-
+#else
+ NTSTATUS ret = BCryptOpenAlgorithmProvider(&bdevice_fd,
+ BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER,
+ 0);
+ if (!(BCRYPT_SUCCESS(ret))) {
+ _gnutls_debug_log
+ ("error in BCryptOpenAlgorithmProvider!\n");
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+#endif
return 0;
}
void _rnd_system_entropy_deinit(void)
{
+#ifndef RING_UWP
CryptReleaseContext(device_fd, 0);
+#else
+ BCryptCloseAlgorithmProvider(bdevice_fd, 0);
+#endif
}
#else /* POSIX */
--- a/lib/opencdk/misc.c
+++ b/lib/opencdk/misc.c
@@ -34,7 +34,6 @@
#include <gnutls_int.h>
#include <gnutls_str.h>
-
u32 _cdk_buftou32(const byte * buf)
{
u32 u;
@@ -149,6 +148,13 @@ int _cdk_check_args(int overwrite, const char *in, const char *out)
}
#ifdef _WIN32
+#if (_WIN32_WINNT >= 0x0600)
+FILE *_cdk_tmpfile(void)
+{
+ return NULL;
+}
+#else
+
#include <io.h>
#include <fcntl.h>
@@ -183,6 +189,7 @@ FILE *_cdk_tmpfile(void)
_close(fd);
return NULL;
}
+#endif /*_WIN32*/
#else
FILE *_cdk_tmpfile(void)
{
--- a/lib/system-keys-win.c
+++ b/lib/system-keys-win.c
@@ -20,9 +20,10 @@
// Before including any Windows header we need to set _WIN32_WINNT to Vista
// (or higher) so that the NCRYPT stuff can be used.
-#if _WIN32_WINNT < 0x600
+#define _WIN32_WINNT 0x0A00
+#if _WIN32_WINNT < 0x0600
#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x600
+#define _WIN32_WINNT 0x0600
#endif
@@ -1075,7 +1076,11 @@ int _gnutls_system_key_init(void)
int ret;
#ifdef DYN_NCRYPT
- ncrypt_lib = LoadLibraryA("ncrypt.dll");
+#if (_WIN32_WINNT < 0x0A00)
+ ncrypt_lib = LoadLibrary("ncrypt.dll");
+#else
+ ncrypt_lib = LoadPackagedLibrary("ncrypt.dll", 0);
+#endif
if (ncrypt_lib == NULL) {
return gnutls_assert_val(GNUTLS_E_CRYPTO_INIT_FAILED);
}
--- a/lib/system-keys-win.c
+++ b/lib/system-keys-win.c
@@ -396,7 +396,11 @@ _gnutls_privkey_import_system_url(gnutls_privkey_t pkey,
blob.cbData = id_size;
blob.pbData = id;
- store = CertOpenSystemStore(0, "MY");
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"MY");
if (store == NULL) {
gnutls_assert();
ret = GNUTLS_E_FILE_ERROR;
@@ -535,7 +539,11 @@ _gnutls_x509_crt_import_system_url(gnutls_x509_crt_t crt, const char *url)
blob.cbData = id_size;
blob.pbData = id;
- store = CertOpenSystemStore(0, "MY");
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"MY");
if (store == NULL) {
gnutls_assert();
ret = GNUTLS_E_FILE_ERROR;
@@ -776,7 +784,11 @@ gnutls_system_key_iter_get_info(gnutls_system_key_iter_t *iter,
if (*iter == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
- (*iter)->store = CertOpenSystemStore(0, "MY");
+ (*iter)->store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"MY");
if ((*iter)->store == NULL) {
gnutls_free(*iter);
*iter = NULL;
@@ -841,7 +853,11 @@ int gnutls_system_key_delete(const char *cert_url, const char *key_url)
blob.cbData = id_size;
blob.pbData = id;
- store = CertOpenSystemStore(0, "MY");
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"MY");
if (store != NULL) {
do {
cert = CertFindCertificateInStore(store,
--- a/lib/system.c
+++ b/lib/system.c
@@ -446,9 +446,17 @@ int add_system_trust(gnutls_x509_trust_list_t list, unsigned int tl_flags,
gnutls_datum_t data;
if (i == 0)
- store = CertOpenSystemStore(0, "ROOT");
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"ROOT");
else
- store = CertOpenSystemStore(0, "CA");
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_SYSTEM_STORE_CURRENT_USER,
+ (const void*)"CA");
if (store == NULL)
return GNUTLS_E_FILE_ERROR;
--- a/lib/accelerated/x86/x86-common.c
+++ b/lib/accelerated/x86/x86-common.c
@@ -652,6 +652,7 @@ void register_x86_intel_crypto(unsigned capabilities)
void register_x86_crypto(void)
{
+#ifndef RING_UWP
unsigned capabilities = 0;
char *p;
p = secure_getenv("GNUTLS_CPUID_OVERRIDE");
@@ -663,5 +664,7 @@ void register_x86_crypto(void)
#ifdef ENABLE_PADLOCK
register_x86_padlock_crypto(capabilities);
#endif
+#endif
+ register_x86_intel_crypto(0);
}
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -240,7 +240,9 @@ int gnutls_global_init(void)
_gnutls_switch_lib_state(LIB_STATE_INIT);
+#ifndef RING_UWP
e = secure_getenv("GNUTLS_DEBUG_LEVEL");
+#endif
if (e != NULL) {
level = atoi(e);
gnutls_global_set_log_level(level);
@@ -473,8 +475,10 @@ const char *e;
if (_gnutls_global_init_skip() != 0)
return;
+#ifndef RING_UWP
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
- if (e != NULL) {
+#endif
+ if (e != NULL) {
ret = atoi(e);
if (ret == 1)
return;
@@ -494,7 +498,9 @@ static void _DESTRUCTOR lib_deinit(void)
if (_gnutls_global_init_skip() != 0)
return;
+#ifndef RING_UWP
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
+#endif
if (e != NULL) {
int ret = atoi(e);
if (ret == 1)
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -105,7 +105,9 @@ static void write_nss_key_log(gnutls_session_t session, const gnutls_datum_t *pr
if (!checked_env) {
checked_env = 1;
+#ifndef RING_UWP
keylogfile = secure_getenv("SSLKEYLOGFILE");
+#endif
}
if (keylogfile == NULL)
--- a/lib/system.c
+++ b/lib/system.c
@@ -340,7 +340,11 @@ void gnutls_system_global_deinit(void)
*/
int _gnutls_find_config_path(char *path, size_t max_size)
{
- const char *home_dir = secure_getenv("HOME");
+#ifndef RING_UWP
+ const char *home_dir = secure_getenv("HOME");
+#else
+ const char *home_dir = NULL;
+#endif
if (home_dir != NULL && home_dir[0] != 0) {
snprintf(path, max_size, "%s/" CONFIG_PATH, home_dir);
@@ -349,8 +353,13 @@ int _gnutls_find_config_path(char *path, size_t max_size)
#ifdef _WIN32
if (home_dir == NULL || home_dir[0] == '\0') {
+#ifndef RING_UWP
const char *home_drive = getenv("HOMEDRIVE");
const char *home_path = getenv("HOMEPATH");
+#else
+ const char *home_drive = NULL;
+ const char *home_path = NULL;
+#endif
if (home_drive != NULL && home_path != NULL) {
snprintf(path, max_size, "%s%s\\" CONFIG_PATH, home_drive, home_path);
2.8.1.windows.1
@@ -0,0 +1,12 @@
--- gnutls/gl/read-file.c.orig 2012-03-06 20:59:29.600593329 -0500
+++ gnutls/gl/read-file.c 2012-03-06 20:59:44.568593328 -0500
@@ -35,6 +35,9 @@
/* Get errno. */
#include <errno.h>
+/* Get SIZE_MAX */
+#include <limits.h>
+
/* Read a STREAM and return a newly allocated string with the content,
and set *LENGTH to the length of the string. The string is
zero-terminated, but the terminating zero byte is not counted in
@@ -0,0 +1,22 @@
set BUILD=%SRC%..\build
set ICONV_VERSION=65ab92f7a1699ecc39e37fb81f66e5a42aaa35c4
set ICONV_URL=https://github.com/ShiftMediaProject/libiconv/archive/%ICONV_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%ICONV_VERSION%.tar.gz %cd%
) else (
wget %ICONV_URL%
)
7z -y x %ICONV_VERSION%.tar.gz && 7z -y x %ICONV_VERSION%.tar -o%BUILD%
del %ICONV_VERSION%.tar && del %ICONV_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\libiconv-%ICONV_VERSION% libiconv
cd %BUILD%\libiconv
git apply --reject --whitespace=fix %SRC%\iconv\libiconv-uwp.patch
cd %SRC%
+99
View File
@@ -0,0 +1,99 @@
--- a/SMP/libiconv.vcxproj
+++ b/SMP/libiconv.vcxproj
@@ -45,6 +45,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}</ProjectGuid>
<RootNamespace>libiconv</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -164,65 +165,65 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconvd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconvd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>iconvd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>iconvd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconv</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconv</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconv</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libiconv</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>iconv</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>iconv</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
--
2.8.1.windows.1
@@ -0,0 +1,22 @@
set BUILD=%SRC%..\build
set MSGPACK_VERSION=1df97bc37b363a340c5ad06c5cbcc53310aaff80
set MSGPACK_URL=https://github.com/msgpack/msgpack-c/archive/%MSGPACK_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%MSGPACK_VERSION%.tar.gz %cd%
) else (
wget %MSGPACK_URL%
)
7z -y x %MSGPACK_VERSION%.tar.gz && 7z -y x %MSGPACK_VERSION%.tar -o%BUILD%
del %MSGPACK_VERSION%.tar && del %MSGPACK_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\msgpack-c-%MSGPACK_VERSION% msgpack-c
cd %BUILD%\msgpack-c
git apply --reject --whitespace=fix %SRC%\msgpack\msgpack-uwp.patch
cd %SRC%
+221
View File
@@ -0,0 +1,221 @@
--- /dev/null
+++ b/msgpack_vc8.vcxproj
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>MessagePack</ProjectName>
+ <ProjectGuid>{122A2EA4-B283-4241-9655-786DE78283B2}</ProjectGuid>
+ <RootNamespace>MessagePack</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <TargetName>msgpackd</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>msgpackd</TargetName>
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <TargetName>msgpack</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>msgpack</TargetName>
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+ <LinkTimeCodeGeneration />
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>MSGPACK_USE_CPP03;WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+ <LinkTimeCodeGeneration />
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\objectc.c" />
+ <ClCompile Include="src\unpack.c" />
+ <ClCompile Include="src\version.c" />
+ <ClCompile Include="src\vrefbuffer.c" />
+ <ClCompile Include="src\zone.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="include\msgpack.hpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--
2.8.1.windows.1
@@ -0,0 +1,22 @@
set BUILD=%SRC%..\build
set NETTLE_VERSION=4e0b2723b76d4163fa37b2b456d41534154ec97c
set NETTLE_URL=https://github.com/ShiftMediaProject/nettle/archive/%NETTLE_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%NETTLE_VERSION%.tar.gz %cd%
) else (
wget %NETTLE_URL%
)
7z -y x %NETTLE_VERSION%.tar.gz && 7z -y x %NETTLE_VERSION%.tar -o%BUILD%
del %NETTLE_VERSION%.tar && del %NETTLE_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\nettle-%NETTLE_VERSION% nettle
cd %BUILD%\nettle
git apply --reject --whitespace=fix %SRC%\nettle\nettle-uwp.patch
cd %SRC%
+228
View File
@@ -0,0 +1,228 @@
--- a/SMP/libhogweed.vcxproj
+++ b/SMP/libhogweed.vcxproj
@@ -242,6 +242,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}</ProjectGuid>
<RootNamespace>libhogweed</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -405,91 +406,91 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweedd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweedd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweedd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweedd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweedd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweedd</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweed</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweed</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweed</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libhogweed</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweed</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweed</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweed</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>hogweed</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
--- a/SMP/libnettle.vcxproj
+++ b/SMP/libnettle.vcxproj
@@ -278,6 +278,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}</ProjectGuid>
<RootNamespace>libnettle</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -397,65 +398,65 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettled</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettled</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>nettled</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>nettled</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettle</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettle</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettle</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libnettle</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>nettle</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>nettle</TargetName>
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
--
2.8.1.windows.1
+22
View File
@@ -0,0 +1,22 @@
set BUILD=%SRC%..\build
set ZLIB_VERSION=3a062eb61d0c3d4aa30851cd1a6597b977b56597
set ZLIB_URL=https://github.com/ShiftMediaProject/zlib/archive/%ZLIB_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\%ZLIB_VERSION%.tar.gz %cd%
) else (
wget %ZLIB_URL%
)
7z -y x %ZLIB_VERSION%.tar.gz && 7z -y x %ZLIB_VERSION%.tar -o%BUILD%
del %ZLIB_VERSION%.tar && del %ZLIB_VERSION%.tar.gz && del %BUILD%\pax_global_header
rename %BUILD%\zlib-%ZLIB_VERSION% zlib
cd %BUILD%\zlib
git apply --reject --whitespace=fix %SRC%\zlib\zlib-uwp.patch
cd %SRC%
+97
View File
@@ -0,0 +1,97 @@
--- a/SMP/libzlib.vcxproj
+++ b/SMP/libzlib.vcxproj
@@ -45,6 +45,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}</ProjectGuid>
<RootNamespace>libzlib</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -165,63 +166,63 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlibd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>zlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>zlibd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlibd</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>libzlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>zlib</TargetName>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+ <OutDir>$(ProjectDir)..\..\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
<TargetName>zlibd</TargetName>
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
--
2.8.1.windows.1
+3 -3
View File
@@ -139,7 +139,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
@@ -147,8 +147,8 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
+3 -3
View File
@@ -139,7 +139,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
@@ -147,8 +147,8 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
+3 -3
View File
@@ -139,7 +139,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
@@ -147,8 +147,8 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
+221
View File
@@ -0,0 +1,221 @@
--- /dev/null
+++ b/msgpack_vc8.vcxproj
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>MessagePack</ProjectName>
+ <ProjectGuid>{122A2EA4-B283-4241-9655-786DE78283B2}</ProjectGuid>
+ <RootNamespace>MessagePack</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <TargetName>msgpackd</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>msgpackd</TargetName>
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <TargetName>msgpack</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>msgpack</TargetName>
+ <OutDir>$(ProjectDir)..\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+ <LinkTimeCodeGeneration />
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>MSGPACK_USE_CPP03;WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+ <LinkTimeCodeGeneration />
+ </Lib>
+ <PostBuildEvent>
+ <Command>mkdir $(OutDir)\include
+
+mkdir $(OutDir)\include\msgpack
+
+copy include\*.h $(OutDir)\include\
+
+copy include\*.hpp $(OutDir)\include\
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\objectc.c" />
+ <ClCompile Include="src\unpack.c" />
+ <ClCompile Include="src\version.c" />
+ <ClCompile Include="src\vrefbuffer.c" />
+ <ClCompile Include="src\zone.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="include\msgpack.hpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--
2.8.1.windows.1
+2 -1
View File
@@ -26,6 +26,7 @@
<ClCompile Include="..\src\dhtrunner.cpp" />
<ClCompile Include="..\src\indexation\pht.cpp" />
<ClCompile Include="..\src\infohash.cpp" />
<ClCompile Include="..\src\log.cpp" />
<ClCompile Include="..\src\network_engine.cpp" />
<ClCompile Include="..\src\node.cpp" />
<ClCompile Include="..\src\node_cache.cpp" />
@@ -207,7 +208,7 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)contrib\build\include;$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)contrib\build\argon2\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\src\callbacks.cpp" />
<ClCompile Include="..\src\crypto.cpp" />
<ClCompile Include="..\src\default_types.cpp" />
<ClCompile Include="..\src\dht.cpp" />
<ClCompile Include="..\src\dhtrunner.cpp" />
<ClCompile Include="..\src\indexation\pht.cpp" />
<ClCompile Include="..\src\infohash.cpp" />
<ClCompile Include="..\src\log.cpp" />
<ClCompile Include="..\src\network_engine.cpp" />
<ClCompile Include="..\src\node.cpp" />
<ClCompile Include="..\src\node_cache.cpp" />
<ClCompile Include="..\src\routing_table.cpp" />
<ClCompile Include="..\src\securedht.cpp" />
<ClCompile Include="..\src\utils.cpp" />
<ClCompile Include="..\src\value.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\opendht.h" />
<ClInclude Include="..\include\opendht\callbacks.h" />
<ClInclude Include="..\include\opendht\crypto.h" />
<ClInclude Include="..\include\opendht\default_types.h" />
<ClInclude Include="..\include\opendht\dht.h" />
<ClInclude Include="..\include\opendht\dhtrunner.h" />
<ClInclude Include="..\include\opendht\indexation\pht.h" />
<ClInclude Include="..\include\opendht\infohash.h" />
<ClInclude Include="..\include\opendht\log.h" />
<ClInclude Include="..\include\opendht\log_enable.h" />
<ClInclude Include="..\include\opendht\network_engine.h" />
<ClInclude Include="..\include\opendht\node.h" />
<ClInclude Include="..\include\opendht\node_cache.h" />
<ClInclude Include="..\include\opendht\rate_limiter.h" />
<ClInclude Include="..\include\opendht\request.h" />
<ClInclude Include="..\include\opendht\rng.h" />
<ClInclude Include="..\include\opendht\routing_table.h" />
<ClInclude Include="..\include\opendht\scheduler.h" />
<ClInclude Include="..\include\opendht\securedht.h" />
<ClInclude Include="..\include\opendht\utils.h" />
<ClInclude Include="..\include\opendht\value.h" />
</ItemGroup>
</Project>
+71 -304
View File
@@ -5,17 +5,17 @@ VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
ProjectSection(ProjectDependencies) = postProject
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA} = {2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
{122A2EA4-B283-4241-9655-786DE78283B2} = {122A2EA4-B283-4241-9655-786DE78283B2}
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}
{6F610EE8-7F59-4191-AB88-F63843267C02} = {6F610EE8-7F59-4191-AB88-F63843267C02}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{71A1A9EC-1104-4335-A87E-AF8749FD5B34}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgmp", "..\..\gmp\MSVC\libgmp.vcxproj", "{02B94302-23D6-43EF-8865-95CDE99D5DC2}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgmp", "contrib\build\gmp\SMP\libgmp.vcxproj", "{02B94302-23D6-43EF-8865-95CDE99D5DC2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "..\..\gnutls\MSVC\libgnutls.vcxproj", "{6F610EE8-7F59-4191-AB88-F63843267C02}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "contrib\build\gnutls\SMP\libgnutls.vcxproj", "{6F610EE8-7F59-4191-AB88-F63843267C02}"
ProjectSection(ProjectDependencies) = postProject
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
@@ -24,25 +24,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "..\..\gnutls\M
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "..\..\libiconv\MSVC\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "contrib\build\libiconv\SMP\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "..\..\nettle\MSVC\libhogweed.vcxproj", "{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "contrib\build\nettle\SMP\libhogweed.vcxproj", "{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}"
ProjectSection(ProjectDependencies) = postProject
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnettle", "..\..\nettle\MSVC\libnettle.vcxproj", "{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnettle", "contrib\build\nettle\SMP\libnettle.vcxproj", "{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "..\..\zlib\MSVC\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "contrib\build\zlib\SMP\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "..\..\msgpack-c\msgpack_vc8.vcxproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "argon", "argon.vcxproj", "{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}"
ProjectSection(ProjectDependencies) = postProject
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6} = {36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blake", "blake.vcxproj", "{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "contrib\build\msgpack-c\msgpack_vc8.vcxproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{296E2989-CF09-43AC-BBD2-BCF1A4B56D07}"
EndProject
@@ -61,386 +54,161 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dhtchat", "dhtchat.vcxproj"
{711397CE-E5D5-467D-9457-8716C047E50C} = {711397CE-E5D5-467D-9457-8716C047E50C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2Ref", "contrib\build\argon2\vs2015\Argon2Ref\Argon2Ref.vcxproj", "{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
DebugDLL|x64 = DebugDLL|x64
DebugDLL|x86 = DebugDLL|x86
DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64
DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
ReleaseDLL|x64 = ReleaseDLL|x64
ReleaseDLL|x86 = ReleaseDLL|x86
ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64
ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86
ReleaseLTO|x64 = ReleaseLTO|x64
ReleaseLTO|x86 = ReleaseLTO|x86
ReleaseStatic|x64 = ReleaseStatic|x64
ReleaseStatic|x86 = ReleaseStatic|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x86.Build.0 = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.ActiveCfg = Debug|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.Build.0 = Debug|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.ActiveCfg = Debug|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.Build.0 = Debug|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.Build.0 = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.ActiveCfg = Release|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.Build.0 = Release|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.ActiveCfg = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.Build.0 = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.ActiveCfg = Debug|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.Build.0 = Debug|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.ActiveCfg = Debug|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.Build.0 = Debug|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.Build.0 = DebugDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.ActiveCfg = Release|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.Build.0 = Release|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.ActiveCfg = Release|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.Build.0 = Release|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.ActiveCfg = Debug|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.Build.0 = Debug|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.ActiveCfg = Debug|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.Build.0 = Debug|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.Build.0 = DebugDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.ActiveCfg = Release|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.Build.0 = Release|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.ActiveCfg = Release|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.Build.0 = Release|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.ActiveCfg = Debug|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.Build.0 = Debug|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.ActiveCfg = Debug|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.Build.0 = Debug|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.Build.0 = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.ActiveCfg = Release|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.Build.0 = Release|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.ActiveCfg = Release|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.Build.0 = Release|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x86.Build.0 = ReleaseLTO|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.Build.0 = Debug|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.Build.0 = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x64.ActiveCfg = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x64.Build.0 = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x86.ActiveCfg = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Debug|x86.Build.0 = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x64.ActiveCfg = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x64.Build.0 = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x86.ActiveCfg = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLL|x86.Build.0 = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x64.ActiveCfg = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x64.Build.0 = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x86.ActiveCfg = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.Release|x86.Build.0 = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x64.ActiveCfg = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x64.Build.0 = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLL|x86.Build.0 = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x64.ActiveCfg = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x64.Build.0 = Release|x64
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA}.ReleaseLTO|x86.Build.0 = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x64.ActiveCfg = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x64.Build.0 = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x86.ActiveCfg = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Debug|x86.Build.0 = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x64.ActiveCfg = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x64.Build.0 = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x86.ActiveCfg = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLL|x86.Build.0 = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x64.ActiveCfg = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x64.Build.0 = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x86.ActiveCfg = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.Release|x86.Build.0 = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x64.ActiveCfg = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x64.Build.0 = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLL|x86.Build.0 = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x64.ActiveCfg = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x64.Build.0 = Release|x64
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6}.ReleaseLTO|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.Build.0 = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.ActiveCfg = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.Build.0 = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.ActiveCfg = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.Build.0 = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x64.ActiveCfg = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x64.Build.0 = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x86.ActiveCfg = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLL|x86.Build.0 = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.ActiveCfg = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.Build.0 = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.ActiveCfg = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.Build.0 = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x64.ActiveCfg = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x64.Build.0 = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLL|x86.Build.0 = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x64.ActiveCfg = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x64.Build.0 = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseLTO|x86.Build.0 = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.ActiveCfg = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.Build.0 = Release|x64
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.ActiveCfg = Release|Win32
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.Build.0 = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.ActiveCfg = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.Build.0 = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.ActiveCfg = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.Build.0 = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x64.ActiveCfg = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x64.Build.0 = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x86.ActiveCfg = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLL|x86.Build.0 = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.ActiveCfg = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.Build.0 = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.ActiveCfg = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.Build.0 = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x64.ActiveCfg = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x64.Build.0 = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLL|x86.Build.0 = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x64.ActiveCfg = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x64.Build.0 = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseLTO|x86.Build.0 = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.ActiveCfg = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.Build.0 = Release|x64
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.ActiveCfg = Release|Win32
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.Build.0 = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.ActiveCfg = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.Build.0 = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.ActiveCfg = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.Build.0 = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x64.ActiveCfg = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x64.Build.0 = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x86.ActiveCfg = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLL|x86.Build.0 = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.ActiveCfg = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.Build.0 = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.ActiveCfg = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.Build.0 = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x64.ActiveCfg = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x64.Build.0 = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLL|x86.Build.0 = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x64.ActiveCfg = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x64.Build.0 = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseLTO|x86.Build.0 = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.ActiveCfg = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.Build.0 = Release|x64
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.ActiveCfg = Release|Win32
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.Build.0 = Release|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.ActiveCfg = Debug|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.Build.0 = Debug|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.ActiveCfg = Debug|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.Build.0 = Debug|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.ActiveCfg = Release|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.Build.0 = Release|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.ActiveCfg = Release|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.Build.0 = Release|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -453,10 +221,9 @@ Global
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
{122A2EA4-B283-4241-9655-786DE78283B2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
{2B85EA05-086B-4DF6-A140-DF52BDAEEEEA} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
{36A40B5B-FBAD-4830-9F74-7B4E5788B7A6} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
{78443BCD-4689-4007-A246-F8F34B27F561} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
EndGlobalSection
EndGlobal
-71
View File
@@ -1,71 +0,0 @@
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET UPSTREAMURL=https://github.com/atraczyk
SET DEPENDENCIES=( ^
gmp, ^
gnutls, ^
nettle, ^
msgpack-c ^
)
SET PASSDEPENDENCIES=%~1
git status >NUL 2>&1
IF %ERRORLEVEL% EQU 128 (
git init
) ELSE (
IF %ERRORLEVEL% EQU 9009 (
ECHO git not installed.
EXIT /B 1
)
)
SET CURRDIR=%~dp1
cd ..\..
FOR %%I IN %DEPENDENCIES% DO (
ECHO !PASSDEPENDENCIES! | FINDSTR /C:"%%I" >NUL 2>&1 || (
CALL :cloneOrUpdateRepo "%%I" )
)
cd %CURRDIR% >NUL
GOTO exit
:cloneOrUpdateRepo
SET REPONAME=%~1
IF NOT EXIST "%REPONAME%" (
ECHO %REPONAME%: Existing folder not found. Cloning repository...
SET REPOURL=%UPSTREAMURL%/%REPONAME%.git
git clone !REPOURL! --quiet
cd %REPONAME%
git config --local core.autocrlf false
git rm --cached -r . --quiet
git reset --hard --quiet
cd ..\
)
SET PASSDEPENDENCIES=%PASSDEPENDENCIES% %REPONAME%
IF EXIST "%REPONAME%\MSVC\project_get_dependencies.bat" (
ECHO %REPONAME%: Found additional dependencies...
ECHO.
cd %REPONAME%\MSVC
project_get_dependencies.bat "!PASSDEPENDENCIES!" || GOTO exitOnError
cd ..\..
)
ECHO.
EXIT /B %ERRORLEVEL%
:exitOnError
cd %CURRDIR%
:exit
(
ENDLOCAL
SET PASSDEPENDENCIES=%PASSDEPENDENCIES%
)
ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1
IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE
EXIT /B 0
+3 -1
View File
@@ -1,6 +1,8 @@
AM_CXXFLAGS = -pthread
SUBDIRS = src
SUBDIRS =
SUBDIRS += src
if ENABLE_TOOLS
SUBDIRS += tools
+2 -2
View File
@@ -91,7 +91,7 @@ for r in results:
- msgpack-c 1.2+, used for data serialization.
- GnuTLS 3.3+, used for cryptographic operations.
- Nettle 2.4+, a GnuTLS dependency for crypto.
- Build tested with GCC 4.8+ (GNU/Linux, Android, Windows with MinGW), Clang/LLVM (Linux, OS X).
- Build tested with GCC 4.8+ (GNU/Linux, Android, Windows with MinGW), Clang/LLVM (Linux, macOS).
- Build tested with Microsoft Visual Studio 2015
## Contact
@@ -99,7 +99,7 @@ for r in results:
IRC: join us on Freenode at [`#opendht`](https://webchat.freenode.net/?channels=%23opendht).
## Licence
Copyright (C) 2014-2016 Savoir-faire Linux Inc.
Copyright (C) 2014-2017 Savoir-faire Linux Inc.
OpenDHT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
Submodule
+1
Submodule argon2 added at 6f5427fb67.
+1
View File
@@ -1 +1,2 @@
git submodule update --init
autoreconf --install --verbose -Wall
+22 -5
View File
@@ -1,7 +1,7 @@
dnl define macros
m4_define([opendht_major_version], 1)
m4_define([opendht_minor_version], 2)
m4_define([opendht_patch_version], 0)
m4_define([opendht_minor_version], 3)
m4_define([opendht_patch_version], 2)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
@@ -45,8 +45,8 @@ AC_ARG_ENABLE([python], [AS_HELP_STRING([--disable-python], [Disble python bindi
AS_IF([test "x$enable_python" != "xno"], [
AM_PATH_PYTHON([3.3],, [:])
AS_IF([test -n "$PYTHON"],[
AC_CHECK_PROGS([CYTHON], [cython3])
AS_IF([test -z "$CYTHON"],[AC_MSG_WARN([Cython not found - continuing without python support])])
echo 'import Cython' | $PYTHON
AS_IF([test $? == 0],[CYTHON=yes],[AC_MSG_WARN([Cython not found - continuing without python support])])
AC_CHECK_PROGS([PIP], [pip3])
AS_IF([test -z "$PIP"],[AC_MSG_WARN([pip not found - continuing without python uninstall support])])
])
@@ -99,6 +99,24 @@ PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
dnl Check for Argon2
AC_ARG_WITH([argon2], AS_HELP_STRING([--without-argon2], [Use included Argon2]))
AS_IF([test "x$with_argon2" != "xno"],
[PKG_CHECK_MODULES([Argon2], [libargon2], [have_argon2=yes], [have_argon2=no])],
[have_argon2=no])
AS_IF([test "x$have_argon2" = "xyes"], [], [
AS_IF([test "x$with_argon2" = "xyes"], [
AC_MSG_ERROR([Argon2 requested but not found])
],[
AC_MSG_NOTICE([Using included Argon2])
AC_SUBST(Argon2_CFLAGS, "-I\${top_srcdir}/argon2/src -I\${top_srcdir}/argon2/include")
AC_SUBST(Argon2_LIBS, "libargon2.la")
AC_SUBST(Argon2_LDFLAGS, "-L\${abs_top_srcdir}/argon2/src/.libs")
])
])
AM_CONDITIONAL([WITH_INCLUDED_ARGON2], [test "x$have_argon2" = "xno"])
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
AM_COND_IF([ENABLE_TOOLS], [
@@ -120,7 +138,6 @@ AM_COND_IF([USE_CYTHON], [
AC_CONFIG_FILES([Makefile
src/Makefile
src/argon2/Makefile
tools/Makefile
opendht.pc])
AC_OUTPUT
+2 -8
View File
@@ -1,9 +1,3 @@
FROM ubuntu:16.04
FROM ubuntu:17.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools && apt-get clean
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.0.0/msgpack-2.0.0.tar.gz \
&& tar -xzf msgpack-2.0.0.tar.gz \
&& cd msgpack-2.0.0 && mkdir build && cd build \
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
&& make -j8 && make install \
&& cd ../.. && rm -rf msgpack-2.0.0 msgpack-2.0.0.tar.gz
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools && apt-get clean
+3 -9
View File
@@ -1,13 +1,7 @@
FROM ubuntu:16.04
FROM ubuntu:17.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update \
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools \
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools \
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
ENV CC cc
ENV CXX c++
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.0.0/msgpack-2.0.0.tar.gz \
&& tar -xzf msgpack-2.0.0.tar.gz \
&& cd msgpack-2.0.0 && mkdir build && cd build \
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
&& make -j8 && make install \
&& cd ../.. && rm -rf msgpack-2.0.0 msgpack-2.0.0.tar.gz
ENV CXX c++
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
+25 -12
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -39,14 +39,24 @@ enum class NodeStatus {
Connected // 1+ good nodes
};
struct OPENDHT_PUBLIC NodeStats {
unsigned good_nodes,
dubious_nodes,
cached_nodes,
incoming_nodes;
unsigned table_depth;
unsigned getKnownNodes() const { return good_nodes + dubious_nodes; }
std::string toString() const;
};
/**
* Dht configuration.
*/
struct Config {
struct OPENDHT_PUBLIC Config {
/** DHT node ID */
InfoHash node_id;
/**
/**
* DHT network ID. A node will only talk with other nodes having
* the same network ID.
* Network ID 0 (default) represents the main public network.
@@ -55,12 +65,15 @@ struct Config {
/** For testing purposes only, enables bootstrap mode */
bool is_bootstrap;
/** Makes the DHT responsible to maintain its stored values. Consumes more ressources. */
bool maintain_storage;
};
/**
* SecureDht configuration.
*/
struct SecureDhtConfig
struct OPENDHT_PUBLIC SecureDhtConfig
{
Config node_config;
crypto::Identity id;
@@ -79,8 +92,8 @@ using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
GetCallback bindGetCb(GetCallbackSimple cb);
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
OPENDHT_PUBLIC GetCallback bindGetCb(GetCallbackSimple cb);
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
typedef void (*DoneCallbackRaw)(bool, std::vector<std::shared_ptr<Node>>*, void *user_data);
@@ -89,9 +102,9 @@ typedef void (*DoneCallbackSimpleRaw)(bool, void *user_data);
using DoneCallbackSimple = std::function<void(bool success)>;
ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
DoneCallback bindDoneCb(DoneCallbackSimple donecb);
DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackSimple donecb);
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
}
+271 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,14 +13,14 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "infohash.h"
#include "utils.h"
#include "rng.h"
extern "C" {
#include <gnutls/gnutls.h>
@@ -38,7 +38,7 @@ extern "C" {
namespace dht {
namespace crypto {
class CryptoException : public std::runtime_error {
class OPENDHT_PUBLIC CryptoException : public std::runtime_error {
public:
CryptoException(const std::string& str) : std::runtime_error(str) {};
};
@@ -46,20 +46,21 @@ class CryptoException : public std::runtime_error {
/**
* Exception thrown when a decryption error happened.
*/
class DecryptError : public CryptoException {
class OPENDHT_PUBLIC DecryptError : public CryptoException {
public:
DecryptError(const std::string& str = "") : CryptoException(str) {};
};
struct PrivateKey;
struct Certificate;
class RevocationList;
using Identity = std::pair<std::shared_ptr<PrivateKey>, std::shared_ptr<Certificate>>;
/**
* A public key.
*/
struct PublicKey
struct OPENDHT_PUBLIC PublicKey
{
PublicKey() {}
@@ -82,12 +83,15 @@ struct PublicKey
PublicKey& operator=(PublicKey&& o) noexcept;
InfoHash getId() const;
PkId getLongId() const;
bool checkSignature(const Blob& data, const Blob& signature) const;
Blob encrypt(const Blob&) const;
void pack(Blob& b) const;
void unpack(const uint8_t* dat, size_t dat_size);
std::string toString() const;
template <typename Packer>
void msgpack_pack(Packer& p) const
{
@@ -109,7 +113,7 @@ private:
/**
* A private key, including the corresponding public key.
*/
struct PrivateKey
struct OPENDHT_PUBLIC PrivateKey
{
PrivateKey();
//PrivateKey(gnutls_privkey_t k) : key(k) {}
@@ -148,6 +152,7 @@ struct PrivateKey
* Recommended values: 4096, 8192
*/
static PrivateKey generate(unsigned key_length = 4096);
static PrivateKey generateEC();
gnutls_privkey_t key {};
gnutls_x509_privkey_t x509_key {};
@@ -159,7 +164,83 @@ private:
//friend dht::crypto::Identity dht::crypto::generateIdentity(const std::string&, dht::crypto::Identity, unsigned key_length);
};
struct Certificate {
class OPENDHT_PUBLIC RevocationList
{
using clock = std::chrono::system_clock;
using time_point = clock::time_point;
using duration = clock::duration;
public:
RevocationList();
RevocationList(const Blob& b);
RevocationList(RevocationList&& o) : crl(o.crl) { o.crl = nullptr; }
~RevocationList();
RevocationList& operator=(RevocationList&& o) { crl = o.crl; o.crl = nullptr; return *this; }
void pack(Blob& b) const;
void unpack(const uint8_t* dat, size_t dat_size);
Blob getPacked() const {
Blob b;
pack(b);
return b;
}
template <typename Packer>
void msgpack_pack(Packer& p) const
{
Blob b = getPacked();
p.pack_bin(b.size());
p.pack_bin_body((const char*)b.data(), b.size());
}
void msgpack_unpack(msgpack::object o);
void revoke(const Certificate& crt, time_point t = time_point::min());
bool isRevoked(const Certificate& crt) const;
/**
* Sign this revocation list using provided key and certificate.
* Validity_period sets the duration until next update (default to no next update).
*/
void sign(const PrivateKey&, const Certificate&, duration validity_period = {});
void sign(const Identity& id) { sign(*id.first, *id.second); }
bool isSignedBy(const Certificate& issuer) const;
std::string toString() const;
/**
* Read the CRL number extension field.
*/
Blob getNumber() const;
/** Read CRL issuer Common Name (CN) */
std::string getIssuerName() const;
/** Read CRL issuer User ID (UID) */
std::string getIssuerUID() const;
time_point getUpdateTime() const;
time_point getNextUpdateTime() const;
gnutls_x509_crl_t get() { return crl; }
gnutls_x509_crl_t getCopy() const {
auto copy = RevocationList(getPacked());
gnutls_x509_crl_t ret = copy.crl;
copy.crl = nullptr;
return ret;
}
private:
gnutls_x509_crl_t crl {};
RevocationList(const RevocationList&) = delete;
RevocationList& operator=(const RevocationList&) = delete;
};
struct OPENDHT_PUBLIC Certificate {
Certificate() {}
/**
@@ -174,7 +255,10 @@ struct Certificate {
* ordered from subject to issuer
*/
Certificate(const Blob& crt);
Certificate(const uint8_t* dat, size_t dat_size) {
Certificate(const std::string& pem) : cert(nullptr) {
unpack((const uint8_t*)pem.data(), pem.size());
}
Certificate(const uint8_t* dat, size_t dat_size) : cert(nullptr) {
unpack(dat, dat_size);
}
@@ -278,6 +362,7 @@ struct Certificate {
/** Same as getPublicKey().getId() */
InfoHash getId() const;
PkId getLongId() const;
/** Read certificate Common Name (CN) */
std::string getName() const;
@@ -296,8 +381,11 @@ struct Certificate {
/** Read certificate alternative names */
std::vector<std::pair<NameType, std::string>> getAltNames() const;
std::chrono::system_clock::time_point getExpiration() const;
/**
* Returns true if the certificate is marked as a Certificate Authority.
* Returns true if the certificate is marked as a Certificate Authority
* and has necessary key usage flags to sign certificates.
*/
bool isCA() const;
@@ -307,15 +395,180 @@ struct Certificate {
*/
std::string toString(bool chain = true) const;
std::string print() const;
void revoke(const PrivateKey&, const Certificate&);
std::vector<std::shared_ptr<RevocationList>> getRevocationLists() const;
void addRevocationList(RevocationList&&);
void addRevocationList(std::shared_ptr<RevocationList>);
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", Identity ca = {}, bool is_ca = false);
gnutls_x509_crt_t getCopy() const {
auto copy = Certificate(getPacked());
gnutls_x509_crt_t ret = copy.cert;
copy.cert = nullptr;
return ret;
}
std::vector<gnutls_x509_crt_t>
getChain(bool copy = false) const
{
std::vector<gnutls_x509_crt_t> crts;
auto c = this;
do {
crts.emplace_back(copy ? c->getCopy() : c->cert);
c = c->issuer.get();
} while (c);
return crts;
}
std::pair<
std::vector<gnutls_x509_crt_t>,
std::vector<gnutls_x509_crl_t>
>
getChainWithRevocations(bool copy = false) const
{
std::vector<gnutls_x509_crt_t> crts;
std::vector<gnutls_x509_crl_t> crls;
auto c = this;
do {
crts.emplace_back(copy ? c->getCopy() : c->cert);
crls.reserve(crls.size() + c->revocation_lists.size());
for (const auto& crl : c->revocation_lists)
crls.emplace_back(copy ? crl->getCopy() : crl->get());
c = c->issuer.get();
} while (c);
return {crts, crls};
}
gnutls_x509_crt_t cert {};
std::shared_ptr<Certificate> issuer {};
private:
Certificate(const Certificate&) = delete;
Certificate& operator=(const Certificate&) = delete;
struct crlNumberCmp {
bool operator() (const std::shared_ptr<RevocationList>& lhs, const std::shared_ptr<RevocationList>& rhs) const {
return lhs->getNumber() < rhs->getNumber();
}
};
std::set<std::shared_ptr<RevocationList>, crlNumberCmp> revocation_lists;
};
struct OPENDHT_PUBLIC TrustList
{
struct VerifyResult {
int ret;
unsigned result;
bool hasError() const { return ret < 0; }
bool isValid() const { return !hasError() and !(result & GNUTLS_CERT_INVALID); }
explicit operator bool() const { return isValid(); }
std::string toString() const;
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const VerifyResult& h);
};
TrustList();
TrustList(TrustList&& o) : trust(std::move(o.trust)) {
o.trust = nullptr;
}
TrustList& operator=(TrustList&& o);
~TrustList();
void add(const Certificate& crt);
void add(const RevocationList& crl);
void remove(const Certificate& crt, bool parents = true);
VerifyResult verify(const Certificate& crt) const;
private:
TrustList(const TrustList& o) = delete;
TrustList& operator=(const TrustList& o) = delete;
gnutls_x509_trust_list_t trust;
};
template <class T>
class OPENDHT_PUBLIC secure_vector
{
public:
secure_vector() {}
secure_vector(secure_vector<T> const&) = default;
secure_vector(secure_vector<T> &&) = default;
explicit secure_vector(unsigned size): data_(size) {}
explicit secure_vector(unsigned size, T _item): data_(size, _item) {}
explicit secure_vector(const std::vector<T>& c): data_(c) {}
secure_vector(std::vector<T>&& c): data_(std::move(c)) {}
~secure_vector() { clean(); }
static secure_vector<T> getRandom(size_t size) {
secure_vector<T> ret(size/sizeof(T));
crypto::random_device rdev;
std::uniform_int_distribution<uint8_t> rand_byte;
std::generate_n((uint8_t*)ret.data_.data(), ret.size()*sizeof(T), std::bind(rand_byte, std::ref(rdev)));
return ret;
}
secure_vector<T>& operator=(const secure_vector<T>& c) {
if (&c == this)
return *this;
clean();
data_ = c.data_;
return *this;
}
secure_vector<T>& operator=(secure_vector<T>&& c) {
if (&c == this)
return *this;
clean();
data_ = std::move(c.data_);
return *this;
}
secure_vector<T>& operator=(std::vector<T>&& c) {
clean();
data_ = std::move(c);
return *this;
}
std::vector<T>& writable() { clean(); return data_; }
const std::vector<T>& makeInsecure() const { return data_; }
const uint8_t* data() const { return data_.data(); }
void clean() {
clean(data_.begin(), data_.end());
}
void clear() { clean(); data_.clear(); }
size_t size() const { return data_.size(); }
bool empty() const { return data_.empty(); }
void swap(secure_vector<T>& other) { data_.swap(other.data_); }
void resize(size_t s) {
if (s == data_.size()) return;
if (s < data_.size()) {
//shrink
clean(data_.begin()+s, data_.end());
data_.resize(s);
} else {
//grow
auto data = std::move(data_); // move protected data
clear();
data_.resize(s);
std::copy(data.begin(), data.end(), data_.begin());
clean(data.begin(), data.end());
}
}
private:
/**
* Securely wipe memory
*/
static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j) {
volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
std::fill(b, e, 0);
}
std::vector<T> data_;
};
using SecureBlob = secure_vector<uint8_t>;
/**
* Generate an RSA key pair (4096 bits) and a certificate.
@@ -324,8 +577,8 @@ private:
* If not set, the generated certificate will be a self-signed CA.
* @param key_length stength of the generated private key (bits).
*/
Identity generateIdentity(const std::string& name, Identity ca, unsigned key_length, bool is_ca);
Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {}, unsigned key_length = 4096);
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name, Identity ca, unsigned key_length, bool is_ca);
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {}, unsigned key_length = 4096);
/**
@@ -336,7 +589,7 @@ Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {},
* will use SHA256 for hash_length up to 32 bytes,
* will use SHA512 for hash_length of 33 bytes and more.
*/
Blob hash(const Blob& data, size_t hash_length = 512/8);
OPENDHT_PUBLIC Blob hash(const Blob& data, size_t hash_length = 512/8);
/**
* Generates an encryption key from a text password,
@@ -345,19 +598,19 @@ Blob hash(const Blob& data, size_t hash_length = 512/8);
* that can be transmitted in clear, and will be generated if
* not provided (32 bytes).
*/
Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
/**
* AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
*/
Blob aesEncrypt(const Blob& data, const Blob& key);
Blob aesEncrypt(const Blob& data, const std::string& password);
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const Blob& key);
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
/**
* AES-GCM decryption.
*/
Blob aesDecrypt(const Blob& data, const Blob& key);
Blob aesDecrypt(const Blob& data, const std::string& password);
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const Blob& key);
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const std::string& password);
}
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define OPENDHT_IMPORT __declspec(dllimport)
#define OPENDHT_EXPORT __declspec(dllexport)
#define OPENDHT_HIDDEN
#else
#define OPENDHT_IMPORT __attribute__ ((visibility ("default")))
#define OPENDHT_EXPORT __attribute__ ((visibility ("default")))
#define OPENDHT_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
// Now we use the generic helper definitions above to define OPENDHT_PUBLIC and OPENDHT_LOCAL.
// OPENDHT_PUBLIC is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
// OPENDHT_LOCAL is used for non-api symbols.
#ifdef opendht_EXPORTS // defined if OpenDHT is compiled as a shared library
#ifdef OPENDHT_BUILD // defined if we are building the OpenDHT shared library (instead of using it)
#define OPENDHT_PUBLIC OPENDHT_EXPORT
#else
#define OPENDHT_PUBLIC OPENDHT_IMPORT
#endif // OPENDHT_BUILD
#define OPENDHT_LOCAL OPENDHT_HIDDEN
#else // opendht_EXPORTS is not defined: this means OpenDHT is a static lib.
#define OPENDHT_PUBLIC
#define OPENDHT_LOCAL
#endif // opendht_EXPORTS
+17 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,16 +13,13 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "value.h"
MSGPACK_ADD_ENUM(dht::Value::Field)
namespace dht {
enum class ImStatus : uint8_t {
NONE = 0,
@@ -35,7 +32,7 @@ MSGPACK_ADD_ENUM(dht::ImStatus)
namespace dht {
class DhtMessage : public Value::Serializable<DhtMessage>
class OPENDHT_PUBLIC DhtMessage : public Value::Serializable<DhtMessage>
{
public:
static const ValueType TYPE;
@@ -61,7 +58,7 @@ public:
};
template <typename T>
class SignedValue : public Value::Serializable<T>
class OPENDHT_PUBLIC SignedValue : public Value::Serializable<T>
{
private:
using BaseClass = Value::Serializable<T>;
@@ -81,7 +78,7 @@ public:
};
template <typename T>
class EncryptedValue : public SignedValue<T>
class OPENDHT_PUBLIC EncryptedValue : public SignedValue<T>
{
public:
using BaseClass = SignedValue<T>;
@@ -105,7 +102,7 @@ public:
class ImMessage : public SignedValue<ImMessage>
class OPENDHT_PUBLIC ImMessage : public SignedValue<ImMessage>
{
private:
using BaseClass = SignedValue<ImMessage>;
@@ -123,7 +120,7 @@ public:
}
dht::InfoHash to;
dht::Value::Id id;
dht::Value::Id id {0};
std::string msg;
long date {0};
ImStatus status {ImStatus::NONE};
@@ -131,7 +128,7 @@ public:
MSGPACK_DEFINE_MAP(id, msg, date, status)
};
class TrustRequest : public EncryptedValue<TrustRequest>
class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
{
private:
using BaseClass = EncryptedValue<TrustRequest>;
@@ -149,10 +146,11 @@ public:
std::string service;
Blob payload;
MSGPACK_DEFINE(service, payload)
bool confirm {false};
MSGPACK_DEFINE_MAP(service, payload, confirm)
};
class IceCandidates : public EncryptedValue<IceCandidates>
class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
{
private:
using BaseClass = EncryptedValue<IceCandidates>;
@@ -192,13 +190,13 @@ public:
ice_data = unpackBlob(o.via.array.ptr[1]);
}
Value::Id id;
Value::Id id {0};
Blob ice_data;
};
/* "Peer" announcement
*/
class IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
class OPENDHT_PUBLIC IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
{
private:
using BaseClass = Value::Serializable<IpServiceAnnouncement>;
@@ -224,7 +222,7 @@ public:
void msgpack_pack(Packer& pk) const
{
pk.pack_array(2);
pk.pack(getPort());
pk.pack(reinterpret_cast<const sockaddr_in*>(&ss)->sin_port);
if (ss.ss_family == AF_INET) {
pk.pack_bin(sizeof(in_addr));
pk.pack_bin_body((const char*)&reinterpret_cast<const sockaddr_in*>(&ss)->sin_addr, sizeof(in_addr));
@@ -238,7 +236,7 @@ public:
{
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
if (o.via.array.size < 2) throw msgpack::type_error();
setPort(o.via.array.ptr[0].as<in_port_t>());
reinterpret_cast<sockaddr_in*>(&ss)->sin_port = o.via.array.ptr[0].as<in_port_t>();
auto ip_dat = o.via.array.ptr[1].as<Blob>();
if (ip_dat.size() == sizeof(in_addr))
std::copy(ip_dat.begin(), ip_dat.end(), (char*)&reinterpret_cast<sockaddr_in*>(&ss)->sin_addr);
@@ -273,8 +271,8 @@ private:
};
extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
}
+67 -57
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -41,7 +41,9 @@
namespace dht {
namespace net {
struct Request;
} /* namespace net */
/**
* Main Dht class.
@@ -50,7 +52,7 @@ struct Request;
* Must be given open UDP sockets and ::periodic must be
* called regularly.
*/
class Dht {
class OPENDHT_PUBLIC Dht {
public:
// [[deprecated]]
@@ -173,12 +175,12 @@ public:
/**
* Get locally stored data for the given hash.
*/
std::vector<std::shared_ptr<Value>> getLocal(const InfoHash& key, Value::Filter f = Value::AllFilter()) const;
std::vector<Sp<Value>> getLocal(const InfoHash& key, Value::Filter f = Value::AllFilter()) const;
/**
* Get locally stored data for the given key and value id.
*/
std::shared_ptr<Value> getLocalById(const InfoHash& key, Value::Id vid) const;
Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const;
/**
* Announce a value on all available protocols (IPv4, IPv6).
@@ -187,12 +189,12 @@ public:
* The done callback will be called once, when the first announce succeeds, or fails.
*/
void put(const InfoHash& key,
std::shared_ptr<Value>,
Sp<Value>,
DoneCallback cb=nullptr,
time_point created=time_point::max(),
bool permanent = false);
void put(const InfoHash& key,
const std::shared_ptr<Value>& v,
const Sp<Value>& v,
DoneCallbackSimple cb,
time_point created=time_point::max(),
bool permanent = false)
@@ -220,12 +222,12 @@ public:
/**
* Get data currently being put at the given hash.
*/
std::vector<std::shared_ptr<Value>> getPut(const InfoHash&);
std::vector<Sp<Value>> getPut(const InfoHash&);
/**
* Get data currently being put at the given hash with the given id.
*/
std::shared_ptr<Value> getPut(const InfoHash&, const Value::Id&);
Sp<Value> getPut(const InfoHash&, const Value::Id&);
/**
* Stop any put/announce operation at the given location,
@@ -268,8 +270,8 @@ public:
std::vector<ValuesExport> exportValues() const;
void importValues(const std::vector<ValuesExport>&);
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return,
unsigned *incoming_return) const;
NodeStats getNodesStats(sa_family_t af) const;
std::string getStorageLog() const;
std::string getStorageLog(const InfoHash&) const;
@@ -344,9 +346,9 @@ private:
/* Timeout for listen */
static constexpr std::chrono::seconds LISTEN_EXPIRE_TIME {30};
static constexpr std::chrono::seconds REANNOUNCE_MARGIN {5};
static constexpr std::chrono::seconds REANNOUNCE_MARGIN {10};
static constexpr size_t TOKEN_SIZE {64};
static constexpr size_t TOKEN_SIZE {32};
// internal structures
struct SearchNode;
@@ -355,6 +357,7 @@ private:
struct LocalListener;
struct Search;
struct ValueStorage;
class StorageBucket;
struct Listener;
struct Storage;
@@ -375,17 +378,19 @@ private:
// Only nodes running only as bootstrap nodes should
// be put in bootstrap mode.
const bool is_bootstrap {false};
const bool maintain_storage {false};
// the stuff
RoutingTable buckets4 {};
RoutingTable buckets6 {};
std::map<InfoHash, Storage> store;
std::map<SockAddr, StorageBucket, SockAddr::ipCmp> store_quota;
size_t total_values {0};
size_t total_store_size {0};
size_t max_store_size {DEFAULT_STORAGE_LIMIT};
using SearchMap = std::map<InfoHash, std::shared_ptr<Search>>;
using SearchMap = std::map<InfoHash, Sp<Search>>;
SearchMap searches4 {};
SearchMap searches6 {};
uint16_t search_id {0};
@@ -397,11 +402,11 @@ private:
// timing
Scheduler scheduler;
std::shared_ptr<Scheduler::Job> nextNodesConfirmation {};
std::shared_ptr<Scheduler::Job> nextStorageMaintenance {};
Sp<Scheduler::Job> nextNodesConfirmation {};
Sp<Scheduler::Job> nextStorageMaintenance {};
time_point mybucket_grow_time {time_point::min()}, mybucket6_grow_time {time_point::min()};
NetworkEngine network_engine;
net::NetworkEngine network_engine;
unsigned pending_pings4 {0};
unsigned pending_pings6 {0};
@@ -416,11 +421,15 @@ private:
void reportedAddr(const SockAddr&);
// Storage
void storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, size_t tid, Query&& = {});
bool storageStore(const InfoHash& id, const std::shared_ptr<Value>& value, time_point created);
void expireStorage();
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {});
bool storageStore(const InfoHash& id, const Sp<Value>& value, time_point created, const SockAddr* sa = nullptr);
void expireStore();
void expireStorage(InfoHash h);
void expireStore(decltype(store)::iterator);
void storageChanged(const InfoHash& id, Storage& st, ValueStorage&);
std::string printStorageLog(const decltype(store)::value_type&) const;
void printStorageQuota(std::ostream& out, const decltype(store_quota)::value_type& ip) const;
/**
* For a given storage, if values don't belong there anymore because this
@@ -456,10 +465,10 @@ private:
void dumpBucket(const Bucket& b, std::ostream& out) const;
// Nodes
void onNewNode(const std::shared_ptr<Node>& node, int confirm);
std::shared_ptr<Node> findNode(const InfoHash& id, sa_family_t af);
const std::shared_ptr<Node> findNode(const InfoHash& id, sa_family_t af) const;
bool trySearchInsert(const std::shared_ptr<Node>& node);
void onNewNode(const Sp<Node>& node, int confirm);
Sp<Node> findNode(const InfoHash& id, sa_family_t af);
const Sp<Node> findNode(const InfoHash& id, sa_family_t af) const;
bool trySearchInsert(const Sp<Node>& node);
// Searches
@@ -470,10 +479,10 @@ private:
* Low-level method that will perform a search on the DHT for the specified
* infohash (id), using the specified IP version (IPv4 or IPv6).
*/
std::shared_ptr<Search> search(const InfoHash& id, sa_family_t af, GetCallback = {}, QueryCallback = {}, DoneCallback = {}, Value::Filter = {}, Query q = {});
Sp<Search> search(const InfoHash& id, sa_family_t af, GetCallback = {}, QueryCallback = {}, DoneCallback = {}, Value::Filter = {}, Query q = {});
void announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created=time_point::max(), bool permanent = false);
size_t listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter f = Value::AllFilter(), const std::shared_ptr<Query>& q = {});
void announce(const InfoHash& id, sa_family_t af, Sp<Value> value, DoneCallback callback, time_point created=time_point::max(), bool permanent = false);
size_t listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter f = Value::AllFilter(), const Sp<Query>& q = {});
/**
* Refill the search with good nodes if possible.
@@ -483,8 +492,6 @@ private:
* @return the number inserted nodes.
*/
unsigned refill(Search& sr);
Search *findSearch(unsigned short tid, sa_family_t af);
void expireSearches();
void confirmNodes();
@@ -498,10 +505,10 @@ private:
* @param ws A weak pointer to the search concerned by the request.
* @param query The query sent to the node.
*/
void searchNodeGetDone(const Request& status,
NetworkEngine::RequestAnswer&& answer,
void searchNodeGetDone(const net::Request& status,
net::NetworkEngine::RequestAnswer&& answer,
std::weak_ptr<Search> ws,
std::shared_ptr<Query> query);
Sp<Query> query);
/**
* Generic function to execute when a 'get' request expires.
@@ -512,7 +519,7 @@ private:
* @param ws A weak pointer to the search concerned by the request.
* @param query The query sent to the node.
*/
void searchNodeGetExpired(const Request& status, bool over, std::weak_ptr<Search> ws, std::shared_ptr<Query> query);
void searchNodeGetExpired(const net::Request& status, bool over, std::weak_ptr<Search> ws, Sp<Query> query);
/**
* This method recovers sends individual request for values per id.
@@ -521,12 +528,12 @@ private:
* @param query The initial query passed through the API.
* @param n The node to which send the requests.
*/
void paginate(std::weak_ptr<Search> ws, std::shared_ptr<Query> query, SearchNode* n);
void paginate(std::weak_ptr<Search> ws, Sp<Query> query, SearchNode* n);
/**
* If update is true, this method will also send message to synced but non-updated search nodes.
*/
SearchNode* searchSendGetValues(std::shared_ptr<Search> sr, SearchNode *n = nullptr, bool update = true);
SearchNode* searchSendGetValues(Sp<Search> sr, SearchNode *n = nullptr, bool update = true);
/**
* Forwards an 'announce' request for a list of nodes to the network engine.
@@ -534,7 +541,7 @@ private:
* @param sr The search for which we want to announce a value.
* @param announce The 'announce' structure.
*/
void searchSendAnnounceValue(const std::shared_ptr<Search>& sr);
void searchSendAnnounceValue(const Sp<Search>& sr);
/**
* Main process of a Search's operations. This function will demand the
@@ -543,51 +550,54 @@ private:
*
* @param sr The search to execute its operations.
*/
void searchStep(std::shared_ptr<Search> sr);
void searchStep(Sp<Search> sr);
void dumpSearch(const Search& sr, std::ostream& out) const;
bool neighbourhoodMaintenance(RoutingTable&);
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr&);
void onError(std::shared_ptr<Request> node, DhtProtocolException e);
void onError(Sp<net::Request> node, net::DhtProtocolException e);
/* when our address is reported by a distant peer. */
void onReportedAddr(const InfoHash& id, const SockAddr&);
/* when we receive a ping request */
NetworkEngine::RequestAnswer onPing(std::shared_ptr<Node> node);
net::NetworkEngine::RequestAnswer onPing(Sp<Node> node);
/* when we receive a "find node" request */
NetworkEngine::RequestAnswer onFindNode(std::shared_ptr<Node> node, const InfoHash& hash, want_t want);
void onFindNodeDone(const Request& status, NetworkEngine::RequestAnswer& a, std::shared_ptr<Search> sr);
net::NetworkEngine::RequestAnswer onFindNode(Sp<Node> node, const InfoHash& hash, want_t want);
void onFindNodeDone(const Sp<Node>& status,
net::NetworkEngine::RequestAnswer& a,
Sp<Search> sr);
/* when we receive a "get values" request */
NetworkEngine::RequestAnswer onGetValues(std::shared_ptr<Node> node,
net::NetworkEngine::RequestAnswer onGetValues(Sp<Node> node,
const InfoHash& hash,
want_t want,
const Query& q);
void onGetValuesDone(const Request& status,
NetworkEngine::RequestAnswer& a,
std::shared_ptr<Search>& sr,
const std::shared_ptr<Query>& orig_query);
void onGetValuesDone(const Sp<Node>& status,
net::NetworkEngine::RequestAnswer& a,
Sp<Search>& sr,
const Sp<Query>& orig_query);
/* when we receive a listen request */
NetworkEngine::RequestAnswer onListen(std::shared_ptr<Node> node,
net::NetworkEngine::RequestAnswer onListen(Sp<Node> node,
const InfoHash& hash,
const Blob& token,
size_t rid,
size_t socket_id,
const Query& query);
void onListenDone(const Request& status,
NetworkEngine::RequestAnswer& a,
std::shared_ptr<Search>& sr,
const std::shared_ptr<Query>& orig_query);
void onListenDone(const Sp<Node>& status,
net::NetworkEngine::RequestAnswer& a,
Sp<Search>& sr);
/* when we receive an announce request */
NetworkEngine::RequestAnswer onAnnounce(std::shared_ptr<Node> node,
net::NetworkEngine::RequestAnswer onAnnounce(Sp<Node> node,
const InfoHash& hash,
const Blob& token,
const std::vector<std::shared_ptr<Value>>& v,
const std::vector<Sp<Value>>& v,
const time_point& created);
NetworkEngine::RequestAnswer onRefresh(std::shared_ptr<Node> node,
net::NetworkEngine::RequestAnswer onRefresh(Sp<Node> node,
const InfoHash& hash,
const Blob& token,
const Value::Id& vid);
void onAnnounceDone(const Request& status, NetworkEngine::RequestAnswer& a, std::shared_ptr<Search>& sr);
void onAnnounceDone(const Sp<Node>& status,
net::NetworkEngine::RequestAnswer& a,
Sp<Search>& sr);
};
}
+12 -9
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -26,6 +25,7 @@
#include "callbacks.h"
#include "sockaddr.h"
#include "log_enable.h"
#include "def.h"
#include <thread>
#include <mutex>
@@ -48,7 +48,7 @@ struct SecureDhtConfig;
* either wait for (expectedly frequent) calls to ::loop() or start an internal
* thread that will update the DHT when appropriate.
*/
class DhtRunner {
class OPENDHT_PUBLIC DhtRunner {
public:
typedef std::function<void(NodeStatus, NodeStatus)> StatusCallback;
@@ -203,6 +203,7 @@ public:
* Usefull to restart a node and get things running fast without putting load on the network.
*/
void bootstrap(const std::vector<std::pair<sockaddr_storage, socklen_t>>& nodes, DoneCallbackSimple&& cb={});
void bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb={});
/**
* Insert known nodes to the routing table, without necessarly ping them.
@@ -275,14 +276,15 @@ public:
return running;
}
int getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
NodeStats getNodesStats(sa_family_t af) const;
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
std::vector<unsigned> getNodeMessageStats(bool in = false) const;
std::string getStorageLog() const;
std::string getStorageLog(const InfoHash&) const;
std::string getRoutingTablesLog(sa_family_t af) const;
std::string getSearchesLog(sa_family_t af = AF_UNSPEC) const;
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC);
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC);
@@ -309,7 +311,8 @@ public:
/*.node_config = */{
/*.node_id = */{},
/*.network = */network,
/*.is_bootstrap = */false
/*.is_bootstrap = */false,
/*.maintain_storage*/false
},
/*.id = */identity
},
@@ -368,7 +371,7 @@ private:
* nodes so that the DHT node can recover quickly from losing connection
* with the network.
*/
void tryBootstrapCoutinuously();
void tryBootstrapContinuously();
void doRun(const sockaddr_in* sin4, const sockaddr_in6* sin6, SecureDhtConfig config);
time_point loop_();
+32 -13
View File
@@ -1,3 +1,23 @@
/*
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Nicolas Reynaud <nicolas.reynaud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
@@ -26,7 +46,7 @@ namespace indexation {
* the node in question is a leaf, *the label is a prefix of all the keys
* contained in the leaf*.
*/
struct Prefix {
struct OPENDHT_PUBLIC Prefix {
Prefix() {}
Prefix(InfoHash h) : size_(h.size() * 8), content_(h.begin(), h.end()) { }
Prefix(const Blob& d, const Blob& f={}) : size_(d.size()*8), flags_(f), content_(d) { }
@@ -245,7 +265,7 @@ private:
};
using Value = std::pair<InfoHash, dht::Value::Id>;
struct IndexEntry : public dht::Value::Serializable<IndexEntry> {
struct OPENDHT_PUBLIC IndexEntry : public dht::Value::Serializable<IndexEntry> {
static const ValueType TYPE;
virtual void unpackValue(const dht::Value& v) {
@@ -265,7 +285,7 @@ struct IndexEntry : public dht::Value::Serializable<IndexEntry> {
MSGPACK_DEFINE_MAP(prefix, value)
};
class Pht {
class OPENDHT_PUBLIC Pht {
static constexpr const char* INVALID_KEY = "Key does not match the PHT key spec.";
/* Prefixes the user_type for all dht values put on the DHT */
@@ -284,13 +304,13 @@ public:
/* Specifications of the keys. It defines the number, the length and the
* serialization order of fields. */
using KeySpec = std::map<std::string, size_t>;
using LookupCallback = std::function<void(std::vector<std::shared_ptr<Value>>& values, Prefix p)>;
using LookupCallback = std::function<void(std::vector<std::shared_ptr<Value>>& values, const Prefix& p)>;
typedef void (*LookupCallbackRaw)(std::vector<std::shared_ptr<Value>>* values, Prefix* p, void *user_data);
static LookupCallback
bindLookupCb(LookupCallbackRaw raw_cb, void* user_data) {
if (not raw_cb) return {};
return [=](std::vector<std::shared_ptr<Value>>& values, Prefix p) {
return [=](std::vector<std::shared_ptr<Value>>& values, const Prefix& p) {
raw_cb((std::vector<std::shared_ptr<Value>>*) &values, (Prefix*) &p, user_data);
};
}
@@ -353,7 +373,7 @@ private:
* @param done_cb : Callback to call when the insert is done
*/
void insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
void insert(const Prefix& kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
bool check_split, DoneCallbackSimple done_cb = {});
class Cache {
@@ -396,8 +416,8 @@ private:
};
/* Callback used for insert value by using the pht */
using RealInsertCallback = std::function<void(std::shared_ptr<Prefix> p, IndexEntry entry)>;
using LookupCallbackWrapper = std::function<void(std::vector<std::shared_ptr<IndexEntry>>& values, Prefix p)>;
using RealInsertCallback = std::function<void(const Prefix& p, IndexEntry entry)>;
using LookupCallbackWrapper = std::function<void(std::vector<std::shared_ptr<IndexEntry>>& values, const Prefix& p)>;
/**
* Performs a step in the lookup operation. Each steps are performed
@@ -446,7 +466,7 @@ private:
* @param entry The entry to put at the prefix p
* @param end_cb Callback to use at the end of counting
*/
void getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertCallback end_cb );
void getRealPrefix(const std::shared_ptr<Prefix>& p, IndexEntry entry, RealInsertCallback end_cb );
/**
* Looking where to put the data cause if there is free space on the node
@@ -465,12 +485,11 @@ private:
* @param vals : The vector of values to compare with comapred
* @return position compared diverge from all others
*/
size_t foundSplitLocation(Prefix compared, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals) {
static size_t findSplitLocation(const Prefix& compared, const std::vector<std::shared_ptr<IndexEntry>>& vals) {
for ( size_t i = 0; i < compared.content_.size() * 8 - 1; i++ )
for ( auto const& v : *vals)
for ( auto const& v : vals)
if ( Prefix(v->prefix).isContentBitActive(i) != compared.isContentBitActive(i) )
return i + 1;
return compared.content_.size() * 8 - 1;
}
@@ -482,7 +501,7 @@ private:
* @param entry : Entry to put on the pht
* @param end_cb : Callback to apply to the insert prefi (here does the insert)
*/
void split(Prefix insert, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals, IndexEntry entry, RealInsertCallback end_cb);
void split(const Prefix& insert, const std::vector<std::shared_ptr<IndexEntry>>& vals, IndexEntry entry, RealInsertCallback end_cb);
/**
* Tells if the key is valid according to the key spec.
+92 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,12 +13,13 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "def.h"
#include <msgpack.hpp>
#ifndef _WIN32
@@ -40,6 +41,7 @@ typedef uint16_t in_port_t;
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <sstream>
#include <cstring>
@@ -48,12 +50,93 @@ typedef uint16_t in_port_t;
namespace dht {
using byte = uint8_t;
template <size_t N>
class OPENDHT_PUBLIC Hash
{
public:
Hash() {
data_.fill(0);
}
Hash(const msgpack::object& o) {
msgpack_unpack(o);
}
byte* data() {
return data_.data();
}
const byte* data() const {
return data_.data();
}
constexpr size_t size() const { return data_.size(); }
explicit operator bool() const { return std::any_of(data_.begin(), data_.end(), [](byte _b) { return _b != 0; }); }
bool operator==(Hash const& _c) const { return data_ == _c.data_; }
bool operator!=(Hash const& _c) const { return data_ != _c.data_; }
bool operator<(Hash const& _c) const { for (unsigned i = 0; i < N; ++i) if (data_[i] < _c.data_[i]) return true; else if (data_[i] > _c.data_[i]) return false; return false; }
bool operator>=(Hash const& _c) const { return !operator<(_c); }
bool operator<=(Hash const& _c) const { return operator==(_c) || operator<(_c); }
bool operator>(Hash const& _c) const { return !operator<=(_c); }
template <typename Packer>
void msgpack_pack(Packer& pk) const
{
pk.pack_bin(N);
pk.pack_bin_body((char*)data_.data(), N);
}
void msgpack_unpack(msgpack::object o) {
if (o.type != msgpack::type::BIN or o.via.bin.size != N)
throw msgpack::type_error();
std::copy_n(o.via.bin.ptr, N, data_.data());
}
template <size_t M>
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
template <size_t M>
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, Hash<M>& h);
std::string toString() const {
std::stringstream ss;
ss << *this;
return ss.str();
}
private:
std::array<byte, N> data_;
};
template <size_t N>
std::ostream& operator<< (std::ostream& s, const Hash<N>& h)
{
s << std::hex;
for (unsigned i=0; i<h.size(); i++)
s << std::setfill('0') << std::setw(2) << (unsigned)h.data_[i];
s << std::dec;
return s;
}
template <size_t N>
std::istream& operator>> (std::istream& s, Hash<N>& h)
{
std::array<char, h.size()*2> dat;
s.exceptions(std::istream::eofbit | std::istream::failbit);
s.read(&(*dat.begin()), dat.size());
for (size_t i = 0; i < h.size(); i++) {
unsigned res = 0;
sscanf(dat.data() + 2*i, "%02x", &res);
h[i] = res;
}
return s;
}
using h256 = Hash<32>;
using PkId = h256;
/**
* Represents an InfoHash.
* An InfoHash is a byte array of HASH_LEN bytes.
* InfoHashes identify nodes and values in the Dht.
*/
class InfoHash final : public std::array<uint8_t, HASH_LEN> {
class OPENDHT_PUBLIC InfoHash final : public std::array<uint8_t, HASH_LEN> {
public:
constexpr InfoHash() : std::array<uint8_t, HASH_LEN>() {}
constexpr InfoHash(const std::array<uint8_t, HASH_LEN>& h) : std::array<uint8_t, HASH_LEN>(h) {}
@@ -96,11 +179,7 @@ public:
* Forget about the ``XOR-metric''. An id is just a path from the
* root of the tree, so bits are numbered from the start.
*/
#ifdef WIN32_NATIVE
static inline int cmp(const InfoHash& __restrict id1, const InfoHash& __restrict id2) {
#else
static inline int cmp(const InfoHash& __restrict__ id1, const InfoHash& __restrict__ id2) {
#endif
static inline int cmp(const InfoHash& id1, const InfoHash& id2) {
return std::memcmp(id1.data(), id2.data(), HASH_LEN);
}
@@ -196,8 +275,10 @@ public:
static InfoHash getRandom();
friend std::ostream& operator<< (std::ostream& s, const InfoHash& h);
friend std::istream& operator>> (std::istream& s, InfoHash& h);
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const InfoHash& h);
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, InfoHash& h);
const char* to_c_str() const;
std::string toString() const;
+10 -52
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -62,58 +61,17 @@ constexpr const Color::Modifier yellow(Color::FG_YELLOW);
/**
* Print va_list to std::ostream (used for logging).
*/
void
printLog(std::ostream& s, char const* m, va_list args) {
// print log to buffer
std::array<char, 8192> buffer;
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
if (ret < 0)
return;
OPENDHT_PUBLIC void
printLog(std::ostream &s, char const *m, va_list args);
// write timestamp
using namespace std::chrono;
using log_precision = microseconds;
constexpr auto den = log_precision::period::den;
auto micro = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
s << "[" << std::setfill('0') << std::setw(6) << micro / den << "."
<< std::setfill('0') << std::setw(6) << micro % den << "]" << " ";
OPENDHT_PUBLIC void
enableLogging(dht::DhtRunner &dht);
// write log
s.write(buffer.data(), std::min((size_t)ret, buffer.size()));
if ((size_t)ret >= buffer.size())
s << "[[TRUNCATED]]";
s.put('\n');
}
OPENDHT_PUBLIC void
enableFileLogging(dht::DhtRunner &dht, const std::string &path);
void
enableLogging(dht::DhtRunner& dht)
{
dht.setLoggers(
[](char const* m, va_list args){ std::cerr << red; printLog(std::cerr, m, args); std::cerr << def; },
[](char const* m, va_list args){ std::cout << yellow; printLog(std::cout, m, args); std::cout << def; },
[](char const* m, va_list args){ printLog(std::cout, m, args); }
);
}
void
enableFileLogging(dht::DhtRunner& dht, const std::string& path)
{
auto logfile = std::make_shared<std::fstream>();
logfile->open(path, std::ios::out);
dht.setLoggers(
[=](char const* m, va_list args){ printLog(*logfile, m, args); },
[=](char const* m, va_list args){ printLog(*logfile, m, args); },
[=](char const* m, va_list args){ printLog(*logfile, m, args); }
);
}
void
disableLogging(dht::DhtRunner& dht)
{
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
}
OPENDHT_PUBLIC void
disableLogging(dht::DhtRunner &dht);
} /* log */
} /* dht */
+1 -1
View File
@@ -13,7 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <cstdint>
namespace dht {
namespace net {
struct TransPrefix : public std::array<uint8_t, 2> {
TransPrefix(const std::string& str) : std::array<uint8_t, 2>({{(uint8_t)str[0], (uint8_t)str[1]}}) {}
static const TransPrefix PING;
static const TransPrefix FIND_NODE;
static const TransPrefix GET_VALUES;
static const TransPrefix ANNOUNCE_VALUES;
static const TransPrefix REFRESH;
static const TransPrefix LISTEN;
};
/* Transaction-ids are 4-bytes long, with the first two bytes identifying
* the kind of request, and the remaining two a sequence number in
* host order.
*/
struct TransId final : public std::array<uint8_t, 4> {
static const constexpr uint16_t INVALID {0};
TransId() { std::fill_n(begin(), 4, 0); }
TransId(const std::array<char, 4>& o) { std::copy(o.begin(), o.end(), begin()); }
TransId(const TransPrefix prefix, uint16_t seqno = 0) {
std::copy_n(prefix.begin(), prefix.size(), begin());
*reinterpret_cast<uint16_t*>(data()+prefix.size()) = seqno;
}
TransId(const char* q, size_t l) : array<uint8_t, 4>() {
if (l > 4) {
length = 0;
} else {
std::copy_n(q, l, begin());
length = l;
}
}
uint16_t getTid() const {
return *reinterpret_cast<const uint16_t*>(&(*this)[2]);
}
uint32_t toInt() const {
return *reinterpret_cast<const uint32_t*>(&(*this)[0]);
}
bool matches(const TransPrefix prefix, uint16_t* tid = nullptr) const {
if (std::equal(begin(), begin()+2, prefix.begin())) {
if (tid)
*tid = getTid();
return true;
} else
return false;
}
unsigned length {4};
};
} /* namespace net */
} /* dht */
+244 -186
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -27,6 +27,7 @@
#include "utils.h"
#include "rng.h"
#include "rate_limiter.h"
#include "net.h"
#include <vector>
#include <string>
@@ -37,6 +38,10 @@
#include <queue>
namespace dht {
namespace net {
struct Request;
struct Socket;
#ifndef MSG_CONFIRM
#define MSG_CONFIRM 0
@@ -96,56 +101,7 @@ struct ParsedMessage;
*/
class NetworkEngine final
{
struct TransPrefix : public std::array<uint8_t, 2> {
TransPrefix(const std::string& str) : std::array<uint8_t, 2>({{(uint8_t)str[0], (uint8_t)str[1]}}) {}
static const TransPrefix PING;
static const TransPrefix FIND_NODE;
static const TransPrefix GET_VALUES;
static const TransPrefix ANNOUNCE_VALUES;
static const TransPrefix REFRESH;
static const TransPrefix LISTEN;
};
public:
/* Transaction-ids are 4-bytes long, with the first two bytes identifying
* the kind of request, and the remaining two a sequence number in
* host order.
*/
struct TransId final : public std::array<uint8_t, 4> {
static const constexpr uint16_t INVALID {0};
TransId() {}
TransId(const std::array<char, 4>& o) { std::copy(o.begin(), o.end(), begin()); }
TransId(const TransPrefix prefix, uint16_t seqno = 0) {
std::copy_n(prefix.begin(), prefix.size(), begin());
*reinterpret_cast<uint16_t*>(data()+prefix.size()) = seqno;
}
TransId(const char* q, size_t l) : array<uint8_t, 4>() {
if (l > 4) {
length = 0;
} else {
std::copy_n(q, l, begin());
length = l;
}
}
uint16_t getTid() const {
return *reinterpret_cast<const uint16_t*>(&(*this)[2]);
}
bool matches(const TransPrefix prefix, uint16_t* tid = nullptr) const {
if (std::equal(begin(), begin()+2, prefix.begin())) {
if (tid)
*tid = getTid();
return true;
} else
return false;
}
unsigned length {4};
};
/*!
* @class RequestAnswer
* @brief Answer for a request.
@@ -156,121 +112,101 @@ public:
struct RequestAnswer {
Blob ntoken {};
Value::Id vid {};
std::vector<std::shared_ptr<Value>> values {};
std::vector<std::shared_ptr<FieldValueIndex>> fields {};
std::vector<std::shared_ptr<Node>> nodes4 {};
std::vector<std::shared_ptr<Node>> nodes6 {};
std::vector<Sp<Value>> values {};
std::vector<Sp<FieldValueIndex>> fields {};
std::vector<Sp<Node>> nodes4 {};
std::vector<Sp<Node>> nodes6 {};
RequestAnswer() {}
RequestAnswer(ParsedMessage&& msg);
};
/**
* Cancel a request. Setting req->cancelled = true is not enough in the case
* a request is "persistent".
*/
void cancelRequest(std::shared_ptr<Request>& req);
void connectivityChanged(sa_family_t);
private:
/**
* Called when we receive an error message.
*/
std::function<void(Sp<Request>, DhtProtocolException)> onError;
/**
* @brief when we receive an error message.
*
* @param node (type: std::shared_ptr<Request>) the associated request for
* which we got an error;
*/
std::function<void(std::shared_ptr<Request>, DhtProtocolException)> onError;
/**
* @brief when a new node happens.
*
* Called for every packets received for handling new nodes contacting us.
*
* @param id (type: InfoHash) id of the node.
* @param saddr (type: sockaddr*) sockaddr* pointer containing address ip information.
* @param saddr_len (type: socklen_t) lenght of the sockaddr struct.
* @param confirm (type: int) 1 if the node sent a message, 2 if it sent us a reply.
* @param node: the node
* @param confirm: 1 if the node sent a message, 2 if it sent us a reply.
*/
std::function<void(const std::shared_ptr<Node>&, int)> onNewNode;
std::function<void(const Sp<Node>&, int)> onNewNode;
/**
* @brief when an addres is reported from a distant node.
* Called when an addres is reported from a requested node.
*
* @param id (type: InfoHash) id of the node.
* @param saddr (type: sockaddr*) sockaddr* pointer containing address ip information.
* @param h: id
* @param saddr_len (type: socklen_t) lenght of the sockaddr struct.
*/
std::function<void(const InfoHash&, const SockAddr&)> onReportedAddr;
/**
* @brief on ping request callback.
* Called on ping reception.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param node (type: Sp<Node>) the requesting node.
*/
std::function<RequestAnswer(std::shared_ptr<Node>)> onPing {};
std::function<RequestAnswer(Sp<Node>)> onPing {};
/**
* @brief on find node request callback.
* Called on find node request.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param vhash (type: InfoHash) hash of the value of interest.
* @param node (type: Sp<Node>) the requesting node.
* @param h (type: InfoHash) hash of the value of interest.
* @param want (type: want_t) states if nodes sent in the response are ipv4
* or ipv6.
*/
std::function<RequestAnswer(std::shared_ptr<Node>,
const InfoHash&,
want_t)> onFindNode {};
std::function<RequestAnswer(Sp<Node>, const InfoHash&, want_t)> onFindNode {};
/**
* @brief on "get values" request callback.
* Called on "get values" request.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param vhash (type: InfoHash) hash of the value of interest.
* @param node (type: Sp<Node>) the requesting node.
* @param h (type: InfoHash) hash of the value of interest.
* @param want (type: want_t) states if nodes sent in the response are ipv4
* or ipv6.
*/
std::function<RequestAnswer(std::shared_ptr<Node>,
const InfoHash&,
want_t,
const Query&)> onGetValues {};
std::function<RequestAnswer(Sp<Node>, const InfoHash&, want_t, const Query&)> onGetValues {};
/**
* @brief on listen request callback.
* Called on listen request.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param vhash (type: InfoHash) hash of the value of interest.
* @param node (type: Sp<Node>) the requesting node.
* @param h (type: InfoHash) hash of the value of interest.
* @param token (type: Blob) security token.
* @param rid (type: uint16_t) request id.
*/
std::function<RequestAnswer(std::shared_ptr<Node>,
std::function<RequestAnswer(Sp<Node>,
const InfoHash&,
const Blob&,
uint16_t,
uint32_t,
const Query&)> onListen {};
/**
* @brief on announce request callback.
* Called on announce request.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param vhash (type: InfoHash) hash of the value of interest.
* @param node (type: Sp<Node>) the requesting node.
* @param h (type: InfoHash) hash of the value of interest.
* @param token (type: Blob) security token.
* @param values (type: std::vector<std::shared_ptr<Value>>) values to store.
* @param values (type: std::vector<Sp<Value>>) values to store.
* @param created (type: time_point) time when the value was created.
*/
std::function<RequestAnswer(std::shared_ptr<Node>,
std::function<RequestAnswer(Sp<Node>,
const InfoHash&,
const Blob&,
const std::vector<std::shared_ptr<Value>>&,
const std::vector<Sp<Value>>&,
const time_point&)> onAnnounce {};
/**
* @brief on refresh request callback.
* Called on refresh request.
*
* @param node (type: std::shared_ptr<Node>) the requesting node.
* @param vhash (type: InfoHash) hash of the value of interest.
* @param node (type: Sp<Node>) the requesting node.
* @param h (type: InfoHash) hash of the value of interest.
* @param token (type: Blob) security token.
* @param vid (type: Value::id) the value id.
*/
std::function<RequestAnswer(std::shared_ptr<Node>,
std::function<RequestAnswer(Sp<Node>,
const InfoHash&,
const Blob&,
const Value::Id&)> onRefresh {};
public:
using SocketCb = std::function<void(const Sp<Node>&, RequestAnswer&&)>;
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
using RequestExpiredCb = std::function<void(const Request&, bool)>;
@@ -293,67 +229,186 @@ public:
/**
* Sends values (with closest nodes) to a listenner.
*
* @param sa The address of the listenner.
* @param sslen The length of the sockaddr structure.
* @param rid The request id of the initial listen request.
* @param hash The hash key of the value.
* @param want Wether to send ipv4 and/or ipv6 nodes.
* @param ntoken Listen security token.
* @param nodes The ipv4 closest nodes.
* @param nodes6 The ipv6 closest nodes.
* @param values The values to send.
* @param sa The address of the listenner.
* @param sslen The length of the sockaddr structure.
* @param socket_id The tid to use to write to the request socket.
* @param hash The hash key of the value.
* @param want Wether to send ipv4 and/or ipv6 nodes.
* @param ntoken Listen security token.
* @param nodes The ipv4 closest nodes.
* @param nodes6 The ipv6 closest nodes.
* @param values The values to send.
*/
void tellListener(std::shared_ptr<Node> n, uint16_t rid, const InfoHash& hash, want_t want, const Blob& ntoken,
std::vector<std::shared_ptr<Node>>&& nodes, std::vector<std::shared_ptr<Node>>&& nodes6,
std::vector<std::shared_ptr<Value>>&& values, const Query& q);
void tellListener(Sp<Node> n, uint32_t socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
std::vector<Sp<Node>>&& nodes, std::vector<Sp<Node>>&& nodes6,
std::vector<Sp<Value>>&& values, const Query& q);
bool isRunning(sa_family_t af) const;
inline want_t want () const { return dht_socket >= 0 && dht_socket6 >= 0 ? (WANT4 | WANT6) : -1; }
/**
* Cancel a request. Setting req->cancelled = true is not enough in the case
* a request is "persistent".
*/
void cancelRequest(Sp<Request>& req);
void connectivityChanged(sa_family_t);
/**************
* Requests *
**************/
std::shared_ptr<Request>
sendPing(std::shared_ptr<Node> n, RequestCb on_done, RequestExpiredCb on_expired);
std::shared_ptr<Request>
sendPing(const sockaddr* sa, socklen_t salen, RequestCb on_done, RequestExpiredCb on_expired) {
return sendPing(std::make_shared<Node>(zeroes, sa, salen), on_done, on_expired);
/**
* Send a "ping" request to a given node.
*
* @param n The node.
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request>
sendPing(Sp<Node> n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
/**
* Send a "ping" request to a given node.
*
* @param sa The node's ip sockaddr info.
* @param salen The associated sockaddr struct length.
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request>
sendPing(const sockaddr* sa, socklen_t salen, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
return sendPing(std::make_shared<Node>(zeroes, sa, salen),
std::forward<RequestCb>(on_done),
std::forward<RequestExpiredCb>(on_expired));
}
std::shared_ptr<Request>
sendFindNode(std::shared_ptr<Node> n,
const InfoHash& target,
want_t want,
RequestCb on_done,
RequestExpiredCb on_expired);
std::shared_ptr<Request>
sendGetValues(std::shared_ptr<Node> n,
const InfoHash& info_hash,
const Query& query,
want_t want,
RequestCb on_done,
RequestExpiredCb on_expired);
std::shared_ptr<Request>
sendListen(std::shared_ptr<Node> n,
const InfoHash& infohash,
const Query& query,
const Blob& token,
RequestCb on_done,
RequestExpiredCb on_expired);
std::shared_ptr<Request>
sendAnnounceValue(std::shared_ptr<Node> n,
const InfoHash& infohash,
const std::shared_ptr<Value>& v,
time_point created,
const Blob& token,
RequestCb on_done,
RequestExpiredCb on_expired);
std::shared_ptr<Request>
sendRefreshValue(std::shared_ptr<Node> n,
const InfoHash& infohash,
const Value::Id& vid,
const Blob& token,
RequestCb on_done,
RequestExpiredCb on_expired);
/**
* Send a "find node" request to a given node.
*
* @param n The node.
* @param target The target hash.
* @param want Indicating wether IPv4 or IPv6 are wanted in response.
* Use NetworkEngine::want()
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendFindNode(Sp<Node> n,
const InfoHash& hash,
want_t want,
RequestCb&& on_done,
RequestExpiredCb&& on_expired);
/**
* Send a "get" request to a given node.
*
* @param n The node.
* @param hash The target hash.
* @param query The query describing filters.
* @param token A security token.
* @param want Indicating wether IPv4 or IPv6 are wanted in response.
* Use NetworkEngine::want()
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendGetValues(Sp<Node> n,
const InfoHash& hash,
const Query& query,
want_t want,
RequestCb&& on_done,
RequestExpiredCb&& on_expired);
/**
* Send a "listen" request to a given node.
*
* @param n The node.
* @param hash The storage's hash.
* @param query The query describing filters.
* @param token A security token.
* @param previous The previous request "listen" sent to this node.
* @param socket **UNUSED** The socket for further response.
*
* For backward compatibility purpose, sendListen has to
* handle creation of the socket. Therefor, you cannot
* use openSocket yourself. TODO: Once we don't support
* the old "listen" negociation, sendListen shall not
* create the socket itself.
*
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
* @param socket_cb Callback to execute each time new updates arrive on
* the socket.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendListen(Sp<Node> n,
const InfoHash& hash,
const Query& query,
const Blob& token,
Sp<Request> previous,
RequestCb&& on_done,
RequestExpiredCb&& on_expired,
SocketCb&& socket_cb);
/**
* Send a "announce" request to a given node.
*
* @param n The node.
* @param hash The target hash.
* @param created The time when the value was created (avoiding extended
* value lifetime)
* @param token A security token.
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendAnnounceValue(Sp<Node> n,
const InfoHash& hash,
const Sp<Value>& v,
time_point created,
const Blob& token,
RequestCb&& on_done,
RequestExpiredCb&& on_expired);
/**
* Send a "refresh" request to a given node. Asks a node to keep the
* associated value Value.type.expiration more minutes in its storage.
*
* @param n The node.
* @param hash The target hash.
* @param vid The value id.
* @param token A security token.
* @param on_done Request callback when the request is completed.
* @param on_expired Request callback when the request expires.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendRefreshValue(Sp<Node> n,
const InfoHash& hash,
const Value::Id& vid,
const Blob& token,
RequestCb&& on_done,
RequestExpiredCb&& on_expired);
/**
* Opens a socket on which a node will be able allowed to write for further
* additionnal updates following the response to a previous request.
*
* @param node The node which will be allowed to write on this socket.
* @param cb The callback to execute once updates arrive on the socket.
*
* @return the socket.
*/
Sp<Socket> openSocket(const Sp<Node>& node, TransPrefix tp, SocketCb&& cb);
/**
* Closes a socket so that no further data will be red on that socket.
*
* @param socket The socket to close.
*/
void closeSocket(Sp<Socket> socket);
/**
* Parses a message and calls appropriate callbacks.
@@ -366,7 +421,7 @@ public:
*/
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr& addr);
std::shared_ptr<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
Sp<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
auto n = cache.getNode(myid, addr, scheduler.time(), 0);
onNewNode(n, 0);
return n;
@@ -379,9 +434,9 @@ public:
return stats;
}
void blacklistNode(const std::shared_ptr<Node>& n);
void blacklistNode(const Sp<Node>& n);
std::vector<std::shared_ptr<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count) {
std::vector<Sp<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count) {
return cache.getCachedNodes(id, sa_f, count);
}
@@ -394,9 +449,9 @@ private:
***************/
static constexpr long unsigned MAX_REQUESTS_PER_SEC {1600};
/* the length of a node info buffer in ipv4 format */
static const constexpr size_t NODE4_INFO_BUF_LEN {26};
static const constexpr size_t NODE4_INFO_BUF_LEN {HASH_LEN + sizeof(in_addr) + sizeof(in_port_t)};
/* the length of a node info buffer in ipv6 format */
static const constexpr size_t NODE6_INFO_BUF_LEN {38};
static const constexpr size_t NODE6_INFO_BUF_LEN {HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t)};
/* after a UDP reply, the period during which we tell the link layer about it */
static constexpr std::chrono::seconds UDP_REPLY_TIME {15};
@@ -421,13 +476,13 @@ private:
static bool isMartian(const SockAddr& addr);
bool isNodeBlacklisted(const SockAddr& addr) const;
void requestStep(std::shared_ptr<Request> req);
void requestStep(Sp<Request> req);
/**
* Sends a request to a node. Request::MAX_ATTEMPT_COUNT attempts will
* be made before the request expires.
*/
void sendRequest(std::shared_ptr<Request>& request);
void sendRequest(Sp<Request>& request);
/**
* Generates a new request id, skipping the invalid id.
@@ -440,20 +495,20 @@ private:
}
struct MessageStats {
unsigned ping {0};
unsigned find {0};
unsigned get {0};
unsigned put {0};
unsigned listen {0};
unsigned ping {0};
unsigned find {0};
unsigned get {0};
unsigned put {0};
unsigned listen {0};
unsigned refresh {0};
};
// basic wrapper for socket sendto function
int send(const char *buf, size_t len, int flags, const SockAddr& addr);
void send(const char *buf, size_t len, int flags, const SockAddr& addr);
void sendValueParts(TransId tid, const std::vector<Blob>& svals, const SockAddr& addr);
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<std::shared_ptr<Value>>&);
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
void maintainRxBuffer(const TransId& tid);
/*************
@@ -466,16 +521,16 @@ private:
TransId tid,
const Blob& nodes,
const Blob& nodes6,
const std::vector<std::shared_ptr<Value>>& st,
const std::vector<Sp<Value>>& st,
const Query& query,
const Blob& token);
Blob bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes);
Blob bufferNodes(sa_family_t af, const InfoHash& id, std::vector<Sp<Node>>& nodes);
std::pair<Blob, Blob> bufferNodes(sa_family_t af,
const InfoHash& id,
want_t want,
std::vector<std::shared_ptr<Node>>& nodes,
std::vector<std::shared_ptr<Node>>& nodes6);
std::vector<Sp<Node>>& nodes,
std::vector<Sp<Node>>& nodes6);
/* answer to a listen request */
void sendListenConfirmation(const SockAddr& addr, TransId tid);
/* answer to put request */
@@ -487,7 +542,7 @@ private:
const std::string& message,
bool include_id=false);
void deserializeNodes(ParsedMessage& msg);
void deserializeNodes(ParsedMessage& msg, const SockAddr& from);
/* DHT info */
const InfoHash& myid;
@@ -528,18 +583,21 @@ private:
};
// global limiting should be triggered by at least 8 different IPs
using IpLimiter = RateLimiter<MAX_REQUESTS_PER_SEC/8>;
using IpLimiterMap = std::map<SockAddr, IpLimiter, cmpSockAddr>;
using IpLimiterMap = std::map<SockAddr, IpLimiter, SockAddr::ipCmp>;
IpLimiterMap address_rate_limiter {};
RateLimiter<MAX_REQUESTS_PER_SEC> rate_limiter {};
// requests handling
uint16_t transaction_id {1};
std::map<uint16_t, std::shared_ptr<Request>> requests {};
std::map<TransId, Sp<Request>> requests {};
std::map<TransId, PartialMessage> partial_messages;
std::map<TransId, Sp<Socket>> opened_sockets {};
MessageStats in_stats {}, out_stats {};
std::set<SockAddr> blacklist {};
Scheduler& scheduler;
};
}
} /* namespace net */
} /* namespace dht */
+10 -9
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -28,7 +27,9 @@
namespace dht {
namespace net {
struct Request;
} /* namespace net */
struct Node {
InfoHash id;
@@ -72,8 +73,8 @@ struct Node {
void update(const SockAddr&);
void requested(std::shared_ptr<Request>& req);
void received(time_point now, std::shared_ptr<Request> req);
void requested(std::shared_ptr<net::Request>& req);
void received(time_point now, std::shared_ptr<net::Request> req);
void setExpired();
@@ -84,7 +85,7 @@ struct Node {
std::string toString() const;
friend std::ostream& operator<< (std::ostream& s, const Node& h);
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Node& h);
static constexpr const std::chrono::minutes NODE_GOOD_TIME {120};
@@ -98,12 +99,12 @@ private:
/* Number of times we accept authentication errors from this node. */
static const constexpr unsigned MAX_AUTH_ERRORS {3};
std::list<std::weak_ptr<Request>> requests_ {};
std::list<std::weak_ptr<net::Request>> requests_ {};
unsigned auth_errors {0};
bool expired_ {false};
void clearPendingQueue() {
requests_.remove_if([](std::weak_ptr<Request>& w) {
requests_.remove_if([](std::weak_ptr<net::Request>& w) {
return w.expired();
});
}
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
+1 -1
View File
@@ -13,7 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
+44 -18
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2016 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,15 +14,40 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "net.h"
namespace dht {
namespace net {
class NetworkEngine;
struct ParsedMessage;
/*!
* @class Socket
* @brief Open route to a node for continous incoming packets.
* @details
* A socket lets a remote node send us continuous packets treated using a
* given callback. This is intended to provide an easy management of
* specific updates nodes can send. For e.g, this is used in the case of the
* "listen" operation for treating updates a node has for a given storage.
*/
struct Socket {
Socket() {}
Socket(std::shared_ptr<Node> node,
TransId id,
std::function<void(const std::shared_ptr<Node>&, ParsedMessage&&)> on_receive) :
node(node), id(id), on_receive(on_receive) {}
std::shared_ptr<Node> node;
TransId id;
std::function<void(const std::shared_ptr<Node>&, ParsedMessage&&)> on_receive {};
};
/*!
* @class Request
* @brief An atomic request destined to a node.
@@ -32,7 +57,8 @@ struct ParsedMessage;
* request is done.
*/
struct Request {
friend class dht::NetworkEngine;
friend class dht::net::NetworkEngine;
std::shared_ptr<Node> node {}; /* the node to whom the request is destined. */
time_point reply_time {time_point::min()}; /* time when we received the response to the request. */
@@ -51,14 +77,14 @@ struct Request {
bool over() const { return not pending(); }
State getState() const { return state_; }
Request() {}
Request(uint16_t tid,
Request(State state = State::PENDING) : state_(state) {}
Request(TransId tid,
std::shared_ptr<Node> node,
Blob&& msg,
std::function<void(const Request& req_status, ParsedMessage&&)> on_done,
std::function<void(const Request& req_status, bool)> on_expired,
bool persistent = false) :
node(node), on_done(on_done), on_expired(on_expired), tid(tid), msg(std::move(msg)), persistent(persistent) { }
std::function<void(const Request&, ParsedMessage&&)> on_done,
std::function<void(const Request&, bool)> on_expired,
std::shared_ptr<Socket> socket = {}) :
node(node), on_done(on_done), on_expired(on_expired), tid(tid), msg(std::move(msg)), socket(socket) { }
void setExpired() {
if (pending()) {
@@ -68,11 +94,10 @@ struct Request {
}
}
void setDone(ParsedMessage&& msg) {
if (pending() or persistent) {
if (pending()) {
state_ = Request::State::COMPLETED;
on_done(*this, std::forward<ParsedMessage>(msg));
if (not persistent)
clear();
clear();
}
}
@@ -102,12 +127,13 @@ private:
time_point start {time_point::min()}; /* time when the request is created. */
time_point last_try {time_point::min()}; /* time of the last attempt to process the request. */
std::function<void(const Request& req_status, ParsedMessage&&)> on_done {};
std::function<void(const Request& req_status, bool)> on_expired {};
std::function<void(const Request&, ParsedMessage&&)> on_done {};
std::function<void(const Request&, bool)> on_expired {};
const uint16_t tid {0}; /* the request id. */
Blob msg {}; /* the serialized message. */
const bool persistent {false}; /* the request is not erased upon completion. */
const TransId tid; /* the request id. */
Blob msg {}; /* the serialized message. */
std::shared_ptr<Socket> socket; /* the socket used for further reponses. */
};
} /* namespace net */
}
+14 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,13 +13,14 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <random>
#include <algorithm>
#include <functional>
namespace dht {
namespace crypto {
@@ -107,4 +108,14 @@ using random_device = std::random_device;
using random_device = std::random_device;
#endif
template<class T = std::mt19937, std::size_t N = T::state_size>
auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
typename T::result_type random_data[N];
random_device source;
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
T seededEngine (seeds);
return seededEngine;
}
}} // dht::crypto
+8 -8
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -31,12 +31,12 @@ struct Bucket {
: af(af), first(f), time(t), cached() {}
sa_family_t af {0};
InfoHash first {};
time_point time {time_point::min()}; /* time of last reply in this bucket */
std::list<std::shared_ptr<Node>> nodes {};
std::shared_ptr<Node> cached; /* the address of a likely candidate */
time_point time {time_point::min()}; /* time of last reply in this bucket */
std::list<Sp<Node>> nodes {};
Sp<Node> cached; /* the address of a likely candidate */
/** Return a random node in a bucket. */
std::shared_ptr<Node> randomNode();
Sp<Node> randomNode();
};
class RoutingTable : public std::list<Bucket> {
@@ -45,7 +45,7 @@ public:
InfoHash middle(const RoutingTable::const_iterator&) const;
std::vector<std::shared_ptr<Node>> findClosestNodes(const InfoHash id, time_point now, size_t count = TARGET_NODES) const;
std::vector<Sp<Node>> findClosestNodes(const InfoHash id, time_point now, size_t count = TARGET_NODES) const;
RoutingTable::iterator findBucket(const InfoHash& id);
RoutingTable::const_iterator findBucket(const InfoHash& id) const;
+6 -7
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -52,7 +51,7 @@ public:
*
* @return pointer to the newly scheduled job.
*/
std::shared_ptr<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
Sp<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
auto job = std::make_shared<Job>(std::move(job_func));
if (t != time_point::max())
timers.emplace(std::move(t), job);
@@ -67,7 +66,7 @@ public:
*
* @return pointer to the newly scheduled job.
*/
void edit(std::shared_ptr<Scheduler::Job>& job, time_point t) {
void edit(Sp<Scheduler::Job>& job, time_point t) {
if (not job) {
DHT_LOG.ERR("editing an empty job");
return;
@@ -118,7 +117,7 @@ public:
private:
time_point now {clock::now()};
std::multimap<time_point, std::shared_ptr<Job>> timers {}; /* the jobs ordered by time */
std::multimap<time_point, Sp<Job>> timers {}; /* the jobs ordered by time */
const Logger& DHT_LOG;
};
+22 -30
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,19 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -40,7 +29,7 @@
namespace dht {
class SecureDht : public Dht {
class OPENDHT_PUBLIC SecureDht : public Dht {
public:
typedef std::function<void(bool)> SignatureCheckCallback;
@@ -62,6 +51,9 @@ public:
InfoHash getId() const {
return key_ ? key_->getPublicKey().getId() : InfoHash();
}
PkId getLongId() const {
return key_ ? key_->getPublicKey().getLongId() : PkId();
}
ValueType secureType(ValueType&& type);
@@ -101,7 +93,7 @@ public:
/**
* Will take ownership of the value, sign it using our private key and put it in the DHT.
*/
void putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
void putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, bool permanent = false);
void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback, bool permanent = false) {
putSigned(hash, std::make_shared<Value>(std::move(v)), callback, permanent);
}
@@ -111,7 +103,7 @@ public:
* and put it in the DHT.
* The operation will be immediate if the recipient' public key is known (otherwise it will be retrived first).
*/
void putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
void putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
@@ -125,14 +117,14 @@ public:
Value decrypt(const Value& v);
void findCertificate(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::Certificate>)> cb);
void findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<const crypto::PublicKey>)> cb);
void findCertificate(const InfoHash& node, std::function<void(const Sp<crypto::Certificate>)> cb);
void findPublicKey(const InfoHash& node, std::function<void(const Sp<const crypto::PublicKey>)> cb);
const std::shared_ptr<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(std::shared_ptr<crypto::Certificate>& cert);
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(Sp<crypto::Certificate>& cert);
const std::shared_ptr<crypto::Certificate> getCertificate(const InfoHash& node) const;
const std::shared_ptr<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
const Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
const Sp<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
/**
* Allows to set a custom callback called by the library to find a locally-stored certificate.
@@ -150,23 +142,23 @@ private:
GetCallback getCallbackFilter(GetCallback, Value::Filter&&);
std::shared_ptr<crypto::PrivateKey> key_ {};
std::shared_ptr<crypto::Certificate> certificate_ {};
Sp<crypto::PrivateKey> key_ {};
Sp<crypto::Certificate> certificate_ {};
// method to query the local certificate store
CertificateStoreQuery localQueryMethod_ {};
// our certificate cache
std::map<InfoHash, std::shared_ptr<crypto::Certificate>> nodesCertificates_ {};
std::map<InfoHash, std::shared_ptr<const crypto::PublicKey>> nodesPubKeys_ {};
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
std::map<InfoHash, Sp<const crypto::PublicKey>> nodesPubKeys_ {};
std::uniform_int_distribution<Value::Id> rand_id {};
};
const ValueType CERTIFICATE_TYPE = {
8, "Certificate", std::chrono::hours(24 * 7),
// A certificate can only be stored at it's public key ID.
[](InfoHash id, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t) {
// A certificate can only be stored at its public key ID.
[](InfoHash id, Sp<Value>& v, InfoHash, const sockaddr*, socklen_t) {
try {
crypto::Certificate crt(v->data);
// TODO check certificate signature
@@ -174,7 +166,7 @@ const ValueType CERTIFICATE_TYPE = {
} catch (const std::exception& e) {}
return false;
},
[](InfoHash, const std::shared_ptr<Value>& o, std::shared_ptr<Value>& n, InfoHash, const sockaddr*, socklen_t) {
[](InfoHash, const Sp<Value>& o, Sp<Value>& n, InfoHash, const sockaddr*, socklen_t) {
try {
return crypto::Certificate(o->data).getPublicKey().getId() == crypto::Certificate(n->data).getPublicKey().getId();
} catch (const std::exception& e) {}
+99 -6
View File
@@ -13,13 +13,19 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "def.h"
#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __ANDROID__
typedef uint16_t in_port_t;
#endif
#else
#include <iso646.h>
#include <ws2def.h>
@@ -30,10 +36,10 @@ typedef uint16_t in_port_t;
namespace dht {
std::string print_addr(const sockaddr* sa, socklen_t slen);
std::string print_addr(const sockaddr_storage& ss, socklen_t sslen);
OPENDHT_PUBLIC std::string print_addr(const sockaddr* sa, socklen_t slen);
OPENDHT_PUBLIC std::string print_addr(const sockaddr_storage& ss, socklen_t sslen);
struct SockAddr : public std::pair<sockaddr_storage, socklen_t> {
struct OPENDHT_PUBLIC SockAddr : public std::pair<sockaddr_storage, socklen_t> {
public:
SockAddr() : pair<sockaddr_storage, socklen_t>::pair({},0) {}
SockAddr(const SockAddr& o) : pair<sockaddr_storage, socklen_t>::pair({},o.second) {
@@ -66,10 +72,97 @@ public:
return print_addr(first, second);
}
sa_family_t getFamily() const { return second > sizeof(sa_family_t) ? first.ss_family : AF_UNSPEC; }
void setFamily(sa_family_t af) {
first.ss_family = af;
switch(af) {
case AF_INET:
second = sizeof(sockaddr_in);
break;
case AF_INET6:
second = sizeof(sockaddr_in6);
break;
}
}
in_port_t getPort() const {
switch(getFamily()) {
case AF_INET:
return ntohs(getIPv4().sin_port);
case AF_INET6:
return ntohs(getIPv6().sin6_port);
default:
return 0;
}
}
void setPort(in_port_t p) {
switch(getFamily()) {
case AF_INET:
getIPv4().sin_port = htons(p);
break;
case AF_INET6:
getIPv6().sin6_port = htons(p);
break;
}
}
const sockaddr_in& getIPv4() const {
return *reinterpret_cast<const sockaddr_in*>(&first);
}
const sockaddr_in6& getIPv6() const {
return *reinterpret_cast<const sockaddr_in6*>(&first);
}
sockaddr_in& getIPv4() {
return *reinterpret_cast<sockaddr_in*>(&first);
}
sockaddr_in6& getIPv6() {
return *reinterpret_cast<sockaddr_in6*>(&first);
}
/**
* Return true if address is a loopback IP address.
*/
bool isLoopback() const;
/**
* Return true if address is not a public IP address.
*/
bool isPrivate() const;
bool isUnspecified() const;
/**
* A comparator to classify IP addresses, only considering the
* first 64 bits in IPv6.
*/
struct ipCmp {
bool operator()(const SockAddr& a, const SockAddr& b) const {
if (a.second != b.second)
return a.second < b.second;
socklen_t start, len;
switch(a.getFamily()) {
case AF_INET:
start = offsetof(sockaddr_in, sin_addr);
len = sizeof(in_addr);
break;
case AF_INET6:
start = offsetof(sockaddr_in6, sin6_addr);
// don't consider more than 64 bits (IPv6)
len = 8;
break;
default:
start = 0;
len = a.second;
break;
}
return std::memcmp((uint8_t*)&a.first+start, (uint8_t*)&b.first+start, len) < 0;
}
};
};
bool operator==(const SockAddr& a, const SockAddr& b);
OPENDHT_PUBLIC bool operator==(const SockAddr& a, const SockAddr& b);
std::string printAddr(const SockAddr& addr);
OPENDHT_PUBLIC std::string printAddr(const SockAddr& addr);
}
+12 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,13 +13,12 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#define WANT4 1
#define WANT6 2
#include "def.h"
#include <msgpack.hpp>
@@ -30,11 +29,18 @@
#include <cstdarg>
#define WANT4 1
#define WANT6 2
namespace dht {
using NetId = uint32_t;
using want_t = int_fast8_t;
// shortcut for std::shared_ptr
template<class T>
using Sp = std::shared_ptr<T>;
template <typename Key, typename Item, typename Condition>
void erase_if(std::map<Key, Item>& map, const Condition& condition)
{
@@ -45,13 +51,12 @@ void erase_if(std::map<Key, Item>& map, const Condition& condition)
}
}
class DhtException : public std::runtime_error {
class OPENDHT_PUBLIC DhtException : public std::runtime_error {
public:
DhtException(const std::string &str = "") :
std::runtime_error("DhtException occurred: " + str) {}
};
// Time related definitions and utility functions
using clock = std::chrono::steady_clock;
@@ -70,9 +75,6 @@ print_dt(DT d) {
return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
}
static /*constexpr*/ const time_point TIME_INVALID = {time_point::min()};
static /*constexpr*/ const time_point TIME_MAX {time_point::max()};
template <typename Duration = duration>
class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> {
using Base = std::uniform_int_distribution<typename Duration::rep>;
@@ -96,7 +98,7 @@ using Blob = std::vector<uint8_t>;
/**
* Provides backward compatibility with msgpack 1.0
*/
Blob unpackBlob(msgpack::object& o);
OPENDHT_PUBLIC Blob unpackBlob(msgpack::object& o);
template <typename Type>
Blob
+19 -47
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
@@ -72,7 +71,7 @@ using EditPolicy = std::function<bool(InfoHash key, const std::shared_ptr<Value>
static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
struct ValueType {
struct OPENDHT_PUBLIC ValueType {
typedef uint16_t Id;
static bool DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr*, socklen_t);
@@ -114,7 +113,7 @@ struct ValueType {
* Values are stored at a given InfoHash in the Dht, but also have a
* unique ID to distinguish between values stored at the same location.
*/
struct Value
struct OPENDHT_PUBLIC Value
{
enum class Field : int {
None = 0,
@@ -409,7 +408,7 @@ struct Value
}
/** print value for debugging */
friend std::ostream& operator<< (std::ostream& s, const Value& v);
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Value& v);
std::string toString() const {
std::stringstream ss;
@@ -553,7 +552,7 @@ using ValuesExport = std::pair<InfoHash, Blob>;
* This structure holds the value for a specified field. It's type can either be
* uint64_t, InfoHash or Blob.
*/
struct FieldValue
struct OPENDHT_PUBLIC FieldValue
{
FieldValue() {}
FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
@@ -630,30 +629,6 @@ private:
Blob blobValue {};
};
/**
* @struct FieldSelectorDescription
* @brief Describes a selection.
* @details
* This is meant to narrow data to a set of specified fields. This structure is
* used to construct a Select structure.
*/
struct FieldSelectorDescription
{
FieldSelectorDescription() {}
FieldSelectorDescription(Value::Field f) : field(f) {}
Value::Field getField() const { return field; }
bool operator==(const FieldSelectorDescription& fd) const { return field == fd.field; }
template <typename Packer>
void msgpack_pack(Packer& p) const { p.pack(static_cast<uint8_t>(field)); }
void msgpack_unpack(msgpack::object msg) { field = static_cast<Value::Field>(msg.as<int>()); }
private:
Value::Field field {Value::Field::None};
};
/**
* @class Select
* @brief Serializable Value field selection.
@@ -661,7 +636,7 @@ private:
* This is a container for a list of FieldSelectorDescription instances. It
* describes a complete SELECT query for dht::Value.
*/
struct Select
struct OPENDHT_PUBLIC Select
{
Select() { }
Select(const std::string& q_str);
@@ -686,23 +661,18 @@ struct Select
* @return the set of fields.
*/
std::set<Value::Field> getSelection() const {
std::set<Value::Field> fields {};
for (const auto& f : fieldSelection_) {
fields.insert(f.getField());
}
return fields;
return {fieldSelection_.begin(), fieldSelection_.end()};
}
template <typename Packer>
void msgpack_pack(Packer& pk) const { pk.pack(fieldSelection_); }
void msgpack_unpack(const msgpack::object& o) {
fieldSelection_.clear();
fieldSelection_ = o.as<decltype(fieldSelection_)>();
}
friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
private:
std::vector<FieldSelectorDescription> fieldSelection_ {};
std::vector<Value::Field> fieldSelection_ {};
};
/**
@@ -712,7 +682,7 @@ private:
* This is container for a list of FieldValue instances. It describes a
* complete WHERE query for dht::Value.
*/
struct Where
struct OPENDHT_PUBLIC Where
{
Where() { }
Where(const std::string& q_str);
@@ -802,7 +772,7 @@ struct Where
filters_ = o.as<decltype(filters_)>();
}
friend std::ostream& operator<<(std::ostream& s, const dht::Where& q);
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Where& q);
private:
std::vector<FieldValue> filters_;
@@ -816,7 +786,7 @@ private:
* itselves to include in the peer response to a GET operation. See
* FieldValue.
*/
struct Query
struct OPENDHT_PUBLIC Query
{
static const std::string QUERY_PARSE_ERROR;
@@ -864,7 +834,7 @@ struct Query
return ss.str();
}
friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
return s << "Query[" << q.select << " " << q.where << "]";
}
@@ -880,7 +850,7 @@ struct Query
* This structures is meant to manipulate a subset of fields normally contained
* in Value.
*/
struct FieldValueIndex {
struct OPENDHT_PUBLIC FieldValueIndex {
FieldValueIndex() {}
FieldValueIndex(const Value& v, Select s = {});
/**
@@ -891,7 +861,7 @@ struct FieldValueIndex {
*/
bool containedIn(const FieldValueIndex& other) const;
friend std::ostream& operator<<(std::ostream& os, const FieldValueIndex& fvi);
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& os, const FieldValueIndex& fvi);
void msgpack_unpack_fields(const std::set<Value::Field>& fields,
const msgpack::object& o,
@@ -953,3 +923,5 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) {
}
}
MSGPACK_ADD_ENUM(dht::Value::Field)
+153 -10
View File
@@ -25,7 +25,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenDHT Python Wrapper. If not, see <http://www.gnu.org/licenses/>.
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
from libcpp.map cimport map as map
from libcpp cimport bool
@@ -125,6 +125,23 @@ cdef class InfoHash(_WithID):
h._infohash = cpp.InfoHash.getRandom()
return h
cdef class SockAddr(object):
cdef cpp.SockAddr _addr
def toString(SockAddr self):
return self._addr.toString()
def getPort(SockAddr self):
return self._addr.getPort()
def getFamily(SockAddr self):
return self._addr.getFamily()
def setPort(SockAddr self, cpp.in_port_t port):
return self._addr.setPort(port)
def setFamily(SockAddr self, cpp.sa_family_t af):
return self._addr.setFamily(af)
def __str__(self):
return self.toString().decode()
def __repr__(self):
return "<%s '%s'>" % (self.__class__.__name__, str(self))
cdef class Node(_WithID):
cdef shared_ptr[cpp.Node] _node
def getId(self):
@@ -224,19 +241,100 @@ cdef class NodeSet(object):
def __iter__(self):
return NodeSetIter(self)
cdef class PrivateKey(_WithID):
cdef shared_ptr[cpp.PrivateKey] _key
def getId(self):
h = InfoHash()
h._infohash = self._key.get().getPublicKey().getId()
return h
def getPublicKey(self):
pk = PublicKey()
pk._key = self._key.get().getPublicKey()
return pk
def decrypt(self, bytes dat):
cdef size_t d_len = len(dat)
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
cdef cpp.Blob indat
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
cdef cpp.Blob decrypted = self._key.get().decrypt(indat)
cdef char* decrypted_c_str = <char *>decrypted.data()
cdef Py_ssize_t length = decrypted.size()
return decrypted_c_str[:length]
def __str__(self):
return self.getId().toString().decode()
@staticmethod
def generate():
k = PrivateKey()
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generate())
return k
@staticmethod
def generateEC():
k = PrivateKey()
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generateEC())
return k
cdef class PublicKey(_WithID):
cdef cpp.PublicKey _key
def getId(self):
h = InfoHash()
h._infohash = self._key.getId()
return h
def encrypt(self, bytes dat):
cdef size_t d_len = len(dat)
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
cdef cpp.Blob indat
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
cdef cpp.Blob encrypted = self._key.encrypt(indat)
cdef char* encrypted_c_str = <char *>encrypted.data()
cdef Py_ssize_t length = encrypted.size()
return encrypted_c_str[:length]
cdef class Certificate(_WithID):
cdef shared_ptr[cpp.Certificate] _cert
def __init__(self, bytes dat = None):
if dat:
self._cert = cpp.make_shared[cpp.Certificate](<cpp.string>dat)
def getId(self):
h = InfoHash()
h._infohash = self._cert.get().getId()
if self._cert:
h._infohash = self._cert.get().getId()
return h
def toString(self):
return self._cert.get().toString().decode()
def getName(self):
return self._cert.get().getName()
def revoke(self, PrivateKey k, Certificate c):
self._cert.get().revoke(deref(k._key.get()), deref(c._cert.get()));
def __bytes__(self):
return self._cert.get().toString() if self._cert else b''
property issuer:
def __get__(self):
c = Certificate()
c._cert = self._cert.get().issuer
return c;
@staticmethod
def generate(PrivateKey k, str name, Identity i = Identity(), bool is_ca = False):
c = Certificate()
c._cert = cpp.make_shared[cpp.Certificate](cpp.Certificate.generate(deref(k._key.get()), name.encode(), i._id, is_ca))
return c
cdef class VerifyResult(object):
cdef cpp.TrustListVerifyResult _result
def __bool__(self):
return self._result.isValid()
def __str(self):
return self._result.toString()
cdef class TrustList(object):
cdef cpp.TrustList _trust
def add(self, Certificate cert):
self._trust.add(deref(cert._cert.get()))
def remove(self, Certificate cert):
self._trust.remove(deref(cert._cert.get()))
def verify(self, Certificate cert):
r = VerifyResult()
r._result = self._trust.verify(deref(cert._cert.get()))
return r
cdef class ListenToken(object):
cdef cpp.InfoHash _h
@@ -245,18 +343,31 @@ cdef class ListenToken(object):
cdef class Identity(object):
cdef cpp.Identity _id
def generate(self, str name = "pydht", Identity ca = Identity(), unsigned bits = 4096):
self._id = cpp.generateIdentity(name.encode(), ca._id, bits)
property PublicKey:
def __init__(self, PrivateKey k = None, Certificate c = None):
if k:
self._id.first = k._key
if c:
self._id.second = c._cert
@staticmethod
def generate(str name = "pydht", Identity ca = Identity(), unsigned bits = 4096):
i = Identity()
i._id = cpp.generateIdentity(name.encode(), ca._id, bits)
return i
property publickey:
def __get__(self):
k = PublicKey()
k._key = self._id.first.get().getPublicKey()
return k
property Certificate:
property certificate:
def __get__(self):
c = Certificate()
c._cert = self._id.second
return c
property key:
def __get__(self):
k = PrivateKey()
k._key = self._id.first
return k
cdef class DhtConfig(object):
cdef cpp.DhtRunnerConfig _config
@@ -269,6 +380,10 @@ cdef class DhtConfig(object):
self._config.dht_config.node_config.is_bootstrap = bootstrap
def setNodeId(self, InfoHash id):
self._config.dht_config.node_config.node_id = id._infohash
def setNetwork(self, unsigned netid):
self._config.dht_config.node_config.network = netid
def setMaintainStorage(self, bool maintain_storage):
self._config.dht_config.node_config.maintain_storage = maintain_storage
cdef class DhtRunner(_WithID):
cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
@@ -276,12 +391,36 @@ cdef class DhtRunner(_WithID):
self.thisptr.reset(new cpp.DhtRunner())
def getId(self):
h = InfoHash()
h._infohash = self.thisptr.get().getId()
if self.thisptr:
h._infohash = self.thisptr.get().getId()
return h
def getNodeId(self):
return self.thisptr.get().getNodeId().toString()
def bootstrap(self, str host, str port):
self.thisptr.get().bootstrap(host.encode(), port.encode())
def ping(self, SockAddr addr, done_cb=None):
if done_cb:
cb_obj = {'done':done_cb}
ref.Py_INCREF(cb_obj)
self.thisptr.get().bootstrap(addr._addr, cpp.bindDoneCbSimple(done_callback_simple, <void*>cb_obj))
else:
lock = threading.Condition()
pending = 0
ok = False
def tmp_done(ok_ret):
nonlocal pending, ok, lock
with lock:
ok = ok_ret
pending -= 1
lock.notify()
with lock:
pending += 1
self.ping(addr, done_cb=tmp_done)
while pending > 0:
lock.wait()
return ok
def bootstrap(self, str host, str port=None):
host_bytes = host.encode()
port_bytes = port.encode() if port else b'4222'
self.thisptr.get().bootstrap(<cpp.const_char*>host_bytes, <cpp.const_char*>port_bytes)
def run(self, Identity id=None, is_bootstrap=False, cpp.in_port_t port=0, str ipv4="", str ipv6="", DhtConfig config=DhtConfig()):
if id:
config.setIdentity(id)
@@ -302,9 +441,13 @@ cdef class DhtRunner(_WithID):
def disableLogging(self):
cpp.disableLogging(self.thisptr.get()[0])
def enableFileLogging(self, str path):
cpp.enableFileLogging(self.thisptr.get()[0], path)
cpp.enableFileLogging(self.thisptr.get()[0], path.encode())
def isRunning(self):
return self.thisptr.get().isRunning()
def getBound(self, cpp.sa_family_t af = 0):
s = SockAddr()
s._addr = self.thisptr.get().getBound(af)
return s
def getStorageLog(self):
return self.thisptr.get().getStorageLog().decode()
def getRoutingTablesLog(self, cpp.sa_family_t af):
+46 -3
View File
@@ -13,7 +13,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
# along with this program; If not, see <https://www.gnu.org/licenses/>.
from libc.stdint cimport *
from libcpp cimport bool
@@ -21,6 +21,7 @@ from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from libcpp.map cimport map
from libc.string cimport const_char, const_uchar
ctypedef uint16_t in_port_t
ctypedef unsigned short int sa_family_t;
@@ -31,7 +32,9 @@ cdef extern from "<memory>" namespace "std" nogil:
shared_ptr(T*) except +
T* get()
T operator*()
bool operator bool() const
void reset(T*)
shared_ptr[T] make_shared[T](...) except +
cdef extern from "<functional>" namespace "std" nogil:
cdef cppclass hash[T]:
@@ -65,6 +68,17 @@ cdef extern from "opendht/infohash.h" namespace "dht":
bool operator==(InfoHash)
bool operator<(InfoHash)
cdef extern from "opendht/sockaddr.h" namespace "dht":
cdef cppclass SockAddr:
SockAddr() except +
string toString() const
in_port_t getPort() const
void setPort(in_port_t p)
sa_family_t getFamily() const
void setFamily(sa_family_t f)
ctypedef vector[uint8_t] Blob
cdef extern from "opendht/crypto.h" namespace "dht::crypto":
ctypedef pair[shared_ptr[PrivateKey], shared_ptr[Certificate]] Identity
cdef Identity generateIdentity(string name, Identity ca, unsigned bits)
@@ -72,14 +86,39 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
cdef cppclass PrivateKey:
PrivateKey()
PublicKey getPublicKey() const
Blob decrypt(Blob data) const
@staticmethod
PrivateKey generate()
@staticmethod
PrivateKey generateEC()
cdef cppclass PublicKey:
PublicKey()
InfoHash getId() const
Blob encrypt(Blob data) const
cdef cppclass Certificate:
Certificate()
Certificate(string pem)
InfoHash getId() const
string toString() const
string getName() const
void revoke(PrivateKey key, Certificate cert)
@staticmethod
Certificate generate(PrivateKey key, string name, Identity ca, bool is_ca)
shared_ptr[Certificate] issuer
cdef cppclass TrustList:
cppclass VerifyResult:
bool operator bool() const
bool isValid() const
string toString() const
TrustList()
void add(Certificate)
void remove(Certificate)
VerifyResult verify(Certificate);
ctypedef TrustList.VerifyResult TrustListVerifyResult
cdef extern from "opendht/value.h" namespace "dht":
cdef cppclass Value:
@@ -123,7 +162,9 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
cppclass Config:
InfoHash node_id
uint32_t network
bool is_bootstrap
bool maintain_storage
cppclass SecureDhtConfig:
Config node_config
Identity id
@@ -138,12 +179,14 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
bool threaded
InfoHash getId() const
InfoHash getNodeId() const
void bootstrap(const char*, const char*)
void bootstrap(const_char*, const_char*)
void bootstrap(const SockAddr&, DoneCallbackSimple done_cb)
void run(in_port_t, Config config)
void run(const char*, const char*, const char*, Config config)
void run(const_char*, const_char*, const_char*, Config config)
void join()
void shutdown(ShutdownCallback)
bool isRunning()
SockAddr getBound(sa_family_t af) const
string getStorageLog() const
string getRoutingTablesLog(sa_family_t af) const
string getSearchesLog(sa_family_t af) const
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
# Copyright (C) 2015-2017 Savoir-faire Linux Inc.
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
@@ -18,7 +18,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenDHT Python Wrapper. If not, see <http://www.gnu.org/licenses/>.
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
#
from setuptools import setup, Extension
@@ -27,7 +27,7 @@ from Cython.Distutils import build_ext
setup(name="opendht",
version="@PACKAGE_VERSION@",
description="Python wrapper for opendht",
description="Python wrapper for OpenDHT",
url='https://github.com/savoirfairelinux/opendht',
author="Adrien Béraud, Guillaume Roguez, Simon Désaulniers",
license="GPLv3",
+53
View File
@@ -0,0 +1,53 @@
import unittest
import opendht as dht
class OpenDhtTester(unittest.TestCase):
# test that DhtRunner can be instatiated and deleted without throwing
def test_instance(self):
for i in range(10):
r = dht.DhtRunner()
r.run()
del r
# test that bootstraping works (raw address)
def test_bootstrap(self):
a = dht.DhtRunner()
a.run()
b = dht.DhtRunner()
b.run()
self.assertTrue(b.ping(a.getBound()))
def test_crypto(self):
i = dht.Identity.generate("id")
message = dht.InfoHash.getRandom().toString()
encrypted = i.publickey.encrypt(message)
decrypted = i.key.decrypt(encrypted)
self.assertTrue(message == decrypted)
def test_crypto_ec(self):
key = dht.PrivateKey.generateEC()
cert = dht.Certificate.generate(key, "CA", is_ca=True)
ca_id = dht.Identity(key, cert)
self.assertTrue(cert.getId() == key.getPublicKey().getId())
key2 = dht.PrivateKey.generateEC()
cert2 = dht.Certificate.generate(key2, "cert", ca_id)
trust = dht.TrustList()
trust.add(cert)
self.assertTrue(trust.verify(cert2))
def test_trust(self):
main_id = dht.Identity.generate("id_1")
sub_id1 = dht.Identity.generate("sid_1", main_id)
sub_id2 = dht.Identity.generate("sid_2", main_id)
main_id.certificate.revoke(main_id.key, sub_id2.certificate)
main_id2 = dht.Identity.generate("id_2")
trust = dht.TrustList()
trust.add(main_id.certificate)
self.assertTrue(trust.verify(main_id.certificate))
self.assertTrue(trust.verify(sub_id1.certificate))
self.assertFalse(trust.verify(sub_id2.certificate))
self.assertFalse(trust.verify(main_id2.certificate))
if __name__ == '__main__':
unittest.main()
+1 -1
View File
@@ -186,6 +186,7 @@ if __name__ == '__main__':
wb = WorkBench(args.ifname, args.virtual_locs, args.node_num, loss=args.loss,
delay=args.delay, disable_ipv4=args.disable_ipv4,
disable_ipv6=args.disable_ipv6)
wb.create_virtual_net()
bootstrap = wb.get_bootstrap()
bs_dht_log_enabled = False
@@ -203,7 +204,6 @@ if __name__ == '__main__':
bs_dht_log_enabled = True
bootstrap.front().enableLogging()
wb.create_virtual_net()
bootstrap.resize(1)
print("Launching", wb.node_num, "nodes (", wb.clusters, "clusters of", wb.node_per_loc, "nodes)")
+265
View File
@@ -0,0 +1,265 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
import os, sys, time, cmd
import subprocess
import signal
import argparse
import threading
import opendht as dht
class NodeCluster(object):
nodes = []
node_uid = 0
@staticmethod
def run_node(ip4, ip6, p, bootstrap=None, is_bootstrap=False, logfile=None):
print("run_node", ip4, ip6, p, bootstrap, logfile)
n = dht.DhtRunner()
n.run(ipv4=ip4 if ip4 else "", ipv6=ip6 if ip6 else "", port=p, is_bootstrap=is_bootstrap)
if logfile:
n.enableFileLogging(logfile)
if bootstrap:
n.bootstrap(bootstrap[0], bootstrap[1])
time.sleep(.01)
return ((ip4, ip6, p), n, id)
@staticmethod
def find_ip(iface):
if not iface or iface == 'any':
return ('0.0.0.0','')
if_ip4 = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
if_ip6 = netifaces.ifaddresses(iface)[netifaces.AF_INET6][0]['addr']
return (if_ip4, if_ip6)
def __init__(self, iface=None, ip4=None, ip6=None, port=4000, bootstrap=None, first_bootstrap=False, logfile=None):
NodeCluster.iface = iface
self.port = port
ips = NodeCluster.find_ip(iface)
self.logfile = logfile
self.ip4 = ip4 if ip4 else ips[0]
self.ip6 = ip6 if ip6 else ips[1]
self.bootstrap = bootstrap
if bootstrap:
self.bootstrap = (bootstrap.hostname, str(bootstrap.port) if bootstrap.port else "4222")
else:
print("Using fallback bootstrap", self.ip4, self.port)
self.bootstrap = ((self.ip4, str(self.port)))
if first_bootstrap:
print("Starting bootstrap node")
self.nodes.append(NodeCluster.run_node(self.ip4, self.ip6, self.port, self.bootstrap, is_bootstrap=True))
self.bootstrap = ((self.ip4, str(self.port)))
self.port += 1
#print(self.ip4, self.ip6, self.port)
def front(self):
if len(self.nodes) == 0:
return None
return self.nodes[0][1]
def get(self, i=None):
if not self.nodes:
return None
if i is None:
l = list(self.nodes)
random.shuffle(l)
return l[0][1]
else:
return self.nodes[i][1]
def getNodeInfoById(self, id=None):
if id:
for n in self.nodes:
if n[1].getNodeId() == id:
return n
return None
def launch_node(self):
node_logfile = (self.logfile + str(self.node_uid) + '.log') if self.logfile else None
n = NodeCluster.run_node(self.ip4, self.ip6, self.port, self.bootstrap, logfile=node_logfile)
self.nodes.append(n)
self.port += 1
self.node_uid += 1
return n
def end_node(self, id=None, shutdown=False, last_msg_stats=None):
"""
Ends a running node.
@param id: The 40 hex chars id of the node.
@type id: bytes
@return: If a node was deleted or not.
@rtype : boolean
"""
lock = threading.Condition()
def shutdown_cb():
nonlocal lock
NodeCluster.Log.log('Done.')
with lock:
lock.notify()
if not self.nodes:
return
elif id:
n = self.getNodeInfoById(id)
if n:
if shutdown:
with lock:
print('Waiting for node to shutdown... ')
n[1].shutdown(shutdown_cb)
lock.wait()
if last_msg_stats:
last_msg_stats.append(self.getMessageStats())
n[1].join()
self.nodes.remove(n)
print(id, 'deleted !')
return True
else:
return False
else:
n = self.nodes.pop()
n[1].join()
return True
def replace_node(self, id=None, shutdown=False, last_msg_stats=None):
random.shuffle(self.nodes)
deleted = self.end_node(id=id, shutdown=shutdown, last_msg_stats=last_msg_stats)
if deleted:
self.launch_node()
def resize(self, n):
n = min(n, 500)
l = len(self.nodes)
if n == l:
return
if n > l:
print("Launching", n-l, "nodes", self.ip4, self.ip6)
for i in range(l, n):
self.launch_node()
else:
print("Ending", l-n, "nodes", self.ip4, self.ip6)
#random.shuffle(self.nodes)
for i in range(n, l):
self.end_node()
def close(self):
self.resize(0)
def getMessageStats(self):
stats = np.array([0,0,0,0,0])
for n in self.nodes:
stats += np.array(n[1].getNodeMessageStats())
stats_list = [len(self.nodes)]
stats_list.extend(stats.tolist())
return stats_list
class ClusterShell(cmd.Cmd):
intro = 'Welcome to the OpenDHT node cluster control. Type help or ? to list commands.\n'
prompt = '>> '
net = None
node = None
log = False
def __init__(self, network):
super(ClusterShell, self).__init__()
self.net = network
def setNode(self, node=None, num=0):
if node == self.node:
return
if self.node:
self.node.disableLogging()
self.node = node
if self.node:
self.prompt = '('+str(num)+') >> '
if self.log:
self.node.enableLogging()
else:
self.prompt = '>> '
def do_exit(self, arg):
self.close()
return True
def do_node(self, arg):
if not arg:
setNode()
else:
nodenum = int(arg)
if nodenum > len(self.net.nodes) or nodenum < 1:
print("Invalid node number:", nodenum, " (accepted: 1-", len(self.net.nodes), ")")
else:
self.setNode(self.net.nodes[nodenum-1][1], nodenum)
def do_ll(self, arg):
if self.node:
print('Node', self.node.getNodeId().decode())
else:
print(len(self.net.nodes), 'nodes running.')
def do_ls(self, arg):
if self.node:
print(self.node.getSearchesLog(0))
else:
print('No node selected.')
def do_log(self, arg):
if self.node:
self.log = not self.log
if self.log:
self.node.enableLogging()
else:
self.node.disableLogging()
def do_EOF(self, line):
self.close()
return True
def close(self):
if self.net:
self.net.close()
self.net = None
if __name__ == '__main__':
import argparse
from urllib.parse import urlparse
net = None
try:
parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
parser.add_argument('-n', '--node-num', help='number of dht nodes to run', type=int, default=32)
parser.add_argument('-I', '--iface', help='local interface to bind', default='any')
parser.add_argument('-p', '--port', help='start of port range (port, port+node_num)', type=int, default=4000)
parser.add_argument('-b', '--bootstrap', help='bootstrap address')
parser.add_argument('-d', '--daemonize', help='daemonize process', action='store_true')
parser.add_argument('-l', '--log', help='log file prefix')
args = parser.parse_args()
if args.bootstrap:
args.bootstrap = urlparse('dht://'+args.bootstrap)
net = NodeCluster(iface=args.iface, port=args.port, bootstrap=args.bootstrap, logfile=args.log)
net.resize(args.node_num)
if args.daemonize:
import daemon, lockfile
#pidfile=lockfile.FileLock('/var/run/dhtcluster.'+str(args.port))
with daemon.DaemonContext():
while True:
time.sleep(2)
else:
ClusterShell(net).cmdloop()
except Exception as e:
traceback.print_tb(e.__traceback__)
print(type(e).__name__+':', e, file=sys.stderr)
finally:
if net:
net.resize(0)
+1
View File
@@ -11,6 +11,7 @@ import string
import time
import subprocess
import re
import traceback
import collections
from matplotlib.ticker import FuncFormatter
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
# Copyright (c) 2016 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
from twisted.web import server, resource
from twisted.internet import reactor, endpoints
from urllib.parse import urlparse
import opendht as dht
import base64, json
class DhtServer(resource.Resource):
isLeaf = True
node = dht.DhtRunner()
def __init__(self, port, bootstrap):
self.node.run(port=port)
b_url = urlparse('//'+bootstrap)
self.node.bootstrap(b_url.hostname, str(b_url.port) if b_url.port else '4222')
def render_GET(self, req):
uri = req.uri[1:]
h = dht.InfoHash(uri) if len(uri) == 40 else dht.InfoHash.get(uri.decode())
print('GET', '"'+uri.decode()+'"', h)
res = self.node.get(h)
req.setHeader(b"content-type", b"application/json")
return json.dumps({'{:x}'.format(v.id):{'base64':base64.b64encode(v.data).decode()} for v in res}).encode()
def render_POST(self, req):
uri = req.uri[1:]
data = req.args[b'data'][0] if b'data' in req.args else None
if not data and b'base64' in req.args:
data = base64.b64decode(req.args[b'base64'][0])
h = dht.InfoHash(uri) if len(uri) == 40 else dht.InfoHash.get(uri.decode())
print('POST', h, data)
req.setHeader(b"content-type", b"application/json")
if data:
self.node.put(h, dht.Value(data))
return json.dumps({'success':True}).encode()
else:
req.setResponseCode(400)
return json.dumps({'success':False, 'error':'no data parameter'}).encode()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Launch an OpenDHT node with an HTTP control interface')
parser.add_argument('-p', '--port', help='OpenDHT port to bind', type=int, default=4222)
parser.add_argument('-hp', '--http-port', help='HTTP port to bind', type=int, default=8080)
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default="bootstrap.ring.cx:4222")
args = parser.parse_args()
endpoints.serverFromString(reactor, "tcp:"+str(args.http_port)).listen(server.Site(DhtServer(args.port, args.bootstrap)))
reactor.run()
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
import time
import argparse
import time
import asyncio
from datetime import datetime
import opendht as dht
parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default='bootstrap.ring.cx')
parser.add_argument('-n', '--num-ops', help='number of concurrent operations on the DHT', type=int, default=8)
parser.add_argument('-p', '--period', help='duration between each test (seconds)', type=int, default=60)
parser.add_argument('-t', '--timeout', help='timeout for a test to complete (seconds)', type=float, default=15)
args = parser.parse_args()
node1 = dht.DhtRunner()
node1.run()
node2 = dht.DhtRunner()
node2.run()
node1.bootstrap(args.bootstrap)
node2.bootstrap(args.bootstrap)
loop = asyncio.get_event_loop()
pending_tests = {}
keys = [dht.InfoHash.getRandom() for _ in range(args.num_ops)]
def listen_cb(key, val):
global pending_tests
kstr = str(key)
if kstr in pending_tests:
if pending_tests[kstr]['v'].id == val.id:
pending_tests.pop(kstr, None)
else:
print("Expected vid", val.id, "got", pending_tests[kstr]['v'].id)
return True
def listen(key):
node1.listen(key, lambda v: loop.call_soon_threadsafe(listen_cb, key, v))
for key in keys:
listen(key)
next_test = time.time()
while True:
start = time.time()
#print(datetime.fromtimestamp(start).strftime('%Y-%m-%d %H:%M:%S'), 'Test started')
for key in keys:
val = dht.Value(str(dht.InfoHash.getRandom()).encode())
pending_tests[str(key)] = {'v':val, 'c':0}
node2.put(key, val, lambda ok, nodes: ok)
while len(pending_tests):
loop.stop()
loop.run_forever()
time.sleep(1)
if time.time()-start > args.timeout:
print('Test timeout !')
exit(1)
end = time.time()
print(datetime.fromtimestamp(end).strftime('%Y-%m-%d %H:%M:%S'),
'Test completed successfully in', end-start)
next_test += args.period
if next_test > end:
time.sleep(next_test-end)
+23 -14
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
# Copyright (c) 2015-2017 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -13,41 +13,50 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
# along with this program; If not, see <https://www.gnu.org/licenses/>.
import opendht as dht
import time
import asyncio
ping_node = dht.DhtRunner()
ping_node.run(port = 5632)
ping_node.run()
#ping_node.enableLogging()
#ping_node.bootstrap("bootstrap.ring.cx", "4222")
pong_node = dht.DhtRunner()
pong_node.run(port = 5633)
pong_node.run()
#pong_node.enableLogging()
pong_node.bootstrap("192.168.49.55", "5632");
#pong_node.bootstrap("192.168.49.55", "5632");
pong_node.ping(ping_node.getBound());
loc_ping = dht.InfoHash.get("toto99")
loc_pong = dht.InfoHash.get(str(loc_ping))
i = 0
MAX = 8192
MAX = 2048
def pong(node, h):
loop = asyncio.get_event_loop()
def done(h, ok):
print(h, "over", ok)
def ping(node, h):
global i
print("got ping", h, i)
time.sleep(0.0075)
time.sleep(0.0075)
i += 1
if i < MAX:
node.put(h, dht.Value(b"hey"), lambda ok, nodes: print("over", ok))
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
else:
loop.stop()
def pong(node, h):
print(node.getNodeId().decode(), "got ping", h, i)
loop.call_soon_threadsafe(ping, node, h);
return True
ping_node.listen(loc_ping, lambda v: pong(pong_node, loc_pong))
pong_node.listen(loc_pong, lambda v: pong(ping_node, loc_ping))
pong_node.put(loc_pong, dht.Value(b"hey"), lambda ok, nodes: print("i over", ok))
ping(pong_node, loc_ping)
while (i < MAX):
time.sleep(1)
loop.run_forever()
+5 -3
View File
@@ -18,7 +18,7 @@
import time, sys, os
from pprint import pprint
from math import cos, sin, pi
from urllib import request
import urllib3
import gzip
import asyncio
@@ -35,6 +35,8 @@ from mpl_toolkits.basemap import Basemap
import GeoIP
http = urllib3.PoolManager()
done = 0
all_nodes = NodeSet()
@@ -72,7 +74,7 @@ def check_dl(fname, url):
if os.path.isfile(fname):
return
print('downloading', url)
ghandle = gzip.GzipFile(fileobj=request.urlopen(url))
ghandle = gzip.GzipFile(fileobj=http.request('GET', url, headers={'User-Agent': 'Mozilla/5.0'}, preload_content=False))
with open(fname, 'wb') as out:
for line in ghandle:
out.write(line)
@@ -224,7 +226,7 @@ def update_plot():
del collection
collection = None
collection = ringx.add_collection(RegularPolyCollection(
fig.dpi, 6, sizes=(10,), facecolors=colors,
int(fig.dpi), 6, sizes=(10,), facecolors=colors,
offsets = xys, transOffset = ringx.transData))
node_ip4s, node_ip6s = generate_set()
+39 -9
View File
@@ -1,13 +1,9 @@
SUBDIRS = argon2
lib_LTLIBRARIES = libopendht.la
AM_CPPFLAGS = -I../include/opendht
libopendht_la_CXXFLAGS = @CXXFLAGS@
libopendht_la_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@
libopendht_la_LIBADD = ./argon2/libargon2.la
libopendht_la_SOURCES = \
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@
libopendht_la_LIBADD = @Argon2_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@
libopendht_la_SOURCES = \
dht.cpp \
node_cache.cpp \
callbacks.cpp \
@@ -21,7 +17,8 @@ libopendht_la_SOURCES = \
securedht.cpp \
dhtrunner.cpp \
default_types.cpp \
indexation/pht.cpp
indexation/pht.cpp \
log.cpp
if WIN32
libopendht_la_SOURCES += rng.cpp
@@ -29,11 +26,13 @@ endif
nobase_include_HEADERS = \
../include/opendht.h \
../include/opendht/def.h \
../include/opendht/dht.h \
../include/opendht/callbacks.h \
../include/opendht/node_cache.h \
../include/opendht/routing_table.h \
../include/opendht/network_engine.h \
../include/opendht/net.h \
../include/opendht/scheduler.h \
../include/opendht/rate_limiter.h \
../include/opendht/utils.h \
@@ -52,3 +51,34 @@ nobase_include_HEADERS = \
nobase_noinst_HEADERS = \
../include/opendht/request.h
clean-local:
rm -rf libargon2.la
######################
# ARGON2 submodule #
######################
if WITH_INCLUDED_ARGON2
noinst_LTLIBRARIES = libargon2.la
libopendht_la_DEPENDENCIES = libargon2.la
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall -I@top_builddir@/argon2/include -I@top_builddir@/argon2/src
libargon2_la_SOURCES = \
@top_builddir@/argon2/src/argon2.c \
@top_builddir@/argon2/src/core.c \
@top_builddir@/argon2/src/blake2/blake2b.c \
@top_builddir@/argon2/src/thread.c \
@top_builddir@/argon2/src/ref.c \
@top_builddir@/argon2/src/encoding.c
noinst_HEADERS = \
@top_builddir@/argon2/include/argon2.h \
@top_builddir@/argon2/src/blake2/blake2.h \
@top_builddir@/argon2/src/blake2/blake2-impl.h \
@top_builddir@/argon2/src/blake2/blamka-round-ref.h \
@top_builddir@/argon2/src/core.h \
@top_builddir@/argon2/src/encoding.h \
@top_builddir@/argon2/src/thread.h
endif
-31
View File
@@ -1,31 +0,0 @@
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
moral rights retained by the original author(s) and/or performer(s);
publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
rights protecting the extraction, dissemination, use and reuse of data in a Work;
database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
-23
View File
@@ -1,23 +0,0 @@
noinst_LTLIBRARIES = libargon2.la
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall
libargon2_la_SOURCES = \
argon2.c \
core.c \
blake2/blake2b.c \
thread.c \
encoding.c \
ref.c
noinst_HEADERS = \
argon2.h \
core.h \
blake2/blake2.h \
blake2/blake2-impl.h \
blake2/blamka-round-ref.h \
blake2/blamka-round-opt.h \
thread.h \
encoding.h \
opt.h \
ref.h
-447
View File
@@ -1,447 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "argon2.h"
#include "encoding.h"
#include "core.h"
const char *argon2_type2string(argon2_type type, int uppercase) {
switch (type) {
case Argon2_d:
return uppercase ? "Argon2d" : "argon2d";
case Argon2_i:
return uppercase ? "Argon2i" : "argon2i";
case Argon2_id:
return uppercase ? "Argon2id" : "argon2id";
}
return NULL;
}
int argon2_ctx(argon2_context *context, argon2_type type) {
/* 1. Validate all inputs */
int result = validate_inputs(context);
uint32_t memory_blocks, segment_length;
argon2_instance_t instance;
if (ARGON2_OK != result) {
return result;
}
if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
return ARGON2_INCORRECT_TYPE;
}
/* 2. Align memory size */
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
memory_blocks = context->m_cost;
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
}
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
/* Ensure that all segments have equal length */
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
instance.version = context->version;
instance.memory = NULL;
instance.passes = context->t_cost;
instance.memory_blocks = memory_blocks;
instance.segment_length = segment_length;
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
instance.lanes = context->lanes;
instance.threads = context->threads;
instance.type = type;
/* 3. Initialization: Hashing inputs, allocating memory, filling first
* blocks
*/
result = initialize(&instance, context);
if (ARGON2_OK != result) {
return result;
}
/* 4. Filling memory */
result = fill_memory_blocks(&instance);
if (ARGON2_OK != result) {
return result;
}
/* 5. Finalization */
finalize(context, &instance);
return ARGON2_OK;
}
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t saltlen,
void *hash, const size_t hashlen, char *encoded,
const size_t encodedlen, argon2_type type,
const uint32_t version){
argon2_context context;
int result;
uint8_t *out;
if (hashlen > ARGON2_MAX_OUTLEN) {
return ARGON2_OUTPUT_TOO_LONG;
}
if (hashlen < ARGON2_MIN_OUTLEN) {
return ARGON2_OUTPUT_TOO_SHORT;
}
out = malloc(hashlen);
if (!out) {
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
context.out = (uint8_t *)out;
context.outlen = (uint32_t)hashlen;
context.pwd = CONST_CAST(uint8_t *)pwd;
context.pwdlen = (uint32_t)pwdlen;
context.salt = CONST_CAST(uint8_t *)salt;
context.saltlen = (uint32_t)saltlen;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = parallelism;
context.threads = parallelism;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
context.version = version;
result = argon2_ctx(&context, type);
if (result != ARGON2_OK) {
secure_wipe_memory(out, hashlen);
free(out);
return result;
}
/* if raw hash requested, write it */
if (hash) {
memcpy(hash, out, hashlen);
}
/* if encoding requested, write it */
if (encoded && encodedlen) {
if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
secure_wipe_memory(out, hashlen); /* wipe buffers if error */
secure_wipe_memory(encoded, encodedlen);
free(out);
return ARGON2_ENCODING_FAIL;
}
}
secure_wipe_memory(out, hashlen);
free(out);
return ARGON2_OK;
}
int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, const size_t hashlen,
char *encoded, const size_t encodedlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
NULL, hashlen, encoded, encodedlen, Argon2_i,
ARGON2_VERSION_NUMBER);
}
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
}
int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, const size_t hashlen,
char *encoded, const size_t encodedlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
NULL, hashlen, encoded, encodedlen, Argon2_d,
ARGON2_VERSION_NUMBER);
}
int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
}
int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, const size_t hashlen,
char *encoded, const size_t encodedlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
NULL, hashlen, encoded, encodedlen, Argon2_id,
ARGON2_VERSION_NUMBER);
}
int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, NULL, 0, Argon2_id,
ARGON2_VERSION_NUMBER);
}
static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
size_t i;
uint8_t d = 0U;
for (i = 0U; i < len; i++) {
d |= b1[i] ^ b2[i];
}
return (int)((1 & ((d - 1) >> 8)) - 1);
}
int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
argon2_type type) {
argon2_context ctx;
uint8_t *out;
int ret;
int decode_result;
uint32_t encoded_len;
size_t encoded_len_tmp;
if(encoded == NULL) {
return ARGON2_DECODING_FAIL;
}
encoded_len_tmp = strlen(encoded);
/* max values, to be updated in decode_string */
if (UINT32_MAX < encoded_len_tmp) {
return ARGON2_DECODING_FAIL;
}
encoded_len = (uint32_t)encoded_len_tmp;
ctx.adlen = encoded_len;
ctx.saltlen = encoded_len;
ctx.outlen = encoded_len;
ctx.allocate_cbk = NULL;
ctx.free_cbk = NULL;
ctx.secret = NULL;
ctx.secretlen = 0;
ctx.pwdlen = 0;
ctx.pwd = NULL;
ctx.ad = malloc(ctx.adlen);
ctx.salt = malloc(ctx.saltlen);
ctx.out = malloc(ctx.outlen);
if (!ctx.out || !ctx.salt || !ctx.ad) {
free(ctx.ad);
free(ctx.salt);
free(ctx.out);
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
out = malloc(ctx.outlen);
if (!out) {
free(ctx.ad);
free(ctx.salt);
free(ctx.out);
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
decode_result = decode_string(&ctx, encoded, type);
if (decode_result != ARGON2_OK) {
free(ctx.ad);
free(ctx.salt);
free(ctx.out);
free(out);
return decode_result;
}
ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen,
ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type,
ctx.version);
free(ctx.ad);
free(ctx.salt);
if (ret == ARGON2_OK && argon2_compare(out, ctx.out, ctx.outlen)) {
ret = ARGON2_VERIFY_MISMATCH;
}
free(out);
free(ctx.out);
return ret;
}
int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
}
int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
}
int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
}
int argon2d_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_d);
}
int argon2i_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_i);
}
int argon2id_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_id);
}
int argon2_verify_ctx(argon2_context *context, const char *hash,
argon2_type type) {
int result;
if (0 == context->outlen || NULL == hash) {
return ARGON2_OUT_PTR_MISMATCH;
}
result = argon2_ctx(context, type);
if (ARGON2_OK != result) {
return result;
}
return 0 == memcmp(hash, context->out, context->outlen);
}
int argon2d_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_d);
}
int argon2i_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_i);
}
int argon2id_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_id);
}
const char *argon2_error_message(int error_code) {
switch (error_code) {
case ARGON2_OK:
return "OK";
case ARGON2_OUTPUT_PTR_NULL:
return "Output pointer is NULL";
case ARGON2_OUTPUT_TOO_SHORT:
return "Output is too short";
case ARGON2_OUTPUT_TOO_LONG:
return "Output is too long";
case ARGON2_PWD_TOO_SHORT:
return "Password is too short";
case ARGON2_PWD_TOO_LONG:
return "Password is too long";
case ARGON2_SALT_TOO_SHORT:
return "Salt is too short";
case ARGON2_SALT_TOO_LONG:
return "Salt is too long";
case ARGON2_AD_TOO_SHORT:
return "Associated data is too short";
case ARGON2_AD_TOO_LONG:
return "Associated data is too long";
case ARGON2_SECRET_TOO_SHORT:
return "Secret is too short";
case ARGON2_SECRET_TOO_LONG:
return "Secret is too long";
case ARGON2_TIME_TOO_SMALL:
return "Time cost is too small";
case ARGON2_TIME_TOO_LARGE:
return "Time cost is too large";
case ARGON2_MEMORY_TOO_LITTLE:
return "Memory cost is too small";
case ARGON2_MEMORY_TOO_MUCH:
return "Memory cost is too large";
case ARGON2_LANES_TOO_FEW:
return "Too few lanes";
case ARGON2_LANES_TOO_MANY:
return "Too many lanes";
case ARGON2_PWD_PTR_MISMATCH:
return "Password pointer is NULL, but password length is not 0";
case ARGON2_SALT_PTR_MISMATCH:
return "Salt pointer is NULL, but salt length is not 0";
case ARGON2_SECRET_PTR_MISMATCH:
return "Secret pointer is NULL, but secret length is not 0";
case ARGON2_AD_PTR_MISMATCH:
return "Associated data pointer is NULL, but ad length is not 0";
case ARGON2_MEMORY_ALLOCATION_ERROR:
return "Memory allocation error";
case ARGON2_FREE_MEMORY_CBK_NULL:
return "The free memory callback is NULL";
case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
return "The allocate memory callback is NULL";
case ARGON2_INCORRECT_PARAMETER:
return "Argon2_Context context is NULL";
case ARGON2_INCORRECT_TYPE:
return "There is no such version of Argon2";
case ARGON2_OUT_PTR_MISMATCH:
return "Output pointer mismatch";
case ARGON2_THREADS_TOO_FEW:
return "Not enough threads";
case ARGON2_THREADS_TOO_MANY:
return "Too many threads";
case ARGON2_MISSING_ARGS:
return "Missing arguments";
case ARGON2_ENCODING_FAIL:
return "Encoding failed";
case ARGON2_DECODING_FAIL:
return "Decoding failed";
case ARGON2_THREAD_FAIL:
return "Threading failure";
case ARGON2_DECODING_LENGTH_FAIL:
return "Some of encoded parameters are too long or too short";
case ARGON2_VERIFY_MISMATCH:
return "The password does not match the supplied hash";
default:
return "Unknown error code";
}
}
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
uint32_t saltlen, uint32_t hashlen, argon2_type type) {
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
}
-430
View File
@@ -1,430 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_H
#define ARGON2_H
#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Symbols visibility control */
#ifdef A2_VISCTL
#define ARGON2_PUBLIC __attribute__((visibility("default")))
#elif _MSC_VER
#define ARGON2_PUBLIC __declspec(dllexport)
#else
#define ARGON2_PUBLIC
#endif
/*
* Argon2 input parameter restrictions
*/
/* Minimum and maximum number of lanes (degree of parallelism) */
#define ARGON2_MIN_LANES UINT32_C(1)
#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
/* Minimum and maximum number of threads */
#define ARGON2_MIN_THREADS UINT32_C(1)
#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
/* Number of synchronization points between lanes per pass */
#define ARGON2_SYNC_POINTS UINT32_C(4)
/* Minimum and maximum digest size in bytes */
#define ARGON2_MIN_OUTLEN UINT32_C(4)
#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
#define ARGON2_MAX_MEMORY_BITS \
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
#define ARGON2_MAX_MEMORY \
ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
/* Minimum and maximum number of passes */
#define ARGON2_MIN_TIME UINT32_C(1)
#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
/* Minimum and maximum password length in bytes */
#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum associated data length in bytes */
#define ARGON2_MIN_AD_LENGTH UINT32_C(0)
#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum salt length in bytes */
#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum key length in bytes */
#define ARGON2_MIN_SECRET UINT32_C(0)
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)
#define ARGON2_DEFAULT_FLAGS (ARGON2_FLAG_CLEAR_MEMORY)
/* Error codes */
typedef enum Argon2_ErrorCodes {
ARGON2_OK = 0,
ARGON2_OUTPUT_PTR_NULL = -1,
ARGON2_OUTPUT_TOO_SHORT = -2,
ARGON2_OUTPUT_TOO_LONG = -3,
ARGON2_PWD_TOO_SHORT = -4,
ARGON2_PWD_TOO_LONG = -5,
ARGON2_SALT_TOO_SHORT = -6,
ARGON2_SALT_TOO_LONG = -7,
ARGON2_AD_TOO_SHORT = -8,
ARGON2_AD_TOO_LONG = -9,
ARGON2_SECRET_TOO_SHORT = -10,
ARGON2_SECRET_TOO_LONG = -11,
ARGON2_TIME_TOO_SMALL = -12,
ARGON2_TIME_TOO_LARGE = -13,
ARGON2_MEMORY_TOO_LITTLE = -14,
ARGON2_MEMORY_TOO_MUCH = -15,
ARGON2_LANES_TOO_FEW = -16,
ARGON2_LANES_TOO_MANY = -17,
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
ARGON2_MEMORY_ALLOCATION_ERROR = -22,
ARGON2_FREE_MEMORY_CBK_NULL = -23,
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
ARGON2_INCORRECT_PARAMETER = -25,
ARGON2_INCORRECT_TYPE = -26,
ARGON2_OUT_PTR_MISMATCH = -27,
ARGON2_THREADS_TOO_FEW = -28,
ARGON2_THREADS_TOO_MANY = -29,
ARGON2_MISSING_ARGS = -30,
ARGON2_ENCODING_FAIL = -31,
ARGON2_DECODING_FAIL = -32,
ARGON2_THREAD_FAIL = -33,
ARGON2_DECODING_LENGTH_FAIL = -34,
ARGON2_VERIFY_MISMATCH = -35
} argon2_error_codes;
/* Memory allocator types --- for external allocation */
typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
/* Argon2 external data structures */
/*
*****
* Context: structure to hold Argon2 inputs:
* output array and its length,
* password and its length,
* salt and its length,
* secret and its length,
* associated data and its length,
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
* number of parallel threads that will be run.
* All the parameters above affect the output hash value.
* Additionally, two function pointers can be provided to allocate and
* deallocate the memory (if NULL, memory will be allocated internally).
* Also, three flags indicate whether to erase password, secret as soon as they
* are pre-hashed (and thus not needed anymore), and the entire memory
*****
* Simplest situation: you have output array out[8], password is stored in
* pwd[32], salt is stored in salt[16], you do not have keys nor associated
* data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
* 4 parallel lanes.
* You want to erase the password, but you're OK with last pass not being
* erased. You want to use the default memory allocator.
* Then you initialize:
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)
*/
typedef struct Argon2_Context {
uint8_t *out; /* output array */
uint32_t outlen; /* digest length */
uint8_t *pwd; /* password array */
uint32_t pwdlen; /* password length */
uint8_t *salt; /* salt array */
uint32_t saltlen; /* salt length */
uint8_t *secret; /* key array */
uint32_t secretlen; /* key length */
uint8_t *ad; /* associated data array */
uint32_t adlen; /* associated data length */
uint32_t t_cost; /* number of passes */
uint32_t m_cost; /* amount of memory requested (KB) */
uint32_t lanes; /* number of lanes */
uint32_t threads; /* maximum number of threads */
uint32_t version; /* version number */
allocate_fptr allocate_cbk; /* pointer to memory allocator */
deallocate_fptr free_cbk; /* pointer to memory deallocator */
uint32_t flags; /* array of bool options */
} argon2_context;
/* Argon2 primitive type */
typedef enum Argon2_type {
Argon2_d = 0,
Argon2_i = 1,
Argon2_id = 2
} argon2_type;
/* Version of the algorithm */
typedef enum Argon2_version {
ARGON2_VERSION_10 = 0x10,
ARGON2_VERSION_13 = 0x13,
ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
} argon2_version;
/*
* Function that gives the string representation of an argon2_type.
* @param type The argon2_type that we want the string for
* @param uppercase Whether the string should have the first letter uppercase
* @return NULL if invalid type, otherwise the string representation.
*/
ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase);
/*
* Function that performs memory-hard hashing with certain degree of parallelism
* @param context Pointer to the Argon2 internal structure
* @return Error code if smth is wrong, ARGON2_OK otherwise
*/
ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type);
/**
* Hashes a password with Argon2i, producing an encoded hash
* @param t_cost Number of iterations
* @param m_cost Sets memory usage to m_cost kibibytes
* @param parallelism Number of threads and compute lanes
* @param pwd Pointer to password
* @param pwdlen Password size in bytes
* @param salt Pointer to salt
* @param saltlen Salt size in bytes
* @param hashlen Desired length of the hash in bytes
* @param encoded Buffer where to write the encoded hash
* @param encodedlen Size of the buffer (thus max size of the encoded hash)
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
const void *pwd, const size_t pwdlen,
const void *salt, const size_t saltlen,
const size_t hashlen, char *encoded,
const size_t encodedlen);
/**
* Hashes a password with Argon2i, producing a raw hash by allocating memory at
* @hash
* @param t_cost Number of iterations
* @param m_cost Sets memory usage to m_cost kibibytes
* @param parallelism Number of threads and compute lanes
* @param pwd Pointer to password
* @param pwdlen Password size in bytes
* @param salt Pointer to salt
* @param saltlen Salt size in bytes
* @param hash Buffer where to write the raw hash - updated by the function
* @param hashlen Desired length of the hash in bytes
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen);
ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
const void *pwd, const size_t pwdlen,
const void *salt, const size_t saltlen,
const size_t hashlen, char *encoded,
const size_t encodedlen);
ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen);
ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
const void *pwd, const size_t pwdlen,
const void *salt, const size_t saltlen,
const size_t hashlen, char *encoded,
const size_t encodedlen);
ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen, char *encoded,
const size_t encodedlen, argon2_type type,
const uint32_t version);
/**
* Verifies a password against an encoded string
* Encoded string is restricted as in validate_inputs()
* @param encoded String encoding parameters, salt, hash
* @param pwd Pointer to password
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd,
const size_t pwdlen, argon2_type type);
/**
* Argon2d: Version of Argon2 that picks memory blocks depending
* on the password and salt. Only for side-channel-free
* environment!!
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
/**
* Argon2i: Version of Argon2 that picks memory blocks
* independent on the password and salt. Good for side-channels,
* but worse w.r.t. tradeoff attacks if only one pass is used.
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2i_ctx(argon2_context *context);
/**
* Argon2id: Version of Argon2 where the first half-pass over memory is
* password-independent, the rest are password-dependent (on the password and
* salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
* better with w.r.t. tradeoff attacks (similar to Argon2d).
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2id_ctx(argon2_context *context);
/**
* Verify if a given password is correct for Argon2d hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
/**
* Verify if a given password is correct for Argon2i hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash);
/**
* Verify if a given password is correct for Argon2id hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context,
const char *hash);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash,
argon2_type type);
/**
* Get the associated error message for given error code
* @return The error message associated with the given error code
*/
ARGON2_PUBLIC const char *argon2_error_message(int error_code);
/**
* Returns the encoded hash length for the given input parameters
* @param t_cost Number of iterations
* @param m_cost Memory usage in kibibytes
* @param parallelism Number of threads; used to compute lanes
* @param saltlen Salt size in bytes
* @param hashlen Hash size in bytes
* @return The encoded hash length in bytes
*/
ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
uint32_t parallelism, uint32_t saltlen,
uint32_t hashlen, argon2_type type);
#if defined(__cplusplus)
}
#endif
#endif
-156
View File
@@ -1,156 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef PORTABLE_BLAKE2_IMPL_H
#define PORTABLE_BLAKE2_IMPL_H
#include <stdint.h>
#include <string.h>
#if defined(_MSC_VER)
#define BLAKE2_INLINE __inline
#elif defined(__GNUC__) || defined(__clang__)
#define BLAKE2_INLINE __inline__
#else
#define BLAKE2_INLINE
#endif
/* Argon2 Team - Begin Code */
/*
Not an exhaustive list, but should cover the majority of modern platforms
Additionally, the code will always be correct---this is only a performance
tweak.
*/
#if (defined(__BYTE_ORDER__) && \
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
defined(_M_ARM)
#define NATIVE_LITTLE_ENDIAN
#endif
/* Argon2 Team - End Code */
static BLAKE2_INLINE uint32_t load32(const void *src) {
#if defined(NATIVE_LITTLE_ENDIAN)
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = (const uint8_t *)src;
uint32_t w = *p++;
w |= (uint32_t)(*p++) << 8;
w |= (uint32_t)(*p++) << 16;
w |= (uint32_t)(*p++) << 24;
return w;
#endif
}
static BLAKE2_INLINE uint64_t load64(const void *src) {
#if defined(NATIVE_LITTLE_ENDIAN)
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = (const uint8_t *)src;
uint64_t w = *p++;
w |= (uint64_t)(*p++) << 8;
w |= (uint64_t)(*p++) << 16;
w |= (uint64_t)(*p++) << 24;
w |= (uint64_t)(*p++) << 32;
w |= (uint64_t)(*p++) << 40;
w |= (uint64_t)(*p++) << 48;
w |= (uint64_t)(*p++) << 56;
return w;
#endif
}
static BLAKE2_INLINE void store32(void *dst, uint32_t w) {
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = (uint8_t *)dst;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
#endif
}
static BLAKE2_INLINE void store64(void *dst, uint64_t w) {
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = (uint8_t *)dst;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
#endif
}
static BLAKE2_INLINE uint64_t load48(const void *src) {
const uint8_t *p = (const uint8_t *)src;
uint64_t w = *p++;
w |= (uint64_t)(*p++) << 8;
w |= (uint64_t)(*p++) << 16;
w |= (uint64_t)(*p++) << 24;
w |= (uint64_t)(*p++) << 32;
w |= (uint64_t)(*p++) << 40;
return w;
}
static BLAKE2_INLINE void store48(void *dst, uint64_t w) {
uint8_t *p = (uint8_t *)dst;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
w >>= 8;
*p++ = (uint8_t)w;
}
static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {
return (w >> c) | (w << (32 - c));
}
static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
return (w >> c) | (w << (64 - c));
}
void secure_wipe_memory(void *v, size_t n);
#endif
-91
View File
@@ -1,91 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef PORTABLE_BLAKE2_H
#define PORTABLE_BLAKE2_H
#include <stddef.h>
#include <stdint.h>
#include <limits.h>
#if defined(__cplusplus)
extern "C" {
#endif
enum blake2b_constant {
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};
#pragma pack(push, 1)
typedef struct __blake2b_param {
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint64_t node_offset; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
} blake2b_param;
#pragma pack(pop)
typedef struct __blake2b_state {
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES];
unsigned buflen;
unsigned outlen;
uint8_t last_node;
} blake2b_state;
/* Ensure param structs have not been wrongly padded */
/* Poor man's static_assert */
enum {
blake2_size_check_0 = 1 / !!(CHAR_BIT == 8),
blake2_size_check_2 =
1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT)
};
/* Streaming API */
int blake2b_init(blake2b_state *S, size_t outlen);
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
size_t keylen);
int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
int blake2b_update(blake2b_state *S, const void *in, size_t inlen);
int blake2b_final(blake2b_state *S, void *out, size_t outlen);
/* Simple API */
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
const void *key, size_t keylen);
/* Argon2 Team - Begin Code */
int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);
/* Argon2 Team - End Code */
#if defined(__cplusplus)
}
#endif
#endif
-389
View File
@@ -1,389 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "blake2.h"
#include "blake2-impl.h"
static const uint64_t blake2b_IV[8] = {
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
static const unsigned int blake2b_sigma[12][16] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
};
static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
S->f[1] = (uint64_t)-1;
}
static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
if (S->last_node) {
blake2b_set_lastnode(S);
}
S->f[0] = (uint64_t)-1;
}
static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
uint64_t inc) {
S->t[0] += inc;
S->t[1] += (S->t[0] < inc);
}
static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
secure_wipe_memory(S, sizeof(*S)); /* wipe */
blake2b_set_lastblock(S); /* invalidate for further use */
}
static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
memset(S, 0, sizeof(*S));
memcpy(S->h, blake2b_IV, sizeof(S->h));
}
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
const unsigned char *p = (const unsigned char *)P;
unsigned int i;
if (NULL == P || NULL == S) {
return -1;
}
blake2b_init0(S);
/* IV XOR Parameter Block */
for (i = 0; i < 8; ++i) {
S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
}
S->outlen = P->digest_length;
return 0;
}
/* Sequential blake2b initialization */
int blake2b_init(blake2b_state *S, size_t outlen) {
blake2b_param P;
if (S == NULL) {
return -1;
}
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
blake2b_invalidate_state(S);
return -1;
}
/* Setup Parameter Block for unkeyed BLAKE2 */
P.digest_length = (uint8_t)outlen;
P.key_length = 0;
P.fanout = 1;
P.depth = 1;
P.leaf_length = 0;
P.node_offset = 0;
P.node_depth = 0;
P.inner_length = 0;
memset(P.reserved, 0, sizeof(P.reserved));
memset(P.salt, 0, sizeof(P.salt));
memset(P.personal, 0, sizeof(P.personal));
return blake2b_init_param(S, &P);
}
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
size_t keylen) {
blake2b_param P;
if (S == NULL) {
return -1;
}
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
blake2b_invalidate_state(S);
return -1;
}
if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
blake2b_invalidate_state(S);
return -1;
}
/* Setup Parameter Block for keyed BLAKE2 */
P.digest_length = (uint8_t)outlen;
P.key_length = (uint8_t)keylen;
P.fanout = 1;
P.depth = 1;
P.leaf_length = 0;
P.node_offset = 0;
P.node_depth = 0;
P.inner_length = 0;
memset(P.reserved, 0, sizeof(P.reserved));
memset(P.salt, 0, sizeof(P.salt));
memset(P.personal, 0, sizeof(P.personal));
if (blake2b_init_param(S, &P) < 0) {
blake2b_invalidate_state(S);
return -1;
}
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset(block, 0, BLAKE2B_BLOCKBYTES);
memcpy(block, key, keylen);
blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
secure_wipe_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
}
return 0;
}
static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
uint64_t m[16];
uint64_t v[16];
unsigned int i, r;
for (i = 0; i < 16; ++i) {
m[i] = load64(block + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i) {
v[i] = S->h[i];
}
v[8] = blake2b_IV[0];
v[9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = blake2b_IV[4] ^ S->t[0];
v[13] = blake2b_IV[5] ^ S->t[1];
v[14] = blake2b_IV[6] ^ S->f[0];
v[15] = blake2b_IV[7] ^ S->f[1];
#define G(r, i, a, b, c, d) \
do { \
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
d = rotr64(d ^ a, 32); \
c = c + d; \
b = rotr64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
d = rotr64(d ^ a, 16); \
c = c + d; \
b = rotr64(b ^ c, 63); \
} while ((void)0, 0)
#define ROUND(r) \
do { \
G(r, 0, v[0], v[4], v[8], v[12]); \
G(r, 1, v[1], v[5], v[9], v[13]); \
G(r, 2, v[2], v[6], v[10], v[14]); \
G(r, 3, v[3], v[7], v[11], v[15]); \
G(r, 4, v[0], v[5], v[10], v[15]); \
G(r, 5, v[1], v[6], v[11], v[12]); \
G(r, 6, v[2], v[7], v[8], v[13]); \
G(r, 7, v[3], v[4], v[9], v[14]); \
} while ((void)0, 0)
for (r = 0; r < 12; ++r) {
ROUND(r);
}
for (i = 0; i < 8; ++i) {
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
}
#undef G
#undef ROUND
}
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
const uint8_t *pin = (const uint8_t *)in;
if (inlen == 0) {
return 0;
}
/* Sanity check */
if (S == NULL || in == NULL) {
return -1;
}
/* Is this a reused state? */
if (S->f[0] != 0) {
return -1;
}
if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
/* Complete current block */
size_t left = S->buflen;
size_t fill = BLAKE2B_BLOCKBYTES - left;
memcpy(&S->buf[left], pin, fill);
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
blake2b_compress(S, S->buf);
S->buflen = 0;
inlen -= fill;
pin += fill;
/* Avoid buffer copies when possible */
while (inlen > BLAKE2B_BLOCKBYTES) {
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
blake2b_compress(S, pin);
inlen -= BLAKE2B_BLOCKBYTES;
pin += BLAKE2B_BLOCKBYTES;
}
}
memcpy(&S->buf[S->buflen], pin, inlen);
S->buflen += (unsigned int)inlen;
return 0;
}
int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
unsigned int i;
/* Sanity checks */
if (S == NULL || out == NULL || outlen < S->outlen) {
return -1;
}
/* Is this a reused state? */
if (S->f[0] != 0) {
return -1;
}
blake2b_increment_counter(S, S->buflen);
blake2b_set_lastblock(S);
memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
blake2b_compress(S, S->buf);
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
}
memcpy(out, buffer, S->outlen);
secure_wipe_memory(buffer, sizeof(buffer));
secure_wipe_memory(S->buf, sizeof(S->buf));
secure_wipe_memory(S->h, sizeof(S->h));
return 0;
}
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
const void *key, size_t keylen) {
blake2b_state S;
int ret = -1;
/* Verify parameters */
if (NULL == in && inlen > 0) {
goto fail;
}
if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
goto fail;
}
if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
goto fail;
}
if (keylen > 0) {
if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
goto fail;
}
} else {
if (blake2b_init(&S, outlen) < 0) {
goto fail;
}
}
if (blake2b_update(&S, in, inlen) < 0) {
goto fail;
}
ret = blake2b_final(&S, out, outlen);
fail:
secure_wipe_memory(&S, sizeof(S));
return ret;
}
/* Argon2 Team - Begin Code */
int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
uint8_t *out = (uint8_t *)pout;
blake2b_state blake_state;
uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
int ret = -1;
if (outlen > UINT32_MAX) {
goto fail;
}
/* Ensure little-endian byte order! */
store32(outlen_bytes, (uint32_t)outlen);
#define TRY(statement) \
do { \
ret = statement; \
if (ret < 0) { \
goto fail; \
} \
} while ((void)0, 0)
if (outlen <= BLAKE2B_OUTBYTES) {
TRY(blake2b_init(&blake_state, outlen));
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
TRY(blake2b_update(&blake_state, in, inlen));
TRY(blake2b_final(&blake_state, out, outlen));
} else {
uint32_t toproduce;
uint8_t out_buffer[BLAKE2B_OUTBYTES];
uint8_t in_buffer[BLAKE2B_OUTBYTES];
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
TRY(blake2b_update(&blake_state, in, inlen));
TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
out += BLAKE2B_OUTBYTES / 2;
toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
while (toproduce > BLAKE2B_OUTBYTES) {
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
BLAKE2B_OUTBYTES, NULL, 0));
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
out += BLAKE2B_OUTBYTES / 2;
toproduce -= BLAKE2B_OUTBYTES / 2;
}
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
0));
memcpy(out, out_buffer, toproduce);
}
fail:
secure_wipe_memory(&blake_state, sizeof(blake_state));
return ret;
#undef TRY
}
/* Argon2 Team - End Code */
-180
View File
@@ -1,180 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef BLAKE_ROUND_MKA_OPT_H
#define BLAKE_ROUND_MKA_OPT_H
#include "blake2-impl.h"
#include <emmintrin.h>
#if defined(__SSSE3__)
#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
#endif
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
#include <x86intrin.h>
#endif
#if !defined(__XOP__)
#if defined(__SSSE3__)
#define r16 \
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
#define r24 \
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
#define _mm_roti_epi64(x, c) \
(-(c) == 32) \
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
: (-(c) == 24) \
? _mm_shuffle_epi8((x), r24) \
: (-(c) == 16) \
? _mm_shuffle_epi8((x), r16) \
: (-(c) == 63) \
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
_mm_add_epi64((x), (x))) \
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
_mm_slli_epi64((x), 64 - (-(c))))
#else /* defined(__SSE2__) */
#define _mm_roti_epi64(r, c) \
_mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c))))
#endif
#else
#endif
static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
const __m128i z = _mm_mul_epu32(x, y);
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
}
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
A0 = fBlaMka(A0, B0); \
A1 = fBlaMka(A1, B1); \
\
D0 = _mm_xor_si128(D0, A0); \
D1 = _mm_xor_si128(D1, A1); \
\
D0 = _mm_roti_epi64(D0, -32); \
D1 = _mm_roti_epi64(D1, -32); \
\
C0 = fBlaMka(C0, D0); \
C1 = fBlaMka(C1, D1); \
\
B0 = _mm_xor_si128(B0, C0); \
B1 = _mm_xor_si128(B1, C1); \
\
B0 = _mm_roti_epi64(B0, -24); \
B1 = _mm_roti_epi64(B1, -24); \
} while ((void)0, 0)
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
A0 = fBlaMka(A0, B0); \
A1 = fBlaMka(A1, B1); \
\
D0 = _mm_xor_si128(D0, A0); \
D1 = _mm_xor_si128(D1, A1); \
\
D0 = _mm_roti_epi64(D0, -16); \
D1 = _mm_roti_epi64(D1, -16); \
\
C0 = fBlaMka(C0, D0); \
C1 = fBlaMka(C1, D1); \
\
B0 = _mm_xor_si128(B0, C0); \
B1 = _mm_xor_si128(B1, C1); \
\
B0 = _mm_roti_epi64(B0, -63); \
B1 = _mm_roti_epi64(B1, -63); \
} while ((void)0, 0)
#if defined(__SSSE3__)
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
B0 = t0; \
B1 = t1; \
\
t0 = C0; \
C0 = C1; \
C1 = t0; \
\
t0 = _mm_alignr_epi8(D1, D0, 8); \
t1 = _mm_alignr_epi8(D0, D1, 8); \
D0 = t1; \
D1 = t0; \
} while ((void)0, 0)
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
B0 = t0; \
B1 = t1; \
\
t0 = C0; \
C0 = C1; \
C1 = t0; \
\
t0 = _mm_alignr_epi8(D0, D1, 8); \
t1 = _mm_alignr_epi8(D1, D0, 8); \
D0 = t1; \
D1 = t0; \
} while ((void)0, 0)
#else /* SSE2 */
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
__m128i t0 = D0; \
__m128i t1 = B0; \
D0 = C0; \
C0 = C1; \
C1 = D0; \
D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
} while ((void)0, 0)
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
do { \
__m128i t0, t1; \
t0 = C0; \
C0 = C1; \
C1 = t0; \
t0 = B0; \
t1 = D0; \
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
} while ((void)0, 0)
#endif
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
do { \
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
\
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
\
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
\
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
} while ((void)0, 0)
#endif
-56
View File
@@ -1,56 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef BLAKE_ROUND_MKA_H
#define BLAKE_ROUND_MKA_H
#include "blake2.h"
#include "blake2-impl.h"
/*designed by the Lyra PHC team */
static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) {
const uint64_t m = UINT64_C(0xFFFFFFFF);
const uint64_t xy = (x & m) * (y & m);
return x + y + 2 * xy;
}
#define G(a, b, c, d) \
do { \
a = fBlaMka(a, b); \
d = rotr64(d ^ a, 32); \
c = fBlaMka(c, d); \
b = rotr64(b ^ c, 24); \
a = fBlaMka(a, b); \
d = rotr64(d ^ a, 16); \
c = fBlaMka(c, d); \
b = rotr64(b ^ c, 63); \
} while ((void)0, 0)
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
v12, v13, v14, v15) \
do { \
G(v0, v4, v8, v12); \
G(v1, v5, v9, v13); \
G(v2, v6, v10, v14); \
G(v3, v7, v11, v15); \
G(v0, v5, v10, v15); \
G(v1, v6, v11, v12); \
G(v2, v7, v8, v13); \
G(v3, v4, v9, v14); \
} while ((void)0, 0)
#endif
-610
View File
@@ -1,610 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
/*For memory wiping*/
#ifdef _MSC_VER
#include <windows.h>
#include <winbase.h> /* For SecureZeroMemory */
#endif
#if defined __STDC_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1
#endif
#define VC_GE_2005(version) (version >= 1400)
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "core.h"
#include "thread.h"
#include "blake2/blake2.h"
#include "blake2/blake2-impl.h"
#ifdef GENKAT
#include "genkat.h"
#endif
#if defined(__clang__)
#if __has_attribute(optnone)
#define NOT_OPTIMIZED __attribute__((optnone))
#endif
#elif defined(__GNUC__)
#define GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION >= 40400
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
#endif
#endif
#ifndef NOT_OPTIMIZED
#define NOT_OPTIMIZED
#endif
/***************Instance and Position constructors**********/
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
void copy_block(block *dst, const block *src) {
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
}
void xor_block(block *dst, const block *src) {
int i;
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
dst->v[i] ^= src->v[i];
}
}
static void load_block(block *dst, const void *input) {
unsigned i;
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
}
}
static void store_block(void *output, const block *src) {
unsigned i;
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
}
}
/***************Memory allocators*****************/
int allocate_memory(block **memory, uint32_t m_cost) {
if (memory != NULL) {
size_t memory_size = sizeof(block) * m_cost;
if (m_cost != 0 &&
memory_size / m_cost !=
sizeof(block)) { /*1. Check for multiplication overflow*/
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
*memory = (block *)malloc(memory_size); /*2. Try to allocate*/
if (!*memory) {
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
return ARGON2_OK;
} else {
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
}
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
SecureZeroMemory(v, n);
#elif defined memset_s
memset_s(v, n, 0, n);
#elif defined(__OpenBSD__)
explicit_bzero(v, n);
#else
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
memset_sec(v, 0, n);
#endif
}
/*********Memory functions*/
void clear_memory(argon2_instance_t *instance, int clear) {
if (instance->memory != NULL && clear) {
secure_wipe_memory(instance->memory,
sizeof(block) * instance->memory_blocks);
}
}
void free_memory(block *memory) { free(memory); }
void finalize(const argon2_context *context, argon2_instance_t *instance) {
if (context != NULL && instance != NULL) {
block blockhash;
uint32_t l;
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
/* XOR the last blocks */
for (l = 1; l < instance->lanes; ++l) {
uint32_t last_block_in_lane =
l * instance->lane_length + (instance->lane_length - 1);
xor_block(&blockhash, instance->memory + last_block_in_lane);
}
/* Hash the result */
{
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
store_block(blockhash_bytes, &blockhash);
blake2b_long(context->out, context->outlen, blockhash_bytes,
ARGON2_BLOCK_SIZE);
secure_wipe_memory(blockhash.v,
ARGON2_BLOCK_SIZE); /* clear blockhash */
secure_wipe_memory(blockhash_bytes,
ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
}
#ifdef GENKAT
print_tag(context->out, context->outlen);
#endif
/* Clear memory */
clear_memory(instance, context->flags & ARGON2_FLAG_CLEAR_PASSWORD);
/* Deallocate the memory */
if (NULL != context->free_cbk) {
context->free_cbk((uint8_t *)instance->memory,
instance->memory_blocks * sizeof(block));
} else {
free_memory(instance->memory);
}
}
}
uint32_t index_alpha(const argon2_instance_t *instance,
const argon2_position_t *position, uint32_t pseudo_rand,
int same_lane) {
/*
* Pass 0:
* This lane : all already finished segments plus already constructed
* blocks in this segment
* Other lanes : all already finished segments
* Pass 1+:
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
* blocks in this segment
* Other lanes : (SYNC_POINTS - 1) last segments
*/
uint32_t reference_area_size;
uint64_t relative_position;
uint32_t start_position, absolute_position;
if (0 == position->pass) {
/* First pass */
if (0 == position->slice) {
/* First slice */
reference_area_size =
position->index - 1; /* all but the previous */
} else {
if (same_lane) {
/* The same lane => add current segment */
reference_area_size =
position->slice * instance->segment_length +
position->index - 1;
} else {
reference_area_size =
position->slice * instance->segment_length +
((position->index == 0) ? (-1) : 0);
}
}
} else {
/* Second pass */
if (same_lane) {
reference_area_size = instance->lane_length -
instance->segment_length + position->index -
1;
} else {
reference_area_size = instance->lane_length -
instance->segment_length +
((position->index == 0) ? (-1) : 0);
}
}
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
* relative position */
relative_position = pseudo_rand;
relative_position = relative_position * relative_position >> 32;
relative_position = reference_area_size - 1 -
(reference_area_size * relative_position >> 32);
/* 1.2.5 Computing starting position */
start_position = 0;
if (0 != position->pass) {
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
? 0
: (position->slice + 1) * instance->segment_length;
}
/* 1.2.6. Computing absolute position */
absolute_position = (start_position + relative_position) %
instance->lane_length; /* absolute position */
return absolute_position;
}
#ifdef _WIN32
static unsigned __stdcall fill_segment_thr(void *thread_data)
#else
static void *fill_segment_thr(void *thread_data)
#endif
{
argon2_thread_data *my_data = (argon2_thread_data *)thread_data;
fill_segment(my_data->instance_ptr, my_data->pos);
argon2_thread_exit();
return 0;
}
int fill_memory_blocks(argon2_instance_t *instance) {
uint32_t r, s;
argon2_thread_handle_t *thread = NULL;
argon2_thread_data *thr_data = NULL;
int rc = ARGON2_OK;
if (instance == NULL || instance->lanes == 0) {
rc = ARGON2_THREAD_FAIL;
goto fail;
}
/* 1. Allocating space for threads */
thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
if (thread == NULL) {
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
goto fail;
}
thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
if (thr_data == NULL) {
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
goto fail;
}
for (r = 0; r < instance->passes; ++r) {
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
uint32_t l;
/* 2. Calling threads */
for (l = 0; l < instance->lanes; ++l) {
argon2_position_t position;
/* 2.1 Join a thread if limit is exceeded */
if (l >= instance->threads) {
if (argon2_thread_join(thread[l - instance->threads])) {
rc = ARGON2_THREAD_FAIL;
goto fail;
}
}
/* 2.2 Create thread */
position.pass = r;
position.lane = l;
position.slice = (uint8_t)s;
position.index = 0;
thr_data[l].instance_ptr =
instance; /* preparing the thread input */
memcpy(&(thr_data[l].pos), &position,
sizeof(argon2_position_t));
if (argon2_thread_create(&thread[l], &fill_segment_thr,
(void *)&thr_data[l])) {
rc = ARGON2_THREAD_FAIL;
goto fail;
}
/* fill_segment(instance, position); */
/*Non-thread equivalent of the lines above */
}
/* 3. Joining remaining threads */
for (l = instance->lanes - instance->threads; l < instance->lanes;
++l) {
if (argon2_thread_join(thread[l])) {
rc = ARGON2_THREAD_FAIL;
goto fail;
}
}
}
#ifdef GENKAT
internal_kat(instance, r); /* Print all memory blocks */
#endif
}
fail:
if (thread != NULL) {
free(thread);
}
if (thr_data != NULL) {
free(thr_data);
}
return rc;
}
int validate_inputs(const argon2_context *context) {
if (NULL == context) {
return ARGON2_INCORRECT_PARAMETER;
}
if (NULL == context->out) {
return ARGON2_OUTPUT_PTR_NULL;
}
/* Validate output length */
if (ARGON2_MIN_OUTLEN > context->outlen) {
return ARGON2_OUTPUT_TOO_SHORT;
}
if (ARGON2_MAX_OUTLEN < context->outlen) {
return ARGON2_OUTPUT_TOO_LONG;
}
/* Validate password length */
if (NULL == context->pwd) {
if (0 != context->pwdlen) {
return ARGON2_PWD_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
return ARGON2_PWD_TOO_SHORT;
}
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
return ARGON2_PWD_TOO_LONG;
}
}
/* Validate salt length */
if (NULL == context->salt) {
if (0 != context->saltlen) {
return ARGON2_SALT_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
return ARGON2_SALT_TOO_SHORT;
}
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
return ARGON2_SALT_TOO_LONG;
}
}
/* Validate secret length */
if (NULL == context->secret) {
if (0 != context->secretlen) {
return ARGON2_SECRET_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_SECRET > context->secretlen) {
return ARGON2_SECRET_TOO_SHORT;
}
if (ARGON2_MAX_SECRET < context->secretlen) {
return ARGON2_SECRET_TOO_LONG;
}
}
/* Validate associated data */
if (NULL == context->ad) {
if (0 != context->adlen) {
return ARGON2_AD_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_AD_LENGTH > context->adlen) {
return ARGON2_AD_TOO_SHORT;
}
if (ARGON2_MAX_AD_LENGTH < context->adlen) {
return ARGON2_AD_TOO_LONG;
}
}
/* Validate memory cost */
if (ARGON2_MIN_MEMORY > context->m_cost) {
return ARGON2_MEMORY_TOO_LITTLE;
}
if (ARGON2_MAX_MEMORY < context->m_cost) {
return ARGON2_MEMORY_TOO_MUCH;
}
if (context->m_cost < 8 * context->lanes) {
return ARGON2_MEMORY_TOO_LITTLE;
}
/* Validate time cost */
if (ARGON2_MIN_TIME > context->t_cost) {
return ARGON2_TIME_TOO_SMALL;
}
if (ARGON2_MAX_TIME < context->t_cost) {
return ARGON2_TIME_TOO_LARGE;
}
/* Validate lanes */
if (ARGON2_MIN_LANES > context->lanes) {
return ARGON2_LANES_TOO_FEW;
}
if (ARGON2_MAX_LANES < context->lanes) {
return ARGON2_LANES_TOO_MANY;
}
/* Validate threads */
if (ARGON2_MIN_THREADS > context->threads) {
return ARGON2_THREADS_TOO_FEW;
}
if (ARGON2_MAX_THREADS < context->threads) {
return ARGON2_THREADS_TOO_MANY;
}
if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
return ARGON2_FREE_MEMORY_CBK_NULL;
}
if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
}
return ARGON2_OK;
}
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
uint32_t l;
/* Make the first and second block in each lane as G(H0||i||0) or
G(H0||i||1) */
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
for (l = 0; l < instance->lanes; ++l) {
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
ARGON2_PREHASH_SEED_LENGTH);
load_block(&instance->memory[l * instance->lane_length + 0],
blockhash_bytes);
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
ARGON2_PREHASH_SEED_LENGTH);
load_block(&instance->memory[l * instance->lane_length + 1],
blockhash_bytes);
}
secure_wipe_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
}
void initial_hash(uint8_t *blockhash, argon2_context *context,
argon2_type type) {
blake2b_state BlakeHash;
uint8_t value[sizeof(uint32_t)];
if (NULL == context || NULL == blockhash) {
return;
}
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
store32(&value, context->lanes);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, context->outlen);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, context->m_cost);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, context->t_cost);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, context->version);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, (uint32_t)type);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
store32(&value, context->pwdlen);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
if (context->pwd != NULL) {
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
context->pwdlen);
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
secure_wipe_memory(context->pwd, context->pwdlen);
context->pwdlen = 0;
}
}
store32(&value, context->saltlen);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
if (context->salt != NULL) {
blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
context->saltlen);
}
store32(&value, context->secretlen);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
if (context->secret != NULL) {
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
context->secretlen);
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
secure_wipe_memory(context->secret, context->secretlen);
context->secretlen = 0;
}
}
store32(&value, context->adlen);
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
if (context->ad != NULL) {
blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
context->adlen);
}
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
}
int initialize(argon2_instance_t *instance, argon2_context *context) {
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
int result = ARGON2_OK;
if (instance == NULL || context == NULL)
return ARGON2_INCORRECT_PARAMETER;
/* 1. Memory allocation */
if (NULL != context->allocate_cbk) {
uint8_t *p;
result = context->allocate_cbk(&p, instance->memory_blocks *
ARGON2_BLOCK_SIZE);
if (ARGON2_OK != result) {
return result;
}
instance->memory = (block *)p;
} else {
result = allocate_memory(&(instance->memory), instance->memory_blocks);
if (ARGON2_OK != result) {
return result;
}
}
/* 2. Initial hashing */
/* H_0 + 8 extra bytes to produce the first blocks */
/* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
/* Hashing all inputs */
initial_hash(blockhash, context, instance->type);
/* Zeroing 8 extra bytes */
secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
ARGON2_PREHASH_SEED_LENGTH -
ARGON2_PREHASH_DIGEST_LENGTH);
#ifdef GENKAT
initial_kat(blockhash, context, instance->type);
#endif
/* 3. Creating first blocks, we always have at least two blocks in a slice
*/
fill_first_blocks(blockhash, instance);
/* Clearing the hash */
secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
return ARGON2_OK;
}
-223
View File
@@ -1,223 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_CORE_H
#define ARGON2_CORE_H
#include "argon2.h"
#if defined(_MSC_VER)
#define ALIGN(n) __declspec(align(16))
#elif defined(__GNUC__) || defined(__clang)
#define ALIGN(x) __attribute__((__aligned__(x)))
#else
#define ALIGN(x)
#endif
#define CONST_CAST(x) (x)(uintptr_t)
/*************************Argon2 internal
* constants**************************************************/
enum argon2_core_constants {
/* Memory block size in bytes */
ARGON2_BLOCK_SIZE = 1024,
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
/* Number of pseudo-random values generated by one call to Blake in Argon2i
to
generate reference block positions */
ARGON2_ADDRESSES_IN_BLOCK = 128,
/* Pre-hashing digest length and its extension*/
ARGON2_PREHASH_DIGEST_LENGTH = 64,
ARGON2_PREHASH_SEED_LENGTH = 72
};
/*************************Argon2 internal data
* types**************************************************/
/*
* Structure for the (1KB) memory block implemented as 128 64-bit words.
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
* bounds checking).
*/
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
/*****************Functions that work with the block******************/
/* Initialize each byte of the block with @in */
void init_block_value(block *b, uint8_t in);
/* Copy block @src to block @dst */
void copy_block(block *dst, const block *src);
/* XOR @src onto @dst bytewise */
void xor_block(block *dst, const block *src);
/*
* Argon2 instance: memory pointer, number of passes, amount of memory, type,
* and derived values.
* Used to evaluate the number and location of blocks to construct in each
* thread
*/
typedef struct Argon2_instance_t {
block *memory; /* Memory pointer */
uint32_t version;
uint32_t passes; /* Number of passes */
uint32_t memory_blocks; /* Number of blocks in memory */
uint32_t segment_length;
uint32_t lane_length;
uint32_t lanes;
uint32_t threads;
argon2_type type;
int print_internals; /* whether to print the memory blocks */
} argon2_instance_t;
/*
* Argon2 position: where we construct the block right now. Used to distribute
* work between threads.
*/
typedef struct Argon2_position_t {
uint32_t pass;
uint32_t lane;
uint8_t slice;
uint32_t index;
} argon2_position_t;
/*Struct that holds the inputs for thread handling FillSegment*/
typedef struct Argon2_thread_data {
argon2_instance_t *instance_ptr;
argon2_position_t pos;
} argon2_thread_data;
/*************************Argon2 core
* functions**************************************************/
/* Allocates memory to the given pointer
* @param memory pointer to the pointer to the memory
* @param m_cost number of blocks to allocate in the memory
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
*/
int allocate_memory(block **memory, uint32_t m_cost);
/* Function that securely cleans the memory
* @param mem Pointer to the memory
* @param s Memory size in bytes
*/
void secure_wipe_memory(void *v, size_t n);
/* Clears memory
* @param instance pointer to the current instance
* @param clear_memory indicates if we clear the memory with zeros.
*/
void clear_memory(argon2_instance_t *instance, int clear);
/* Deallocates memory
* @param memory pointer to the blocks
*/
void free_memory(block *memory);
/*
* Computes absolute position of reference block in the lane following a skewed
* distribution and using a pseudo-random value as input
* @param instance Pointer to the current instance
* @param position Pointer to the current position
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
* @param same_lane Indicates if the block will be taken from the current lane.
* If so we can reference the current segment
* @pre All pointers must be valid
*/
uint32_t index_alpha(const argon2_instance_t *instance,
const argon2_position_t *position, uint32_t pseudo_rand,
int same_lane);
/*
* Function that validates all inputs against predefined restrictions and return
* an error code
* @param context Pointer to current Argon2 context
* @return ARGON2_OK if everything is all right, otherwise one of error codes
* (all defined in <argon2.h>
*/
int validate_inputs(const argon2_context *context);
/*
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
* password and secret if needed
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
* @param blockhash Buffer for pre-hashing digest
* @param type Argon2 type
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
* allocated
*/
void initial_hash(uint8_t *blockhash, argon2_context *context,
argon2_type type);
/*
* Function creates first 2 blocks per lane
* @param instance Pointer to the current instance
* @param blockhash Pointer to the pre-hashing digest
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
*/
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
/*
* Function allocates memory, hashes the inputs with Blake, and creates first
* two blocks. Returns the pointer to the main memory with 2 blocks per lane
* initialized
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
* @param instance Current Argon2 instance
* @return Zero if successful, -1 if memory failed to allocate. @context->state
* will be modified if successful.
*/
int initialize(argon2_instance_t *instance, argon2_context *context);
/*
* XORing the last block of each lane, hashing it, making the tag. Deallocates
* the memory.
* @param context Pointer to current Argon2 context (use only the out parameters
* from it)
* @param instance Pointer to current instance of Argon2
* @pre instance->state must point to necessary amount of memory
* @pre context->out must point to outlen bytes of memory
* @pre if context->free_cbk is not NULL, it should point to a function that
* deallocates memory
*/
void finalize(const argon2_context *context, argon2_instance_t *instance);
/*
* Function that fills the segment using previous segments also from other
* threads
* @param instance Pointer to the current instance
* @param position Current position
* @pre all block pointers must be valid
*/
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position);
/*
* Function that fills the entire memory t_cost times based on the first two
* blocks in each lane
* @param instance Pointer to the current instance
* @return ARGON2_OK if successful, @context->state
*/
int fill_memory_blocks(argon2_instance_t *instance);
#endif
-462
View File
@@ -1,462 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "encoding.h"
#include "core.h"
/*
* Example code for a decoder and encoder of "hash strings", with Argon2
* parameters.
*
* This code comprises three sections:
*
* -- The first section contains generic Base64 encoding and decoding
* functions. It is conceptually applicable to any hash function
* implementation that uses Base64 to encode and decode parameters,
* salts and outputs. It could be made into a library, provided that
* the relevant functions are made public (non-static) and be given
* reasonable names to avoid collisions with other functions.
*
* -- The second section is specific to Argon2. It encodes and decodes
* the parameters, salts and outputs. It does not compute the hash
* itself.
*
* -- The third section is test code, with a main() function. With
* this section, the whole file compiles as a stand-alone program
* that exercises the encoding and decoding functions with some
* test vectors.
*
* The code was originally written by Thomas Pornin <pornin@bolet.org>,
* to whom comments and remarks may be sent. It is released under what
* should amount to Public Domain or its closest equivalent; the
* following mantra is supposed to incarnate that fact with all the
* proper legal rituals:
*
* ---------------------------------------------------------------------
* This file is provided under the terms of Creative Commons CC0 1.0
* Public Domain Dedication. To the extent possible under law, the
* author (Thomas Pornin) has waived all copyright and related or
* neighboring rights to this file. This work is published from: Canada.
* ---------------------------------------------------------------------
*
* Copyright (c) 2015 Thomas Pornin
*/
/* ==================================================================== */
/*
* Common code; could be shared between different hash functions.
*
* Note: the Base64 functions below assume that uppercase letters (resp.
* lowercase letters) have consecutive numerical codes, that fit on 8
* bits. All modern systems use ASCII-compatible charsets, where these
* properties are true. If you are stuck with a dinosaur of a system
* that still defaults to EBCDIC then you already have much bigger
* interoperability issues to deal with.
*/
/*
* Some macros for constant-time comparisons. These work over values in
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
*/
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
#define GE(x, y) (GT(y, x) ^ 0xFF)
#define LT(x, y) GT(y, x)
#define LE(x, y) GE(y, x)
/*
* Convert value x (0..63) to corresponding Base64 character.
*/
static int b64_byte_to_char(unsigned x) {
return (LT(x, 26) & (x + 'A')) |
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
(EQ(x, 63) & '/');
}
/*
* Convert character c to the corresponding 6-bit value. If character c
* is not a Base64 character, then 0xFF (255) is returned.
*/
static unsigned b64_char_to_byte(int c) {
unsigned x;
x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
(GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
(GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
(EQ(c, '/') & 63);
return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
}
/*
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
* of the output buffer 'dst'; if that buffer is not large enough to
* receive the result (including the terminating 0), then (size_t)-1
* is returned. Otherwise, the zero-terminated Base64 string is written
* in the buffer, and the output length (counted WITHOUT the terminating
* zero) is returned.
*/
static size_t to_base64(char *dst, size_t dst_len, const void *src,
size_t src_len) {
size_t olen;
const unsigned char *buf;
unsigned acc, acc_len;
olen = (src_len / 3) << 2;
switch (src_len % 3) {
case 2:
olen++;
/* fall through */
case 1:
olen += 2;
break;
}
if (dst_len <= olen) {
return (size_t)-1;
}
acc = 0;
acc_len = 0;
buf = (const unsigned char *)src;
while (src_len-- > 0) {
acc = (acc << 8) + (*buf++);
acc_len += 8;
while (acc_len >= 6) {
acc_len -= 6;
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
}
}
if (acc_len > 0) {
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
}
*dst++ = 0;
return olen;
}
/*
* Decode Base64 chars into bytes. The '*dst_len' value must initially
* contain the length of the output buffer '*dst'; when the decoding
* ends, the actual number of decoded bytes is written back in
* '*dst_len'.
*
* Decoding stops when a non-Base64 character is encountered, or when
* the output buffer capacity is exceeded. If an error occurred (output
* buffer is too small, invalid last characters leading to unprocessed
* buffered bits), then NULL is returned; otherwise, the returned value
* points to the first non-Base64 character in the source stream, which
* may be the terminating zero.
*/
static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
size_t len;
unsigned char *buf;
unsigned acc, acc_len;
buf = (unsigned char *)dst;
len = 0;
acc = 0;
acc_len = 0;
for (;;) {
unsigned d;
d = b64_char_to_byte(*src);
if (d == 0xFF) {
break;
}
src++;
acc = (acc << 6) + d;
acc_len += 6;
if (acc_len >= 8) {
acc_len -= 8;
if ((len++) >= *dst_len) {
return NULL;
}
*buf++ = (acc >> acc_len) & 0xFF;
}
}
/*
* If the input length is equal to 1 modulo 4 (which is
* invalid), then there will remain 6 unprocessed bits;
* otherwise, only 0, 2 or 4 bits are buffered. The buffered
* bits must also all be zero.
*/
if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) {
return NULL;
}
*dst_len = len;
return src;
}
/*
* Decode decimal integer from 'str'; the value is written in '*v'.
* Returned value is a pointer to the next non-decimal character in the
* string. If there is no digit at all, or the value encoding is not
* minimal (extra leading zeros), or the value does not fit in an
* 'unsigned long', then NULL is returned.
*/
static const char *decode_decimal(const char *str, unsigned long *v) {
const char *orig;
unsigned long acc;
acc = 0;
for (orig = str;; str++) {
int c;
c = *str;
if (c < '0' || c > '9') {
break;
}
c -= '0';
if (acc > (ULONG_MAX / 10)) {
return NULL;
}
acc *= 10;
if ((unsigned long)c > (ULONG_MAX - acc)) {
return NULL;
}
acc += (unsigned long)c;
}
if (str == orig || (*orig == '0' && str != (orig + 1))) {
return NULL;
}
*v = acc;
return str;
}
/* ==================================================================== */
/*
* Code specific to Argon2.
*
* The code below applies the following format:
*
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
*
* where <T> is either 'd' or 'i', <num> is a decimal integer (positive, fits in
* an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
* characters, no newline or whitespace).
* The "keyid" is a binary identifier for a key (up to 8 bytes);
* "data" is associated data (up to 32 bytes). When the 'keyid'
* (resp. the 'data') is empty, then it is ommitted from the output.
*
* The last two binary chunks (encoded in Base64) are, in that order,
* the salt and the output. Both are optional, but you cannot have an
* output without a salt. The binary salt length is between 8 and 48 bytes.
* The output length is always exactly 32 bytes.
*/
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
/* check for prefix */
#define CC(prefix) \
do { \
size_t cc_len = strlen(prefix); \
if (strncmp(str, prefix, cc_len) != 0) { \
return ARGON2_DECODING_FAIL; \
} \
str += cc_len; \
} while ((void)0, 0)
/* prefix checking with supplied code */
#define CC_opt(prefix, code) \
do { \
size_t cc_len = strlen(prefix); \
if (strncmp(str, prefix, cc_len) == 0) { \
str += cc_len; \
{ code; } \
} \
} while ((void)0, 0)
/* Decoding prefix into decimal */
#define DECIMAL(x) \
do { \
unsigned long dec_x; \
str = decode_decimal(str, &dec_x); \
if (str == NULL) { \
return ARGON2_DECODING_FAIL; \
} \
(x) = dec_x; \
} while ((void)0, 0)
#define BIN(buf, max_len, len) \
do { \
size_t bin_len = (max_len); \
str = from_base64(buf, &bin_len, str); \
if (str == NULL || bin_len > UINT32_MAX) { \
return ARGON2_DECODING_FAIL; \
} \
(len) = (uint32_t)bin_len; \
} while ((void)0, 0)
size_t maxadlen = ctx->adlen;
size_t maxsaltlen = ctx->saltlen;
size_t maxoutlen = ctx->outlen;
int validation_result;
const char* type_string;
ctx->adlen = 0;
ctx->saltlen = 0;
ctx->outlen = 0;
ctx->pwdlen = 0;
/* We should start with the argon2_type we are using */
CC("$");
type_string = argon2_type2string(type, 0);
if (type_string) {
CC(type_string);
} else {
return ARGON2_INCORRECT_TYPE;
}
/* Reading the version number if the default is suppressed */
ctx->version = ARGON2_VERSION_10;
CC_opt("$v=", DECIMAL(ctx->version));
CC("$m=");
DECIMAL(ctx->m_cost);
CC(",t=");
DECIMAL(ctx->t_cost);
CC(",p=");
DECIMAL(ctx->lanes);
ctx->threads = ctx->lanes;
CC_opt(",data=", BIN(ctx->ad, maxadlen, ctx->adlen));
if (*str == 0) {
return ARGON2_OK;
}
CC("$");
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
if (*str == 0) {
return ARGON2_OK;
}
CC("$");
BIN(ctx->out, maxoutlen, ctx->outlen);
validation_result = validate_inputs(ctx);
if (validation_result != ARGON2_OK) {
return validation_result;
}
if (*str == 0) {
return ARGON2_OK;
} else {
return ARGON2_DECODING_FAIL;
}
#undef CC
#undef CC_opt
#undef DECIMAL
#undef BIN
}
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
argon2_type type) {
#define SS(str) \
do { \
size_t pp_len = strlen(str); \
if (pp_len >= dst_len) { \
return ARGON2_ENCODING_FAIL; \
} \
memcpy(dst, str, pp_len + 1); \
dst += pp_len; \
dst_len -= pp_len; \
} while ((void)0, 0)
#define SX(x) \
do { \
char tmp[30]; \
sprintf(tmp, "%lu", (unsigned long)(x)); \
SS(tmp); \
} while ((void)0, 0)
#define SB(buf, len) \
do { \
size_t sb_len = to_base64(dst, dst_len, buf, len); \
if (sb_len == (size_t)-1) { \
return ARGON2_ENCODING_FAIL; \
} \
dst += sb_len; \
dst_len -= sb_len; \
} while ((void)0, 0)
const char* type_string = argon2_type2string(type, 0);
SS("$");
if (type_string) {
SS(type_string);
} else {
return ARGON2_ENCODING_FAIL;
}
if (validate_inputs(ctx) != ARGON2_OK) {
return validate_inputs(ctx);
}
SS("$v=");
SX(ctx->version);
SS("$m=");
SX(ctx->m_cost);
SS(",t=");
SX(ctx->t_cost);
SS(",p=");
SX(ctx->lanes);
if (ctx->adlen > 0) {
SS(",data=");
SB(ctx->ad, ctx->adlen);
}
if (ctx->saltlen == 0)
return ARGON2_OK;
SS("$");
SB(ctx->salt, ctx->saltlen);
if (ctx->outlen == 0)
return ARGON2_OK;
SS("$");
SB(ctx->out, ctx->outlen);
return ARGON2_OK;
#undef SS
#undef SX
#undef SB
}
size_t b64len(uint32_t len) {
size_t olen = ((size_t)len / 3) << 2;
switch (len % 3) {
case 2:
olen++;
/* fall through */
case 1:
olen += 2;
break;
}
return olen;
}
size_t numlen(uint32_t num) {
size_t len = 1;
while (num >= 10) {
++len;
num = num / 10;
}
return len;
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ENCODING_H
#define ENCODING_H
#include "argon2.h"
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
/*
* encode an Argon2 hash string into the provided buffer. 'dst_len'
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
* is less than the number of required characters (including the
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
*
* if ctx->outlen is 0, then the hash string will be a salt string
* (no output). if ctx->saltlen is also 0, then the string will be a
* parameter-only string (no salt and no output).
*
* on success, ARGON2_OK is returned.
*
* No other parameters are checked
*/
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
argon2_type type);
/*
* Decodes an Argon2 hash string into the provided structure 'ctx'.
* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out
* length values that are allowed; invalid input string causes an error.
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
*/
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
/* Returns the length of the encoded byte stream with length len */
size_t b64len(uint32_t len);
/* Returns the length of the encoded number num */
size_t numlen(uint32_t num);
#endif
-227
View File
@@ -1,227 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "argon2.h"
#include "opt.h"
#include "blake2/blake2.h"
#include "blake2/blamka-round-opt.h"
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
uint32_t i;
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
block_XY[i] = state[i] = _mm_xor_si128(
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
}
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
state[8 * i + 6], state[8 * i + 7]);
}
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
state[8 * 6 + i], state[8 * 7 + i]);
}
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
state[i] = _mm_xor_si128(state[i], block_XY[i]);
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
}
}
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
uint8_t *next_block) {
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
uint32_t i;
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
state[i] = _mm_xor_si128(
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
block_XY[i] = _mm_xor_si128(
state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i])));
}
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
state[8 * i + 6], state[8 * i + 7]);
}
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
state[8 * 6 + i], state[8 * 7 + i]);
}
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
state[i] = _mm_xor_si128(state[i], block_XY[i]);
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
}
}
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands) {
block address_block, input_block, tmp_block;
uint32_t i;
init_block_value(&address_block, 0);
init_block_value(&input_block, 0);
if (instance != NULL && position != NULL) {
input_block.v[0] = position->pass;
input_block.v[1] = position->lane;
input_block.v[2] = position->slice;
input_block.v[3] = instance->memory_blocks;
input_block.v[4] = instance->passes;
input_block.v[5] = instance->type;
for (i = 0; i < instance->segment_length; ++i) {
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
/*Temporary zero-initialized blocks*/
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
memset(zero_block, 0, sizeof(zero_block));
memset(zero2_block, 0, sizeof(zero2_block));
init_block_value(&address_block, 0);
init_block_value(&tmp_block, 0);
/*Increasing index counter*/
input_block.v[6]++;
/*First iteration of G*/
fill_block_with_xor(zero_block, (uint8_t *)&input_block.v,
(uint8_t *)&tmp_block.v);
/*Second iteration of G*/
fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v,
(uint8_t *)&address_block.v);
}
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
}
}
}
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL;
uint64_t pseudo_rand, ref_index, ref_lane;
uint32_t prev_offset, curr_offset;
uint32_t starting_index, i;
__m128i state[64];
int data_independent_addressing;
/* Pseudo-random values that determine the reference block position */
uint64_t *pseudo_rands = NULL;
if (instance == NULL) {
return;
}
data_independent_addressing =
(instance->type == Argon2_i) ||
(instance->type == Argon2_id && (position.pass == 0) &&
(position.slice < ARGON2_SYNC_POINTS / 2));
pseudo_rands =
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
if (pseudo_rands == NULL) {
return;
}
if (data_independent_addressing) {
generate_addresses(instance, &position, pseudo_rands);
}
starting_index = 0;
if ((0 == position.pass) && (0 == position.slice)) {
starting_index = 2; /* we have already generated the first two blocks */
}
/* Offset of the current block */
curr_offset = position.lane * instance->lane_length +
position.slice * instance->segment_length + starting_index;
if (0 == curr_offset % instance->lane_length) {
/* Last block in this lane */
prev_offset = curr_offset + instance->lane_length - 1;
} else {
/* Previous block */
prev_offset = curr_offset - 1;
}
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) {
/*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) {
prev_offset = curr_offset - 1;
}
/* 1.2 Computing the index of the reference block */
/* 1.2.1 Taking pseudo-random value from the previous block */
if (data_independent_addressing) {
pseudo_rand = pseudo_rands[i];
} else {
pseudo_rand = instance->memory[prev_offset].v[0];
}
/* 1.2.2 Computing the lane of the reference block */
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
if ((position.pass == 0) && (position.slice == 0)) {
/* Can not reference other lanes yet */
ref_lane = position.lane;
}
/* 1.2.3 Computing the number of possible reference block within the
* lane.
*/
position.index = i;
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
ref_lane == position.lane);
/* 2 Creating a new block */
ref_block =
instance->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->memory + curr_offset;
if (ARGON2_VERSION_10 == instance->version) {
/* version 1.2.1 and earlier: overwrite, not XOR */
fill_block(state, (uint8_t *)ref_block->v,
(uint8_t *)curr_block->v);
} else {
if(0 == position.pass) {
fill_block(state, (uint8_t *)ref_block->v,
(uint8_t *)curr_block->v);
} else {
fill_block_with_xor(state, (uint8_t *)ref_block->v,
(uint8_t *)curr_block->v);
}
}
}
free(pseudo_rands);
}
-56
View File
@@ -1,56 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_OPT_H
#define ARGON2_OPT_H
#include "core.h"
#include <emmintrin.h>
/*
* Function fills a new memory block by XORing the new block over the old one. Memory must be initialized.
* After finishing, @state is identical to @next_block
* @param state Pointer to the just produced block. Content will be updated(!)
* @param ref_block Pointer to the reference block
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
* @pre all block pointers must be valid
*/
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
/* LEGACY CODE: version 1.2.1 and earlier
* Function fills a new memory block by overwriting @next_block.
* @param state Pointer to the just produced block. Content will be updated(!)
* @param ref_block Pointer to the reference block
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
* @pre all block pointers must be valid
*/
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
/*
* Generate pseudo-random values to reference blocks in the segment and puts
* them into the array
* @param instance Pointer to the current instance
* @param position Pointer to the current position
* @param pseudo_rands Pointer to the array of 64-bit values
* @pre pseudo_rands must point to @a instance->segment_length allocated values
*/
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands);
#endif /* ARGON2_OPT_H */
-235
View File
@@ -1,235 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "argon2.h"
#include "ref.h"
#include "blake2/blamka-round-ref.h"
#include "blake2/blake2-impl.h"
#include "blake2/blake2.h"
void fill_block(const block *prev_block, const block *ref_block,
block *next_block) {
block blockR, block_tmp;
unsigned i;
copy_block(&blockR, ref_block);
xor_block(&blockR, prev_block);
copy_block(&block_tmp, &blockR);
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block */
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
(16,17,..31)... finally (112,113,...127) */
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND_NOMSG(
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
blockR.v[16 * i + 15]);
}
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
for (i = 0; i < 8; i++) {
BLAKE2_ROUND_NOMSG(
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
blockR.v[2 * i + 113]);
}
copy_block(next_block, &block_tmp);
xor_block(next_block, &blockR);
}
void fill_block_with_xor(const block *prev_block, const block *ref_block,
block *next_block) {
block blockR, block_tmp;
unsigned i;
copy_block(&blockR, ref_block);
xor_block(&blockR, prev_block);
copy_block(&block_tmp, &blockR);
xor_block(&block_tmp, next_block); /*Saving the next block contents for XOR over*/
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block*/
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
(16,17,..31)... finally (112,113,...127) */
for (i = 0; i < 8; ++i) {
BLAKE2_ROUND_NOMSG(
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
blockR.v[16 * i + 15]);
}
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
for (i = 0; i < 8; i++) {
BLAKE2_ROUND_NOMSG(
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
blockR.v[2 * i + 113]);
}
copy_block(next_block, &block_tmp);
xor_block(next_block, &blockR);
}
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands) {
block zero_block, input_block, address_block,tmp_block;
uint32_t i;
init_block_value(&zero_block, 0);
init_block_value(&input_block, 0);
if (instance != NULL && position != NULL) {
input_block.v[0] = position->pass;
input_block.v[1] = position->lane;
input_block.v[2] = position->slice;
input_block.v[3] = instance->memory_blocks;
input_block.v[4] = instance->passes;
input_block.v[5] = instance->type;
for (i = 0; i < instance->segment_length; ++i) {
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
input_block.v[6]++;
init_block_value(&tmp_block, 0);
init_block_value(&address_block, 0);
fill_block_with_xor(&zero_block, &input_block, &tmp_block);
fill_block_with_xor(&zero_block, &tmp_block, &address_block);
}
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
}
}
}
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL;
uint64_t pseudo_rand, ref_index, ref_lane;
uint32_t prev_offset, curr_offset;
uint32_t starting_index;
uint32_t i;
int data_independent_addressing;
/* Pseudo-random values that determine the reference block position */
uint64_t *pseudo_rands = NULL;
if (instance == NULL) {
return;
}
data_independent_addressing =
(instance->type == Argon2_i) ||
(instance->type == Argon2_id && (position.pass == 0) &&
(position.slice < ARGON2_SYNC_POINTS / 2));
pseudo_rands =
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
if (pseudo_rands == NULL) {
return;
}
if (data_independent_addressing) {
generate_addresses(instance, &position, pseudo_rands);
}
starting_index = 0;
if ((0 == position.pass) && (0 == position.slice)) {
starting_index = 2; /* we have already generated the first two blocks */
}
/* Offset of the current block */
curr_offset = position.lane * instance->lane_length +
position.slice * instance->segment_length + starting_index;
if (0 == curr_offset % instance->lane_length) {
/* Last block in this lane */
prev_offset = curr_offset + instance->lane_length - 1;
} else {
/* Previous block */
prev_offset = curr_offset - 1;
}
for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) {
/*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) {
prev_offset = curr_offset - 1;
}
/* 1.2 Computing the index of the reference block */
/* 1.2.1 Taking pseudo-random value from the previous block */
if (data_independent_addressing) {
pseudo_rand = pseudo_rands[i];
} else {
pseudo_rand = instance->memory[prev_offset].v[0];
}
/* 1.2.2 Computing the lane of the reference block */
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
if ((position.pass == 0) && (position.slice == 0)) {
/* Can not reference other lanes yet */
ref_lane = position.lane;
}
/* 1.2.3 Computing the number of possible reference block within the
* lane.
*/
position.index = i;
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
ref_lane == position.lane);
/* 2 Creating a new block */
ref_block =
instance->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->memory + curr_offset;
if (ARGON2_VERSION_10 == instance->version) {
/* version 1.2.1 and earlier: overwrite, not XOR */
fill_block(instance->memory + prev_offset, ref_block, curr_block);
} else {
if(0 == position.pass) {
fill_block(instance->memory + prev_offset, ref_block,
curr_block);
} else {
fill_block_with_xor(instance->memory + prev_offset, ref_block,
curr_block);
}
}
}
free(pseudo_rands);
}
-55
View File
@@ -1,55 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_REF_H
#define ARGON2_REF_H
#include "core.h"
/*
* Function fills a new memory block by XORing over @next_block. @next_block must be initialized
* @param prev_block Pointer to the previous block
* @param ref_block Pointer to the reference block
* @param next_block Pointer to the block to be constructed
* @pre all block pointers must be valid
*/
void fill_block_with_xor(const block *prev_block, const block *ref_block,
block *next_block);
/* LEGACY CODE: version 1.2.1 and earlier
* Function fills a new memory block by overwriting @next_block.
* @param prev_block Pointer to the previous block
* @param ref_block Pointer to the reference block
* @param next_block Pointer to the block to be constructed
* @pre all block pointers must be valid
*/
void fill_block(const block *prev_block, const block *ref_block,
block *next_block);
/*
* Generate pseudo-random values to reference blocks in the segment and puts
* them into the array
* @param instance Pointer to the current instance
* @param position Pointer to the current position
* @param pseudo_rands Pointer to the array of 64-bit values
* @pre pseudo_rands must point to @a instance->segment_length allocated values
*/
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands);
#endif /* ARGON2_REF_H */
-53
View File
@@ -1,53 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#include "thread.h"
#if defined(_WIN32)
#include <windows.h>
#endif
int argon2_thread_create(argon2_thread_handle_t *handle,
argon2_thread_func_t func, void *args) {
if (NULL == handle || func == NULL) {
return -1;
}
#if defined(_WIN32)
*handle = _beginthreadex(NULL, 0, func, args, 0, NULL);
return *handle != 0 ? 0 : -1;
#else
return pthread_create(handle, NULL, func, args);
#endif
}
int argon2_thread_join(argon2_thread_handle_t handle) {
#if defined(_WIN32)
if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) {
return CloseHandle((HANDLE)handle) != 0 ? 0 : -1;
}
return -1;
#else
return pthread_join(handle, NULL);
#endif
}
void argon2_thread_exit(void) {
#if defined(_WIN32)
_endthreadex(0);
#else
pthread_exit(NULL);
#endif
}
-63
View File
@@ -1,63 +0,0 @@
/*
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_THREAD_H
#define ARGON2_THREAD_H
/*
Here we implement an abstraction layer for the simpĺe requirements
of the Argon2 code. We only require 3 primitives---thread creation,
joining, and termination---so full emulation of the pthreads API
is unwarranted. Currently we wrap pthreads and Win32 threads.
The API defines 2 types: the function pointer type,
argon2_thread_func_t,
and the type of the thread handle---argon2_thread_handle_t.
*/
#if defined(_WIN32)
#include <process.h>
typedef unsigned(__stdcall *argon2_thread_func_t)(void *);
typedef uintptr_t argon2_thread_handle_t;
#else
#include <pthread.h>
typedef void *(*argon2_thread_func_t)(void *);
typedef pthread_t argon2_thread_handle_t;
#endif
/* Creates a thread
* @param handle pointer to a thread handle, which is the output of this
* function. Must not be NULL.
* @param func A function pointer for the thread's entry point. Must not be
* NULL.
* @param args Pointer that is passed as an argument to @func. May be NULL.
* @return 0 if @handle and @func are valid pointers and a thread is successfuly
* created.
*/
int argon2_thread_create(argon2_thread_handle_t *handle,
argon2_thread_func_t func, void *args);
/* Waits for a thread to terminate
* @param handle Handle to a thread created with argon2_thread_create.
* @return 0 if @handle is a valid handle, and joining completed successfully.
*/
int argon2_thread_join(argon2_thread_handle_t handle);
/* Terminate the current thread. Must be run inside a thread created by
* argon2_thread_create.
*/
void argon2_thread_exit(void);
#endif
+14 -1
View File
@@ -55,4 +55,17 @@ bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
};
}
}
std::string
NodeStats::toString() const
{
std::stringstream ss;
ss << "Known nodes: " << good_nodes << " good, " << dubious_nodes << " dubious, " << incoming_nodes << " incoming." << std::endl;
if (table_depth > 1) {
ss << "Routing table depth: " << table_depth << std::endl;
unsigned long tot_nodes = 8 * std::exp2(table_depth);
ss << "Network size estimation: " << tot_nodes << " nodes" << std::endl;
}
return ss.str();
}
}
+473 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "crypto.h"
@@ -27,7 +26,7 @@ extern "C" {
#include <nettle/gcm.h>
#include <nettle/aes.h>
#include "argon2/argon2.h"
#include <argon2.h>
}
#include <random>
@@ -184,7 +183,7 @@ Blob aesDecrypt(const Blob& data, const Blob& key)
Blob aesDecrypt(const Blob& data, const std::string& password)
{
if (data.size() <= PASSWORD_SALT_LENGTH)
throw DecryptError("Wrong data size");
throw DecryptError("Wrong data size");
Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH};
Blob key = stretchKey(password, salt, 256/8);
Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()};
@@ -208,7 +207,7 @@ Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
Blob hash(const Blob& data, size_t hash_len)
{
auto algo = gnutlsHashAlgo(hash_len);
auto algo = gnutlsHashAlgo(hash_len);
size_t res_size = gnutlsHashSize(algo);
Blob res;
res.resize(res_size);
@@ -239,7 +238,7 @@ PrivateKey::PrivateKey(const Blob& import, const std::string& password)
const gnutls_datum_t dt {(uint8_t*)import.data(), static_cast<unsigned>(import.size())};
const char* password_ptr = password.empty() ? nullptr : password.c_str();
int flags = password.empty() ? GNUTLS_PKCS_PLAIN
int flags = password.empty() ? GNUTLS_PKCS_PLAIN
: ( GNUTLS_PKCS_PBES2_AES_128 | GNUTLS_PKCS_PBES2_AES_192 | GNUTLS_PKCS_PBES2_AES_256
| GNUTLS_PKCS_PKCS12_3DES | GNUTLS_PKCS_PKCS12_ARCFOUR | GNUTLS_PKCS_PKCS12_RC2_40);
@@ -426,6 +425,22 @@ PublicKey::unpack(const uint8_t* data, size_t data_size)
throw CryptoException(std::string("Could not read public key: ") + gnutls_strerror(err));
}
std::string
PublicKey::toString() const
{
std::string ret;
size_t sz = ret.size();
int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_PEM, (void*)ret.data(), &sz);
if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
ret.resize(sz);
int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_PEM, (void*)ret.data(), &sz);
if (err != GNUTLS_E_SUCCESS)
throw CryptoException(std::string("Could not print public key: ") + gnutls_strerror(err));
} else if (err != GNUTLS_E_SUCCESS)
throw CryptoException(std::string("Could not print public key: ") + gnutls_strerror(err));
return ret;
}
void
PublicKey::msgpack_unpack(msgpack::object o)
{
@@ -510,13 +525,35 @@ PublicKey::encrypt(const Blob& data) const
InfoHash
PublicKey::getId() const
{
if (not pk)
return {};
InfoHash id;
size_t sz = id.size();
if (gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
return {};
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get public key ID: wrong output length.");
return id;
}
PkId
PublicKey::getLongId() const
{
if (not pk)
return {};
#if GNUTLS_VERSION_NUMBER < 0x030401
throw CryptoException("Can't get 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
#else
PkId h;
size_t sz = h.size();
if (auto err = gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz))
throw CryptoException(std::string("Can't get 256 bits public key ID: ") + gnutls_strerror(err));
if (sz != h.size())
throw CryptoException("Can't get 256 bits public key ID: wrong output length.");
return h;
#endif
}
Certificate::Certificate(const Blob& certData) : cert(nullptr)
{
unpack(certData.data(), certData.size());
@@ -616,11 +653,31 @@ Certificate::getId() const
return {};
InfoHash id;
size_t sz = id.size();
if (gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
throw CryptoException("Can't get certificate public key ID.");
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate public key ID: wrong output length.");
return id;
}
PkId
Certificate::getLongId() const
{
if (not cert)
return {};
#if GNUTLS_VERSION_NUMBER < 0x030401
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
#else
PkId id;
size_t sz = id.size();
if (auto err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz))
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
return id;
#endif
}
static std::string
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
{
@@ -631,7 +688,7 @@ getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
? gnutls_x509_crt_get_issuer_dn_by_oid(cert, oid, 0, 0, &(*dn.begin()), &dn_sz)
: gnutls_x509_crt_get_dn_by_oid( cert, oid, 0, 0, &(*dn.begin()), &dn_sz);
if (ret != GNUTLS_E_SUCCESS)
return {};
return {};
dn.resize(dn_sz);
return dn;
}
@@ -700,7 +757,20 @@ bool
Certificate::isCA() const
{
unsigned critical;
return gnutls_x509_crt_get_ca_status(cert, &critical) > 0;
bool ca_flag = gnutls_x509_crt_get_ca_status(cert, &critical) > 0;
if (ca_flag) {
unsigned usage;
auto ret = gnutls_x509_crt_get_key_usage(cert, &usage, &critical);
/* Conforming CAs MUST include this extension in certificates that
contain public keys that are used to validate digital signatures on
other public key certificates or CRLs. */
if (ret < 0)
return false;
if (not critical)
return true;
return usage & GNUTLS_KEY_KEY_CERT_SIGN;
}
return false;
}
std::string
@@ -725,6 +795,51 @@ Certificate::toString(bool chain) const
return ss.str();
}
std::string
Certificate::print() const
{
gnutls_datum_t out;
gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &out);
std::string ret(out.data, out.data+out.size);
gnutls_free(out.data);
return ret;
}
void
Certificate::revoke(const PrivateKey& key, const Certificate& to_revoke)
{
if (revocation_lists.empty())
revocation_lists.emplace(std::make_shared<RevocationList>());
auto& list = *(*revocation_lists.begin());
list.revoke(to_revoke);
list.sign(key, *this);
}
void
Certificate::addRevocationList(RevocationList&& list)
{
addRevocationList(std::make_shared<RevocationList>(std::forward<RevocationList>(list)));
}
void
Certificate::addRevocationList(std::shared_ptr<RevocationList> list)
{
if (revocation_lists.find(list) != revocation_lists.end())
return; // Already in the list
if (not list->isSignedBy(*this))
throw CryptoException("CRL is not signed by this certificate");
revocation_lists.emplace(std::move(list));
}
std::chrono::system_clock::time_point
Certificate::getExpiration() const
{
auto t = gnutls_x509_crt_get_expiration_time(cert);
if (t == (time_t)-1)
return std::chrono::system_clock::time_point::min();
return std::chrono::system_clock::from_time_t(t);
}
PrivateKey
PrivateKey::generate(unsigned key_length)
{
@@ -739,6 +854,20 @@ PrivateKey::generate(unsigned key_length)
return PrivateKey{key};
}
PrivateKey
PrivateKey::generateEC()
{
gnutls_x509_privkey_t key;
if (gnutls_x509_privkey_init(&key) != GNUTLS_E_SUCCESS)
throw CryptoException("Can't initialize private key.");
int err = gnutls_x509_privkey_generate(key, GNUTLS_PK_EC, gnutls_sec_param_to_pk_bits(GNUTLS_PK_EC, GNUTLS_SEC_PARAM_ULTRA), 0);
if (err != GNUTLS_E_SUCCESS) {
gnutls_x509_privkey_deinit(key);
throw CryptoException(std::string("Can't generate EC key pair: ") + gnutls_strerror(err));
}
return PrivateKey{key};
}
Identity
generateIdentity(const std::string& name, crypto::Identity ca, unsigned key_length, bool is_ca)
{
@@ -795,6 +924,10 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
gnutls_x509_crt_set_key_usage(cert, key_usage);
if (ca.first && ca.second) {
if (not ca.second->isCA()) {
// Signing certificate must be CA.
return {};
}
//if (gnutls_x509_crt_sign2(cert, ca.second->cert, ca.first->x509_key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
std::cerr << "Error when signing certificate" << std::endl;
@@ -809,8 +942,335 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
}
}
return ret.getPacked();
}
std::vector<std::shared_ptr<RevocationList>>
Certificate::getRevocationLists() const
{
std::vector<std::shared_ptr<RevocationList>> ret;
ret.reserve(revocation_lists.size());
for (const auto& crl : revocation_lists)
ret.emplace_back(crl);
return ret;
}
RevocationList::RevocationList()
{
gnutls_x509_crl_init(&crl);
}
RevocationList::RevocationList(const Blob& b)
{
gnutls_x509_crl_init(&crl);
try {
unpack(b.data(), b.size());
} catch (const std::exception& e) {
gnutls_x509_crl_deinit(crl);
crl = nullptr;
throw e;
}
}
RevocationList::~RevocationList()
{
if (crl) {
gnutls_x509_crl_deinit(crl);
crl = nullptr;
}
}
void
RevocationList::pack(Blob& b) const
{
gnutls_datum_t gdat {nullptr, 0};
if (auto err = gnutls_x509_crl_export2(crl, GNUTLS_X509_FMT_DER, &gdat)) {
throw CryptoException(std::string("Can't export CRL: ") + gnutls_strerror(err));
}
b.insert(b.end(), gdat.data, gdat.data + gdat.size);
gnutls_free(gdat.data);
}
void
RevocationList::unpack(const uint8_t* dat, size_t dat_size)
{
if (std::numeric_limits<unsigned>::max() < dat_size)
throw CryptoException("Can't load CRL: too large!");
const gnutls_datum_t gdat {(uint8_t*)dat, (unsigned)dat_size};
if (auto err_pem = gnutls_x509_crl_import(crl, &gdat, GNUTLS_X509_FMT_PEM))
if (auto err_der = gnutls_x509_crl_import(crl, &gdat, GNUTLS_X509_FMT_DER)) {
throw CryptoException(std::string("Can't load CRL: PEM: ") + gnutls_strerror(err_pem)
+ " DER: " + gnutls_strerror(err_der));
}
}
void
RevocationList::msgpack_unpack(msgpack::object o)
{
try {
if (o.type == msgpack::type::BIN)
unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
else {
Blob dat = unpackBlob(o);
unpack(dat.data(), dat.size());
}
} catch (...) {
throw msgpack::type_error();
}
}
bool
RevocationList::isRevoked(const Certificate& crt) const
{
auto ret = gnutls_x509_crt_check_revocation(crt.cert, &crl, 1);
if (ret < 0)
throw CryptoException(std::string("Can't check certificate revocation status: ") + gnutls_strerror(ret));
return ret != 0;
}
void
RevocationList::revoke(const Certificate& crt, std::chrono::system_clock::time_point t)
{
if (t == time_point::min())
t = clock::now();
if (auto err = gnutls_x509_crl_set_crt(crl, crt.cert, std::chrono::system_clock::to_time_t(t)))
throw CryptoException(std::string("Can't revoke certificate: ") + gnutls_strerror(err));
}
static std::string
getCRLIssuerDN(gnutls_x509_crl_t cert, const char* oid)
{
std::string dn;
dn.resize(512);
size_t dn_sz = dn.size();
int ret = gnutls_x509_crl_get_issuer_dn_by_oid(cert, oid, 0, 0, &(*dn.begin()), &dn_sz);
if (ret != GNUTLS_E_SUCCESS)
return {};
dn.resize(dn_sz);
return dn;
}
std::string
RevocationList::getIssuerName() const
{
return getCRLIssuerDN(crl, GNUTLS_OID_X520_COMMON_NAME);
}
/** Read CRL issuer User ID (UID) */
std::string
RevocationList::getIssuerUID() const
{
return getCRLIssuerDN(crl, GNUTLS_OID_LDAP_UID);
}
RevocationList::time_point
RevocationList::getNextUpdateTime() const
{
auto t = gnutls_x509_crl_get_next_update(crl);
if (t == (time_t)-1)
return std::chrono::system_clock::time_point::min();
return std::chrono::system_clock::from_time_t(t);
}
RevocationList::time_point
RevocationList::getUpdateTime() const
{
auto t = gnutls_x509_crl_get_this_update(crl);
if (t == (time_t)-1)
return std::chrono::system_clock::time_point::min();
return std::chrono::system_clock::from_time_t(t);
}
enum class Endian : uint32_t
{
LITTLE = 0,
BIG = 1
};
template <typename T>
T endian(T w, Endian endian = Endian::BIG)
{
// this gets optimized out into if (endian == host_endian) return w;
union { uint64_t quad; uint32_t islittle; } t;
t.quad = 1;
if (t.islittle ^ (uint32_t)endian) return w;
T r = 0;
// decent compilers will unroll this (gcc)
// or even convert straight into single bswap (clang)
for (size_t i = 0; i < sizeof(r); i++) {
r <<= 8;
r |= w & 0xff;
w >>= 8;
}
return r;
}
void
RevocationList::sign(const PrivateKey& key, const Certificate& ca, duration validity)
{
if (auto err = gnutls_x509_crl_set_version(crl, 2))
throw CryptoException(std::string("Can't set CRL version: ") + gnutls_strerror(err));
auto now = std::chrono::system_clock::now();
auto next_update = (validity == duration{}) ? ca.getExpiration() : now + validity;
if (auto err = gnutls_x509_crl_set_this_update(crl, std::chrono::system_clock::to_time_t(now)))
throw CryptoException(std::string("Can't set CRL update time: ") + gnutls_strerror(err));
if (auto err = gnutls_x509_crl_set_next_update(crl, std::chrono::system_clock::to_time_t(next_update)))
throw CryptoException(std::string("Can't set CRL next update time: ") + gnutls_strerror(err));
uint64_t number {0};
size_t number_sz {sizeof(number)};
unsigned critical {0};
gnutls_x509_crl_get_number(crl, &number, &number_sz, &critical);
if (number == 0) {
// initialize to a random number
number_sz = sizeof(number);
random_device rdev;
std::generate_n((uint8_t*)&number, sizeof(number), std::bind(rand_byte, std::ref(rdev)));
} else
number = endian(endian(number) + 1);
if (auto err = gnutls_x509_crl_set_number(crl, &number, sizeof(number)))
throw CryptoException(std::string("Can't set CRL update time: ") + gnutls_strerror(err));
if (auto err = gnutls_x509_crl_sign2(crl, ca.cert, key.x509_key, GNUTLS_DIG_SHA512, 0))
throw CryptoException(std::string("Can't sign certificate revocation list: ") + gnutls_strerror(err));
// to be able to actually use the CRL we need to serialize/deserialize it
auto packed = getPacked();
unpack(packed.data(), packed.size());
}
bool
RevocationList::isSignedBy(const Certificate& issuer) const
{
unsigned result {0};
auto err = gnutls_x509_crl_verify(crl, &issuer.cert, 1, 0, &result);
if (err < 0) {
//std::cout << "Can't verify CRL: " << err << " " << result << " " << gnutls_strerror(err) << std::endl;
return false;
}
return result == 0;
}
Blob
RevocationList::getNumber() const
{
Blob number(20);
size_t number_sz {number.size()};
unsigned critical {0};
gnutls_x509_crl_get_number(crl, number.data(), &number_sz, &critical);
if (number_sz != number.size())
number.resize(number_sz);
return number;
}
std::string
RevocationList::toString() const
{
gnutls_datum_t out;
gnutls_x509_crl_print(crl, GNUTLS_CRT_PRINT_FULL, &out);
std::string ret(out.data, out.data+out.size);
gnutls_free(out.data);
return ret;
}
TrustList::TrustList() {
gnutls_x509_trust_list_init(&trust, 0);
}
TrustList::~TrustList() {
gnutls_x509_trust_list_deinit(trust, 1);
}
TrustList&
TrustList::operator=(TrustList&& o)
{
if (trust)
gnutls_x509_trust_list_deinit(trust, true);
trust = std::move(o.trust);
o.trust = nullptr;
return *this;
}
void TrustList::add(const Certificate& crt)
{
auto chain = crt.getChainWithRevocations(true);
gnutls_x509_trust_list_add_cas(trust, chain.first.data(), chain.first.size(), GNUTLS_TL_NO_DUPLICATES);
if (not chain.second.empty())
gnutls_x509_trust_list_add_crls(
trust,
chain.second.data(), chain.second.size(),
GNUTLS_TL_VERIFY_CRL | GNUTLS_TL_NO_DUPLICATES, 0);
}
void TrustList::add(const RevocationList& crl)
{
auto copy = crl.getCopy();
gnutls_x509_trust_list_add_crls(trust, &copy, 1, GNUTLS_TL_VERIFY_CRL | GNUTLS_TL_NO_DUPLICATES, 0);
}
void TrustList::remove(const Certificate& crt, bool parents)
{
gnutls_x509_trust_list_remove_cas(trust, &crt.cert, 1);
if (parents) {
for (auto c = crt.issuer; c; c = c->issuer)
gnutls_x509_trust_list_remove_cas(trust, &c->cert, 1);
}
}
TrustList::VerifyResult
TrustList::verify(const Certificate& crt) const
{
auto chain = crt.getChain();
VerifyResult ret;
ret.ret = gnutls_x509_trust_list_verify_crt2(
trust,
chain.data(), chain.size(),
nullptr, 0,
GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM),
&ret.result, nullptr);
return ret;
}
std::string
TrustList::VerifyResult::toString() const
{
std::ostringstream ss;
ss << *this;
return ss.str();
}
std::ostream& operator<< (std::ostream& o, const TrustList::VerifyResult& h)
{
if (h.ret < 0) {
o << "Error verifying certificate: " << gnutls_strerror(h.ret) << std::endl;
} else if (h.result & GNUTLS_CERT_INVALID) {
o << "Certificate check failed with code: " << h.result << std::endl;
if (h.result & GNUTLS_CERT_SIGNATURE_FAILURE)
o << "* The signature verification failed." << std::endl;
if (h.result & GNUTLS_CERT_REVOKED)
o << "* Certificate is revoked" << std::endl;
if (h.result & GNUTLS_CERT_SIGNER_NOT_FOUND)
o << "* Certificate's issuer is not known" << std::endl;
if (h.result & GNUTLS_CERT_SIGNER_NOT_CA)
o << "* Certificate's issuer not a CA" << std::endl;
if (h.result & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
o << "* Certificate's signer constraints were violated" << std::endl;
if (h.result & GNUTLS_CERT_INSECURE_ALGORITHM)
o << "* Certificate was signed using an insecure algorithm" << std::endl;
if (h.result & GNUTLS_CERT_NOT_ACTIVATED)
o << "* Certificate is not yet activated" << std::endl;
if (h.result & GNUTLS_CERT_EXPIRED)
o << "* Certificate has expired" << std::endl;
if (h.result & GNUTLS_CERT_UNEXPECTED_OWNER)
o << "* The owner is not the expected one" << std::endl;
if (h.result & GNUTLS_CERT_PURPOSE_MISMATCH)
o << "* Certificate or an intermediate does not match the intended purpose" << std::endl;
if (h.result & GNUTLS_CERT_MISMATCH)
o << "* Certificate presented isn't the expected one" << std::endl;
} else {
o << "Certificate is valid" << std::endl;
}
return o;
}
}
}
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "default_types.h"
+581 -398
View File
File diff suppressed because it is too large. Load diff
+34 -9
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "dhtrunner.h"
@@ -233,11 +232,27 @@ DhtRunner::importValues(const std::vector<ValuesExport>& values) {
dht_->importValues(values);
}
int
unsigned
DhtRunner::getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const
{
std::lock_guard<std::mutex> lck(dht_mtx);
return dht_->getNodesStats(af, good_return, dubious_return, cached_return, incoming_return);
const auto stats = dht_->getNodesStats(af);
if (good_return)
*good_return = stats.good_nodes;
if (dubious_return)
*dubious_return = stats.dubious_nodes;
if (cached_return)
*cached_return = stats.cached_nodes;
if (incoming_return)
*incoming_return = stats.incoming_nodes;
return stats.good_nodes + stats.dubious_nodes;
}
NodeStats
DhtRunner::getNodesStats(sa_family_t af) const
{
std::lock_guard<std::mutex> lck(dht_mtx);
return dht_->getNodesStats(af);
}
std::vector<unsigned>
@@ -348,7 +363,7 @@ DhtRunner::loop_()
// We have lost connection with the DHT. Try to recover using bootstrap nodes.
std::unique_lock<std::mutex> lck(bootstrap_mtx);
bootstrap_nodes = bootstrap_nodes_all;
tryBootstrapCoutinuously();
tryBootstrapContinuously();
} else {
std::unique_lock<std::mutex> lck(bootstrap_mtx);
bootstrap_nodes.clear();
@@ -618,7 +633,7 @@ DhtRunner::putEncrypted(const std::string& key, InfoHash to, Value&& value, Done
}
void
DhtRunner::tryBootstrapCoutinuously()
DhtRunner::tryBootstrapContinuously()
{
if (bootstrap_thread.joinable()) {
if (bootstraping)
@@ -707,7 +722,7 @@ DhtRunner::bootstrap(const std::string& host, const std::string& service)
std::lock_guard<std::mutex> lck(bootstrap_mtx);
bootstrap_nodes_all.emplace_back(host, service);
bootstrap_nodes.emplace_back(host, service);
tryBootstrapCoutinuously();
tryBootstrapContinuously();
}
void
@@ -735,6 +750,16 @@ DhtRunner::bootstrap(const std::vector<std::pair<sockaddr_storage, socklen_t>>&
cv.notify_all();
}
void
DhtRunner::bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb)
{
std::lock_guard<std::mutex> lck(storage_mtx);
pending_ops_prio.emplace([addr,cb](SecureDht& dht) mutable {
dht.pingNode((const sockaddr*)&addr.first, addr.second, std::move(cb));
});
cv.notify_all();
}
void
DhtRunner::bootstrap(const std::vector<NodeExport>& nodes)
{
+54 -34
View File
@@ -1,3 +1,23 @@
/*
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Nicolas Reynaud <nicolas.reynaud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "indexation/pht.h"
#include "rng.h"
@@ -276,7 +296,7 @@ void Pht::lookup(Key k, Pht::LookupCallback cb, DoneCallbackSimple done_cb, bool
std::shared_ptr<unsigned> max_common_prefix_len = not exact_match ? std::make_shared<unsigned>(0) : nullptr;
lookupStep(prefix, lo, hi, values,
[=](std::vector<std::shared_ptr<IndexEntry>>& entries, Prefix p) {
[=](std::vector<std::shared_ptr<IndexEntry>>& entries, const Prefix& p) {
std::vector<std::shared_ptr<Value>> vals(entries.size());
std::transform(entries.begin(), entries.end(), vals.begin(),
@@ -309,7 +329,7 @@ void Pht::updateCanary(Prefix p) {
}
}
void Pht::insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
void Pht::insert(const Prefix& kp, IndexEntry entry, std::shared_ptr<int> lo, std::shared_ptr<int> hi, time_point time_p,
bool check_split, DoneCallbackSimple done_cb) {
if (time_p + ValueType::USER_DATA.expiration < clock::now()) return;
@@ -327,26 +347,25 @@ void Pht::insert(Prefix kp, IndexEntry entry, std::shared_ptr<int> lo, std::shar
done_cb(false);
} else {
RealInsertCallback real_insert = [=]( std::shared_ptr<Prefix> p, IndexEntry entry) {
updateCanary(*p);
checkPhtUpdate(*p, entry, time_p);
cache_.insert(*p);
dht_->put(p->hash(), std::move(entry), done_cb , time_p);
RealInsertCallback real_insert = [=](const Prefix& p, IndexEntry entry) {
updateCanary(p);
checkPhtUpdate(p, entry, time_p);
cache_.insert(p);
dht_->put(p.hash(), std::move(entry), done_cb , time_p);
};
if ( not check_split or final_prefix->size_ == kp.size_ ) {
real_insert(final_prefix, std::move(entry));
real_insert(*final_prefix, std::move(entry));
} else {
if ( vals->size() < MAX_NODE_ENTRY_COUNT ) {
getRealPrefix(final_prefix, std::move(entry), real_insert);
}
else {
split(*final_prefix, vals, entry, real_insert);
split(*final_prefix, *vals, entry, real_insert);
}
}
}
}, nullptr, cache_.lookup(kp), true
);
}, nullptr, cache_.lookup(kp), true);
}
Prefix Pht::zcurve(const std::vector<Prefix>& all_prefix) const {
@@ -420,43 +439,44 @@ Prefix Pht::linearize(Key k) const {
return zcurve(all_prefix);
}
void Pht::getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertCallback end_cb ) {
void Pht::getRealPrefix(const std::shared_ptr<Prefix>& p, IndexEntry entry, RealInsertCallback end_cb )
{
if ( p->size_ == 0 ) {
end_cb(p, std::move(entry));
end_cb(*p, std::move(entry));
return;
}
auto total = std::make_shared<unsigned int>(0); /* Will contains the total number of data on 3 nodes */
auto ended = std::make_shared<unsigned int>(0); /* Just indicate how many have end */
auto parent = std::make_shared<Prefix>(p->getPrefix(-1));
auto sibling = std::make_shared<Prefix>(p->getSibling());
struct OpState {
unsigned entry_count {0}; /* Total number of data on 3 nodes */
unsigned ended {0}; /* How many ops have ended */
Prefix parent;
OpState(Prefix p) : parent(p) {}
};
auto op_state = std::make_shared<OpState>(p->getPrefix(-1));
auto pht_filter = [&](const dht::Value& v) {
return v.user_type.compare(0, name_.size(), name_) == 0;
};
/* Lambda will count total number of data node */
auto count = [=]( const std::shared_ptr<dht::Value> value ) {
if ( value->user_type != canary_)
(*total)++;
auto count = [=]( const std::shared_ptr<dht::Value>& value ) {
if (value->user_type != canary_)
op_state->entry_count++;
return true;
};
auto on_done = [=] ( bool ) {
(*ended)++;
op_state->ended++;
/* Only the last one do the CallBack*/
if ( *ended == 3 ) {
if ( *total < MAX_NODE_ENTRY_COUNT )
end_cb(parent, std::move(entry));
if (op_state->ended == 3) {
if (op_state->entry_count < MAX_NODE_ENTRY_COUNT)
end_cb(op_state->parent, std::move(entry));
else
end_cb(p, std::move(entry));
end_cb(*p, std::move(entry));
}
};
dht_->get(parent->hash(),
dht_->get(op_state->parent.hash(),
count,
on_done,
pht_filter
@@ -468,7 +488,7 @@ void Pht::getRealPrefix(std::shared_ptr<Prefix> p, IndexEntry entry, RealInsertC
pht_filter
);
dht_->get(sibling->hash(),
dht_->get(p->getSibling().hash(),
count,
on_done,
pht_filter
@@ -500,11 +520,11 @@ void Pht::checkPhtUpdate(Prefix p, IndexEntry entry, time_point time_p) {
);
}
void Pht::split(Prefix insert, std::shared_ptr<std::vector<std::shared_ptr<IndexEntry>>> vals, IndexEntry entry, RealInsertCallback end_cb ) {
auto full = Prefix(entry.prefix);
void Pht::split(const Prefix& insert, const std::vector<std::shared_ptr<IndexEntry>>& vals, IndexEntry entry, RealInsertCallback end_cb ) {
const auto full = Prefix(entry.prefix);
auto loc = foundSplitLocation(full, vals);
auto prefix_to_insert = std::make_shared<Prefix>(full.getPrefix(loc));
auto loc = findSplitLocation(full, vals);
const auto prefix_to_insert = full.getPrefix(loc);
for(;loc != insert.size_ - 1; loc--) {
updateCanary(full.getPrefix(loc));
+34 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "infohash.h"
@@ -57,7 +56,7 @@ InfoHash::get(const uint8_t* data, size_t data_len)
int rc = gnutls_fingerprint(algo, &gnudata, h.data(), &s);
if (rc == 0 && s == HASH_LEN)
return h;
throw std::string("Error while hashing");
throw std::runtime_error(std::string("Error hashing: ") + gnutls_strerror(rc));
}
InfoHash
@@ -65,29 +64,47 @@ InfoHash::getRandom()
{
InfoHash h;
crypto::random_device rdev;
#ifdef _WIN32
static std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
#else
static std::uniform_int_distribution<uint8_t> rand_byte;
#endif
std::generate(h.begin(), h.end(), std::bind(rand_byte, std::ref(rdev)));
std::uniform_int_distribution<uint32_t> rand_int;
auto a = reinterpret_cast<uint32_t*>(&(*h.begin()));
auto b = reinterpret_cast<uint32_t*>(&(*h.end()));
std::generate(a, b, std::bind(rand_int, std::ref(rdev)));
return h;
}
struct HexMap : public std::array<std::array<char, 2>, 256> {
HexMap() {
for (size_t i=0; i<size(); i++) {
auto& e = (*this)[i];
e[0] = hex_digits[(i >> 4) & 0x0F];
e[1] = hex_digits[i & 0x0F];
}
}
private:
static constexpr const char* hex_digits = "0123456789abcdef";
};
const char*
InfoHash::to_c_str() const
{
static const HexMap map;
thread_local std::array<char, HASH_LEN*2+1> buf;
for (size_t i=0; i<HASH_LEN; i++) {
auto b = buf.data()+i*2;
const auto& m = map[(*this)[i]];
*((uint16_t*)b) = *((uint16_t*)&m);
}
return buf.data();
}
std::string
InfoHash::toString() const
{
std::stringstream ss;
ss << *this;
return ss.str();
return std::string(to_c_str(), HASH_LEN*2);
}
std::ostream& operator<< (std::ostream& s, const InfoHash& h)
{
s << std::hex;
for (unsigned i=0; i<HASH_LEN; i++)
s << std::setfill('0') << std::setw(2) << (unsigned)h[i];
s << std::dec;
s.write(h.to_c_str(), HASH_LEN*2);
return s;
}
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "log.h"
namespace dht {
namespace log {
/**
* Print va_list to std::ostream (used for logging).
*/
void
printLog(std::ostream& s, char const *m, va_list args) {
// print log to buffer
std::array<char, 8192> buffer;
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
if (ret < 0)
return;
// write timestamp
using namespace std::chrono;
using log_precision = microseconds;
constexpr auto den = log_precision::period::den;
auto micro = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
s << "[" << std::setfill('0') << std::setw(6) << micro / den << "."
<< std::setfill('0') << std::setw(6) << micro % den << "]" << " ";
// write log
s.write(buffer.data(), std::min((size_t) ret, buffer.size()));
if ((size_t) ret >= buffer.size())
s << "[[TRUNCATED]]";
s << std::endl;
}
void
enableLogging(dht::DhtRunner &dht) {
dht.setLoggers(
[](char const *m, va_list args) {
std::cerr << red;
printLog(std::cerr, m, args);
std::cerr << def;
},
[](char const *m, va_list args) {
std::cout << yellow;
printLog(std::cout, m, args);
std::cout << def;
},
[](char const *m, va_list args) { printLog(std::cout, m, args); }
);
}
void
enableFileLogging(dht::DhtRunner &dht, const std::string &path) {
auto logfile = std::make_shared<std::fstream>();
logfile->open(path, std::ios::out);
dht.setLoggers(
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
[=](char const *m, va_list args) { printLog(*logfile, m, args); }
);
}
void
disableLogging(dht::DhtRunner &dht) {
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
}
}
}
+218 -145
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2014-2016 Savoir-faire Linux Inc.
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <sim.desaulniers@gmail.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -26,6 +26,7 @@
#include <msgpack.hpp>
namespace dht {
namespace net {
const std::string DhtProtocolException::GET_NO_INFOHASH {"Get_values with no info_hash"};
const std::string DhtProtocolException::LISTEN_NO_INFOHASH {"Listen with no info_hash"};
@@ -40,15 +41,15 @@ constexpr std::chrono::seconds NetworkEngine::RX_MAX_PACKET_TIME;
constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
const std::string NetworkEngine::my_v {"RNG1"};
const constexpr uint16_t NetworkEngine::TransId::INVALID;
const constexpr uint16_t TransId::INVALID;
std::mt19937 NetworkEngine::rd_device {dht::crypto::random_device{}()};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::PING = {"pn"};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::FIND_NODE = {"fn"};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::GET_VALUES = {"gt"};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::ANNOUNCE_VALUES = {"pt"};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::REFRESH = {"rf"};
const NetworkEngine::TransPrefix NetworkEngine::TransPrefix::LISTEN = {"lt"};
const TransPrefix TransPrefix::PING = {"pn"};
const TransPrefix TransPrefix::FIND_NODE = {"fn"};
const TransPrefix TransPrefix::GET_VALUES = {"gt"};
const TransPrefix TransPrefix::ANNOUNCE_VALUES = {"pt"};
const TransPrefix TransPrefix::REFRESH = {"rf"};
const TransPrefix TransPrefix::LISTEN = {"lt"};
constexpr long unsigned NetworkEngine::MAX_REQUESTS_PER_SEC;
static const uint8_t v4prefix[16] = {
@@ -80,7 +81,9 @@ struct ParsedMessage {
/* target id around which to find nodes */
InfoHash target;
/* transaction id */
NetworkEngine::TransId tid;
TransId tid;
/* tid for packets going through request socket */
TransId socket_id;
/* security token */
Blob token;
/* the value id (announce confirmation) */
@@ -89,11 +92,11 @@ struct ParsedMessage {
time_point created { time_point::max() };
/* IPv4 nodes in response to a 'find' request */
Blob nodes4_raw, nodes6_raw;
std::vector<std::shared_ptr<Node>> nodes4, nodes6;
std::vector<Sp<Node>> nodes4, nodes6;
/* values to store or retreive request */
std::vector<std::shared_ptr<Value>> values;
std::vector<Sp<Value>> values;
/* index for fields values */
std::vector<std::shared_ptr<FieldValueIndex>> fields;
std::vector<Sp<FieldValueIndex>> fields;
/** When part of the message header: {index -> (total size, {})}
* When part of partial value data: {index -> (offset, part_data)} */
std::map<unsigned, std::pair<unsigned, Blob>> value_parts;
@@ -120,7 +123,7 @@ struct NetworkEngine::PartialMessage {
};
std::vector<Blob>
serializeValues(const std::vector<std::shared_ptr<Value>>& st)
serializeValues(const std::vector<Sp<Value>>& st)
{
std::vector<Blob> svals;
svals.reserve(st.size());
@@ -156,15 +159,14 @@ NetworkEngine::~NetworkEngine() {
}
void
NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, const InfoHash& hash, want_t want,
const Blob& ntoken, std::vector<std::shared_ptr<Node>>&& nodes,
std::vector<std::shared_ptr<Node>>&& nodes6, std::vector<std::shared_ptr<Value>>&& values,
NetworkEngine::tellListener(Sp<Node> node, uint32_t socket_id, const InfoHash& hash, want_t want,
const Blob& ntoken, std::vector<Sp<Node>>&& nodes,
std::vector<Sp<Node>>&& nodes6, std::vector<Sp<Value>>&& values,
const Query& query)
{
auto nnodes = bufferNodes(node->getFamily(), hash, want, nodes, nodes6);
try {
sendNodesValues(node->addr, TransId {TransPrefix::GET_VALUES, (uint16_t)rid}, nnodes.first, nnodes.second,
values, query, ntoken);
sendNodesValues(node->addr, TransId((char*)&socket_id, 4), nnodes.first, nnodes.second, values, query, ntoken);
} catch (const std::overflow_error& e) {
DHT_LOG.e("Can't send value: buffer not large enough !");
}
@@ -185,11 +187,29 @@ NetworkEngine::isRunning(sa_family_t af) const
}
}
Sp<Socket>
NetworkEngine::openSocket(const Sp<Node>& node, TransPrefix tp, SocketCb&& cb)
{
auto tid = TransId {tp, getNewTid()};
auto s = opened_sockets.emplace(tid, std::make_shared<Socket>(node, tid, cb));
if (not s.second)
DHT_LOG.e(node->id, "[node %s] socket (tid: %d) already opened!", node->id.toString().c_str(), tid.toInt());
return s.first->second;
}
void
NetworkEngine::cancelRequest(std::shared_ptr<Request>& req)
NetworkEngine::closeSocket(Sp<Socket> socket)
{
if (socket)
opened_sockets.erase(socket->id);
}
void
NetworkEngine::cancelRequest(Sp<Request>& req)
{
if (req) {
req->cancel();
closeSocket(req->socket);
requests.erase(req->tid);
}
}
@@ -209,7 +229,7 @@ NetworkEngine::connectivityChanged(sa_family_t af)
}
void
NetworkEngine::requestStep(std::shared_ptr<Request> sreq)
NetworkEngine::requestStep(Sp<Request> sreq)
{
auto& req = *sreq;
if (not req.pending()) {
@@ -246,7 +266,7 @@ NetworkEngine::requestStep(std::shared_ptr<Request> sreq)
* be made before the request expires.
*/
void
NetworkEngine::sendRequest(std::shared_ptr<Request>& request)
NetworkEngine::sendRequest(Sp<Request>& request)
{
request->start = scheduler.time();
auto e = requests.emplace(request->tid, request);
@@ -255,7 +275,7 @@ NetworkEngine::sendRequest(std::shared_ptr<Request>& request)
// Try to handle this scenario as well as we can
e.first->second->setExpired();
e.first->second = request;
DHT_LOG.e(request->node->id, "Request already existed (tid: %d)!", request->tid);
DHT_LOG.e(request->node->id, "Request already existed (tid: %d)!", request->tid.getTid());
}
request->node->requested(request);
requestStep(request);
@@ -287,32 +307,25 @@ NetworkEngine::rateLimit(const SockAddr& addr)
bool
NetworkEngine::isMartian(const SockAddr& addr)
{
// Check that sa_family can be accessed safely
if (addr.second < sizeof(sockaddr_in))
if (addr.getPort() == 0)
return true;
switch(addr.first.ss_family) {
switch(addr.getFamily()) {
case AF_INET: {
sockaddr_in *sin = (sockaddr_in*)&addr.first;
const uint8_t *address = (const uint8_t*)&sin->sin_addr;
return sin->sin_port == 0 ||
(address[0] == 0) ||
(address[0] == 127) ||
((address[0] & 0xE0) == 0xE0);
const auto& sin = addr.getIPv4();
const uint8_t* address = (const uint8_t*)&sin.sin_addr;
return (address[0] == 0) ||
((address[0] & 0xE0) == 0xE0);
}
case AF_INET6: {
if (addr.second < sizeof(sockaddr_in6))
return true;
sockaddr_in6 *sin6 = (sockaddr_in6*)&addr.first;
const uint8_t *address = (const uint8_t*)&sin6->sin6_addr;
return sin6->sin6_port == 0 ||
(address[0] == 0xFF) ||
(address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
(memcmp(address, zeroes.data(), 15) == 0 &&
(address[15] == 0 || address[15] == 1)) ||
(memcmp(address, v4prefix, 12) == 0);
const auto& sin6 = addr.getIPv6();
const uint8_t* address = (const uint8_t*)&sin6.sin6_addr;
return address[0] == 0xFF ||
(address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
memcmp(address, zeroes.data(), 16) == 0 ||
memcmp(address, v4prefix, 12) == 0;
}
default:
return true;
}
@@ -321,7 +334,7 @@ NetworkEngine::isMartian(const SockAddr& addr)
/* The internal blacklist is an LRU cache of nodes that have sent
incorrect messages. */
void
NetworkEngine::blacklistNode(const std::shared_ptr<Node>& n)
NetworkEngine::blacklistNode(const Sp<Node>& n)
{
n->setExpired();
for (auto rit = requests.begin(); rit != requests.end();) {
@@ -435,19 +448,22 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
const auto& now = scheduler.time();
if (msg->type == MessageType::Error or msg->type == MessageType::Reply) {
auto reqp = requests.find(msg->tid.getTid());
if (reqp == requests.end()) {
/* either response for a request or data for an opened socket */
auto req_it = requests.find(msg->tid);
auto rsocket_it = opened_sockets.end();
if (req_it == requests.end())
rsocket_it = opened_sockets.find(msg->tid);
if (req_it == requests.end() and rsocket_it == opened_sockets.end())
throw DhtProtocolException {DhtProtocolException::UNKNOWN_TID, "Can't find transaction", msg->id};
}
auto req = reqp->second;
auto node = req->node;
auto req = req_it != requests.end() ? req_it->second : nullptr;
auto rsocket = rsocket_it != opened_sockets.end() ? rsocket_it->second : nullptr;
auto& node = req ? req->node : rsocket->node;
if (node->id != msg->id) {
bool unknown_node = node->id == zeroes;
node = cache.getNode(msg->id, from, now, true);
if (unknown_node) {
// received reply to a message sent when we didn't know the node ID.
req->node = node;
} else {
if (node->id == zeroes) // received reply to a message sent when we didn't know the node ID.
node = cache.getNode(msg->id, from, now, true);
else {
// received reply from unexpected node
node->received(now, req);
onNewNode(node, 2);
@@ -456,14 +472,15 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
}
} else
node->update(from);
node->received(now, req);
onNewNode(node, 2);
onReportedAddr(msg->id, msg->addr);
if (req->cancelled() or req->expired() or (req->completed() and not req->persistent)) {
if (req and (req->cancelled() or req->expired() or req->completed())) {
DHT_LOG.w(node->id, "[node %s] response to expired, cancelled or completed request", node->toString().c_str());
requests.erase(reqp);
requests.erase(req_it);
return;
}
@@ -474,8 +491,8 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
(msg->error_code == DhtProtocolException::UNAUTHORIZED and (msg->tid.matches(TransPrefix::ANNOUNCE_VALUES)
or msg->tid.matches(TransPrefix::LISTEN)))))
{
req->last_try = TIME_INVALID;
req->reply_time = TIME_INVALID;
req->last_try = time_point::min();
req->reply_time = time_point::min();
onError(req, DhtProtocolException {msg->error_code});
} else {
DHT_LOG.w(msg->id, "[node %s %s] received unknown error message %u",
@@ -484,17 +501,21 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
break;
}
case MessageType::Reply:
if (msg->type == MessageType::AnnounceValue or msg->type == MessageType::Listen)
req->node->authSuccess();
if (req) { /* request reply */
if (msg->type == MessageType::AnnounceValue or msg->type == MessageType::Listen)
req->node->authSuccess();
// erase before calling callback to make sure iterator is still valid
if (not req->persistent)
requests.erase(reqp);
req->reply_time = scheduler.time();
// erase before calling callback to make sure iterator is still valid
requests.erase(req_it);
req->reply_time = scheduler.time();
deserializeNodes(*msg);
req->setDone(std::move(*msg));
break;
deserializeNodes(*msg, from);
req->setDone(std::move(*msg));
break;
} else { /* request socket data */
deserializeNodes(*msg, from);
rsocket->on_receive(rsocket->node, std::move(*msg));
}
default:
break;
}
@@ -548,7 +569,9 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
case MessageType::Listen: {
DHT_LOG.d(msg->info_hash, node->id, "[node %s] got 'listen' request for %s", node->toString().c_str(), msg->info_hash.toString().c_str());
++in_stats.listen;
RequestAnswer answer = onListen(node, msg->info_hash, msg->token, msg->tid.getTid(), std::move(msg->query));
/* TODO: backward compatibility check to remove in a few versions (see ::sendListen doc) */
auto socket_id = msg->socket_id.getTid() ? msg->socket_id : TransId { TransPrefix::GET_VALUES, msg->tid.getTid() };
RequestAnswer answer = onListen(node, msg->info_hash, msg->token, socket_id.toInt(), std::move(msg->query));
sendListenConfirmation(from, msg->tid);
break;
}
@@ -564,7 +587,7 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
}
void
packToken(msgpack::packer<msgpack::sbuffer>& pk, Blob token)
packToken(msgpack::packer<msgpack::sbuffer>& pk, const Blob& token)
{
pk.pack_bin(token.size());
pk.pack_bin_body((char*)token.data(), token.size());
@@ -582,11 +605,11 @@ insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const SockAddr& addr)
pk.pack_bin_body((char*)addr_ptr, addr_len);
}
int
void
NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr)
{
if (addr.second == 0)
return -1;
return;
int s;
if (addr.getFamily() == AF_INET)
@@ -597,12 +620,13 @@ NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr
s = -1;
if (s < 0)
return -1;
return sendto(s, buf, len, flags, (const sockaddr*)&addr.first, addr.second);
return;
if (sendto(s, buf, len, flags, (const sockaddr*)&addr.first, addr.second) == -1)
DHT_LOG.e("Can't send message to %s: %s", addr.toString().c_str(), strerror(errno));
}
std::shared_ptr<Request>
NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestExpiredCb on_expired) {
Sp<Request>
NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
auto tid = TransId {TransPrefix::PING, getNewTid()};
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -620,8 +644,8 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), node, std::move(b),
auto req = std::make_shared<Request>(tid, node,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&&) {
DHT_LOG.d(req_status.node->id, "[node %s] got pong !", req_status.node->toString().c_str());
if (on_done) {
@@ -633,7 +657,7 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
on_expired(req_status, done);
}
}
});
);
sendRequest(req);
++out_stats.ping;
return req;
@@ -660,9 +684,9 @@ NetworkEngine::sendPong(const SockAddr& addr, TransId tid) {
send(buffer.data(), buffer.size(), 0, addr);
}
std::shared_ptr<Request>
NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, want_t want,
RequestCb on_done, RequestExpiredCb on_expired) {
Sp<Request>
NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
RequestCb&& on_done, RequestExpiredCb&& on_expired) {
auto tid = TransId {TransPrefix::FIND_NODE, getNewTid()};
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -687,8 +711,8 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
auto req = std::make_shared<Request>(tid, n,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
if (on_done) {
on_done(req_status, {std::forward<ParsedMessage>(msg)});
@@ -699,16 +723,16 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
on_expired(req_status, done);
}
}
});
);
sendRequest(req);
++out_stats.find;
return req;
}
std::shared_ptr<Request>
NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash, const Query& query, want_t want,
RequestCb on_done, RequestExpiredCb on_expired) {
Sp<Request>
NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query& query, want_t want,
RequestCb&& on_done, RequestExpiredCb&& on_expired) {
auto tid = TransId {TransPrefix::GET_VALUES, getNewTid()};
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
@@ -736,8 +760,8 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
auto req = std::make_shared<Request>(tid, n,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
if (on_done) {
on_done(req_status, {std::forward<ParsedMessage>(msg)});
@@ -748,31 +772,49 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
on_expired(req_status, done);
}
}
});
);
sendRequest(req);
++out_stats.get;
return req;
}
SockAddr deserializeIPv4(const uint8_t* ni) {
SockAddr addr;
auto& sin = addr.getIPv4();
std::fill_n((uint8_t*)&sin, sizeof(sockaddr_in), 0);
addr.setFamily(AF_INET);
memcpy(&sin.sin_addr, ni, 4);
memcpy(&sin.sin_port, ni + 4, 2);
return addr;
}
SockAddr deserializeIPv6(const uint8_t* ni) {
SockAddr addr;
auto& sin6 = addr.getIPv6();
std::fill_n((uint8_t*)&sin6, sizeof(sockaddr_in6), 0);
addr.setFamily(AF_INET6);
memcpy(&sin6.sin6_addr, ni, 16);
memcpy(&sin6.sin6_port, ni + 16, 2);
return addr;
}
void
NetworkEngine::deserializeNodes(ParsedMessage& msg) {
NetworkEngine::deserializeNodes(ParsedMessage& msg, const SockAddr& from) {
if (msg.nodes4_raw.size() % NODE4_INFO_BUF_LEN != 0 || msg.nodes6_raw.size() % NODE6_INFO_BUF_LEN != 0) {
throw DhtProtocolException {DhtProtocolException::WRONG_NODE_INFO_BUF_LEN};
} else {
// deserialize nodes
const auto& now = scheduler.time();
SockAddr addr;
for (unsigned i = 0; i < msg.nodes4_raw.size() / NODE4_INFO_BUF_LEN; i++) {
uint8_t *ni = msg.nodes4_raw.data() + i * NODE4_INFO_BUF_LEN;
const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni);
if (ni_id == myid)
continue;
auto sin = (sockaddr_in*)&addr.first;
std::fill_n((uint8_t*)sin, sizeof(sockaddr_in), 0);
sin->sin_family = AF_INET;
memcpy(&sin->sin_addr, ni + ni_id.size(), 4);
memcpy(&sin->sin_port, ni + ni_id.size() + 4, 2);
addr.second = sizeof(sockaddr_in);
SockAddr addr = deserializeIPv4(ni + ni_id.size());
if (addr.isLoopback() and from.getFamily() == AF_INET) {
auto port = addr.getPort();
addr = from;
addr.setPort(port);
}
if (isMartian(addr) || isNodeBlacklisted(addr))
continue;
msg.nodes4.emplace_back(cache.getNode(ni_id, addr, now, false));
@@ -783,12 +825,12 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) {
const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni);
if (ni_id == myid)
continue;
auto sin6 = (sockaddr_in6*)&addr.first;
std::fill_n((uint8_t*)sin6, sizeof(sockaddr_in6), 0);
sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, ni + HASH_LEN, 16);
memcpy(&sin6->sin6_port, ni + HASH_LEN + 16, 2);
addr.second = sizeof(sockaddr_in6);
SockAddr addr = deserializeIPv6(ni + ni_id.size());
if (addr.isLoopback() and from.getFamily() == AF_INET6) {
auto port = addr.getPort();
addr = from;
addr.setPort(port);
}
if (isMartian(addr) || isNodeBlacklisted(addr))
continue;
msg.nodes6.emplace_back(cache.getNode(ni_id, addr, now, false));
@@ -798,7 +840,7 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) {
}
std::vector<Blob>
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<std::shared_ptr<Value>>& st)
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<Sp<Value>>& st)
{
auto svals = serializeValues(st);
size_t total_size = 0;
@@ -853,7 +895,8 @@ NetworkEngine::sendValueParts(TransId tid, const std::vector<Blob>& svals, const
void
NetworkEngine::sendNodesValues(const SockAddr& addr, TransId tid, const Blob& nodes, const Blob& nodes6,
const std::vector<std::shared_ptr<Value>>& st, const Query& query, const Blob& token) {
const std::vector<Sp<Value>>& st, const Query& query, const Blob& token)
{
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack_map(4+(network?1:0));
@@ -909,34 +952,32 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, TransId tid, const Blob& no
}
Blob
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes)
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<Sp<Node>>& nodes)
{
std::sort(nodes.begin(), nodes.end(), [&](const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b){
std::sort(nodes.begin(), nodes.end(), [&](const Sp<Node>& a, const Sp<Node>& b){
return id.xorCmp(a->id, b->id) < 0;
});
size_t nnode = std::min<size_t>(SEND_NODES, nodes.size());
Blob bnodes;
if (af == AF_INET) {
bnodes.resize(NODE4_INFO_BUF_LEN * nnode);
const constexpr size_t size = HASH_LEN + sizeof(in_addr) + sizeof(in_port_t); // 26
for (size_t i=0; i<nnode; i++) {
const Node& n = *nodes[i];
sockaddr_in *sin = (sockaddr_in*)&n.addr.first;
auto dest = bnodes.data() + size * i;
auto dest = bnodes.data() + NODE4_INFO_BUF_LEN * i;
memcpy(dest, n.id.data(), HASH_LEN);
memcpy(dest + HASH_LEN, &sin->sin_addr, sizeof(in_addr));
memcpy(dest + HASH_LEN + sizeof(in_addr), &sin->sin_port, 2);
memcpy(dest + HASH_LEN + sizeof(in_addr), &sin->sin_port, sizeof(in_port_t));
}
} else if (af == AF_INET6) {
bnodes.resize(NODE6_INFO_BUF_LEN * nnode);
const constexpr size_t size = HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t); // 38
for (size_t i=0; i<nnode; i++) {
const Node& n = *nodes[i];
sockaddr_in6 *sin6 = (sockaddr_in6*)&n.addr.first;
auto dest = bnodes.data() + size * i;
auto dest = bnodes.data() + NODE6_INFO_BUF_LEN * i;
memcpy(dest, n.id.data(), HASH_LEN);
memcpy(dest + HASH_LEN, &sin6->sin6_addr, sizeof(in6_addr));
memcpy(dest + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, 2);
memcpy(dest + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, sizeof(in_port_t));
}
}
return bnodes;
@@ -944,7 +985,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::
std::pair<Blob, Blob>
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
std::vector<std::shared_ptr<Node>>& nodes4, std::vector<std::shared_ptr<Node>>& nodes6)
std::vector<Sp<Node>>& nodes4, std::vector<Sp<Node>>& nodes6)
{
if (want < 0)
want = af == AF_INET ? WANT4 : WANT6;
@@ -960,19 +1001,47 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
return {std::move(bnodes4), std::move(bnodes6)};
}
std::shared_ptr<Request>
NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, const Query& query, const Blob& token,
RequestCb on_done, RequestExpiredCb on_expired) {
auto tid = TransId {TransPrefix::LISTEN, getNewTid()};
Sp<Request>
NetworkEngine::sendListen(Sp<Node> n,
const InfoHash& hash,
const Query& query,
const Blob& token,
Sp<Request> previous,
RequestCb&& on_done,
RequestExpiredCb&& on_expired,
SocketCb&& socket_cb)
{
Sp<Socket> socket;
auto tid = TransId { TransPrefix::LISTEN, previous ? previous->tid.getTid() : getNewTid() };
if (previous and previous->node == n) {
socket = previous->socket;
} else {
if (previous)
DHT_LOG.e(hash, "[node %s] trying refresh listen contract with wrong node", previous->node->toString().c_str());
/* TODO: Manually creating a socket for "listen" backward compatibility.
* As soon as this is not an issue anymore, switch to using
* ::createSocket function! */
auto sid = TransId {TransPrefix::GET_VALUES, tid.getTid()};
socket = std::make_shared<Socket>(n, sid, socket_cb);
opened_sockets.emplace(sid, socket);
}
if (not socket) {
DHT_LOG.e(hash, "[node %s] unable to get a valid socket for listen. Aborting listen", n->toString().c_str());
return {};
}
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack_map(5+(network?1:0));
auto has_query = query.where.getFilter() or not query.select.getSelection().empty();
pk.pack(std::string("a")); pk.pack_map(3 + has_query);
pk.pack(std::string("a")); pk.pack_map(4 + has_query);
pk.pack(std::string("id")); pk.pack(myid);
pk.pack(std::string("h")); pk.pack(infohash);
pk.pack(std::string("h")); pk.pack(hash);
pk.pack(std::string("token")); packToken(pk, token);
pk.pack(std::string("sid")); pk.pack_bin(socket->id.size());
pk.pack_bin_body((const char*)socket->id.data(), socket->id.size());
if (has_query) {
pk.pack(std::string("q")); pk.pack(query);
}
@@ -986,8 +1055,8 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
auto req = std::make_shared<Request>(tid, n,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
if (on_done)
on_done(req_status, {std::forward<ParsedMessage>(msg)});
@@ -996,8 +1065,8 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
if (on_expired)
on_expired(req_status, done);
},
true
});
socket
);
sendRequest(req);
++out_stats.listen;
return req;
@@ -1024,14 +1093,14 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, TransId tid) {
send(buffer.data(), buffer.size(), 0, addr);
}
std::shared_ptr<Request>
NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
Sp<Request>
NetworkEngine::sendAnnounceValue(Sp<Node> n,
const InfoHash& infohash,
const std::shared_ptr<Value>& value,
const Sp<Value>& value,
time_point created,
const Blob& token,
RequestCb on_done,
RequestExpiredCb on_expired)
RequestCb&& on_done,
RequestExpiredCb&& on_expired)
{
auto tid = TransId {TransPrefix::ANNOUNCE_VALUES, getNewTid()};
msgpack::sbuffer buffer;
@@ -1057,8 +1126,8 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
auto req = std::make_shared<Request>(tid, n,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
if (msg.value_id == Value::INVALID_ID) {
DHT_LOG.d(infohash, "Unknown search or announce!");
@@ -1075,7 +1144,7 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
on_expired(req_status, done);
}
}
});
);
sendRequest(req);
if (not v.empty())
sendValueParts(tid, v, n->addr);
@@ -1083,13 +1152,13 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n,
return req;
}
std::shared_ptr<Request>
NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
Sp<Request>
NetworkEngine::sendRefreshValue(Sp<Node> n,
const InfoHash& infohash,
const Value::Id& vid,
const Blob& token,
RequestCb on_done,
RequestExpiredCb on_expired)
RequestCb&& on_done,
RequestExpiredCb&& on_expired)
{
auto tid = TransId {TransPrefix::REFRESH, getNewTid()};
msgpack::sbuffer buffer;
@@ -1111,8 +1180,8 @@ NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
pk.pack(std::string("n")); pk.pack(network);
}
Blob b {buffer.data(), buffer.data() + buffer.size()};
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
auto req = std::make_shared<Request>(tid, n,
Blob(buffer.data(), buffer.data() + buffer.size()),
[=](const Request& req_status, ParsedMessage&& msg) { /* on done */
if (msg.value_id == Value::INVALID_ID) {
DHT_LOG.d(infohash, "Unknown search or announce!");
@@ -1129,11 +1198,10 @@ NetworkEngine::sendRefreshValue(std::shared_ptr<Node> n,
on_expired(req_status, done);
}
}
});
);
sendRequest(req);
++out_stats.refresh;
return req;
}
void
@@ -1163,7 +1231,8 @@ NetworkEngine::sendError(const SockAddr& addr,
TransId tid,
uint16_t code,
const std::string& message,
bool include_id) {
bool include_id)
{
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack_map(4 + (include_id?1:0));
@@ -1260,6 +1329,9 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
error_code = e->via.array.ptr[0].as<uint16_t>();
}
if (auto t = findMapValue(req, "sid"))
socket_id = {t->as<std::array<char, 4>>()};
if (auto rid = findMapValue(req, "id"))
id = {*rid};
@@ -1369,9 +1441,9 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
void
NetworkEngine::maintainRxBuffer(const TransId& tid)
{
const auto& now = scheduler.time();
auto msg = partial_messages.find(tid);
if (msg != partial_messages.end()) {
const auto& now = scheduler.time();
if (msg->second.start + RX_MAX_PACKET_TIME < now
|| msg->second.last_part + RX_TIMEOUT < now) {
DHT_LOG.w("Dropping expired partial message from %s", msg->second.from.toString().c_str());
@@ -1419,4 +1491,5 @@ ParsedMessage::complete()
}
}
} /* namespace net */
} /* namespace dht */
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more