diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index a766bb8c1..f17d38a2e 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -177,7 +177,7 @@ ActorOwn<> get_simple_config_google_dns(Promise promise, bool is_t #endif } -ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { +ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise promise) { class SessionCallback : public Session::Callback { public: SessionCallback(ActorShared<> parent, IPAddress address) @@ -190,7 +190,7 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { void request_raw_connection(Promise> promise) final { request_raw_connection_cnt_++; VLOG(config_recoverer) << "Request full config from " << address_ << ", try = " << request_raw_connection_cnt_; - if (request_raw_connection_cnt_ <= 1) { + if (request_raw_connection_cnt_ <= 2) { send_closure(G()->connection_creator(), &ConnectionCreator::request_raw_connection_by_ip, address_, std::move(promise)); } else { @@ -211,14 +211,22 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { class SimpleAuthData : public AuthDataShared { public: + explicit SimpleAuthData(DcId dc_id) : dc_id_(dc_id) { + } DcId dc_id() const override { - return DcId::empty(); + return dc_id_; } const std::shared_ptr &public_rsa_key() override { return public_rsa_key_; } mtproto::AuthKey get_auth_key() override { - return auth_key_; + string dc_key = G()->td_db()->get_binlog_pmc()->get(auth_key_key()); + + mtproto::AuthKey res; + if (!dc_key.empty()) { + unserialize(res, dc_key).ensure(); + } + return res; } std::pair get_auth_state() override { auto auth_key = get_auth_key(); @@ -226,16 +234,16 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { return std::make_pair(state, auth_key.was_auth_flag()); } void set_auth_key(const mtproto::AuthKey &auth_key) override { - auth_key_ = auth_key; + G()->td_db()->get_binlog_pmc()->set(auth_key_key(), serialize(auth_key)); + + //notify(); } void update_server_time_difference(double diff) override { - if (!has_server_time_difference_ || server_time_difference_ < diff) { - has_server_time_difference_ = true; - server_time_difference_ = diff; - } + G()->update_server_time_difference(diff); } double get_server_time_difference() override { - return server_time_difference_; + return G()->get_server_time_difference(); + //return server_time_difference_; } void add_auth_key_listener(unique_ptr listener) override { if (listener->notify()) { @@ -244,41 +252,52 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { } void set_future_salts(const std::vector &future_salts) override { - future_salts_ = future_salts; + G()->td_db()->get_binlog_pmc()->set(future_salts_key(), serialize(future_salts)); } + std::vector get_future_salts() override { - return future_salts_; + string future_salts = G()->td_db()->get_binlog_pmc()->get(future_salts_key()); + std::vector res; + if (!future_salts.empty()) { + unserialize(res, future_salts).ensure(); + } + return res; } private: + DcId dc_id_; std::shared_ptr public_rsa_key_ = std::make_shared(DcId::empty()); - mtproto::AuthKey auth_key_; bool has_server_time_difference_ = false; double server_time_difference_ = 0; - std::vector future_salts_; - std::vector> auth_key_listeners_; void notify() { auto it = std::remove_if(auth_key_listeners_.begin(), auth_key_listeners_.end(), [&](auto &listener) { return !listener->notify(); }); auth_key_listeners_.erase(it, auth_key_listeners_.end()); } + + string auth_key_key() { + return PSTRING() << "config_recovery_auth" << dc_id().get_raw_id(); + } + string future_salts_key() { + return PSTRING() << "config_recovery_salt" << dc_id().get_raw_id(); + } }; class GetConfigActor : public NetQueryCallback { public: - GetConfigActor(IPAddress ip_address, Promise promise) - : ip_address_(std::move(ip_address)), promise_(std::move(promise)) { + GetConfigActor(DcId dc_id, IPAddress ip_address, Promise promise) + : dc_id_(dc_id), ip_address_(std::move(ip_address)), promise_(std::move(promise)) { } private: void start_up() override { auto session_callback = std::make_unique(actor_shared(this, 1), std::move(ip_address_)); - auto auth_data = std::make_shared(); + auto auth_data = std::make_shared(dc_id_); session_ = create_actor("ConfigSession", std::move(session_callback), std::move(auth_data), - false /*is_main*/, false /*use_pfs*/, true /*is_cdn*/, mtproto::AuthKey()); + false /*is_main*/, true /*use_pfs*/, false /*is_cdn*/, mtproto::AuthKey()); auto query = G()->net_query_creator().create(create_storer(telegram_api::help_getConfig()), DcId::empty(), NetQuery::Type::Common, NetQuery::AuthFlag::Off, NetQuery::GzipFlag::On, 60 * 60 * 24); @@ -293,7 +312,9 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { } void hangup_shared() override { if (get_link_token() == 1) { - promise_.set_error(Status::Error("Failed")); + if (promise_) { + promise_.set_error(Status::Error("Failed")); + } stop(); } } @@ -302,15 +323,16 @@ ActorOwn<> get_full_config(IPAddress ip_address, Promise promise) { } void timeout_expired() override { promise_.set_error(Status::Error("Timeout expired")); - stop(); + session_.reset(); } + DcId dc_id_; IPAddress ip_address_; ActorOwn session_; Promise promise_; }; - return ActorOwn<>(create_actor("GetConfigActor", std::move(ip_address), std::move(promise))); + return ActorOwn<>(create_actor("GetConfigActor", dc_id, std::move(ip_address), std::move(promise))); } class ConfigRecoverer : public Actor { @@ -508,11 +530,11 @@ class ConfigRecoverer : public Actor { if (need_full_config) { ref_cnt_++; VLOG(config_recoverer) << "ASK FULL CONFIG"; - full_config_query_ = - get_full_config(dc_options_.dc_options[dc_options_i_].get_ip_address(), - PromiseCreator::lambda([actor_id = actor_shared(this)](Result r_full_config) { - send_closure(actor_id, &ConfigRecoverer::on_full_config, std::move(r_full_config), false); - })); + full_config_query_ = get_full_config( + dc_options_.dc_options[dc_options_i_].get_dc_id(), dc_options_.dc_options[dc_options_i_].get_ip_address(), + PromiseCreator::lambda([actor_id = actor_shared(this)](Result r_full_config) { + send_closure(actor_id, &ConfigRecoverer::on_full_config, std::move(r_full_config), false); + })); dc_options_i_ = (dc_options_i_ + 1) % dc_options_.dc_options.size(); } diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index 3f2c7f05c..72fc4847d 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -32,7 +32,7 @@ ActorOwn<> get_simple_config_google_dns(Promise promise, bool is_t using FullConfig = tl_object_ptr; -ActorOwn<> get_full_config(IPAddress ip_address, Promise promise); +ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise promise); class ConfigRecoverer; class ConfigManager : public NetQueryCallback {