IPv4をIPv6に優先させる

下記の記事を書いた後、IPv6について改めて調べました


対処療法として、プリンタを指定する際にIPv4のアドレスを使用したり、Windows7のIP Helperサービスを無効にするなどして問題は解決していましたが、根本の原因はIPv4IPv6の共存にあることがわかりました。

  • TCPコネクション確立の際の問題

    • コネクションを確立しようとするとき、DNSクエリによってIPv4IPv6両方のレコードが帰ってくると、Windows7ではIPv6が優先されるので、ますIPv6でコネクションを確立しようとします。
    • ここで正常にIPv6でコネクションが確立できないと、タイムアウトの後IPv4で再挑戦するので、結果的にコネクションを確立するのに非常に時間がかかります


  • onlink assumption

    • このとき問題になるのが、IPv6の仕様にあるonlink assumptionです。これは、IPv6で割り当てられたアドレスにデフォルトゲートウェイが設定されていない場合、他のIPv6ノードはすべて同じセグメント上にあると仮定するという動作です。Windowsで実装されている自動アドレス構成(APIPA)のような機能と言ってよいでしょう。
    • この機能があるため、不完全なIPv6ネットワーク上で仮に割り当てられたアドレスでも、一度はIPv6でコネクションを確立しようとしてしまいます。
    • 個人的には、この手の機能が有効に働くようなケースをほとんど想像できないので、なぜ広く実装されているのか甚だ疑問です。

  • 上記の問題は、IPv4の優先順位を上げることで解決することができます。
    こちらの情報が非常に参考になりました。

    参考: MURA's HomePage - IPv4 を IPv6 より優先にする

    現在の設定を確認するには、下記のコマンド

     netsh interface ipv6 show prefixpolicies


    アクティブ状態を照会しています...

    優先順位 ラベル プレフィックス
    ---------- ----- --------------------------------
    50 0 ::1/128
    40 1 ::/0
    30 2 2002::/16
    20 3 ::/96
    10 4 ::ffff:0:0/96
    5 5 2001::/32

    ここで、それぞれのプレフィックスは下記のアドレスを示します

     ::1/128        ループバック
    ::/0 IPv6通信全般
    2002::/16 6to4
    ::/96 IPv4互換
    ::ffff:0:0/96 IPv4マップ
    2001::/32 Teredo
    下記のコマンドで、::ffff:0:0/96 IPv4マップの優先順位を::1/128のループバックより上にする。

    netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 50 0
    netsh interface ipv6 set prefixpolicy ::1/128 40 1
    netsh interface ipv6 set prefixpolicy ::/0 30 2
    netsh interface ipv6 set prefixpolicy 2002::/16 20 3
    netsh interface ipv6 set prefixpolicy ::/96 10 4


    結果は下記の通り

     netsh interface ipv6 show prefixpolicies

    アクティブ状態を照会しています...

    優先順位 ラベル プレフィックス
    ---------- ----- --------------------------------
    50 0 ::ffff:0:0/96
    40 1 ::1/128
    30 2 ::/0
    20 3 2002::/16
    10 4 ::/96
    5 5 2001::/32

    設定を元に戻すには、下記のコマンドを実行し再起動します。

    netsh interface ipv6 reset



参考: IPv6普及高度化推進委員会 - LANや端末でIPv6を利用する際の問題

参考: ほっといたらIPv4運用に影響するIPv6の話

参考: IPv6 fix