macでipv6環境を作成して、iosでsockaddr_inを利用しても動作してしまう

投稿者: Anonymous

ipv6検証をするためにios Developer CenterのTest for IPv6 DNS64/NAT64 Compatibility Regularlyを参考にipv6環境をmacに作りました。

Qiitaでも同様のやり方が書かれていました。

そして、以下のコードで検証しようとしました。

Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

以下が該当のReachabilityのソースです。

+(instancetype)reachabilityForInternetConnection {
  struct sockaddr_in zeroAddress;
  bzero(&zeroAddress, sizeof(zeroAddress));
  zeroAddress.sin_len = sizeof(zeroAddress);
  zeroAddress.sin_family = AF_INET;

  return [self reachabilityWithAddress:&zeroAddress];
}

+(instancetype)reachabilityWithAddress:(void *)hostAddress {
   SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);

   if (ref) 
    {
     id reachability = [[self alloc] initWithReachabilityRef:ref];
     return reachability;
    }

   return nil;
}    

sockaddr_inはipv4用なので動作しないはずと考えていましたが、ios9.3.1で動作させたところ、普通に動作してしまいました。
(参考までにAFNetworkingのipv6対応を見ると sockaddr_in6 に変えていていました。)

なぜ動作してしまうのか、教えていただけると幸いです。

解決

推測ですが、AppleのReachabilityのサンプルソースのReadme
https://developer.apple.com/library/ios/samplecode/Reachability/Listings/ReadMe_md.html
には、

IPv6 Support

Reachability fully supports IPv6. More specifically, each of the APIs >handles IPv6 in the following way:

reachabilityForInternetConnection

This monitors the address 0.0.0.0, which reachability treats as a >special token that causes it to actually monitor the general routing >status of the device, both IPv4 and IPv6

とあるので、IPv4ではReachしないけど、IPv6でReachしているからOKということですかね。

iOS9.3.1でreachabilityWithAddressでIPv4アドレスリテラルを使うと失敗しますね。

struct sockaddr_in addr;
addr.sin_len = INET_ADDRSTRLEN;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("XXX.XXX.XXX.XXX"); // ここは適当な0.0.0.0でない有効なグローバルIPを入れる
Reachability* reachability = [Reachability reachabilityWithAddress:&addr];
[reachability startNotifier];
NSLog(@"reachable[%d]", reachability.currentReachabilityStatus); // ipv6環境では、NotReachableで、ipv4環境ではReachableViaWiFiになります

他のバージョンでは試してません。

この辺も見ておいた方が良さそうです。

https://github.com/AFNetworking/AFNetworking/issues/3498

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *