From 449974d425cdbe6d02216c1af723f848c227ff21 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Mon, 2 May 2022 19:34:01 +0400 Subject: [PATCH 01/16] Double check authorization during start up --- td/telegram/AuthManager.cpp | 1 + td/telegram/net/DcAuthManager.cpp | 8 ++++++++ td/telegram/net/DcAuthManager.h | 2 ++ td/telegram/net/NetQueryDispatcher.cpp | 4 ++++ td/telegram/net/NetQueryDispatcher.h | 1 + 5 files changed, 16 insertions(+) diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 5a8206a77..24702f2f6 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -59,6 +59,7 @@ AuthManager::AuthManager(int32 api_id, const string &api_hash, ActorShared<> par ContactsManager::send_get_me_query( td_, PromiseCreator::lambda([this](Result result) { update_state(State::Ok); })); } + G()->net_query_dispatcher().check_authorization_is_ok(); } else if (auth_str == "logout") { LOG(WARNING) << "Continue to log out"; update_state(State::LoggingOut); diff --git a/td/telegram/net/DcAuthManager.cpp b/td/telegram/net/DcAuthManager.cpp index deae91ca1..a61bd5b62 100644 --- a/td/telegram/net/DcAuthManager.cpp +++ b/td/telegram/net/DcAuthManager.cpp @@ -6,6 +6,7 @@ // #include "td/telegram/net/DcAuthManager.h" +#include "td/telegram/ConfigShared.h" #include "td/telegram/Global.h" #include "td/telegram/net/AuthDataShared.h" #include "td/telegram/net/NetQuery.h" @@ -240,4 +241,11 @@ void DcAuthManager::loop() { } } +void DcAuthManager::check_authorization_is_ok() { + auto main_dc = find_dc(main_dc_id_.get_raw_id()); + if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { + G()->shared_config().set_option_string("auth", "Authorization check failed in DcAuthManager"); + } +} + } // namespace td diff --git a/td/telegram/net/DcAuthManager.h b/td/telegram/net/DcAuthManager.h index 96473428e..ecefeb694 100644 --- a/td/telegram/net/DcAuthManager.h +++ b/td/telegram/net/DcAuthManager.h @@ -31,6 +31,8 @@ class DcAuthManager final : public NetQueryCallback { void update_main_dc(DcId new_main_dc_id); void destroy(Promise<> promise); + void check_authorization_is_ok(); + private: struct DcInfo { DcId dc_id; diff --git a/td/telegram/net/NetQueryDispatcher.cpp b/td/telegram/net/NetQueryDispatcher.cpp index e9be4cd50..686dbee01 100644 --- a/td/telegram/net/NetQueryDispatcher.cpp +++ b/td/telegram/net/NetQueryDispatcher.cpp @@ -352,4 +352,8 @@ void NetQueryDispatcher::set_main_dc_id(int32 new_main_dc_id) { G()->td_db()->get_binlog_pmc()->set("main_dc_id", to_string(main_dc_id_.load(std::memory_order_relaxed))); } +void NetQueryDispatcher::check_authorization_is_ok() { + send_closure(dc_auth_manager_, &DcAuthManager::check_authorization_is_ok); +} + } // namespace td diff --git a/td/telegram/net/NetQueryDispatcher.h b/td/telegram/net/NetQueryDispatcher.h index d771009fc..5b1eacc59 100644 --- a/td/telegram/net/NetQueryDispatcher.h +++ b/td/telegram/net/NetQueryDispatcher.h @@ -58,6 +58,7 @@ class NetQueryDispatcher { } void set_main_dc_id(int32 new_main_dc_id); + void check_authorization_is_ok(); private: std::atomic stop_flag_{false}; From 134b7e7d01265f2ce088c09602a1c63819b9f1b8 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 20:35:37 +0300 Subject: [PATCH 02/16] Remove unused function. --- td/telegram/net/NetQueryDispatcher.cpp | 5 +---- td/telegram/net/NetQueryDispatcher.h | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/td/telegram/net/NetQueryDispatcher.cpp b/td/telegram/net/NetQueryDispatcher.cpp index 686dbee01..263816ef0 100644 --- a/td/telegram/net/NetQueryDispatcher.cpp +++ b/td/telegram/net/NetQueryDispatcher.cpp @@ -272,13 +272,10 @@ void NetQueryDispatcher::update_mtproto_header() { } } -void NetQueryDispatcher::update_valid_dc(DcId dc_id) { - wait_dc_init(dc_id, true).ignore(); -} - bool NetQueryDispatcher::is_dc_inited(int32 raw_dc_id) { return dcs_[raw_dc_id - 1].is_valid_.load(std::memory_order_relaxed); } + int32 NetQueryDispatcher::get_session_count() { return max(narrow_cast(G()->shared_config().get_option_integer("session_count")), 1); } diff --git a/td/telegram/net/NetQueryDispatcher.h b/td/telegram/net/NetQueryDispatcher.h index 5b1eacc59..236081cb0 100644 --- a/td/telegram/net/NetQueryDispatcher.h +++ b/td/telegram/net/NetQueryDispatcher.h @@ -51,8 +51,6 @@ class NetQueryDispatcher { void update_use_pfs(); void update_mtproto_header(); - void update_valid_dc(DcId dc_id); - DcId get_main_dc_id() const { return DcId::internal(main_dc_id_.load(std::memory_order_relaxed)); } From d6569d43fd2f4c3efd74d8b0c113c008e18ca099 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 20:44:37 +0300 Subject: [PATCH 03/16] Fix DcAuthManager::check_authorization_is_ok. --- td/telegram/net/DcAuthManager.cpp | 9 +++++---- td/telegram/net/DcAuthManager.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/td/telegram/net/DcAuthManager.cpp b/td/telegram/net/DcAuthManager.cpp index a61bd5b62..cb52faba4 100644 --- a/td/telegram/net/DcAuthManager.cpp +++ b/td/telegram/net/DcAuthManager.cpp @@ -232,20 +232,21 @@ void DcAuthManager::loop() { } auto main_dc = find_dc(main_dc_id_.get_raw_id()); if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { + if (need_check_authorization_is_ok_) { + G()->shared_config().set_option_string("auth", "Authorization check failed in DcAuthManager"); + } 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() { - auto main_dc = find_dc(main_dc_id_.get_raw_id()); - if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { - G()->shared_config().set_option_string("auth", "Authorization check failed in DcAuthManager"); - } + need_check_authorization_is_ok_ = true; } } // namespace td diff --git a/td/telegram/net/DcAuthManager.h b/td/telegram/net/DcAuthManager.h index ecefeb694..a6e21abda 100644 --- a/td/telegram/net/DcAuthManager.h +++ b/td/telegram/net/DcAuthManager.h @@ -50,6 +50,7 @@ class DcAuthManager final : public NetQueryCallback { std::vector dcs_; DcId main_dc_id_; + bool need_check_authorization_is_ok_{false}; bool close_flag_{false}; Promise<> destroy_promise_; From 6b838b706b5f30d796e5d4fda38d6a1c289dea96 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 20:46:20 +0300 Subject: [PATCH 04/16] Increase bound for unique_ptr-based HashTable node usage to improve performance. --- tdutils/td/utils/MapNode.h | 2 +- tdutils/td/utils/SetNode.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tdutils/td/utils/MapNode.h b/tdutils/td/utils/MapNode.h index 806abe0a5..25cc84448 100644 --- a/tdutils/td/utils/MapNode.h +++ b/tdutils/td/utils/MapNode.h @@ -92,7 +92,7 @@ struct MapNode { }; template -struct MapNode 6 * sizeof(void *))>> { +struct MapNode 28 * sizeof(void *))>> { struct Impl { using first_type = KeyT; using second_type = ValueT; diff --git a/tdutils/td/utils/SetNode.h b/tdutils/td/utils/SetNode.h index f30a93bc8..e04127494 100644 --- a/tdutils/td/utils/SetNode.h +++ b/tdutils/td/utils/SetNode.h @@ -64,7 +64,7 @@ struct SetNode { }; template -struct SetNode 6 * sizeof(void *))>> { +struct SetNode 28 * sizeof(void *))>> { struct Impl { using second_type = KeyT; From 746816e7d737cf06ac7580819fd31998c4c4f1a1 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 20:59:07 +0300 Subject: [PATCH 05/16] Add Global::log_out helper. --- td/telegram/Global.cpp | 6 ++++++ td/telegram/Global.h | 2 ++ td/telegram/net/DcAuthManager.cpp | 3 +-- td/telegram/net/Session.cpp | 3 +-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index 9e1320248..d896e6754 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -31,11 +31,17 @@ Global::Global() = default; Global::~Global() = default; +void Global::log_out(Slice reason) { + CHECK(shared_config_ != nullptr); + shared_config_->set_option_string("auth", reason); +} + void Global::close_all(Promise<> on_finished) { td_db_->close_all(std::move(on_finished)); state_manager_.clear(); parameters_ = TdParameters(); } + void Global::close_and_destroy_all(Promise<> on_finished) { td_db_->close_and_destroy_all(std::move(on_finished)); state_manager_.clear(); diff --git a/td/telegram/Global.h b/td/telegram/Global.h index a148a7a9b..c576e169e 100644 --- a/td/telegram/Global.h +++ b/td/telegram/Global.h @@ -84,6 +84,8 @@ class Global final : public ActorContext { return td_db_.get(); } + void log_out(Slice reason); + void close_all(Promise<> on_finished); void close_and_destroy_all(Promise<> on_finished); diff --git a/td/telegram/net/DcAuthManager.cpp b/td/telegram/net/DcAuthManager.cpp index cb52faba4..6833bce13 100644 --- a/td/telegram/net/DcAuthManager.cpp +++ b/td/telegram/net/DcAuthManager.cpp @@ -6,7 +6,6 @@ // #include "td/telegram/net/DcAuthManager.h" -#include "td/telegram/ConfigShared.h" #include "td/telegram/Global.h" #include "td/telegram/net/AuthDataShared.h" #include "td/telegram/net/NetQuery.h" @@ -233,7 +232,7 @@ void DcAuthManager::loop() { auto main_dc = find_dc(main_dc_id_.get_raw_id()); if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { if (need_check_authorization_is_ok_) { - G()->shared_config().set_option_string("auth", "Authorization check failed in DcAuthManager"); + G()->log_out("Authorization check failed in DcAuthManager"); } 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); diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index d55b5927a..1050c9035 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -6,7 +6,6 @@ // #include "td/telegram/net/Session.h" -#include "td/telegram/ConfigShared.h" #include "td/telegram/DhCache.h" #include "td/telegram/Global.h" #include "td/telegram/net/DcAuthManager.h" @@ -837,7 +836,7 @@ void Session::on_message_result_error(uint64 id, int error_code, string message) "write to recover@telegram.org your phone number and other details to recover the account."; } auth_data_.set_auth_flag(false); - G()->shared_config().set_option_string("auth", message); + G()->log_out(message); shared_auth_data_->set_auth_key(auth_data_.get_main_auth_key()); on_session_failed(Status::OK()); } From de15cdb1f057435416e83f83b8c363cbbe2d0feb Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 21:17:06 +0300 Subject: [PATCH 06/16] Log out if key check has failed. --- td/telegram/net/Session.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index 1050c9035..d7877f3a8 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -294,6 +294,7 @@ void Session::on_bind_result(NetQueryPtr query) { LOG(WARNING) << "Drop main key because check with temporary key failed"; auth_data_.drop_main_auth_key(); on_auth_key_updated(); + G()->log_out("Main authorization key is invalid"); } } else { if (has_immunity) { @@ -538,6 +539,7 @@ void Session::on_closed(Status status) { LOG(WARNING) << "Invalidate main key"; auth_data_.drop_main_auth_key(); on_auth_key_updated(); + G()->log_out("Main PFS authorization key is invalid"); } yield(); } From d95b20b631ccf121ebbd34ce8a9fc977384bf104 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 21:20:39 +0300 Subject: [PATCH 07/16] Try not to override "auth" option. --- td/telegram/Global.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index d896e6754..2dcc56129 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -33,7 +33,9 @@ Global::~Global() = default; void Global::log_out(Slice reason) { CHECK(shared_config_ != nullptr); - shared_config_->set_option_string("auth", reason); + if (!shared_config_->have_option("auth")) { + shared_config_->set_option_string("auth", reason); + } } void Global::close_all(Promise<> on_finished) { From 0d0b641ac6ae5ffa8e6e99ebb7af5021b1c29891 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 2 May 2022 21:41:04 +0300 Subject: [PATCH 08/16] Log out only if there is main auth key, but it isn't logged in. --- td/telegram/Global.cpp | 3 ++- td/telegram/net/DcAuthManager.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index 2dcc56129..c3b0cd89b 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -34,7 +34,8 @@ Global::~Global() = default; void Global::log_out(Slice reason) { CHECK(shared_config_ != nullptr); if (!shared_config_->have_option("auth")) { - shared_config_->set_option_string("auth", reason); + LOG(ERROR) << reason; + // shared_config_->set_option_string("auth", reason); } } diff --git a/td/telegram/net/DcAuthManager.cpp b/td/telegram/net/DcAuthManager.cpp index 6833bce13..23db9130e 100644 --- a/td/telegram/net/DcAuthManager.cpp +++ b/td/telegram/net/DcAuthManager.cpp @@ -231,7 +231,7 @@ void DcAuthManager::loop() { } auto main_dc = find_dc(main_dc_id_.get_raw_id()); if (!main_dc || main_dc->auth_key_state != AuthKeyState::OK) { - if (need_check_authorization_is_ok_) { + if (main_dc && need_check_authorization_is_ok_) { G()->log_out("Authorization check failed in DcAuthManager"); } VLOG(dc) << "Skip loop, because main DC is " << main_dc_id_ << ", main auth key state is " From 0450b05757dafae634f4a0949afa976273de4415 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Tue, 3 May 2022 16:33:09 +0400 Subject: [PATCH 09/16] Session: improve key immunity condition --- td/telegram/net/Session.cpp | 9 +++++++-- td/telegram/net/Session.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index d7877f3a8..7553e957a 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -182,6 +182,7 @@ Session::Session(unique_ptr callback, std::shared_ptr } last_activity_timestamp_ = Time::now(); last_success_timestamp_ = Time::now() - 366 * 86400; + last_bind_success_timestamp_ = Time::now() - 366 * 86400; } bool Session::can_destroy_auth_key() const { @@ -286,7 +287,8 @@ void Session::on_bind_result(NetQueryPtr query) { if (status.code() == 400 && status.message() == "ENCRYPTED_MESSAGE_INVALID") { auto auth_key_age = G()->server_time() - auth_data_.get_main_auth_key().created_at(); bool has_immunity = !G()->is_server_time_reliable() || auth_key_age < 60 || - (auth_key_age > 86400 && last_success_timestamp_ > Time::now() - 86400); + (auth_key_age > 86400 && + (use_pfs_ ? last_bind_success_timestamp_ : last_success_timestamp_) > Time::now() - 86400); if (!use_pfs_) { if (has_immunity) { LOG(WARNING) << "Do not drop main key, because it was created too recently"; @@ -317,6 +319,7 @@ void Session::on_bind_result(NetQueryPtr query) { if (status.is_ok()) { LOG(INFO) << "Bound temp auth key " << auth_data_.get_tmp_auth_key().id(); auth_data_.on_bind(); + last_bind_success_timestamp_ = td::Time::now(); on_tmp_auth_key_updated(); } else if (status.error().message() == "DispatchTtlError") { LOG(INFO) << "Resend bind auth key " << auth_data_.get_tmp_auth_key().id() << " request after DispatchTtlError"; @@ -580,7 +583,9 @@ void Session::on_closed(Status status) { void Session::on_session_created(uint64 unique_id, uint64 first_id) { // TODO: use unique_id LOG(INFO) << "New session " << unique_id << " created with first message_id " << first_id; - last_success_timestamp_ = Time::now(); + if (!use_pfs_) { + last_success_timestamp_ = Time::now(); + } if (is_main_) { LOG(DEBUG) << "Sending updatesTooLong to force getDifference"; BufferSlice packet(4); diff --git a/td/telegram/net/Session.h b/td/telegram/net/Session.h index 259307d02..16ce9a5b1 100644 --- a/td/telegram/net/Session.h +++ b/td/telegram/net/Session.h @@ -119,7 +119,8 @@ class Session final uint64 last_bind_query_id_ = 0; uint64 last_check_query_id_ = 0; double last_activity_timestamp_ = 0; - double last_success_timestamp_ = 0; // time when auth_key and Session definitely was valid + double last_success_timestamp_ = 0; // time when auth_key and Session definitely was valid + double last_bind_success_timestamp_ = 0; // time when auth_key and Session definitely was valid and authorized size_t dropped_size_ = 0; FlatHashSet unknown_queries_; From 4b7dab920e3e48b714af053e0b729b638043c670 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 3 May 2022 16:06:14 +0300 Subject: [PATCH 10/16] Don't update last_success_timestamp_ in Session::on_update with PFS. --- td/telegram/net/Session.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index 7553e957a..0f4ffb1e9 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -319,7 +319,7 @@ void Session::on_bind_result(NetQueryPtr query) { if (status.is_ok()) { LOG(INFO) << "Bound temp auth key " << auth_data_.get_tmp_auth_key().id(); auth_data_.on_bind(); - last_bind_success_timestamp_ = td::Time::now(); + last_bind_success_timestamp_ = Time::now(); on_tmp_auth_key_updated(); } else if (status.error().message() == "DispatchTtlError") { LOG(INFO) << "Resend bind auth key " << auth_data_.get_tmp_auth_key().id() << " request after DispatchTtlError"; @@ -741,7 +741,9 @@ Status Session::on_update(BufferSlice packet) { return Status::Error("Receive at update from CDN connection"); } - last_success_timestamp_ = Time::now(); + if (!use_pfs_) { + last_success_timestamp_ = Time::now(); + } last_activity_timestamp_ = Time::now(); callback_->on_update(std::move(packet)); return Status::OK(); From fb1efdbba8f37a3827655ba0a3bd1d734a37f635 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 3 May 2022 16:09:40 +0300 Subject: [PATCH 11/16] Return back notification.is_silent. --- td/generate/scheme/td_api.tl | 4 +- td/telegram/MessagesManager.cpp | 10 ++--- td/telegram/Notification.h | 13 ++++--- td/telegram/NotificationManager.cpp | 60 ++++++++++++++++++----------- td/telegram/NotificationManager.h | 6 +-- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a8367eb6c..9cd48fcee 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3173,8 +3173,8 @@ notificationSounds notification_sounds:vector = NotificationS //@description Contains information about a notification @id Unique persistent identifier of this notification @date Notification date -//@sound_id Identifier of the notification sound to be played; 0 if sound is disabled @type Notification type -notification id:int32 date:int32 sound_id:int64 type:NotificationType = Notification; +//@is_silent True, if the notification was explicitly sent without sound @type Notification type +notification id:int32 date:int32 is_silent:Bool type:NotificationType = Notification; //@description Describes a group of notifications @id Unique persistent auto-incremented from 1 identifier of the notification group @type Type of the group //@chat_id Identifier of a chat to which all notifications in the group belong diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index e08e9fb74..72f8c0371 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -29761,7 +29761,7 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f DialogId settings_dialog_id = d->dialog_id; Dialog *settings_dialog = d; - if (m->contains_mention && !m->is_mention_notification_disabled) { + if (is_from_mention_notification_group(d, m)) { // have a mention, so use notification settings from the dialog with the sender auto sender_dialog_id = get_message_sender(m); if (sender_dialog_id.is_valid()) { @@ -29877,9 +29877,9 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f bool is_silent = m->disable_notification || m->message_id <= d->max_notification_message_id; send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, notification_group_id, from_mentions ? NotificationGroupType::Mentions : NotificationGroupType::Messages, d->dialog_id, - m->date, settings_dialog_id, m->disable_notification ? 0 : ringtone_id, - is_silent ? 0 : ringtone_id, min_delay_ms, m->notification_id, - create_new_message_notification(m->message_id), "add_new_message_notification"); + m->date, settings_dialog_id, m->disable_notification, is_silent ? 0 : ringtone_id, min_delay_ms, + m->notification_id, create_new_message_notification(m->message_id), + "add_new_message_notification"); return true; } @@ -35733,7 +35733,7 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source auto ringtone_id = get_dialog_notification_ringtone_id(dialog_id, d); send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, notification_group_id, NotificationGroupType::SecretChat, dialog_id, date, dialog_id, - ringtone_id, ringtone_id, 0, d->new_secret_chat_notification_id, + false, ringtone_id, 0, d->new_secret_chat_notification_id, create_new_secret_chat_notification(), "add_new_secret_chat_notification"); } } diff --git a/td/telegram/Notification.h b/td/telegram/Notification.h index fd47ad09a..837945b70 100644 --- a/td/telegram/Notification.h +++ b/td/telegram/Notification.h @@ -20,11 +20,14 @@ class Notification { public: NotificationId notification_id; int32 date = 0; - int64 ringtone_id = -1; + bool disable_notification = false; unique_ptr type; - Notification(NotificationId notification_id, int32 date, int64 ringtone_id, unique_ptr type) - : notification_id(notification_id), date(date), ringtone_id(ringtone_id), type(std::move(type)) { + Notification(NotificationId notification_id, int32 date, bool disable_notification, unique_ptr type) + : notification_id(notification_id) + , date(date) + , disable_notification(disable_notification) + , type(std::move(type)) { } }; @@ -32,13 +35,13 @@ inline td_api::object_ptr get_notification_object(DialogId const Notification ¬ification) { CHECK(notification.type != nullptr); return td_api::make_object(notification.notification_id.get(), notification.date, - notification.ringtone_id, + notification.disable_notification, notification.type->get_notification_type_object(dialog_id)); } inline StringBuilder &operator<<(StringBuilder &sb, const Notification ¬ification) { return sb << "notification[" << notification.notification_id << ", " << notification.date << ", " - << notification.ringtone_id << ", " << *notification.type << ']'; + << notification.disable_notification << ", " << *notification.type << ']'; } } // namespace td diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index d4ea395a1..e073ce767 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -855,7 +855,7 @@ int32 NotificationManager::get_notification_delay_ms(DialogId dialog_id, const P void NotificationManager::add_notification(NotificationGroupId group_id, NotificationGroupType group_type, DialogId dialog_id, int32 date, DialogId notification_settings_dialog_id, - int64 initial_ringtone_id, int64 ringtone_id, int32 min_delay_ms, + bool disable_notification, int64 ringtone_id, int32 min_delay_ms, NotificationId notification_id, unique_ptr type, const char *source) { if (is_disabled() || max_notification_group_count_ == 0) { @@ -904,8 +904,8 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific PendingNotification notification; notification.date = date; notification.settings_dialog_id = notification_settings_dialog_id; - notification.initial_ringtone_id = initial_ringtone_id; - notification.ringtone_id = ringtone_id; + notification.disable_notification = disable_notification; + notification.ringtone_id = disable_notification ? 0 : ringtone_id; notification.notification_id = notification_id; notification.type = std::move(type); @@ -1392,7 +1392,7 @@ bool NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g added_notifications.reserve(pending_notifications.size()); for (auto &pending_notification : pending_notifications) { Notification notification(pending_notification.notification_id, pending_notification.date, - pending_notification.initial_ringtone_id, std::move(pending_notification.type)); + pending_notification.disable_notification, std::move(pending_notification.type)); added_notifications.push_back(get_notification_object(group_key.dialog_id, notification)); CHECK(added_notifications.back()->type_ != nullptr); @@ -1523,7 +1523,7 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ group.total_count += narrow_cast(group.pending_notifications.size()); for (auto &pending_notification : group.pending_notifications) { group.notifications.emplace_back(pending_notification.notification_id, pending_notification.date, - pending_notification.initial_ringtone_id, std::move(pending_notification.type)); + pending_notification.disable_notification, std::move(pending_notification.type)); } } else { if (!was_updated) { @@ -2318,8 +2318,8 @@ void NotificationManager::add_call_notification(DialogId dialog_id, CallId call_ } active_notifications.push_back(ActiveCallNotification{call_id, notification_id}); - add_notification(group_id, NotificationGroupType::Calls, dialog_id, G()->unix_time() + 120, dialog_id, false, false, - 0, notification_id, create_new_call_notification(call_id), "add_call_notification"); + add_notification(group_id, NotificationGroupType::Calls, dialog_id, G()->unix_time() + 120, dialog_id, false, -1, 0, + notification_id, create_new_call_notification(call_id), "add_call_notification"); } void NotificationManager::remove_call_notification(DialogId dialog_id, CallId call_id) { @@ -3437,16 +3437,19 @@ Status NotificationManager::process_push_notification_payload(string payload, bo std::move(promise)); } else { bool is_from_scheduled = has_json_object_field(custom, "schedule"); + bool disable_notification = false; int64 ringtone_id = -1; if (has_json_object_field(custom, "silent")) { + disable_notification = true; ringtone_id = 0; } else if (has_json_object_field(custom, "ringtone")) { TRY_RESULT_ASSIGN(ringtone_id, get_json_object_long_field(custom, "ringtone")); } add_message_push_notification(dialog_id, MessageId(server_message_id), random_id, sender_user_id, sender_dialog_id, - std::move(sender_name), sent_date, is_from_scheduled, contains_mention, ringtone_id, - ringtone_id, std::move(loc_key), std::move(arg), std::move(attached_photo), - std::move(attached_document), NotificationId(), 0, std::move(promise)); + std::move(sender_name), sent_date, is_from_scheduled, contains_mention, + disable_notification, ringtone_id, std::move(loc_key), std::move(arg), + std::move(attached_photo), std::move(attached_document), NotificationId(), 0, + std::move(promise)); } return Status::OK(); } @@ -3462,6 +3465,7 @@ class NotificationManager::AddMessagePushNotificationLogEvent { int32 date_; bool is_from_scheduled_; bool contains_mention_; + bool disable_notification_; int64 ringtone_id_; string loc_key_; string arg_; @@ -3479,11 +3483,10 @@ class NotificationManager::AddMessagePushNotificationLogEvent { bool has_photo = !photo_.is_empty(); bool has_document = !document_.empty(); bool has_sender_dialog_id = sender_dialog_id_.is_valid(); - bool is_silent = ringtone_id_ == 0; - bool has_ringtone_id = !is_silent && ringtone_id_ != -1; + bool has_ringtone_id = !disable_notification_ && ringtone_id_ != -1; BEGIN_STORE_FLAGS(); STORE_FLAG(contains_mention_); - STORE_FLAG(is_silent); + STORE_FLAG(disable_notification_); STORE_FLAG(has_message_id); STORE_FLAG(has_random_id); STORE_FLAG(has_sender); @@ -3538,11 +3541,10 @@ class NotificationManager::AddMessagePushNotificationLogEvent { bool has_photo; bool has_document; bool has_sender_dialog_id; - bool is_silent; bool has_ringtone_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(contains_mention_); - PARSE_FLAG(is_silent); + PARSE_FLAG(disable_notification_); PARSE_FLAG(has_message_id); PARSE_FLAG(has_random_id); PARSE_FLAG(has_sender); @@ -3587,7 +3589,7 @@ class NotificationManager::AddMessagePushNotificationLogEvent { if (has_ringtone_id) { td::parse(ringtone_id_, parser); } else { - ringtone_id_ = is_silent ? 0 : -1; + ringtone_id_ = disable_notification_ ? 0 : -1; } } }; @@ -3595,7 +3597,7 @@ class NotificationManager::AddMessagePushNotificationLogEvent { void NotificationManager::add_message_push_notification(DialogId dialog_id, MessageId message_id, int64 random_id, UserId sender_user_id, DialogId sender_dialog_id, string sender_name, int32 date, bool is_from_scheduled, - bool contains_mention, int64 initial_ringtone_id, + bool contains_mention, bool disable_notification, int64 ringtone_id, string loc_key, string arg, Photo photo, Document document, NotificationId notification_id, uint64 log_event_id, Promise promise) { @@ -3659,10 +3661,22 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess } if (log_event_id == 0 && G()->parameters().use_message_db) { - AddMessagePushNotificationLogEvent log_event{ - dialog_id, message_id, random_id, sender_user_id, sender_dialog_id, sender_name, - date, is_from_scheduled, contains_mention, initial_ringtone_id, loc_key, arg, - photo, document, notification_id}; + AddMessagePushNotificationLogEvent log_event{dialog_id, + message_id, + random_id, + sender_user_id, + sender_dialog_id, + sender_name, + date, + is_from_scheduled, + contains_mention, + disable_notification, + ringtone_id, + loc_key, + arg, + photo, + document, + notification_id}; log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::AddMessagePushNotification, get_log_event_storer(log_event)); } @@ -3690,7 +3704,7 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess << group_type << " with settings from " << settings_dialog_id; add_notification( - group_id, group_type, dialog_id, date, settings_dialog_id, initial_ringtone_id, ringtone_id, 0, notification_id, + group_id, group_type, dialog_id, date, settings_dialog_id, disable_notification, ringtone_id, 0, notification_id, create_new_push_message_notification(sender_user_id, sender_dialog_id, sender_name, is_outgoing, message_id, std::move(loc_key), std::move(arg), std::move(photo), std::move(document)), "add_message_push_notification"); @@ -4143,7 +4157,7 @@ void NotificationManager::on_binlog_events(vector &&events) { add_message_push_notification( log_event.dialog_id_, log_event.message_id_, log_event.random_id_, log_event.sender_user_id_, log_event.sender_dialog_id_, log_event.sender_name_, log_event.date_, log_event.is_from_scheduled_, - log_event.contains_mention_, log_event.ringtone_id_, 0, log_event.loc_key_, log_event.arg_, + log_event.contains_mention_, log_event.disable_notification_, 0, log_event.loc_key_, log_event.arg_, log_event.photo_, log_event.document_, log_event.notification_id_, event.id_, PromiseCreator::lambda([](Result result) { if (result.is_error() && result.error().code() != 200 && result.error().code() != 406) { diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 6fe5d0cf3..9ba19171a 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -67,7 +67,7 @@ class NotificationManager final : public Actor { void load_group_force(NotificationGroupId group_id); void add_notification(NotificationGroupId group_id, NotificationGroupType group_type, DialogId dialog_id, int32 date, - DialogId notification_settings_dialog_id, int64 initial_ringtone_id, int64 ringtone_id, + DialogId notification_settings_dialog_id, bool disable_notification, int64 ringtone_id, int32 min_delay_ms, NotificationId notification_id, unique_ptr type, const char *source); @@ -161,7 +161,7 @@ class NotificationManager final : public Actor { struct PendingNotification { int32 date = 0; DialogId settings_dialog_id; - int64 initial_ringtone_id = -1; + bool disable_notification = false; int64 ringtone_id = -1; NotificationId notification_id; unique_ptr type; @@ -313,7 +313,7 @@ class NotificationManager final : public Actor { void add_message_push_notification(DialogId dialog_id, MessageId message_id, int64 random_id, UserId sender_user_id, DialogId sender_dialog_id, string sender_name, int32 date, bool is_from_scheduled, - bool contains_mention, int64 initial_ringtone_id, int64 ringtone_id, + bool contains_mention, bool disable_notification, int64 ringtone_id, string loc_key, string arg, Photo photo, Document document, NotificationId notification_id, uint64 log_event_id, Promise promise); From 852fe4f24bd675ffcf306b2604a810c4ab60e929 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Tue, 3 May 2022 17:17:14 +0400 Subject: [PATCH 12/16] Session: force ack when we received unknown answer --- td/mtproto/SessionConnection.cpp | 6 ++++++ td/mtproto/SessionConnection.h | 1 + td/telegram/net/Session.cpp | 1 + 3 files changed, 8 insertions(+) diff --git a/td/mtproto/SessionConnection.cpp b/td/mtproto/SessionConnection.cpp index 05f3dfa0c..d6722f264 100644 --- a/td/mtproto/SessionConnection.cpp +++ b/td/mtproto/SessionConnection.cpp @@ -838,6 +838,12 @@ std::pair SessionConnection::encrypted_bind(int64 perm_key, return std::make_pair(query.message_id, packet.as_buffer_slice()); } +void SessionConnection::force_ack() { + if (!to_ack_.empty()) { + send_before(Time::now_cached()); + } +} + void SessionConnection::send_ack(uint64 message_id) { VLOG(mtproto) << "Send ack: [msg_id:" << format::as_hex(message_id) << "]"; if (to_ack_.empty()) { diff --git a/td/mtproto/SessionConnection.h b/td/mtproto/SessionConnection.h index 8446fd1c0..0b2e75555 100644 --- a/td/mtproto/SessionConnection.h +++ b/td/mtproto/SessionConnection.h @@ -91,6 +91,7 @@ class SessionConnection final void destroy_key(); void set_online(bool online_flag, bool is_main); + void force_ack(); class Callback { public: diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index 0f4ffb1e9..b4682669e 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -871,6 +871,7 @@ void Session::on_message_result_error(uint64 id, int error_code, string message) } auto it = sent_queries_.find(id); if (it == sent_queries_.end()) { + current_info_->connection_->force_ack(); return; } From fc6b1c0ea8b943718bf80fd263ab7e820beb5abc Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 3 May 2022 16:31:58 +0300 Subject: [PATCH 13/16] Enable back log out. --- td/telegram/Global.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index c3b0cd89b..2dcc56129 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -34,8 +34,7 @@ Global::~Global() = default; void Global::log_out(Slice reason) { CHECK(shared_config_ != nullptr); if (!shared_config_->have_option("auth")) { - LOG(ERROR) << reason; - // shared_config_->set_option_string("auth", reason); + shared_config_->set_option_string("auth", reason); } } From 1191f13f91bfa562112690989239459fb08bacad Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 4 May 2022 17:17:40 +0300 Subject: [PATCH 14/16] Fix compilation error. --- td/telegram/AttachMenuManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/AttachMenuManager.cpp b/td/telegram/AttachMenuManager.cpp index c5c13f04f..84cc6bfc4 100644 --- a/td/telegram/AttachMenuManager.cpp +++ b/td/telegram/AttachMenuManager.cpp @@ -598,7 +598,7 @@ Result AttachMenuManager::get_attach_menu_bot( auto parsed_document = td_->documents_manager_->on_get_document(move_tl_object_as(icon->icon_), DialogId()); if (parsed_document.type != expected_document_type) { - if (user_id != UserId(5000860301) || !G()->is_test_dc() || name != "macos_animated") { + if (user_id != UserId(static_cast(5000860301)) || !G()->is_test_dc() || name != "macos_animated") { LOG(ERROR) << "Receive wrong attachment menu bot icon \"" << name << "\" for " << user_id; } continue; From bf05cf16803c8d685aa9bd33cb734e46f158b9df Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 4 May 2022 20:02:35 +0300 Subject: [PATCH 15/16] Update user photo from user full photo. --- td/telegram/ContactsManager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 901d5c76c..d0aa65646 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -4668,7 +4668,7 @@ void ContactsManager::apply_pending_user_photo(User *u, UserId user_id) { auto it = pending_user_photos_.find(user_id); if (it != pending_user_photos_.end()) { - do_update_user_photo(u, user_id, std::move(it->second), "get_user_dialog_photo"); + do_update_user_photo(u, user_id, std::move(it->second), "apply_pending_user_photo"); pending_user_photos_.erase(it); update_user(u, user_id); } @@ -10618,6 +10618,9 @@ void ContactsManager::on_get_user_full(tl_object_ptr &&u } auto photo = get_photo(td_->file_manager_.get(), std::move(user->profile_photo_), DialogId(user_id)); + // do_update_user_photo should be a no-op if server sent consistent data + do_update_user_photo(u, user_id, as_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, photo), false, + "on_get_user_full"); if (photo != user_full->photo) { user_full->photo = std::move(photo); user_full->is_changed = true; @@ -10628,6 +10631,7 @@ void ContactsManager::on_get_user_full(tl_object_ptr &&u register_user_photo(u, user_id, user_full->photo); } + update_user(u, user_id); user_full->is_update_user_full_sent = true; update_user_full(user_full, user_id, "on_get_user_full"); @@ -11156,7 +11160,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c update_channel_full(channel_full, channel_id, "on_get_channel_full"); if (linked_channel_id.is_valid()) { - auto linked_channel_full = get_channel_full_force(linked_channel_id, true, "on_get_chat_full"); + auto linked_channel_full = get_channel_full_force(linked_channel_id, true, "on_get_channel_full"); on_update_channel_full_linked_channel_id(linked_channel_full, linked_channel_id, channel_id); if (linked_channel_full != nullptr) { update_channel_full(linked_channel_full, linked_channel_id, "on_get_channel_full 2"); From ab3a8282d4ee307d341071267ef1090b1a941478 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 4 May 2022 20:08:32 +0300 Subject: [PATCH 16/16] Add warning when receive inconsistent photos in chatPhoto and chatPhotoInfo. --- td/telegram/ContactsManager.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index d0aa65646..66b974320 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -10631,7 +10631,11 @@ void ContactsManager::on_get_user_full(tl_object_ptr &&u register_user_photo(u, user_id, user_full->photo); } - update_user(u, user_id); + if (u->is_changed) { + LOG(WARNING) << "Receive inconsistent chatPhoto and chatPhotoInfo for " << user_id; + update_user(u, user_id); + } + user_full->is_update_user_full_sent = true; update_user_full(user_full, user_id, "on_get_user_full"); @@ -10885,8 +10889,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c chat_full->is_changed = true; } + if (c->is_changed) { + LOG(WARNING) << "Receive inconsistent chatPhoto and chatPhotoInfo for " << chat_id; + update_chat(c, chat_id); + } + chat_full->is_update_chat_full_sent = true; - update_chat(c, chat_id); update_chat_full(chat_full, chat_id, "on_get_chat_full"); } else { CHECK(chat_full_ptr->get_id() == telegram_api::channelFull::ID); @@ -11155,8 +11163,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c channel_full->is_changed = true; } + if (c->is_changed) { + LOG(WARNING) << "Receive inconsistent chatPhoto and chatPhotoInfo for " << channel_id; + update_channel(c, channel_id); + } + channel_full->is_update_channel_full_sent = true; - update_channel(c, channel_id); update_channel_full(channel_full, channel_id, "on_get_channel_full"); if (linked_channel_id.is_valid()) {