onRetryRequest: Send only after session archive or found senderKey

This commit is contained in:
Scott Nonnenberg 2021-11-18 14:22:24 -08:00 committed by GitHub
parent b48477a19c
commit 834023779e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -31,8 +31,16 @@ import type {
import { SignalService as Proto } from '../protobuf'; import { SignalService as Proto } from '../protobuf';
import * as log from '../logging/log'; import * as log from '../logging/log';
const RETRY_LIMIT = 5;
// Entrypoints // Entrypoints
const retryRecord = new Map<number, number>();
export function _getRetryRecord(): Map<number, number> {
return retryRecord;
}
export async function onRetryRequest(event: RetryRequestEvent): Promise<void> { export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
const { confirm, retryRequest } = event; const { confirm, retryRequest } = event;
const { const {
@ -54,6 +62,16 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
return; return;
} }
const retryCount = (retryRecord.get(sentAt) || 0) + 1;
retryRecord.set(sentAt, retryCount);
if (retryCount > RETRY_LIMIT) {
log.warn(
`onRetryRequest/${logId}: retryCount is ${retryCount}; returning early.`
);
confirm();
return;
}
if (window.RETRY_DELAY) { if (window.RETRY_DELAY) {
log.warn(`onRetryRequest/${logId}: Delaying because RETRY_DELAY is set...`); log.warn(`onRetryRequest/${logId}: Delaying because RETRY_DELAY is set...`);
await new Promise(resolve => setTimeout(resolve, 5000)); await new Promise(resolve => setTimeout(resolve, 5000));
@ -74,13 +92,13 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
); );
} }
await archiveSessionOnMatch(retryRequest); const didArchive = await archiveSessionOnMatch(retryRequest);
if (isOlderThan(sentAt, retryRespondMaxAge)) { if (isOlderThan(sentAt, retryRespondMaxAge)) {
log.info( log.info(
`onRetryRequest/${logId}: Message is too old, refusing to send again.` `onRetryRequest/${logId}: Message is too old, refusing to send again.`
); );
await sendDistributionMessageOrNullMessage(logId, retryRequest); await sendDistributionMessageOrNullMessage(logId, retryRequest, didArchive);
confirm(); confirm();
return; return;
} }
@ -93,7 +111,7 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
if (!sentProto) { if (!sentProto) {
log.info(`onRetryRequest/${logId}: Did not find sent proto`); log.info(`onRetryRequest/${logId}: Did not find sent proto`);
await sendDistributionMessageOrNullMessage(logId, retryRequest); await sendDistributionMessageOrNullMessage(logId, retryRequest, didArchive);
confirm(); confirm();
return; return;
} }
@ -153,6 +171,16 @@ export async function onDecryptionError(
log.info(`onDecryptionError/${logId}: Starting...`); log.info(`onDecryptionError/${logId}: Starting...`);
const retryCount = (retryRecord.get(timestamp) || 0) + 1;
retryRecord.set(timestamp, retryCount);
if (retryCount > RETRY_LIMIT) {
log.warn(
`onDecryptionError/${logId}: retryCount is ${retryCount}; returning early.`
);
confirm();
return;
}
const conversation = window.ConversationController.getOrCreate( const conversation = window.ConversationController.getOrCreate(
senderUuid, senderUuid,
'private' 'private'
@ -183,13 +211,13 @@ async function archiveSessionOnMatch({
requesterUuid, requesterUuid,
requesterDevice, requesterDevice,
senderDevice, senderDevice,
}: RetryRequestEventData): Promise<void> { }: RetryRequestEventData): Promise<boolean> {
const ourDeviceId = parseIntOrThrow( const ourDeviceId = parseIntOrThrow(
window.textsecure.storage.user.getDeviceId(), window.textsecure.storage.user.getDeviceId(),
'archiveSessionOnMatch/getDeviceId' 'archiveSessionOnMatch/getDeviceId'
); );
if (ourDeviceId !== senderDevice || !ratchetKey) { if (ourDeviceId !== senderDevice || !ratchetKey) {
return; return false;
} }
const ourUuid = window.textsecure.storage.user.getCheckedUuid(); const ourUuid = window.textsecure.storage.user.getCheckedUuid();
@ -204,12 +232,16 @@ async function archiveSessionOnMatch({
'archiveSessionOnMatch: Matching device and ratchetKey, archiving session' 'archiveSessionOnMatch: Matching device and ratchetKey, archiving session'
); );
await window.textsecure.storage.protocol.archiveSession(address); await window.textsecure.storage.protocol.archiveSession(address);
return true;
} }
return false;
} }
async function sendDistributionMessageOrNullMessage( async function sendDistributionMessageOrNullMessage(
logId: string, logId: string,
options: RetryRequestEventData options: RetryRequestEventData,
didArchive: boolean
): Promise<void> { ): Promise<void> {
const { groupId, requesterUuid } = options; const { groupId, requesterUuid } = options;
let sentDistributionMessage = false; let sentDistributionMessage = false;
@ -261,6 +293,13 @@ async function sendDistributionMessageOrNullMessage(
} }
if (!sentDistributionMessage) { if (!sentDistributionMessage) {
if (!didArchive) {
log.info(
`sendDistributionMessageOrNullMessage/${logId}: Did't send distribution message and didn't archive session. Returning early.`
);
return;
}
log.info( log.info(
`sendDistributionMessageOrNullMessage/${logId}: Did not send distribution message, sending null message` `sendDistributionMessageOrNullMessage/${logId}: Did not send distribution message, sending null message`
); );
@ -306,7 +345,7 @@ async function getRetryConversation({
}); });
if (!message) { if (!message) {
log.warn( log.warn(
`maybeAddSenderKeyDistributionMessage/${logId}: Unable to find message ${messageId}` `getRetryConversation/${logId}: Unable to find message ${messageId}`
); );
// Fail over to requested groupId // Fail over to requested groupId
return window.ConversationController.get(requestGroupId); return window.ConversationController.get(requestGroupId);
@ -328,7 +367,10 @@ async function maybeAddSenderKeyDistributionMessage({
messageIds: Array<string>; messageIds: Array<string>;
requestGroupId?: string; requestGroupId?: string;
requesterUuid: string; requesterUuid: string;
}): Promise<{ contentProto: Proto.IContent; groupId?: string }> { }): Promise<{
contentProto: Proto.IContent;
groupId?: string;
}> {
const conversation = await getRetryConversation({ const conversation = await getRetryConversation({
logId, logId,
messageIds, messageIds,