Route push notifications to Huawei devices, which have no Google Play
Services and therefore cannot receive FCM. gorush, already used as the
push relay, supports HMS natively as platform 3.
HMS takes its payload as a serialized JSON string in "huawei_data" and
carries its own ttl/priority fields, so it needs its own branch rather
than the generic "data" object used for FCM and APNs.
The enum value is appended last: MSGPACK_ADD_ENUM serializes it as an
integer, so reordering would break compatibility with deployed proxies.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The DHT listen callback of a push subscription kept the push type and
topic of the request that created it. Refreshing the subscription
with another platform updated the listener, but values kept being
pushed to the first platform: an Android device that once subscribed
without platform was pushed as an iOS device forever (BadDeviceToken)
and never received values such as connection requests.
Keep the push type and topic in the session context shared with the
callback, and update them on each subscription refresh and when the
state is restored.
Co-authored-by: Copilot (Claude Opus 5.5) <223556219+Copilot@users.noreply.github.com>
~DhtProxyServer destroyed requests_ whose ~http::Request notifies DONE;
the handler registered by sendPushNotification then erased from the map
being destroyed, corrupting the heap (double free under ASan) whenever a
push request was still pending, e.g. an unreachable push server. Detach
the state-change callbacks and release the requests before the members
are destroyed.
Track subscribe/permanent-put expiration with std::chrono::system_clock
(wall clock) instead of steady_clock in both the proxy client and server,
so persisted expirations survive restarts and map directly to epoch time.
- DhtProxyServer::clock is now system_clock; expireTimer/expireNotifyTimer
use asio::system_timer.
- DhtProxyClient::refreshSubscriberTimer uses asio::system_timer and
system_clock::now() for subscriber refresh.
Because there is multiple unifiedpush endpoint (ntfy.sh is one),
we should not pass it as an option to dhtnode, but use the one
provided by the user in the token (from unified push library).
Make the proxy able to support the UnifiedPush platform, so that
applications using the proxy server can use any UnifiedPush provider.
Documentation: https://unifiedpush.org/
How to test:
+ Install a UnifiedPush provider on a device (e.g. https://ntfy.sh)
+ Run dhtnode with a proxyserver and --unifiedpush https://ntfy.sh
+ Subscribe to a random topic on ntfy (e.g. "dhtproxytest")
+ Subscribe to a hash on the DHT:
curl -X SUBSCRIBE http://my.dht.proxy:8000/key/foo \
-d '{"key":"dhtproxytest", "platform":"unifiedpush"}'
+ Send data on the subscribed hash
Note: the topic should be completely random.
when searching for a value to put, the proxy server returned
a json with value->id = 0, causing the client to not refreshing
correctly the values later (when timeout-ing, the value to refresh
is not found).
When a second permanent put request was received, we didn't call
async_wait after changing the expiration, causing push to not be
sent the second day and presence to expire on some devices after
~3 days.
If the android device is offline during more than 10 minutes, it
can misses push notifications and cause an incorrect state with
values not expired even if the re-subscribe is correct.