dhtrunner: add getNodeInfo()

Allow to retrieve all dht stats in a single API call using
the new method getNodeInfo() and the JSON-serializable
new structure NodeInfo.
This commit is contained in:
Adrien Béraud committed 2018-06-05 19:43:56 -04:00
1 parent 4c89ce9d3f
commit aa202b2cd8
11 files changed
+152 -91

No files matched your search

+13 -6
View File
@@ -47,9 +47,21 @@ if (NOT OPENDHT_ARGON2)
set(OPENDHT_ARGON2 ON)
endif()
endif ()
pkg_search_module(Jsoncpp jsoncpp)
if (Jsoncpp_FOUND)
add_definitions(-DOPENDHT_JSONCPP)
list (APPEND opendht_SOURCES
src/base64.h
src/base64.cpp
)
endif()
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
find_package(Restbed REQUIRED)
pkg_search_module(Jsoncpp jsoncpp)
if (!Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
endif()
# Build flags
@@ -207,13 +219,8 @@ if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
list (APPEND opendht_HEADERS
include/opendht/proxy.h
)
list (APPEND opendht_SOURCES
src/base64.h
src/base64.cpp
)
endif ()
if(OPENDHT_ARGON2)
# make sure argon2 submodule is up to date and initialized
message("Initializing Argon2 submodule")
+55 -50
View File
@@ -101,9 +101,51 @@ LT_LANG(C++)
AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
PKG_PROG_PKG_CONFIG()
AC_ARG_ENABLE([proxy_server], AS_HELP_STRING([--enable-proxy-server], [Enable proxy server ability]), proxy_server=yes, proxy_server=no)
AM_CONDITIONAL(ENABLE_PROXY_SERVER, test x$proxy_server == xyes)
AC_ARG_ENABLE([push_notifications], AS_HELP_STRING([--enable-push-notifications], [Enable push notifications support]), push_notifications=yes, push_notifications=no)
AM_CONDITIONAL(ENABLE_PUSH_NOTIFICATIONS, test x$push_notifications == xyes)
AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-identity],
[Enable proxy server ability]), proxy_server_identity=yes, proxy_server_identity=no)
AM_CONDITIONAL(ENABLE_PROXY_SERVER_IDENTITY, test x$proxy_server_identity == xyes -a x$proxy_server == xyes)
AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-identity],
[Enable proxy server ability]), proxy_server_identity=yes, proxy_server_identity=no)
AC_ARG_ENABLE([proxy_client], AS_HELP_STRING([--enable-proxy-client], [Enable proxy client ability]), proxy_client=yes, proxy_client=no)
AM_CONDITIONAL(ENABLE_PROXY_CLIENT, test x$proxy_client == xyes)
AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
AM_CONDITIONAL(ENABLE_TESTS, test x$build_tests == xyes)
AM_COND_IF([ENABLE_TESTS], [
PKG_CHECK_MODULES([CppUnit], [cppunit >= 1.12])
])
AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes | test x$proxy_server == xyes)
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
AC_ARG_WITH([jsoncpp], AS_HELP_STRING([--without-jsoncpp], [Build without JsonCpp support]))
AS_IF([test "x$with_jsoncpp" != "xno"],
[PKG_CHECK_MODULES([JsonCpp], [jsoncpp >= 1.7.2], [have_jsoncpp=yes], [have_jsoncpp=no])],
[have_jsoncpp=no])
AS_IF([test "x$have_jsoncpp" = "xyes"], [
AC_MSG_NOTICE([Using JsonCpp])
CPPFLAGS+=" -DOPENDHT_JSONCPP=1"
], [
AC_MSG_NOTICE([Not using JsonCpp])
AM_COND_IF(PROXY_CLIENT_OR_SERVER, AC_MSG_ERROR(["JsonCpp is required for proxy/push notification support"]))
])
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
AC_CHECK_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files]))
LDFLAGS="${LDFLAGS} -lrestbed"
])
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
dnl Check for Argon2
@@ -135,58 +177,21 @@ AM_COND_IF([ENABLE_TOOLS], [
])
])
AC_ARG_ENABLE([proxy_server], AS_HELP_STRING([--enable-proxy-server], [Enable proxy server ability]), proxy_server=yes, proxy_server=no)
AM_CONDITIONAL(ENABLE_PROXY_SERVER, test x$proxy_server == xyes)
AC_ARG_ENABLE([push_notifications], AS_HELP_STRING([--enable-push-notifications], [Enable push notifications support]), push_notifications=yes, push_notifications=no)
AM_CONDITIONAL(ENABLE_PUSH_NOTIFICATIONS, test x$push_notifications == xyes)
AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-identity],
[Enable proxy server ability]), proxy_server_identity=yes, proxy_server_identity=no)
AM_CONDITIONAL(ENABLE_PROXY_SERVER_IDENTITY, test x$proxy_server_identity == xyes)
AC_ARG_ENABLE([proxy_client], AS_HELP_STRING([--enable-proxy-client], [Enable proxy client ability]), proxy_client=yes, proxy_client=no)
AM_CONDITIONAL(ENABLE_PROXY_CLIENT, test x$proxy_client == xyes)
AM_COND_IF(ENABLE_PROXY_SERVER,
[CPPFLAGS+=" -DOPENDHT_PROXY_SERVER=true"],
[CPPFLAGS+=" -DOPENDHT_PROXY_SERVER=false"])
AM_COND_IF([ENABLE_PROXY_SERVER], [
AC_CHECK_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files]))
PKG_CHECK_MODULES([Jsoncpp], [jsoncpp >= 1.7.2])
CPPFLAGS+=" -DOPENDHT_PROXY_SERVER=true -ljsoncpp -lrestbed"
], [
CPPFLAGS+=" -DOPENDHT_PROXY_SERVER=false"
])
AM_COND_IF(ENABLE_PROXY_CLIENT,
[CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT=true"],
[CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT=false"])
AM_COND_IF([ENABLE_PUSH_NOTIFICATIONS], [
CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS=true"
], [
CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS=false"
])
AM_COND_IF(ENABLE_PUSH_NOTIFICATIONS,
[CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS=true"],
[CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS=false"])
AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-identity],
[Enable proxy server ability]), proxy_server_identity=yes, proxy_server_identity=no)
AM_CONDITIONAL(ENABLE_PROXY_SERVER_IDENTITY, test x$proxy_server_identity == xyes -a x$proxy_server == xyes)
AM_COND_IF([ENABLE_PROXY_SERVER_IDENTITY], [
CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY=true"
], [
CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY=false"
])
AM_COND_IF([ENABLE_PROXY_CLIENT], [
CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT=true"
], [
CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT=false"
])
AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes | test x$proxy_server == xyes)
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
AC_CHECK_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files]))
PKG_CHECK_MODULES([Jsoncpp], [jsoncpp >= 1.7.4])
CPPFLAGS="${CPPFLAGS} ${Jsoncpp_CFLAGS}"
LDFLAGS="${LDFLAGS} ${Jsoncpp_LIBS} -lrestbed"
], [])
AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
AM_CONDITIONAL(ENABLE_TESTS, test x$build_tests == xyes)
AM_COND_IF([ENABLE_TESTS], [
PKG_CHECK_MODULES([CppUnit], [cppunit >= 1.12])
])
AM_COND_IF(ENABLE_PROXY_SERVER_IDENTITY,
[CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY=true"],
[CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY=false"])
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
@@ -202,6 +207,6 @@ AM_COND_IF([USE_CYTHON], [
AC_CONFIG_FILES([Makefile
src/Makefile
tools/Makefile
tests/Makefile
tests/Makefile
opendht.pc])
AC_OUTPUT
+25 -4
View File
@@ -27,9 +27,9 @@
#include <memory>
#include <functional>
#if OPENDHT_PROXY_SERVER
#ifdef OPENDHT_JSONCPP
#include <json/json.h>
#endif //OPENDHT_PROXY_SERVER
#endif
namespace dht {
@@ -52,14 +52,35 @@ struct OPENDHT_PUBLIC NodeStats {
unsigned table_depth {0};
unsigned getKnownNodes() const { return good_nodes + dubious_nodes; }
std::string toString() const;
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
/**
* Build a json object from a NodeStats
*/
Json::Value toJson() const;
NodeStats() {};
explicit NodeStats(const Json::Value& v);
#endif //OPENDHT_PROXY_SERVER
#endif
MSGPACK_DEFINE_MAP(good_nodes, dubious_nodes, cached_nodes, incoming_nodes, table_depth)
};
struct OPENDHT_PUBLIC NodeInfo {
InfoHash id;
InfoHash node_id;
NodeStats ipv4;
NodeStats ipv6;
#ifdef OPENDHT_JSONCPP
/**
* Build a json object from a NodeStats
*/
Json::Value toJson() const;
NodeInfo() {};
explicit NodeInfo(const Json::Value& v);
#endif
MSGPACK_DEFINE_MAP(id, node_id, ipv4, ipv6)
};
/**
+1 -2
View File
@@ -239,8 +239,7 @@ private:
Sp<Scheduler::Job> printStatsJob_;
mutable std::mutex statsMutex_;
mutable NodeStats ipv4Stats_ {};
mutable NodeStats ipv6Stats_ {};
mutable NodeInfo nodeInfo_ {};
// Handle client quit for listen.
// NOTE: can be simplified when we will supports restbed 5.0
+1
View File
@@ -293,6 +293,7 @@ public:
NodeStats getNodesStats(sa_family_t af) const;
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
NodeInfo getNodeInfo() const;
std::vector<unsigned> getNodeMessageStats(bool in = false) const;
std::string getStorageLog() const;
+7 -7
View File
@@ -37,9 +37,9 @@
#include <chrono>
#include <set>
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
#include <json/json.h>
#endif //OPENDHT_PROXY_SERVER
#endif
namespace dht {
@@ -372,13 +372,13 @@ struct OPENDHT_PUBLIC Value
Value(ValueType::Id t, const uint8_t* dat_ptr, size_t dat_len, Id id = INVALID_ID)
: id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
/**
* Build a value from a json object
* @param json
*/
Value(Json::Value& json);
#endif //OPENDHT_PROXY_SERVER
#endif
template <typename Type>
Value(ValueType::Id t, const Type& d, Id id = INVALID_ID)
@@ -451,7 +451,7 @@ struct OPENDHT_PUBLIC Value
return ss.str();
}
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
/**
* Build a json object from a value
* Example:
@@ -461,7 +461,7 @@ struct OPENDHT_PUBLIC Value
* }
*/
Json::Value toJson() const;
#endif //OPENDHT_PROXY_SERVER
#endif
/** Return the size in bytes used by this value in memory (minimum). */
size_t size() const;
@@ -996,7 +996,7 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) {
return ret;
}
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
uint64_t unpackId(const Json::Value& json, const std::string& key);
#endif
+2 -2
View File
@@ -1,7 +1,7 @@
lib_LTLIBRARIES = libopendht.la
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@
libopendht_la_LIBADD = @Argon2_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@
libopendht_la_SOURCES = \
dht.cpp \
+28 -2
View File
@@ -68,7 +68,7 @@ NodeStats::toString() const
return ss.str();
}
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
/**
* Build a json object from a NodeStats
*/
@@ -98,6 +98,32 @@ NodeStats::NodeStats(const Json::Value& val)
if (val.isMember("table_depth"))
table_depth = static_cast<unsigned>(val["table_depth"].asLargestUInt());
}
#endif //OPENDHT_PROXY_SERVER
/**
* Build a json object from a NodeStats
*/
Json::Value
NodeInfo::toJson() const
{
Json::Value val;
if (id)
val["id"] = id.toString();
val["node_id"] = node_id.toString();
val["ipv4"] = ipv4.toJson();
val["ipv6"] = ipv6.toJson();
return val;
}
NodeInfo::NodeInfo(const Json::Value& v)
{
if (v.isMember("id"))
id = InfoHash(v["id"].asString());
node_id = InfoHash(v["node_id"].asString());
ipv4 = NodeStats(v["ipv4"]);
ipv6 = NodeStats(v["ipv6"]);
}
#endif
}
+5 -14
View File
@@ -29,7 +29,6 @@
#include <chrono>
#include <functional>
#include <limits>
#include <iostream>
using namespace std::placeholders;
@@ -132,12 +131,10 @@ DhtProxyServer::DhtProxyServer(std::shared_ptr<DhtRunner> dht, in_port_t port ,
}
if (not stopListeners) {
// Refresh stats cache
auto newIpv4Stats = dht_->getNodesStats(AF_INET);
auto newIpv6Stats = dht_->getNodesStats(AF_INET6);
auto newInfo = dht_->getNodeInfo();
{
std::lock_guard<std::mutex> lck(statsMutex_);
ipv4Stats_ = std::move(newIpv4Stats);
ipv6Stats_ = std::move(newIpv6Stats);
nodeInfo_ = std::move(newInfo);
}
}
});
@@ -213,22 +210,16 @@ DhtProxyServer::getNodeInfo(const std::shared_ptr<restbed::Session>& session) co
try {
if (dht_) {
Json::Value result;
auto id = dht_->getId();
if (id)
result["id"] = id.toString();
result["node_id"] = dht_->getNodeId().toString();
{
std::lock_guard<std::mutex> lck(statsMutex_);
if (ipv4Stats_.good_nodes == 0 && ipv6Stats_.good_nodes == 0) {
if (nodeInfo_.ipv4.good_nodes == 0 && nodeInfo_.ipv6.good_nodes == 0) {
// NOTE: we want to avoid the disconnected state as much as possible
// So, if the node is disconnected, we should force the update of the cache
// and reconnect as soon as possible
// This should not happen much
ipv4Stats_ = dht_->getNodesStats(AF_INET);
ipv6Stats_ = dht_->getNodesStats(AF_INET);
nodeInfo_ = dht_->getNodeInfo();
}
result["ipv4"] = ipv4Stats_.toJson();
result["ipv6"] = ipv6Stats_.toJson();
result = nodeInfo_.toJson();
}
result["public_ip"] = s->get_origin(); // [ipv6:ipv4]:port or ipv4:port
Json::StreamWriterBuilder wbuilder;
+11
View File
@@ -301,6 +301,17 @@ DhtRunner::getNodesStats(sa_family_t af) const
return activeDht()->getNodesStats(af);
}
NodeInfo
DhtRunner::getNodeInfo() const {
std::lock_guard<std::mutex> lck(dht_mtx);
NodeInfo info;
info.id = getId();
info.node_id = getNodeId();
info.ipv4 = dht_->getNodesStats(AF_INET);
info.ipv6 = dht_->getNodesStats(AF_INET6);
return info;
}
std::vector<unsigned>
DhtRunner::getNodeMessageStats(bool in) const
{
+4 -4
View File
@@ -22,9 +22,9 @@
#include "default_types.h"
#include "securedht.h" // print certificate ID
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
#include "base64.h"
#endif //OPENDHT_PROXY_SERVER
#endif
namespace dht {
@@ -172,7 +172,7 @@ Value::msgpack_unpack_body(const msgpack::object& o)
}
}
#if OPENDHT_PROXY_SERVER || OPENDHT_PROXY_CLIENT
#ifdef OPENDHT_JSONCPP
Value::Value(Json::Value& json)
{
id = Value::Id(unpackId(json, "id"));
@@ -248,7 +248,7 @@ unpackId(const Json::Value& json, const std::string& key) {
} catch (...) {}
return ret;
}
#endif //OPENDHT_PROXY_SERVER
#endif
bool
FieldValue::operator==(const FieldValue& vfd) const