From cbb1ee599a4e99f795e6a0bc88bbca8ac8e92e8f Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 23 May 2015 23:52:08 +0300 Subject: [PATCH] no message --- MTDiscoverConnectionSignals.h | 10 + MTDiscoverConnectionSignals.m | 204 ++++++++++++++++++ MTProtoKit/MTApiEnvironment.h | 2 +- MTProtoKit/MTContext.m | 82 +++++-- MTProtoKit/MTDatacenterAddress.h | 3 +- MTProtoKit/MTDatacenterAddress.m | 10 +- MTProtoKit/MTDiscoverTransportSchemeAction.m | 30 +-- MTProtoKit/MTEncryption.m | 5 - MTProtoKit/MTHttpWorker.h | 8 + MTProtoKit/MTHttpWorker.m | 22 ++ MTProtoKit/MTInputStream.h | 4 +- MTProtoKit/MTInputStream.m | 4 +- MTProtoKit/MTOutputStream.m | 5 + MTProtoKit/MTProto.h | 1 + MTProtoKit/MTProto.m | 3 + MTProtoKit/MTTcpConnection.h | 5 + MTProtoKit/MTTcpConnection.m | 10 +- MtProtoKit.xcodeproj/project.pbxproj | 21 ++ .../AFNetworking/AFHTTPRequestOperation.h | 6 +- .../AFNetworking/AFHTTPRequestOperation.m | 4 +- 20 files changed, 371 insertions(+), 68 deletions(-) create mode 100644 MTDiscoverConnectionSignals.h create mode 100644 MTDiscoverConnectionSignals.m diff --git a/MTDiscoverConnectionSignals.h b/MTDiscoverConnectionSignals.h new file mode 100644 index 0000000000..fab72b6fa4 --- /dev/null +++ b/MTDiscoverConnectionSignals.h @@ -0,0 +1,10 @@ +#import + +#import +#import + +@interface MTDiscoverConnectionSignals : NSObject + ++ (SSignal *)discoverSchemeWithContext:(MTContext *)context addressList:(NSArray *)addressList preferMedia:(bool)preferMedia; + +@end diff --git a/MTDiscoverConnectionSignals.m b/MTDiscoverConnectionSignals.m new file mode 100644 index 0000000000..9ed2629c2a --- /dev/null +++ b/MTDiscoverConnectionSignals.m @@ -0,0 +1,204 @@ +#import "MTDiscoverConnectionSignals.h" + +#import "MTTcpConnection.h" +#import "MTHttpWorker.h" +#import "MTTransportScheme.h" +#import "MTTcpTransport.h" +#import "MTHttpTransport.h" + +#import +#import + +typedef struct { + uint8_t nonce[16]; +} MTPayloadData; + +@implementation MTDiscoverConnectionSignals + ++ (NSData *)payloadData:(MTPayloadData *)outPayloadData; +{ + uint8_t reqPqBytes[] = { + 0, 0, 0, 0, 0, 0, 0, 0, // zero * 8 + 0, 0, 0, 0, 0, 0, 0, 0, // message id + 20, 0, 0, 0, // message length + 0x78, 0x97, 0x46, 0x60, // req_pq + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // nonce + }; + + MTPayloadData payloadData; + arc4random_buf(&payloadData.nonce, 16); + if (outPayloadData) + *outPayloadData = payloadData; + + arc4random_buf(reqPqBytes + 8, 8); + memcpy(reqPqBytes + 8 + 8 + 4 + 4, payloadData.nonce, 16); + + return [[NSData alloc] initWithBytes:reqPqBytes length:sizeof(reqPqBytes)]; +} + ++ (bool)isResponseValid:(NSData *)data payloadData:(MTPayloadData)payloadData +{ + if (data.length == 84) + { + uint8_t zero[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t length[] = { 0x40, 0, 0, 0 }; + uint8_t resPq[] = { 0x63, 0x24, 0x16, 0x05 }; + if (memcmp((uint8_t * const)data.bytes, zero, 8) == 0 && memcmp(((uint8_t * const)data.bytes) + 16, length, 4) == 0 && memcmp(((uint8_t * const)data.bytes) + 20, resPq, 4) == 0 && memcmp(((uint8_t * const)data.bytes) + 24, payloadData.nonce, 16) == 0) + { + return true; + } + } + + return false; +} + ++ (bool)isIpv6:(NSString *)ip +{ + const char *utf8 = [ip UTF8String]; + int success; + + struct in6_addr dst6; + success = inet_pton(AF_INET6, utf8, &dst6); + + return success == 1; +} + ++ (SSignal *)tcpConnectionWithAddress:(MTDatacenterAddress *)address; +{ + return [[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) + { + MTPayloadData payloadData; + NSData *data = [self payloadData:&payloadData]; + + MTTcpConnection *connection = [[MTTcpConnection alloc] initWithAddress:address interface:nil]; + __weak MTTcpConnection *weakConnection = connection; + connection.connectionOpened = ^ + { + __strong MTTcpConnection *strongConnection = weakConnection; + if (strongConnection != nil) + [strongConnection sendDatas:@[data] completion:nil requestQuickAck:false expectDataInResponse:true]; + }; + connection.connectionReceivedData = ^(NSData *data) + { + if ([self isResponseValid:data payloadData:payloadData]) + [subscriber putCompletion]; + else + [subscriber putError:nil]; + }; + connection.connectionClosed = ^ + { + [subscriber putError:nil]; + }; + MTLog(@"trying tcp://%@:%d", address.ip, (int)address.port); + [connection start]; + + return [[SBlockDisposable alloc] initWithBlock:^ + { + [connection stop]; + }]; + }]; +} + ++ (SSignal *)httpConnectionWithAddress:(MTDatacenterAddress *)address +{ + return [[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) + { + MTPayloadData payloadData; + NSData *data = [self payloadData:&payloadData]; + + MTHttpWorkerBlockDelegate *delegate = [[MTHttpWorkerBlockDelegate alloc] init]; + + delegate.completedWithData = ^(NSData *data) + { + if ([self isResponseValid:data payloadData:payloadData]) + [subscriber putCompletion]; + else + [subscriber putError:nil]; + }; + delegate.failed = ^ + { + [subscriber putError:nil]; + }; + + MTLog(@"trying http://%@:%d", address.ip, (int)address.port); + MTHttpWorker *httpWorker = [[MTHttpWorker alloc] initWithDelegate:delegate address:address payloadData:data performsLongPolling:false]; + + return [[SBlockDisposable alloc] initWithBlock:^ + { + [delegate description]; // keep reference + [httpWorker stop]; + }]; + }]; +} + ++ (SSignal *)discoverSchemeWithContext:(MTContext *)context addressList:(NSArray *)addressList preferMedia:(bool)preferMedia +{ + NSMutableArray *bestAddressList = [[NSMutableArray alloc] init]; + NSMutableArray *remainingAddressList = [[NSMutableArray alloc] init]; + + for (MTDatacenterAddress *address in addressList) + { + if (preferMedia == address.preferForMedia) + [bestAddressList addObject:address]; + else + [remainingAddressList addObject:address]; + } + + NSMutableArray *bestTcp4Signals = [[NSMutableArray alloc] init]; + NSMutableArray *bestTcp6Signals = [[NSMutableArray alloc] init]; + NSMutableArray *bestHttpSignals = [[NSMutableArray alloc] init]; + + for (MTDatacenterAddress *address in bestAddressList) + { + MTTransportScheme *tcpTransportScheme = [[MTTransportScheme alloc] initWithTransportClass:[MTTcpTransport class] address:address]; + MTTransportScheme *httpTransportScheme = [[MTTransportScheme alloc] initWithTransportClass:[MTHttpTransport class] address:address]; + + if ([self isIpv6:address.ip]) + { + SSignal *signal = [[[[self tcpConnectionWithAddress:address] then:[SSignal single:tcpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error) + { + return [SSignal complete]; + }]; + [bestTcp6Signals addObject:signal]; + } + else + { + SSignal *signal = [[[[self tcpConnectionWithAddress:address] then:[SSignal single:tcpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error) + { + return [SSignal complete]; + }]; + [bestTcp4Signals addObject:signal]; + } + + SSignal *signal = [[[[self httpConnectionWithAddress:address] then:[SSignal single:httpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error) + { + return [SSignal complete]; + }]; + [bestHttpSignals addObject:signal]; + } + + SSignal *repeatDelaySignal = [[SSignal complete] delay:1.0 onQueue:[SQueue concurrentDefaultQueue]]; + SSignal *optimalDelaySignal = [[SSignal complete] delay:30.0 onQueue:[SQueue concurrentDefaultQueue]]; + + SSignal *firstTcp4Match = [[[[SSignal mergeSignals:bestTcp4Signals] then:repeatDelaySignal] restart] take:1]; + SSignal *firstTcp6Match = [[[[SSignal mergeSignals:bestTcp6Signals] then:repeatDelaySignal] restart] take:1]; + SSignal *firstHttpMatch = [[[[SSignal mergeSignals:bestHttpSignals] then:repeatDelaySignal] restart] take:1]; + + SSignal *optimalTcp4Match = [[[[SSignal mergeSignals:bestTcp4Signals] then:optimalDelaySignal] restart] take:1]; + SSignal *optimalTcp6Match = [[[[SSignal mergeSignals:bestTcp6Signals] then:optimalDelaySignal] restart] take:1]; + + SSignal *anySignal = [[SSignal mergeSignals:@[firstTcp4Match, firstTcp6Match, firstHttpMatch]] take:1]; + SSignal *optimalSignal = [[SSignal mergeSignals:@[optimalTcp4Match, optimalTcp6Match]] take:1]; + + SSignal *signal = [anySignal mapToSignal:^SSignal *(MTTransportScheme *scheme) + { + if (![scheme isOptimal]) + return [[SSignal single:scheme] then:optimalSignal]; + else + return [SSignal single:scheme]; + }]; + + return signal; +} + +@end diff --git a/MTProtoKit/MTApiEnvironment.h b/MTProtoKit/MTApiEnvironment.h index 3150a1e25f..e56494d156 100644 --- a/MTProtoKit/MTApiEnvironment.h +++ b/MTProtoKit/MTApiEnvironment.h @@ -13,7 +13,7 @@ @property (nonatomic) int32_t apiId; @property (nonatomic, strong, readonly) NSString *deviceModel; @property (nonatomic, strong, readonly) NSString *systemVersion; -@property (nonatomic, strong, readonly) NSString *appVersion; +@property (nonatomic, strong) NSString *appVersion; @property (nonatomic, strong, readonly) NSString *langCode; @property (nonatomic, strong) NSNumber *layer; diff --git a/MTProtoKit/MTContext.m b/MTProtoKit/MTContext.m index 596d04324f..f39446b844 100644 --- a/MTProtoKit/MTContext.m +++ b/MTProtoKit/MTContext.m @@ -30,6 +30,8 @@ #import +#import "MTDiscoverConnectionSignals.h" + @implementation MTContextBlockChangeListener - (void)contextIsPasswordRequiredUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId @@ -68,6 +70,8 @@ volatile OSSpinLock _passwordEntryRequiredLock; NSMutableDictionary *_passwordRequiredByDatacenterId; + + NSMutableDictionary *_transportSchemeDisposableByDatacenterId; } @end @@ -602,15 +606,7 @@ if (result != nil && ![result isOptimal]) { - MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)]; - if (action == nil) - { - action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId]; - action.delegate = self; - _discoverDatacenterTransportSchemeActions[@(datacenterId)] = action; - } - - [action discoverMoreOptimalSchemeThan:result]; + [self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:result beginWithHttp:false]; } } synchronous:true]; @@ -672,10 +668,47 @@ } - (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId +{ + [self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:nil beginWithHttp:false]; +} + +- (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId moreOptimalThan:(MTTransportScheme *)suboptimalScheme beginWithHttp:(bool)beginWithHttp { [[MTContext contextQueue] dispatchOnQueue:^ { - MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)]; + if (_transportSchemeDisposableByDatacenterId == nil) + _transportSchemeDisposableByDatacenterId = [[NSMutableDictionary alloc] init]; + id disposable = _transportSchemeDisposableByDatacenterId[@(datacenterId)]; + if (disposable == nil) + { + __weak MTContext *weakSelf = self; + MTDatacenterAddressSet *addressSet = [self addressSetForDatacenterWithId:datacenterId]; + _transportSchemeDisposableByDatacenterId[@(datacenterId)] = [[[MTDiscoverConnectionSignals discoverSchemeWithContext:self addressList:addressSet.addressList preferMedia:false] onDispose:^ + { + __strong MTContext *strongSelf = weakSelf; + if (strongSelf != nil) + { + [[MTContext contextQueue] dispatchOnQueue:^ + { + [strongSelf->_transportSchemeDisposableByDatacenterId removeObjectForKey:@(datacenterId)]; + }]; + } + }] startWithNext:^(id next) + { + MTLog(@"scheme: %@", next); + __strong MTContext *strongSelf = weakSelf; + if (strongSelf != nil) + [strongSelf updateTransportSchemeForDatacenterWithId:datacenterId transportScheme:next]; + } error:^(id error) + { + + } completed:^ + { + + }]; + } + + /*MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)]; if (action == nil) { action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId]; @@ -683,7 +716,15 @@ _discoverDatacenterTransportSchemeActions[@(datacenterId)] = action; } - [action discoverScheme]; + if (suboptimalScheme) + { + if (beginWithHttp) + [action invalidateScheme:suboptimalScheme beginWithHttp:true]; + else + [action discoverMoreOptimalSchemeThan:suboptimalScheme]; + } + else + [action discoverScheme];*/ }]; } @@ -694,15 +735,7 @@ [[MTContext contextQueue] dispatchOnQueue:^ { - MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)]; - if (action == nil) - { - action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId]; - action.delegate = self; - _discoverDatacenterTransportSchemeActions[@(datacenterId)] = action; - } - - [action invalidateScheme:transportScheme beginWithHttp:isProbablyHttp]; + [self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:transportScheme beginWithHttp:isProbablyHttp]; }]; } @@ -713,6 +746,15 @@ MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)]; if (action != nil) [action validateScheme:transportScheme]; + + if ([transportScheme isOptimal]) + { + if (_transportSchemeDisposableByDatacenterId == nil) + _transportSchemeDisposableByDatacenterId = [[NSMutableDictionary alloc] init]; + id disposable = _transportSchemeDisposableByDatacenterId[@(datacenterId)]; + [disposable dispose]; + [_transportSchemeDisposableByDatacenterId removeObjectForKey:@(datacenterId)]; + } }]; } diff --git a/MTProtoKit/MTDatacenterAddress.h b/MTProtoKit/MTDatacenterAddress.h index cd128819ee..24aecc044a 100644 --- a/MTProtoKit/MTDatacenterAddress.h +++ b/MTProtoKit/MTDatacenterAddress.h @@ -13,8 +13,9 @@ @property (nonatomic, strong, readonly) NSString *host; @property (nonatomic, strong, readonly) NSString *ip; @property (nonatomic, readonly) uint16_t port; +@property (nonatomic, readonly) bool preferForMedia; -- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port; +- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port preferForMedia:(bool)preferForMedia; - (BOOL)isEqualToAddress:(MTDatacenterAddress *)other; diff --git a/MTProtoKit/MTDatacenterAddress.m b/MTProtoKit/MTDatacenterAddress.m index 38d31ba1e3..8ee861d94c 100644 --- a/MTProtoKit/MTDatacenterAddress.m +++ b/MTProtoKit/MTDatacenterAddress.m @@ -10,13 +10,14 @@ @implementation MTDatacenterAddress -- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port +- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port preferForMedia:(bool)preferForMedia { self = [super init]; if (self != nil) { _ip = ip; _port = port; + _preferForMedia = preferForMedia; } return self; } @@ -29,6 +30,7 @@ _ip = [aDecoder decodeObjectForKey:@"ip"]; _host = [aDecoder decodeObjectForKey:@"host"]; _port = (uint16_t)[aDecoder decodeIntForKey:@"port"]; + _preferForMedia = [aDecoder decodeBoolForKey:@"preferForMedia"]; } return self; } @@ -38,6 +40,7 @@ [aCoder encodeObject:_ip forKey:@"ip"]; [aCoder encodeObject:_host forKey:@"host"]; [aCoder encodeInt:_port forKey:@"port"]; + [aCoder encodeBool:_preferForMedia forKey:@"preferForMedia"]; } - (BOOL)isEqual:(id)object @@ -59,12 +62,15 @@ if (_port != other.port) return false; + if (_preferForMedia != other.preferForMedia) + return false; + return true; } - (NSString *)description { - return [[NSString alloc] initWithFormat:@"%@:%d", _ip == nil ? _host : _ip, (int)_port]; + return [[NSString alloc] initWithFormat:@"%@:%d (media: %@)", _ip == nil ? _host : _ip, (int)_port, _preferForMedia ? @"yes" : @"no"]; } @end diff --git a/MTProtoKit/MTDiscoverTransportSchemeAction.m b/MTProtoKit/MTDiscoverTransportSchemeAction.m index 08bd3f47f7..f8dc301a2b 100644 --- a/MTProtoKit/MTDiscoverTransportSchemeAction.m +++ b/MTProtoKit/MTDiscoverTransportSchemeAction.m @@ -115,34 +115,6 @@ typedef enum { }]; } -- (NSArray *)interfaceList -{ - NSMutableArray *list = [[NSMutableArray alloc] init]; - - struct ifaddrs *addrs = NULL; - const struct ifaddrs *cursor = NULL; - - bool success = getifaddrs(&addrs) == 0; - if (success) - { - cursor = addrs; - while (cursor != NULL) - { - if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0) - { - NSString *name = [NSString stringWithUTF8String:cursor->ifa_name]; - if (name != nil) - [list addObject:name]; - } - - cursor = cursor->ifa_next; - } - freeifaddrs(addrs); - } - - return list; -} - - (void)networkAvailabilityChanged:(MTNetworkAvailability *)networkAvailability networkIsAvailable:(bool)networkIsAvailable { [[MTDiscoverTransportSchemeAction discoverTransportSchemeQueue] dispatchOnQueue:^ @@ -356,7 +328,7 @@ typedef enum { NSMutableArray *httpAddresses = [[NSMutableArray alloc] init]; for (MTDatacenterAddress *address in [(MTContext *)_context addressSetForDatacenterWithId:_datacenterId].addressList) { - MTDatacenterAddress *actualAddress = [[MTDatacenterAddress alloc] initWithIp:address.ip port:80]; + MTDatacenterAddress *actualAddress = [[MTDatacenterAddress alloc] initWithIp:address.ip port:80 preferForMedia:false]; if (![httpAddresses containsObject:actualAddress]) { [httpAddresses addObject:httpAddresses]; diff --git a/MTProtoKit/MTEncryption.m b/MTProtoKit/MTEncryption.m index 39e853ccf0..5fcd0eca2b 100644 --- a/MTProtoKit/MTEncryption.m +++ b/MTProtoKit/MTEncryption.m @@ -70,11 +70,6 @@ static inline uint32_t rotl32 ( uint32_t x, int8_t r ) return (x << r) | (x >> (32 - r)); } -static inline uint64_t rotl64 ( uint64_t x, int8_t r ) -{ - return (x << r) | (x >> (64 - r)); -} - #define ROTL32(x,y) rotl32(x,y) #define ROTL64(x,y) rotl64(x,y) diff --git a/MTProtoKit/MTHttpWorker.h b/MTProtoKit/MTHttpWorker.h index 69aea89650..0fecde5303 100644 --- a/MTProtoKit/MTHttpWorker.h +++ b/MTProtoKit/MTHttpWorker.h @@ -21,6 +21,14 @@ @end +@interface MTHttpWorkerBlockDelegate : NSObject + +@property (nonatomic, copy) void (^completedWithData)(NSData *); +@property (nonatomic, copy) void (^connected)(); +@property (nonatomic, copy) void (^failed)(); + +@end + @interface MTHttpWorker : AFHTTPClient @property (nonatomic, strong, readonly) id internalId; diff --git a/MTProtoKit/MTHttpWorker.m b/MTProtoKit/MTHttpWorker.m index bef35e9ccc..a05e353689 100644 --- a/MTProtoKit/MTHttpWorker.m +++ b/MTProtoKit/MTHttpWorker.m @@ -17,6 +17,28 @@ MTInternalIdClass(MTHttpWorker) +@implementation MTHttpWorkerBlockDelegate + +- (void)httpWorker:(MTHttpWorker *)__unused httpWorker completedWithData:(NSData *)data +{ + if (_completedWithData) + _completedWithData(data); +} + +- (void)httpWorkerConnected:(MTHttpWorker *)__unused httpWorker +{ + if (_connected) + _connected(); +} + +- (void)httpWorkerFailed:(MTHttpWorker *)__unused httpWorker +{ + if (_failed) + _failed(); +} + +@end + @interface MTHttpWorker () { MTTimer *_timeoutTimer; diff --git a/MTProtoKit/MTInputStream.h b/MTProtoKit/MTInputStream.h index a38005767c..080e09e06c 100644 --- a/MTProtoKit/MTInputStream.h +++ b/MTProtoKit/MTInputStream.h @@ -21,8 +21,8 @@ - (double)readDouble:(bool *)failed __attribute__((nonnull(1))); - (NSData *)readData:(int)length; - (NSData *)readData:(int)length failed:(bool *)failed __attribute__((nonnull(2))); -- (NSMutableData *)readMutableData:(int)length; -- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed __attribute__((nonnull(2))); +- (NSMutableData *)readMutableData:(NSUInteger)length; +- (NSMutableData *)readMutableData:(NSUInteger)length failed:(bool *)failed __attribute__((nonnull(2))); - (NSString *)readString; - (NSString *)readString:(bool *)failed __attribute__((nonnull(1))); - (NSData *)readBytes; diff --git a/MTProtoKit/MTInputStream.m b/MTProtoKit/MTInputStream.m index 5b183201ab..b432f6d847 100644 --- a/MTProtoKit/MTInputStream.m +++ b/MTProtoKit/MTInputStream.m @@ -203,7 +203,7 @@ static inline int roundUpInput(int numToRound, int multiple) return data; } -- (NSMutableData *)readMutableData:(int)length +- (NSMutableData *)readMutableData:(NSUInteger)length { uint8_t *bytes = (uint8_t *)malloc(length); NSInteger readLen = [_wrappedInputStream read:bytes maxLength:length]; @@ -215,7 +215,7 @@ static inline int roundUpInput(int numToRound, int multiple) return data; } -- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed +- (NSMutableData *)readMutableData:(NSUInteger)length failed:(bool *)failed { uint8_t *bytes = (uint8_t *)malloc(length); NSInteger readLen = [_wrappedInputStream read:bytes maxLength:length]; diff --git a/MTProtoKit/MTOutputStream.m b/MTProtoKit/MTOutputStream.m index ca0c8d22ee..1bcce89231 100644 --- a/MTProtoKit/MTOutputStream.m +++ b/MTProtoKit/MTOutputStream.m @@ -37,6 +37,11 @@ static inline int roundUp(int numToRound, int multiple) return self; } +- (NSOutputStream *)wrappedOutputStream +{ + return _wrappedOutputStream; +} + - (void)dealloc { [_wrappedOutputStream close]; diff --git a/MTProtoKit/MTProto.h b/MTProtoKit/MTProto.h index 9365c6af65..2ded29dbb8 100644 --- a/MTProtoKit/MTProto.h +++ b/MTProtoKit/MTProto.h @@ -34,6 +34,7 @@ @property (nonatomic) bool shouldStayConnected; @property (nonatomic) bool useUnauthorizedMode; +@property (nonatomic) bool preferMediaAddresses; @property (nonatomic) id requiredAuthToken; @property (nonatomic) NSInteger authTokenMasterDatacenterId; diff --git a/MTProtoKit/MTProto.m b/MTProtoKit/MTProto.m index fc58d05d1a..e5da377a36 100644 --- a/MTProtoKit/MTProto.m +++ b/MTProtoKit/MTProto.m @@ -1953,7 +1953,10 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64; shouldRequest = true; if (shouldRequest) + { [self requestMessageWithId:detailedInfoMessage.responseMessageId]; + MTLog(@"[MTProto#%p will request message %" PRId64 "", self, detailedInfoMessage.responseMessageId); + } else { [_sessionInfo scheduleMessageConfirmation:detailedInfoMessage.responseMessageId size:(NSInteger)detailedInfoMessage.responseLength]; diff --git a/MTProtoKit/MTTcpConnection.h b/MTProtoKit/MTTcpConnection.h index db03ad646e..5724071451 100644 --- a/MTProtoKit/MTTcpConnection.h +++ b/MTProtoKit/MTTcpConnection.h @@ -33,6 +33,11 @@ @interface MTTcpConnection : NSObject @property (nonatomic, weak) id delegate; + +@property (nonatomic, copy) void (^connectionOpened)(); +@property (nonatomic, copy) void (^connectionClosed)(); +@property (nonatomic, copy) void (^connectionReceivedData)(NSData *); + @property (nonatomic, strong, readonly) id internalId; @property (nonatomic, strong, readonly) MTDatacenterAddress *address; @property (nonatomic, strong, readonly) NSString *interface; diff --git a/MTProtoKit/MTTcpConnection.m b/MTProtoKit/MTTcpConnection.m index 7f74a2bd8a..aff0d1634c 100644 --- a/MTProtoKit/MTTcpConnection.m +++ b/MTProtoKit/MTTcpConnection.m @@ -115,8 +115,10 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096; MTLog(@"[MTTcpConnection#%x connecting to %@:%d]", (int)self, _address.ip, (int)_address.port); + NSString *ip = _address.ip; + __autoreleasing NSError *error = nil; - if (![_socket connectToHost:_address.ip onPort:_address.port viaInterface:_interface withTimeout:12 error:&error] || error != nil) + if (![_socket connectToHost:ip onPort:_address.port viaInterface:_interface withTimeout:12 error:&error] || error != nil) [self closeAndNotify]; else [_socket readDataToLength:1 withTimeout:-1 tag:MTTcpReadTagPacketShortLength]; @@ -145,6 +147,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096; _socket.delegate = nil; _socket = nil; + if (_connectionClosed) + _connectionClosed(); id delegate = _delegate; if ([delegate respondsToSelector:@selector(tcpConnectionClosed:)]) [delegate tcpConnectionClosed:self]; @@ -374,6 +378,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096; _packetHead = nil; } + if (_connectionReceivedData) + _connectionReceivedData(packetData); id delegate = _delegate; if ([delegate respondsToSelector:@selector(tcpConnectionReceivedData:data:)]) [delegate tcpConnectionReceivedData:self data:packetData]; @@ -402,6 +408,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096; - (void)socket:(GCDAsyncSocket *)__unused socket didConnectToHost:(NSString *)__unused host port:(uint16_t)__unused port { + if (_connectionOpened) + _connectionOpened(); id delegate = _delegate; if ([delegate respondsToSelector:@selector(tcpConnectionOpened:)]) [delegate tcpConnectionOpened:self]; diff --git a/MtProtoKit.xcodeproj/project.pbxproj b/MtProtoKit.xcodeproj/project.pbxproj index 6c924ebf83..ef9446b9ef 100644 --- a/MtProtoKit.xcodeproj/project.pbxproj +++ b/MtProtoKit.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + D0580ABF1B0F3E7100E8235B /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */; }; + D0580AC21B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */; }; + D0580AC31B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m in Sources */ = {isa = PBXBuildFile; fileRef = D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */; }; D079AB9C1AF39B8000076F59 /* MtProtoKitMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D079AB9B1AF39B8000076F59 /* MtProtoKitMac.h */; settings = {ATTRIBUTES = (Public, ); }; }; D079ABB01AF39BA400076F59 /* MTProtoKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D063A31D18B158AE00C65116 /* MTProtoKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0CB05FC1ADC4483005E298F /* MtProtoKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0CB05FB1ADC4483005E298F /* MtProtoKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -250,6 +253,9 @@ D0503AD918B027F80074C3FE /* MTOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTOutputStream.m; path = MTProtoKit/MTOutputStream.m; sourceTree = ""; }; D0503ADC18B029480074C3FE /* MTInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTInputStream.h; path = MTProtoKit/MTInputStream.h; sourceTree = ""; }; D0503ADD18B029480074C3FE /* MTInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTInputStream.m; path = MTProtoKit/MTInputStream.m; sourceTree = ""; }; + D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SSignalKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos/SSignalKit.framework"; sourceTree = ""; }; + D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTDiscoverConnectionSignals.h; sourceTree = ""; }; + D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTDiscoverConnectionSignals.m; sourceTree = ""; }; D05A831718AFB3F9007F1076 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; D05A832818AFB3F9007F1076 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; D05A832B18AFB3F9007F1076 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -438,6 +444,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D0580ABF1B0F3E7100E8235B /* SSignalKit.framework in Frameworks */, D0D1A0721ADDE2FC007D9ED6 /* libz.dylib in Frameworks */, D0CB066B1ADC48C4005E298F /* libcrypto.a in Frameworks */, ); @@ -453,6 +460,8 @@ D063A33518B161B600C65116 /* MTTransportScheme.m */, 9389BC5918DA2BD300F9C1A6 /* MTDiscoverTransportSchemeAction.h */, 9389BC5A18DA2BD300F9C1A6 /* MTDiscoverTransportSchemeAction.m */, + D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */, + D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */, ); name = "Transport Scheme"; sourceTree = ""; @@ -578,6 +587,7 @@ D05A831618AFB3F9007F1076 /* Frameworks */ = { isa = PBXGroup; children = ( + D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */, D0D1A0711ADDE2FC007D9ED6 /* libz.dylib */, D063A2F918B14AB500C65116 /* libcrypto.dylib */, D05A831718AFB3F9007F1076 /* Foundation.framework */, @@ -1105,6 +1115,7 @@ D0CB06581ADC45CE005E298F /* MTNetworkAvailability.h in Headers */, D0CB06601ADC45CE005E298F /* MTHttpWorkerBehaviour.h in Headers */, D0CB06211ADC454C005E298F /* MTKeychain.h in Headers */, + D0580AC21B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h in Headers */, D0CB065F1ADC45CE005E298F /* MTHttpWorker.h in Headers */, D0CB063B1ADC4591005E298F /* MTPreparedMessage.h in Headers */, D0CB065E1ADC45CE005E298F /* MTHttpTransport.h in Headers */, @@ -1271,6 +1282,7 @@ D0CB06141ADC44B7005E298F /* MTQueue.m in Sources */, D0CB06711ADC4A50005E298F /* MTTransportScheme.m in Sources */, D0D1A04B1ADD983C007D9ED6 /* MTMsgContainerMessage.m in Sources */, + D0580AC31B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m in Sources */, D0CB06341ADC4588005E298F /* MTDatacenterAddress.m in Sources */, D0CB06111ADC44B7005E298F /* MTTimer.m in Sources */, D0CB062E1ADC457B005E298F /* MTDatacenterAuthAction.m in Sources */, @@ -1509,6 +1521,10 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos", + ); GCC_NO_COMMON_BLOCKS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MtProtoKitiOS/MtProtoKit-Prefix.pch"; @@ -1553,6 +1569,10 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos", + ); GCC_NO_COMMON_BLOCKS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MtProtoKitiOS/MtProtoKit-Prefix.pch"; @@ -1598,6 +1618,7 @@ D079ABAB1AF39B8000076F59 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; D0CB060E1ADC4483005E298F /* Build configuration list for PBXNativeTarget "MtProtoKit" */ = { isa = XCConfigurationList; diff --git a/thirdparty/AFNetworking/AFHTTPRequestOperation.h b/thirdparty/AFNetworking/AFHTTPRequestOperation.h index fb9a961f7a..111384296f 100644 --- a/thirdparty/AFNetworking/AFHTTPRequestOperation.h +++ b/thirdparty/AFNetworking/AFHTTPRequestOperation.h @@ -77,17 +77,17 @@ /** The callback dispatch queue on success. If `NULL` (default), the main queue is used. */ -@property (nonatomic) dispatch_queue_t successCallbackQueue; +@property (nonatomic, strong) dispatch_queue_t successCallbackQueue; /** The callback dispatch queue on failure. If `NULL` (default), the main queue is used. */ -@property (nonatomic) dispatch_queue_t failureCallbackQueue; +@property (nonatomic, strong) dispatch_queue_t failureCallbackQueue; /** The dispatch group on which to call the completion/failure block */ -@property (nonatomic) dispatch_group_t dispatchGroup; +@property (nonatomic, strong) dispatch_group_t dispatchGroup; /** A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`. diff --git a/thirdparty/AFNetworking/AFHTTPRequestOperation.m b/thirdparty/AFNetworking/AFHTTPRequestOperation.m index d1b793d061..aa36079f66 100644 --- a/thirdparty/AFNetworking/AFHTTPRequestOperation.m +++ b/thirdparty/AFNetworking/AFHTTPRequestOperation.m @@ -38,11 +38,11 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } if (range.length == 1) { - [string appendFormat:@"%u", range.location]; + [string appendFormat:@"%lu", (unsigned long)range.location]; } else { NSUInteger firstIndex = range.location; NSUInteger lastIndex = firstIndex + range.length - 1; - [string appendFormat:@"%u-%u", firstIndex, lastIndex]; + [string appendFormat:@"%lu-%lu", (unsigned long)firstIndex, (unsigned long)lastIndex]; } range.location = nextIndex;