diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp | 134 |
1 files changed, 84 insertions, 50 deletions
diff --git a/protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp index dd3776a449..23db9130e7 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/net/DcAuthManager.cpp @@ -1,23 +1,21 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 // // 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/DcAuthManager.h" -#include "td/actor/actor.h" - -#include "td/telegram/ConfigShared.h" #include "td/telegram/Global.h" #include "td/telegram/net/AuthDataShared.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UniqueId.h" -#include "td/telegram/telegram_api.h" +#include "td/actor/actor.h" -#include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/misc.h" @@ -26,25 +24,33 @@ namespace td { +int VERBOSITY_NAME(dc) = VERBOSITY_NAME(DEBUG) + 2; + DcAuthManager::DcAuthManager(ActorShared<> parent) { parent_ = std::move(parent); auto s_main_dc_id = G()->td_db()->get_binlog_pmc()->get("main_dc_id"); if (!s_main_dc_id.empty()) { - main_dc_id_ = DcId::internal(to_integer<int32>(s_main_dc_id)); + auto main_dc_id = to_integer<int32>(s_main_dc_id); + if (DcId::is_valid(main_dc_id)) { + main_dc_id_ = DcId::internal(main_dc_id); + VLOG(dc) << "Init main DcId to " << main_dc_id_; + } else { + LOG(ERROR) << "Receive invalid main DcId " << main_dc_id; + } } } void DcAuthManager::add_dc(std::shared_ptr<AuthDataShared> auth_data) { VLOG(dc) << "Register " << auth_data->dc_id(); - class Listener : public AuthDataShared::Listener { + class Listener final : public AuthDataShared::Listener { public: explicit Listener(ActorShared<DcAuthManager> dc_manager) : dc_manager_(std::move(dc_manager)) { } - bool notify() override { + bool notify() final { if (!dc_manager_.is_alive()) { return false; } - send_closure(dc_manager_, &DcAuthManager::update_auth_state); + send_closure(dc_manager_, &DcAuthManager::update_auth_key_state); return true; } @@ -56,19 +62,20 @@ void DcAuthManager::add_dc(std::shared_ptr<AuthDataShared> auth_data) { info.dc_id = auth_data->dc_id(); CHECK(info.dc_id.is_exact()); info.shared_auth_data = std::move(auth_data); - auto state_was_auth = info.shared_auth_data->get_auth_state(); - info.auth_state = state_was_auth.first; - was_auth_ |= state_was_auth.second; + info.auth_key_state = info.shared_auth_data->get_auth_key_state(); + VLOG(dc) << "Add " << info.dc_id << " with auth key state " << info.auth_key_state; if (!main_dc_id_.is_exact()) { main_dc_id_ = info.dc_id; + VLOG(dc) << "Set main DcId to " << main_dc_id_; } - info.shared_auth_data->add_auth_key_listener(std::make_unique<Listener>(actor_shared(this, info.dc_id.get_raw_id()))); + info.shared_auth_data->add_auth_key_listener(make_unique<Listener>(actor_shared(this, info.dc_id.get_raw_id()))); dcs_.emplace_back(std::move(info)); loop(); } void DcAuthManager::update_main_dc(DcId new_main_dc_id) { main_dc_id_ = new_main_dc_id; + VLOG(dc) << "Update main DcId to " << main_dc_id_; loop(); } @@ -85,20 +92,17 @@ DcAuthManager::DcInfo *DcAuthManager::find_dc(int32 dc_id) { return &*it; } -void DcAuthManager::update_auth_state() { - int32 dc_id = narrow_cast<int32>(get_link_token()); +void DcAuthManager::update_auth_key_state() { + auto dc_id = narrow_cast<int32>(get_link_token()); auto &dc = get_dc(dc_id); - auto state_was_auth = dc.shared_auth_data->get_auth_state(); - VLOG(dc) << "Update dc auth state " << tag("dc_id", dc_id) << tag("old_auth_state", dc.auth_state) - << tag("new_auth_state", state_was_auth.first); - dc.auth_state = state_was_auth.first; - was_auth_ |= state_was_auth.second; + dc.auth_key_state = dc.shared_auth_data->get_auth_key_state(); + VLOG(dc) << "Update " << dc_id << " auth key state from " << dc.auth_key_state << " to " << dc.auth_key_state; loop(); } void DcAuthManager::on_result(NetQueryPtr result) { - int32 dc_id = narrow_cast<int32>(get_link_token()); + auto dc_id = narrow_cast<int32>(get_link_token()); auto &dc = get_dc(dc_id); CHECK(dc.wait_id == result->id()); dc.wait_id = std::numeric_limits<decltype(dc.wait_id)>::max(); @@ -109,14 +113,15 @@ void DcAuthManager::on_result(NetQueryPtr result) { dc.state = DcInfo::State::Export; break; } - auto result_auth_exported = fetch_result<telegram_api::auth_exportAuthorization>(result->ok()); - if (result_auth_exported.is_error()) { - LOG(WARNING) << "Failed to parse result to auth_exportAuthorization: " << result_auth_exported.error(); + auto r_result_auth_exported = fetch_result<telegram_api::auth_exportAuthorization>(result->ok()); + if (r_result_auth_exported.is_error()) { + LOG(WARNING) << "Failed to parse result to auth_exportAuthorization: " << r_result_auth_exported.error(); dc.state = DcInfo::State::Export; break; } - dc.export_id = result_auth_exported.ok()->id_; - dc.export_bytes = std::move(result_auth_exported.ok()->bytes_); + auto result_auth_exported = r_result_auth_exported.move_as_ok(); + dc.export_id = result_auth_exported->id_; + dc.export_bytes = std::move(result_auth_exported->bytes_); break; } case DcInfo::State::BeforeOk: { @@ -142,25 +147,28 @@ void DcAuthManager::on_result(NetQueryPtr result) { } void DcAuthManager::dc_loop(DcInfo &dc) { - VLOG(dc) << "dc_loop " << dc.dc_id << " " << dc.auth_state; - if (dc.auth_state == AuthState::OK) { + VLOG(dc) << "In dc_loop: " << dc.dc_id << " " << dc.auth_key_state; + if (dc.auth_key_state == AuthKeyState::OK) { return; } + if (dc.state == DcInfo::State::Ok) { + LOG(WARNING) << "Lost key in " << dc.dc_id << ", restart dc_loop"; + dc.state = DcInfo::State::Waiting; + } CHECK(dc.shared_auth_data); switch (dc.state) { case DcInfo::State::Waiting: { // wait for timeout - // break; + // break; } case DcInfo::State::Export: { // send auth.exportAuthorization to auth_dc VLOG(dc) << "Send exportAuthorization to " << dc.dc_id; auto id = UniqueId::next(); - G()->net_query_dispatcher().dispatch_with_callback( - G()->net_query_creator().create( - id, create_storer(telegram_api::auth_exportAuthorization(dc.dc_id.get_raw_id())), DcId::main(), - NetQuery::Type::Common, NetQuery::AuthFlag::On, NetQuery::GzipFlag::On, 60 * 60 * 24), - actor_shared(this, dc.dc_id.get_raw_id())); + auto query = G()->net_query_creator().create(id, telegram_api::auth_exportAuthorization(dc.dc_id.get_raw_id()), + {}, DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::On); + query->total_timeout_limit_ = 60 * 60 * 24; + G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, dc.dc_id.get_raw_id())); dc.wait_id = id; dc.export_id = -1; dc.state = DcInfo::State::Import; @@ -173,21 +181,41 @@ void DcAuthManager::dc_loop(DcInfo &dc) { } uint64 id = UniqueId::next(); VLOG(dc) << "Send importAuthorization to " << dc.dc_id; - G()->net_query_dispatcher().dispatch_with_callback( - G()->net_query_creator().create( - id, create_storer(telegram_api::auth_importAuthorization(dc.export_id, std::move(dc.export_bytes))), - dc.dc_id, NetQuery::Type::Common, NetQuery::AuthFlag::Off, NetQuery::GzipFlag::On, 60 * 60 * 24), - actor_shared(this, dc.dc_id.get_raw_id())); + auto query = G()->net_query_creator().create( + id, telegram_api::auth_importAuthorization(dc.export_id, std::move(dc.export_bytes)), {}, dc.dc_id, + NetQuery::Type::Common, NetQuery::AuthFlag::Off); + query->total_timeout_limit_ = 60 * 60 * 24; + G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, dc.dc_id.get_raw_id())); dc.wait_id = id; dc.state = DcInfo::State::BeforeOk; break; } - case DcInfo::State::BeforeOk: { + case DcInfo::State::BeforeOk: break; - } - case DcInfo::State::Ok: { + case DcInfo::State::Ok: break; - } + } +} + +void DcAuthManager::destroy(Promise<> promise) { + destroy_promise_ = std::move(promise); + loop(); +} + +void DcAuthManager::destroy_loop() { + if (!destroy_promise_) { + return; + } + bool is_ready{true}; + for (auto &dc : dcs_) { + is_ready &= dc.auth_key_state == AuthKeyState::Empty; + } + + if (is_ready) { + VLOG(dc) << "Destroy auth keys loop is ready, all keys are destroyed"; + destroy_promise_.set_value(Unit()); + } else { + VLOG(dc) << "DC is not ready for destroying auth key"; } } @@ -196,22 +224,28 @@ void DcAuthManager::loop() { VLOG(dc) << "Skip loop because close_flag"; return; } + destroy_loop(); if (!main_dc_id_.is_exact()) { VLOG(dc) << "Skip loop because main_dc_id is unknown"; return; } auto main_dc = find_dc(main_dc_id_.get_raw_id()); - if (!main_dc || main_dc->auth_state != AuthState::OK) { - if (was_auth_) { - G()->shared_config().set_option_boolean("auth", false); + if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { + if (main_dc && need_check_authorization_is_ok_) { + G()->log_out("Authorization check failed in DcAuthManager"); } - VLOG(dc) << "Skip loop because auth state of main dc " << main_dc_id_.get_raw_id() << " is " - << (main_dc != nullptr ? (PSTRING() << main_dc->auth_state) : "unknown"); - + VLOG(dc) << "Skip loop, because main DC is " << main_dc_id_ << ", main auth key state is " + << (main_dc != nullptr ? main_dc->auth_key_state : AuthKeyState::Empty); return; } + need_check_authorization_is_ok_ = false; for (auto &dc : dcs_) { dc_loop(dc); } } + +void DcAuthManager::check_authorization_is_ok() { + need_check_authorization_is_ok_ = true; +} + } // namespace td |