mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 20:37:23 +00:00
Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4d17c6797 | ||
|
|
44a251de56 | ||
|
|
1c536a4c51 | ||
|
|
502a649f42 | ||
|
|
12a52c78ac | ||
|
|
df2a775927 | ||
|
|
2c86ccbe15 | ||
|
|
b9321a338b | ||
|
|
dc9a211fb0 | ||
|
|
d49b394eae | ||
|
|
f82c68a871 | ||
|
|
3f4235da69 | ||
|
|
e259cb0847 | ||
|
|
08f9b424de | ||
|
|
d33c3515f8 | ||
|
|
0a70b0f80f | ||
|
|
949cbb9fc7 | ||
|
|
37cfbffdca | ||
|
|
efad2ada89 | ||
|
|
d825f4e5ae | ||
|
|
baa2a5d21c | ||
|
|
b3f9683018 |
No files matched your search
+14
-9
@@ -1,10 +1,4 @@
|
||||
cmake_minimum_required (VERSION 3.10)
|
||||
if(POLICY CMP0065)
|
||||
cmake_policy(SET CMP0065 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0069)
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
endif()
|
||||
cmake_minimum_required (VERSION 3.10..3.20)
|
||||
if(POLICY CMP0073)
|
||||
cmake_policy(SET CMP0073 NEW)
|
||||
endif()
|
||||
@@ -15,11 +9,12 @@ project (opendht)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
include(CheckIncludeFileCXX)
|
||||
include(FindPkgConfig)
|
||||
include(cmake/CheckAtomic.cmake)
|
||||
|
||||
set (opendht_VERSION_MAJOR 2)
|
||||
set (opendht_VERSION_MINOR 4.5)
|
||||
set (opendht_VERSION_MINOR 4.7)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
@@ -60,7 +55,10 @@ if (NOT MSVC)
|
||||
find_package (PkgConfig REQUIRED)
|
||||
find_package (GnuTLS 3.3 REQUIRED)
|
||||
pkg_search_module (Nettle REQUIRED nettle)
|
||||
find_package (msgpack REQUIRED)
|
||||
check_include_file_cxx(msgpack.hpp HAVE_MSGPACKCXX)
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
find_package (msgpack REQUIRED)
|
||||
endif()
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
@@ -225,6 +223,13 @@ list (APPEND opendht_SOURCES
|
||||
src/thread_pool.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/compat/apple/apple_utils.h
|
||||
src/compat/apple/apple_utils.mm
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht/def.h
|
||||
include/opendht/utils.h
|
||||
|
||||
+4
-1
@@ -1,7 +1,10 @@
|
||||
lib_LTLIBRARIES = libopendht-c.la
|
||||
noinst_HEADERS = opendht_c.h
|
||||
|
||||
AM_CPPFLAGS = -isystem @top_srcdir@/include @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@
|
||||
AM_CPPFLAGS = -DOPENDHT_C_BUILD -isystem @top_srcdir@/include @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@
|
||||
if OPENDHT_SHARED
|
||||
AM_CPPFLAGS += -Dopendht_c_EXPORTS
|
||||
endif
|
||||
|
||||
libopendht_c_la_LIBADD = $(LIBOBJS) ../src/.libs/libopendht.la
|
||||
|
||||
|
||||
+3
-8
@@ -342,6 +342,7 @@ int dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config
|
||||
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
|
||||
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
|
||||
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
|
||||
config.push_topic = conf->push_topic ? std::string(conf->push_topic) : std::string{};
|
||||
config.peer_discovery = conf->peer_discovery;
|
||||
config.peer_publish = conf->peer_publish;
|
||||
|
||||
@@ -504,14 +505,8 @@ struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
|
||||
if (addrs.empty())
|
||||
return nullptr;
|
||||
auto ret = (struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
|
||||
for (size_t i=0; i<addrs.size(); i++) {
|
||||
if (const auto& addr = addrs[i]) {
|
||||
ret[i] = (struct sockaddr*)malloc(addr.getLength());
|
||||
memcpy((struct sockaddr*)ret[i], addr.get(), addr.getLength());
|
||||
} else {
|
||||
ret[i] = nullptr;
|
||||
}
|
||||
}
|
||||
for (size_t i=0; i<addrs.size(); i++)
|
||||
ret[i] = addrs[i].release();
|
||||
ret[addrs.size()] = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ struct OPENDHT_PUBLIC dht_runner_config {
|
||||
const char* proxy_server;
|
||||
const char* push_node_id;
|
||||
const char* push_token;
|
||||
const char* push_topic;
|
||||
bool peer_discovery;
|
||||
bool peer_publish;
|
||||
dht_certificate* server_ca;
|
||||
|
||||
+23
-14
@@ -1,7 +1,7 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 2)
|
||||
m4_define([opendht_minor_version], 4)
|
||||
m4_define([opendht_patch_version], 5)
|
||||
m4_define([opendht_patch_version], 7)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
@@ -19,17 +19,26 @@ AC_SUBST(OPENDHT_PATCH_VERSION, opendht_patch_version)
|
||||
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Build in debug mode, adds stricter warnings, disables optimization]))
|
||||
AS_IF([test "x$enable_debug" = "xyes"],
|
||||
[CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -O0 -pedantic-errors"],
|
||||
[CXXFLAGS="${CXXFLAGS} -O3 -pedantic-errors"])
|
||||
[CXXFLAGS="${CXXFLAGS} -O3 -pedantic-errors -fvisibility=hidden"])
|
||||
|
||||
CPPFLAGS+=" -DOPENDHT_BUILD"
|
||||
AM_CONDITIONAL([OPENDHT_SHARED], [test "x$enable_shared" != xno])
|
||||
AM_COND_IF(OPENDHT_SHARED, [
|
||||
CPPFLAGS+=" -Dopendht_EXPORTS"
|
||||
])
|
||||
|
||||
AC_PROG_CXX
|
||||
AM_PROG_AR
|
||||
LT_INIT()
|
||||
LT_LANG(C++)
|
||||
AC_LANG(C++)
|
||||
AC_PROG_CXX
|
||||
AC_PROG_OBJCXX
|
||||
AX_CXX_COMPILE_STDCXX(17,[noext],[mandatory])
|
||||
|
||||
dnl Check for logs
|
||||
AC_ARG_ENABLE([logs], [AS_HELP_STRING([--disable-logs], [Disable DHT logs])])
|
||||
AS_IF([test "x$enable_logs" != "xno"], [
|
||||
AC_DEFINE([OPENDHT_LOG], [true], [Define if DHT logs are enabled])
|
||||
], [
|
||||
AC_DEFINE([OPENDHT_LOG], [false], [Define if DHT logs are enabled])
|
||||
AS_IF([test "x$enable_logs" != "xno"], [], [
|
||||
AC_DEFINE([OPENDHT_LOG], [false], [Define if DHT logs are disabled])
|
||||
])
|
||||
|
||||
dnl Check for C binding
|
||||
@@ -83,6 +92,7 @@ case "${host_os}" in
|
||||
SYS=linux
|
||||
;;
|
||||
darwin*)
|
||||
APPLE=1
|
||||
SYS=darwin
|
||||
;;
|
||||
mingw32*)
|
||||
@@ -102,15 +112,11 @@ case "${host_os}" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AM_CONDITIONAL(APPLE, [test "x$SYS" = "xdarwin"])
|
||||
AM_CONDITIONAL(WIN32, [test "x$SYS" = "xmingw32"])
|
||||
AS_IF([test "x$SYS" = "xandroid"],
|
||||
[], [LDFLAGS="${LDFLAGS} -lpthread"])
|
||||
|
||||
LT_INIT()
|
||||
LT_LANG(C++)
|
||||
|
||||
AX_CXX_COMPILE_STDCXX(17,[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)
|
||||
@@ -138,7 +144,9 @@ AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes || test x$pro
|
||||
|
||||
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
|
||||
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
AC_CHECK_HEADERS([msgpack.hpp], [], [
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
])
|
||||
PKG_CHECK_MODULES([Argon2], [libargon2])
|
||||
AC_SUBST(argon2_lib, [", libargon2"])
|
||||
|
||||
@@ -167,7 +175,7 @@ AS_IF([test "x$have_openssl" = "xyes"], [
|
||||
])
|
||||
|
||||
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
AC_CHECK_HEADERS([asio.hpp], exit,, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
AC_CHECK_HEADERS([asio.hpp],, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
|
||||
PKG_CHECK_MODULES([Fmt], [fmt >= 5.3.0], [have_fmt=yes], [have_fmt=no])
|
||||
AS_IF([test "x$have_fmt" = "xyes"], [
|
||||
@@ -183,6 +191,7 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
])
|
||||
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
OBJCXX="$CXX $CXXFLAGS"
|
||||
|
||||
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
|
||||
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
|
||||
|
||||
@@ -32,6 +32,8 @@ extern "C" {
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <iso646.h>
|
||||
@@ -100,12 +102,12 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
/**
|
||||
* Get public key fingerprint
|
||||
*/
|
||||
InfoHash getId() const;
|
||||
const InfoHash& getId() const;
|
||||
|
||||
/**
|
||||
* Get public key long fingerprint
|
||||
*/
|
||||
PkId getLongId() const;
|
||||
const PkId& getLongId() const;
|
||||
|
||||
bool checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const;
|
||||
inline bool checkSignature(const Blob& data, const Blob& signature) const {
|
||||
@@ -138,6 +140,11 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
|
||||
gnutls_pubkey_t pk {nullptr};
|
||||
private:
|
||||
mutable InfoHash cachedId_ {};
|
||||
mutable PkId cachedLongId_ {};
|
||||
mutable std::atomic_bool idCached_ {false};
|
||||
mutable std::atomic_bool longIdCached_ {false};
|
||||
|
||||
PublicKey(const PublicKey&) = delete;
|
||||
PublicKey& operator=(const PublicKey&) = delete;
|
||||
void encryptBloc(const uint8_t* src, size_t src_size, uint8_t* dst, size_t dst_size) const;
|
||||
@@ -201,6 +208,7 @@ private:
|
||||
PrivateKey& operator=(const PrivateKey&) = delete;
|
||||
Blob decryptBloc(const uint8_t* src, size_t src_size) const;
|
||||
|
||||
mutable std::mutex publicKeyMutex_ {};
|
||||
mutable std::shared_ptr<PublicKey> publicKey_ {};
|
||||
};
|
||||
|
||||
@@ -486,9 +494,9 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
PublicKey getPublicKey() const;
|
||||
|
||||
/** Same as getPublicKey().getId() */
|
||||
InfoHash getId() const;
|
||||
const InfoHash& getId() const;
|
||||
/** Same as getPublicKey().getLongId() */
|
||||
PkId getLongId() const;
|
||||
const PkId& getLongId() const;
|
||||
|
||||
Blob getSerialNumber() const;
|
||||
|
||||
@@ -606,6 +614,8 @@ private:
|
||||
Certificate& operator=(const Certificate&) = delete;
|
||||
mutable InfoHash cachedId_ {};
|
||||
mutable PkId cachedLongId_ {};
|
||||
mutable std::atomic_bool idCached_ {false};
|
||||
mutable std::atomic_bool longIdCached_ {false};
|
||||
|
||||
struct crlNumberCmp {
|
||||
bool operator() (const std::shared_ptr<RevocationList>& lhs, const std::shared_ptr<RevocationList>& rhs) const {
|
||||
|
||||
@@ -265,6 +265,8 @@ public:
|
||||
|
||||
virtual void setPushNotificationToken(const std::string&) {};
|
||||
|
||||
virtual void setPushNotificationTopic(const std::string&) {};
|
||||
|
||||
/**
|
||||
* Call linked callback with a push notification
|
||||
* @param notification to process
|
||||
|
||||
@@ -67,6 +67,14 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void setPushNotificationTopic(const std::string& topic) override {
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
notificationTopic_ = topic;
|
||||
#else
|
||||
(void) topic;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~DhtProxyClient();
|
||||
|
||||
/**
|
||||
@@ -263,7 +271,7 @@ public:
|
||||
void dumpTables() const override {}
|
||||
std::vector<unsigned> getNodeMessageStats(bool) override { return {}; }
|
||||
void setStorageLimit(size_t) override {}
|
||||
virtual size_t getStorageLimit() const { return 0; }
|
||||
virtual size_t getStorageLimit() const override { return 0; }
|
||||
void connectivityChanged(sa_family_t) override {
|
||||
getProxyInfos();
|
||||
}
|
||||
@@ -400,6 +408,11 @@ private:
|
||||
*/
|
||||
std::string deviceKey_ {};
|
||||
|
||||
/**
|
||||
* Notification topic for ios notifications.
|
||||
*/
|
||||
std::string notificationTopic_ {};
|
||||
|
||||
const std::function<void()> loopSignal_;
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
@@ -40,7 +40,8 @@ namespace dht {
|
||||
enum class PushType {
|
||||
None = 0,
|
||||
Android,
|
||||
iOS
|
||||
iOS,
|
||||
iOSLegacy
|
||||
};
|
||||
}
|
||||
MSGPACK_ADD_ENUM(dht::PushType)
|
||||
@@ -273,6 +274,7 @@ private:
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
PushType getTypeFromString(const std::string& type);
|
||||
/**
|
||||
* Subscribe to push notifications for an iOS or Android device.
|
||||
* Method: SUBSCRIBE "/{InfoHash: .*}"
|
||||
@@ -300,7 +302,7 @@ private:
|
||||
* @param key of the device
|
||||
* @param json, the content to send
|
||||
*/
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, PushType type, bool highPriority);
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, PushType type, bool highPriority, const std::string& topic);
|
||||
|
||||
/**
|
||||
* Send push notification with an expire timeout.
|
||||
@@ -308,9 +310,10 @@ private:
|
||||
* @param pushToken
|
||||
* @param json
|
||||
* @param type
|
||||
* @param topic
|
||||
*/
|
||||
void handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
|
||||
std::function<Json::Value()> json, PushType type);
|
||||
std::function<Json::Value()> json, PushType type, const std::string& topic);
|
||||
|
||||
/**
|
||||
* Remove a push listener between a client and a hash
|
||||
@@ -382,6 +385,7 @@ private:
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
Sp<Value> value;
|
||||
PushType type;
|
||||
std::string topic;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
@@ -425,6 +429,7 @@ private:
|
||||
std::unique_ptr<asio::steady_timer> expireTimer;
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
PushType type;
|
||||
std::string topic;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
std::string proxy_server {};
|
||||
std::string push_node_id {};
|
||||
std::string push_token {};
|
||||
std::string push_topic {};
|
||||
bool peer_discovery {false};
|
||||
bool peer_publish {false};
|
||||
std::shared_ptr<dht::crypto::Certificate> server_ca;
|
||||
@@ -372,8 +373,8 @@ public:
|
||||
std::string getRoutingTablesLog(sa_family_t af) const;
|
||||
std::string getSearchesLog(sa_family_t af = AF_UNSPEC) const;
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC);
|
||||
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC);
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC) const;
|
||||
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC) const;
|
||||
void getPublicAddress(std::function<void(std::vector<SockAddr>&&)>, sa_family_t af = AF_UNSPEC);
|
||||
|
||||
// securedht methods
|
||||
@@ -437,7 +438,6 @@ public:
|
||||
/**
|
||||
* Start or stop the proxy
|
||||
* @param proxify if we want to use the proxy
|
||||
* @param deviceKey non empty to enable push notifications
|
||||
*/
|
||||
void enableProxy(bool proxify);
|
||||
|
||||
@@ -448,6 +448,11 @@ public:
|
||||
*/
|
||||
void setPushNotificationToken(const std::string& token);
|
||||
|
||||
/**
|
||||
* Sets the push notification topic
|
||||
*/
|
||||
void setPushNotificationTopic(const std::string& topic);
|
||||
|
||||
/**
|
||||
* Insert a push notification to process for OpenDHT
|
||||
*/
|
||||
@@ -474,12 +479,9 @@ private:
|
||||
DoneCallback bindOpDoneCallback(DoneCallback&& cb);
|
||||
DoneCallbackSimple bindOpDoneCallback(DoneCallbackSimple&& cb);
|
||||
|
||||
/** Local DHT instance */
|
||||
/** DHT instance */
|
||||
std::unique_ptr<SecureDht> dht_;
|
||||
|
||||
/** Proxy client instance */
|
||||
std::unique_ptr<SecureDht> dht_via_proxy_;
|
||||
|
||||
/** true if we are currently using a proxy */
|
||||
std::atomic_bool use_proxy {false};
|
||||
|
||||
@@ -491,17 +493,6 @@ private:
|
||||
* reset dht clients
|
||||
*/
|
||||
void resetDht();
|
||||
/**
|
||||
* @return the current active DHT
|
||||
*/
|
||||
SecureDht* activeDht() const;
|
||||
|
||||
/**
|
||||
* Store current listeners and translates global tokens for each client.
|
||||
*/
|
||||
struct Listener;
|
||||
std::map<size_t, Listener> listeners_;
|
||||
size_t listener_token_ {1};
|
||||
|
||||
mutable std::mutex dht_mtx {};
|
||||
std::thread dht_thread {};
|
||||
|
||||
@@ -103,13 +103,7 @@ public:
|
||||
static constexpr inline Hash zero() noexcept { return Hash{}; }
|
||||
|
||||
bool operator==(const Hash& h) const {
|
||||
auto a = reinterpret_cast<const uint32_t*>(data_.data());
|
||||
auto b = reinterpret_cast<const uint32_t*>(h.data_.data());
|
||||
constexpr unsigned n = N / sizeof(uint32_t);
|
||||
for (unsigned i=0; i < n; i++)
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
return true;
|
||||
return data_ == h.data_;
|
||||
}
|
||||
bool operator!=(const Hash& h) const { return !(*this == h); }
|
||||
|
||||
|
||||
@@ -236,6 +236,15 @@ public:
|
||||
return *reinterpret_cast<sockaddr_in6*>(get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the ownership of the managed object, if any.
|
||||
* The caller is responsible for deleting the object with free().
|
||||
*/
|
||||
inline sockaddr* release() {
|
||||
len = 0;
|
||||
return addr.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if address is a loopback IP address.
|
||||
*/
|
||||
|
||||
@@ -625,6 +625,12 @@ struct OPENDHT_PUBLIC Value
|
||||
*/
|
||||
unsigned priority {0};
|
||||
|
||||
inline bool isSignatureChecked() const {
|
||||
return signatureChecked;
|
||||
}
|
||||
inline bool isDecrypted() const {
|
||||
return decrypted;
|
||||
}
|
||||
bool checkSignature();
|
||||
Sp<Value> decrypt(const crypto::PrivateKey& key);
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
Name: OpenDHT
|
||||
Description: C++14 Distributed Hash Table library
|
||||
Description: C++17 Distributed Hash Table library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lopendht
|
||||
Libs.private: @http_parser_lib@ -pthread
|
||||
|
||||
@@ -47,6 +47,7 @@ impl DhtRunnerConfig {
|
||||
proxy_server: ptr::null(),
|
||||
push_node_id: ptr::null(),
|
||||
push_token: ptr::null(),
|
||||
push_topic: ptr::null(),
|
||||
peer_discovery: false,
|
||||
peer_publish: false,
|
||||
server_ca: ptr::null_mut(),
|
||||
@@ -73,6 +74,10 @@ impl DhtRunnerConfig {
|
||||
self.push_token = CString::new(push_token).unwrap().as_ptr();
|
||||
}
|
||||
|
||||
pub fn set_push_topic(&mut self, push_topic: &str) {
|
||||
self.push_topic = CString::new(push_topic).unwrap().as_ptr();
|
||||
}
|
||||
|
||||
pub fn set_identity(&mut self, certificate: Box<DhtCertificate>, privatekey: Box<PrivateKey>) {
|
||||
self.dht_config.id.privatekey = Box::into_raw(privatekey);
|
||||
self.dht_config.id.certificate = Box::into_raw(certificate);
|
||||
|
||||
@@ -118,6 +118,7 @@ pub struct DhtRunnerConfig
|
||||
pub proxy_server: *const c_char,
|
||||
pub push_node_id: *const c_char,
|
||||
pub push_token: *const c_char,
|
||||
pub push_topic: *const c_char,
|
||||
pub peer_discovery: bool,
|
||||
pub peer_publish: bool,
|
||||
pub server_ca: *mut DhtCertificate,
|
||||
|
||||
+6
-3
@@ -30,6 +30,12 @@ libopendht_la_SOURCES = \
|
||||
network_utils.cpp \
|
||||
thread_pool.cpp
|
||||
|
||||
if APPLE
|
||||
libopendht_la_SOURCES += \
|
||||
compat/apple/apple_utils.h \
|
||||
compat/apple/apple_utils.mm
|
||||
endif
|
||||
|
||||
if WIN32
|
||||
libopendht_la_SOURCES += rng.cpp
|
||||
endif
|
||||
@@ -84,6 +90,3 @@ if ENABLE_INDEXATION
|
||||
libopendht_la_SOURCES += indexation/pht.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/indexation/pht.h
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
rm -rf libargon2.la
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 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
|
||||
* 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 <string>
|
||||
|
||||
namespace dht {
|
||||
namespace apple_utils {
|
||||
|
||||
std::string getPlatformVersion();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 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
|
||||
* 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 "apple_utils.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
namespace apple_utils {
|
||||
|
||||
std::string
|
||||
getPlatformVersion() {
|
||||
#ifdef __APPLE__
|
||||
#if TARGET_OS_IPHONE
|
||||
if (@available(iOS 14.5, *)) {
|
||||
return "ios";
|
||||
}
|
||||
return "apple";
|
||||
#elif TARGET_OS_MAC
|
||||
return "macos";
|
||||
#endif
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
} /* dht */
|
||||
+55
-78
@@ -43,18 +43,6 @@ static std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint
|
||||
static std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
#endif
|
||||
|
||||
// support for GnuTLS < 3.4.
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030400
|
||||
#define GNUTLS_PKCS_PKCS12_3DES GNUTLS_PKCS_USE_PKCS12_3DES
|
||||
#define GNUTLS_PKCS_PKCS12_ARCFOUR GNUTLS_PKCS_USE_PKCS12_ARCFOUR
|
||||
#define GNUTLS_PKCS_PKCS12_RC2_40 GNUTLS_PKCS_USE_PKCS12_RC2_40
|
||||
#define GNUTLS_PKCS_PBES2_3DES GNUTLS_PKCS_USE_PBES2_3DES
|
||||
#define GNUTLS_PKCS_PBES2_AES_128 GNUTLS_PKCS_USE_PBES2_AES_128
|
||||
#define GNUTLS_PKCS_PBES2_AES_192 GNUTLS_PKCS_USE_PBES2_AES_192
|
||||
#define GNUTLS_PKCS_PBES2_AES_256 GNUTLS_PKCS_USE_PBES2_AES_256
|
||||
#endif
|
||||
|
||||
#define DHT_AES_LEGACY_ENCRYPT 0
|
||||
#define DHT_AES_LEGACY_DECRYPT 1
|
||||
|
||||
namespace dht {
|
||||
@@ -110,10 +98,6 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
|
||||
struct gcm_aes_ctx aes;
|
||||
gcm_aes_set_key(&aes, key.size(), key.data());
|
||||
gcm_aes_set_iv(&aes, GCM_IV_SIZE, ret.data());
|
||||
#if DHT_AES_LEGACY_ENCRYPT
|
||||
gcm_aes_update(&aes, data_length, data);
|
||||
#endif
|
||||
|
||||
gcm_aes_encrypt(&aes, data_length, ret.data() + GCM_IV_SIZE, data);
|
||||
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data_length);
|
||||
return ret;
|
||||
@@ -377,12 +361,13 @@ PrivateKey::getPublicKey() const
|
||||
const std::shared_ptr<PublicKey>&
|
||||
PrivateKey::getSharedPublicKey() const
|
||||
{
|
||||
if (publicKey_)
|
||||
return publicKey_;
|
||||
auto pk = std::make_shared<PublicKey>();
|
||||
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));
|
||||
publicKey_ = pk;
|
||||
std::lock_guard<std::mutex> lock(publicKeyMutex_);
|
||||
if (not publicKey_) {
|
||||
auto pk = std::make_shared<PublicKey>();
|
||||
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));
|
||||
publicKey_ = pk;
|
||||
}
|
||||
return publicKey_;
|
||||
}
|
||||
|
||||
@@ -542,36 +527,36 @@ PublicKey::encrypt(const uint8_t* data, size_t data_len) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
InfoHash
|
||||
const InfoHash&
|
||||
PublicKey::getId() const
|
||||
{
|
||||
if (not pk)
|
||||
return {};
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get public key ID: wrong output length.");
|
||||
return id;
|
||||
if (pk and not idCached_.load()) {
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get public key ID: wrong output length.");
|
||||
cachedId_ = id;
|
||||
idCached_.store(true);
|
||||
}
|
||||
return cachedId_;
|
||||
}
|
||||
|
||||
PkId
|
||||
const PkId&
|
||||
PublicKey::getLongId() const
|
||||
{
|
||||
if (not pk)
|
||||
return {};
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
throw CryptoException("Can't get 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
|
||||
#else
|
||||
PkId h;
|
||||
size_t sz = h.size();
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != h.size())
|
||||
throw CryptoException("Can't get 256 bits public key ID: wrong output length.");
|
||||
return h;
|
||||
#endif
|
||||
if (pk and not longIdCached_.load()) {
|
||||
PkId h;
|
||||
size_t sz = h.size();
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != h.size())
|
||||
throw CryptoException("Can't get 256 bits public key ID: wrong output length.");
|
||||
cachedLongId_ = h;
|
||||
longIdCached_.store(true);
|
||||
}
|
||||
return cachedLongId_;
|
||||
}
|
||||
|
||||
gnutls_digest_algorithm_t
|
||||
@@ -848,42 +833,36 @@ Certificate::getPublicKey() const
|
||||
return pk_ret;
|
||||
}
|
||||
|
||||
InfoHash
|
||||
const InfoHash&
|
||||
Certificate::getId() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
if (cachedId_)
|
||||
return cachedId_;
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate public key ID: wrong output length.");
|
||||
cachedId_ = id;
|
||||
return id;
|
||||
if (cert and not idCached_.load()) {
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate public key ID: wrong output length.");
|
||||
cachedId_ = id;
|
||||
idCached_.store(true);
|
||||
}
|
||||
return cachedId_;
|
||||
}
|
||||
|
||||
PkId
|
||||
const PkId&
|
||||
Certificate::getLongId() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
if (cachedLongId_)
|
||||
return cachedLongId_;
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
|
||||
#else
|
||||
PkId id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
|
||||
cachedLongId_ = id;
|
||||
return id;
|
||||
#endif
|
||||
if (cert and not longIdCached_.load()) {
|
||||
PkId id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
|
||||
cachedLongId_ = id;
|
||||
longIdCached_.store(true);
|
||||
}
|
||||
return cachedLongId_;
|
||||
}
|
||||
|
||||
Blob
|
||||
@@ -1771,10 +1750,8 @@ std::ostream& operator<< (std::ostream& o, const TrustList::VerifyResult& h)
|
||||
o << "* Certificate has expired" << std::endl;
|
||||
if (h.result & GNUTLS_CERT_UNEXPECTED_OWNER)
|
||||
o << "* The owner is not the expected one" << std::endl;
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030401
|
||||
if (h.result & GNUTLS_CERT_PURPOSE_MISMATCH)
|
||||
o << "* Certificate or an intermediate does not match the intended purpose" << std::endl;
|
||||
#endif
|
||||
if (h.result & GNUTLS_CERT_MISMATCH)
|
||||
o << "* Certificate presented isn't the expected one" << std::endl;
|
||||
} else {
|
||||
|
||||
@@ -22,10 +22,14 @@
|
||||
#include "dhtrunner.h"
|
||||
#include "op_cache.h"
|
||||
#include "utils.h"
|
||||
#ifdef __APPLE__
|
||||
#include "compat/apple/apple_utils.h"
|
||||
#endif
|
||||
|
||||
#include <http_parser.h>
|
||||
#include <deque>
|
||||
|
||||
|
||||
namespace dht {
|
||||
|
||||
struct DhtProxyClient::InfoState {
|
||||
@@ -1303,7 +1307,8 @@ DhtProxyClient::getPushRequest(Json::Value& body) const
|
||||
body["platform"] = "android";
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
body["platform"] = "apple";
|
||||
body["topic"] = notificationTopic_;
|
||||
body["platform"] = apple_utils::getPlatformVersion();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+49
-14
@@ -372,7 +372,7 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
pput.second.expireNotifyTimer = std::make_unique<asio::steady_timer>(io_context(), pput.second.expiration - proxy::OP_MARGIN);
|
||||
pput.second.expireNotifyTimer->async_wait(std::bind(
|
||||
&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pput.second.pushToken, std::move(jsonProvider), pput.second.type));
|
||||
std::placeholders::_1, pput.second.pushToken, std::move(jsonProvider), pput.second.type, pput.second.topic));
|
||||
}
|
||||
#endif
|
||||
dht_->put(put.first, pput.second.value, DoneCallbackSimple{}, time_point::max(), true);
|
||||
@@ -392,7 +392,7 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
for (auto& listeners : pushListener.second.listeners) {
|
||||
for (auto& listener : listeners.second) {
|
||||
listener.internalToken = dht_->listen(listeners.first,
|
||||
[this, infoHash=listeners.first, pushToken=pushListener.first, type=listener.type, clientId=listener.clientId, sessionCtx = listener.sessionCtx]
|
||||
[this, infoHash=listeners.first, pushToken=pushListener.first, type=listener.type, clientId=listener.clientId, sessionCtx = listener.sessionCtx, topic=listener.topic]
|
||||
(const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
// Build message content
|
||||
Json::Value json;
|
||||
@@ -414,7 +414,7 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
auto maxPrio = 1000u;
|
||||
for (const auto& v : values)
|
||||
maxPrio = std::min(maxPrio, v->priority);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0, topic);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
@@ -429,7 +429,7 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
return json;
|
||||
};
|
||||
listener.expireNotifyTimer->async_wait(std::bind(&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushListener.first, std::move(jsonProvider), listener.type));
|
||||
std::placeholders::_1, pushListener.first, std::move(jsonProvider), listener.type, listener.topic));
|
||||
// cancel push listen
|
||||
listener.expireTimer = std::make_unique<asio::steady_timer>(io_context(), listener.expiration);
|
||||
listener.expireTimer->async_wait(std::bind(&DhtProxyServer::handleCancelPushListen, this,
|
||||
@@ -745,6 +745,21 @@ DhtProxyServer::listen(restinio::request_handle_t request,
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
PushType
|
||||
DhtProxyServer::getTypeFromString(const std::string& type) {
|
||||
if (type == "android") {
|
||||
return PushType::Android;
|
||||
}
|
||||
if (type == "apple") {
|
||||
// proxy_client is not updated or using ios < 14.5
|
||||
return PushType::iOSLegacy;
|
||||
}
|
||||
if (type == "ios") {
|
||||
return PushType::iOS;
|
||||
}
|
||||
return PushType::None;
|
||||
}
|
||||
|
||||
RequestStatus
|
||||
DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params)
|
||||
@@ -771,7 +786,8 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
response.set_body(RESP_MSG_NO_TOKEN);
|
||||
return response.done();
|
||||
}
|
||||
auto type = root["platform"].asString() == "android" ? PushType::Android : PushType::iOS;
|
||||
auto type = getTypeFromString(root["platform"].asString());
|
||||
auto topic = root["topic"].asString();
|
||||
auto clientId = root["client_id"].asString();
|
||||
auto sessionId = root["session_id"].asString();
|
||||
|
||||
@@ -802,6 +818,7 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
auto timeout = std::chrono::steady_clock::now() + proxy::OP_TIMEOUT;
|
||||
listener.expiration = timeout;
|
||||
listener.type = type;
|
||||
listener.topic = topic;
|
||||
if (listener.expireNotifyTimer)
|
||||
listener.expireNotifyTimer->expires_at(timeout - proxy::OP_MARGIN);
|
||||
else
|
||||
@@ -815,7 +832,7 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
return json;
|
||||
};
|
||||
listener.expireNotifyTimer->async_wait(std::bind(&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), listener.type));
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), listener.type, listener.topic));
|
||||
if (!listener.expireTimer)
|
||||
listener.expireTimer = std::make_unique<asio::steady_timer>(io_context(), timeout);
|
||||
else
|
||||
@@ -850,7 +867,7 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
// =========== No existing listener for an infoHash ============
|
||||
// Add listen on dht
|
||||
listener.internalToken = dht_->listen(infoHash,
|
||||
[this, infoHash, pushToken, type, clientId, sessionCtx = listener.sessionCtx]
|
||||
[this, infoHash, pushToken, type, clientId, sessionCtx = listener.sessionCtx, topic]
|
||||
(const std::vector<std::shared_ptr<Value>>& values, bool expired){
|
||||
// Build message content
|
||||
Json::Value json;
|
||||
@@ -872,7 +889,7 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
auto maxPrio = 1000u;
|
||||
for (const auto& v : values)
|
||||
maxPrio = std::min(maxPrio, v->priority);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0, topic);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
@@ -928,7 +945,7 @@ DhtProxyServer::unsubscribe(restinio::request_handle_t request,
|
||||
|
||||
void
|
||||
DhtProxyServer::handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
|
||||
std::function<Json::Value()> jsonProvider, PushType type)
|
||||
std::function<Json::Value()> jsonProvider, PushType type, const std::string& topic)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
@@ -938,7 +955,7 @@ DhtProxyServer::handleNotifyPushListenExpire(const asio::error_code &ec, const s
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [subscribe] sending put refresh to %s token", pushToken.c_str());
|
||||
sendPushNotification(pushToken, jsonProvider(), type, false);
|
||||
sendPushNotification(pushToken, jsonProvider(), type, false, topic);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -980,7 +997,7 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code &ec, const std::st
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority)
|
||||
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority, const std::string& topic)
|
||||
{
|
||||
if (pushServer_.empty())
|
||||
return;
|
||||
@@ -1011,6 +1028,22 @@ DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& jso
|
||||
const auto expiration = std::chrono::system_clock::now() + std::chrono::hours(24);
|
||||
uint32_t exp = std::chrono::duration_cast<std::chrono::seconds>(expiration.time_since_epoch()).count();
|
||||
notification["expiration"] = exp;
|
||||
if (!topic.empty())
|
||||
notification["topic"] = topic;
|
||||
if (type == PushType::iOS) {
|
||||
if (highPriority) {
|
||||
Json::Value alert(Json::objectValue);
|
||||
alert["title"]="hello";
|
||||
notification["push_type"] = "alert";
|
||||
notification["alert"] = alert;
|
||||
notification["mutable_content"] = true;
|
||||
} else {
|
||||
notification["push_type"] = "background";
|
||||
notification["content_available"] = true;
|
||||
}
|
||||
} else if (type == PushType::iOSLegacy) {
|
||||
notification["push_type"] = "voip";
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value notifications(Json::arrayValue);
|
||||
@@ -1104,13 +1137,14 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
logger_->d("[proxy:server] [put %s] %s %s", infoHash.toString().c_str(),
|
||||
value->toString().c_str(), (permanent ? "permanent" : ""));
|
||||
if (permanent) {
|
||||
std::string pushToken, clientId, sessionId, platform;
|
||||
std::string pushToken, clientId, sessionId, platform, topic;
|
||||
auto& pVal = root["permanent"];
|
||||
if (pVal.isObject()){
|
||||
pushToken = pVal["key"].asString();
|
||||
clientId = pVal["client_id"].asString();
|
||||
platform = pVal["platform"].asString();
|
||||
sessionId = pVal["session_id"].asString();
|
||||
topic = pVal["topic"].asString();
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
auto timeout = std::chrono::steady_clock::now() + proxy::OP_TIMEOUT;
|
||||
@@ -1153,7 +1187,8 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
bool isAndroid = platform == "android";
|
||||
pput.pushToken = pushToken;
|
||||
pput.clientId = clientId;
|
||||
pput.type = isAndroid ? PushType::Android : PushType::iOS;
|
||||
pput.type = getTypeFromString(platform);
|
||||
pput.topic = topic;
|
||||
pput.sessionCtx = std::make_shared<PushSessionContext>(sessionId);
|
||||
// notify push listen expire
|
||||
auto jsonProvider = [infoHash, clientId, vid, sessionCtx = pput.sessionCtx](){
|
||||
@@ -1172,7 +1207,7 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
pput.expireNotifyTimer->expires_at(timeout - proxy::OP_MARGIN);
|
||||
pput.expireNotifyTimer->async_wait(std::bind(
|
||||
&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), pput.type));
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), pput.type, pput.topic));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
|
||||
+96
-231
@@ -38,15 +38,6 @@ namespace dht {
|
||||
|
||||
static const std::string PEER_DISCOVERY_DHT_SERVICE = "dht";
|
||||
|
||||
struct DhtRunner::Listener {
|
||||
size_t tokenClassicDht {0};
|
||||
size_t tokenProxyDht {0};
|
||||
ValueCallback gcb;
|
||||
InfoHash hash {};
|
||||
Value::Filter f;
|
||||
Where w;
|
||||
};
|
||||
|
||||
struct NodeInsertionPack {
|
||||
dht::InfoHash nodeId;
|
||||
in_port_t port;
|
||||
@@ -55,9 +46,6 @@ struct NodeInsertionPack {
|
||||
};
|
||||
|
||||
DhtRunner::DhtRunner() : dht_()
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
, dht_via_proxy_()
|
||||
#endif //OPENDHT_PROXY_CLIENT
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsd;
|
||||
@@ -144,69 +132,59 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
|
||||
if (context.logger) {
|
||||
logger_ = context.logger;
|
||||
}
|
||||
|
||||
if (not context.sock) {
|
||||
context.sock.reset(new net::UdpSocket(local4, local6, context.logger));
|
||||
}
|
||||
|
||||
if (not state_path.empty() and config.proxy_server.empty()) {
|
||||
std::ofstream outConfig(state_path);
|
||||
outConfig << context.sock->getBoundRef(AF_INET).getPort() << std::endl;
|
||||
outConfig << context.sock->getBoundRef(AF_INET6).getPort() << std::endl;
|
||||
}
|
||||
|
||||
if (context.logger) {
|
||||
logger_->d("[runner %p] state changed to Running", this);
|
||||
}
|
||||
|
||||
context.sock->setOnReceive([&] (net::PacketList&& pkts) {
|
||||
net::PacketList ret;
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(sock_mtx);
|
||||
rcv.splice(rcv.end(), std::move(pkts));
|
||||
size_t dropped = 0;
|
||||
while (rcv.size() > net::RX_QUEUE_MAX_SIZE) {
|
||||
rcv.pop_front();
|
||||
dropped++;
|
||||
}
|
||||
if (dropped and logger_) {
|
||||
logger_->w("[runner %p] dropped %zu packets: queue is full!", this, dropped);
|
||||
}
|
||||
ret = std::move(rcv_free);
|
||||
}
|
||||
cv.notify_all();
|
||||
return ret;
|
||||
});
|
||||
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
config_ = config;
|
||||
identityAnnouncedCb_ = context.identityAnnouncedCb;
|
||||
#endif
|
||||
auto dht = std::make_unique<Dht>(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger);
|
||||
dht_ = std::make_unique<SecureDht>(std::move(dht), config.dht_config, std::move(context.identityAnnouncedCb), context.logger);
|
||||
enableProxy(not config.proxy_server.empty());
|
||||
|
||||
if (config.proxy_server.empty()) {
|
||||
if (not context.sock) {
|
||||
context.sock.reset(new net::UdpSocket(local4, local6, context.logger));
|
||||
}
|
||||
context.sock->setOnReceive([&] (net::PacketList&& pkts) {
|
||||
net::PacketList ret;
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(sock_mtx);
|
||||
rcv.splice(rcv.end(), std::move(pkts));
|
||||
size_t dropped = 0;
|
||||
while (rcv.size() > net::RX_QUEUE_MAX_SIZE) {
|
||||
rcv.pop_front();
|
||||
dropped++;
|
||||
}
|
||||
if (dropped and logger_) {
|
||||
logger_->w("[runner %p] dropped %zu packets: queue is full!", this, dropped);
|
||||
}
|
||||
ret = std::move(rcv_free);
|
||||
}
|
||||
cv.notify_all();
|
||||
return ret;
|
||||
});
|
||||
if (not state_path.empty()) {
|
||||
std::ofstream outConfig(state_path);
|
||||
outConfig << context.sock->getBoundRef(AF_INET).getPort() << std::endl;
|
||||
outConfig << context.sock->getBoundRef(AF_INET6).getPort() << std::endl;
|
||||
}
|
||||
auto dht = std::make_unique<Dht>(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger);
|
||||
dht_ = std::make_unique<SecureDht>(std::move(dht), config.dht_config, std::move(context.identityAnnouncedCb), context.logger);
|
||||
} else {
|
||||
enableProxy(true);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
config_ = {};
|
||||
identityAnnouncedCb_ = {};
|
||||
dht_.reset();
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
dht_via_proxy_.reset();
|
||||
#endif
|
||||
running = State::Idle;
|
||||
throw;
|
||||
}
|
||||
|
||||
if (context.logger and dht_via_proxy_) {
|
||||
dht_via_proxy_->setLogger(context.logger);
|
||||
}
|
||||
if (context.statusChangedCallback) {
|
||||
statusCb = std::move(context.statusChangedCallback);
|
||||
}
|
||||
if (context.certificateStore) {
|
||||
dht_->setLocalCertificateStore(std::move(context.certificateStore));
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->setLocalCertificateStore(std::move(context.certificateStore));
|
||||
}
|
||||
|
||||
if (not config.threaded)
|
||||
@@ -289,7 +267,8 @@ DhtRunner::shutdown(ShutdownCallback cb, bool stop) {
|
||||
auto expected = State::Running;
|
||||
if (not running.compare_exchange_strong(expected, State::Stopping)) {
|
||||
if (expected == State::Stopping and ongoing_ops) {
|
||||
shutdownCallbacks_.emplace_back(std::move(cb));
|
||||
if (cb)
|
||||
shutdownCallbacks_.emplace_back(std::move(cb));
|
||||
}
|
||||
else if (cb) {
|
||||
lck.unlock();
|
||||
@@ -299,20 +278,10 @@ DhtRunner::shutdown(ShutdownCallback cb, bool stop) {
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("[runner %p] state changed to Stopping, %zu ongoing ops", this, ongoing_ops.load());
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
ongoing_ops += 2;
|
||||
#else
|
||||
ongoing_ops++;
|
||||
#endif
|
||||
shutdownCallbacks_.emplace_back(std::move(cb));
|
||||
pending_ops.emplace([=](SecureDht&) mutable {
|
||||
auto onShutdown = [this]{ opEnded(); };
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->shutdown(onShutdown, stop);
|
||||
else
|
||||
opEnded();
|
||||
#endif
|
||||
if (dht_)
|
||||
dht_->shutdown(onShutdown, stop);
|
||||
else
|
||||
@@ -419,31 +388,25 @@ void
|
||||
DhtRunner::dumpTables() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
activeDht()->dumpTables();
|
||||
dht_->dumpTables();
|
||||
}
|
||||
|
||||
InfoHash
|
||||
DhtRunner::getId() const
|
||||
{
|
||||
if (auto dht = activeDht())
|
||||
return dht->getId();
|
||||
return {};
|
||||
return dht_ ? dht_->getId() : InfoHash{};
|
||||
}
|
||||
|
||||
std::shared_ptr<crypto::PublicKey>
|
||||
DhtRunner::getPublicKey() const
|
||||
{
|
||||
if (auto dht = activeDht())
|
||||
return dht->getPublicKey();
|
||||
return {};
|
||||
return dht_ ? dht_->getPublicKey() : std::shared_ptr<crypto::PublicKey>{};
|
||||
}
|
||||
|
||||
InfoHash
|
||||
DhtRunner::getNodeId() const
|
||||
{
|
||||
if (auto dht = activeDht())
|
||||
return dht->getNodeId();
|
||||
return {};
|
||||
return dht_ ? dht_->getNodeId() : InfoHash{};
|
||||
}
|
||||
|
||||
|
||||
@@ -485,10 +448,6 @@ DhtRunner::setLogger(const Sp<Logger>& logger) {
|
||||
logger_ = logger;
|
||||
if (dht_)
|
||||
dht_->setLogger(logger);
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->setLogger(logger);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -502,16 +461,12 @@ DhtRunner::setLogFilter(const InfoHash& f) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
if (dht_)
|
||||
dht_->setLogFilter(f);
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->setLogFilter(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::registerType(const ValueType& type) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
activeDht()->registerType(type);
|
||||
dht_->registerType(type);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -524,7 +479,7 @@ unsigned
|
||||
DhtRunner::getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
const auto stats = activeDht()->getNodesStats(af);
|
||||
const auto stats = dht_->getNodesStats(af);
|
||||
if (good_return)
|
||||
*good_return = stats.good_nodes;
|
||||
if (dubious_return)
|
||||
@@ -540,19 +495,19 @@ NodeStats
|
||||
DhtRunner::getNodesStats(sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getNodesStats(af);
|
||||
return dht_->getNodesStats(af);
|
||||
}
|
||||
|
||||
NodeInfo
|
||||
DhtRunner::getNodeInfo() const {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
NodeInfo info {};
|
||||
if (auto dht = activeDht()) {
|
||||
info.id = dht->getId();
|
||||
info.node_id = dht->getNodeId();
|
||||
info.ipv4 = dht->getNodesStats(AF_INET);
|
||||
info.ipv6 = dht->getNodesStats(AF_INET6);
|
||||
if (auto sock = dht->getSocket()) {
|
||||
if (dht_) {
|
||||
info.id = dht_->getId();
|
||||
info.node_id = dht_->getNodeId();
|
||||
info.ipv4 = dht_->getNodesStats(AF_INET);
|
||||
info.ipv6 = dht_->getNodesStats(AF_INET6);
|
||||
if (auto sock = dht_->getSocket()) {
|
||||
info.bound4 = sock->getBoundRef(AF_INET).getPort();
|
||||
info.bound6 = sock->getBoundRef(AF_INET6).getPort();
|
||||
}
|
||||
@@ -589,49 +544,49 @@ std::vector<unsigned>
|
||||
DhtRunner::getNodeMessageStats(bool in) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getNodeMessageStats(in);
|
||||
return dht_->getNodeMessageStats(in);
|
||||
}
|
||||
|
||||
std::string
|
||||
DhtRunner::getStorageLog() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getStorageLog();
|
||||
return dht_->getStorageLog();
|
||||
}
|
||||
std::string
|
||||
DhtRunner::getStorageLog(const InfoHash& f) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getStorageLog(f);
|
||||
return dht_->getStorageLog(f);
|
||||
}
|
||||
std::string
|
||||
DhtRunner::getRoutingTablesLog(sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getRoutingTablesLog(af);
|
||||
return dht_->getRoutingTablesLog(af);
|
||||
}
|
||||
std::string
|
||||
DhtRunner::getSearchesLog(sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getSearchesLog(af);
|
||||
return dht_->getSearchesLog(af);
|
||||
}
|
||||
std::string
|
||||
DhtRunner::getSearchLog(const InfoHash& f, sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
return activeDht()->getSearchLog(f, af);
|
||||
return dht_->getSearchLog(f, af);
|
||||
}
|
||||
std::vector<SockAddr>
|
||||
DhtRunner::getPublicAddress(sa_family_t af)
|
||||
DhtRunner::getPublicAddress(sa_family_t af) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
if (auto dht = activeDht())
|
||||
return dht->getPublicAddress(af);
|
||||
if (dht_)
|
||||
return dht_->getPublicAddress(af);
|
||||
return {};
|
||||
}
|
||||
std::vector<std::string>
|
||||
DhtRunner::getPublicAddressStr(sa_family_t af)
|
||||
DhtRunner::getPublicAddressStr(sa_family_t af) const
|
||||
{
|
||||
auto addrs = getPublicAddress(af);
|
||||
std::vector<std::string> ret(addrs.size());
|
||||
@@ -654,15 +609,12 @@ DhtRunner::getPublicAddress(std::function<void(std::vector<SockAddr>&&)> cb, sa_
|
||||
void
|
||||
DhtRunner::registerCertificate(std::shared_ptr<crypto::Certificate> cert) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
activeDht()->registerCertificate(cert);
|
||||
dht_->registerCertificate(cert);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setLocalCertificateStore(CertificateStoreQuery&& query_method) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->setLocalCertificateStore(std::forward<CertificateStoreQuery>(query_method));
|
||||
#endif
|
||||
if (dht_)
|
||||
dht_->setLocalCertificateStore(std::forward<CertificateStoreQuery>(query_method));
|
||||
}
|
||||
@@ -670,8 +622,7 @@ DhtRunner::setLocalCertificateStore(CertificateStoreQuery&& query_method) {
|
||||
time_point
|
||||
DhtRunner::loop_()
|
||||
{
|
||||
auto dht = activeDht();
|
||||
if (not dht)
|
||||
if (not dht_)
|
||||
return {};
|
||||
|
||||
decltype(pending_ops) ops {};
|
||||
@@ -682,7 +633,7 @@ DhtRunner::loop_()
|
||||
std::move(pending_ops) : std::move(pending_ops_prio);
|
||||
}
|
||||
while (not ops.empty()) {
|
||||
ops.front()(*dht);
|
||||
ops.front()(*dht_);
|
||||
ops.pop();
|
||||
}
|
||||
|
||||
@@ -715,13 +666,13 @@ DhtRunner::loop_()
|
||||
if (now - pkt.received > net::RX_QUEUE_MAX_DELAY)
|
||||
dropped++;
|
||||
else
|
||||
wakeup = dht->periodic(pkt.data.data(), pkt.data.size(), std::move(pkt.from), now);
|
||||
wakeup = dht_->periodic(pkt.data.data(), pkt.data.size(), std::move(pkt.from), now);
|
||||
pkt.data.clear();
|
||||
}
|
||||
received_treated.splice(received_treated.end(), std::move(received));
|
||||
} else {
|
||||
// Or just run the scheduler
|
||||
wakeup = dht->periodic(nullptr, 0, nullptr, 0, clock::now());
|
||||
wakeup = dht_->periodic(nullptr, 0, nullptr, 0, clock::now());
|
||||
}
|
||||
|
||||
if (not received_treated.empty()) {
|
||||
@@ -733,8 +684,8 @@ DhtRunner::loop_()
|
||||
if (dropped && logger_)
|
||||
logger_->e("[runner %p] Dropped %zu packets with high delay.", this, dropped);
|
||||
|
||||
NodeStatus nstatus4 = dht->updateStatus(AF_INET);
|
||||
NodeStatus nstatus6 = dht->updateStatus(AF_INET6);
|
||||
NodeStatus nstatus4 = dht_->updateStatus(AF_INET);
|
||||
NodeStatus nstatus6 = dht_->updateStatus(AF_INET6);
|
||||
if (nstatus4 != status4 || nstatus6 != status6) {
|
||||
status4 = nstatus4;
|
||||
status6 = nstatus6;
|
||||
@@ -792,27 +743,7 @@ DhtRunner::listen(InfoHash hash, ValueCallback vcb, Value::Filter f, Where w)
|
||||
return ret_token->get_future();
|
||||
}
|
||||
pending_ops.emplace([=](SecureDht& dht) mutable {
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
auto tokenbGlobal = listener_token_++;
|
||||
auto& listener = listeners_[tokenbGlobal];
|
||||
listener.hash = hash;
|
||||
listener.f = std::move(f);
|
||||
listener.w = std::move(w);
|
||||
listener.gcb = [hash,vcb,tokenbGlobal,this](const std::vector<Sp<Value>>& vals, bool expired) {
|
||||
if (not vcb(vals, expired)) {
|
||||
cancelListen(hash, tokenbGlobal);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (auto token = dht.listen(hash, listener.gcb, listener.f, listener.w)) {
|
||||
if (use_proxy) listener.tokenProxyDht = token;
|
||||
else listener.tokenClassicDht = token;
|
||||
}
|
||||
ret_token->set_value(tokenbGlobal);
|
||||
#else
|
||||
ret_token->set_value(dht.listen(hash, std::move(vcb), std::move(f), std::move(w)));
|
||||
#endif
|
||||
});
|
||||
cv.notify_all();
|
||||
return ret_token->get_future();
|
||||
@@ -831,27 +762,10 @@ DhtRunner::cancelListen(InfoHash h, size_t token)
|
||||
if (running != State::Running)
|
||||
return;
|
||||
ongoing_ops++;
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
pending_ops.emplace([=](SecureDht&) {
|
||||
auto it = listeners_.find(token);
|
||||
if (it != listeners_.end()) {
|
||||
if (it->second.tokenClassicDht)
|
||||
dht_->cancelListen(h, it->second.tokenClassicDht);
|
||||
if (it->second.tokenProxyDht and dht_via_proxy_)
|
||||
dht_via_proxy_->cancelListen(h, it->second.tokenProxyDht);
|
||||
listeners_.erase(it);
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->w("[runner %p] cancelListen: unknown token %zu.", this, token);
|
||||
}
|
||||
opEnded();
|
||||
});
|
||||
#else
|
||||
pending_ops.emplace([=](SecureDht& dht) {
|
||||
dht.cancelListen(h, token);
|
||||
opEnded();
|
||||
});
|
||||
#endif // OPENDHT_PROXY_CLIENT
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
@@ -862,28 +776,10 @@ DhtRunner::cancelListen(InfoHash h, std::shared_future<size_t> ftoken)
|
||||
if (running != State::Running)
|
||||
return;
|
||||
ongoing_ops++;
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
pending_ops.emplace([this, h, ftoken = std::move(ftoken)](SecureDht&) {
|
||||
auto token = ftoken.get();
|
||||
auto it = listeners_.find(token);
|
||||
if (it != listeners_.end()) {
|
||||
if (it->second.tokenClassicDht)
|
||||
dht_->cancelListen(h, it->second.tokenClassicDht);
|
||||
if (it->second.tokenProxyDht and dht_via_proxy_)
|
||||
dht_via_proxy_->cancelListen(h, it->second.tokenProxyDht);
|
||||
listeners_.erase(it);
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->w("[runner %p] cancelListen: unknown token %zu.", this, token);
|
||||
}
|
||||
opEnded();
|
||||
});
|
||||
#else
|
||||
pending_ops.emplace([this, h, ftoken = std::move(ftoken)](SecureDht& dht) {
|
||||
dht.cancelListen(h, ftoken.get());
|
||||
opEnded();
|
||||
});
|
||||
#endif // OPENDHT_PROXY_CLIENT
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
@@ -1172,23 +1068,9 @@ void
|
||||
DhtRunner::resetDht()
|
||||
{
|
||||
peerDiscovery_.reset();
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
listeners_.clear();
|
||||
dht_via_proxy_.reset();
|
||||
#endif // OPENDHT_PROXY_CLIENT
|
||||
dht_.reset();
|
||||
}
|
||||
|
||||
SecureDht*
|
||||
DhtRunner::activeDht() const
|
||||
{
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
return use_proxy? dht_via_proxy_.get() : dht_.get();
|
||||
#else
|
||||
return dht_.get();
|
||||
#endif // OPENDHT_PROXY_CLIENT
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setProxyServer(const std::string& proxy, const std::string& pushNodeId)
|
||||
{
|
||||
@@ -1201,7 +1083,7 @@ DhtRunner::setProxyServer(const std::string& proxy, const std::string& pushNodeI
|
||||
enableProxy(use_proxy and not config_.proxy_server.empty());
|
||||
#else
|
||||
if (not proxy.empty())
|
||||
std::cerr << "DHT proxy requested but OpenDHT built without proxy support." << std::endl;
|
||||
throw std::runtime_error("DHT proxy requested but OpenDHT built without proxy support.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1209,54 +1091,35 @@ void
|
||||
DhtRunner::enableProxy(bool proxify)
|
||||
{
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_) {
|
||||
dht_via_proxy_->shutdown({});
|
||||
if (dht_) {
|
||||
dht_->shutdown({});
|
||||
}
|
||||
if (proxify) {
|
||||
// Init the proxy client
|
||||
auto dht_via_proxy = std::unique_ptr<DhtInterface>(
|
||||
new DhtProxyClient(
|
||||
auto dht_via_proxy = std::make_unique<DhtProxyClient>(
|
||||
config_.server_ca,
|
||||
config_.client_identity,
|
||||
[this]{
|
||||
if (config_.threaded) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops_prio.emplace([=](SecureDht&) mutable {});
|
||||
}
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops_prio.emplace([=](SecureDht&) mutable {});
|
||||
cv.notify_all();
|
||||
}
|
||||
},
|
||||
config_.proxy_server, config_.push_node_id, logger_)
|
||||
);
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
config_.proxy_server, config_.push_node_id, logger_);
|
||||
if (not config_.push_token.empty())
|
||||
dht_via_proxy->setPushNotificationToken(config_.push_token);
|
||||
#endif
|
||||
dht_via_proxy_ = std::unique_ptr<SecureDht>(new SecureDht(std::move(dht_via_proxy), config_.dht_config, identityAnnouncedCb_, logger_));
|
||||
// add current listeners
|
||||
for (auto& l: listeners_)
|
||||
l.second.tokenProxyDht = dht_via_proxy_->listen(l.second.hash, l.second.gcb, l.second.f, l.second.w);
|
||||
if (not config_.push_topic.empty())
|
||||
dht_via_proxy->setPushNotificationTopic(config_.push_topic);
|
||||
dht_ = std::make_unique<SecureDht>(std::move(dht_via_proxy), config_.dht_config, identityAnnouncedCb_, logger_);
|
||||
// and use it
|
||||
use_proxy = proxify;
|
||||
} else {
|
||||
use_proxy = proxify;
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
if (not listeners_.empty()) {
|
||||
pending_ops.emplace([this](SecureDht& /*dht*/) mutable {
|
||||
if (not dht_)
|
||||
return;
|
||||
for (auto& l : listeners_) {
|
||||
if (not l.second.tokenClassicDht) {
|
||||
l.second.tokenClassicDht = dht_->listen(l.second.hash, l.second.gcb, l.second.f, l.second.w);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (proxify)
|
||||
std::cerr << "DHT proxy requested but OpenDHT built without proxy support." << std::endl;
|
||||
throw std::runtime_error("DHT proxy requested but OpenDHT built without proxy support.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1264,16 +1127,8 @@ void
|
||||
DhtRunner::forwardAllMessages(bool forward)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
#ifdef OPENDHT_PROXY_SERVER
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->forwardAllMessages(forward);
|
||||
#endif // OPENDHT_PROXY_CLIENT
|
||||
if (dht_)
|
||||
dht_->forwardAllMessages(forward);
|
||||
#else
|
||||
(void) forward;
|
||||
#endif // OPENDHT_PROXY_SERVER
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1284,24 +1139,34 @@ DhtRunner::setPushNotificationToken(const std::string& token) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
|
||||
config_.push_token = token;
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->setPushNotificationToken(token);
|
||||
if (dht_)
|
||||
dht_->setPushNotificationToken(token);
|
||||
#else
|
||||
(void) token;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setPushNotificationTopic(const std::string& topic) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
|
||||
config_.push_topic = topic;
|
||||
if (dht_)
|
||||
dht_->setPushNotificationTopic(topic);
|
||||
#else
|
||||
(void) topic;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::pushNotificationReceived(const std::map<std::string, std::string>& data)
|
||||
{
|
||||
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops_prio.emplace([=](SecureDht&) {
|
||||
if (dht_via_proxy_)
|
||||
dht_via_proxy_->pushNotificationReceived(data);
|
||||
});
|
||||
}
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
pending_ops_prio.emplace([=](SecureDht&) {
|
||||
if (dht_)
|
||||
dht_->pushNotificationReceived(data);
|
||||
});
|
||||
cv.notify_all();
|
||||
#else
|
||||
(void) data;
|
||||
|
||||
@@ -415,7 +415,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<ParsedMessage> msg {new ParsedMessage};
|
||||
auto msg = std::make_unique<ParsedMessage>();
|
||||
try {
|
||||
msgpack::unpacked msg_res = msgpack::unpack((const char*)buf, buflen);
|
||||
msg->msgpack_unpack(msg_res.get());
|
||||
|
||||
+5
-2
@@ -238,8 +238,10 @@ SecureDht::checkValue(const Sp<Value>& v)
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
auto isDecrypted = v->isDecrypted();
|
||||
if (auto decrypted_val = v->decrypt(*key_)) {
|
||||
if (decrypted_val->owner)
|
||||
auto cacheValue = not isDecrypted and decrypted_val->owner;
|
||||
if (cacheValue)
|
||||
nodesPubKeys_[decrypted_val->owner->getId()] = decrypted_val->owner;
|
||||
return decrypted_val;
|
||||
}
|
||||
@@ -250,8 +252,9 @@ SecureDht::checkValue(const Sp<Value>& v)
|
||||
}
|
||||
// Check signed values
|
||||
else if (v->isSigned()) {
|
||||
auto cacheValue = not v->isSignatureChecked() and enableCache_ and v->owner;
|
||||
if (v->checkSignature()) {
|
||||
if (enableCache_ and v->owner)
|
||||
if (cacheValue)
|
||||
nodesPubKeys_[v->owner->getId()] = v->owner;
|
||||
return v;
|
||||
} else if (logger_)
|
||||
|
||||
+1
-1
@@ -296,8 +296,8 @@ Value::decrypt(const crypto::PrivateKey& key)
|
||||
decrypted = true;
|
||||
if (isEncrypted()) {
|
||||
auto decryptedBlob = key.decrypt(cypher);
|
||||
std::unique_ptr<Value> v {new Value(id)};
|
||||
auto msg = msgpack::unpack((const char*)decryptedBlob.data(), decryptedBlob.size());
|
||||
auto v = std::make_unique<Value>(id);
|
||||
v->msgpack_unpack_body(msg.get());
|
||||
if (v->recipient != key.getPublicKey().getId())
|
||||
throw crypto::DecryptError("Recipient mismatch");
|
||||
|
||||
+1
-3
@@ -242,12 +242,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
free(addrs);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (!strcmp(cmd, "ll")) {
|
||||
dht_infohash key = dht_runner_get_node_id(runner);
|
||||
key = dht_runner_get_node_id(runner);
|
||||
printf("DHT node %s running on port %u\n", dht_infohash_print(&key), dht_runner_get_bound_port(runner, AF_INET));
|
||||
continue;
|
||||
}
|
||||
else if (!strcmp(cmd, "g")) {
|
||||
key = parse_key(arg);
|
||||
|
||||
Reference in new issue
Block a user