mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-09 04:49:14 +00:00
Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d80aab9399 | ||
|
|
9b881d4e95 | ||
|
|
b4c3c2cba0 | ||
|
|
4519a23996 | ||
|
|
1ac4e08f45 | ||
|
|
5e92777702 | ||
|
|
4401e47002 | ||
|
|
215b44ca3b | ||
|
|
379fdae212 | ||
|
|
1e10e28fd7 | ||
|
|
dccdb84836 | ||
|
|
71599da8ea | ||
|
|
f418b3651f | ||
|
|
313f54c840 | ||
|
|
cdb721ade4 | ||
|
|
57ea09808e | ||
|
|
fec5a6ede7 | ||
|
|
5f8e9d9480 | ||
|
|
311a8981fc | ||
|
|
04850e1701 | ||
|
|
a30f1b8032 |
No files matched your search
@@ -0,0 +1 @@
|
||||
Checks: '-*,clang-diagnostic-*,performance-*,bugprone-*,llvm-*,clang-analyzer-*,misc-*,-llvm-namespace-comment,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-llvm-header-guard,-llvm-include-order,-bugprone-suspicious-string-compare'
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 1)
|
||||
set (opendht_VERSION_MINOR 8.1)
|
||||
set (opendht_VERSION_MINOR 8.2)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
@@ -70,8 +70,6 @@ set (CMAKE_CXX_STANDARD_REQUIRED on)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
|
||||
if (OPENDHT_SANITIZE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
|
||||
else ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-protector")
|
||||
endif ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
@@ -306,6 +304,8 @@ if (OPENDHT_TESTS)
|
||||
list (APPEND test_FILES
|
||||
tests/infohashtester.h
|
||||
tests/infohashtester.cpp
|
||||
tests/valuetester.h
|
||||
tests/valuetester.cpp
|
||||
tests/cryptotester.h
|
||||
tests/cryptotester.cpp
|
||||
tests/dhtrunnertester.h
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -106,7 +106,7 @@ for r in results:
|
||||
IRC: join us on Freenode at [`#opendht`](https://webchat.freenode.net/?channels=%23opendht).
|
||||
|
||||
## License
|
||||
Copyright (C) 2014-2018 Savoir-faire Linux Inc.
|
||||
Copyright (C) 2014-2019 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.
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 1)
|
||||
m4_define([opendht_minor_version], 8)
|
||||
m4_define([opendht_patch_version], 1)
|
||||
m4_define([opendht_patch_version], 2)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -131,8 +131,8 @@ using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::
|
||||
|
||||
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
|
||||
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(GetCallbackSimple cb);
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(const GetCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(const 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);
|
||||
@@ -142,10 +142,10 @@ typedef bool (*FilterRaw)(const Value&, void *user_data);
|
||||
|
||||
using DoneCallbackSimple = std::function<void(bool success)>;
|
||||
|
||||
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
|
||||
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(const 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);
|
||||
OPENDHT_PUBLIC Value::Filter bindFilterRaw(FilterRaw raw_filter, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC Value::Filter bindFilterRaw(const FilterRaw& raw_filter, void* user_data);
|
||||
|
||||
}
|
||||
+52
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -66,7 +66,7 @@ using Identity = std::pair<std::shared_ptr<PrivateKey>, std::shared_ptr<Certific
|
||||
*/
|
||||
struct OPENDHT_PUBLIC PublicKey
|
||||
{
|
||||
PublicKey() {}
|
||||
PublicKey();
|
||||
|
||||
/**
|
||||
* Takes ownership of an existing gnutls_pubkey.
|
||||
@@ -115,7 +115,9 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
|
||||
gnutls_pubkey_t pk {};
|
||||
gnutls_digest_algorithm_t getPreferredDigest() const;
|
||||
|
||||
gnutls_pubkey_t pk {nullptr};
|
||||
private:
|
||||
PublicKey(const PublicKey&) = delete;
|
||||
PublicKey& operator=(const PublicKey&) = delete;
|
||||
@@ -254,14 +256,48 @@ private:
|
||||
RevocationList& operator=(const RevocationList&) = delete;
|
||||
};
|
||||
|
||||
enum class NameType { UNKNOWN = 0, RFC822, DNS, URI, IP };
|
||||
|
||||
class OPENDHT_PUBLIC CertificateRequest {
|
||||
public:
|
||||
CertificateRequest();
|
||||
CertificateRequest(const uint8_t* data, size_t size);
|
||||
CertificateRequest(const Blob& data) : CertificateRequest(data.data(), data.size()) {}
|
||||
|
||||
CertificateRequest(CertificateRequest&& o) noexcept : request(std::move(o.request)) {
|
||||
o.request = nullptr;
|
||||
}
|
||||
CertificateRequest& operator=(CertificateRequest&& o) noexcept;
|
||||
|
||||
~CertificateRequest();
|
||||
|
||||
void setName(const std::string& name);
|
||||
void setUID(const std::string& name);
|
||||
void setAltName(NameType type, const std::string& name);
|
||||
|
||||
std::string getName() const;
|
||||
std::string getUID() const;
|
||||
|
||||
void sign(const PrivateKey& key, const std::string& password = {});
|
||||
|
||||
bool verify() const;
|
||||
|
||||
Blob pack() const;
|
||||
|
||||
gnutls_x509_crq_t get() const { return request; }
|
||||
private:
|
||||
CertificateRequest(const CertificateRequest& o) = delete;
|
||||
CertificateRequest& operator=(const CertificateRequest& o) = delete;
|
||||
gnutls_x509_crq_t request {nullptr};
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC Certificate {
|
||||
Certificate() {}
|
||||
Certificate() noexcept {}
|
||||
|
||||
/**
|
||||
* Take ownership of existing gnutls structure
|
||||
*/
|
||||
Certificate(gnutls_x509_crt_t crt) : cert(crt) {}
|
||||
Certificate(gnutls_x509_crt_t crt) noexcept : cert(crt) {}
|
||||
|
||||
Certificate(Certificate&& o) noexcept : cert(o.cert), issuer(std::move(o.issuer)) { o.cert = nullptr; };
|
||||
|
||||
@@ -392,8 +428,6 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
/** Read certificate issuer User ID (UID) */
|
||||
std::string getIssuerUID() const;
|
||||
|
||||
enum class NameType { UNKNOWN = 0, RFC822, DNS, URI, IP };
|
||||
|
||||
/** Read certificate alternative names */
|
||||
std::vector<std::pair<NameType, std::string>> getAltNames() const;
|
||||
|
||||
@@ -431,7 +465,8 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
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);
|
||||
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false);
|
||||
static Certificate generate(const CertificateRequest& request, const Identity& ca);
|
||||
|
||||
gnutls_x509_crt_t getCopy() const {
|
||||
if (not cert)
|
||||
@@ -472,7 +507,9 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
return {crts, crls};
|
||||
}
|
||||
|
||||
gnutls_x509_crt_t cert {};
|
||||
gnutls_digest_algorithm_t getPreferredDigest() const;
|
||||
|
||||
gnutls_x509_crt_t cert {nullptr};
|
||||
std::shared_ptr<Certificate> issuer {};
|
||||
private:
|
||||
Certificate(const Certificate&) = delete;
|
||||
@@ -503,7 +540,7 @@ struct OPENDHT_PUBLIC TrustList
|
||||
TrustList(TrustList&& o) noexcept : trust(std::move(o.trust)) {
|
||||
o.trust = nullptr;
|
||||
}
|
||||
TrustList& operator=(TrustList&& o);
|
||||
TrustList& operator=(TrustList&& o) noexcept;
|
||||
~TrustList();
|
||||
void add(const Certificate& crt);
|
||||
void add(const RevocationList& crl);
|
||||
@@ -513,7 +550,7 @@ struct OPENDHT_PUBLIC TrustList
|
||||
private:
|
||||
TrustList(const TrustList& o) = delete;
|
||||
TrustList& operator=(const TrustList& o) = delete;
|
||||
gnutls_x509_trust_list_t trust;
|
||||
gnutls_x509_trust_list_t trust {nullptr};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -611,11 +648,11 @@ using SecureBlob = secure_vector<uint8_t>;
|
||||
* If not set, the generated certificate will be a self-signed CA.
|
||||
* @param key_length stength of the generated private key (bits).
|
||||
*/
|
||||
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);
|
||||
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name, const Identity& ca, unsigned key_length, bool is_ca);
|
||||
OPENDHT_PUBLIC Identity generateIdentity(const std::string& name = "dhtnode", const Identity& ca = {}, unsigned key_length = 4096);
|
||||
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name, Identity ca, bool is_ca);
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name = "dhtnode", Identity ca = {});
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name, const Identity& ca, bool is_ca);
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name = "dhtnode", const Identity& ca = {});
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -38,7 +38,7 @@ class OPENDHT_PUBLIC DhtMessage : public Value::Serializable<DhtMessage>
|
||||
public:
|
||||
static const ValueType TYPE;
|
||||
|
||||
DhtMessage(std::string s = {}, Blob msg = {}) : service(s), data(msg) {}
|
||||
DhtMessage(const std::string& s = {}, const Blob& msg = {}) : service(s), data(msg) {}
|
||||
|
||||
std::string getService() const {
|
||||
return service;
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
static bool storePolicy(InfoHash key, std::shared_ptr<Value>& value, const InfoHash& from, const SockAddr&);
|
||||
|
||||
static Value::Filter ServiceFilter(std::string s);
|
||||
static Value::Filter ServiceFilter(const std::string& s);
|
||||
|
||||
/** print value for debugging */
|
||||
friend std::ostream& operator<< (std::ostream&, const DhtMessage&);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
* Initialise the Dht with two open sockets (for IPv4 and IP6)
|
||||
* and an ID for the node.
|
||||
*/
|
||||
Dht(const int& s, const int& s6, Config config);
|
||||
Dht(const int& s, const int& s6, const Config& config);
|
||||
virtual ~Dht();
|
||||
|
||||
/**
|
||||
@@ -430,7 +430,7 @@ private:
|
||||
* nodes.
|
||||
*/
|
||||
void dataPersistence(InfoHash id);
|
||||
size_t maintainStorage(decltype(store)::value_type&, bool force=false, DoneCallback donecb=nullptr);
|
||||
size_t maintainStorage(decltype(store)::value_type&, bool force=false, const DoneCallback& donecb={});
|
||||
|
||||
// Buckets
|
||||
RoutingTable& buckets(sa_family_t af) { return af == AF_INET ? buckets4 : buckets6; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -364,7 +364,7 @@ public:
|
||||
/*.push_node_id = */""
|
||||
});
|
||||
}
|
||||
void run(in_port_t port, Config config);
|
||||
void run(in_port_t port, const Config& config);
|
||||
|
||||
/**
|
||||
* @param local4: Local IPv4 address and port to bind. Can be null.
|
||||
@@ -374,12 +374,12 @@ public:
|
||||
* @param threaded: If false, loop() must be called periodically. Otherwise a thread is launched.
|
||||
* @param cb: Optional callback to receive general state information.
|
||||
*/
|
||||
void run(const SockAddr& local4, const SockAddr& local6, Config config);
|
||||
void run(const SockAddr& local4, const SockAddr& local6, const Config& config);
|
||||
|
||||
/**
|
||||
* Same as @run(sockaddr_in, sockaddr_in6, Identity, bool, StatusCallback), but with string IP addresses and service (port).
|
||||
*/
|
||||
void run(const char* ip4, const char* ip6, const char* service, Config config);
|
||||
void run(const char* ip4, const char* ip6, const char* service, const Config& config);
|
||||
|
||||
void setOnStatusChanged(StatusCallback&& cb) {
|
||||
statusCb = std::move(cb);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 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>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -206,15 +206,15 @@ public:
|
||||
|
||||
NetworkEngine(Logger& log, Scheduler& scheduler, const int& s = -1, const int& s6 = -1);
|
||||
NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
|
||||
decltype(NetworkEngine::onError) onError,
|
||||
decltype(NetworkEngine::onNewNode) onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr) onReportedAddr,
|
||||
decltype(NetworkEngine::onPing) onPing,
|
||||
decltype(NetworkEngine::onFindNode) onFindNode,
|
||||
decltype(NetworkEngine::onGetValues) onGetValues,
|
||||
decltype(NetworkEngine::onListen) onListen,
|
||||
decltype(NetworkEngine::onAnnounce) onAnnounce,
|
||||
decltype(NetworkEngine::onRefresh) onRefresh);
|
||||
decltype(NetworkEngine::onError)&& onError,
|
||||
decltype(NetworkEngine::onNewNode)&& onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
|
||||
decltype(NetworkEngine::onPing)&& onPing,
|
||||
decltype(NetworkEngine::onFindNode)&& onFindNode,
|
||||
decltype(NetworkEngine::onGetValues)&& onGetValues,
|
||||
decltype(NetworkEngine::onListen)&& onListen,
|
||||
decltype(NetworkEngine::onAnnounce)&& onAnnounce,
|
||||
decltype(NetworkEngine::onRefresh)&& onRefresh);
|
||||
|
||||
virtual ~NetworkEngine();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
* result_type is unsigned int so this is currently safe.
|
||||
*/
|
||||
static_assert(
|
||||
sizeof(result_type) == 2 ||
|
||||
sizeof(result_type) == 4 ||
|
||||
sizeof(result_type) == 2 ||
|
||||
sizeof(result_type) == 4 ||
|
||||
sizeof(result_type) == 8,
|
||||
"result_type must be 16, 32 or 64 bits");
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -37,9 +37,9 @@ public:
|
||||
|
||||
using Config = SecureDhtConfig;
|
||||
|
||||
static dht::Config& getConfig(SecureDht::Config& conf)
|
||||
static dht::Config getConfig(const SecureDht::Config& conf)
|
||||
{
|
||||
auto& c = conf.node_config;
|
||||
auto c = conf.node_config;
|
||||
if (not c.node_id and conf.id.second)
|
||||
c.node_id = InfoHash::get("node:"+conf.id.second->getId().toString());
|
||||
return c;
|
||||
@@ -127,8 +127,8 @@ public:
|
||||
|
||||
Value decrypt(const Value& v);
|
||||
|
||||
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);
|
||||
void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
|
||||
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb);
|
||||
|
||||
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
void registerCertificate(Sp<crypto::Certificate>& cert);
|
||||
@@ -332,8 +332,8 @@ private:
|
||||
SecureDht& operator=(const SecureDht&) = delete;
|
||||
|
||||
Sp<Value> checkValue(const Sp<Value>& v);
|
||||
ValueCallback getCallbackFilter(ValueCallback, Value::Filter&&);
|
||||
GetCallback getCallbackFilter(GetCallback, Value::Filter&&);
|
||||
ValueCallback getCallbackFilter(const ValueCallback&, Value::Filter&&);
|
||||
GetCallback getCallbackFilter(const GetCallback&, Value::Filter&&);
|
||||
|
||||
Sp<crypto::PrivateKey> key_ {};
|
||||
Sp<crypto::Certificate> certificate_ {};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+17
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -79,7 +79,7 @@ static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
|
||||
struct OPENDHT_PUBLIC ValueType {
|
||||
typedef uint16_t Id;
|
||||
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&);
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, const std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&);
|
||||
static bool DEFAULT_EDIT_POLICY(InfoHash, const std::shared_ptr<Value>&, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&) {
|
||||
return false;
|
||||
}
|
||||
@@ -165,8 +165,15 @@ struct OPENDHT_PUBLIC Value
|
||||
return chainOr(std::move(f1), std::move(f2));
|
||||
}
|
||||
static Filter chain(Filter&& f1, Filter&& f2) {
|
||||
if (not f1) return std::move(f1);
|
||||
if (not f2) return std::move(f2);
|
||||
if (not f1) return std::move(f2);
|
||||
if (not f2) return std::move(f1);
|
||||
return [f1,f2](const Value& v) {
|
||||
return f1(v) and f2(v);
|
||||
};
|
||||
}
|
||||
static Filter chain(const Filter& f1, const Filter& f2) {
|
||||
if (not f1) return f2;
|
||||
if (not f2) return f1;
|
||||
return [f1,f2](const Value& v) {
|
||||
return f1(v) and f2(v);
|
||||
};
|
||||
@@ -189,6 +196,10 @@ struct OPENDHT_PUBLIC Value
|
||||
return f1(v) or f2(v);
|
||||
};
|
||||
}
|
||||
static Filter notFilter(Filter&& f) {
|
||||
if (not f) return [](const Value&) { return false; };
|
||||
return [f](const Value& v) { return not f(v); };
|
||||
}
|
||||
std::vector<Sp<Value>> filter(const std::vector<Sp<Value>>& values) {
|
||||
if (not (*this))
|
||||
return values;
|
||||
@@ -874,7 +885,7 @@ struct OPENDHT_PUBLIC Query
|
||||
{
|
||||
static const std::string QUERY_PARSE_ERROR;
|
||||
|
||||
Query(Select s = {}, Where w = {}, bool none = false) : select(s), where(w), none(none) { };
|
||||
Query(Select s = {}, Where w = {}, bool none = false) : select(std::move(s)), where(std::move(w)), none(none) { };
|
||||
|
||||
/**
|
||||
* Initializes a query based on a SQL-ish formatted string. The abstract
|
||||
@@ -936,7 +947,7 @@ struct OPENDHT_PUBLIC Query
|
||||
*/
|
||||
struct OPENDHT_PUBLIC FieldValueIndex {
|
||||
FieldValueIndex() {}
|
||||
FieldValueIndex(const Value& v, Select s = {});
|
||||
FieldValueIndex(const Value& v, const Select& s = {});
|
||||
/**
|
||||
* Tells if all the fields of this are contained in the other
|
||||
* FieldValueIndex with the same value.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
# distutils: libraries = opendht gnutls
|
||||
# cython: language_level=3
|
||||
#
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author(s): Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2015-2017 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Savoir-Faire Linux Inc.
|
||||
# Copyright (C) 2015-2019 Savoir-Faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015-2017 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2016-2019 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2017 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -27,7 +27,7 @@ ping_node.run()
|
||||
pong_node = dht.DhtRunner()
|
||||
pong_node.run()
|
||||
#pong_node.enableLogging()
|
||||
pong_node.ping(ping_node.getBound());
|
||||
pong_node.ping(ping_node.getBound())
|
||||
|
||||
loc_ping = dht.InfoHash.get("toto99")
|
||||
loc_pong = dht.InfoHash.get(str(loc_ping))
|
||||
@@ -42,7 +42,7 @@ def done(h, ok):
|
||||
|
||||
def ping(node, h):
|
||||
global i
|
||||
time.sleep(0.0075)
|
||||
time.sleep(0.0075)
|
||||
i += 1
|
||||
if i < MAX:
|
||||
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2004-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Mainly based on the following stackoverflow question:
|
||||
* http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2004-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@ namespace dht {
|
||||
|
||||
|
||||
GetCallbackSimple
|
||||
bindGetCb(GetCallbackRaw raw_cb, void* user_data)
|
||||
bindGetCb(const GetCallbackRaw& raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](const std::shared_ptr<Value>& value) {
|
||||
@@ -13,7 +13,7 @@ bindGetCb(GetCallbackRaw raw_cb, void* user_data)
|
||||
}
|
||||
|
||||
GetCallback
|
||||
bindGetCb(GetCallbackSimple cb)
|
||||
bindGetCb(const GetCallbackSimple& cb)
|
||||
{
|
||||
if (not cb) return {};
|
||||
return [=](const std::vector<std::shared_ptr<Value>>& values) {
|
||||
@@ -25,7 +25,7 @@ bindGetCb(GetCallbackSimple cb)
|
||||
}
|
||||
|
||||
ShutdownCallback
|
||||
bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data)
|
||||
bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data)
|
||||
{
|
||||
return [=]() { shutdown_cb_raw(user_data); };
|
||||
}
|
||||
@@ -39,7 +39,7 @@ bindDoneCb(DoneCallbackSimple donecb)
|
||||
}
|
||||
|
||||
DoneCallback
|
||||
bindDoneCb(DoneCallbackRaw raw_cb, void* user_data)
|
||||
bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](bool success, const std::vector<std::shared_ptr<Node>>& nodes) {
|
||||
@@ -48,7 +48,7 @@ bindDoneCb(DoneCallbackRaw raw_cb, void* user_data)
|
||||
}
|
||||
|
||||
DoneCallbackSimple
|
||||
bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
|
||||
bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data) {
|
||||
if (not raw_cb) return {};
|
||||
return [=](bool success) {
|
||||
raw_cb(success, user_data);
|
||||
|
||||
+265
-106
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -40,31 +40,6 @@ static std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint
|
||||
static std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
#endif
|
||||
|
||||
static gnutls_digest_algorithm_t get_dig_for_pub(gnutls_pubkey_t pubkey)
|
||||
{
|
||||
gnutls_digest_algorithm_t dig;
|
||||
int result = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &dig, nullptr);
|
||||
if (result < 0)
|
||||
return GNUTLS_DIG_UNKNOWN;
|
||||
return dig;
|
||||
}
|
||||
|
||||
static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt_t crt)
|
||||
{
|
||||
gnutls_pubkey_t pubkey;
|
||||
gnutls_pubkey_init(&pubkey);
|
||||
|
||||
int result = gnutls_pubkey_import_x509(pubkey, crt, 0);
|
||||
if (result < 0) {
|
||||
gnutls_pubkey_deinit(pubkey);
|
||||
return GNUTLS_DIG_UNKNOWN;
|
||||
}
|
||||
|
||||
gnutls_digest_algorithm_t dig = get_dig_for_pub(pubkey);
|
||||
gnutls_pubkey_deinit(pubkey);
|
||||
return dig;
|
||||
}
|
||||
|
||||
// support for GnuTLS < 3.4.
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030400
|
||||
#define GNUTLS_PKCS_PKCS12_3DES GNUTLS_PKCS_USE_PKCS12_3DES
|
||||
@@ -377,15 +352,19 @@ PrivateKey::serialize(const std::string& password) const
|
||||
PublicKey
|
||||
PrivateKey::getPublicKey() const
|
||||
{
|
||||
gnutls_pubkey_t pk;
|
||||
gnutls_pubkey_init(&pk);
|
||||
PublicKey pk_ret {pk};
|
||||
if (gnutls_pubkey_import_privkey(pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0) != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
return pk_ret;
|
||||
PublicKey pk;
|
||||
if (auto err = gnutls_pubkey_import_privkey(pk.pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
|
||||
throw CryptoException(std::string("Can't retreive public key: ") + gnutls_strerror(err));
|
||||
return pk;
|
||||
}
|
||||
|
||||
PublicKey::PublicKey(const Blob& dat) : pk(nullptr)
|
||||
PublicKey::PublicKey()
|
||||
{
|
||||
if (auto err = gnutls_pubkey_init(&pk))
|
||||
throw CryptoException(std::string("Can't initialize public key: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
PublicKey::PublicKey(const Blob& dat) : PublicKey()
|
||||
{
|
||||
unpack(dat.data(), dat.size());
|
||||
}
|
||||
@@ -415,8 +394,7 @@ PublicKey::pack(Blob& b) const
|
||||
throw CryptoException(std::string("Could not export public key: null key"));
|
||||
std::vector<uint8_t> tmp(2048);
|
||||
size_t sz = tmp.size();
|
||||
int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_DER, tmp.data(), &sz);
|
||||
if (err != GNUTLS_E_SUCCESS)
|
||||
if (int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_DER, tmp.data(), &sz))
|
||||
throw CryptoException(std::string("Could not export public key: ") + gnutls_strerror(err));
|
||||
tmp.resize(sz);
|
||||
b.insert(b.end(), tmp.begin(), tmp.end());
|
||||
@@ -425,9 +403,6 @@ PublicKey::pack(Blob& b) const
|
||||
void
|
||||
PublicKey::unpack(const uint8_t* data, size_t data_size)
|
||||
{
|
||||
if (pk)
|
||||
gnutls_pubkey_deinit(pk);
|
||||
gnutls_pubkey_init(&pk);
|
||||
const gnutls_datum_t dat {(uint8_t*)data, (unsigned)data_size};
|
||||
int err = gnutls_pubkey_import(pk, &dat, GNUTLS_X509_FMT_PEM);
|
||||
if (err != GNUTLS_E_SUCCESS)
|
||||
@@ -446,10 +421,9 @@ PublicKey::toString() const
|
||||
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)
|
||||
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));
|
||||
return ret;
|
||||
}
|
||||
@@ -572,7 +546,180 @@ PublicKey::getLongId() const
|
||||
#endif
|
||||
}
|
||||
|
||||
Certificate::Certificate(const Blob& certData) : cert(nullptr)
|
||||
gnutls_digest_algorithm_t
|
||||
PublicKey::getPreferredDigest() const
|
||||
{
|
||||
gnutls_digest_algorithm_t dig;
|
||||
int result = gnutls_pubkey_get_preferred_hash_algorithm(pk, &dig, nullptr);
|
||||
if (result < 0)
|
||||
return GNUTLS_DIG_UNKNOWN;
|
||||
return dig;
|
||||
}
|
||||
|
||||
// Certificate Request
|
||||
|
||||
static NameType
|
||||
typeFromGnuTLS(gnutls_x509_subject_alt_name_t type)
|
||||
{
|
||||
switch(type) {
|
||||
case GNUTLS_SAN_DNSNAME:
|
||||
return NameType::DNS;
|
||||
case GNUTLS_SAN_RFC822NAME:
|
||||
return NameType::RFC822;
|
||||
case GNUTLS_SAN_URI:
|
||||
return NameType::URI;
|
||||
case GNUTLS_SAN_IPADDRESS:
|
||||
return NameType::IP;
|
||||
default:
|
||||
return NameType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static gnutls_x509_subject_alt_name_t
|
||||
GnuTLSFromType(NameType type)
|
||||
{
|
||||
switch(type) {
|
||||
case NameType::DNS:
|
||||
return GNUTLS_SAN_DNSNAME;
|
||||
case NameType::RFC822:
|
||||
return GNUTLS_SAN_RFC822NAME;
|
||||
case NameType::URI:
|
||||
return GNUTLS_SAN_URI;
|
||||
case NameType::IP:
|
||||
return GNUTLS_SAN_IPADDRESS;
|
||||
default:
|
||||
return (gnutls_x509_subject_alt_name_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string
|
||||
getDN(gnutls_x509_crq_t request, const char* oid)
|
||||
{
|
||||
std::string dn;
|
||||
dn.resize(512);
|
||||
size_t dn_sz = dn.size();
|
||||
int ret = gnutls_x509_crq_get_dn_by_oid(request, oid, 0, 0, &(*dn.begin()), &dn_sz);
|
||||
if (ret != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
dn.resize(dn_sz);
|
||||
return dn;
|
||||
}
|
||||
|
||||
CertificateRequest::CertificateRequest()
|
||||
{
|
||||
if (auto err = gnutls_x509_crq_init(&request))
|
||||
throw CryptoException(std::string("Can't initialize certificate request: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
CertificateRequest::CertificateRequest(const uint8_t* data, size_t size) : CertificateRequest()
|
||||
{
|
||||
const gnutls_datum_t dat {(uint8_t*)data, (unsigned)size};
|
||||
if (auto err = gnutls_x509_crq_import(request, &dat, GNUTLS_X509_FMT_PEM))
|
||||
throw CryptoException(std::string("Can't import certificate request: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
CertificateRequest::~CertificateRequest()
|
||||
{
|
||||
if (request) {
|
||||
gnutls_x509_crq_deinit(request);
|
||||
request = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CertificateRequest&
|
||||
CertificateRequest::operator=(CertificateRequest&& o) noexcept
|
||||
{
|
||||
if (request)
|
||||
gnutls_x509_crq_deinit(request);
|
||||
request = o.request;
|
||||
o.request = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
CertificateRequest::setAltName(NameType type, const std::string& name)
|
||||
{
|
||||
gnutls_x509_crq_set_subject_alt_name(request, GnuTLSFromType(type), name.data(), name.size(), 0);
|
||||
}
|
||||
|
||||
void
|
||||
CertificateRequest::setName(const std::string& name)
|
||||
{
|
||||
gnutls_x509_crq_set_dn_by_oid(request, GNUTLS_OID_X520_COMMON_NAME, 0, name.data(), name.length());
|
||||
}
|
||||
|
||||
std::string
|
||||
CertificateRequest::getName() const
|
||||
{
|
||||
return getDN(request, GNUTLS_OID_X520_COMMON_NAME);
|
||||
}
|
||||
|
||||
std::string
|
||||
CertificateRequest::getUID() const
|
||||
{
|
||||
return getDN(request, GNUTLS_OID_LDAP_UID);
|
||||
}
|
||||
|
||||
void
|
||||
CertificateRequest::setUID(const std::string& uid)
|
||||
{
|
||||
gnutls_x509_crq_set_dn_by_oid(request, GNUTLS_OID_LDAP_UID, 0, uid.data(), uid.length());
|
||||
}
|
||||
|
||||
void
|
||||
CertificateRequest::sign(const PrivateKey& key, const std::string& password)
|
||||
{
|
||||
gnutls_x509_crq_set_version(request, 1);
|
||||
if (not password.empty())
|
||||
gnutls_x509_crq_set_challenge_password(request, password.c_str());
|
||||
|
||||
if (auto err = gnutls_x509_crq_set_key(request, key.x509_key))
|
||||
throw CryptoException(std::string("Can't set certificate request key: ") + gnutls_strerror(err));
|
||||
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030601
|
||||
if (auto err = gnutls_x509_crq_privkey_sign(request, key.key, key.getPublicKey().getPreferredDigest(), 0))
|
||||
throw CryptoException(std::string("Can't sign certificate request: ") + gnutls_strerror(err));
|
||||
#else
|
||||
if (auto err = gnutls_x509_crq_privkey_sign(request, key.key, GNUTLS_DIG_UNKNOWN, 0))
|
||||
throw CryptoException(std::string("Can't sign certificate request: ") + gnutls_strerror(err));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
CertificateRequest::verify() const
|
||||
{
|
||||
return gnutls_x509_crq_verify(request, 0) >= 0;
|
||||
}
|
||||
|
||||
Blob
|
||||
CertificateRequest::pack() const
|
||||
{
|
||||
gnutls_datum_t dat {nullptr, 0};
|
||||
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
|
||||
throw CryptoException(std::string("Can't export certificate request: ") + gnutls_strerror(err));
|
||||
Blob ret(dat.data, dat.data + dat.size);
|
||||
gnutls_free(dat.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Certificate
|
||||
|
||||
static std::string
|
||||
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
|
||||
{
|
||||
std::string dn;
|
||||
dn.resize(512);
|
||||
size_t dn_sz = dn.size();
|
||||
int ret = issuer
|
||||
? 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 {};
|
||||
dn.resize(dn_sz);
|
||||
return dn;
|
||||
}
|
||||
|
||||
Certificate::Certificate(const Blob& certData)
|
||||
{
|
||||
unpack(certData.data(), certData.size());
|
||||
}
|
||||
@@ -656,11 +803,9 @@ Certificate::~Certificate()
|
||||
PublicKey
|
||||
Certificate::getPublicKey() const
|
||||
{
|
||||
gnutls_pubkey_t pk;
|
||||
gnutls_pubkey_init(&pk);
|
||||
PublicKey pk_ret(pk);
|
||||
if (gnutls_pubkey_import_x509(pk, cert, 0) != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
PublicKey pk_ret;
|
||||
if (auto err = gnutls_pubkey_import_x509(pk_ret.pk, cert, 0))
|
||||
throw CryptoException(std::string("Can't get certificate public key: ") + gnutls_strerror(err));
|
||||
return pk_ret;
|
||||
}
|
||||
|
||||
@@ -696,21 +841,6 @@ Certificate::getLongId() const
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string
|
||||
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
|
||||
{
|
||||
std::string dn;
|
||||
dn.resize(512);
|
||||
size_t dn_sz = dn.size();
|
||||
int ret = issuer
|
||||
? 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 {};
|
||||
dn.resize(dn_sz);
|
||||
return dn;
|
||||
}
|
||||
|
||||
std::string
|
||||
Certificate::getName() const
|
||||
{
|
||||
@@ -735,24 +865,7 @@ Certificate::getIssuerUID() const
|
||||
return getDN(cert, GNUTLS_OID_LDAP_UID, true);
|
||||
}
|
||||
|
||||
static Certificate::NameType
|
||||
typeFromGnuTLS(gnutls_x509_subject_alt_name_t type)
|
||||
{
|
||||
switch(type) {
|
||||
case GNUTLS_SAN_DNSNAME:
|
||||
return Certificate::NameType::DNS;
|
||||
case GNUTLS_SAN_RFC822NAME:
|
||||
return Certificate::NameType::RFC822;
|
||||
case GNUTLS_SAN_URI:
|
||||
return Certificate::NameType::URI;
|
||||
case GNUTLS_SAN_IPADDRESS:
|
||||
return Certificate::NameType::IP;
|
||||
default:
|
||||
return Certificate::NameType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<Certificate::NameType, std::string>>
|
||||
std::vector<std::pair<NameType, std::string>>
|
||||
Certificate::getAltNames() const
|
||||
{
|
||||
std::vector<std::pair<NameType, std::string>> names;
|
||||
@@ -867,6 +980,14 @@ Certificate::getExpiration() const
|
||||
return std::chrono::system_clock::from_time_t(t);
|
||||
}
|
||||
|
||||
gnutls_digest_algorithm_t
|
||||
Certificate::getPreferredDigest() const
|
||||
{
|
||||
return getPublicKey().getPreferredDigest();
|
||||
}
|
||||
|
||||
// PrivateKey
|
||||
|
||||
PrivateKey
|
||||
PrivateKey::generate(unsigned key_length)
|
||||
{
|
||||
@@ -896,7 +1017,7 @@ PrivateKey::generateEC()
|
||||
}
|
||||
|
||||
Identity
|
||||
generateIdentity(const std::string& name, crypto::Identity ca, unsigned key_length, bool is_ca)
|
||||
generateIdentity(const std::string& name, const Identity& ca, unsigned key_length, bool is_ca)
|
||||
{
|
||||
auto key = std::make_shared<PrivateKey>(PrivateKey::generate(key_length));
|
||||
auto cert = std::make_shared<Certificate>(Certificate::generate(*key, name, ca, is_ca));
|
||||
@@ -905,12 +1026,12 @@ generateIdentity(const std::string& name, crypto::Identity ca, unsigned key_leng
|
||||
|
||||
|
||||
Identity
|
||||
generateIdentity(const std::string& name, Identity ca, unsigned key_length) {
|
||||
generateIdentity(const std::string& name, const Identity& ca, unsigned key_length) {
|
||||
return generateIdentity(name, ca, key_length, !ca.first || !ca.second);
|
||||
}
|
||||
|
||||
Identity
|
||||
generateEcIdentity(const std::string& name, crypto::Identity ca, bool is_ca)
|
||||
generateEcIdentity(const std::string& name, const Identity& ca, bool is_ca)
|
||||
{
|
||||
auto key = std::make_shared<PrivateKey>(PrivateKey::generateEC());
|
||||
auto cert = std::make_shared<Certificate>(Certificate::generate(*key, name, ca, is_ca));
|
||||
@@ -918,25 +1039,40 @@ generateEcIdentity(const std::string& name, crypto::Identity ca, bool is_ca)
|
||||
}
|
||||
|
||||
Identity
|
||||
generateEcIdentity(const std::string& name, Identity ca) {
|
||||
generateEcIdentity(const std::string& name, const Identity& ca) {
|
||||
return generateEcIdentity(name, ca, !ca.first || !ca.second);
|
||||
}
|
||||
|
||||
void
|
||||
setValidityPeriod(gnutls_x509_crt_t cert, int64_t validity)
|
||||
{
|
||||
int64_t now = time(nullptr);
|
||||
/* 2038 bug: don't allow time wrap */
|
||||
auto boundTime = [](int64_t t) -> time_t {
|
||||
return std::min<int64_t>(t, std::numeric_limits<time_t>::max());
|
||||
};
|
||||
gnutls_x509_crt_set_activation_time(cert, boundTime(now));
|
||||
gnutls_x509_crt_set_expiration_time(cert, boundTime(now + validity));
|
||||
}
|
||||
|
||||
void
|
||||
setRandomSerial(gnutls_x509_crt_t cert)
|
||||
{
|
||||
random_device rdev;
|
||||
std::uniform_int_distribution<uint64_t> dist{};
|
||||
uint64_t cert_serial = dist(rdev);
|
||||
gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial));
|
||||
}
|
||||
|
||||
Certificate
|
||||
Certificate::generate(const PrivateKey& key, const std::string& name, Identity ca, bool is_ca)
|
||||
Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca)
|
||||
{
|
||||
gnutls_x509_crt_t cert;
|
||||
if (not key.x509_key or gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
Certificate ret {cert};
|
||||
|
||||
int64_t now = time(NULL);
|
||||
/* 2038 bug: don't allow time wrap */
|
||||
auto boundTime = [](int64_t t) -> time_t {
|
||||
return std::min<int64_t>(t, std::numeric_limits<time_t>::max());
|
||||
};
|
||||
gnutls_x509_crt_set_activation_time(cert, boundTime(now));
|
||||
gnutls_x509_crt_set_expiration_time(cert, boundTime(now + (10 * 365 * 24 * 60 * 60)));
|
||||
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
|
||||
if (gnutls_x509_crt_set_key(cert, key.x509_key) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when setting certificate key" << std::endl;
|
||||
return {};
|
||||
@@ -947,19 +1083,15 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
|
||||
}
|
||||
|
||||
// TODO: compute the subject key using the recommended RFC method
|
||||
auto pk_id = key.getPublicKey().getId();
|
||||
auto pk = key.getPublicKey();
|
||||
auto pk_id = pk.getId();
|
||||
const std::string uid_str = pk_id.toString();
|
||||
|
||||
gnutls_x509_crt_set_subject_key_id(cert, &pk_id, sizeof(pk_id));
|
||||
gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, name.data(), name.length());
|
||||
gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_LDAP_UID, 0, uid_str.data(), uid_str.length());
|
||||
|
||||
{
|
||||
random_device rdev;
|
||||
std::uniform_int_distribution<uint64_t> dist{};
|
||||
uint64_t cert_serial = dist(rdev);
|
||||
gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial));
|
||||
}
|
||||
setRandomSerial(cert);
|
||||
|
||||
unsigned key_usage = 0;
|
||||
if (is_ca) {
|
||||
@@ -975,15 +1107,13 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
|
||||
// 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) {
|
||||
if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when signing certificate" << std::endl;
|
||||
return {};
|
||||
}
|
||||
ret.issuer = ca.second;
|
||||
} else {
|
||||
//if (gnutls_x509_crt_sign2(cert, cert, key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
|
||||
if (gnutls_x509_crt_privkey_sign(cert, cert, key.key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
|
||||
if (gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when signing certificate" << std::endl;
|
||||
return {};
|
||||
}
|
||||
@@ -992,6 +1122,31 @@ Certificate::generate(const PrivateKey& key, const std::string& name, Identity c
|
||||
return ret.getPacked();
|
||||
}
|
||||
|
||||
Certificate
|
||||
Certificate::generate(const CertificateRequest& request, const Identity& ca)
|
||||
{
|
||||
gnutls_x509_crt_t cert;
|
||||
if (auto err = gnutls_x509_crt_init(&cert))
|
||||
throw CryptoException(std::string("Can't initialize certificate: ") + gnutls_strerror(err));
|
||||
Certificate ret {cert};
|
||||
if (auto err = gnutls_x509_crt_set_crq(cert, request.get()))
|
||||
throw CryptoException(std::string("Can't initialize certificate: ") + gnutls_strerror(err));
|
||||
|
||||
if (auto err = gnutls_x509_crt_set_version(cert, 3)) {
|
||||
throw CryptoException(std::string("Can't set certificate version: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
|
||||
setRandomSerial(cert);
|
||||
|
||||
if (auto err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) {
|
||||
throw CryptoException(std::string("Can't sign certificate: ") + gnutls_strerror(err));
|
||||
}
|
||||
ret.issuer = ca.second;
|
||||
|
||||
return ret.getPacked();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<RevocationList>>
|
||||
Certificate::getRevocationLists() const
|
||||
{
|
||||
@@ -1002,6 +1157,8 @@ Certificate::getRevocationLists() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
// RevocationList
|
||||
|
||||
RevocationList::RevocationList()
|
||||
{
|
||||
gnutls_x509_crl_init(&crl);
|
||||
@@ -1219,6 +1376,8 @@ RevocationList::toString() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TrustList
|
||||
|
||||
TrustList::TrustList() {
|
||||
gnutls_x509_trust_list_init(&trust, 0);
|
||||
}
|
||||
@@ -1228,11 +1387,11 @@ TrustList::~TrustList() {
|
||||
}
|
||||
|
||||
TrustList&
|
||||
TrustList::operator=(TrustList&& o)
|
||||
TrustList::operator=(TrustList&& o) noexcept
|
||||
{
|
||||
if (trust)
|
||||
gnutls_x509_trust_list_deinit(trust, true);
|
||||
trust = std::move(o.trust);
|
||||
trust = o.trust;
|
||||
o.trust = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -38,7 +38,7 @@ DhtMessage::storePolicy(InfoHash h, std::shared_ptr<Value>& v, const InfoHash& f
|
||||
}
|
||||
|
||||
Value::Filter
|
||||
DhtMessage::ServiceFilter(std::string s)
|
||||
DhtMessage::ServiceFilter(const std::string& s)
|
||||
{
|
||||
return Value::Filter::chain(
|
||||
Value::TypeFilter(TYPE),
|
||||
|
||||
+30
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -537,7 +537,7 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
|
||||
if (auto sr = ws.lock()) {
|
||||
auto l = sr->listeners.find(list_token);
|
||||
if (l != sr->listeners.end()) {
|
||||
l->second.get_cb(l->second.filter.filter(values), expired);
|
||||
l->second.get_cb(values, expired);
|
||||
}
|
||||
}
|
||||
}, [ws,list_token] (ListenSyncStatus status) {
|
||||
@@ -836,41 +836,28 @@ Dht::listen(const InfoHash& id, ValueCallback cb, Value::Filter f, Where where)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
|
||||
Query q {{}, where};
|
||||
auto vals = std::make_shared<std::map<Value::Id, Sp<Value>>>();
|
||||
auto token = ++listener_token;
|
||||
|
||||
auto gcb = OpValueCache::cacheCallback(std::move(cb), [this, id, token]{
|
||||
cancelListen(id, token);
|
||||
});
|
||||
|
||||
auto query = std::make_shared<Query>(q);
|
||||
auto filter = f.chain(q.where.getFilter());
|
||||
size_t tokenlocal = 0;
|
||||
auto query = std::make_shared<Query>(Select{}, std::move(where));
|
||||
auto filter = f.chain(query->where.getFilter());
|
||||
auto st = store.find(id);
|
||||
if (st == store.end() && store.size() < MAX_HASHES)
|
||||
st = store.emplace(id, scheduler.time() + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME).first;
|
||||
|
||||
size_t tokenlocal = 0;
|
||||
if (st != store.end()) {
|
||||
if (not st->second.empty()) {
|
||||
std::vector<Sp<Value>> newvals = st->second.get(filter);
|
||||
if (not newvals.empty()) {
|
||||
if (!gcb(newvals, false))
|
||||
return 0;
|
||||
for (const auto& v : newvals) {
|
||||
auto it = vals->emplace(v->id, v);
|
||||
if (not it.second)
|
||||
it.first->second = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
tokenlocal = ++st->second.listener_token;
|
||||
st->second.local_listeners.emplace(tokenlocal, LocalListener{query, filter, gcb});
|
||||
tokenlocal = st->second.listen(gcb, filter, query);
|
||||
if (tokenlocal == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto token4 = Dht::listenTo(id, AF_INET, gcb, filter, query);
|
||||
auto token6 = token4 == 0 ? 0 : Dht::listenTo(id, AF_INET6, gcb, filter, query);
|
||||
if (token6 == 0 && st != store.end()) {
|
||||
st->second.local_listeners.erase(tokenlocal);
|
||||
st->second.cancelListen(tokenlocal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -889,15 +876,17 @@ Dht::cancelListen(const InfoHash& id, size_t token)
|
||||
return false;
|
||||
}
|
||||
DHT_LOG.d(id, "cancelListen %s with token %d", id.toString().c_str(), token);
|
||||
auto st = store.find(id);
|
||||
auto tokenlocal = std::get<0>(it->second);
|
||||
if (st != store.end() && tokenlocal)
|
||||
st->second.local_listeners.erase(tokenlocal);
|
||||
|
||||
if (auto tokenlocal = std::get<0>(it->second)) {
|
||||
auto st = store.find(id);
|
||||
if (st != store.end())
|
||||
st->second.cancelListen(tokenlocal);
|
||||
}
|
||||
auto searches_cancel_listen = [this,&id](std::map<InfoHash, Sp<Search>>& srs, size_t token) {
|
||||
auto srp = srs.find(id);
|
||||
if (srp != srs.end() and token)
|
||||
srp->second->cancelListen(token, scheduler);
|
||||
if (token) {
|
||||
auto srp = srs.find(id);
|
||||
if (srp != srs.end())
|
||||
srp->second->cancelListen(token, scheduler);
|
||||
}
|
||||
};
|
||||
searches_cancel_listen(searches4, std::get<1>(it->second));
|
||||
searches_cancel_listen(searches6, std::get<2>(it->second));
|
||||
@@ -1276,16 +1265,16 @@ Dht::storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t socket_
|
||||
return;
|
||||
st = store.emplace(id, now).first;
|
||||
}
|
||||
auto node_listeners = st->second.listeners.emplace(node, std::map<size_t, Listener> {}).first;
|
||||
auto l = node_listeners->second.find(socket_id);
|
||||
if (l == node_listeners->second.end()) {
|
||||
auto& node_listeners = st->second.listeners[node];
|
||||
auto l = node_listeners.find(socket_id);
|
||||
if (l == node_listeners.end()) {
|
||||
auto vals = st->second.get(query.where.getFilter());
|
||||
if (not vals.empty()) {
|
||||
network_engine.tellListener(node, socket_id, id, WANT4 | WANT6, makeToken(node->getAddr(), false),
|
||||
buckets4.findClosestNodes(id, now, TARGET_NODES), buckets6.findClosestNodes(id, now, TARGET_NODES),
|
||||
std::move(vals), query);
|
||||
}
|
||||
node_listeners->second.emplace(socket_id, Listener {now, std::forward<Query>(query)});
|
||||
node_listeners.emplace(socket_id, Listener {now, std::forward<Query>(query)});
|
||||
}
|
||||
else
|
||||
l->second.refresh(now, std::forward<Query>(query));
|
||||
@@ -1725,7 +1714,7 @@ Dht::~Dht()
|
||||
|
||||
Dht::Dht() : store(), network_engine(DHT_LOG, scheduler) {}
|
||||
|
||||
Dht::Dht(const int& s, const int& s6, Config config)
|
||||
Dht::Dht(const int& s, const int& s6, const Config& config)
|
||||
: myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
|
||||
network_engine(myid, config.network, s, s6, DHT_LOG, scheduler,
|
||||
std::bind(&Dht::onError, this, _1, _2),
|
||||
@@ -1857,12 +1846,12 @@ Dht::bucketMaintenance(RoutingTable& list)
|
||||
}
|
||||
|
||||
DHT_LOG.d(id, n->id, "[node %s] sending find %s for bucket maintenance", n->toString().c_str(), id.toString().c_str());
|
||||
auto start = scheduler.time();
|
||||
network_engine.sendFindNode(n, id, want, nullptr, [this,start,n](const net::Request&, bool over) {
|
||||
//auto start = scheduler.time();
|
||||
network_engine.sendFindNode(n, id, want, nullptr, [this,n](const net::Request&, bool over) {
|
||||
if (over) {
|
||||
const auto& end = scheduler.time();
|
||||
using namespace std::chrono;
|
||||
DHT_LOG.d(n->id, "[node %s] bucket maintenance op expired after %llu ms", n->toString().c_str(), duration_cast<milliseconds>(end-start).count());
|
||||
// using namespace std::chrono;
|
||||
// DHT_LOG.d(n->id, "[node %s] bucket maintenance op expired after %llu ms", n->toString().c_str(), duration_cast<milliseconds>(end-start).count());
|
||||
scheduler.edit(nextNodesConfirmation, end + Node::MAX_RESPONSE_TIME);
|
||||
}
|
||||
});
|
||||
@@ -1888,7 +1877,7 @@ Dht::dataPersistence(InfoHash id)
|
||||
}
|
||||
|
||||
size_t
|
||||
Dht::maintainStorage(decltype(store)::value_type& storage, bool force, DoneCallback donecb)
|
||||
Dht::maintainStorage(decltype(store)::value_type& storage, bool force, const DoneCallback& donecb)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
size_t announce_per_af = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -75,7 +75,7 @@ DhtRunner::~DhtRunner()
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::run(in_port_t port, DhtRunner::Config config)
|
||||
DhtRunner::run(in_port_t port, const DhtRunner::Config& config)
|
||||
{
|
||||
SockAddr sin4;
|
||||
sin4.setFamily(AF_INET);
|
||||
@@ -87,7 +87,7 @@ DhtRunner::run(in_port_t port, DhtRunner::Config config)
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::run(const char* ip4, const char* ip6, const char* service, DhtRunner::Config config)
|
||||
DhtRunner::run(const char* ip4, const char* ip6, const char* service, const DhtRunner::Config& config)
|
||||
{
|
||||
auto res4 = SockAddr::resolve(ip4, service);
|
||||
auto res6 = SockAddr::resolve(ip6, service);
|
||||
@@ -96,7 +96,7 @@ DhtRunner::run(const char* ip4, const char* ip6, const char* service, DhtRunner:
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::run(const SockAddr& local4, const SockAddr& local6, DhtRunner::Config config)
|
||||
DhtRunner::run(const SockAddr& local4, const SockAddr& local6, const DhtRunner::Config& config)
|
||||
{
|
||||
if (running)
|
||||
return;
|
||||
@@ -629,7 +629,7 @@ DhtRunner::get(InfoHash hash, GetCallback vcb, DoneCallback dcb, Value::Filter f
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops.emplace([=](SecureDht& dht) mutable {
|
||||
dht.get(hash, vcb, dcb, std::move(f), std::move(w));
|
||||
dht.get(hash, std::move(vcb), std::move(dcb), std::move(f), std::move(w));
|
||||
});
|
||||
}
|
||||
cv.notify_all();
|
||||
@@ -638,14 +638,14 @@ DhtRunner::get(InfoHash hash, GetCallback vcb, DoneCallback dcb, Value::Filter f
|
||||
void
|
||||
DhtRunner::get(const std::string& key, GetCallback vcb, DoneCallbackSimple dcb, Value::Filter f, Where w)
|
||||
{
|
||||
get(InfoHash::get(key), vcb, dcb, f, w);
|
||||
get(InfoHash::get(key), std::move(vcb), std::move(dcb), std::move(f), std::move(w));
|
||||
}
|
||||
void
|
||||
DhtRunner::query(const InfoHash& hash, QueryCallback cb, DoneCallback done_cb, Query q) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops.emplace([=](SecureDht& dht) mutable {
|
||||
dht.query(hash, cb, done_cb, std::move(q));
|
||||
dht.query(hash, std::move(cb), std::move(done_cb), std::move(q));
|
||||
});
|
||||
}
|
||||
cv.notify_all();
|
||||
@@ -678,7 +678,7 @@ DhtRunner::listen(InfoHash hash, ValueCallback vcb, Value::Filter f, Where w)
|
||||
listeners_.emplace(tokenbGlobal, std::move(listener));
|
||||
ret_token->set_value(tokenbGlobal);
|
||||
#else
|
||||
ret_token->set_value(dht.listen(hash, vcb, f, w));
|
||||
ret_token->set_value(dht.listen(hash, std::move(vcb), std::move(f), std::move(w)));
|
||||
#endif
|
||||
});
|
||||
}
|
||||
@@ -689,7 +689,7 @@ DhtRunner::listen(InfoHash hash, ValueCallback vcb, Value::Filter f, Where w)
|
||||
std::future<size_t>
|
||||
DhtRunner::listen(const std::string& key, GetCallback vcb, Value::Filter f, Where w)
|
||||
{
|
||||
return listen(InfoHash::get(key), vcb, f, w);
|
||||
return listen(InfoHash::get(key), std::move(vcb), std::move(f), std::move(w));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -768,7 +768,7 @@ DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb, tim
|
||||
void
|
||||
DhtRunner::put(const std::string& key, Value&& value, DoneCallbackSimple cb, time_point created, bool permanent)
|
||||
{
|
||||
put(InfoHash::get(key), std::forward<Value>(value), cb, created, permanent);
|
||||
put(InfoHash::get(key), std::forward<Value>(value), std::move(cb), created, permanent);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -798,13 +798,13 @@ DhtRunner::putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback c
|
||||
void
|
||||
DhtRunner::putSigned(InfoHash hash, Value&& value, DoneCallback cb)
|
||||
{
|
||||
putSigned(hash, std::make_shared<Value>(std::move(value)), cb);
|
||||
putSigned(hash, std::make_shared<Value>(std::move(value)), std::move(cb));
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::putSigned(const std::string& key, Value&& value, DoneCallbackSimple cb)
|
||||
{
|
||||
putSigned(InfoHash::get(key), std::forward<Value>(value), cb);
|
||||
putSigned(InfoHash::get(key), std::forward<Value>(value), std::move(cb));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -822,13 +822,13 @@ DhtRunner::putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value
|
||||
void
|
||||
DhtRunner::putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb)
|
||||
{
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(value)), cb);
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(value)), std::move(cb));
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb)
|
||||
{
|
||||
putEncrypted(InfoHash::get(key), to, std::forward<Value>(value), cb);
|
||||
putEncrypted(InfoHash::get(key), to, std::forward<Value>(value), std::move(cb));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 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>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+139
-131
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -142,19 +142,27 @@ RequestAnswer::RequestAnswer(ParsedMessage&& msg)
|
||||
NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, const int& s, const int& s6)
|
||||
: myid(zeroes), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
{}
|
||||
|
||||
NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
|
||||
decltype(NetworkEngine::onError) onError,
|
||||
decltype(NetworkEngine::onNewNode) onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr) onReportedAddr,
|
||||
decltype(NetworkEngine::onPing) onPing,
|
||||
decltype(NetworkEngine::onFindNode) onFindNode,
|
||||
decltype(NetworkEngine::onGetValues) onGetValues,
|
||||
decltype(NetworkEngine::onListen) onListen,
|
||||
decltype(NetworkEngine::onAnnounce) onAnnounce,
|
||||
decltype(NetworkEngine::onRefresh) onRefresh) :
|
||||
onError(onError), onNewNode(onNewNode), onReportedAddr(onReportedAddr), onPing(onPing), onFindNode(onFindNode),
|
||||
onGetValues(onGetValues), onListen(onListen), onAnnounce(onAnnounce), onRefresh(onRefresh), myid(myid),
|
||||
network(net), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
decltype(NetworkEngine::onError)&& onError,
|
||||
decltype(NetworkEngine::onNewNode)&& onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
|
||||
decltype(NetworkEngine::onPing)&& onPing,
|
||||
decltype(NetworkEngine::onFindNode)&& onFindNode,
|
||||
decltype(NetworkEngine::onGetValues)&& onGetValues,
|
||||
decltype(NetworkEngine::onListen)&& onListen,
|
||||
decltype(NetworkEngine::onAnnounce)&& onAnnounce,
|
||||
decltype(NetworkEngine::onRefresh)&& onRefresh) :
|
||||
onError(std::move(onError)),
|
||||
onNewNode(std::move(onNewNode)),
|
||||
onReportedAddr(std::move(onReportedAddr)),
|
||||
onPing(std::move(onPing)),
|
||||
onFindNode(std::move(onFindNode)),
|
||||
onGetValues(std::move(onGetValues)),
|
||||
onListen(std::move(onListen)),
|
||||
onAnnounce(std::move(onAnnounce)),
|
||||
onRefresh(std::move(onRefresh)),
|
||||
myid(myid), network(net), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
{
|
||||
if (dht_socket >= 0) {
|
||||
if (!set_nonblocking(dht_socket, 1))
|
||||
@@ -191,23 +199,23 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("u"));
|
||||
pk.pack(KEY_U);
|
||||
pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
if (not token.empty()) {
|
||||
pk.pack(std::string("token")); packToken(pk, token);
|
||||
pk.pack(KEY_REQ_TOKEN); packToken(pk, token);
|
||||
}
|
||||
if (not values.empty()) {
|
||||
pk.pack(std::string("re"));
|
||||
pk.pack(KEY_REQ_REFRESHED);
|
||||
pk.pack(values);
|
||||
DHT_LOG.d(n->id, "[node %s] sending %zu refreshed values", n->toString().c_str(), values.size());
|
||||
}
|
||||
|
||||
pk.pack(std::string("t")); pk.pack(socket_id);
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_TID); pk.pack(socket_id);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
// send response
|
||||
@@ -221,23 +229,23 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("u"));
|
||||
pk.pack(KEY_U);
|
||||
pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
if (not token.empty()) {
|
||||
pk.pack(std::string("token")); packToken(pk, token);
|
||||
pk.pack(KEY_REQ_TOKEN); packToken(pk, token);
|
||||
}
|
||||
if (not values.empty()) {
|
||||
pk.pack(std::string("exp"));
|
||||
pk.pack(KEY_REQ_EXPIRED);
|
||||
pk.pack(values);
|
||||
DHT_LOG.d(n->id, "[node %s] sending %zu expired values", n->toString().c_str(), values.size());
|
||||
}
|
||||
|
||||
pk.pack(std::string("t")); pk.pack(socket_id);
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_TID); pk.pack(socket_id);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
// send response
|
||||
@@ -687,16 +695,16 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(1);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_A); pk.pack_map(1);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("ping"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_PING);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Ping, tid.toInt(), node,
|
||||
@@ -724,17 +732,17 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(2);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_R); pk.pack_map(2);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
insertAddr(pk, addr);
|
||||
|
||||
TransId t (tid);
|
||||
pk.pack(std::string("t")); pk.pack_bin(t.size());
|
||||
pk.pack(KEY_TID); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
@@ -748,23 +756,23 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("target")); pk.pack(target);
|
||||
pk.pack(KEY_A); pk.pack_map(2 + (want>0?1:0));
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_TARGET); pk.pack(target);
|
||||
if (want > 0) {
|
||||
pk.pack(std::string("w"));
|
||||
pk.pack(KEY_REQ_WANT);
|
||||
pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0));
|
||||
if (want & WANT4) pk.pack(AF_INET);
|
||||
if (want & WANT6) pk.pack(AF_INET6);
|
||||
}
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("find"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_FIND);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::FindNode, tid.toInt(), n,
|
||||
@@ -794,26 +802,26 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query&
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(2 +
|
||||
pk.pack(KEY_A); pk.pack_map(2 +
|
||||
(query.where.getFilter() or not query.select.getSelection().empty() ? 1:0) +
|
||||
(want>0?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("h")); pk.pack(info_hash);
|
||||
pk.pack(std::string("q")); pk.pack(query);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_H); pk.pack(info_hash);
|
||||
pk.pack(KEY_Q); pk.pack(query);
|
||||
if (want > 0) {
|
||||
pk.pack(std::string("w"));
|
||||
pk.pack(KEY_REQ_WANT);
|
||||
pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0));
|
||||
if (want & WANT4) pk.pack(AF_INET);
|
||||
if (want & WANT6) pk.pack(AF_INET6);
|
||||
}
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("get"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_GET);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::GetValues, tid.toInt(), n,
|
||||
@@ -901,13 +909,13 @@ NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<Sp<Va
|
||||
total_size += v.size();
|
||||
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack(std::string("values"));
|
||||
pk.pack(KEY_REQ_VALUES);
|
||||
pk.pack_array(svals.size());
|
||||
// try to put everything in a single UDP packet
|
||||
if (svals.size() < 50 && total_size < MAX_PACKET_VALUE_SIZE) {
|
||||
for (const auto& b : svals)
|
||||
buffer.write((const char*)b.data(), b.size());
|
||||
DHT_LOG.d("sending %lu bytes of values", total_size);
|
||||
// DHT_LOG.d("sending %lu bytes of values", total_size);
|
||||
svals.clear();
|
||||
} else {
|
||||
for (const auto& b : svals)
|
||||
@@ -929,12 +937,12 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(3+(network?1:0));
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
pk.pack(std::string("y")); pk.pack(std::string("v"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_V);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("p")); pk.pack_map(1);
|
||||
pk.pack(KEY_V); pk.pack_map(1);
|
||||
pk.pack(i); pk.pack_map(2);
|
||||
pk.pack(std::string("o")); pk.pack(start);
|
||||
pk.pack(std::string("d")); pk.pack_bin(end-start);
|
||||
@@ -954,22 +962,22 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("r"));
|
||||
pk.pack(KEY_R);
|
||||
pk.pack_map(2 + (not st.empty()?1:0) + (nodes.size()>0?1:0) + (nodes6.size()>0?1:0) + (not token.empty()?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
insertAddr(pk, addr);
|
||||
if (nodes.size() > 0) {
|
||||
pk.pack(std::string("n4"));
|
||||
pk.pack(KEY_REQ_NODES4);
|
||||
pk.pack_bin(nodes.size());
|
||||
pk.pack_bin_body((const char*)nodes.data(), nodes.size());
|
||||
}
|
||||
if (nodes6.size() > 0) {
|
||||
pk.pack(std::string("n6"));
|
||||
pk.pack(KEY_REQ_NODES6);
|
||||
pk.pack_bin(nodes6.size());
|
||||
pk.pack_bin_body((const char*)nodes6.data(), nodes6.size());
|
||||
}
|
||||
if (not token.empty()) {
|
||||
pk.pack(std::string("token")); packToken(pk, token);
|
||||
pk.pack(KEY_REQ_TOKEN); packToken(pk, token);
|
||||
}
|
||||
std::vector<Blob> svals {};
|
||||
if (not st.empty()) { /* pack complete values */
|
||||
@@ -977,7 +985,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
if (fields.empty()) {
|
||||
svals = packValueHeader(buffer, st);
|
||||
} else { /* pack fields */
|
||||
pk.pack(std::string("fields"));
|
||||
pk.pack(KEY_REQ_FIELDS);
|
||||
pk.pack_map(2);
|
||||
pk.pack(std::string("f")); pk.pack(fields);
|
||||
pk.pack(std::string("v")); pk.pack_array(st.size()*fields.size());
|
||||
@@ -989,12 +997,12 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
}
|
||||
|
||||
TransId t (tid);
|
||||
pk.pack(std::string("t")); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_TID); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
// send response
|
||||
@@ -1086,23 +1094,23 @@ NetworkEngine::sendListen(Sp<Node> n,
|
||||
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(4 + has_query);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("h")); pk.pack(hash);
|
||||
pk.pack(std::string("token")); packToken(pk, token);
|
||||
pk.pack(std::string("sid")); pk.pack_bin(sid.size());
|
||||
pk.pack_bin_body((const char*)sid.data(), sid.size());
|
||||
pk.pack(KEY_A); pk.pack_map(4 + has_query);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_H); pk.pack(hash);
|
||||
pk.pack(KEY_REQ_TOKEN); packToken(pk, token);
|
||||
pk.pack(KEY_REQ_SID); pk.pack_bin(sid.size());
|
||||
pk.pack_bin_body((const char*)sid.data(), sid.size());
|
||||
if (has_query) {
|
||||
pk.pack(std::string("q")); pk.pack(query);
|
||||
pk.pack(KEY_REQ_QUERY); pk.pack(query);
|
||||
}
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("listen"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_LISTEN);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Listen, tid.toInt(), n,
|
||||
@@ -1128,17 +1136,17 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(2);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_R); pk.pack_map(2);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
insertAddr(pk, addr);
|
||||
|
||||
TransId t (tid);
|
||||
pk.pack(std::string("t")); pk.pack_bin(t.size());
|
||||
pk.pack(KEY_TID); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
@@ -1158,23 +1166,23 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map((created < scheduler.time() ? 5 : 4));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("h")); pk.pack(infohash);
|
||||
pk.pack(KEY_A); pk.pack_map((created < scheduler.time() ? 5 : 4));
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_H); pk.pack(infohash);
|
||||
auto v = packValueHeader(buffer, {value});
|
||||
if (created < scheduler.time()) {
|
||||
pk.pack(std::string("c"));
|
||||
pk.pack(KEY_REQ_CREATION);
|
||||
pk.pack(to_time_t(created));
|
||||
}
|
||||
pk.pack(std::string("token")); pk.pack(token);
|
||||
pk.pack(KEY_REQ_TOKEN); pk.pack(token);
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("put"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_PUT);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::AnnounceValue, tid.toInt(), n,
|
||||
@@ -1216,19 +1224,19 @@ NetworkEngine::sendRefreshValue(Sp<Node> n,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(4);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("h")); pk.pack(infohash);
|
||||
pk.pack(std::string("vid")); pk.pack(vid);
|
||||
pk.pack(std::string("token")); pk.pack(token);
|
||||
pk.pack(KEY_A); pk.pack_map(4);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_H); pk.pack(infohash);
|
||||
pk.pack(KEY_REQ_VALUE_ID); pk.pack(vid);
|
||||
pk.pack(KEY_REQ_TOKEN); pk.pack(token);
|
||||
|
||||
pk.pack(std::string("q")); pk.pack(std::string("refresh"));
|
||||
pk.pack(std::string("t")); pk.pack_bin(tid.size());
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_REFRESH);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Refresh, tid.toInt(), n,
|
||||
@@ -1261,18 +1269,18 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid)
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(3);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(std::string("vid")); pk.pack(vid);
|
||||
pk.pack(KEY_R); pk.pack_map(3);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
pk.pack(KEY_REQ_VALUE_ID); pk.pack(vid);
|
||||
insertAddr(pk, addr);
|
||||
|
||||
TransId t(tid);
|
||||
pk.pack(std::string("t")); pk.pack_bin(t.size());
|
||||
pk.pack(KEY_TID); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
@@ -1289,22 +1297,22 @@ NetworkEngine::sendError(const SockAddr& addr,
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4 + (include_id?1:0));
|
||||
|
||||
pk.pack(std::string("e")); pk.pack_array(2);
|
||||
pk.pack(KEY_E); pk.pack_array(2);
|
||||
pk.pack(code);
|
||||
pk.pack(message);
|
||||
|
||||
if (include_id) {
|
||||
pk.pack(std::string("r")); pk.pack_map(1);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
pk.pack(KEY_R); pk.pack_map(1);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
}
|
||||
|
||||
TransId t(tid);
|
||||
pk.pack(std::string("t")); pk.pack_bin(t.size());
|
||||
pk.pack(KEY_TID); pk.pack_bin(t.size());
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("e"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_E);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -49,7 +49,7 @@ Node::isGood(time_point now) const
|
||||
bool
|
||||
Node::isPendingMessage() const
|
||||
{
|
||||
for (auto r : requests_) {
|
||||
for (const auto& r : requests_) {
|
||||
if (r.second->pending())
|
||||
return true;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ size_t
|
||||
Node::getPendingMessageCount() const
|
||||
{
|
||||
size_t count {0};
|
||||
for (auto r : requests_) {
|
||||
for (const auto& r : requests_) {
|
||||
if (r.second->pending())
|
||||
count++;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -160,7 +160,7 @@ SearchCache::getOp(const Sp<Query>& q) const
|
||||
}
|
||||
|
||||
size_t
|
||||
SearchCache::listen(ValueCallback get_cb, Sp<Query> q, Value::Filter filter, OnListen onListen)
|
||||
SearchCache::listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value::Filter& filter, const OnListen& onListen)
|
||||
{
|
||||
// find exact match
|
||||
auto op = getOp(q);
|
||||
@@ -192,7 +192,7 @@ SearchCache::cancelListen(size_t gtoken, const time_point& now) {
|
||||
}
|
||||
|
||||
void
|
||||
SearchCache::cancelAll(std::function<void(size_t)> onCancel) {
|
||||
SearchCache::cancelAll(const std::function<void(size_t)>& onCancel) {
|
||||
for (auto& op : ops) {
|
||||
auto cache = std::move(op.second);
|
||||
cache->removeAll();
|
||||
@@ -202,7 +202,7 @@ SearchCache::cancelAll(std::function<void(size_t)> onCancel) {
|
||||
}
|
||||
|
||||
time_point
|
||||
SearchCache::expire(const time_point& now, std::function<void(size_t)> onCancel) {
|
||||
SearchCache::expire(const time_point& now, const std::function<void(size_t)>& onCancel) {
|
||||
nextExpiration_ = time_point::max();
|
||||
auto ret = nextExpiration_;
|
||||
for (auto it = ops.begin(); it != ops.end();) {
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
void onValuesAdded(const std::vector<Sp<Value>>& vals);
|
||||
void onValuesExpired(const std::vector<Sp<Value>>& vals);
|
||||
|
||||
bool addListener(size_t token, ValueCallback cb, Sp<Query> q, Value::Filter filter) {
|
||||
bool addListener(size_t token, const ValueCallback& cb, const Sp<Query>& q, const Value::Filter& filter) {
|
||||
listeners.emplace(token, LocalListener{q, filter, cb});
|
||||
auto cached = cache.get(filter);
|
||||
if (not cached.empty()) {
|
||||
@@ -163,12 +163,12 @@ public:
|
||||
SearchCache(SearchCache&&) = default;
|
||||
|
||||
using OnListen = std::function<size_t(Sp<Query>, ValueCallback, SyncCallback)>;
|
||||
size_t listen(ValueCallback get_cb, Sp<Query> q, Value::Filter filter, OnListen onListen);
|
||||
size_t listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value::Filter& filter, const OnListen& onListen);
|
||||
|
||||
bool cancelListen(size_t gtoken, const time_point& now);
|
||||
void cancelAll(std::function<void(size_t)> onCancel);
|
||||
void cancelAll(const std::function<void(size_t)>& onCancel);
|
||||
|
||||
time_point expire(const time_point& now, std::function<void(size_t)> onCancel);
|
||||
time_point expire(const time_point& now, const std::function<void(size_t)>& onCancel);
|
||||
time_point getExpiration() const {
|
||||
return nextExpiration_;
|
||||
}
|
||||
|
||||
+156
-93
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -26,6 +26,42 @@
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
static const std::string KEY_Y {"y"};
|
||||
static const std::string KEY_R {"r"};
|
||||
static const std::string KEY_U {"u"};
|
||||
static const std::string KEY_E {"e"};
|
||||
static const std::string KEY_V {"p"};
|
||||
static const std::string KEY_TID {"t"};
|
||||
static const std::string KEY_UA {"v"};
|
||||
static const std::string KEY_NETID {"n"};
|
||||
static const std::string KEY_ISCLIENT {"s"};
|
||||
static const std::string KEY_Q {"q"};
|
||||
static const std::string KEY_A {"a"};
|
||||
|
||||
static const std::string KEY_REQ_SID {"sid"};
|
||||
static const std::string KEY_REQ_ID {"id"};
|
||||
static const std::string KEY_REQ_H {"h"};
|
||||
static const std::string KEY_REQ_TARGET {"target"};
|
||||
static const std::string KEY_REQ_QUERY {"q"};
|
||||
static const std::string KEY_REQ_TOKEN {"token"};
|
||||
static const std::string KEY_REQ_VALUE_ID {"vid"};
|
||||
static const std::string KEY_REQ_NODES4 {"n4"};
|
||||
static const std::string KEY_REQ_NODES6 {"n6"};
|
||||
static const std::string KEY_REQ_CREATION {"c"};
|
||||
static const std::string KEY_REQ_ADDRESS {"sa"};
|
||||
static const std::string KEY_REQ_VALUES {"values"};
|
||||
static const std::string KEY_REQ_EXPIRED {"exp"};
|
||||
static const std::string KEY_REQ_REFRESHED {"re"};
|
||||
static const std::string KEY_REQ_FIELDS {"fileds"};
|
||||
static const std::string KEY_REQ_WANT {"w"};
|
||||
|
||||
static const std::string QUERY_PING {"ping"};
|
||||
static const std::string QUERY_FIND {"find"};
|
||||
static const std::string QUERY_GET {"get"};
|
||||
static const std::string QUERY_PUT {"put"};
|
||||
static const std::string QUERY_LISTEN {"listen"};
|
||||
static const std::string QUERY_REFRESH {"refresh"};
|
||||
|
||||
Tid unpackTid(const msgpack::object& o) {
|
||||
switch (o.type) {
|
||||
case msgpack::type::POSITIVE_INTEGER:
|
||||
@@ -78,7 +114,7 @@ struct ParsedMessage {
|
||||
/* reported address by the distant node */
|
||||
std::string ua;
|
||||
SockAddr addr;
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
void msgpack_unpack(const msgpack::object& o);
|
||||
|
||||
bool append(const ParsedMessage& block);
|
||||
bool complete();
|
||||
@@ -123,63 +159,79 @@ ParsedMessage::complete()
|
||||
}
|
||||
|
||||
void
|
||||
ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
{
|
||||
auto y = findMapValue(msg, "y");
|
||||
auto r = findMapValue(msg, "r");
|
||||
auto u = findMapValue(msg, "u");
|
||||
auto e = findMapValue(msg, "e");
|
||||
auto v = findMapValue(msg, "p");
|
||||
if (msg.type != msgpack::type::MAP) throw msgpack::type_error();
|
||||
|
||||
if (auto t = findMapValue(msg, "t"))
|
||||
tid = unpackTid(*t);
|
||||
struct ParsedMsg {
|
||||
msgpack::object* y;
|
||||
msgpack::object* r;
|
||||
msgpack::object* u;
|
||||
msgpack::object* e;
|
||||
msgpack::object* v;
|
||||
msgpack::object* a;
|
||||
std::string q;
|
||||
} parsed {};
|
||||
|
||||
if (auto rv = findMapValue(msg, "v"))
|
||||
ua = rv->as<std::string>();
|
||||
|
||||
if (auto netid = findMapValue(msg, "n"))
|
||||
network = netid->as<NetId>();
|
||||
|
||||
if (auto is_client_v = findMapValue(msg, "s"))
|
||||
is_client = is_client_v->as<bool>();
|
||||
|
||||
std::string q;
|
||||
if (auto rq = findMapValue(msg, "q")) {
|
||||
if (rq->type != msgpack::type::STR)
|
||||
throw msgpack::type_error();
|
||||
q = rq->as<std::string>();
|
||||
for (unsigned i = 0; i < msg.via.map.size; i++) {
|
||||
auto& o = msg.via.map.ptr[i];
|
||||
if (o.key.type != msgpack::type::STR)
|
||||
continue;
|
||||
auto key = o.key.as<std::string>();
|
||||
if (key == KEY_Y)
|
||||
parsed.y = &o.val;
|
||||
else if (key == KEY_R)
|
||||
parsed.r = &o.val;
|
||||
else if (key == KEY_U)
|
||||
parsed.u = &o.val;
|
||||
else if (key == KEY_E)
|
||||
parsed.e = &o.val;
|
||||
else if (key == KEY_V)
|
||||
parsed.v = &o.val;
|
||||
else if (key == KEY_TID)
|
||||
tid = unpackTid(o.val);
|
||||
else if (key == KEY_UA)
|
||||
ua = o.val.as<std::string>();
|
||||
else if (key == KEY_NETID)
|
||||
network = o.val.as<NetId>();
|
||||
else if (key == KEY_ISCLIENT)
|
||||
is_client = o.val.as<bool>();
|
||||
else if (key == KEY_Q)
|
||||
parsed.q = o.val.as<std::string>();
|
||||
else if (key == KEY_A)
|
||||
parsed.a = &o.val;
|
||||
}
|
||||
|
||||
if (e)
|
||||
if (parsed.e)
|
||||
type = MessageType::Error;
|
||||
else if (r)
|
||||
else if (parsed.r)
|
||||
type = MessageType::Reply;
|
||||
else if (v)
|
||||
else if (parsed.v)
|
||||
type = MessageType::ValueData;
|
||||
else if (u)
|
||||
else if (parsed.u)
|
||||
type = MessageType::ValueUpdate;
|
||||
else if (y and y->as<std::string>() != "q")
|
||||
else if (parsed.y and parsed.y->as<std::string>() != "q")
|
||||
throw msgpack::type_error();
|
||||
else if (q == "ping")
|
||||
else if (parsed.q == QUERY_PING)
|
||||
type = MessageType::Ping;
|
||||
else if (q == "find")
|
||||
else if (parsed.q == QUERY_FIND)
|
||||
type = MessageType::FindNode;
|
||||
else if (q == "get")
|
||||
else if (parsed.q == QUERY_GET)
|
||||
type = MessageType::GetValues;
|
||||
else if (q == "listen")
|
||||
else if (parsed.q == QUERY_LISTEN)
|
||||
type = MessageType::Listen;
|
||||
else if (q == "put")
|
||||
else if (parsed.q == QUERY_PUT)
|
||||
type = MessageType::AnnounceValue;
|
||||
else if (q == "refresh")
|
||||
else if (parsed.q == QUERY_REFRESH)
|
||||
type = MessageType::Refresh;
|
||||
else
|
||||
throw msgpack::type_error();
|
||||
|
||||
if (type == MessageType::ValueData) {
|
||||
if (v->type != msgpack::type::MAP)
|
||||
if (parsed.v->type != msgpack::type::MAP)
|
||||
throw msgpack::type_error();
|
||||
for (size_t i = 0; i < v->via.map.size; ++i) {
|
||||
auto& vdat = v->via.map.ptr[i];
|
||||
for (size_t i = 0; i < parsed.v->via.map.size; ++i) {
|
||||
auto& vdat = parsed.v->via.map.ptr[i];
|
||||
auto o = findMapValue(vdat.val, "o");
|
||||
auto d = findMapValue(vdat.val, "d");
|
||||
if (not o or not d)
|
||||
@@ -189,70 +241,85 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
return;
|
||||
}
|
||||
|
||||
auto a = findMapValue(msg, "a");
|
||||
if (!a && !r && !e && !u)
|
||||
if (!parsed.a && !parsed.r && !parsed.e && !parsed.u)
|
||||
throw msgpack::type_error();
|
||||
auto& req = a ? *a : (r ? *r : (u ? *u : *e));
|
||||
auto& req = parsed.a ? *parsed.a : (parsed.r ? *parsed.r : (parsed.u ? *parsed.u : *parsed.e));
|
||||
|
||||
if (e) {
|
||||
if (e->type != msgpack::type::ARRAY)
|
||||
if (parsed.e) {
|
||||
if (parsed.e->type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
error_code = e->via.array.ptr[0].as<uint16_t>();
|
||||
error_code = parsed.e->via.array.ptr[0].as<uint16_t>();
|
||||
}
|
||||
|
||||
if (auto t = findMapValue(req, "sid"))
|
||||
socket_id = unpackTid(*t);
|
||||
struct ParsedReq {
|
||||
msgpack::object* values;
|
||||
msgpack::object* fields;
|
||||
msgpack::object* sa;
|
||||
msgpack::object* want;
|
||||
} parsedReq {};
|
||||
|
||||
if (auto rid = findMapValue(req, "id"))
|
||||
id = {*rid};
|
||||
for (unsigned i = 0; i < req.via.map.size; i++) {
|
||||
auto& o = req.via.map.ptr[i];
|
||||
if (o.key.type != msgpack::type::STR)
|
||||
continue;
|
||||
auto key = o.key.as<std::string>();
|
||||
if (key == KEY_REQ_SID)
|
||||
socket_id = unpackTid(o.val);
|
||||
else if (key == KEY_REQ_ID)
|
||||
id = {o.val};
|
||||
else if (key == KEY_REQ_H)
|
||||
info_hash = {o.val};
|
||||
else if (key == KEY_REQ_TARGET)
|
||||
target = {o.val};
|
||||
else if (key == KEY_REQ_QUERY)
|
||||
query.msgpack_unpack(o.val);
|
||||
else if (key == KEY_REQ_TOKEN)
|
||||
token = unpackBlob(o.val);
|
||||
else if (key == KEY_REQ_VALUE_ID)
|
||||
value_id = o.val.as<Value::Id>();
|
||||
else if (key == KEY_REQ_NODES4)
|
||||
nodes4_raw = unpackBlob(o.val);
|
||||
else if (key == KEY_REQ_NODES6)
|
||||
nodes6_raw = unpackBlob(o.val);
|
||||
else if (key == KEY_REQ_ADDRESS)
|
||||
parsedReq.sa = &o.val;
|
||||
else if (key == KEY_REQ_CREATION)
|
||||
created = from_time_t(o.val.as<std::time_t>());
|
||||
else if (key == KEY_REQ_VALUES)
|
||||
parsedReq.values = &o.val;
|
||||
else if (key == KEY_REQ_EXPIRED)
|
||||
expired_values = o.val.as<decltype(expired_values)>();
|
||||
else if (key == KEY_REQ_REFRESHED)
|
||||
refreshed_values = o.val.as<decltype(refreshed_values)>();
|
||||
else if (key == KEY_REQ_FIELDS)
|
||||
parsedReq.fields = &o.val;
|
||||
else if (key == KEY_REQ_WANT)
|
||||
parsedReq.want = &o.val;
|
||||
}
|
||||
|
||||
if (auto rh = findMapValue(req, "h"))
|
||||
info_hash = {*rh};
|
||||
|
||||
if (auto rtarget = findMapValue(req, "target"))
|
||||
target = {*rtarget};
|
||||
|
||||
if (auto rquery = findMapValue(req, "q"))
|
||||
query.msgpack_unpack(*rquery);
|
||||
|
||||
if (auto otoken = findMapValue(req, "token"))
|
||||
token = unpackBlob(*otoken);
|
||||
|
||||
if (auto vid = findMapValue(req, "vid"))
|
||||
value_id = vid->as<Value::Id>();
|
||||
|
||||
if (auto rnodes4 = findMapValue(req, "n4"))
|
||||
nodes4_raw = unpackBlob(*rnodes4);
|
||||
|
||||
if (auto rnodes6 = findMapValue(req, "n6"))
|
||||
nodes6_raw = unpackBlob(*rnodes6);
|
||||
|
||||
if (auto sa = findMapValue(req, "sa")) {
|
||||
if (sa->type != msgpack::type::BIN)
|
||||
if (parsedReq.sa) {
|
||||
if (parsedReq.sa->type != msgpack::type::BIN)
|
||||
throw msgpack::type_error();
|
||||
auto l = sa->via.bin.size;
|
||||
auto l = parsedReq.sa->via.bin.size;
|
||||
if (l == sizeof(in_addr)) {
|
||||
addr.setFamily(AF_INET);
|
||||
auto& a = addr.getIPv4();
|
||||
a.sin_port = 0;
|
||||
std::copy_n(sa->via.bin.ptr, l, (char*)&a.sin_addr);
|
||||
std::copy_n(parsedReq.sa->via.bin.ptr, l, (char*)&a.sin_addr);
|
||||
} else if (l == sizeof(in6_addr)) {
|
||||
addr.setFamily(AF_INET6);
|
||||
auto& a = addr.getIPv6();
|
||||
a.sin6_port = 0;
|
||||
std::copy_n(sa->via.bin.ptr, l, (char*)&a.sin6_addr);
|
||||
std::copy_n(parsedReq.sa->via.bin.ptr, l, (char*)&a.sin6_addr);
|
||||
}
|
||||
} else
|
||||
addr = {};
|
||||
|
||||
if (auto rcreated = findMapValue(req, "c"))
|
||||
created = from_time_t(rcreated->as<std::time_t>());
|
||||
|
||||
if (auto rvalues = findMapValue(req, "values")) {
|
||||
if (rvalues->type != msgpack::type::ARRAY)
|
||||
if (parsedReq.values) {
|
||||
if (parsedReq.values->type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
for (size_t i = 0; i < rvalues->via.array.size; i++) {
|
||||
auto& packed_v = rvalues->via.array.ptr[i];
|
||||
for (size_t i = 0; i < parsedReq.values->via.array.size; i++) {
|
||||
auto& packed_v = parsedReq.values->via.array.ptr[i];
|
||||
if (packed_v.type == msgpack::type::POSITIVE_INTEGER) {
|
||||
// Skip oversize values with a small margin for header overhead
|
||||
if (packed_v.via.u64 > MAX_VALUE_SIZE + 32)
|
||||
@@ -260,16 +327,16 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
value_parts.emplace(i, std::make_pair(packed_v.via.u64, Blob{}));
|
||||
} else {
|
||||
try {
|
||||
values.emplace_back(std::make_shared<Value>(rvalues->via.array.ptr[i]));
|
||||
values.emplace_back(std::make_shared<Value>(parsedReq.values->via.array.ptr[i]));
|
||||
} catch (const std::exception& e) {
|
||||
//DHT_LOG_WARN("Error reading value: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (auto raw_fields = findMapValue(req, "fields")) {
|
||||
if (auto rfields = findMapValue(*raw_fields, "f")) {
|
||||
} else if (parsedReq.fields) {
|
||||
if (auto rfields = findMapValue(*parsedReq.fields, "f")) {
|
||||
auto vfields = rfields->as<std::set<Value::Field>>();
|
||||
if (auto rvalues = findMapValue(*raw_fields, "v")) {
|
||||
if (auto rvalues = findMapValue(*parsedReq.fields, "v")) {
|
||||
if (rvalues->type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
size_t val_num = rvalues->via.array.size / vfields.size();
|
||||
@@ -284,18 +351,14 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
} else {
|
||||
throw msgpack::type_error();
|
||||
}
|
||||
} else if (auto raw_fields = findMapValue(req, "exp")) {
|
||||
expired_values = raw_fields->as<decltype(expired_values)>();
|
||||
} else if (auto raw_fields = findMapValue(req, "re")) {
|
||||
refreshed_values = raw_fields->as<decltype(refreshed_values)>();
|
||||
}
|
||||
|
||||
if (auto w = findMapValue(req, "w")) {
|
||||
if (w->type != msgpack::type::ARRAY)
|
||||
if (parsedReq.want) {
|
||||
if (parsedReq.want->type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
want = 0;
|
||||
for (unsigned i=0; i<w->via.array.size; i++) {
|
||||
auto& val = w->via.array.ptr[i];
|
||||
for (unsigned i=0; i<parsedReq.want->via.array.size; i++) {
|
||||
auto& val = parsedReq.want->via.array.ptr[i];
|
||||
try {
|
||||
auto w = val.as<sa_family_t>();
|
||||
if (w == AF_INET)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -92,7 +92,7 @@ RoutingTable::middle(const RoutingTable::const_iterator& it) const
|
||||
throw std::out_of_range("End of table");
|
||||
|
||||
InfoHash id = it->first;
|
||||
id.setBit(bit, 1);
|
||||
id.setBit(bit, true);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -387,7 +387,6 @@ struct Dht::Search {
|
||||
/* listeners */
|
||||
struct SearchListener {
|
||||
Sp<Query> query;
|
||||
Value::Filter filter;
|
||||
ValueCallback get_cb;
|
||||
SyncCallback sync_cb;
|
||||
};
|
||||
@@ -489,7 +488,7 @@ struct Dht::Search {
|
||||
bool isAnnounced(Value::Id id) const;
|
||||
bool isListening(time_point now) const;
|
||||
|
||||
void get(Value::Filter f, const Sp<Query>& q, const QueryCallback& qcb, const GetCallback& gcb, const DoneCallback& dcb, Scheduler& scheduler) {
|
||||
void get(const Value::Filter& f, const Sp<Query>& q, const QueryCallback& qcb, const GetCallback& gcb, const DoneCallback& dcb, Scheduler& scheduler) {
|
||||
if (gcb or qcb) {
|
||||
if (not cache.get(f, q, gcb, dcb)) {
|
||||
const auto& now = scheduler.time();
|
||||
@@ -499,12 +498,12 @@ struct Dht::Search {
|
||||
}
|
||||
}
|
||||
|
||||
size_t listen(ValueCallback cb, Value::Filter f, const Sp<Query>& q, Scheduler& scheduler) {
|
||||
size_t listen(const ValueCallback& cb, const Value::Filter& f, const Sp<Query>& q, Scheduler& scheduler) {
|
||||
//DHT_LOG.e(id, "[search %s IPv%c] listen", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
return cache.listen(cb, q, f, [&](const Sp<Query>& q, ValueCallback vcb, SyncCallback scb){
|
||||
done = false;
|
||||
auto token = ++listener_token;
|
||||
listeners.emplace(token, SearchListener{q, f, vcb, scb});
|
||||
listeners.emplace(token, SearchListener{q, vcb, scb});
|
||||
scheduler.edit(nextSearchStep, scheduler.time());
|
||||
return token;
|
||||
});
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -61,8 +61,7 @@ SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf)
|
||||
}
|
||||
}
|
||||
|
||||
SecureDht::~SecureDht()
|
||||
{}
|
||||
SecureDht::~SecureDht() = default;
|
||||
|
||||
ValueType
|
||||
SecureDht::secureType(ValueType&& type)
|
||||
@@ -166,7 +165,7 @@ SecureDht::registerCertificate(Sp<crypto::Certificate>& cert)
|
||||
}
|
||||
|
||||
void
|
||||
SecureDht::findCertificate(const InfoHash& node, std::function<void(const Sp<crypto::Certificate>)> cb)
|
||||
SecureDht::findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb)
|
||||
{
|
||||
Sp<crypto::Certificate> b = getCertificate(node);
|
||||
if (b && *b) {
|
||||
@@ -207,7 +206,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const Sp<cry
|
||||
}
|
||||
|
||||
void
|
||||
SecureDht::findPublicKey(const InfoHash& node, std::function<void(const Sp<const crypto::PublicKey>)> cb)
|
||||
SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb)
|
||||
{
|
||||
auto pk = getPublicKey(node);
|
||||
if (pk && *pk) {
|
||||
@@ -280,7 +279,7 @@ SecureDht::checkValue(const Sp<Value>& v)
|
||||
}
|
||||
|
||||
ValueCallback
|
||||
SecureDht::getCallbackFilter(ValueCallback cb, Value::Filter&& filter)
|
||||
SecureDht::getCallbackFilter(const ValueCallback& cb, Value::Filter&& filter)
|
||||
{
|
||||
return [=](const std::vector<Sp<Value>>& values, bool expired) {
|
||||
std::vector<Sp<Value>> tmpvals {};
|
||||
@@ -299,7 +298,7 @@ SecureDht::getCallbackFilter(ValueCallback cb, Value::Filter&& filter)
|
||||
|
||||
|
||||
GetCallback
|
||||
SecureDht::getCallbackFilter(GetCallback cb, Value::Filter&& filter)
|
||||
SecureDht::getCallbackFilter(const GetCallback& cb, Value::Filter&& filter)
|
||||
{
|
||||
return [=](const std::vector<Sp<Value>>& values) {
|
||||
std::vector<Sp<Value>> tmpvals {};
|
||||
|
||||
+23
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -153,6 +153,12 @@ struct Storage {
|
||||
return time_point::max();
|
||||
}
|
||||
|
||||
size_t listen(ValueCallback& cb, Value::Filter& f, const Sp<Query>& q);
|
||||
|
||||
void cancelListen(size_t token) {
|
||||
local_listeners.erase(token);
|
||||
}
|
||||
|
||||
StoreDiff remove(const InfoHash& id, Value::Id);
|
||||
|
||||
std::pair<ssize_t, std::vector<Sp<Value>>> expire(const InfoHash& id, time_point now);
|
||||
@@ -166,6 +172,22 @@ private:
|
||||
};
|
||||
|
||||
|
||||
size_t
|
||||
Storage::listen(ValueCallback& gcb, Value::Filter& filter, const Sp<Query>& query)
|
||||
{
|
||||
if (not empty()) {
|
||||
std::vector<Sp<Value>> newvals = get(filter);
|
||||
if (not newvals.empty()) {
|
||||
if (!gcb(newvals, false))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
auto tokenlocal = ++listener_token;
|
||||
local_listeners.emplace(tokenlocal, LocalListener{query, filter, gcb});
|
||||
return tokenlocal;
|
||||
}
|
||||
|
||||
|
||||
std::pair<ValueStorage*, Storage::StoreDiff>
|
||||
Storage::store(const InfoHash& id, const Sp<Value>& value, time_point created, time_point expiration, StorageBucket* sb)
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -65,8 +65,8 @@ std::ostream& operator<< (std::ostream& s, const Value& v)
|
||||
} else {
|
||||
s << "Data (type: " << v.type << " ): ";
|
||||
s << std::hex;
|
||||
for (size_t i=0; i<v.data.size(); i++)
|
||||
s << std::setfill('0') << std::setw(2) << (unsigned)v.data[i];
|
||||
for (auto i : v.data)
|
||||
s << std::setfill('0') << std::setw(2) << (unsigned)i;
|
||||
s << std::dec;
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ std::ostream& operator<< (std::ostream& s, const Value& v)
|
||||
const ValueType ValueType::USER_DATA = {0, "User Data"};
|
||||
|
||||
bool
|
||||
ValueType::DEFAULT_STORE_POLICY(InfoHash, std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&)
|
||||
ValueType::DEFAULT_STORE_POLICY(InfoHash, const std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&)
|
||||
{
|
||||
return v->size() <= MAX_VALUE_SIZE;
|
||||
}
|
||||
@@ -292,7 +292,7 @@ FieldValue::getLocalFilter() const
|
||||
}
|
||||
}
|
||||
|
||||
FieldValueIndex::FieldValueIndex(const Value& v, Select s)
|
||||
FieldValueIndex::FieldValueIndex(const Value& v, const Select& s)
|
||||
{
|
||||
auto selection = s.getSelection();
|
||||
if (not selection.empty()) {
|
||||
@@ -399,8 +399,8 @@ FieldValueIndex::msgpack_unpack_fields(const std::set<Value::Field>& fields, con
|
||||
}
|
||||
|
||||
void trim_str(std::string& str) {
|
||||
auto first = std::min(str.size(), str.find_first_not_of(" "));
|
||||
auto last = std::min(str.size(), str.find_last_not_of(" "));
|
||||
auto first = std::min(str.size(), str.find_first_not_of(' '));
|
||||
auto last = std::min(str.size(), str.find_last_not_of(' '));
|
||||
str = str.substr(first, last - first + 1);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ bin_PROGRAMS = opendht_unit_tests
|
||||
|
||||
AM_CPPFLAGS = -I../include
|
||||
|
||||
nobase_include_HEADERS = infohashtester.h cryptotester.h dhtrunnertester.h dhtproxytester.h
|
||||
opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp dhtrunnertester.cpp dhtproxytester.cpp
|
||||
nobase_include_HEADERS = infohashtester.h valuetester.h cryptotester.h dhtrunnertester.h dhtproxytester.h
|
||||
opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp valuetester.cpp dhtrunnertester.cpp dhtproxytester.cpp
|
||||
opendht_unit_tests_LDFLAGS = -lopendht -lcppunit -L@top_builddir@/src/.libs @GnuTLS_LIBS@
|
||||
endif
|
||||
+30
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -54,7 +54,6 @@ CryptoTester::testCertificateRevocation()
|
||||
auto device11 = dht::crypto::generateIdentity("dev11", account1);
|
||||
auto device12 = dht::crypto::generateIdentity("dev12", account1);
|
||||
|
||||
|
||||
dht::crypto::TrustList list;
|
||||
list.add(*ca1.second);
|
||||
auto v = list.verify(*account1.second);
|
||||
@@ -72,7 +71,7 @@ CryptoTester::testCertificateRevocation()
|
||||
|
||||
v = list.verify(*device2.second);
|
||||
CPPUNIT_ASSERT_MESSAGE(v.toString(), !v);
|
||||
|
||||
|
||||
account1.second->revoke(*account1.first, *device11.second);
|
||||
dht::crypto::TrustList list2;
|
||||
list2.add(*account1.second);
|
||||
@@ -83,6 +82,34 @@ CryptoTester::testCertificateRevocation()
|
||||
CPPUNIT_ASSERT_MESSAGE(v.toString(), v);
|
||||
}
|
||||
|
||||
void
|
||||
CryptoTester::testCertificateRequest()
|
||||
{
|
||||
// Generate CA
|
||||
auto ca = dht::crypto::generateIdentity("Test CA");
|
||||
|
||||
// Generate signed request
|
||||
auto deviceKey = dht::crypto::PrivateKey::generate();
|
||||
auto request = dht::crypto::CertificateRequest();
|
||||
request.setName("Test Device");
|
||||
request.sign(deviceKey);
|
||||
|
||||
// Export/import request
|
||||
auto importedRequest = dht::crypto::CertificateRequest(request.pack());
|
||||
CPPUNIT_ASSERT(importedRequest.verify());
|
||||
|
||||
// Generate/sign certificate from request
|
||||
auto signedCert = dht::crypto::Certificate::generate(request, ca);
|
||||
CPPUNIT_ASSERT_EQUAL(ca.second->getName(), signedCert.getIssuerName());
|
||||
CPPUNIT_ASSERT_EQUAL(request.getName(), signedCert.getName());
|
||||
|
||||
// Check generated certificate
|
||||
dht::crypto::TrustList list;
|
||||
list.add(*ca.second);
|
||||
auto v = list.verify(signedCert);
|
||||
CPPUNIT_ASSERT_MESSAGE(v.toString(), v);
|
||||
}
|
||||
|
||||
void
|
||||
CryptoTester::tearDown() {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -29,6 +29,7 @@ class CryptoTester : public CppUnit::TestFixture {
|
||||
CPPUNIT_TEST_SUITE(CryptoTester);
|
||||
CPPUNIT_TEST(testSignatureEncryption);
|
||||
CPPUNIT_TEST(testCertificateRevocation);
|
||||
CPPUNIT_TEST(testCertificateRequest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@@ -48,6 +49,10 @@ class CryptoTester : public CppUnit::TestFixture {
|
||||
* Test certificate generation, validation and revocation
|
||||
*/
|
||||
void testCertificateRevocation();
|
||||
/**
|
||||
* Test certificate requests
|
||||
*/
|
||||
void testCertificateRequest();
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
@@ -38,14 +38,13 @@ void
|
||||
InfoHashTester::testConstructors() {
|
||||
// Default constructor creates a null infohash
|
||||
auto nullHash = dht::InfoHash();
|
||||
CPPUNIT_ASSERT(nullHash.size() == 20);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)20u, nullHash.size());
|
||||
CPPUNIT_ASSERT(!nullHash);
|
||||
// Build from a uint8_t. if length to short, should get a null infohash
|
||||
uint8_t to_short[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
|
||||
auto infohash = dht::InfoHash(to_short, 8);
|
||||
CPPUNIT_ASSERT(infohash.size() == 20);
|
||||
CPPUNIT_ASSERT_EQUAL(infohash.toString(),
|
||||
std::string("0000000000000000000000000000000000000000"));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)20u, infohash.size());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("0000000000000000000000000000000000000000"), infohash.toString());
|
||||
// Build from a uint8_t. if length is enough, data should contains the uint8_t
|
||||
uint8_t enough[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
|
||||
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
|
||||
@@ -66,7 +65,7 @@ InfoHashTester::testConstructors() {
|
||||
}
|
||||
// Build from string
|
||||
auto infohashFromStr = dht::InfoHash("0102030405060708090A0102030405060708090A");
|
||||
CPPUNIT_ASSERT(infohashFromStr.size() == 20);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)20u, infohashFromStr.size());
|
||||
const auto* dataStr = infohashFromStr.data();
|
||||
for (auto i = 0; i < 20; ++i) {
|
||||
CPPUNIT_ASSERT_EQUAL((int)dataStr[i], (int)data[i]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <cppunit/CompilerOutputter.h>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int /*argc*/, char** /*argv*/) {
|
||||
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry();
|
||||
CppUnit::Test *suite = registry.makeTest();
|
||||
if (suite->countTestCases() == 0) {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "valuetester.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// opendht
|
||||
#include "opendht/value.h"
|
||||
|
||||
namespace test {
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(ValueTester);
|
||||
|
||||
void
|
||||
ValueTester::setUp() {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ValueTester::testConstructors() {
|
||||
std::string the_data {"42 cats"};
|
||||
dht::Value the_dht_value {(const uint8_t*)the_data.data(), the_data.size()};
|
||||
std::string from_value {the_dht_value.data.begin(), the_dht_value.data.end()};
|
||||
CPPUNIT_ASSERT_EQUAL(the_data, from_value);
|
||||
}
|
||||
|
||||
void
|
||||
ValueTester::testFilter()
|
||||
{
|
||||
dht::Value::Filter defaultFiler {};
|
||||
|
||||
auto isPairSize = dht::Value::Filter([](const dht::Value& v) {
|
||||
return v.data.size() % 2 == 0;
|
||||
});
|
||||
|
||||
auto isUserTypeTest = dht::Value::Filter([](const dht::Value& v) {
|
||||
return v.user_type == "test";
|
||||
});
|
||||
|
||||
std::string data1 {"42 cats"};
|
||||
dht::Value value1 {(const uint8_t*)data1.data(), data1.size()};
|
||||
value1.user_type = "test";
|
||||
|
||||
std::string data2 {"420 cats"};
|
||||
dht::Value value2 {(const uint8_t*)data2.data(), data2.size()};
|
||||
dht::Value value3 {(const uint8_t*)data2.data(), data2.size()};
|
||||
value3.user_type = "test";
|
||||
|
||||
CPPUNIT_ASSERT(!isPairSize(value1));
|
||||
CPPUNIT_ASSERT(isUserTypeTest(value1));
|
||||
|
||||
auto isBoth = dht::Value::Filter::chain(isPairSize, isUserTypeTest);
|
||||
auto isUserTypeTest2 = dht::Value::Filter::chain(defaultFiler, isUserTypeTest);
|
||||
|
||||
CPPUNIT_ASSERT(isUserTypeTest2(value1));
|
||||
CPPUNIT_ASSERT(!isUserTypeTest2(value2));
|
||||
CPPUNIT_ASSERT(!isBoth(value1));
|
||||
CPPUNIT_ASSERT(!isBoth(value2));
|
||||
CPPUNIT_ASSERT(isBoth(value3));
|
||||
}
|
||||
|
||||
void
|
||||
ValueTester::tearDown() {
|
||||
|
||||
}
|
||||
} // namespace test
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// cppunit
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace test {
|
||||
|
||||
class ValueTester : public CppUnit::TestFixture {
|
||||
CPPUNIT_TEST_SUITE(ValueTester);
|
||||
CPPUNIT_TEST(testConstructors);
|
||||
CPPUNIT_TEST(testFilter);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Method automatically called before each test by CppUnit
|
||||
*/
|
||||
void setUp();
|
||||
/**
|
||||
* Method automatically called after each test CppUnit
|
||||
*/
|
||||
void tearDown();
|
||||
/**
|
||||
* Test the differents behaviors of constructors
|
||||
*/
|
||||
void testConstructors();
|
||||
/**
|
||||
* Test compare operators
|
||||
*/
|
||||
void testFilter();
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
@@ -307,7 +307,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
|
||||
}, [start](bool ok) {
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::cout << "Get: " << (ok ? "completed" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
|
||||
}, {}, dht::Where {std::move(rem)});
|
||||
}, {}, dht::Where {rem});
|
||||
}
|
||||
else if (op == "q") {
|
||||
std::string rem;
|
||||
@@ -322,7 +322,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
|
||||
}, [start](bool ok) {
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::cout << "Query: " << (ok ? "completed" : "failure") << " (took " << print_dt(end-start) << "s)" << std::endl;
|
||||
}, dht::Query {std::move(rem)});
|
||||
}, dht::Query {rem});
|
||||
}
|
||||
else if (op == "l") {
|
||||
std::string rem;
|
||||
@@ -332,7 +332,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
|
||||
for (const auto& value : values)
|
||||
std::cout << "\t" << *value << std::endl;
|
||||
return true;
|
||||
}, {}, dht::Where {std::move(rem)});
|
||||
}, {}, dht::Where {rem});
|
||||
auto t = token.get();
|
||||
std::cout << "Listening, token: " << t << std::endl;
|
||||
}
|
||||
@@ -431,7 +431,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
|
||||
<< p.toString() << std::endl
|
||||
<< " hash: " << p.hash() << std::endl;
|
||||
std::cout << " entries:" << std::endl;
|
||||
for (auto v : vals)
|
||||
for (const auto& v : vals)
|
||||
std::cout << " " << v->first.toString() << "[vid: " << v->second << "]" << std::endl;
|
||||
},
|
||||
[start](bool ok) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
|
||||
Reference in new issue
Block a user