mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 12:28:42 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
370f619ac4 |
No files matched your search
@@ -159,13 +159,7 @@ public:
|
||||
{}
|
||||
|
||||
static Value::Filter getFilter() { return EncryptedValue::getFilter(); }
|
||||
virtual void unpackValue(const dht::Value& v) override
|
||||
{
|
||||
BaseClass::unpackValue(v);
|
||||
id = v.id;
|
||||
}
|
||||
|
||||
dht::Value::Id id {0}; /// Value ID of the trust request, used for deserialization only.
|
||||
std::string service;
|
||||
std::string conversationId;
|
||||
Blob payload;
|
||||
|
||||
@@ -146,26 +146,6 @@ public:
|
||||
|
||||
std::shared_ptr<DhtRunner> getNode() const { return dht_; }
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
/**
|
||||
* Decide whether a batch of values notified to a push listener must be
|
||||
* delivered as a high (urgent) priority push notification.
|
||||
*
|
||||
* Only real-time call signaling — values whose pushType is "audioCall" or
|
||||
* "videoCall", published at high priority (priority == 0) — warrants an
|
||||
* urgent push. Every other notification (presence/connection-request
|
||||
* refreshes carrying an empty pushType, value expirations, etc.) is sent at
|
||||
* normal priority so it does not saturate the mobile platform's adaptive
|
||||
* high-priority quota; once that quota is tripped, the platform silently
|
||||
* drops genuine call pushes.
|
||||
*
|
||||
* @param values the values being notified to the listener.
|
||||
* @param expired whether this notification is for expired (removed) values.
|
||||
* @return true if the notification must be sent at high priority.
|
||||
*/
|
||||
static bool isHighPriorityPush(const std::vector<std::shared_ptr<Value>>& values, bool expired) noexcept;
|
||||
#endif // OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
private:
|
||||
class ConnectionListener;
|
||||
struct RestRouterTraitsTls;
|
||||
|
||||
+14
-8
@@ -51,11 +51,11 @@ using ConnectHandlerCb = std::function<void(const asio::error_code& ec, const as
|
||||
using ssl_socket_t = restinio::impl::tls_socket_t;
|
||||
using socket_t = asio::ip::tcp::socket;
|
||||
|
||||
struct OPENDHT_PUBLIC Url
|
||||
class OPENDHT_PUBLIC Url
|
||||
{
|
||||
public:
|
||||
Url() = default;
|
||||
Url(std::string url);
|
||||
|
||||
Url(std::string_view url);
|
||||
std::string url;
|
||||
std::string protocol {"http"};
|
||||
std::string_view user;
|
||||
@@ -149,7 +149,7 @@ public:
|
||||
using ResolverCb
|
||||
= std::function<void(const asio::error_code& ec, const std::vector<asio::ip::tcp::endpoint>& endpoints)>;
|
||||
|
||||
Resolver(asio::io_context& ctx, std::string url, std::shared_ptr<log::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<log::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx,
|
||||
std::string_view host,
|
||||
std::string_view service,
|
||||
@@ -161,6 +161,10 @@ public:
|
||||
std::vector<asio::ip::tcp::endpoint> endpoints,
|
||||
const bool ssl = false,
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx,
|
||||
const std::string& url,
|
||||
std::vector<asio::ip::tcp::endpoint> endpoints,
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
~Resolver();
|
||||
|
||||
@@ -212,19 +216,19 @@ public:
|
||||
|
||||
// resolves implicitly
|
||||
Request(asio::io_context& ctx,
|
||||
std::string url,
|
||||
const std::string& url,
|
||||
const Json::Value& json,
|
||||
OnJsonCb jsoncb,
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, std::string url, OnJsonCb jsoncb, std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb, std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
Request(asio::io_context& ctx, std::string url, std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx,
|
||||
std::string_view host,
|
||||
std::string_view service,
|
||||
const bool ssl = false,
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, std::string url, OnDoneCb onDone, std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
// user defined resolver
|
||||
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family = AF_UNSPEC);
|
||||
@@ -340,6 +344,8 @@ private:
|
||||
|
||||
dht::crypto::Identity client_identity_;
|
||||
std::shared_ptr<dht::crypto::Certificate> server_ca_;
|
||||
std::string service_;
|
||||
std::string host_;
|
||||
|
||||
unsigned int id_;
|
||||
static std::atomic_uint ids_;
|
||||
|
||||
+11
-1
@@ -28,8 +28,18 @@ install(CODE [[
|
||||
if(NOT _pip_check EQUAL 0)
|
||||
message(WARNING "Skipping Python package install: pip not available for ${Python3_EXECUTABLE}.")
|
||||
else()
|
||||
set(_pip_install_args
|
||||
install
|
||||
--no-deps
|
||||
--no-build-isolation
|
||||
--break-system-packages
|
||||
--prefix ${CMAKE_INSTALL_PREFIX})
|
||||
if(DEFINED ENV{DESTDIR} AND NOT "$ENV{DESTDIR}" STREQUAL "")
|
||||
list(APPEND _pip_install_args --root "$ENV{DESTDIR}")
|
||||
endif()
|
||||
list(APPEND _pip_install_args .)
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install --no-deps --break-system-packages .
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip ${_pip_install_args}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python
|
||||
OUTPUT_VARIABLE _pip_output
|
||||
ERROR_VARIABLE _pip_error
|
||||
|
||||
@@ -36,19 +36,4 @@ base64_decode(std::string_view str)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<unsigned char>
|
||||
base64_default_or_url_decode(std::string_view str)
|
||||
{
|
||||
std::vector<unsigned char> buffer(simdutf::maximal_binary_length_from_base64(str.data(), str.size()));
|
||||
simdutf::result r = simdutf::base64_to_binary(str.data(),
|
||||
str.size(),
|
||||
(char*) buffer.data(),
|
||||
simdutf::base64_options::base64_default_or_url);
|
||||
if (r.error) {
|
||||
throw std::invalid_argument(concat("Invalid base64 input: "sv, simdutf::error_to_string(r.error)));
|
||||
} else {
|
||||
buffer.resize(r.count);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
} // namespace dht
|
||||
+1
-8
@@ -21,12 +21,5 @@ std::string base64_encode(const std::vector<unsigned char>& str);
|
||||
* @return a base64-decoded buffer
|
||||
*/
|
||||
std::vector<unsigned char> base64_decode(std::string_view str);
|
||||
/**
|
||||
* Decode a buffer in base64 or url style base64 (including '-' '_' ).
|
||||
*
|
||||
* @param str the input buffer
|
||||
* @return a base64-decoded buffer
|
||||
*/
|
||||
std::vector<unsigned char> base64_default_or_url_decode(std::string_view str);
|
||||
|
||||
} // namespace dht
|
||||
} // namespace dht
|
||||
+16
-31
@@ -1134,25 +1134,6 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code& ec,
|
||||
pushListeners_.erase(pushListener);
|
||||
}
|
||||
|
||||
bool
|
||||
DhtProxyServer::isHighPriorityPush(const std::vector<std::shared_ptr<Value>>& values, bool expired) noexcept
|
||||
{
|
||||
// Expired-value notifications (de-registration) are never time-critical.
|
||||
if (expired)
|
||||
return false;
|
||||
// Promote to high (urgent) push priority only for real-time call signaling.
|
||||
// Background traffic — most notably connection-request refreshes, which
|
||||
// carry an empty pushType — stays at normal priority so it does not trip the
|
||||
// mobile platform's adaptive high-priority quota, which would otherwise
|
||||
// silently drop genuine call pushes once the high-priority noise ratio gets
|
||||
// too high.
|
||||
for (const auto& v : values) {
|
||||
if (v->priority == 0 and (v->pushType == "videoCall" or v->pushType == "audioCall"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DhtProxyServer::handlePushListen(const InfoHash& infoHash,
|
||||
const std::string& pushToken,
|
||||
@@ -1195,23 +1176,20 @@ DhtProxyServer::handlePushListen(const InfoHash& infoHash,
|
||||
json["exp"] = json["ids"];
|
||||
}
|
||||
|
||||
const bool highPriority = isHighPriorityPush(values, expired);
|
||||
auto minPriority = 1000u;
|
||||
for (const auto& v : values)
|
||||
minPriority = std::min(minPriority, v->priority);
|
||||
|
||||
if (logger_) {
|
||||
auto minPriority = 1000u;
|
||||
for (const auto& v : values)
|
||||
minPriority = std::min(minPriority, v->priority);
|
||||
logger_->debug("[proxy:server] [listen {}] [client {}] [session {}] [expired {}] [priority {}] [high {}] [values {}]",
|
||||
if (logger_)
|
||||
logger_->debug("[proxy:server] [listen {}] [client {}] [session {}] [expired {}] [priority {}] [values {}]",
|
||||
infoHash,
|
||||
clientId,
|
||||
sessionCtx->sessionId,
|
||||
expired,
|
||||
minPriority,
|
||||
highPriority,
|
||||
values.size());
|
||||
}
|
||||
|
||||
sendPushNotification(pushToken, std::move(json), type, highPriority, topic);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and minPriority == 0, topic);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1227,7 +1205,14 @@ DhtProxyServer::sendPushNotification(
|
||||
try {
|
||||
std::shared_ptr<http::Request> request;
|
||||
if (type == PushType::UnifiedPush) {
|
||||
request = std::make_shared<http::Request>(io_context(), token, logger_);
|
||||
http::Url tokenUrl(token);
|
||||
request = std::make_shared<http::Request>(io_context(),
|
||||
concat(tokenUrl.protocol, "://"sv, tokenUrl.host),
|
||||
tokenUrl.service,
|
||||
tokenUrl.protocol.find("https") == 0,
|
||||
logger_);
|
||||
request->set_target(tokenUrl.target);
|
||||
request->set_header_field(restinio::http_field_t::host, std::string(tokenUrl.host));
|
||||
} else {
|
||||
request = std::make_shared<http::Request>(io_context(),
|
||||
pushHostPort_.first,
|
||||
@@ -1246,8 +1231,8 @@ DhtProxyServer::sendPushNotification(
|
||||
Blob auth; ///< Auth secret
|
||||
auto delim = topicView.find('|');
|
||||
if (delim != std::string_view::npos) {
|
||||
pubKey = base64_default_or_url_decode(topicView.substr(0, delim));
|
||||
auth = base64_default_or_url_decode(topicView.substr(delim + 1));
|
||||
pubKey = base64_decode(topicView.substr(0, delim));
|
||||
auth = base64_decode(topicView.substr(delim + 1));
|
||||
}
|
||||
|
||||
request->set_header_field(restinio::http_field_t::ttl, "86400");
|
||||
|
||||
+13
-12
@@ -42,8 +42,8 @@ constexpr std::string_view ORIGIN_PROTOCOL {"//"sv};
|
||||
constexpr const char HTTP_HEADER_DELIM[] = "\r\n\r\n";
|
||||
constexpr unsigned MAX_REDIRECTS {5};
|
||||
|
||||
Url::Url(std::string url_str)
|
||||
: url(std::move(url_str))
|
||||
Url::Url(std::string_view url_str)
|
||||
: url(url_str)
|
||||
{
|
||||
std::string_view u = url;
|
||||
if (u.empty())
|
||||
@@ -830,8 +830,8 @@ Connection::timeout(const std::chrono::seconds& timeout, HandlerCb cb)
|
||||
|
||||
// Resolver
|
||||
|
||||
Resolver::Resolver(asio::io_context& ctx, std::string url, std::shared_ptr<dht::Logger> logger)
|
||||
: url_(std::move(url))
|
||||
Resolver::Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger)
|
||||
: url_(url)
|
||||
, resolver_(ctx)
|
||||
, destroyed_(std::make_shared<bool>(false))
|
||||
, logger_(logger)
|
||||
@@ -967,14 +967,14 @@ Resolver::resolve(std::string_view host, std::string_view service)
|
||||
std::atomic_uint Request::ids_ {1};
|
||||
|
||||
Request::Request(asio::io_context& ctx,
|
||||
std::string url,
|
||||
const std::string& url,
|
||||
const Json::Value& json,
|
||||
OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(std::move(logger))
|
||||
, id_(Request::ids_++)
|
||||
, ctx_(ctx)
|
||||
, resolver_(std::make_shared<Resolver>(ctx, std::move(url), logger))
|
||||
, resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
set_header_field(restinio::http_field_t::content_type, std::string(HTTP_HEADER_CONTENT_TYPE_JSON));
|
||||
@@ -997,11 +997,11 @@ Request::Request(asio::io_context& ctx,
|
||||
});
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::string url, OnJsonCb jsoncb, std::shared_ptr<dht::Logger> logger)
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(std::move(logger))
|
||||
, id_(Request::ids_++)
|
||||
, ctx_(ctx)
|
||||
, resolver_(std::make_shared<Resolver>(ctx, std::move(url), logger))
|
||||
, resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
set_header_field(restinio::http_field_t::accept, std::string(HTTP_HEADER_CONTENT_TYPE_JSON));
|
||||
@@ -1022,20 +1022,20 @@ Request::Request(asio::io_context& ctx, std::string url, OnJsonCb jsoncb, std::s
|
||||
});
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::string url, std::shared_ptr<dht::Logger> logger)
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger)
|
||||
, id_(Request::ids_++)
|
||||
, ctx_(ctx)
|
||||
, resolver_(std::make_shared<Resolver>(ctx, std::move(url), logger))
|
||||
, resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::string url, OnDoneCb onDone, std::shared_ptr<dht::Logger> logger)
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger)
|
||||
, id_(Request::ids_++)
|
||||
, ctx_(ctx)
|
||||
, resolver_(std::make_shared<Resolver>(ctx, std::move(url), logger))
|
||||
, resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
add_on_done_callback(std::move(onDone));
|
||||
@@ -1086,6 +1086,7 @@ Request::Request(asio::io_context& ctx,
|
||||
, family_(family)
|
||||
, resolver_(resolver)
|
||||
{
|
||||
set_header_field(restinio::http_field_t::host, concat(get_url().host, ":", get_url().service));
|
||||
set_target(Url(target).target);
|
||||
}
|
||||
|
||||
|
||||
@@ -327,39 +327,4 @@ DhtProxyTester::testShutdownStop()
|
||||
CPPUNIT_ASSERT_EQUAL(2 * C, callback_count.load());
|
||||
}
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
void
|
||||
DhtProxyTester::testPushNotificationPriority()
|
||||
{
|
||||
auto mkValue = [](unsigned priority, const std::string& pushType) {
|
||||
auto v = std::make_shared<dht::Value>();
|
||||
v->priority = priority;
|
||||
v->pushType = pushType;
|
||||
return v;
|
||||
};
|
||||
|
||||
// Real-time call signaling at high priority => urgent push.
|
||||
CPPUNIT_ASSERT(dht::DhtProxyServer::isHighPriorityPush({mkValue(0, "videoCall")}, false));
|
||||
CPPUNIT_ASSERT(dht::DhtProxyServer::isHighPriorityPush({mkValue(0, "audioCall")}, false));
|
||||
|
||||
// Connection-request refresh (empty pushType) is noise => normal push.
|
||||
CPPUNIT_ASSERT(!dht::DhtProxyServer::isHighPriorityPush({mkValue(0, "")}, false));
|
||||
|
||||
// Any other pushType is not a call => normal push.
|
||||
CPPUNIT_ASSERT(!dht::DhtProxyServer::isHighPriorityPush({mkValue(0, "message")}, false));
|
||||
|
||||
// Expired (de-registration) notifications are never urgent, even for calls.
|
||||
CPPUNIT_ASSERT(!dht::DhtProxyServer::isHighPriorityPush({mkValue(0, "videoCall")}, true));
|
||||
|
||||
// A call value explicitly published at normal priority stays normal.
|
||||
CPPUNIT_ASSERT(!dht::DhtProxyServer::isHighPriorityPush({mkValue(1, "videoCall")}, false));
|
||||
|
||||
// Mixed batch: a single high-priority call value is enough to make it urgent.
|
||||
CPPUNIT_ASSERT(dht::DhtProxyServer::isHighPriorityPush({mkValue(0, ""), mkValue(0, "videoCall")}, false));
|
||||
|
||||
// Empty batch => normal.
|
||||
CPPUNIT_ASSERT(!dht::DhtProxyServer::isHighPriorityPush({}, false));
|
||||
}
|
||||
#endif // OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
} // namespace test
|
||||
@@ -21,9 +21,6 @@ class DhtProxyTester : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testPutGet40KChars);
|
||||
CPPUNIT_TEST(testFuzzy);
|
||||
CPPUNIT_TEST(testShutdownStop);
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
CPPUNIT_TEST(testPushNotificationPriority);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@@ -58,15 +55,6 @@ public:
|
||||
|
||||
void testShutdownStop();
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
/**
|
||||
* The proxy must only request a high-priority push for real-time call
|
||||
* signaling (audioCall/videoCall at priority 0); everything else stays at
|
||||
* normal priority.
|
||||
*/
|
||||
void testPushNotificationPriority();
|
||||
#endif
|
||||
|
||||
private:
|
||||
dht::DhtRunner::Config clientConfig {};
|
||||
dht::DhtRunner nodePeer;
|
||||
|
||||
Reference in new issue
Block a user