diff --git a/submodules/MtProtoKit/BUCK b/submodules/MtProtoKit/BUCK index 215e91f784..e7c782ef4e 100644 --- a/submodules/MtProtoKit/BUCK +++ b/submodules/MtProtoKit/BUCK @@ -3,10 +3,10 @@ load("//Config:buck_rule_macros.bzl", "static_library", "framework", "glob_map", framework( name = "MtProtoKit", srcs = glob([ - "Sources/*.m", + "Sources/**/*.m", ]), headers = glob([ - "Sources/*.h", + "Sources/**/*.h", ]), exported_headers = glob([ "PublicHeaders/**/*.h", diff --git a/submodules/MtProtoKit/BUILD b/submodules/MtProtoKit/BUILD index cdc4b42171..c316d024a3 100644 --- a/submodules/MtProtoKit/BUILD +++ b/submodules/MtProtoKit/BUILD @@ -4,8 +4,8 @@ objc_library( enable_modules = True, module_name = "MtProtoKit", srcs = glob([ - "Sources/*.m", - "Sources/*.h", + "Sources/**/*.m", + "Sources/**/*.h", ]), hdrs = glob([ "PublicHeaders/**/*.h", diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h index c4cff82ef3..1f01237c4c 100644 --- a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h @@ -20,7 +20,7 @@ @optional - (void)contextDatacenterAddressSetUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId addressSet:(MTDatacenterAddressSet *)addressSet; -- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo; +- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector; - (void)contextDatacenterAuthTokenUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authToken:(id)authToken; - (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId shouldReset:(bool)shouldReset; - (void)contextIsPasswordRequiredUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId; @@ -73,7 +73,7 @@ - (void)updateAddressSetForDatacenterWithId:(NSInteger)datacenterId addressSet:(MTDatacenterAddressSet *)addressSet forceUpdateSchemes:(bool)forceUpdateSchemes; - (void)addAddressForDatacenterWithId:(NSInteger)datacenterId address:(MTDatacenterAddress *)address; - (void)updateTransportSchemeForDatacenterWithId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme media:(bool)media isProxy:(bool)isProxy; -- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo; +- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector; - (bool)isPasswordInputRequiredForDatacenterWithId:(NSInteger)datacenterId; - (bool)updatePasswordInputRequiredForDatacenterWithId:(NSInteger)datacenterId required:(bool)required; @@ -95,7 +95,7 @@ - (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId media:(bool)media; - (void)invalidateTransportSchemeForDatacenterId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme isProbablyHttp:(bool)isProbablyHttp media:(bool)media; - (void)revalidateTransportSchemeForDatacenterId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme media:(bool)media; -- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId; +- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId selector:(MTDatacenterAuthInfoSelector)selector; - (NSArray *)publicKeysForDatacenterWithId:(NSInteger)datacenterId; - (void)updatePublicKeysForDatacenterWithId:(NSInteger)datacenterId publicKeys:(NSArray *)publicKeys; @@ -107,8 +107,7 @@ - (void)updateAuthTokenForDatacenterWithId:(NSInteger)datacenterId authToken:(id)authToken; - (void)addressSetForDatacenterWithIdRequired:(NSInteger)datacenterId; -- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn; -- (void)tempAuthKeyForDatacenterWithIdRequired:(NSInteger)datacenterId keyType:(MTDatacenterAuthTempKeyType)keyType; +- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector; - (void)authTokenForDatacenterWithIdRequired:(NSInteger)datacenterId authToken:(id)authToken masterDatacenterId:(NSInteger)masterDatacenterId; - (void)reportProblemsWithDatacenterAddressForId:(NSInteger)datacenterId address:(MTDatacenterAddress *)address; diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthAction.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthAction.h index c9643cdaf3..8d2beeeda9 100644 --- a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthAction.h +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthAction.h @@ -18,7 +18,7 @@ @property (nonatomic, weak) id delegate; @property (nonatomic, copy) void (^completedWithResult)(bool); -- (instancetype)initWithTempAuth:(bool)tempAuth tempAuthKeyType:(MTDatacenterAuthTempKeyType)tempAuthKeyType bindKey:(MTDatacenterAuthKey *)bindKey; +- (instancetype)initWithTempAuth:(bool)tempAuth authKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector bindKey:(MTDatacenterAuthKey *)bindKey; - (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn; - (void)cancel; diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthInfo.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthInfo.h index ae73123a64..26c7c7ea3f 100644 --- a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthInfo.h +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTDatacenterAuthInfo.h @@ -1,10 +1,5 @@ #import -typedef NS_ENUM(NSUInteger, MTDatacenterAuthTempKeyType) { - MTDatacenterAuthTempKeyTypeMain, - MTDatacenterAuthTempKeyTypeMedia -}; - @interface MTDatacenterAuthKey: NSObject @property (nonatomic, strong, readonly) NSData *authKey; @@ -15,24 +10,24 @@ typedef NS_ENUM(NSUInteger, MTDatacenterAuthTempKeyType) { @end +typedef NS_ENUM(int64_t, MTDatacenterAuthInfoSelector) { + MTDatacenterAuthInfoSelectorPersistent = 0, + MTDatacenterAuthInfoSelectorEphemeralMain, + MTDatacenterAuthInfoSelectorEphemeralMedia +}; + @interface MTDatacenterAuthInfo : NSObject @property (nonatomic, strong, readonly) NSData *authKey; @property (nonatomic, readonly) int64_t authKeyId; @property (nonatomic, strong, readonly) NSArray *saltSet; @property (nonatomic, strong, readonly) NSDictionary *authKeyAttributes; -@property (nonatomic, strong, readonly) MTDatacenterAuthKey *mainTempAuthKey; -@property (nonatomic, strong, readonly) MTDatacenterAuthKey *mediaTempAuthKey; -@property (nonatomic, strong, readonly) MTDatacenterAuthKey *persistentAuthKey; - -- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes mainTempAuthKey:(MTDatacenterAuthKey *)mainTempAuthKey mediaTempAuthKey:(MTDatacenterAuthKey *)mediaTempAuthKey; +- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes; - (int64_t)authSaltForMessageId:(int64_t)messageId; - (MTDatacenterAuthInfo *)mergeSaltSet:(NSArray *)updatedSaltSet forTimestamp:(NSTimeInterval)timestamp; - (MTDatacenterAuthInfo *)withUpdatedAuthKeyAttributes:(NSDictionary *)authKeyAttributes; -- (MTDatacenterAuthKey *)tempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type; -- (MTDatacenterAuthInfo *)withUpdatedTempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type key:(MTDatacenterAuthKey *)key; @end diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTMessageService.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTMessageService.h index 2b89f85ecf..d16a96bb73 100644 --- a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTMessageService.h +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTMessageService.h @@ -1,6 +1,7 @@ #import +#import @class MTProto; @class MTIncomingMessage; @@ -15,10 +16,10 @@ - (void)mtProtoDidAddService:(MTProto *)mtProto; - (void)mtProtoDidRemoveService:(MTProto *)mtProto; - (void)mtProtoPublicKeysUpdated:(MTProto *)mtProto datacenterId:(NSInteger)datacenterId publicKeys:(NSArray *)publicKeys; -- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto; +- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector; - (void)mtProtoDidChangeSession:(MTProto *)mtProto; - (void)mtProtoServerDidChangeSession:(MTProto *)mtProto firstValidMessageId:(int64_t)firstValidMessageId otherValidMessageIds:(NSArray *)otherValidMessageIds; -- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message; +- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector; - (void)mtProto:(MTProto *)mtProto receivedQuickAck:(int32_t)quickAckId; - (void)mtProto:(MTProto *)mtProto transactionsMayHaveFailed:(NSArray *)transactionIds; - (void)mtProtoAllTransactionsMayHaveFailed:(MTProto *)mtProto; diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoEngine.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoEngine.h new file mode 100644 index 0000000000..a5e507e8de --- /dev/null +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoEngine.h @@ -0,0 +1,13 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MTProtoEngine : NSObject + +- (instancetype)initWithPersistenceInterface:(id)persistenceInterface; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoInstance.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoInstance.h new file mode 100644 index 0000000000..91a58939e5 --- /dev/null +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoInstance.h @@ -0,0 +1,12 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MTProtoInstance : NSObject + +- (instancetype)initWithEngine:(MTProtoEngine *)engine; + +@end + +NS_ASSUME_NONNULL_END diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoPersistenceInterface.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoPersistenceInterface.h new file mode 100644 index 0000000000..ecabfee72f --- /dev/null +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTProtoPersistenceInterface.h @@ -0,0 +1,14 @@ +#import + +@class MTSignal; + +NS_ASSUME_NONNULL_BEGIN + +@protocol MTProtoPersistenceInterface + +- (MTSignal *)get:(NSData *)key; +- (void)set:(NSData *)key value:(NSData *)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/submodules/MtProtoKit/Sources/MTContext.m b/submodules/MtProtoKit/Sources/MTContext.m index 506a954d98..d9507e0923 100644 --- a/submodules/MtProtoKit/Sources/MTContext.m +++ b/submodules/MtProtoKit/Sources/MTContext.m @@ -114,6 +114,33 @@ @end +typedef int64_t MTDatacenterAuthInfoMapKey; + +typedef struct { + int32_t datacenterId; + MTDatacenterAuthInfoSelector selector; +} MTDatacenterAuthInfoMapKeyStruct; + +static MTDatacenterAuthInfoMapKey authInfoMapKey(int32_t datacenterId, MTDatacenterAuthInfoSelector selector) { + int64_t result = (((int64_t)(selector)) << 32) | ((int64_t)(datacenterId)); + return result; +} + +static NSNumber *authInfoMapIntegerKey(int32_t datacenterId, MTDatacenterAuthInfoSelector selector) { + return [NSNumber numberWithLongLong:authInfoMapKey(datacenterId, selector)]; +} + +static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKey(int64_t key) { + MTDatacenterAuthInfoMapKeyStruct result; + result.datacenterId = (int32_t)(key & 0x7fffffff); + result.selector = (int32_t)(((key >> 32) & 0x7fffffff)); + return result; +} + +static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKeyInteger(NSNumber *key) { + return parseAuthInfoMapKey([key longLongValue]); +} + @interface MTContext () { int64_t _uniqueId; @@ -127,7 +154,7 @@ NSMutableDictionary *> *_transportSchemeStats; MTTimer *_schemeStatsSyncTimer; - NSMutableDictionary *_datacenterAuthInfoById; + NSMutableDictionary *_datacenterAuthInfoById; NSMutableDictionary *_datacenterPublicKeysById; @@ -582,29 +609,35 @@ static int32_t fixedTimeDifferenceValue = 0; }]; } -- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo +- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector { [[MTContext contextQueue] dispatchOnQueue:^ { if (datacenterId != 0) { + NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector); + + if (authInfo != nil) { + _datacenterAuthInfoById[infoKey] = authInfo; + } else { + if (_datacenterAuthInfoById[infoKey] == nil) { + return; + } + [_datacenterAuthInfoById removeObjectForKey:infoKey]; + } + if (MTLogEnabled()) { MTLog(@"[MTContext#%x: auth info updated for %d to %@]", (int)self, datacenterId, authInfo); } - if (authInfo != nil) { - _datacenterAuthInfoById[@(datacenterId)] = authInfo; - } else { - [_datacenterAuthInfoById removeObjectForKey:@(datacenterId)]; - } [_keychain setObject:_datacenterAuthInfoById forKey:@"datacenterAuthInfoById" group:@"persistent"]; NSArray *currentListeners = [[NSArray alloc] initWithArray:_changeListeners]; for (id listener in currentListeners) { - if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:)]) - [listener contextDatacenterAuthInfoUpdated:self datacenterId:datacenterId authInfo:authInfo]; + if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:selector:)]) + [listener contextDatacenterAuthInfoUpdated:self datacenterId:datacenterId authInfo:authInfo selector:selector]; } } }]; @@ -864,10 +897,11 @@ static int32_t fixedTimeDifferenceValue = 0; return results; } -- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId { +- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId selector:(MTDatacenterAuthInfoSelector)selector { __block MTDatacenterAuthInfo *result = nil; [[MTContext contextQueue] dispatchOnQueue:^{ - result = _datacenterAuthInfoById[@(datacenterId)]; + NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector); + result = _datacenterAuthInfoById[infoKey]; } synchronous:true]; return result; @@ -1251,13 +1285,13 @@ static int32_t fixedTimeDifferenceValue = 0; }]; } -- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn +- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector { [[MTContext contextQueue] dispatchOnQueue:^ { if (_datacenterAuthActions[@(datacenterId)] == nil) { - MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:false tempAuthKeyType:MTDatacenterAuthTempKeyTypeMain bindKey:nil]; + MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:false authKeyInfoSelector:selector bindKey:nil]; authAction.delegate = self; _datacenterAuthActions[@(datacenterId)] = authAction; [authAction execute:self datacenterId:datacenterId isCdn:isCdn]; @@ -1265,17 +1299,6 @@ static int32_t fixedTimeDifferenceValue = 0; }]; } -- (void)tempAuthKeyForDatacenterWithIdRequired:(NSInteger)datacenterId keyType:(MTDatacenterAuthTempKeyType)keyType { - [[MTContext contextQueue] dispatchOnQueue:^{ - if (_datacenterTempAuthActions[@(datacenterId)] == nil) { - MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:true tempAuthKeyType:keyType bindKey:nil]; - authAction.delegate = self; - _datacenterTempAuthActions[@(datacenterId)] = authAction; - [authAction execute:self datacenterId:datacenterId isCdn:false]; - } - }]; -} - - (void)datacenterAuthActionCompleted:(MTDatacenterAuthAction *)action { [[MTContext contextQueue] dispatchOnQueue:^ @@ -1357,21 +1380,11 @@ static int32_t fixedTimeDifferenceValue = 0; - (void)updatePeriodicTasks { - [[MTContext contextQueue] dispatchOnQueue:^ - { - int64_t saltsRequiredAtLeastUntilMessageId = (int64_t)(([self globalTime] + 24 * 60.0 * 60.0) * 4294967296); - - [_datacenterAuthInfoById enumerateKeysAndObjectsUsingBlock:^(NSNumber *nDatacenterId, MTDatacenterAuthInfo *authInfo, __unused BOOL *stop) - { - if ([authInfo authSaltForMessageId:saltsRequiredAtLeastUntilMessageId == 0]) { - } - }]; - }]; } - (void)checkIfLoggedOut:(NSInteger)datacenterId { [[MTContext contextQueue] dispatchOnQueue:^{ - MTDatacenterAuthInfo *authInfo = [self authInfoForDatacenterWithId:datacenterId]; + MTDatacenterAuthInfo *authInfo = [self authInfoForDatacenterWithId:datacenterId selector:MTDatacenterAuthInfoSelectorPersistent]; if (authInfo == nil || authInfo.authKey == nil) { return; } @@ -1382,7 +1395,7 @@ static int32_t fixedTimeDifferenceValue = 0; _datacenterCheckKeyRemovedActionTimestamps[@(datacenterId)] = currentTimestamp; [_datacenterCheckKeyRemovedActions[@(datacenterId)] dispose]; __weak MTContext *weakSelf = self; - _datacenterCheckKeyRemovedActions[@(datacenterId)] = [[MTDiscoverConnectionSignals checkIfAuthKeyRemovedWithContext:self datacenterId:datacenterId authKey:authInfo.authKey] startWithNext:^(NSNumber *isRemoved) { + _datacenterCheckKeyRemovedActions[@(datacenterId)] = [[MTDiscoverConnectionSignals checkIfAuthKeyRemovedWithContext:self datacenterId:datacenterId authKey:[[MTDatacenterAuthKey alloc] initWithAuthKey:authInfo.authKey authKeyId:authInfo.authKeyId notBound:false]] startWithNext:^(NSNumber *isRemoved) { [[MTContext contextQueue] dispatchOnQueue:^{ __strong MTContext *strongSelf = weakSelf; if (strongSelf == nil) { diff --git a/submodules/MtProtoKit/Sources/MTDatacenterAuthAction.m b/submodules/MtProtoKit/Sources/MTDatacenterAuthAction.m index 3896afcd51..9ca4736340 100644 --- a/submodules/MtProtoKit/Sources/MTDatacenterAuthAction.m +++ b/submodules/MtProtoKit/Sources/MTDatacenterAuthAction.m @@ -17,7 +17,7 @@ @interface MTDatacenterAuthAction () { bool _isCdn; - MTDatacenterAuthTempKeyType _tempAuthKeyType; + MTDatacenterAuthInfoSelector _authKeyInfoSelector; MTDatacenterAuthKey *_bindKey; NSInteger _datacenterId; @@ -34,11 +34,11 @@ @implementation MTDatacenterAuthAction -- (instancetype)initWithTempAuth:(bool)tempAuth tempAuthKeyType:(MTDatacenterAuthTempKeyType)tempAuthKeyType bindKey:(MTDatacenterAuthKey *)bindKey { +- (instancetype)initWithTempAuth:(bool)tempAuth authKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector bindKey:(MTDatacenterAuthKey *)bindKey { self = [super init]; if (self != nil) { _tempAuth = tempAuth; - _tempAuthKeyType = tempAuthKeyType; + _authKeyInfoSelector = authKeyInfoSelector; _bindKey = bindKey; _verifyDisposable = [[MTMetaDisposable alloc] init]; } @@ -59,15 +59,10 @@ if (_datacenterId != 0 && context != nil) { bool alreadyCompleted = false; - MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId]; + + MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector]; if (currentAuthInfo != nil && _bindKey == nil) { - if (_tempAuth) { - if ([currentAuthInfo tempAuthKeyWithType:_tempAuthKeyType] != nil) { - alreadyCompleted = true; - } - } else { - alreadyCompleted = true; - } + alreadyCompleted = true; } if (alreadyCompleted) { @@ -77,11 +72,11 @@ _authMtProto.cdn = isCdn; _authMtProto.useUnauthorizedMode = true; if (_tempAuth) { - switch (_tempAuthKeyType) { - case MTDatacenterAuthTempKeyTypeMain: + switch (_authKeyInfoSelector) { + case MTDatacenterAuthInfoSelectorEphemeralMain: _authMtProto.media = false; break; - case MTDatacenterAuthTempKeyTypeMedia: + case MTDatacenterAuthInfoSelectorEphemeralMedia: _authMtProto.media = true; _authMtProto.enforceMedia = true; break; @@ -128,20 +123,19 @@ } else { MTContext *context = _context; [context performBatchUpdates:^{ - MTDatacenterAuthInfo *authInfo = [context authInfoForDatacenterWithId:_datacenterId]; + MTDatacenterAuthInfo *authInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector]; if (authInfo != nil) { - authInfo = [authInfo withUpdatedTempAuthKeyWithType:_tempAuthKeyType key:authKey]; - [context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo]; + [context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector]; } }]; [self complete]; } } } else { - MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil mainTempAuthKey:nil mediaTempAuthKey:nil]; + MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil]; MTContext *context = _context; - [context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo]; + [context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector]; [self complete]; } } diff --git a/submodules/MtProtoKit/Sources/MTDatacenterAuthInfo.m b/submodules/MtProtoKit/Sources/MTDatacenterAuthInfo.m index f9959626a9..d6b783dfcd 100644 --- a/submodules/MtProtoKit/Sources/MTDatacenterAuthInfo.m +++ b/submodules/MtProtoKit/Sources/MTDatacenterAuthInfo.m @@ -27,7 +27,7 @@ @implementation MTDatacenterAuthInfo -- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes mainTempAuthKey:(MTDatacenterAuthKey *)mainTempAuthKey mediaTempAuthKey:(MTDatacenterAuthKey *)mediaTempAuthKey +- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes { self = [super init]; if (self != nil) @@ -36,8 +36,6 @@ _authKeyId = authKeyId; _saltSet = saltSet; _authKeyAttributes = authKeyAttributes; - _mainTempAuthKey = mainTempAuthKey; - _mediaTempAuthKey = mediaTempAuthKey; } return self; } @@ -51,8 +49,6 @@ _authKeyId = [aDecoder decodeInt64ForKey:@"authKeyId"]; _saltSet = [aDecoder decodeObjectForKey:@"saltSet"]; _authKeyAttributes = [aDecoder decodeObjectForKey:@"authKeyAttributes"]; - _mainTempAuthKey = [aDecoder decodeObjectForKey:@"tempAuthKey"]; - _mediaTempAuthKey = [aDecoder decodeObjectForKey:@"mediaTempAuthKey"]; } return self; } @@ -63,8 +59,6 @@ [aCoder encodeInt64:_authKeyId forKey:@"authKeyId"]; [aCoder encodeObject:_saltSet forKey:@"saltSet"]; [aCoder encodeObject:_authKeyAttributes forKey:@"authKeyAttributes"]; - [aCoder encodeObject:_mainTempAuthKey forKey:@"tempAuthKey"]; - [aCoder encodeObject:_mediaTempAuthKey forKey:@"mediaTempAuthKey"]; } - (int64_t)authSaltForMessageId:(int64_t)messageId @@ -113,35 +107,11 @@ } } - return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:mergedSaltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:_mediaTempAuthKey]; + return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:mergedSaltSet authKeyAttributes:_authKeyAttributes]; } - (MTDatacenterAuthInfo *)withUpdatedAuthKeyAttributes:(NSDictionary *)authKeyAttributes { - return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:_mediaTempAuthKey]; -} - -- (MTDatacenterAuthKey *)tempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type { - switch (type) { - case MTDatacenterAuthTempKeyTypeMain: - return _mainTempAuthKey; - case MTDatacenterAuthTempKeyTypeMedia: - return _mediaTempAuthKey; - default: - NSAssert(false, @"unknown MTDatacenterAuthTempKeyType"); - return nil; - } -} - -- (MTDatacenterAuthInfo *)withUpdatedTempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type key:(MTDatacenterAuthKey *)key { - switch (type) { - case MTDatacenterAuthTempKeyTypeMain: - return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:key mediaTempAuthKey:_mediaTempAuthKey]; - case MTDatacenterAuthTempKeyTypeMedia: - return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:key]; - default: - NSAssert(false, @"unknown MTDatacenterAuthTempKeyType"); - return self; - } + return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:authKeyAttributes]; } - (MTDatacenterAuthKey *)persistentAuthKey { diff --git a/submodules/MtProtoKit/Sources/MTDatacenterAuthMessageService.m b/submodules/MtProtoKit/Sources/MTDatacenterAuthMessageService.m index a72758f2a0..01f4e320d5 100644 --- a/submodules/MtProtoKit/Sources/MTDatacenterAuthMessageService.m +++ b/submodules/MtProtoKit/Sources/MTDatacenterAuthMessageService.m @@ -222,7 +222,7 @@ typedef enum { } } -- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto +- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if (_currentStageTransactionId == nil) { @@ -308,7 +308,7 @@ typedef enum { return nil; } -- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message +- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if (_stage == MTDatacenterAuthStagePQ && [message.body isKindOfClass:[MTResPqMessage class]]) { diff --git a/submodules/MtProtoKit/Sources/MTDiscoverConnectionSignals.m b/submodules/MtProtoKit/Sources/MTDiscoverConnectionSignals.m index 6ad6cc0976..d4446e9204 100644 --- a/submodules/MtProtoKit/Sources/MTDiscoverConnectionSignals.m +++ b/submodules/MtProtoKit/Sources/MTDiscoverConnectionSignals.m @@ -249,7 +249,7 @@ MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init]; [[MTContext contextQueue] dispatchOnQueue:^{ - MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithTempAuth:true tempAuthKeyType:MTDatacenterAuthTempKeyTypeMain bindKey:authKey]; + MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithTempAuth:true authKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain bindKey:authKey]; action.completedWithResult = ^(bool success) { [subscriber putNext:@(!success)]; [subscriber putCompletion]; diff --git a/submodules/MtProtoKit/Sources/MTDiscoverDatacenterAddressAction.m b/submodules/MtProtoKit/Sources/MTDiscoverDatacenterAddressAction.m index 940d8eb942..bfd5b5292d 100644 --- a/submodules/MtProtoKit/Sources/MTDiscoverDatacenterAddressAction.m +++ b/submodules/MtProtoKit/Sources/MTDiscoverDatacenterAddressAction.m @@ -88,7 +88,7 @@ [self fail]; else { - if ([context authInfoForDatacenterWithId:_targetDatacenterId] != nil) + if ([context authInfoForDatacenterWithId:_targetDatacenterId selector:MTDatacenterAuthInfoSelectorPersistent] != nil) { _mtProto = [[MTProto alloc] initWithContext:context datacenterId:_targetDatacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0]; _mtProto.useTempAuthKeys = useTempAuthKeys; @@ -118,11 +118,11 @@ [_requestService addRequest:request]; } else - [context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false]; + [context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent]; } } -- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)__unused authInfo +- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)__unused authInfo selector:(MTDatacenterAuthInfoSelector)selector { if (_context != context || !_awaitingAddresSetUpdate) return; diff --git a/submodules/MtProtoKit/Sources/MTProto.m b/submodules/MtProtoKit/Sources/MTProto.m index 7c96b4930f..7aa4bf30dd 100644 --- a/submodules/MtProtoKit/Sources/MTProto.m +++ b/submodules/MtProtoKit/Sources/MTProto.m @@ -14,7 +14,6 @@ #import #import #import -#import "MTBindingTempAuthKeyContext.h" #import #import @@ -58,13 +57,11 @@ typedef enum { MTProtoStateAwaitingDatacenterScheme = 1, MTProtoStateAwaitingDatacenterAuthorization = 2, - MTProtoStateAwaitingDatacenterTempAuthKey = 4, MTProtoStateAwaitingDatacenterAuthToken = 8, MTProtoStateAwaitingTimeFixAndSalts = 16, MTProtoStateAwaitingLostMessages = 32, MTProtoStateStopped = 64, - MTProtoStatePaused = 128, - MTProtoStateBindingTempAuthKey = 256 + MTProtoStatePaused = 128 } MTProtoState; static const NSUInteger MTMaxContainerSize = 3 * 1024; @@ -85,17 +82,36 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; @end +@interface MTProtoValidAuthInfo : NSObject + +@property (nonatomic, strong, readonly) MTDatacenterAuthInfo *authInfo; +@property (nonatomic, readonly) MTDatacenterAuthInfoSelector selector; + +@end + +@implementation MTProtoValidAuthInfo + +- (instancetype)initWithAuthInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector { + self = [super init]; + if (self != nil) { + _authInfo = authInfo; + _selector = selector; + } + return self; +} + +@end + @interface MTProto () { NSMutableArray *_messageServices; - MTDatacenterAuthInfo *_authInfo; + MTProtoValidAuthInfo *_validAuthInfo; + NSNumber *_awaitingAuthInfoForSelector; + MTSessionInfo *_sessionInfo; MTTimeFixContext *_timeFixContext; - int64_t _bindingTempAuthKeyId; - MTBindingTempAuthKeyContext *_bindingTempAuthKeyContext; - MTTransport *_transport; int _mtState; @@ -149,7 +165,8 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; _messageServices = [[NSMutableArray alloc] init]; _sessionInfo = [[MTSessionInfo alloc] initWithRandomSessionIdAndContext:_context]; - _authInfo = [_context authInfoForDatacenterWithId:_datacenterId]; + + _shouldStayConnected = true; } @@ -170,15 +187,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; }]; } -- (void)setUseExplicitAuthKey:(MTDatacenterAuthKey *)useExplicitAuthKey { - _useExplicitAuthKey = useExplicitAuthKey; - if (_useExplicitAuthKey != nil) { - _authInfo = [_authInfo withUpdatedTempAuthKeyWithType:MTDatacenterAuthTempKeyTypeMain key:useExplicitAuthKey]; - [self setMtState:_mtState | MTProtoStateBindingTempAuthKey]; - [self requestTransportTransaction]; - } -} - - (void)setUsageCalculationInfo:(MTNetworkUsageCalculationInfo *)usageCalculationInfo { [[MTProto managerQueue] dispatchOnQueue:^{ _usageCalculationInfo = usageCalculationInfo; @@ -278,7 +286,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; }]; _timeFixContext = nil; - _bindingTempAuthKeyContext = nil; if (_transport != nil) [self removeMessageService:_transport]; @@ -286,20 +293,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; _transport = transport; [previousTransport stop]; - if (_transport != nil && _useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - /*if (_transport.scheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - }*/ - - MTDatacenterAuthKey *effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - if (effectiveAuthKey == nil) { - if (MTLogEnabled()) { - MTLog(@"[MTProto#%p setTransport temp auth key missing]", self); - } - } - } - if (_transport != nil) [self addMessageService:_transport]; @@ -323,38 +316,13 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; NSArray *transportSchemes = [_context transportSchemesForDatacenterWithId:_datacenterId media:_media enforceMedia:_enforceMedia isProxy:_apiEnvironment.socksProxySettings != nil]; - /*MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (_transportScheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - }*/ - if (transportSchemes.count == 0) { if ((_mtState & MTProtoStateAwaitingDatacenterScheme) == 0) { [self setMtState:_mtState | MTProtoStateAwaitingDatacenterScheme]; [_context transportSchemeForDatacenterWithIdRequired:_datacenterId media:_media]; } - } else if (!_useUnauthorizedMode && [_context authInfoForDatacenterWithId:_datacenterId] == nil) { - if (MTLogEnabled()) { - MTLog(@"[MTProto#%p@%p authInfoForDatacenterWithId:%d is nil]", self, _context, _datacenterId); - } - MTShortLog(@"[MTProto#%p@%p authInfoForDatacenterWithId:%d is nil]", self, _context, _datacenterId); - if ((_mtState & MTProtoStateAwaitingDatacenterAuthorization) == 0) { - [self setMtState:_mtState | MTProtoStateAwaitingDatacenterAuthorization]; - - if (MTLogEnabled()) { - MTLog(@"[MTProto#%p@%p requesting authInfo for %d]", self, _context, _datacenterId); - } - MTShortLog(@"[MTProto#%p@%p requesting authInfo for %d]", self, _context, _datacenterId); - [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn]; - } - }/* else if (!_useUnauthorizedMode && _useTempAuthKeys && [[_context authInfoForDatacenterWithId:_datacenterId] tempAuthKeyWithType:tempAuthKeyType] == nil) { - if ((_mtState & MTProtoStateAwaitingDatacenterTempAuthKey) == 0) { - [self setMtState:_mtState | MTProtoStateAwaitingDatacenterTempAuthKey]; - - [_context tempAuthKeyForDatacenterWithIdRequired:_datacenterId keyType:tempAuthKeyType]; - } - }*/ + } else if (_requiredAuthToken != nil && !_useUnauthorizedMode && ![_requiredAuthToken isEqual:[_context authTokenForDatacenterWithId:_datacenterId]]) { if ((_mtState & MTProtoStateAwaitingDatacenterAuthToken) == 0) { [self setMtState:_mtState | MTProtoStateAwaitingDatacenterAuthToken]; @@ -366,8 +334,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; MTTransport *transport = [[MTTcpTransport alloc] initWithDelegate:self context:_context datacenterId:_datacenterId schemes:transportSchemes proxySettings:_context.apiEnvironment.socksProxySettings usageCalculationInfo:_usageCalculationInfo]; [self setTransport:transport]; - - //[self checkTempAuthKeyBinding:transport.scheme.address]; } }]; } @@ -381,13 +347,8 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; } MTShortLog(@"[MTProto#%p@%p resetting session]", self, _context); - if (_authInfo.authKeyId != 0 && !self.cdn) { - [_context scheduleSessionCleanupForAuthKeyId:_authInfo.authKeyId sessionInfo:_sessionInfo]; - } - _sessionInfo = [[MTSessionInfo alloc] initWithRandomSessionIdAndContext:_context]; _timeFixContext = nil; - _bindingTempAuthKeyContext = nil; for (NSInteger i = (NSInteger)_messageServices.count - 1; i >= 0; i--) { @@ -402,11 +363,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; } - (void)finalizeSession { - [[MTProto managerQueue] dispatchOnQueue:^{ - if (_authInfo.authKeyId != 0 && !self.cdn) { - [_context scheduleSessionCleanupForAuthKeyId:_authInfo.authKeyId sessionInfo:_sessionInfo]; - } - }]; } - (void)requestTimeResync @@ -695,12 +651,12 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; - (bool)canAskForTransactions { - return (_mtState & (MTProtoStateAwaitingDatacenterScheme | MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterTempAuthKey | MTProtoStateAwaitingDatacenterAuthToken | MTProtoStateAwaitingTimeFixAndSalts | MTProtoStateBindingTempAuthKey | MTProtoStateStopped)) == 0; + return (_mtState & (MTProtoStateAwaitingDatacenterScheme | MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterAuthToken | MTProtoStateAwaitingTimeFixAndSalts | MTProtoStateStopped)) == 0; } - (bool)canAskForServiceTransactions { - return (_mtState & (MTProtoStateAwaitingDatacenterScheme | MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterTempAuthKey | MTProtoStateAwaitingDatacenterAuthToken | MTProtoStateStopped)) == 0; + return (_mtState & (MTProtoStateAwaitingDatacenterScheme | MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterAuthToken | MTProtoStateStopped)) == 0; } - (bool)timeFixOrSaltsMissing @@ -708,11 +664,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; return _mtState & MTProtoStateAwaitingTimeFixAndSalts; } -- (bool)bindingTempAuthKey -{ - return _mtState & MTProtoStateBindingTempAuthKey; -} - - (bool)isStopped { return (_mtState & MTProtoStateStopped) != 0; @@ -876,6 +827,47 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; return [[NSString alloc] initWithFormat:@"%@ (%" PRId64", %" PRId64"/%" PRId64")", message.body, message.messageId, message.authKeyId, message.sessionId]; } +- (MTDatacenterAuthKey *)getAuthKeyForCurrentScheme:(MTTransportScheme *)scheme createIfNeeded:(bool)createIfNeeded authInfoSelector:(MTDatacenterAuthInfoSelector *)authInfoSelector { + MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorPersistent; + + if (_cdn) { + selector = MTDatacenterAuthInfoSelectorPersistent; + } else { + if (_useTempAuthKeys) { + if (scheme.address.preferForMedia) { + selector = MTDatacenterAuthInfoSelectorEphemeralMedia; + } else { + selector = MTDatacenterAuthInfoSelectorEphemeralMain; + } + } else { + selector = MTDatacenterAuthInfoSelectorPersistent; + } + } + + if (authInfoSelector != nil) { + *authInfoSelector = selector; + } + + if (_validAuthInfo != nil && _validAuthInfo.selector == selector) { + return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false]; + } else { + MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:selector]; + if (authInfo != nil) { + _validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector]; + return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false]; + } else { + [_context performBatchUpdates:^{ + [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:selector]; + [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector]; + }]; + _mtState |= MTProtoStateAwaitingDatacenterAuthorization; + _awaitingAuthInfoForSelector = @(selector); + + return nil; + } + } +} + - (void)transportReadyForTransaction:(MTTransport *)transport scheme:(MTTransportScheme *)scheme transportSpecificTransaction:(MTMessageTransaction *)transportSpecificTransaction forceConfirmations:(bool)forceConfirmations transactionReady:(void (^)(NSArray *))transactionReady { [[MTProto managerQueue] dispatchOnQueue:^ @@ -887,6 +879,19 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; return; } + MTDatacenterAuthKey *authKey = nil; + MTDatacenterAuthInfoSelector authInfoSelector = MTDatacenterAuthInfoSelectorPersistent; + if (!_useUnauthorizedMode) { + authKey = [self getAuthKeyForCurrentScheme:scheme createIfNeeded:true authInfoSelector:&authInfoSelector]; + + if (authKey == nil) { + if (transactionReady) { + transactionReady(nil); + } + return; + } + } + bool extendedPadding = false; if (transport.proxySettings != nil && transport.proxySettings.secret != nil) { MTProxySecret *parsedSecret = [MTProxySecret parseData:transport.proxySettings.secret]; @@ -908,7 +913,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; if (transportSpecificTransaction != nil) { - if (!(transportSpecificTransaction.requiresEncryption && _useUnauthorizedMode) && (!transportSpecificTransaction.requiresEncryption || _authInfo != nil)) + if (!(transportSpecificTransaction.requiresEncryption && _useUnauthorizedMode) && (!transportSpecificTransaction.requiresEncryption || authKey != nil)) { [messageTransactions addObject:transportSpecificTransaction]; } @@ -919,9 +924,9 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; NSMutableArray *messageServiceTransactions = [[NSMutableArray alloc] init]; for (id messageService in _messageServices) { - if ([messageService respondsToSelector:@selector(mtProtoMessageTransaction:)]) + if ([messageService respondsToSelector:@selector(mtProtoMessageTransaction:authInfoSelector:)]) { - MTMessageTransaction *messageTransaction = [messageService mtProtoMessageTransaction:self]; + MTMessageTransaction *messageTransaction = [messageService mtProtoMessageTransaction:self authInfoSelector:authInfoSelector]; if (messageTransaction != nil) { for (MTOutgoingMessage *message in messageTransaction.messagePayload) @@ -977,7 +982,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; int64_t messageSalt = 0; if (!_useUnauthorizedMode) { - messageSalt = [_authInfo authSaltForMessageId:[transactionSessionInfo actualClientMessagId]]; + messageSalt = [_validAuthInfo.authInfo authSaltForMessageId:[transactionSessionInfo actualClientMessagId]]; if (messageSalt == 0) saltSetEmpty = true; } @@ -1156,7 +1161,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; if (currentContainerMessages.count == 1) { int32_t quickAckId = 0; - NSData *messageData = [self _dataForEncryptedMessage:currentContainerMessages[0] sessionInfo:transactionSessionInfo quickAckId:&quickAckId address:scheme.address extendedPadding:extendedPadding]; + NSData *messageData = [self _dataForEncryptedMessage:currentContainerMessages[0] authKey:authKey sessionInfo:transactionSessionInfo quickAckId:&quickAckId address:scheme.address extendedPadding:extendedPadding]; if (messageData != nil) { [transactionPayloadList addObject:messageData]; @@ -1167,7 +1172,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; else if (currentContainerMessages.count != 0) { int32_t quickAckId = 0; - NSData *containerData = [self _dataForEncryptedContainerWithMessages:currentContainerMessages sessionInfo:transactionSessionInfo quickAckId:&quickAckId address:scheme.address extendedPadding:extendedPadding]; + NSData *containerData = [self _dataForEncryptedContainerWithMessages:currentContainerMessages authKey:authKey sessionInfo:transactionSessionInfo quickAckId:&quickAckId address:scheme.address extendedPadding:extendedPadding]; if (containerData != nil) { [transactionPayloadList addObject:containerData]; @@ -1309,7 +1314,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; } MTShortLog(@"[MTProto#%p@%p sending time fix ping (%" PRId64 "/%" PRId32 ", %" PRId64 ")]", self, _context, timeFixMessageId, timeFixSeqNo, _sessionInfo.sessionId); - [decryptedOs writeInt64:[_authInfo authSaltForMessageId:timeFixMessageId]]; // salt + [decryptedOs writeInt64:[_validAuthInfo.authInfo authSaltForMessageId:timeFixMessageId]]; // salt [decryptedOs writeInt64:_sessionInfo.sessionId]; [decryptedOs writeInt64:timeFixMessageId]; [decryptedOs writeInt32:timeFixSeqNo]; @@ -1319,18 +1324,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; NSData *decryptedData = [self paddedData:[decryptedOs currentBytes] extendedPadding:extendedPadding]; - MTDatacenterAuthKey *effectiveAuthKey; - if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (scheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - NSAssert(effectiveAuthKey != nil, @"effectiveAuthKey == nil"); - } else { - effectiveAuthKey = [[MTDatacenterAuthKey alloc] initWithAuthKey:_authInfo.authKey authKeyId:_authInfo.authKeyId notBound:false]; - } + MTDatacenterAuthKey *effectiveAuthKey = authKey; int xValue = 0; NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init]; @@ -1384,115 +1378,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; transactionReady(nil); } } - else if (![self timeFixOrSaltsMissing] && [self bindingTempAuthKey] && [self canAskForServiceTransactions] && (_bindingTempAuthKeyContext == nil || _bindingTempAuthKeyContext.transactionId == nil)) - { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (scheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - MTDatacenterAuthKey *effectiveTempAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - NSAssert(effectiveTempAuthKey != nil, @"effectiveAuthKey == nil"); - - int64_t bindingMessageId = [_sessionInfo generateClientMessageId:NULL]; - int32_t bindingSeqNo = [_sessionInfo takeSeqNo:true]; - - int32_t expiresAt = (int32_t)([_context globalTime] + 60 * 60 * 32); - - int64_t randomId = 0; - arc4random_buf(&randomId, 8); - - int64_t nonce = 0; - arc4random_buf(&nonce, 8); - - MTBuffer *decryptedMessage = [[MTBuffer alloc] init]; - //bind_auth_key_inner#75a3f765 nonce:long temp_auth_key_id:long perm_auth_key_id:long temp_session_id:long expires_at:int = BindAuthKeyInner; - [decryptedMessage appendInt32:(int32_t)0x75a3f765]; - [decryptedMessage appendInt64:nonce]; - [decryptedMessage appendInt64:effectiveTempAuthKey.authKeyId]; - [decryptedMessage appendInt64:_authInfo.authKeyId]; - [decryptedMessage appendInt64:_sessionInfo.sessionId]; - [decryptedMessage appendInt32:expiresAt]; - - NSData *encryptedMessage = [self _manuallyEncryptedMessage:[decryptedMessage data] messageId:bindingMessageId authKey:_authInfo.persistentAuthKey]; - - MTBuffer *bindRequestData = [[MTBuffer alloc] init]; - - //auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool; - - [bindRequestData appendInt32:(int32_t)0xcdd42a05]; - [bindRequestData appendInt64:_authInfo.persistentAuthKey.authKeyId]; - [bindRequestData appendInt64:nonce]; - [bindRequestData appendInt32:expiresAt]; - [bindRequestData appendTLBytes:encryptedMessage]; - - NSData *messageData = bindRequestData.data; - - MTOutputStream *decryptedOs = [[MTOutputStream alloc] init]; - - if (MTLogEnabled()) { - MTLog(@"[MTProto#%p@%p sending temp key binding message (%" PRId64 "/%" PRId32 ") for %lld (%d)]", self, _context, bindingMessageId, bindingSeqNo, effectiveTempAuthKey.authKeyId, (int)tempAuthKeyType); - } - MTShortLog(@"[MTProto#%p@%p sending temp key binding message (%" PRId64 "/%" PRId32 ") for %lld (%d)]", self, _context, bindingMessageId, bindingSeqNo, effectiveTempAuthKey.authKeyId, (int)tempAuthKeyType); - - [decryptedOs writeInt64:[_authInfo authSaltForMessageId:bindingMessageId]]; - [decryptedOs writeInt64:_sessionInfo.sessionId]; - [decryptedOs writeInt64:bindingMessageId]; - [decryptedOs writeInt32:bindingSeqNo]; - - [decryptedOs writeInt32:(int32_t)messageData.length]; - [decryptedOs writeData:messageData]; - - NSData *decryptedData = [self paddedData:[decryptedOs currentBytes] extendedPadding:extendedPadding]; - - int xValue = 0; - NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init]; - [msgKeyLargeData appendBytes:effectiveTempAuthKey.authKey.bytes + 88 + xValue length:32]; - [msgKeyLargeData appendData:decryptedData]; - - NSData *msgKeyLarge = MTSha256(msgKeyLargeData); - NSData *messageKey = [msgKeyLarge subdataWithRange:NSMakeRange(8, 16)]; - MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:effectiveTempAuthKey.authKey messageKey:messageKey toClient:false]; - - NSData *transactionData = nil; - - if (encryptionKey != nil) - { - NSMutableData *encryptedData = [[NSMutableData alloc] initWithCapacity:14 + decryptedData.length]; - [encryptedData appendData:decryptedData]; - MTAesEncryptInplace(encryptedData, encryptionKey.key, encryptionKey.iv); - - int64_t authKeyId = effectiveTempAuthKey.authKeyId; - [encryptedData replaceBytesInRange:NSMakeRange(0, 0) withBytes:&authKeyId length:8]; - [encryptedData replaceBytesInRange:NSMakeRange(8, 0) withBytes:messageKey.bytes length:messageKey.length]; - - transactionData = encryptedData; - } - - if (transactionReady != nil) - { - if (transactionData != nil) - { - __weak MTProto *weakSelf = self; - transactionReady(@[[[MTTransportTransaction alloc] initWithPayload:transactionData completion:^(bool success, id transactionId) { - [[MTProto managerQueue] dispatchOnQueue:^{ - if (success) { - if (transactionId != nil) { - _bindingTempAuthKeyContext = [[MTBindingTempAuthKeyContext alloc] initWithMessageId:bindingMessageId messageSeqNo:bindingSeqNo transactionId:transactionId]; - } - } - else - { - __strong MTProto *strongSelf = weakSelf; - [strongSelf requestTransportTransaction]; - } - }]; - } needsQuickAck:false expectsDataInResponse:true]]); - } - else - transactionReady(nil); - } - } else if (transactionReady != nil) transactionReady(nil); @@ -1503,19 +1388,8 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; }]; } -- (NSData *)_dataForEncryptedContainerWithMessages:(NSArray *)preparedMessages sessionInfo:(MTSessionInfo *)sessionInfo quickAckId:(int32_t *)quickAckId address:(MTDatacenterAddress *)address extendedPadding:(bool)extendedPadding { - MTDatacenterAuthKey *effectiveAuthKey; - if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - - NSAssert(effectiveAuthKey != nil, @"effectiveAuthKey == nil"); - } else { - effectiveAuthKey = [[MTDatacenterAuthKey alloc] initWithAuthKey:_authInfo.authKey authKeyId:_authInfo.authKeyId notBound:false]; - } +- (NSData *)_dataForEncryptedContainerWithMessages:(NSArray *)preparedMessages authKey:(MTDatacenterAuthKey *)authKey sessionInfo:(MTSessionInfo *)sessionInfo quickAckId:(int32_t *)quickAckId address:(MTDatacenterAddress *)address extendedPadding:(bool)extendedPadding { + MTDatacenterAuthKey *effectiveAuthKey = authKey; NSMutableArray *containerMessageIds = [[NSMutableArray alloc] init]; @@ -1708,19 +1582,10 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; return nil; } -- (NSData *)_dataForEncryptedMessage:(MTPreparedMessage *)preparedMessage sessionInfo:(MTSessionInfo *)sessionInfo quickAckId:(int32_t *)quickAckId address:(MTDatacenterAddress *)address extendedPadding:(bool)extendedPadding +- (NSData *)_dataForEncryptedMessage:(MTPreparedMessage *)preparedMessage authKey:(MTDatacenterAuthKey *)authKey sessionInfo:(MTSessionInfo *)sessionInfo quickAckId:(int32_t *)quickAckId address:(MTDatacenterAddress *)address extendedPadding:(bool)extendedPadding { - MTDatacenterAuthKey *effectiveAuthKey; - if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - NSAssert(effectiveAuthKey != nil, @"effectiveAuthKey == nil"); - } else { - effectiveAuthKey = [[MTDatacenterAuthKey alloc] initWithAuthKey:_authInfo.authKey authKeyId:_authInfo.authKeyId notBound:false]; - } + MTDatacenterAuthKey *effectiveAuthKey = authKey; + NSAssert(effectiveAuthKey != nil, @"effectiveAuthKey == nil"); MTOutputStream *decryptedOs = [[MTOutputStream alloc] init]; @@ -1774,12 +1639,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; requestTransaction = true; } - if (_bindingTempAuthKeyContext != nil && _bindingTempAuthKeyContext.transactionId != nil && [transactionIds containsObject:_bindingTempAuthKeyContext.transactionId]) - { - _bindingTempAuthKeyContext = nil; - requestTransaction = true; - } - for (NSInteger i = (NSInteger)_messageServices.count - 1; i >= 0; i--) { id messageService = _messageServices[(NSUInteger)i]; @@ -1806,12 +1665,6 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; requestTransaction = true; } - if (_bindingTempAuthKeyContext != nil && _bindingTempAuthKeyContext.transactionId != nil) - { - _bindingTempAuthKeyContext = nil; - requestTransaction = true; - } - for (NSInteger i = (NSInteger)_messageServices.count - 1; i >= 0; i--) { id messageService = _messageServices[(NSUInteger)i]; @@ -1848,24 +1701,18 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; if (transport != _transport || completion == nil) return; - MTDatacenterAuthKey *effectiveAuthKey; - if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (scheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - NSAssert(effectiveAuthKey != nil, @"effectiveAuthKey == nil"); - } else { - effectiveAuthKey = [[MTDatacenterAuthKey alloc] initWithAuthKey:_authInfo.authKey authKeyId:_authInfo.authKeyId notBound:false]; + MTDatacenterAuthKey *authKey = [self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:nil]; + if (authKey == nil) { + return; } + MTDatacenterAuthKey *effectiveAuthKey = authKey; + MTInputStream *is = [[MTInputStream alloc] initWithData:data]; int64_t keyId = [is readInt64]; - if (keyId != 0 && _authInfo != nil) + if (keyId == authKey.authKeyId) { NSData *messageKey = [is readData:16]; @@ -2070,7 +1917,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { } if (protocolErrorCode == -404) { - [self handleMissingKey:scheme.address]; + [self handleMissingKey:scheme]; } if (currentTransport == _transport) @@ -2081,10 +1928,17 @@ static NSString *dumpHexString(NSData *data, int maxLength) { NSData *decryptedData = nil; - if (_useUnauthorizedMode) + int64_t embeddedAuthKeyId = 0; + MTDatacenterAuthInfoSelector authInfoSelector = MTDatacenterAuthInfoSelectorPersistent; + if (_useUnauthorizedMode) { decryptedData = data; - else - decryptedData = [self _decryptIncomingTransportData:data address:scheme.address]; + } else { + MTDatacenterAuthKey *authKey = [self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:&authInfoSelector]; + if (authKey != nil) { + embeddedAuthKeyId = authKey.authKeyId; + decryptedData = [self _decryptIncomingTransportData:data address:scheme.address authKey:authKey]; + } + } if (decryptedData != nil) { @@ -2093,9 +1947,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { int64_t dataMessageId = 0; bool parseError = false; - NSArray *parsedMessages = [self _parseIncomingMessages:decryptedData dataMessageId:&dataMessageId parseError:&parseError]; - - + NSArray *parsedMessages = [self _parseIncomingMessages:decryptedData dataMessageId:&dataMessageId embeddedAuthKeyId:embeddedAuthKeyId parseError:&parseError]; for (MTIncomingMessage *message in parsedMessages) { if ([message.body isKindOfClass:[MTRpcResultMessage class]]) { @@ -2108,7 +1960,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { MTLog(@"[MTProto#%p@%p received AUTH_KEY_PERM_EMPTY]", self, _context); } MTShortLog(@"[MTProto#%p@%p received AUTH_KEY_PERM_EMPTY]", self, _context); - [self handleMissingKey:scheme.address]; + [self handleMissingKey:scheme]; [self requestSecureTransportReset]; return; @@ -2132,7 +1984,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { for (MTIncomingMessage *incomingMessage in parsedMessages) { - [self _processIncomingMessage:incomingMessage totalSize:(int)data.length withTransactionId:transactionId address:scheme.address]; + [self _processIncomingMessage:incomingMessage totalSize:(int)data.length withTransactionId:transactionId address:scheme.address authInfoSelector:authInfoSelector]; } if (requestTransactionAfterProcessing) @@ -2155,71 +2007,54 @@ static NSString *dumpHexString(NSData *data, int maxLength) { }]; } -- (void)handleMissingKey:(MTDatacenterAddress *)address { +- (void)handleMissingKey:(MTTransportScheme *)scheme { NSAssert([[MTProto managerQueue] isCurrentQueue], @"invalid queue"); + MTDatacenterAuthInfoSelector authInfoSelector; + [self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:&authInfoSelector]; + if (_useExplicitAuthKey != nil) { } else if (_cdn) { - _authInfo = nil; + _validAuthInfo = nil; + [_context performBatchUpdates:^{ - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil]; - [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:true]; + [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector]; + [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:true selector:authInfoSelector]; }]; _mtState |= MTProtoStateAwaitingDatacenterAuthorization; - } else if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - MTDatacenterAuthKey *currentTempAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - - _authInfo = [_authInfo withUpdatedTempAuthKeyWithType:tempAuthKeyType key:nil]; - _mtState |= MTProtoStateAwaitingDatacenterTempAuthKey; - - [_context performBatchUpdates:^{ - MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId]; - if ([authInfo tempAuthKeyWithType:tempAuthKeyType].authKeyId == currentTempAuthKey.authKeyId) { - authInfo = [authInfo withUpdatedTempAuthKeyWithType:tempAuthKeyType key:nil]; - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo]; - [_context tempAuthKeyForDatacenterWithIdRequired:_datacenterId keyType:tempAuthKeyType]; - } - }]; + _awaitingAuthInfoForSelector = @(authInfoSelector); } else { + MTDatacenterAuthInfoSelector authInfoSelector; + [self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:&authInfoSelector]; + if (_requiredAuthToken != nil && _authTokenMasterDatacenterId != _datacenterId) { - _authInfo = nil; + _validAuthInfo = nil; + [_context removeTokenForDatacenterWithId:_datacenterId]; [_context performBatchUpdates:^{ - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil]; - [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false]; + [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector]; + [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector]; }]; _mtState |= MTProtoStateAwaitingDatacenterAuthorization; + _awaitingAuthInfoForSelector = @(authInfoSelector); } else if (_canResetAuthData) { - _authInfo = nil; + _validAuthInfo = nil; + [_context performBatchUpdates:^{ - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil]; - [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false]; + [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector]; + [_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector]; }]; _mtState |= MTProtoStateAwaitingDatacenterAuthorization; + _awaitingAuthInfoForSelector = @(authInfoSelector); } else { [_context checkIfLoggedOut:_datacenterId]; } } } -- (NSData *)_decryptIncomingTransportData:(NSData *)transportData address:(MTDatacenterAddress *)address +- (NSData *)_decryptIncomingTransportData:(NSData *)transportData address:(MTDatacenterAddress *)address authKey:(MTDatacenterAuthKey *)authKey { - MTDatacenterAuthKey *effectiveAuthKey; - if (_useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - effectiveAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - } else { - effectiveAuthKey = [[MTDatacenterAuthKey alloc] initWithAuthKey:_authInfo.authKey authKeyId:_authInfo.authKeyId notBound:false]; - } + MTDatacenterAuthKey *effectiveAuthKey = authKey; if (effectiveAuthKey == nil) return nil; @@ -2281,13 +2116,12 @@ static NSString *dumpHexString(NSData *data, int maxLength) { return [_context.serialization parseMessage:unwrappedData]; } -- (NSArray *)_parseIncomingMessages:(NSData *)data dataMessageId:(out int64_t *)dataMessageId parseError:(out bool *)parseError +- (NSArray *)_parseIncomingMessages:(NSData *)data dataMessageId:(out int64_t *)dataMessageId embeddedAuthKeyId:(int64_t)embeddedAuthKeyId parseError:(out bool *)parseError { MTInputStream *is = [[MTInputStream alloc] initWithData:data]; bool readError = false; - int64_t embeddedAuthKeyId = 0; int64_t embeddedSessionId = 0; int64_t embeddedMessageId = 0; int32_t embeddedSeqNo = 0; @@ -2303,7 +2137,6 @@ static NSString *dumpHexString(NSData *data, int maxLength) { *parseError = true; return nil; } - embeddedAuthKeyId = authKeyId; embeddedMessageId = [is readInt64:&readError]; if (readError) @@ -2326,7 +2159,6 @@ static NSString *dumpHexString(NSData *data, int maxLength) { } else { - embeddedAuthKeyId = _authInfo.authKeyId; embeddedSalt = [is readInt64:&readError]; if (readError) { @@ -2436,7 +2268,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { return messages; } -- (void)_processIncomingMessage:(MTIncomingMessage *)incomingMessage totalSize:(int)totalSize withTransactionId:(id)transactionId address:(MTDatacenterAddress *)address +- (void)_processIncomingMessage:(MTIncomingMessage *)incomingMessage totalSize:(int)totalSize withTransactionId:(id)transactionId address:(MTDatacenterAddress *)address authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if ([_sessionInfo messageProcessed:incomingMessage.messageId]) { @@ -2482,7 +2314,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { int64_t validSalt = ((MTBadServerSaltNotificationMessage *)badMsgNotification).nextServerSalt; NSTimeInterval timeDifference = incomingMessage.messageId / 4294967296.0 - [[NSDate date] timeIntervalSince1970]; [self completeTimeSync]; - [self timeSyncInfoChanged:timeDifference saltList:@[[[MTDatacenterSaltInfo alloc] initWithSalt:validSalt firstValidMessageId:incomingMessage.messageId lastValidMessageId:incomingMessage.messageId + (4294967296 * 30 * 60)]]]; + [self timeSyncInfoChanged:timeDifference saltList:@[[[MTDatacenterSaltInfo alloc] initWithSalt:validSalt firstValidMessageId:incomingMessage.messageId lastValidMessageId:incomingMessage.messageId + (4294967296 * 30 * 60)]] authInfoSelector:authInfoSelector]; } else [self initiateTimeSync]; @@ -2500,7 +2332,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) { NSTimeInterval timeDifference = incomingMessage.messageId / 4294967296.0 - [[NSDate date] timeIntervalSince1970]; [self completeTimeSync]; - [self timeSyncInfoChanged:timeDifference saltList:nil]; + [self timeSyncInfoChanged:timeDifference saltList:nil authInfoSelector:authInfoSelector]; } else [self initiateTimeSync]; @@ -2542,11 +2374,6 @@ static NSString *dumpHexString(NSData *data, int maxLength) { } } - if (_bindingTempAuthKeyContext != nil && badMessageId == _bindingTempAuthKeyContext.messageId) - { - _bindingTempAuthKeyContext = nil; - } - if ([self canAskForTransactions] || [self canAskForServiceTransactions]) [self requestTransportTransaction]; } @@ -2624,8 +2451,8 @@ static NSString *dumpHexString(NSData *data, int maxLength) { { id messageService = _messageServices[(NSUInteger)i]; - if ([messageService respondsToSelector:@selector(mtProto:receivedMessage:)]) - [messageService mtProto:self receivedMessage:incomingMessage]; + if ([messageService respondsToSelector:@selector(mtProto:receivedMessage:authInfoSelector:)]) + [messageService mtProto:self receivedMessage:incomingMessage authInfoSelector:authInfoSelector]; } if (_timeFixContext != nil && [incomingMessage.body isKindOfClass:[MTPongMessage class]] && ((MTPongMessage *)incomingMessage.body).messageId == _timeFixContext.messageId) @@ -2636,71 +2463,6 @@ static NSString *dumpHexString(NSData *data, int maxLength) { if ([self canAskForTransactions] || [self canAskForServiceTransactions]) [self requestTransportTransaction]; } - - if (_bindingTempAuthKeyContext != nil && [incomingMessage.body isKindOfClass:[MTRpcResultMessage class]] && ((MTRpcResultMessage *)incomingMessage.body).requestMessageId == _bindingTempAuthKeyContext.messageId) { - MTRpcResultMessage *rpcResultMessage = (MTRpcResultMessage *)incomingMessage.body; - - _bindingTempAuthKeyContext = nil; - - id maybeInternalMessage = [MTInternalMessageParser parseMessage:rpcResultMessage.data]; - - id rpcResult = nil; - MTRpcError *rpcError = nil; - - if ([maybeInternalMessage isKindOfClass:[MTRpcError class]]) - rpcError = maybeInternalMessage; - else - { - if (rpcResultMessage.data.length >= 4) { - int32_t signature = 0; - [rpcResultMessage.data getBytes:&signature range:NSMakeRange(0, 4)]; - if (signature == (int32_t)0xbc799737) { - rpcResult = @true; - } else if (signature == (int32_t)0x997275b5) { - rpcResult = @false; - } - } - if (rpcResult == nil) { - rpcError = [[MTRpcError alloc] initWithErrorCode:500 errorDescription:@"TL_PARSING_ERROR"]; - } - } - - if ([rpcResult respondsToSelector:@selector(boolValue)]) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - MTDatacenterAuthKey *effectiveTempAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - if (effectiveTempAuthKey != nil) { - _authInfo = [_authInfo withUpdatedTempAuthKeyWithType:tempAuthKeyType key:[[MTDatacenterAuthKey alloc] initWithAuthKey:effectiveTempAuthKey.authKey authKeyId:effectiveTempAuthKey.authKeyId notBound:false]]; - NSMutableDictionary *authKeyAttributes = [[NSMutableDictionary alloc] initWithDictionary:_authInfo.authKeyAttributes]; - [authKeyAttributes removeObjectForKey:@"apiInitializationHash"]; - _authInfo = [_authInfo withUpdatedAuthKeyAttributes:authKeyAttributes]; - if (_useExplicitAuthKey == nil) { - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:_authInfo]; - } - if (_tempAuthKeyBindingResultUpdated) { - _tempAuthKeyBindingResultUpdated(true); - } - } - _bindingTempAuthKeyId = 0; - if ((_mtState & MTProtoStateBindingTempAuthKey) != 0) { - [self setMtState:_mtState & (~MTProtoStateBindingTempAuthKey)]; - [self requestTransportTransaction]; - } - } else { - if (MTLogEnabled()) { - MTLog(@"[MTProto#%p@%p bindTempAuthKey error %@]", self, _context, rpcError); - } - MTShortLog(@"[MTProto#%p@%p bindTempAuthKey error %@]", self, _context, rpcError); - - [self requestTransportTransaction]; - - if (_tempAuthKeyBindingResultUpdated) { - _tempAuthKeyBindingResultUpdated(false); - } - } - } } } @@ -2722,18 +2484,25 @@ static NSString *dumpHexString(NSData *data, int maxLength) { }]; } -- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo +- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector { [[MTProto managerQueue] dispatchOnQueue:^ { if (!_useUnauthorizedMode && context == _context && datacenterId == _datacenterId) { - _authInfo = authInfo; - if (_useExplicitAuthKey != nil) { - _authInfo = [_authInfo withUpdatedTempAuthKeyWithType:MTDatacenterAuthTempKeyTypeMain key:_useExplicitAuthKey]; + if (_validAuthInfo != nil) { + if (_validAuthInfo.selector != selector) { + return; + } + } else if (_awaitingAuthInfoForSelector != nil) { + if ([_awaitingAuthInfoForSelector intValue] != selector) { + return; + } + } else { + return; } - bool wasSuspended = _mtState & (MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterTempAuthKey); + bool wasSuspended = _mtState & (MTProtoStateAwaitingDatacenterAuthorization); if (authInfo != nil) { if (_mtState & MTProtoStateAwaitingDatacenterAuthorization) { @@ -2741,38 +2510,8 @@ static NSString *dumpHexString(NSData *data, int maxLength) { } } - /*if (_transportScheme != nil && _useTempAuthKeys) { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (_transportScheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - if ([[_context authInfoForDatacenterWithId:_datacenterId] tempAuthKeyWithType:tempAuthKeyType] == nil) { - if ((_mtState & MTProtoStateAwaitingDatacenterTempAuthKey) == 0) { - [self setMtState:_mtState | MTProtoStateAwaitingDatacenterTempAuthKey]; - - [_context tempAuthKeyForDatacenterWithIdRequired:_datacenterId keyType:tempAuthKeyType]; - } - } - } - - if (_transportScheme != nil && (_mtState & MTProtoStateAwaitingDatacenterTempAuthKey)) - { - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (_transportScheme.address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - - if ([_authInfo tempAuthKeyWithType:tempAuthKeyType] != nil) { - [self setMtState:_mtState & (~MTProtoStateAwaitingDatacenterTempAuthKey)]; - } - } - - if (_transportScheme != nil) { - [self checkTempAuthKeyBinding:_transportScheme.address]; - }*/ - if (authInfo != nil) { - if ((_mtState & (MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterTempAuthKey)) == 0) { + if ((_mtState & (MTProtoStateAwaitingDatacenterAuthorization)) == 0) { if (wasSuspended) { [self resetTransport]; [self requestTransportTransaction]; @@ -2785,38 +2524,6 @@ static NSString *dumpHexString(NSData *data, int maxLength) { }]; } -- (void)checkTempAuthKeyBinding:(MTDatacenterAddress *)address { - NSAssert([[MTProto managerQueue] isCurrentQueue], @"invalid queue"); - - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - MTDatacenterAuthKey *effectiveTempAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - - if (_useTempAuthKeys && effectiveTempAuthKey != nil && effectiveTempAuthKey.notBound) { - bool isAlreadyBinding = false; - if (_bindingTempAuthKeyId != 0) { - if (_bindingTempAuthKeyId == effectiveTempAuthKey.authKeyId) { - isAlreadyBinding = true; - } else { - _bindingTempAuthKeyId = 0; - _bindingTempAuthKeyContext = nil; - } - } - if (!isAlreadyBinding && (_mtState & MTProtoStateBindingTempAuthKey) == 0) { - [self bindToPersistentKey:address]; - } - } else { - _bindingTempAuthKeyId = 0; - _bindingTempAuthKeyContext = nil; - if ((_mtState & MTProtoStateBindingTempAuthKey) != 0) { - [self setMtState:_mtState & (~MTProtoStateBindingTempAuthKey)]; - [self requestTransportTransaction]; - } - } -} - - (void)contextDatacenterAuthTokenUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authToken:(id)authToken { [[MTProto managerQueue] dispatchOnQueue:^ @@ -2842,28 +2549,31 @@ static NSString *dumpHexString(NSData *data, int maxLength) { }]; } -- (void)timeSyncServiceCompleted:(MTTimeSyncMessageService *)timeSyncService timeDifference:(NSTimeInterval)timeDifference saltList:(NSArray *)saltList +- (void)timeSyncServiceCompleted:(MTTimeSyncMessageService *)timeSyncService timeDifference:(NSTimeInterval)timeDifference saltList:(NSArray *)saltList authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if ([_messageServices containsObject:timeSyncService]) { [self completeTimeSync]; [_messageServices removeObject:timeSyncService]; - [self timeSyncInfoChanged:timeDifference saltList:saltList]; + [self timeSyncInfoChanged:timeDifference saltList:saltList authInfoSelector:authInfoSelector]; } } -- (void)timeSyncInfoChanged:(NSTimeInterval)timeDifference saltList:(NSArray *)saltList +- (void)timeSyncInfoChanged:(NSTimeInterval)timeDifference saltList:(NSArray *)saltList authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { [_context setGlobalTimeDifference:timeDifference]; if (saltList != nil) { - MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId]; + MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:authInfoSelector]; if (authInfo != nil) { MTDatacenterAuthInfo *updatedAuthInfo = [authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]]; - [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:updatedAuthInfo]; + [_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:updatedAuthInfo selector:authInfoSelector]; + if (_validAuthInfo != nil && _validAuthInfo.selector == authInfoSelector) { + _validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:updatedAuthInfo selector:authInfoSelector]; + } } } @@ -2925,18 +2635,4 @@ static NSString *dumpHexString(NSData *data, int maxLength) { }]; } -- (void)bindToPersistentKey:(MTDatacenterAddress *)address { - [[MTProto managerQueue] dispatchOnQueue:^{ - MTDatacenterAuthTempKeyType tempAuthKeyType = MTDatacenterAuthTempKeyTypeMain; - if (address.preferForMedia) { - tempAuthKeyType = MTDatacenterAuthTempKeyTypeMedia; - } - MTDatacenterAuthKey *effectiveTempAuthKey = [_authInfo tempAuthKeyWithType:tempAuthKeyType]; - - _bindingTempAuthKeyId = effectiveTempAuthKey.authKeyId; - _bindingTempAuthKeyContext = nil; - _mtState |= MTProtoStateBindingTempAuthKey; - }]; -} - @end diff --git a/submodules/MtProtoKit/Sources/MTProtoEngine.m b/submodules/MtProtoKit/Sources/MTProtoEngine.m new file mode 100644 index 0000000000..f48cc993cd --- /dev/null +++ b/submodules/MtProtoKit/Sources/MTProtoEngine.m @@ -0,0 +1,52 @@ +#import + +#import "Utils/MTQueueLocalObject.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MTProtoEngineImpl : NSObject { + MTQueue *_queue; + id _persistenceInterface; +} + +@end + +@implementation MTProtoEngineImpl + +- (instancetype)initWithQueue:(MTQueue *)queue persistenceInterface:(id)persistenceInterface { + self = [super init]; + if (self != nil) { + _queue = queue; + _persistenceInterface = persistenceInterface; + } + return self; +} + +@end + +@interface MTProtoEngine () { + MTQueue *_queue; + MTQueueLocalObject *_impl; +} + +@end + +@implementation MTProtoEngine + +- (instancetype)initWithPersistenceInterface:(id)persistenceInterface { + self = [super init]; + if (self != nil) { + _queue = [[MTQueue alloc] init]; + __auto_type queue = _queue; + _impl = [[MTQueueLocalObject alloc] initWithQueue:queue generator:^MTProtoEngineImpl *{ + return [[MTProtoEngineImpl alloc] initWithQueue:queue persistenceInterface:persistenceInterface]; + }]; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/submodules/MtProtoKit/Sources/MTProtoInstance.m b/submodules/MtProtoKit/Sources/MTProtoInstance.m new file mode 100644 index 0000000000..ba5da46abf --- /dev/null +++ b/submodules/MtProtoKit/Sources/MTProtoInstance.m @@ -0,0 +1,48 @@ +#import + +#import +#import "Utils/MTQueueLocalObject.h" + +@interface MTProtoInstanceImpl : NSObject { + MTQueue *_queue; + MTProtoEngine *_engine; +} + +@end + +@implementation MTProtoInstanceImpl + +- (instancetype)initWithQueue:(MTQueue *)queue engine:(MTProtoEngine *)engine { + self = [super init]; + if (self != nil) { + _queue = queue; + _engine = engine; + } + return self; +} + +@end + +@interface MTProtoInstance () { + MTQueue *_queue; + MTQueueLocalObject *_impl; +} + +@end + +@implementation MTProtoInstance + +- (instancetype)initWithEngine:(MTProtoEngine *)engine { + self = [super init]; + if (self != nil) { + _queue = [[MTQueue alloc] init]; + __auto_type queue = _queue; + _impl = [[MTQueueLocalObject alloc] initWithQueue:queue generator:^MTProtoInstanceImpl *{ + return [[MTProtoInstanceImpl alloc] initWithQueue:queue engine:engine]; + }]; + } + return self; +} + +@end diff --git a/submodules/MtProtoKit/Sources/MTRequestMessageService.m b/submodules/MtProtoKit/Sources/MTRequestMessageService.m index 23f12dc625..b37bd8d6d0 100644 --- a/submodules/MtProtoKit/Sources/MTRequestMessageService.m +++ b/submodules/MtProtoKit/Sources/MTRequestMessageService.m @@ -391,12 +391,12 @@ return currentData; } -- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto +- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { NSMutableArray *messages = nil; NSMutableDictionary *requestInternalIdToMessageInternalId = nil; - bool requestsWillInitializeApi = _apiEnvironment != nil && ![_apiEnvironment.apiInitializationHash isEqualToString:[_context authInfoForDatacenterWithId:mtProto.datacenterId].authKeyAttributes[@"apiInitializationHash"]]; + bool requestsWillInitializeApi = _apiEnvironment != nil && ![_apiEnvironment.apiInitializationHash isEqualToString:[_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector].authKeyAttributes[@"apiInitializationHash"]]; CFAbsoluteTime currentTime = MTAbsoluteSystemTime(); @@ -561,7 +561,7 @@ return nil; } -- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)message +- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if ([message.body isKindOfClass:[MTRpcResultMessage class]]) { @@ -610,13 +610,13 @@ { rpcError = [[MTRpcError alloc] initWithErrorCode:500 errorDescription:@"TL_PARSING_ERROR"]; [_context performBatchUpdates:^{ - MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId]; + MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector]; NSMutableDictionary *authKeyAttributes = [[NSMutableDictionary alloc] initWithDictionary:authInfo.authKeyAttributes]; authKeyAttributes[@"apiInitializationHash"] = @""; authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes]; - [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo]; + [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector]; }]; } } @@ -636,7 +636,7 @@ if (rpcResult != nil && request.requestContext.willInitializeApi) { - MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId]; + MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector]; if (![_apiEnvironment.apiInitializationHash isEqualToString:authInfo.authKeyAttributes[@"apiInitializationHash"]]) { @@ -644,7 +644,7 @@ authKeyAttributes[@"apiInitializationHash"] = _apiEnvironment.apiInitializationHash; authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes]; - [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo]; + [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector]; } } @@ -726,13 +726,13 @@ { [_context performBatchUpdates:^ { - MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId]; + MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector]; NSMutableDictionary *authKeyAttributes = [[NSMutableDictionary alloc] initWithDictionary:authInfo.authKeyAttributes]; [authKeyAttributes removeObjectForKey:@"apiInitializationHash"]; authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes]; - [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo]; + [_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector]; }]; } else if (rpcError.errorCode == 406) { if (_didReceiveSoftAuthResetError) { diff --git a/submodules/MtProtoKit/Sources/MTResendMessageService.m b/submodules/MtProtoKit/Sources/MTResendMessageService.m index 4e515ba39f..16f7b7f4f6 100644 --- a/submodules/MtProtoKit/Sources/MTResendMessageService.m +++ b/submodules/MtProtoKit/Sources/MTResendMessageService.m @@ -41,7 +41,7 @@ [mtProto requestTransportTransaction]; } -- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto +- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if (_currentRequestMessageId == 0 || _currentRequestTransactionId == nil) { @@ -121,7 +121,7 @@ } } -- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message +- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if (message.messageId == _messageId) { diff --git a/submodules/MtProtoKit/Sources/MTTcpTransport.m b/submodules/MtProtoKit/Sources/MTTcpTransport.m index 6b4cc265f1..3b0883b3aa 100644 --- a/submodules/MtProtoKit/Sources/MTTcpTransport.m +++ b/submodules/MtProtoKit/Sources/MTTcpTransport.m @@ -747,7 +747,7 @@ static const NSTimeInterval MTTcpTransportSleepWatchdogTimeout = 60.0; }]; } -- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)incomingMessage +- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)incomingMessage authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if ([incomingMessage.body isKindOfClass:[MTPongMessage class]]) { diff --git a/submodules/MtProtoKit/Sources/MTTimeSyncMessageService.m b/submodules/MtProtoKit/Sources/MTTimeSyncMessageService.m index 6d8919c176..9504df24f0 100644 --- a/submodules/MtProtoKit/Sources/MTTimeSyncMessageService.m +++ b/submodules/MtProtoKit/Sources/MTTimeSyncMessageService.m @@ -45,7 +45,7 @@ [mtProto requestTransportTransaction]; } -- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto +- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if (_currentTransactionId == nil) { @@ -127,7 +127,7 @@ } } -- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message +- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector { if ([message.body isKindOfClass:[MTFutureSaltsMessage class]] && ((MTFutureSaltsMessage *)message.body).requestMessageId == _currentMessageId) { diff --git a/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.h b/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.h new file mode 100644 index 0000000000..63165bd89f --- /dev/null +++ b/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.h @@ -0,0 +1,14 @@ +#import + +@class MTQueue; + +NS_ASSUME_NONNULL_BEGIN + +@interface MTQueueLocalObject<__covariant T> : NSObject + +- (instancetype)initWithQueue:(MTQueue *)queue generator:(T(^)())generator; +- (void)with:(void (^)(T))f; + +@end + +NS_ASSUME_NONNULL_END diff --git a/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.m b/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.m new file mode 100644 index 0000000000..a84da57845 --- /dev/null +++ b/submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.m @@ -0,0 +1,56 @@ +#import "MTQueueLocalObject.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MTQueueLocalObjectHolder : NSObject + +@property (nonatomic, assign) CFTypeRef impl; + +@end + +@implementation MTQueueLocalObjectHolder + +@end + +@interface MTQueueLocalObject () { + MTQueue *_queue; + MTQueueLocalObjectHolder *_holder; +} + +@end + +@implementation MTQueueLocalObject + +- (instancetype)initWithQueue:(MTQueue *)queue generator:(id(^)())generator { + self = [super init]; + if (self != nil) { + _queue = queue; + _holder = [[MTQueueLocalObjectHolder alloc] init]; + __auto_type holder = _holder; + [queue dispatchOnQueue:^{ + id value = generator(); + holder.impl = CFBridgingRetain(value); + } synchronous:false]; + } + return self; +} + +- (void)dealloc { + __auto_type holder = _holder; + [_queue dispatchOnQueue:^{ + CFBridgingRelease(holder.impl); + } synchronous:false]; +} + +- (void)with:(void (^)(id))f { + __auto_type holder = _holder; + [_queue dispatchOnQueue:^{ + id value = (__bridge id)holder.impl; + f(value); + } synchronous:false]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/submodules/TelegramCore/Sources/Account.swift b/submodules/TelegramCore/Sources/Account.swift index 24194959ca..195f72ae0e 100644 --- a/submodules/TelegramCore/Sources/Account.swift +++ b/submodules/TelegramCore/Sources/Account.swift @@ -103,8 +103,8 @@ public class UnauthorizedAccount { datacenterIds.append(contentsOf: [4]) } for id in datacenterIds { - if network.context.authInfoForDatacenter(withId: id) == nil { - network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false) + if network.context.authInfoForDatacenter(withId: id, selector: .persistent) == nil { + network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false, selector: .persistent) } } network.context.beginExplicitBackupAddressDiscovery() @@ -243,7 +243,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw let backupState = AuthorizedAccountState(isTestingEnvironment: beginWithTestingEnvironment, masterDatacenterId: backupData.masterDatacenterId, peerId: PeerId(backupData.peerId), state: nil) state = backupState let dict = NSMutableDictionary() - dict.setObject(MTDatacenterAuthInfo(authKey: backupData.masterDatacenterKey, authKeyId: backupData.masterDatacenterKeyId, saltSet: [], authKeyAttributes: [:], mainTempAuthKey: nil, mediaTempAuthKey: nil), forKey: backupData.masterDatacenterId as NSNumber) + dict.setObject(MTDatacenterAuthInfo(authKey: backupData.masterDatacenterKey, authKeyId: backupData.masterDatacenterKeyId, saltSet: [], authKeyAttributes: [:]), forKey: backupData.masterDatacenterId as NSNumber) let data = NSKeyedArchiver.archivedData(withRootObject: dict) transaction.setState(backupState) transaction.setKeychainEntry(data, forKey: "persistent:datacenterAuthInfoById") diff --git a/submodules/TelegramCore/Sources/SynchronizePeerReadState.swift b/submodules/TelegramCore/Sources/SynchronizePeerReadState.swift index 5f55a1bce3..9817e3c28b 100644 --- a/submodules/TelegramCore/Sources/SynchronizePeerReadState.swift +++ b/submodules/TelegramCore/Sources/SynchronizePeerReadState.swift @@ -34,12 +34,18 @@ private func inputSecretChat(postbox: Postbox, peerId: PeerId) -> Signal take(1) } -private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(Int32, Int32), PeerReadStateValidationError> { +private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(Int32, Int32)?, PeerReadStateValidationError> { return inputPeer(postbox: postbox, peerId: peerId) - |> mapToSignal { inputPeer -> Signal<(Int32, Int32), PeerReadStateValidationError> in + |> mapToSignal { inputPeer -> Signal<(Int32, Int32)?, PeerReadStateValidationError> in return network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: Int32.max, offsetDate: Int32.max, addOffset: 0, limit: 1, maxId: Int32.max, minId: 1, hash: 0)) - |> retryRequest - |> mapToSignalPromotingError { result -> Signal<(Int32, Int32), PeerReadStateValidationError> in + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> mapToSignalPromotingError { result -> Signal<(Int32, Int32)?, PeerReadStateValidationError> in + guard let result = result else { + return .single(nil) + } let apiMessages: [Api.Message] switch result { case let .channelMessages(_, _, _, messages, _, _): @@ -60,14 +66,18 @@ private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId } } -private func dialogReadState(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> { +private func dialogReadState(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> { return dialogTopMessage(network: network, postbox: postbox, peerId: peerId) - |> mapToSignal { topMessage -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in + |> mapToSignal { topMessage -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in + guard let _ = topMessage else { + return .single(nil) + } + return inputPeer(postbox: postbox, peerId: peerId) - |> mapToSignal { inputPeer -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in + |> mapToSignal { inputPeer -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in return network.request(Api.functions.messages.getPeerDialogs(peers: [.inputDialogPeer(peer: inputPeer)])) |> retryRequest - |> mapToSignalPromotingError { result -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in + |> mapToSignalPromotingError { result -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in switch result { case let .peerDialogs(dialogs, _, _, _, state): if let dialog = dialogs.filter({ $0.peerId == peerId }).first { @@ -150,10 +160,16 @@ enum PeerReadStateValidationError { private func validatePeerReadState(network: Network, postbox: Postbox, stateManager: AccountStateManager, peerId: PeerId) -> Signal { let readStateWithInitialState = dialogReadState(network: network, postbox: postbox, peerId: peerId) - |> map { ($0.0, $0.1) } let maybeAppliedReadState = readStateWithInitialState - |> mapToSignal { (readState, finalMarker) -> Signal in + |> mapToSignal { data -> Signal in + guard let (readState, _) = data else { + return postbox.transaction { transaction -> Void in + transaction.confirmSynchronizedIncomingReadState(peerId) + } + |> castError(PeerReadStateValidationError.self) + |> ignoreValues + } return stateManager.addCustomOperation(postbox.transaction { transaction -> PeerReadStateValidationError? in if let currentReadState = transaction.getCombinedPeerReadState(peerId) { loop: for (namespace, currentState) in currentReadState.states { diff --git a/submodules/TelegramUI/Sources/ManageSharedAccountInfo.swift b/submodules/TelegramUI/Sources/ManageSharedAccountInfo.swift index 49ee068a3a..396a494187 100644 --- a/submodules/TelegramUI/Sources/ManageSharedAccountInfo.swift +++ b/submodules/TelegramUI/Sources/ManageSharedAccountInfo.swift @@ -22,7 +22,7 @@ private func accountInfo(account: Account) -> Signal var datacenters: [Int32: AccountDatacenterInfo] = [:] for nId in context.knownDatacenterIds() { if let id = nId as? Int { - if let authInfo = context.authInfoForDatacenter(withId: id), let authKey = authInfo.authKey { + if let authInfo = context.authInfoForDatacenter(withId: id, selector: .persistent), let authKey = authInfo.authKey { let transportScheme = context.chooseTransportSchemeForConnection(toDatacenterId: id, schemes: context.transportSchemesForDatacenter(withId: id, media: true, enforceMedia: false, isProxy: false)) var addressList: [AccountDatacenterAddress] = [] if let transportScheme = transportScheme, let address = transportScheme.address, let host = address.host {