20#if OPENDHT_PROXY_CLIENT
30#include "dht_interface.h"
46class OPENDHT_PUBLIC DhtProxyClient final :
public DhtInterface {
51 explicit DhtProxyClient(std::function<
void()> loopSignal,
const std::string& serverHost,
const std::string& pushClientId =
"");
53 virtual void setPushNotificationToken(
const std::string& token) {
54#if OPENDHT_PUSH_NOTIFICATIONS
59 virtual ~DhtProxyClient();
64 inline const InfoHash& getNodeId()
const {
return myid; }
71 return std::max(getStatus(AF_INET), getStatus(AF_INET6));
77 void shutdown(ShutdownCallback cb);
85 bool isRunning(sa_family_t af = 0)
const;
97 virtual void get(
const InfoHash& key, GetCallback cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {});
98 virtual void get(
const InfoHash& key, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f={}, Where&& w = {}) {
99 get(key, cb, bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
101 virtual void get(
const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) {
102 get(key, bindGetCb(cb), donecb, std::forward<Value::Filter>(f), std::forward<Where>(w));
104 virtual void get(
const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, Where&& w = {}) {
105 get(key, bindGetCb(cb), bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
115 void put(
const InfoHash& key,
117 DoneCallback cb=
nullptr,
118 time_point created=time_point::max(),
119 bool permanent =
false);
120 void put(
const InfoHash& key,
122 DoneCallbackSimple cb,
123 time_point created=time_point::max(),
124 bool permanent =
false)
126 put(key, v, bindDoneCb(cb), created, permanent);
129 void put(
const InfoHash& key,
131 DoneCallback cb=
nullptr,
132 time_point created=time_point::max(),
133 bool permanent =
false)
135 put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
137 void put(
const InfoHash& key,
139 DoneCallbackSimple cb,
140 time_point created=time_point::max(),
141 bool permanent =
false)
143 put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
150 NodeStats getNodesStats(sa_family_t af)
const;
156 std::vector<SockAddr> getPublicAddress(sa_family_t family = 0);
165 virtual size_t listen(
const InfoHash&, ValueCallback, Value::Filter={}, Where={});
167 virtual size_t listen(
const InfoHash& key, GetCallback cb, Value::Filter f={}, Where w={}) {
168 return listen(key, [cb](
const std::vector<Sp<Value>>& vals,
bool expired){
172 }, std::forward<Value::Filter>(f), std::forward<Where>(w));
174 virtual size_t listen(
const InfoHash& key, GetCallbackSimple cb, Value::Filter f={}, Where w={}) {
175 return listen(key, bindGetCb(cb), std::forward<Value::Filter>(f), std::forward<Where>(w));
177 virtual bool cancelListen(
const InfoHash& key,
size_t token);
183 void pushNotificationReceived(
const std::map<std::string, std::string>& notification);
185 time_point periodic(
const uint8_t*,
size_t,
const SockAddr&);
186 time_point periodic(
const uint8_t *buf,
size_t buflen,
const sockaddr* from, socklen_t fromlen) {
187 return periodic(buf, buflen, SockAddr(from, fromlen));
201 virtual void query(
const InfoHash& , QueryCallback , DoneCallback = {}, Query&& = {}) { }
202 virtual void query(
const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) {
203 query(key, cb, bindDoneCb(done_cb), std::forward<Query>(q));
209 std::vector<Sp<Value>> getPut(
const InfoHash&);
214 Sp<Value> getPut(
const InfoHash&,
const Value::Id&);
220 bool cancelPut(
const InfoHash&,
const Value::Id&);
222 void pingNode(
const sockaddr*, socklen_t, DoneCallbackSimple&& ={}) { }
224 virtual void registerType(
const ValueType& type) {
225 types.registerType(type);
227 const ValueType& getType(ValueType::Id type_id)
const {
228 return types.getType(type_id);
231 std::vector<Sp<Value>> getLocal(
const InfoHash& k, Value::Filter filter)
const;
232 Sp<Value> getLocalById(
const InfoHash& k, Value::Id
id)
const;
238 void insertNode(
const InfoHash&,
const SockAddr&) { }
239 void insertNode(
const InfoHash&,
const sockaddr*, socklen_t) { }
240 void insertNode(
const NodeExport&) { }
241 std::pair<size_t, size_t> getStoreSize()
const {
return {}; }
242 std::vector<NodeExport> exportNodes() {
return {}; }
243 std::vector<ValuesExport> exportValues()
const {
return {}; }
244 void importValues(
const std::vector<ValuesExport>&) {}
245 std::string getStorageLog()
const {
return {}; }
246 std::string getStorageLog(
const InfoHash&)
const {
return {}; }
247 std::string getRoutingTablesLog(sa_family_t)
const {
return {}; }
248 std::string getSearchesLog(sa_family_t)
const {
return {}; }
249 std::string getSearchLog(
const InfoHash&, sa_family_t)
const {
return {}; }
250 void dumpTables()
const {}
251 std::vector<unsigned> getNodeMessageStats(
bool) {
return {}; }
252 void setStorageLimit(
size_t) {}
253 void connectivityChanged(sa_family_t) {
256 void connectivityChanged() {
273 void getProxyInfos();
274 void onProxyInfos(
const Json::Value& val, sa_family_t family);
275 SockAddr parsePublicAddress(
const Json::Value& val);
279 size_t doListen(
const InfoHash& key, ValueCallback, Value::Filter);
280 bool doCancelListen(
const InfoHash& key,
size_t token);
283 void sendListen(
const std::shared_ptr<restbed::Request>& request,
const ValueCallback&,
const Value::Filter& filter,
const Sp<ListenState>& state);
284 void sendSubscribe(
const std::shared_ptr<restbed::Request>& request,
const Sp<proxy::ListenToken>&,
const Sp<ListenState>& state);
286 void doPut(
const InfoHash&, Sp<Value>, DoneCallback, time_point created,
bool permanent);
291 void getConnectivityStatus();
295 void cancelAllListeners();
299 void cancelAllOperations();
301 std::string serverHost_;
302 std::string pushClientId_;
304 mutable std::mutex lockCurrentProxyInfos_;
305 NodeStatus statusIpv4_ {NodeStatus::Disconnected};
306 NodeStatus statusIpv6_ {NodeStatus::Disconnected};
307 NodeStats stats4_ {};
308 NodeStats stats6_ {};
309 SockAddr publicAddressV4_;
310 SockAddr publicAddressV6_;
323 size_t listenerToken_ {0};
324 std::map<InfoHash, ProxySearch> searches_;
325 mutable std::mutex searchLock_;
332 std::shared_ptr<restbed::Request> req;
334 std::shared_ptr<std::atomic_bool> finished;
336 std::vector<Operation> operations_;
337 std::mutex lockOperations_;
341 std::vector<std::function<void()>> callbacks_;
342 std::mutex lockCallbacks;
344 Sp<InfoState> infoState_;
345 std::thread statusThread_;
346 mutable std::mutex statusLock_;
353 Sp<Scheduler::Job> nextProxyConfirmation {};
357 void restartListeners();
363 void resubscribe(
const InfoHash& key, Listener& listener);
369 std::string deviceKey_ {};
371 const std::function<void()> loopSignal_;
373#if OPENDHT_PUSH_NOTIFICATIONS
374 void fillBodyToGetToken(std::shared_ptr<restbed::Request> request,
unsigned token = 0);
375 void getPushRequest(Json::Value&)
const;
378 bool isDestroying_ {
false};