Merge branch 'charlesmchen/lostMessages'

This commit is contained in:
Matthew Chen 2017-04-17 16:06:14 -04:00
commit 91aeddf383
4 changed files with 41 additions and 21 deletions

View File

@ -89,7 +89,7 @@ NS_ASSUME_NONNULL_BEGIN
[self.thread receivedMessagesForInvalidKey:newKey]; [self.thread receivedMessagesForInvalidKey:newKey];
for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) { for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) {
[[TSMessagesManager sharedManager] handleReceivedEnvelope:errorMessage.envelope]; [[TSMessagesManager sharedManager] handleReceivedEnvelope:errorMessage.envelope completion:nil];
// Here we remove the existing error message because handleReceivedEnvelope will either // Here we remove the existing error message because handleReceivedEnvelope will either
// 1.) succeed and create a new successful message in the thread or... // 1.) succeed and create a new successful message in the thread or...

View File

@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
@protocol ContactsManagerProtocol; @protocol ContactsManagerProtocol;
@protocol OWSCallMessageHandler; @protocol OWSCallMessageHandler;
typedef void (^MessageManagerCompletionBlock)();
@interface TSMessagesManager : NSObject @interface TSMessagesManager : NSObject
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
@ -27,18 +29,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) TSNetworkManager *networkManager; @property (nonatomic, readonly) TSNetworkManager *networkManager;
@property (nonatomic, readonly) ContactsUpdater *contactsUpdater; @property (nonatomic, readonly) ContactsUpdater *contactsUpdater;
- (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope; - (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
completion:(nullable MessageManagerCompletionBlock)completion;
/**
* Processes all kinds of incoming envelopes with a data message, along with any attachments.
*
* @returns
* If an incoming message is created, it will be returned. If it is, for example, a group update,
* no incoming message is created, so nil will be returned.
*/
- (TSIncomingMessage *)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
withDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
attachmentIds:(NSArray<NSString *> *)attachmentIds;
/** /**
* @returns * @returns

View File

@ -153,15 +153,27 @@ NS_ASSUME_NONNULL_BEGIN
} }
- (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope - (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
completion:(nullable MessageManagerCompletionBlock)completionHandler
{ {
OWSAssert([NSThread isMainThread]); OWSAssert([NSThread isMainThread]);
// Ensure that completionHandler is called on the main thread,
// and handle the nil case.
MessageManagerCompletionBlock completion = ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (completionHandler) {
completionHandler();
}
});
};
DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]); DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
OWSAssert(envelope.source.length > 0); OWSAssert(envelope.source.length > 0);
BOOL isEnvelopeBlocked = [_blockingManager.blockedPhoneNumbers containsObject:envelope.source]; BOOL isEnvelopeBlocked = [_blockingManager.blockedPhoneNumbers containsObject:envelope.source];
if (isEnvelopeBlocked) { if (isEnvelopeBlocked) {
DDLogInfo(@"%@ ignoring blocked envelope: %@", self.tag, envelope.source); DDLogInfo(@"%@ ignoring blocked envelope: %@", self.tag, envelope.source);
completion();
return; return;
} }
@ -175,8 +187,10 @@ NS_ASSUME_NONNULL_BEGIN
DDLogError( DDLogError(
@"%@ handling secure message failed with error: %@", self.tag, error); @"%@ handling secure message failed with error: %@", self.tag, error);
} }
completion();
}]; }];
break; // Return to avoid double-acknowledging.
return;
} }
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle: { case OWSSignalServiceProtosEnvelopeTypePrekeyBundle: {
[self handlePreKeyBundleAsync:envelope [self handlePreKeyBundleAsync:envelope
@ -186,8 +200,10 @@ NS_ASSUME_NONNULL_BEGIN
DDLogError( DDLogError(
@"%@ handling pre-key bundle failed with error: %@", self.tag, error); @"%@ handling pre-key bundle failed with error: %@", self.tag, error);
} }
completion();
}]; }];
break; // Return to avoid double-acknowledging.
return;
} }
case OWSSignalServiceProtosEnvelopeTypeReceipt: case OWSSignalServiceProtosEnvelopeTypeReceipt:
DDLogInfo(@"Received a delivery receipt"); DDLogInfo(@"Received a delivery receipt");
@ -207,8 +223,10 @@ NS_ASSUME_NONNULL_BEGIN
break; break;
} }
} @catch (NSException *exception) { } @catch (NSException *exception) {
DDLogWarn(@"Received an incorrectly formatted protocol buffer: %@", exception.debugDescription); DDLogError(@"Received an incorrectly formatted protocol buffer: %@", exception.debugDescription);
} }
completion();
} }
- (void)handleDeliveryReceipt:(OWSSignalServiceProtosEnvelope *)envelope - (void)handleDeliveryReceipt:(OWSSignalServiceProtosEnvelope *)envelope
@ -241,6 +259,8 @@ NS_ASSUME_NONNULL_BEGIN
[TSErrorMessage missingSessionWithEnvelope:messageEnvelope withTransaction:transaction]; [TSErrorMessage missingSessionWithEnvelope:messageEnvelope withTransaction:transaction];
[errorMessage saveWithTransaction:transaction]; [errorMessage saveWithTransaction:transaction];
}]; }];
DDLogError(@"Skipping message envelope for unknown session.");
completion(nil);
return; return;
} }
@ -248,7 +268,8 @@ NS_ASSUME_NONNULL_BEGIN
NSData *encryptedData NSData *encryptedData
= messageEnvelope.hasContent ? messageEnvelope.content : messageEnvelope.legacyMessage; = messageEnvelope.hasContent ? messageEnvelope.content : messageEnvelope.legacyMessage;
if (!encryptedData) { if (!encryptedData) {
DDLogError(@"Skipping message envelope which had no encrypted data"); DDLogError(@"Skipping message envelope which had no encrypted data.");
completion(nil);
return; return;
} }
@ -297,6 +318,7 @@ NS_ASSUME_NONNULL_BEGIN
NSData *encryptedData = preKeyEnvelope.hasContent ? preKeyEnvelope.content : preKeyEnvelope.legacyMessage; NSData *encryptedData = preKeyEnvelope.hasContent ? preKeyEnvelope.content : preKeyEnvelope.legacyMessage;
if (!encryptedData) { if (!encryptedData) {
DDLogError(@"Skipping message envelope which had no encrypted data"); DDLogError(@"Skipping message envelope which had no encrypted data");
completion(nil);
return; return;
} }
@ -327,6 +349,7 @@ NS_ASSUME_NONNULL_BEGIN
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self handleEnvelope:preKeyEnvelope plaintextData:plaintextData]; [self handleEnvelope:preKeyEnvelope plaintextData:plaintextData];
completion(nil);
}); });
}); });
} }

View File

@ -368,8 +368,6 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
DDLogInfo(@"Got message with verb: %@ and path: %@", message.verb, message.path); DDLogInfo(@"Got message with verb: %@ and path: %@", message.verb, message.path);
[self sendWebSocketMessageAcknowledgement:message];
// If we receive a message over the socket while the app is in the background, // If we receive a message over the socket while the app is in the background,
// prolong how long the socket stays open. // prolong how long the socket stays open.
[self requestSocketAliveForAtLeastSeconds:kBackgroundKeepSocketAliveDurationSeconds]; [self requestSocketAliveForAtLeastSeconds:kBackgroundKeepSocketAliveDurationSeconds];
@ -381,15 +379,22 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
if (!decryptedPayload) { if (!decryptedPayload) {
DDLogWarn(@"Failed to decrypt incoming payload or bad HMAC"); DDLogWarn(@"Failed to decrypt incoming payload or bad HMAC");
[self sendWebSocketMessageAcknowledgement:message];
return; return;
} }
OWSSignalServiceProtosEnvelope *envelope = [OWSSignalServiceProtosEnvelope parseFromData:decryptedPayload]; OWSSignalServiceProtosEnvelope *envelope = [OWSSignalServiceProtosEnvelope parseFromData:decryptedPayload];
[[TSMessagesManager sharedManager] handleReceivedEnvelope:envelope]; [[TSMessagesManager sharedManager] handleReceivedEnvelope:envelope
completion:^{
// Don't acknowledge delivery until the envelope has been
// processed.
[self sendWebSocketMessageAcknowledgement:message];
}];
} else { } else {
DDLogWarn(@"Unsupported WebSocket Request"); DDLogWarn(@"Unsupported WebSocket Request");
[self sendWebSocketMessageAcknowledgement:message];
} }
} }