IPv6 DNS64/NAT64ネットワークのサポート

IPv4アドレスプールが間もなく枯渇する状況にあるため、エンタープライズプロバイダーと携帯電話プロバイダーは、IPv6 DNS64およびNAT64ネットワークの導入ペースを上げています。DNS64/NAT64ネットワークは、IPv6専用のネットワークですが、変換を行うことにより、IPv4コンテンツへのアクセスが引き続き可能です。アプリケーションの性質によっては、これに対処するのが難しいかもしれません。

IPv6を採用する理由

米国の主要な携帯電話キャリアを含む、主要なネットワークサービスプロバイダーは、IPv6を積極的に推し進め、導入しています。これには、さまざまな要因があります。

IPv4アドレスの枯渇

長年の間、IPv4アドレスはやがて枯渇することがわかっていました。この状況を遅らせるのに役立ったのが、クラスレスドメイン間ルーティング(CIDR)やネットワークアドレス変換(NAT)などのテクノロジーでした。しかし、2011年1月31日、IANA(Internet Assigned Numbers Authority)は、IPv4アドレスのトップレベルプールが枯渇したことを正式に発表しました。ARIN(American Registry for Internet Numbers)は、IPv4アドレスが2015の夏には枯渇すると予測しています。IPv4アドレス枯渇のカウントダウンは、こちらで確認できます。

IPv4よりも効率的なIPv6

IPv4の枯渇問題の解決は別にして、IPv6はIPv4よりも効率的なプロトコルです。たとえば、IPv6には、次の特徴があります。

  • ネットワークアドレス変換(NAT)の必要がない

  • 簡素化されたヘッダを使うことにより、ネットワークルーティングの高速化が可能

  • ネットワークが断片化されない

  • 近隣アドレス解決のためのブロードキャストを回避

4Gの導入

第4世代の移動体通信テクノロジー(4G)は、パケット交換のみをベースにしています。IPv4アドレスの供給には限界があります。そのため、4Gの導入を拡張できるようにするには、IPv6のサポートが必要です。

マルチメディアサービスの互換性

IMS(IP Multimedia Core Network Subsystem)により、マルチメディアSMSメッセージングやVoLTE(Voice over LTE)などのサービスをIP経由で配信できます。一部のサービスプロバイダーが使うIMSは、IPv6としか互換性がありません。

料金

業界がIPv6への移行を続ける中、サービスプロバイダーは、既存のIPv4ネットワークのサポートを続けることにより、追加の運用コストと管理コストがかかります。

DNS64/NAT64による移行ワークフロー

IPv4アドレスの枯渇を遅くするために、多くのIPv4ネットワークでは、NATが実装されました。この解決策は一時的には有効でしたが、コストがかかり、脆弱であることがわかりました。現在、IPv6を使うクライアントが増えているため、プロバイダーは、IPv4とIPv6の両方をサポートする必要があります。これはコストのかかる試みです。

図10-1 IPv4接続とIPv6接続を別々に提供する携帯電話ネットワーク

プロバイダーとしては、IPv4ネットワークのサポートを廃止できれば理想的です。しかし、そうすれば、インターネットの重要な部分であるIPv4サーバにクライアントはアクセスできなくなります。この問題を解決するために、主要なネットワークプロバイダーの大半は、DNS64/NAT64による移行ワークフローを実装しています。これはIPv6専用のネットワークですが、変換を行うことにより、IPv4コンテンツへのアクセスが引き続き可能です。

図10-2 DNS64およびNAT64とともにIPv6ネットワークを導入する携帯電話ネットワーク

このタイプのワークフローでは、クライアントがDNSクエリをDNS64サーバに送信し、DNS64サーバがDNSサーバからのIPv6アドレスを要求します。IPv6アドレスが見つかると、ただちにクライアントに渡されます。ただし、IPv6アドレスが見つからない場合、DNS64サーバは、代わりにIPv4アドレスを要求します。この場合、DNS64サーバは、IPv4アドレスをプレフィックス変換してIPv6アドレスを合成し、クライアントに渡します。この点で、クライアントは常にIPv6対応アドレスを受信します。図10-3を参照してください。

図10-3 DNS64によるIPv4からIPv6への変換プロセス

クライアントがサーバに要求を送信する場合、合成されたアドレスに向かうIPv6パケットは、NAT64ゲートウェイを通じてネットワークにより自動ルーティングされます。このゲートウェイは、要求のアドレスとプロトコルをIPv6からIPv4へと変換します。また、サーバからの応答をIPv4からIPv6に変換する操作も行います。図10-4を参照してください。

図10-4 DNS64/NAT64による移行ソリューションのワークフロー

IPv6およびApp Storeの要件

IPv6 DNS64/NAT64ネットワークとの互換性がApp Storeの送信要件になります。そのため、アプリケーションで互換性を保証することが必要です。幸いなことに、アプリケーションの大多数は、すでにIPv6に対応しています。ただし、これらのアプリケーションは、定期的に回帰テストすることが重要です。IPv6に対応していないアプリケーションは、DNS64/NAT64ネットワークで実行したときに問題が発生する場合があります。幸いにも、これらの問題は通常は非常に簡単に解決できます。詳しくは、この章全体で説明します。

IPv6をサポートする際のよくある障壁

アプリケーションがIPv6をサポートできない状況がいくつかあります。以降のセクションでは、これらの問題の解決方法を説明します。

IPv6 DNS64/NAT64の互換性の保証

お使いのアプリケーションでのIPv6 DNS64/NAT64の互換性を保証するために、次のガイドラインに従ってください。

高レベルネットワークフレームワークの使用

ネットワーク接続が必要なアプリケーションは、高レベルネットワークフレームワークまたは低レベルPOSIXソケットAPIを基に構築できます。ほとんどの場合は、高レベルフレームワークで十分です。高レベルフレームワークは、機能性に優れ、使いやすく、低レベルAPIに比べると、よくある落とし穴に陥りにくくなっています。

図10-5ネットワークフレームワークおよびAPI階層
  • WebKit。このフレームワークは、ウェブコンテンツをウィンドウで表示するための一連のクラスを備えており、ブラウザの機能(リンクの追跡、戻る-進むリストの管理、最近訪問したページの履歴管理など)を実装します。WebKitは、ウェブページを読み込む複雑なプロセス、つまり、HTTPサーバから非同期でウェブコンテンツを要求するプロセスを簡単に処理できるようにします(このプロセスでは、応答が増加的に到達したり、ランダムな順序で到達したり、ネットワークエラーのために部分的に到達したりします)。詳しくは、『WebKit Framework Reference』を参照してください。

  • Cocoa URLの読み込みシステム。このシステムは、IPアドレスを明示的に指定せずにネットワーク経由でデータを送受信するためのもっとも簡単な手段です。データは、NSURLオブジェクトとともに動作するいくつかのクラス(NSURLSessionNSURLRequestNSURLConnectionなど)のいずれかを使って送受信されます。NSURLオブジェクトを使うと、アプリケーションでURLと参照先のリソースを操作できます。initWithString:メソッドを呼び出してURL指定子に渡すことにより、NSURLオブジェクトを作成します。NSURLクラスのcheckResourceIsReachableAndReturnError:メソッドを呼び出して、ホストの到達可能性をチェックします。詳しくは、『URLローディングシステムプログラミングガイド』を参照してください。

  • CFNetwork。Core Servicesフレームワークは、ネットワークプロトコルの抽象化のライブラリを備えています。これにより、さまざまなネットワークタスク、たとえば、BSDソケットの操作、DNSホストの解決、HTTP/HTTPSの操作などを簡単に行うことができます。IPアドレスを明示的に指定せずにホストをターゲットにするには、CFHostCreateWithNameメソッドを呼び出します。ホストへのTCPソケットのペアを開くには、CFStreamCreatePairWithSocketToCFHostメソッドを呼び出します。詳しくは、『CFNetwork Programming Guide』の「CFNetwork Concepts」を参照してください。

低レベルのソケットAPIが必要な場合は、『RFC4038:IPv6への移行におけるアプリケーションからの側面のガイドライン』に従ってください。

IPアドレスリテラルを使わない

ドット表記のIPv4アドレスリテラルをgetaddrinfoSCNetworkReachabilityCreateWithNameなどのAPIに渡していないことを確認します。その代わりに、高レベルのネットワークフレームワークとアドレスアグノスティックバージョンのAPI(getaddrinfogetnameinfoなど)を使って、それらにホスト名または完全修飾ドメイン名(FQDN)を渡します。『getaddrinfo(3) Mac OS X Developer Tools Manual Page』および『getnameinfo(3) Mac OS X Developer Tools Manual Page』を参照してください。

プリフライトなしの接続

到達可能性API(『SCNetworkReachability Reference』を参照)は、接続の問題を特定した、診断の目的で使うものです。多くのアプリケーションでは、このAPIが誤って使われています。つまり、SCNetworkReachabilityCreateWithAddressメソッドを呼び出して0.0.0.0のIPv4アドレスをAPIに渡し、インターネット接続を事前にチェックするために使われています(これは、ネットワークにルーターがあることを示しています)。しかし、ルーターが存在していても、インターネット接続が存在するとは限りません。一般的には、ネットワーク到達可能性のプリフライトは回避します。単に接続の確立を試み、適切に障害を処理します。ネットワークの可用性をチェックする場合は、SCNetworkReachabilityCreateWithAddressメソッドを呼び出さないでください。その代わりに、SCNetworkReachabilityCreateWithNameメソッドを呼び出し、ホスト名を渡してください。

アプリケーションによっては、自分で割り当てたリンクローカルアドレスである、169.254.0.0というIPv4アドレスをSCNetworkReachabilityCreateWithAddressメソッドに渡し、アクティブなWi-Fi接続が存在しないかチェックするものもあります。Wi-Fiまたは携帯電話の接続をチェックするには、代わりにネットワーク到達可能性フラグkSCNetworkReachabilityFlagsIsWWANを探してください。

適性サイズのストレージコンテナの使用

余裕をもってIPv6アドレスを保存できるサイズのアドレスストレージコンテナ(sockaddr_storageなど)を使います。

ソースコードをチェックし、IPv6 DNS64/NAT64との非互換性がないか確認する

次のようなIPv4固有のAPIがないか確認し、あれば削除します。

  • inet_addr()

  • inet_aton()

  • inet_lnaof()

  • inet_makeaddr()

  • inet_netof()

  • inet_network()

  • inet_ntoa()

  • inet_ntoa_r()

  • bindresvport()

  • getipv4sourcefilter()

  • setipv4sourcefilter()

コードでIPv4タイプが処理される場合は、対応するIPv6タイプも処理されることを確認します。

IPv4

IPv6

AF_INET

AF_INET6

PF_INET

PF_INET6

struct in_addr

struct in_addr6

struct sockaddr_in

struct sockaddr_in6

kDNSServiceProtocol_IPv4

kDNSServiceProtocol_IPv6

システムAPIによるIPv6アドレスの合成

アプリケーションが、DNSホスト名のない、IPv4のみのサーバに接続する必要がある場合、getaddrinfoでIPv4アドレスのリテラルを解決します。現在のネットワークインターフェイスがIPv4に対応しておらず、IPv6、NAT64、DNS64には対応しているという場合、この手順でIPv6アドレスを合成できます。

リスト10-1に、getaddrinfoをつかってIPv6リテラルを解決する方法を示します。4バイトのメモリ領域にIPv4アドレス(たとえば、{192, 0, 2, 1})を格納しているとしましょう。例として示したコードは、これを"192.0.2.1"のような文字列に変換し、getaddrinfoを使ってIPv6アドレス(「"64:ff9b::192.0.2.1"」というIPv6アドレスを収容するstruct sockaddr_in6)を合成し、このIPv6アドレスに接続しようと試みます。

リスト10-1  getaddrinfoを使ってIPv4アドレスのリテラルを解決するコード例

#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
 
    uint8_t ipv4[4] = {192, 0, 2, 1};
    struct addrinfo hints, *res, *res0;
    int error, s;
    const char *cause = NULL;
 
    char ipv4_str_buf[INET_ADDRSTRLEN] = { 0 };
    const char *ipv4_str = inet_ntop(AF_INET, &ipv4, ipv4_str_buf, sizeof(ipv4_str_buf));
 
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_DEFAULT;
    error = getaddrinfo(ipv4_str, "http", &hints, &res0);
    if (error) {
        errx(1, "%s", gai_strerror(error));
        /*NOTREACHED*/
    }
    s = -1;
    for (res = res0; res; res = res->ai_next) {
        s = socket(res->ai_family, res->ai_socktype,
                   res->ai_protocol);
        if (s < 0) {
            cause = "socket";
            continue;
        }
 
        if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
            cause = "connect";
            close(s);
            s = -1;
            continue;
        }
 
        break; /* okay we got one */
    }
    if (s < 0) {
        err(1, "%s", cause);
        /*NOTREACHED*/
    }
    freeaddrinfo(res0);

IPv6 DNS64/NAT64の互換性の定期的なテスト

アプリケーションがIPv6 DNS64/NAT64と互換性があるかどうかをテストするもっとも簡単な方法は、MacでローカルIPv6 DNS64/NAT64ネットワークを設定することです(IPv6 DNS64/NAT64は、大部分の携帯電話キャリアが導入しているネットワークタイプです)。これにより、他のデバイスからこのネットワークにテスト目的で接続できます。図10-6を参照してください。

図10-6 MacベースのIPv6 DNS64/NAT64ローカルネットワーク

Macを使ってローカルIPv6 Wi-Fiネットワークを設定するには

  1. MacがWi-Fi以外でインターネットに接続していることを確認します。

  2. Dock、LaunchPad、またはアップルメニューからシステム環境設定を起動します。

  3. Optionキーを押して「共有」をクリックします。Optionキーはまだ放さないでください。

    図10-7共有環境設定のオープン
  4. 共有サービスのリストで「インターネット共有」を選択します。

    図10-8インターネット共有の構成
  5. 「option」キーを放します。

  6. 「NAT64ネットワークの作成」チェックボックスを選択します。

    図10-9ローカルIPv6 NAT64ネットワークの有効化
  7. インターネット接続を可能にするネットワークインターフェイス(Thunderbolt Ethernetなど)を選択します。

    図10-10共有するネットワークインターフェイスの選択
  8. 「Wi-Fi」チェックボックスを選択します。

    図10-11 Wi-Fi経由での共有の有効化
  9. 「Wi-Fiオプション」をクリックし、ネットワークのネットワーク名とセキュリティオプションを構成します。

    図10-12 Wi-Fiネットワークオプションへのアクセス
    図10-13ローカルWi-Fiネットワークオプションの設定
  10. 「インターネット共有」チェックボックスを選択し、ローカルネットワークを有効にします。

    図10-14インターネット共有の有効化
  11. 共有を開始するかどうかを尋ねられたら、「開始」をクリックします。

    図10-15インターネット共有の開始

共有が有効になると、緑のステータスライトと「インターネット共有:オン」というラベルが表示されます。「Wi-Fi」メニューには、小さく薄い上向き矢印も表示されます。これは、インターネット共有が有効であることを示しています。以上でIPv6 NAT64ネットワークが利用可能になり、アプリケーションをテストするために他のデバイスからこのネットワークに接続できるようになりました。

図10-16インターネット共有インジケータ

ローカルテストの制限

MacベースのIPv6 DNS64/NAT64ネットワークは、IPv6環境でアプリケーションをテストするための便利なツールです。ただし、常に合成したIPv6アドレスを生成し、IPv4を使ってWAN側でデータを転送するため、サービスプロバイダーによって提供されるネットワークの厳密な複製ではありません。これらのネットワーク(およびアプリケーション審査で使用されるネットワーク)は、IPv6同士の直接接続を許可します。サーバの構成が誤っていると、通常使用またはレビュー中にアプリケーションがローカルテスト時と異なる動作をする場合があります。アプリケーション審査不合格という結果になり、自分の環境で再現が難しい場合もあります。

特に、お使いのサーバがIPv6のサポートを主張しているが、実際にはサポートしていない場合に、問題が発生する可能性があります。この場合、最初のテスト時に、アプリケーションがIPv6パスでサーバと通信しているように見え、適切に動作します。しかし実際には、テストネットワークが、アプリケーションが生成するIPv6トラフィックをWAN側でIPv4トラフィックに変換しています。したがって、実際にはサーバのIPv4データパスを使っています。後で、アプリケーション審査(または実社会)で、アプリケーションは同じように動作しますが、ネットワークはサーバに対して直接IPv6接続を行います。サーバがIPv6トラフィックに正しく応答できない場合、アプリケーションは正常に動作せず、アプリケーション審査で不合格となる場合があります。

このような状況を避けるため、MacベースのIPv6 DNS64/NAT64テストネットワークを使ってアプリケーションの検証を行うだけでなく、サーバがIPv6サーバとして正しく機能していることを検証してください。たとえば、サーバの以下の点を確認します。

  • 正しいDNS情報を持っている。サーバ自体の調査に加えて、Macからコマンドラインツールdig(1)を使って、サーバがAAAAレコードをどのように報告するか確認できます。

  • サーバが実際にIPv6でリッスンしている。ipv6-test.comなどのツールを使ってウェブサーバ(HTTPまたはHTTPS)をテストします。ほかのプロトコルの場合は、ネイティブのIPv6ネットワークからこれを検証する必要があります。

  • IPv6リクエストに正しく応答する。アクセスできる場合は、サーバログを調べて、IPv6トラフィックが正しく処理されていることを確認します。正しく処理されていない場合は、ネイティブのIPv6ネットワークからテストする必要があります。

関連情報

ネットワークの実装について詳しくは、次を参照してください。

IPv6への移行について詳しくは、次を参照してください。

IPv6への移行中に発生した技術的な問題については、次を参照してください。