如何在iOS上使用Objective-C触发按需VPN

时间:2014-04-07 15:00:08

标签: objective-c ios7 dns httprequest vpn

我有一个iPad应用程序,它使用C中的套接字库打开与Intranet中服务器的套接字连接。启动应用程序时,如果iPad未连接到同一网络(即无法解析服务器的域名),我希望它能自动建立VPN连接。但是应用程序中的套接字调用和getaddrinfo()方法无法做到这一点。他们只是无法连接到服务器而不尝试打开VPN连接。

使用Safari,浏览到地址" http://..."工作正常并成功启动VPN。如果我使用下面的代码在应用程序的开头发出类似的HTTP请求,我可以让它启动VPN连接。但发送额外的http请求对我来说是最好的解决方案。只要iPad需要解析域名,VPN就应该启动,而不依赖于协议或远程端口号。

NSString* urlForVPN = @"http://..";
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlForVPN] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
[NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];

在Apple开发者网站上,它说"避免在连接到主机之前解析DNS名称。连接到主机的首选方法是使用接受DNS名称的API,例如 CFHost CFNetService " (https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html)。因此,我希望以下代码在尝试解析服务器名称时应启动VPN,但它也不起作用。它只是无法获得IP地址。我不得不手动打开VPN以使其连接到服务器。

NSString* hostname = @"myserver";
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
BOOL isSuccess = CFHostStartInfoResolution(hostRef, kCFHostAddresses, nil);

如何让应用程序了解它需要启动VPN? 是" VPN点播"仅适用于URL连接?

2 个答案:

答案 0 :(得分:0)

从我通过文章和第一手资料中了解到的内容,VPN-on-Demand只会在您使用使用WebKit的Apple库(NSURLSession,NSURLConnection等)时触发。

因此,基于套接字的网络请求无法触发Apple的On-Demand VPN。

此处显示支持此文档的文档: https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html#//apple_ref/doc/uid/TP40010220-CH4-SW2

答案 1 :(得分:0)

对于那些遇到此问题的人来说,使用POSIX套接字不会触发按需VPN,因为这些规则按域匹配,并且这些套接字没有域信息。

一种解决方法是通过通常的NSURLSession / NSURLConnection向正确的域启动虚拟请求,以仅触发VPN。

您可能还想get the reachability status并检查“ kSCNetworkReachabilityFlagsTransientConnection”,凭经验,当VPN连接可用时,它会变为“ kSCNetworkReachabilityFlagsTransientConnection”(因为许多现代VPN基于ppp)。通过这种方式,您可以检测到VPN何时关闭以启动另一个虚拟请求。