secret: fix infinity loop for non-rewritable queries during flood control errors

GitOrigin-RevId: 8f0e3d0a402426c22760074b0bbdf144401f353f
This commit is contained in:
Arseny Smirnov 2020-06-09 14:34:48 +03:00
parent ab854dac52
commit e8dba312fe
2 changed files with 15 additions and 11 deletions

View File

@ -342,7 +342,7 @@ void SecretChatActor::send_message_impl(tl_object_ptr<secret_api::DecryptedMessa
binlog_event->encrypted_message =
create_encrypted_message(current_layer(), binlog_event->my_in_seq_no, binlog_event->my_out_seq_no, message)
.move_as_ok();
binlog_event->is_service = (flags & SendFlag::Push) == 0;
binlog_event->need_notify_user = (flags & SendFlag::Push) == 0;
binlog_event->is_external = (flags & SendFlag::External) != 0;
if (message->get_id() == secret_api::decryptedMessageService::ID) {
binlog_event->is_rewritable = false;
@ -1460,12 +1460,11 @@ void SecretChatActor::inbound_loop(InboundMessageState *state, uint64 state_id)
NetQueryPtr SecretChatActor::create_net_query(const logevent::OutboundSecretMessage &message) {
NetQueryPtr query;
if (message.is_service) {
if (message.need_notify_user) {
CHECK(message.file.empty());
query = create_net_query(QueryType::Message,
telegram_api::messages_sendEncryptedService(get_input_chat(), message.random_id,
message.encrypted_message.clone()));
query->total_timeout_limit = 1000000000; // inf. We will re-sent it immediately anyway
} else if (message.file.empty()) {
query = create_net_query(
QueryType::Message,
@ -1476,6 +1475,9 @@ NetQueryPtr SecretChatActor::create_net_query(const logevent::OutboundSecretMess
telegram_api::messages_sendEncryptedFile(get_input_chat(), message.random_id, message.encrypted_message.clone(),
message.file.as_input_encrypted_file()));
}
if (!message.is_rewritable) {
query->total_timeout_limit = 1000000000; // inf. We will re-sent it immediately anyway
}
if (message.is_external && context_->get_config_option_boolean("use_quick_ack")) {
query->quick_ack_promise_ =
PromiseCreator::lambda([actor_id = actor_id(this), random_id = message.random_id](
@ -1558,7 +1560,7 @@ Status SecretChatActor::outbound_rewrite_with_empty(uint64 state_id) {
LOG(INFO) << tag("crc", crc64(state->message->encrypted_message.as_slice()));
state->message->is_rewritable = false;
state->message->is_external = false;
state->message->is_service = true;
state->message->need_notify_user = false;
state->message->file = logevent::EncryptedInputFile::from_input_encrypted_file(nullptr);
binlog_rewrite(context_->binlog(), state->message->logevent_id(), LogEvent::HandlerType::SecretChats,
create_storer(*state->message));

View File

@ -321,8 +321,11 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
}
bool is_sent = false;
bool is_service = false;
// need send push notification to the receiver
// should send such messages with messages_sendEncryptedsService
bool need_notify_user = false;
bool is_rewritable = false;
// should notify our parent about state of this message (using context and random_id)
bool is_external = false;
tl_object_ptr<secret_api::DecryptedMessageAction> action;
@ -331,7 +334,6 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
// Flags:
// 2. can_fail = !file.empty() // send of other messages can't fail if chat is ok. It is usless to rewrite them with
// empty
// 1. is_service // use messages_sendEncryptedsService
// 3. can_rewrite_with_empty // false for almost all service messages
// TODO: combine these two functions into one macros hell. Or a lambda hell.
@ -351,7 +353,7 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
bool has_action = static_cast<bool>(action);
BEGIN_STORE_FLAGS();
STORE_FLAG(is_sent);
STORE_FLAG(is_service);
STORE_FLAG(need_notify_user);
STORE_FLAG(has_action);
STORE_FLAG(is_rewritable);
STORE_FLAG(is_external);
@ -381,7 +383,7 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
bool has_action;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_sent);
PARSE_FLAG(is_service);
PARSE_FLAG(need_notify_user);
PARSE_FLAG(has_action);
PARSE_FLAG(is_rewritable);
PARSE_FLAG(is_external);
@ -395,9 +397,9 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
StringBuilder &print(StringBuilder &sb) const override {
return sb << "[Logevent OutboundSecretMessage " << tag("id", logevent_id()) << tag("chat_id", chat_id)
<< tag("is_sent", is_sent) << tag("is_service", is_service) << tag("is_rewritable", is_rewritable)
<< tag("is_external", is_external) << tag("message_id", message_id) << tag("random_id", random_id)
<< tag("my_in_seq_no", my_in_seq_no) << tag("my_out_seq_no", my_out_seq_no)
<< tag("is_sent", is_sent) << tag("need_notify_user", need_notify_user)
<< tag("is_rewritable", is_rewritable) << tag("is_external", is_external) << tag("message_id", message_id)
<< tag("random_id", random_id) << tag("my_in_seq_no", my_in_seq_no) << tag("my_out_seq_no", my_out_seq_no)
<< tag("his_in_seq_no", his_in_seq_no) << tag("file", file) << tag("action", to_string(action)) << "]";
}
};