diff --git a/CMakeLists.txt b/CMakeLists.txt index 6845eb7db..b26d7ec3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,7 +429,8 @@ set(TDLIB_SOURCE td/telegram/net/NetQueryStats.cpp td/telegram/net/NetStatsManager.cpp td/telegram/net/Proxy.cpp - td/telegram/net/PublicRsaKeyShared.cpp + td/telegram/net/PublicRsaKeySharedCdn.cpp + td/telegram/net/PublicRsaKeySharedMain.cpp td/telegram/net/PublicRsaKeyWatchdog.cpp td/telegram/net/Session.cpp td/telegram/net/SessionMultiProxy.cpp @@ -735,7 +736,8 @@ set(TDLIB_SOURCE td/telegram/net/NetStatsManager.h td/telegram/net/NetType.h td/telegram/net/Proxy.h - td/telegram/net/PublicRsaKeyShared.h + td/telegram/net/PublicRsaKeySharedCdn.h + td/telegram/net/PublicRsaKeySharedMain.h td/telegram/net/PublicRsaKeyWatchdog.h td/telegram/net/Session.h td/telegram/net/SessionProxy.h diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 7fad9ec45..42b65d2c9 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -21,7 +21,7 @@ #include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/net/NetType.h" -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" #include "td/telegram/net/Session.h" #include "td/telegram/OptionManager.h" #include "td/telegram/Premium.h" @@ -493,7 +493,7 @@ static ActorOwn<> get_full_config(DcOption option, Promise public_rsa_key_ = - std::make_shared(DcId::empty(), G()->is_test_dc()); + std::make_shared(G()->is_test_dc()); std::vector> auth_key_listeners_; void notify() { @@ -1497,7 +1497,8 @@ void ConfigManager::process_app_config(tl_object_ptr &c key == "getfile_experimental_params" || key == "message_animated_emoji_max" || key == "stickers_emoji_cache_time" || key == "stories_export_nopublic_link" || key == "test" || key == "upload_max_fileparts_default" || key == "upload_max_fileparts_premium" || - key == "wallet_blockchain_name" || key == "wallet_config" || key == "wallet_enabled" || key == "channel_color_level_min") { + key == "wallet_blockchain_name" || key == "wallet_config" || key == "wallet_enabled" || + key == "channel_color_level_min") { continue; } if (key == "ignore_restriction_reasons") { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index f98606b01..60922e021 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -100,7 +100,7 @@ #include "td/telegram/net/NetStatsManager.h" #include "td/telegram/net/NetType.h" #include "td/telegram/net/Proxy.h" -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" #include "td/telegram/net/TempAuthKeyWatchdog.h" #include "td/telegram/NotificationGroupId.h" #include "td/telegram/NotificationId.h" @@ -529,11 +529,11 @@ class TestProxyRequest final : public RequestOnceActor { return nullptr; } mtproto::PublicRsaKeyInterface *get_public_rsa_key_interface() final { - return &public_rsa_key; + return &public_rsa_key_; } private: - PublicRsaKeyShared public_rsa_key{DcId::empty(), false}; + PublicRsaKeySharedMain public_rsa_key_{false}; }; auto handshake = make_unique(dc_id_, 3600); auto data = r_data.move_as_ok(); diff --git a/td/telegram/net/NetQueryDispatcher.cpp b/td/telegram/net/NetQueryDispatcher.cpp index 7bb5f532b..5bcbb3c21 100644 --- a/td/telegram/net/NetQueryDispatcher.cpp +++ b/td/telegram/net/NetQueryDispatcher.cpp @@ -11,7 +11,8 @@ #include "td/telegram/net/DcAuthManager.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDelayer.h" -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedCdn.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" #include "td/telegram/net/PublicRsaKeyWatchdog.h" #include "td/telegram/net/SessionMultiProxy.h" #include "td/telegram/SequenceDispatcher.h" @@ -150,13 +151,14 @@ Status NetQueryDispatcher::wait_dc_init(DcId dc_id, bool force) { } // init dc dc.id_ = dc_id; - decltype(common_public_rsa_key_) public_rsa_key; + std::shared_ptr public_rsa_key; bool is_cdn = false; if (dc_id.is_internal()) { public_rsa_key = common_public_rsa_key_; } else { - public_rsa_key = std::make_shared(dc_id, G()->is_test_dc()); - send_closure_later(public_rsa_key_watchdog_, &PublicRsaKeyWatchdog::add_public_rsa_key, public_rsa_key); + auto public_rsa_key_cdn = std::make_shared(dc_id); + send_closure_later(public_rsa_key_watchdog_, &PublicRsaKeyWatchdog::add_public_rsa_key, public_rsa_key_cdn); + public_rsa_key = public_rsa_key_cdn; is_cdn = true; } auto auth_data = AuthDataShared::create(dc_id, std::move(public_rsa_key), td_guard_); @@ -299,7 +301,7 @@ NetQueryDispatcher::NetQueryDispatcher(const std::function()> &cre LOG(INFO) << tag("main_dc_id", main_dc_id_.load(std::memory_order_relaxed)); delayer_ = create_actor("NetQueryDelayer", create_reference()); dc_auth_manager_ = create_actor("DcAuthManager", create_reference()); - common_public_rsa_key_ = std::make_shared(DcId::empty(), G()->is_test_dc()); + common_public_rsa_key_ = std::make_shared(G()->is_test_dc()); public_rsa_key_watchdog_ = create_actor("PublicRsaKeyWatchdog", create_reference()); sequence_dispatcher_ = MultiSequenceDispatcher::create("MultiSequenceDispatcher"); diff --git a/td/telegram/net/NetQueryDispatcher.h b/td/telegram/net/NetQueryDispatcher.h index 24361f8d6..3f72df969 100644 --- a/td/telegram/net/NetQueryDispatcher.h +++ b/td/telegram/net/NetQueryDispatcher.h @@ -27,7 +27,7 @@ namespace td { class DcAuthManager; class MultiSequenceDispatcher; class NetQueryDelayer; -class PublicRsaKeyShared; +class PublicRsaKeySharedMain; class PublicRsaKeyWatchdog; class SessionMultiProxy; @@ -79,7 +79,7 @@ class NetQueryDispatcher { #else std::atomic main_dc_id_{1}; #endif - std::shared_ptr common_public_rsa_key_; + std::shared_ptr common_public_rsa_key_; ActorOwn public_rsa_key_watchdog_; std::mutex main_dc_id_mutex_; std::shared_ptr td_guard_; diff --git a/td/telegram/net/PublicRsaKeySharedCdn.cpp b/td/telegram/net/PublicRsaKeySharedCdn.cpp new file mode 100644 index 000000000..fbd74f565 --- /dev/null +++ b/td/telegram/net/PublicRsaKeySharedCdn.cpp @@ -0,0 +1,76 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/net/PublicRsaKeySharedCdn.h" + +#include "td/utils/algorithm.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" + +#include + +namespace td { + +PublicRsaKeySharedCdn::PublicRsaKeySharedCdn(DcId dc_id) : dc_id_(dc_id) { + CHECK(!dc_id_.is_empty()); + CHECK(!dc_id_.is_internal()); +} + +void PublicRsaKeySharedCdn::add_rsa(mtproto::RSA rsa) { + auto lock = rw_mutex_.lock_write(); + auto fingerprint = rsa.get_fingerprint(); + if (get_rsa_key_unsafe(fingerprint) != nullptr) { + return; + } + keys_.push_back(RsaKey{std::move(rsa), fingerprint}); +} + +Result PublicRsaKeySharedCdn::get_rsa_key(const vector &fingerprints) { + auto lock = rw_mutex_.lock_read(); + for (auto fingerprint : fingerprints) { + auto *rsa_key = get_rsa_key_unsafe(fingerprint); + if (rsa_key != nullptr) { + return RsaKey{rsa_key->rsa.clone(), fingerprint}; + } + } + return Status::Error(PSLICE() << "Unknown fingerprints " << format::as_array(fingerprints)); +} + +void PublicRsaKeySharedCdn::drop_keys() { + LOG(INFO) << "Drop " << keys_.size() << " keys for " << dc_id_; + auto lock = rw_mutex_.lock_write(); + keys_.clear(); + notify(); +} + +bool PublicRsaKeySharedCdn::has_keys() { + auto lock = rw_mutex_.lock_read(); + return !keys_.empty(); +} + +void PublicRsaKeySharedCdn::add_listener(unique_ptr listener) { + if (listener->notify()) { + auto lock = rw_mutex_.lock_write(); + listeners_.push_back(std::move(listener)); + } +} + +mtproto::PublicRsaKeyInterface::RsaKey *PublicRsaKeySharedCdn::get_rsa_key_unsafe(int64 fingerprint) { + auto it = std::find_if(keys_.begin(), keys_.end(), + [fingerprint](const auto &value) { return value.fingerprint == fingerprint; }); + if (it == keys_.end()) { + return nullptr; + } + return &*it; +} + +void PublicRsaKeySharedCdn::notify() { + td::remove_if(listeners_, [&](auto &listener) { return !listener->notify(); }); +} + +} // namespace td diff --git a/td/telegram/net/PublicRsaKeyShared.h b/td/telegram/net/PublicRsaKeySharedCdn.h similarity index 85% rename from td/telegram/net/PublicRsaKeyShared.h rename to td/telegram/net/PublicRsaKeySharedCdn.h index c4811a8e0..a4157efc4 100644 --- a/td/telegram/net/PublicRsaKeyShared.h +++ b/td/telegram/net/PublicRsaKeySharedCdn.h @@ -16,9 +16,9 @@ namespace td { -class PublicRsaKeyShared final : public mtproto::PublicRsaKeyInterface { +class PublicRsaKeySharedCdn final : public mtproto::PublicRsaKeyInterface { public: - PublicRsaKeyShared(DcId dc_id, bool is_test); + explicit PublicRsaKeySharedCdn(DcId dc_id); class Listener { public: @@ -32,8 +32,11 @@ class PublicRsaKeyShared final : public mtproto::PublicRsaKeyInterface { }; void add_rsa(mtproto::RSA rsa); + Result get_rsa_key(const vector &fingerprints) final; + void drop_keys() final; + bool has_keys(); void add_listener(unique_ptr listener); @@ -44,8 +47,8 @@ class PublicRsaKeyShared final : public mtproto::PublicRsaKeyInterface { private: DcId dc_id_; - std::vector keys_; - std::vector> listeners_; + vector keys_; + vector> listeners_; RwMutex rw_mutex_; RsaKey *get_rsa_key_unsafe(int64 fingerprint); diff --git a/td/telegram/net/PublicRsaKeyShared.cpp b/td/telegram/net/PublicRsaKeySharedMain.cpp similarity index 61% rename from td/telegram/net/PublicRsaKeyShared.cpp rename to td/telegram/net/PublicRsaKeySharedMain.cpp index 6ec405c51..5f25a1aa5 100644 --- a/td/telegram/net/PublicRsaKeyShared.cpp +++ b/td/telegram/net/PublicRsaKeySharedMain.cpp @@ -4,29 +4,29 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" -#include "td/utils/algorithm.h" #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" -#include "td/utils/Status.h" #include namespace td { -PublicRsaKeyShared::PublicRsaKeyShared(DcId dc_id, bool is_test) : dc_id_(dc_id) { - if (!dc_id_.is_empty()) { - return; - } +PublicRsaKeySharedMain::PublicRsaKeySharedMain(bool is_test) { auto add_pem = [this](CSlice pem) { auto r_rsa = mtproto::RSA::from_pem_public_key(pem); LOG_CHECK(r_rsa.is_ok()) << r_rsa.error() << " " << pem; if (r_rsa.is_ok()) { - add_rsa(r_rsa.move_as_ok()); + auto rsa = r_rsa.move_as_ok(); + auto fingerprint = rsa.get_fingerprint(); + if (get_rsa_key_unsafe(fingerprint) != nullptr) { + return; + } + keys_.push_back(RsaKey{std::move(rsa), fingerprint}); } }; @@ -54,19 +54,9 @@ PublicRsaKeyShared::PublicRsaKeyShared(DcId dc_id, bool is_test) : dc_id_(dc_id) "-----END RSA PUBLIC KEY-----"); } -void PublicRsaKeyShared::add_rsa(mtproto::RSA rsa) { - auto lock = rw_mutex_.lock_write(); - auto fingerprint = rsa.get_fingerprint(); - if (get_rsa_key_unsafe(fingerprint) != nullptr) { - return; - } - keys_.push_back(RsaKey{std::move(rsa), fingerprint}); -} - -Result PublicRsaKeyShared::get_rsa_key(const vector &fingerprints) { - auto lock = rw_mutex_.lock_read(); +Result PublicRsaKeySharedMain::get_rsa_key(const vector &fingerprints) { for (auto fingerprint : fingerprints) { - auto *rsa_key = get_rsa_key_unsafe(fingerprint); + const auto *rsa_key = get_rsa_key_unsafe(fingerprint); if (rsa_key != nullptr) { return RsaKey{rsa_key->rsa.clone(), fingerprint}; } @@ -74,30 +64,11 @@ Result PublicRsaKeyShared::get_rsa_key(c return Status::Error(PSLICE() << "Unknown fingerprints " << format::as_array(fingerprints)); } -void PublicRsaKeyShared::drop_keys() { - if (dc_id_.is_empty()) { - // not CDN - return; - } - auto lock = rw_mutex_.lock_write(); - LOG(INFO) << "Drop " << keys_.size() << " keys for " << dc_id_; - keys_.clear(); - notify(); +void PublicRsaKeySharedMain::drop_keys() { + // nothing to do } -bool PublicRsaKeyShared::has_keys() { - auto lock = rw_mutex_.lock_read(); - return !keys_.empty(); -} - -void PublicRsaKeyShared::add_listener(unique_ptr listener) { - if (listener->notify()) { - auto lock = rw_mutex_.lock_write(); - listeners_.push_back(std::move(listener)); - } -} - -mtproto::PublicRsaKeyInterface::RsaKey *PublicRsaKeyShared::get_rsa_key_unsafe(int64 fingerprint) { +const mtproto::PublicRsaKeyInterface::RsaKey *PublicRsaKeySharedMain::get_rsa_key_unsafe(int64 fingerprint) const { auto it = std::find_if(keys_.begin(), keys_.end(), [fingerprint](const auto &value) { return value.fingerprint == fingerprint; }); if (it == keys_.end()) { @@ -106,8 +77,4 @@ mtproto::PublicRsaKeyInterface::RsaKey *PublicRsaKeyShared::get_rsa_key_unsafe(i return &*it; } -void PublicRsaKeyShared::notify() { - td::remove_if(listeners_, [&](auto &listener) { return !listener->notify(); }); -} - } // namespace td diff --git a/td/telegram/net/PublicRsaKeySharedMain.h b/td/telegram/net/PublicRsaKeySharedMain.h new file mode 100644 index 000000000..5b7adcc88 --- /dev/null +++ b/td/telegram/net/PublicRsaKeySharedMain.h @@ -0,0 +1,30 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/mtproto/RSA.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class PublicRsaKeySharedMain final : public mtproto::PublicRsaKeyInterface { + public: + explicit PublicRsaKeySharedMain(bool is_test); + + Result get_rsa_key(const vector &fingerprints) final; + + void drop_keys() final; + + private: + vector keys_; + + const RsaKey *get_rsa_key_unsafe(int64 fingerprint) const; +}; + +} // namespace td diff --git a/td/telegram/net/PublicRsaKeyWatchdog.cpp b/td/telegram/net/PublicRsaKeyWatchdog.cpp index 2cf94c739..cc351182f 100644 --- a/td/telegram/net/PublicRsaKeyWatchdog.cpp +++ b/td/telegram/net/PublicRsaKeyWatchdog.cpp @@ -22,8 +22,8 @@ namespace td { PublicRsaKeyWatchdog::PublicRsaKeyWatchdog(ActorShared<> parent) : parent_(std::move(parent)) { } -void PublicRsaKeyWatchdog::add_public_rsa_key(std::shared_ptr key) { - class Listener final : public PublicRsaKeyShared::Listener { +void PublicRsaKeyWatchdog::add_public_rsa_key(std::shared_ptr key) { + class Listener final : public PublicRsaKeySharedCdn::Listener { public: explicit Listener(ActorId parent) : parent_(std::move(parent)) { } @@ -119,7 +119,7 @@ void PublicRsaKeyWatchdog::sync(BufferSlice cdn_config_serialized) { } } -void PublicRsaKeyWatchdog::sync_key(std::shared_ptr &key) { +void PublicRsaKeyWatchdog::sync_key(std::shared_ptr &key) { if (!cdn_config_) { return; } diff --git a/td/telegram/net/PublicRsaKeyWatchdog.h b/td/telegram/net/PublicRsaKeyWatchdog.h index 227da7dcc..c64b3191b 100644 --- a/td/telegram/net/PublicRsaKeyWatchdog.h +++ b/td/telegram/net/PublicRsaKeyWatchdog.h @@ -9,7 +9,7 @@ #include "td/telegram/net/NetActor.h" #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/net/NetQueryDispatcher.h" -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedCdn.h" #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" @@ -26,11 +26,11 @@ class PublicRsaKeyWatchdog final : public NetActor { public: explicit PublicRsaKeyWatchdog(ActorShared<> parent); - void add_public_rsa_key(std::shared_ptr key); + void add_public_rsa_key(std::shared_ptr key); private: ActorShared<> parent_; - vector> keys_; + vector> keys_; tl_object_ptr cdn_config_; FloodControlStrict flood_control_; bool has_query_{false}; @@ -41,7 +41,7 @@ class PublicRsaKeyWatchdog final : public NetActor { void on_result(NetQueryPtr net_query) final; void sync(BufferSlice cdn_config_serialized); - void sync_key(std::shared_ptr &key); + void sync_key(std::shared_ptr &key); }; } // namespace td diff --git a/test/mtproto.cpp b/test/mtproto.cpp index e7db14580..342c9b3cc 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -6,7 +6,7 @@ // #include "td/telegram/ConfigManager.h" #include "td/telegram/net/DcId.h" -#include "td/telegram/net/PublicRsaKeyShared.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" #include "td/telegram/net/Session.h" #include "td/telegram/NotificationManager.h" @@ -304,7 +304,7 @@ class HandshakeContext final : public td::mtproto::AuthKeyHandshakeContext { } private: - td::PublicRsaKeyShared public_rsa_key{td::DcId::empty(), true}; + td::PublicRsaKeySharedMain public_rsa_key{true}; }; class HandshakeTestActor final : public td::Actor {