fix: Better handle olm session recovery

This commit is contained in:
Sorunome 2020-10-17 12:03:54 +02:00
parent 9632d68b92
commit d116a52ea9
No known key found for this signature in database
GPG Key ID: B19471D07FC9BE9C
2 changed files with 18 additions and 1 deletions

View File

@ -28,6 +28,7 @@ import '../encryption/utils/json_signature_check_extension.dart';
import '../src/utils/logs.dart'; import '../src/utils/logs.dart';
import 'encryption.dart'; import 'encryption.dart';
import 'utils/olm_session.dart'; import 'utils/olm_session.dart';
import '../src/utils/run_in_root.dart';
class OlmManager { class OlmManager {
final Encryption encryption; final Encryption encryption;
@ -344,6 +345,8 @@ class OlmManager {
return res; return res;
} }
final Map<String, DateTime> _restoredOlmSessionsTime = {};
Future<void> restoreOlmSession(String userId, String senderKey) async { Future<void> restoreOlmSession(String userId, String senderKey) async {
if (!client.userDeviceKeys.containsKey(userId)) { if (!client.userDeviceKeys.containsKey(userId)) {
return; return;
@ -353,6 +356,15 @@ class OlmManager {
if (device == null) { if (device == null) {
return; return;
} }
// per device only one olm session per hour should be restored
final mapKey = '$userId;$senderKey';
if (_restoredOlmSessionsTime.containsKey(mapKey) &&
DateTime.now()
.subtract(Duration(hours: 1))
.isBefore(_restoredOlmSessionsTime[mapKey])) {
return;
}
_restoredOlmSessionsTime[mapKey] = DateTime.now();
await startOutgoingOlmSessions([device]); await startOutgoingOlmSessions([device]);
await client.sendToDeviceEncrypted([device], 'm.dummy', {}); await client.sendToDeviceEncrypted([device], 'm.dummy', {});
} }
@ -386,7 +398,8 @@ class OlmManager {
} catch (_) { } catch (_) {
// okay, the thing errored while decrypting. It is safe to assume that the olm session is corrupt and we should generate a new one // okay, the thing errored while decrypting. It is safe to assume that the olm session is corrupt and we should generate a new one
if (client.enableE2eeRecovery) { if (client.enableE2eeRecovery) {
unawaited(restoreOlmSession(event.senderId, senderKey)); unawaited(
runInRoot(() => restoreOlmSession(event.senderId, senderKey)));
} }
rethrow; rethrow;
} }

View File

@ -869,6 +869,8 @@ class Client extends MatrixApi {
var update = RoomUpdate.fromSyncRoomUpdate(room, id); var update = RoomUpdate.fromSyncRoomUpdate(room, id);
if (database != null) { if (database != null) {
// TODO: This method seems to be rather slow for some updates
// Perhaps don't dynamically build that one query?
await database.storeRoomUpdate(this.id, update, getRoomById(id)); await database.storeRoomUpdate(this.id, update, getRoomById(id));
} }
_updateRoomsByRoomUpdate(update); _updateRoomsByRoomUpdate(update);
@ -883,6 +885,7 @@ class Client extends MatrixApi {
/// Handle now all room events and save them in the database /// Handle now all room events and save them in the database
if (room is JoinedRoomUpdate) { if (room is JoinedRoomUpdate) {
if (room.state?.isNotEmpty ?? false) { if (room.state?.isNotEmpty ?? false) {
// TODO: This method seems to be comperatively slow for some updates
await _handleRoomEvents( await _handleRoomEvents(
id, room.state.map((i) => i.toJson()).toList(), 'state'); id, room.state.map((i) => i.toJson()).toList(), 'state');
handledEvents = true; handledEvents = true;
@ -896,6 +899,7 @@ class Client extends MatrixApi {
handledEvents = true; handledEvents = true;
} }
if (room.ephemeral?.isNotEmpty ?? false) { if (room.ephemeral?.isNotEmpty ?? false) {
// TODO: This method seems to be comperatively slow for some updates
await _handleEphemerals( await _handleEphemerals(
id, room.ephemeral.map((i) => i.toJson()).toList()); id, room.ephemeral.map((i) => i.toJson()).toList());
} }