Unixソケット(AF_UNIX)を利用し、Win32プロセス間でプロセス間通信が可能に
先日リリースされた「Build 17063」で「UNIXソケット(AF_UNIX)」が利用できるようになり、UNIXソケット(UNIXドメインソケット)を利用してWin32プロセス間でプロセス間通信(IPC)が行えるようになりました。プロセス間通信とは、異なるプロセス間でデータのやり取りを行う仕組みのことです。
例えばAというアプリとBというアプリでデータのやり取りが可能になります。
もちろん元々「Windows」でもプロセス間通信は可能です。
しかしプロセス間通信の手法にはいくつか種類があり、「Linux」や「BSD」でよく使われるUNIXソケットを利用したプロセス間通信は、今まで「Windows」上で利用することができませんでした。
アプリの移植コストやメンテナンスコストの削減
「Windows」ではIPCに「名前付きパイプ」という仕組みを提供しています。しかし「名前付きパイプ」とUNIXソケットの使い方は異なっており、メンテナンスコストを抑えたクロスプラットフォームのソフトウェアの開発が困難になっていました。
例えば接続を終了させる手続きにおいてUNIXソケットでは、双方向の通信を閉じる意味を持つ「shutdown」というAPI(BSD Socket APIの1つ)を利用できます。
一方「名前付きパイプ」では、それと同じ意味を持つAPIは提供されていません。
このような違いがあるため、UNIXソケットを利用してるLinuxのソフトウェアをWindowsに移植するには、相応のコストがかかり移植を困難なものにしています。
逆もまた然りです。
Winsock APIでAF_UNIXが利用可能に
「Build 17063」ではUNIXソケットがネイティブにサポートされ、BSD Socket APIに非常に似た「Winsock API」を通じて「AF_UNIX」を利用し、Win32プロセス間でプロセス間通信(IPC)が行えるようになりました。現状はSOCK_STREAMのみサポート
現状利用できるソケットタイプは、「SOCK_STREAM」のみです。「SOCK_STREAM」は、プロセスが1:1で通信を行う接続形態で使用されるソケットです。
「SOCK_DGRAM」ソケットタイプのサポートに関しては、フィードバックや需要等を考慮して、将来のビルドでサポートされる可能性があります。
sockaddr_un構造体
「sockaddr_un」構造体は、UNIXソケットのアドレスを定義するために使用される構造体です。Windowsの実装では、クロスプラットフォームの開発を容易にするため、UNIXソケットアドレスの名称や定義、そして意味がLinuxのそれと同じになるように実装されています。
3種類のアドレスフォーマット
UNIXソケットのアドレスには、以下の3種類の異なるアドレスフォーマットがあります。- パス名(pathname)
- 抽象(abstract)
- 無名(unnamed)
パス名によるアドレスは、ファイルシステムに結び付けらるアドレスであり、Windowsの実装でサポートされています。
「sockaddr_un.sun_path」には、NULL文字で終端するファイルシステム上のパスをUTF-8で指定します。
抽象によるアドレスは、「sockaddr_un.sun_path」にNULLバイト(\0)が入ります。
Windowsの実装では抽象によるアドレスをサポートしていますが、現在の実装では自動バインド(autobind)機能をサポートしていないため、抽象アドレスは自動的に生成されます。
無名によるアドレスはパス名に結び付けられないアドレスであり、このアドレスもWindowsの実装ではサポートされています。
しかし「Winsock 2.0」では無名のソケットを生成するSocket APIの1つである「socketpair」をサポートしていません。
ソケットとセキュリティー
UNIXソケットは安全な通信を実現する仕組みを提供しています。パス名によるソケットでは、ファイルや(親)ディレクトリーのパーミッションを適切に設定することでUNIXソケット上の通信の安全性を制御することができます。
例えばSocket APIの「bind」は、ソケットファイルを指定されたパスに生成します。
もし呼び出し側のプロセスが指定されたパス上のディレクトリーに対し書き込み権限がない場合、ソケットファイルの生成に失敗します。
同様にソケットに接続するプロセスでは、そのソケットファイルに対し書き込み権限が必要になります。
Windowsの実装でも同レベルのセキュリティーが提供されています。
詳しくはAF_UNIXのヘルプ(man)を参照してください。
WindowsにおけるUNIXソケットの実装
Windowsが実装しているAF_UNIXの大部分の機能は、Windowsカーネル内で動作する「afunix.sys」ドライバーで実装されています。Windowsカーネルのネットワークスタックは、非常に柔軟性及び拡張性のあるモデルを提供しています。
これにより新しいネットワーク機能を簡単にサポートできるようになっています。
「bind」APIの呼び出しにより生成されるソケットファイルは、NTFSのリパースポイントをカスタムしたもので実現されています。
サポートされていない機能
現時点で以下の機能はサポートされていません。ソケットタイプ
以下のソケットタイプはサポートされていません。- SOCK_DGRAM
- SOCK_SEQPACKET
補助データ
LinuxのUNIXソケットは、「SCM_RIGHTS」や「SCM_CREDENTIALS」といった補助データをサポートしています。Windowsの実装では、補助データはサポートされていません。
自動バインド機能
自動バインド(autobind)機能はサポートされていません。socketpair
「socketpair」は「Winsock 2.0」でサポートされていません。AF_UNIXを利用したWindowsアプリを開発するには
AF_UNIXを利用したWindowsアプリを開発する方法です。1.Windows 10 SDK Preview Build 17061のダウンロード
「Windows 10 SDK Preview Build 17061」をダウンロードします。2.afunixサービスが動作しているか確認する
管理者として実行したコマンドプロンプトから以下のコマンドを実行し、afunixサービスが動作しているか確認します。
sc query afunix
3.ヘッダーファイルのインクルード
ソースコードで以下の記述を行い、「afunix.h」をインクルードします。#include <afunix.h>
後は他のUNIXソケットを利用したアプリケーションの開発と同じように、「Winsock API」を利用してUNIXソケットの処理を記述します。
注意事項
ソケットファイルはファイルシステム内に生成されます。Linuxでは同じパスにソケットファイルを生成する前に、そのソケットファイルに対し「unlink」することが求められます。
Windowsでも同様に「bind」を実行する前に「DeleteFile」などファイルを削除するAPIを利用してソケットファイルを削除する必要があります。