54class OPENDHT_PUBLIC DhtRunner {
62 std::string proxy_server {};
63 std::string push_node_id {};
64 std::string push_token {};
65 std::string push_topic {};
66 std::string push_platform {};
67 std::string proxy_user_agent {};
68 bool peer_discovery {
false};
69 bool peer_publish {
false};
70 std::shared_ptr<dht::crypto::Certificate> server_ca;
71 dht::crypto::Identity client_identity;
76 std::shared_ptr<Logger> logger {};
77 std::unique_ptr<net::DatagramSocket> sock;
78 std::shared_ptr<PeerDiscovery> peerDiscovery {};
79 StatusCallback statusChangedCallback {};
80 CertificateStoreQueryLegacy certificateStore {};
81 CertificateStoreQuery certificateStorePkId {};
82 IdentityAnnouncedCb identityAnnouncedCb {};
83 PublicAddressChangedCb publicAddressChangedCb {};
84 std::unique_ptr<std::mt19937_64> rng {};
91 void get(InfoHash
id, GetCallbackSimple cb, DoneCallback donecb={},
Value::Filter f = {}, Where w = {}) {
92 get(
id, bindGetCb(cb), donecb, f, w);
95 void get(InfoHash
id, GetCallbackSimple cb, DoneCallbackSimple donecb={}, Value::Filter f = {}, Where w = {}) {
96 get(
id, bindGetCb(cb), donecb, f, w);
99 void get(InfoHash hash, GetCallback vcb, DoneCallback dcb, Value::Filter f={}, Where w = {});
101 void get(InfoHash
id, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter f = {}, Where w = {}) {
102 get(
id, cb, bindDoneCb(donecb), f, w);
104 void get(
const std::string& key, GetCallback vcb, DoneCallbackSimple dcb={}, Value::Filter f = {}, Where w = {});
107 void get(InfoHash hash, std::function<
bool(std::vector<T>&&)> cb, DoneCallbackSimple dcb={})
109 get(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals) {
110 return cb(unpackVector<T>(vals));
116 void get(InfoHash hash, std::function<
bool(T&&)> cb, DoneCallbackSimple dcb={})
118 get(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals) {
119 for (
const auto& v : vals) {
121 if (not cb(Value::unpack<T>(*v)))
123 }
catch (
const std::exception&) {
133 std::future<std::vector<std::shared_ptr<dht::Value>>> get(InfoHash key, Value::Filter f = {}, Where w = {}) {
134 auto p = std::make_shared<std::promise<std::vector<std::shared_ptr< dht::Value >>>>();
135 auto values = std::make_shared<std::vector<std::shared_ptr< dht::Value >>>();
136 get(key, [=](
const std::vector<std::shared_ptr<dht::Value>>& vlist) {
137 values->insert(values->end(), vlist.begin(), vlist.end());
140 p->set_value(std::move(*values));
143 return p->get_future();
147 std::future<std::vector<T>> get(InfoHash key) {
148 auto p = std::make_shared<std::promise<std::vector<T>>>();
149 auto values = std::make_shared<std::vector<T>>();
150 get<T>(key, [=](T&& v) {
151 values->emplace_back(std::move(v));
154 p->set_value(std::move(*values));
156 return p->get_future();
159 void query(
const InfoHash& hash, QueryCallback cb, DoneCallback done_cb = {}, Query q = {});
160 void query(
const InfoHash& hash, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query q = {}) {
161 query(hash, cb, bindDoneCb(done_cb), q);
164 std::future<size_t> listen(InfoHash key, ValueCallback vcb, Value::Filter f = {}, Where w = {});
166 std::future<size_t> listen(InfoHash key, GetCallback cb, Value::Filter f={}, Where w={}) {
167 return listen(key, [cb=std::move(cb)](
const std::vector<Sp<Value>>& vals,
bool expired){
171 }, std::forward<Value::Filter>(f), std::forward<Where>(w));
173 std::future<size_t> listen(
const std::string& key, GetCallback vcb, Value::Filter f = {}, Where w = {});
174 std::future<size_t> listen(InfoHash key, GetCallbackSimple cb, Value::Filter f = {}, Where w = {}) {
175 return listen(key, bindGetCb(cb), f, w);
179 std::future<size_t> listen(InfoHash hash, std::function<
bool(std::vector<T>&&)> cb)
181 return listen(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals) {
182 return cb(unpackVector<T>(vals));
187 std::future<size_t> listen(InfoHash hash, std::function<
bool(std::vector<T>&&,
bool)> cb)
189 return listen(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals,
bool expired) {
190 return cb(unpackVector<T>(vals), expired);
195 template <
typename T>
196 std::future<size_t> listen(InfoHash hash, std::function<
bool(T&&)> cb, Value::Filter f = {}, Where w = {})
198 return listen(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals) {
199 for (
const auto& v : vals) {
201 if (not cb(Value::unpack<T>(*v)))
203 }
catch (
const std::exception&) {
209 getFilterSet<T>(f), w);
211 template <
typename T>
212 std::future<size_t> listen(InfoHash hash, std::function<
bool(T&&,
bool)> cb, Value::Filter f = {}, Where w = {})
214 return listen(hash, [cb=std::move(cb)](
const std::vector<std::shared_ptr<Value>>& vals,
bool expired) {
215 for (
const auto& v : vals) {
217 if (not cb(Value::unpack<T>(*v), expired))
219 }
catch (
const std::exception&) {
225 getFilterSet<T>(f), w);
228 void cancelListen(InfoHash h,
size_t token);
229 void cancelListen(InfoHash h, std::shared_future<size_t> token);
231 void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={}, time_point created=time_point::max(),
bool permanent =
false);
232 void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb, time_point created=time_point::max(),
bool permanent =
false) {
233 put(hash, value, bindDoneCb(cb), created, permanent);
236 void put(InfoHash hash, Value&& value, DoneCallback cb={}, time_point created=time_point::max(),
bool permanent =
false);
237 void put(InfoHash hash, Value&& value, DoneCallbackSimple cb, time_point created=time_point::max(),
bool permanent =
false) {
238 put(hash, std::forward<Value>(value), bindDoneCb(cb), created, permanent);
240 void put(
const std::string& key, Value&& value, DoneCallbackSimple cb={}, time_point created=time_point::max(),
bool permanent =
false);
242 void cancelPut(
const InfoHash& h, Value::Id
id);
243 void cancelPut(
const InfoHash& h,
const std::shared_ptr<Value>& value);
245 void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={},
bool permanent =
false);
246 void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb,
bool permanent =
false) {
247 putSigned(hash, value, bindDoneCb(cb), permanent);
250 void putSigned(InfoHash hash, Value&& value, DoneCallback cb={},
bool permanent =
false);
251 void putSigned(InfoHash hash, Value&& value, DoneCallbackSimple cb,
bool permanent =
false) {
252 putSigned(hash, std::forward<Value>(value), bindDoneCb(cb), permanent);
254 void putSigned(
const std::string& key, Value&& value, DoneCallbackSimple cb={},
bool permanent =
false);
256 void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb={},
bool permanent =
false);
257 void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallbackSimple cb,
bool permanent =
false) {
258 putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
261 void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb={},
bool permanent =
false);
262 void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallbackSimple cb,
bool permanent =
false) {
263 putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
265 void putEncrypted(
const std::string& key, InfoHash to, Value&& value, DoneCallback cb={},
bool permanent =
false);
267 void putEncrypted(InfoHash hash,
const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb={},
bool permanent =
false);
268 void putEncrypted(InfoHash hash,
const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallbackSimple cb,
bool permanent =
false) {
269 putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
272 [[deprecated(
"Use the shared_ptr version instead")]]
273 void putEncrypted(InfoHash hash,
const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={},
bool permanent =
false);
274 [[deprecated(
"Use the shared_ptr version instead")]]
275 void putEncrypted(InfoHash hash,
const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb,
bool permanent =
false) {
276 putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
279 void putEncrypted(InfoHash hash,
const PkId& to, std::shared_ptr<Value> value, DoneCallback cb={},
bool permanent =
false);
280 void putEncrypted(InfoHash hash,
const PkId& to, std::shared_ptr<Value> value, DoneCallbackSimple cb,
bool permanent =
false) {
281 putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
288 void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple cb={});
289 void bootstrap(
SockAddr addr, DoneCallbackSimple cb={});
303 void bootstrap(
const std::string& host,
const std::string& service);
304 void bootstrap(
const std::string& hostService);
324 void dumpTables()
const;
329 [[deprecated(
"Use getPublicKey()->getLongId() instead")]] InfoHash
getId()
const;
330 std::shared_ptr<crypto::PublicKey> getPublicKey()
const;
349 std::pair<size_t, size_t> getStoreSize()
const;
351 void getStorageLimit()
const;
352 void setStorageLimit(
size_t limit = DEFAULT_STORAGE_LIMIT);
354 std::vector<NodeExport> exportNodes()
const;
356 std::vector<ValuesExport> exportValues()
const;
358 void setLogger(
const Sp<Logger>& logger = {});
359 void setLogger(
const Logger& logger) {
360 setLogger(std::make_shared<Logger>(logger));
368 void registerType(
const ValueType& type);
370 void importValues(
const std::vector<ValuesExport>& values);
372 bool isRunning()
const {
373 return running != State::Idle;
376 NodeStats getNodesStats(sa_family_t af)
const;
377 unsigned getNodesStats(sa_family_t af,
unsigned *good_return,
unsigned *dubious_return,
unsigned *cached_return,
unsigned *incoming_return)
const;
378 NodeInfo getNodeInfo()
const;
379 void getNodeInfo(std::function<
void(std::shared_ptr<NodeInfo>)>);
381 std::vector<unsigned> getNodeMessageStats(
bool in =
false)
const;
382 std::string getStorageLog()
const;
383 std::string getStorageLog(
const InfoHash&)
const;
384 std::string getRoutingTablesLog(sa_family_t af)
const;
385 std::string getSearchesLog(sa_family_t af = AF_UNSPEC)
const;
386 std::string getSearchLog(
const InfoHash&, sa_family_t af = AF_UNSPEC)
const;
387 std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC)
const;
388 std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC)
const;
389 void getPublicAddress(std::function<
void(std::vector<SockAddr>&&)>, sa_family_t af = AF_UNSPEC);
393 void findCertificate(InfoHash hash, std::function<
void(
const std::shared_ptr<crypto::Certificate>&)>);
394 void findCertificate(PkId hash, std::function<
void(
const std::shared_ptr<crypto::Certificate>&)>);
396 void registerCertificate(
const std::shared_ptr<crypto::Certificate>& cert);
397 void setLocalCertificateStore(CertificateStoreQueryLegacy&& query_method);
398 void setLocalCertificateStore(CertificateStoreQuery&& query_method);
406 void run(in_port_t port = dht::net::DHT_DEFAULT_PORT,
const crypto::Identity& identity = {},
bool threaded =
true, NetId network = 0) {
408 config.dht_config.node_config.
network = network;
409 config.dht_config.id = identity;
410 config.threaded = threaded;
413 void run(in_port_t port, Config& config, Context&& context = {});
418 void run(
const char* ip4,
const char* ip6,
const char* service,
Config& config,
Context&& context = {});
420 void run(
const Config& config, Context&& context);
422 void setOnStatusChanged(StatusCallback&& cb) {
424 statusCbs.emplace_back(std::move(cb));
433 std::lock_guard<std::mutex> lck(dht_mtx);
440 void shutdown(ShutdownCallback cb = {},
bool stop =
false);
451 std::shared_ptr<PeerDiscovery> getPeerDiscovery()
const {
return peerDiscovery_; };
453 void setProxyServer(
const std::string& proxy,
const std::string& pushNodeId =
"");
484 void forwardAllMessages(
bool forward);
496 return std::max(status4, status6);
499 bool checkShutdown();
501 DoneCallback bindOpDoneCallback(DoneCallback&& cb);
502 DoneCallbackSimple bindOpDoneCallback(DoneCallbackSimple&& cb);
505 std::unique_ptr<SecureDht> dht_;
508 std::atomic_bool use_proxy {
false};
512 IdentityAnnouncedCb identityAnnouncedCb_;
519 mutable std::mutex dht_mtx {};
520 std::thread dht_thread {};
521 std::condition_variable cv {};
522 std::mutex sock_mtx {};
523 net::PacketList rcv {};
524 decltype(rcv) rcv_free {};
526 std::queue<std::function<void(SecureDht&)>> pending_ops_prio {};
527 std::queue<std::function<void(SecureDht&)>> pending_ops {};
528 std::mutex storage_mtx {};
530 std::atomic<State> running {State::Idle};
531 std::atomic_size_t ongoing_ops {0};
532 std::vector<ShutdownCallback> shutdownCallbacks_;
534 NodeStatus status4 {NodeStatus::Disconnected},
535 status6 {NodeStatus::Disconnected};
537 std::vector<StatusCallback> statusCbs {};
540 std::shared_ptr<PeerDiscovery> peerDiscovery_;
546 std::shared_ptr<dht::Logger> logger_;