WinSock (Windows Sockets)ってOS毎に挙動が異なる場合がありますが、決して不具合(バグ)ではありません。。。。


こんにちは小泉です。

季節がらクリスマスの話題といきたいのですが、今回もいつもの如くクリスマスのような時事ネタは全く無視して、WinSock API  について記載させていただきますね。

WinSock API を利用して通信プログラムを開発する場合、下層部で利用する通信プロトコルはTCP や UDP を利用するシナリオが多いかと思います。このため、OS の TCP/IP のプロトコル スタックの仕様変更や機能向上に合わせて、WinSock API の動作にも OS 毎に違いが発生するわけです。もちろん、この違いは WinSock API の不具合(バグ)ではなく、れっきとした仕様動作となります。というわけで、そろそろ Windows 8 の足音も聞こえてきたので、ここで少し既存の OS に関して WinSock API の挙動の違いをおさらいしてみましょう。

( なお、本件は WinSock  API  について記載していますが、.NET Framework の System.Net.Sockets 名前空間で提供している Socket、TcpClient、NetworkStream クラスでも同じ動作となります。)

 

SYN 攻撃保護(Syn Attack Protect

Windows Server 2003 SP1 以降では、Dos 攻撃の一種である SYN 攻撃に対する保護機能が既定で有効となっております。このため、Windows Server 2003 SP なし や Windows 2000 Server に対する接続にてバックログを超えた場合は、クライアントアプリケーション側の connect  API にて 10061 (WSAECONNREFUSED) エラーが返されていたものが、Windows Server 2003 SP1 以降ではクライアント アプリケーション側の connect API の成功後の send API や recv API 等で 10054(WSAECONNRESET) エラーが発生する動作に変わります。

<参考技術情報>

Microsoft Windows Server 2003 Service Pack 1 の新しいネットワーク機能

http://technet.microsoft.com/ja-jp/library/bb878132.aspx

詳細は「SYN 攻撃保護が既定で有効」の欄をご参照ください。

 

Microsoft Windows Server 2003 TCP/IP 実装詳細

http://technet.microsoft.com/ja-jp/library/cc758746(WS.10).aspx#ID0EFGCI

詳細は「SynAttackProtect」の欄をご参照ください。

 

同時接続数の制限(Half-open TCP connections limit)

Windows XP SP2 以降にて、ウイルスの拡散防止や悪意のあるプログラムがサーバーに対して DoS 攻撃ができないようにTCP 接続の同時試行数の制限が10 に制限されました。

この結果、SYNSENT 状態の接続数が10以上になると、以降は connect API が失敗します。

なお、現在、TCP 接続の同時試行数の制限は対応策としてあまり一般的な手法ではなくなったため、Windows Vista SP2 以降では制限自体を廃止しております。

 

<参考技術情報>

How to enable the half-open TCP connections limit in Windows Vista with Service Pack 2 and in Windows Server 2008 with Service Pack 2

 http://support.microsoft.com/kb/969710/en-us

 

“Windows XP Service Pack 2 セキュリティ強化機能搭載” での機能の変更点 ‐ 第 2 部 : ネットワーク保護技術

http://technet.microsoft.com/ja-jp/library/bb457156.aspx

詳細は「不完全な送信 TCP 接続の同時試行数の制限」の欄をご参照ください。

 

LAN ケーブル の切断の検知

Windows Vista 以降では、故意 ( PC の移動等) や過失により自ホストの LAN ケーブルが抜かれた場合でも、LAN ケーブルが再接続された際に通信が可能な限り継続できるよう対障害性の向上がされております。これは、昨今の無線 LAN の普及に伴い、瞬断が発生しやすい接続が不安定な通信に対してもアプリケーションレベルでは可能な限り安定した通信を提供できるようにと考慮した機能向上となります。

この結果、Windows Vista より以前の OS  ( Windows XP や Windows Server 2003 )では、recv API 等にて受信待機中に自ホストの LAN ケーブルが抜かれると、数秒後に 10054 (WSAECONNRESET) エラーが返されていましたが、Windows Vista 以降ではエラーは返りません。Windows Vista 以降では、自ホストの LAN ケーブルが抜かれた後、send API 等にて実際にデータの送信を開始し、通信相手にデータが届かないと判断された際に初めて 10054 (WSAECONNRESET) エラーを検知します。もちろん、10054 (WSAECONNRESET) エラーが検知されるまでに LAN ケーブルを元に戻すと、何事もなかったかのように通信を再開させる事ができます。

もし、Windows Vista 以降にて、Windows Vista より以前の OS のように LAN ケーブルが抜かれたことを Winsock API で検知させたい場合は、SO_KEEPALIVE socket option を利用して KEEP ALIVE パケットを定期的に送信させることをご検討ください。厳密には、自ホストの LAN ケーブルが抜かれたのではなく、通信相手までの何れかの通信経路で障害が発生した事の検知となりますが、KEEP ALIVE パケットにて通信相手にデータが届かないと判断されると、同様に recv API 等にて受信待機中にエラーを発生させることも可能となります。

 

<参考技術情報>

 SO_KEEPALIVE socket option
http://msdn.microsoft.com/en-us/library/ee470551

 

Raw ソケット (Raw Sockets)

Raw ソケットは、低レベルでアプリケーションが TCP や UDP パケットを作成し送信する事が可能な手法となります。

非常に強力で柔軟な通信を行える半面、悪用されるとセキュリティ上のリスクも高い手法となりますので、Windows XP SP2以降では以下の 3 点の制限事項を加え、セキュアにご利用いただけるようになりました。

  • TCP データの送信を禁止しました。
  • 自身のIPアドレス以外のIPアドレスを指定して UDP データグラムを送信することを禁止しました。
  • IPPROTO_TCP を用いたソケットでの bind APIの実行を禁止しました。

 

<参考技術情報>

“Windows XP Service Pack 2 セキュリティ強化機能搭載” での機能の変更点 ‐ 第 2 部 : ネットワーク保護技術

http://technet.microsoft.com/ja-jp/library/bb457156.aspx

詳細は「raw ソケット経由のトラフィックの制限」の欄をご参照ください。

 

TCP/IP Raw Sockets

http://msdn.microsoft.com/en-us/library/ms740548.aspx

詳細は「Limitations on Raw Sockets」の欄をご参照ください。

 

 

以上が主な違いとなります。ご参考になりましたでしょうか。

例年、クリスマスも超えると「あっ」という間に今年も終わり。忘年会、仕事納め、大掃除とイベントが盛りだくさんで大変ですが、皆様も体調を崩さないよう頑張っていきましょう!!

と言いつつ、私は少し風邪気味かもしれません・・・・・・喉が痛いです。


Skip to main content