2015年7月18日土曜日

同一セグメントに割り当てたNICを複数備えたPCで不定期に通信が出来なくなる

長らく悩んでいたものが解決したので備忘録として残しておく。

[環境]
有線/無線のNICを備えたノートPCを利用しており、場所に応じて利用するNICを切り替えている。
どちらのNICも割り当てるセグメントは同じ。
有線側の方のメトリック値を小さくしておき、有線/無線のどちらも接続されている状態であれば、有線側で通信が行われるように制御。

[現象]
有線側を断線状態にし、無線側で利用していると不定期に外部通信が出来ない状態になる。
具体的には、
 最後に通信を行ってから30sec以上経過して、再度通信を試みると通信に失敗する。
 通信に失敗して再度通信を試みると通信に成功する。



[原因]
以下のレジストリが"1"になっていたため。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\DisableDHCPMediaSense

レジストリの意味は以下のURLを参照。

デフォルトでは上記レジストリは"0"であり、各NICのリンクダウンが検知されたタイミングで、バインドされているプロトコルは削除される。

Windowsは内部的にNUD(Neighbor Unreachable Detection)という機能を有しており、
どのNICが使用可能かをNUDに基づいて判定し、通信を行っている。
DisableDHCPMediaSense=1となっていると、リンクダウンしたNICのバインドが解除されないため、
断線している有線側(メトリック値の小さい方)で通信を試みてしまっていた。

ちなみに、NUDは前回通信に失敗したNICの情報を30sec程度キャッシュしているため、
その間に通信を試みた場合は、他の使用可能なNICが選択されるため、正常に通信が出来る模様。


[そもそも・・・]
何故DisableDHCPMediaSense=1にしていたか?
XPまではDisableDHCPMediaSense=1にしておく事で、NICが一時的にリンクダウンしている間でも、
IPアドレスを取得可能だったため、当時これを活用した仕組みを構築していた。

Vista以降、Windowsの仕様変更により、DisableDHCPMediaSense=1としていても、リンクダウンしている間にIPアドレスの取得は出来なくなり、別の対策を打ったが、DisableDHCPMediaSenseの存在を忘れたまま放置していた。。とさ。

0 件のコメント:

コメントを投稿