#import "MTConnectionProbing.h" #if defined(MtProtoKitDynamicFramework) # import # import # import # import # import # import # import # import # import # import # import # import # import # import # import #elif defined(MtProtoKitMacFramework) # import # import # import # import # import # import # import # import # import # import # import # import # import # import # import #else # import # import # import # import # import # import # import # import # import # import # import # import # import # import # import #endif #import "PingFoundation.h" @interface MTPingHelper : NSObject { void (^_success)(); PingFoundation *_ping; } @end @implementation MTPingHelper - (instancetype)initWithSuccess:(void (^)())success { self = [super init]; if (self != nil) { _success = [success copy]; NSArray *hosts = @[ @"google.com", @"8.8.8.8" ]; NSString *host = hosts[(int)(arc4random_uniform((uint32_t)hosts.count))]; _ping = [[PingFoundation alloc] initWithHostName:host]; _ping.delegate = self; [_ping start]; } return self; } - (void)dealloc { _ping.delegate = nil; [_ping stop]; } - (void)stop { } - (void)pingFoundation:(PingFoundation *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber { if (_success) { _success(); } } - (void)pingFoundation:(PingFoundation *)pinger didStartWithAddress:(NSData *)__unused address { [pinger sendPingWithData:nil]; } @end @implementation MTConnectionProbing + (MTSignal *)pingAddress { return [[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { MTQueue *queue = [MTQueue mainQueue]; MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init]; [queue dispatchOnQueue:^{ MTPingHelper *helper = [[MTPingHelper alloc] initWithSuccess:^{ [subscriber putNext:@true]; [subscriber putCompletion]; }]; [disposable setDisposable:[[MTBlockDisposable alloc] initWithBlock:^{ [helper stop]; }]]; }]; return disposable; }]; } + (MTSignal *)probeProxyWithContext:(MTContext *)context datacenterId:(NSInteger)datacenterId settings:(MTSocksProxySettings *)settings { MTSignal *proxyAvailable = [[[MTProxyConnectivity pingProxyWithContext:context datacenterId:datacenterId settings:settings] map:^id(MTProxyConnectivityStatus *status) { return @(status.reachable); }] timeout:10.0 onQueue:[MTQueue concurrentDefaultQueue] orSignal:[MTSignal single:@false]]; MTSignal *referenceAvailable = [[self pingAddress] timeout:10.0 onQueue:[MTQueue concurrentDefaultQueue] orSignal:[MTSignal single:@false]]; MTSignal *combined = [[MTSignal combineSignals:@[proxyAvailable, referenceAvailable]] map:^id(NSArray *values) { NSNumber *proxy = values[0]; NSNumber *ping = values[1]; if (![proxy boolValue] && [ping boolValue]) { return @true; } else { return @false; } }]; return combined; } @end