/* * Copyright (C) 2014-2023 Savoir-faire Linux Inc. * Author(s) : Adrien Béraud * * 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 . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "callbacks.h" namespace dht { GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data) { if (not raw_cb) return {}; return [=](const std::shared_ptr& value) { return raw_cb(value, user_data); }; } GetCallback bindGetCb(GetCallbackSimple cb) { if (not cb) return {}; return [cb=std::move(cb)](const std::vector>& values) { for (const auto& v : values) if (not cb(v)) return false; return true; }; } ValueCallback bindValueCb(ValueCallbackRaw raw_cb, void* user_data) { if (not raw_cb) return {}; return [=](const std::vector>& values, bool expired) { for (const auto& v : values) if (not raw_cb(v, expired, user_data)) return false; return true; }; } ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data) { return [=]() { shutdown_cb_raw(user_data); }; } DoneCallback bindDoneCb(DoneCallbackSimple donecb) { if (not donecb) return {}; using namespace std::placeholders; return std::bind(std::move(donecb), _1); } DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data) { if (not raw_cb) return {}; return [=](bool success, const std::vector>& nodes) { raw_cb(success, (std::vector>*)&nodes, user_data); }; } DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) { if (not raw_cb) return {}; return [=](bool success) { raw_cb(success, user_data); }; } std::string NodeStats::toString() const { std::ostringstream ss; ss << "Known nodes: " << good_nodes << " good, " << dubious_nodes << " dubious, " << incoming_nodes << " incoming." << std::endl; ss << searches << " searches, " << node_cache_size << " total cached nodes" << std::endl; if (table_depth > 1) { ss << "Routing table depth: " << table_depth << std::endl; ss << "Network size estimation: " << getNetworkSizeEstimation() << " nodes" << std::endl; } return ss.str(); } #ifdef OPENDHT_JSONCPP /** * Build a json object from a NodeStats */ Json::Value NodeStats::toJson() const { Json::Value val; val["good"] = static_cast(good_nodes); val["dubious"] = static_cast(dubious_nodes); val["incoming"] = static_cast(incoming_nodes); if (table_depth > 1) { val["table_depth"] = static_cast(table_depth); val["network_size_estimation"] = static_cast(getNetworkSizeEstimation()); } return val; } NodeStats::NodeStats(const Json::Value& val) { if (val.isMember("good")) good_nodes = static_cast(val["good"].asLargestUInt()); if (val.isMember("dubious")) dubious_nodes = static_cast(val["dubious"].asLargestUInt()); if (val.isMember("incoming")) incoming_nodes = static_cast(val["incoming"].asLargestUInt()); if (val.isMember("table_depth")) table_depth = static_cast(val["table_depth"].asLargestUInt()); } /** * 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(); val["ops"] = Json::Value::LargestUInt(ongoing_ops); 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"]); ongoing_ops = v["ops"].asLargestUInt(); } #endif }