現在プレビューが実施されている、Windows 10 Ver.2003となる20H1には、WSL2(Windows Subsystem for Linux 2)が搭載される予定だ。このWSL2では、Build 18945での改良で、Win32側からlocalhostでアクセスできるようになった。これで、WSL2側でHTTPサーバーなどを動かしたとき、Win32側からはWin32のネットワークサービス同様にlocalhostでアクセスが可能になる。
WSL2でのネットワークはどうなっている?
WSL2は、Linuxカーネルを仮想環境(軽量ユーティリティ仮想マシン)で実行するので、“ほぼLinux”として振る舞うことができる。WSL1には、Linuxカーネルは存在せず、LXSSと呼ばれるシステムが、Linuxのカーネル機能呼び出しをWindowsのAPIに変換していた。このため、WSL1のネットワークはすべてWin32側で処理されていた。
TCP/IPのネットワークスタックでは、接続管理のために複数のTCP/IPスタックを同一アドレスで同時に動かすことはできない。絶対に不可能かというとそうでもないのだが、2つのTCP/IPスタックソフトウェアが通信してお互いの状態を同期させるなどの処理では、ネットワークスタックとしての動作が遅くなってしまう。
そうなるとシステム全体の処理の足を引っ張ってしまい、性能がかなり低下する可能性が高い。それではあまり実用的ではないし、こうした実装をするなら、既存のTCP/IPスタックを完全に置き換える必要もあり、コストを考えると現実的には不可能な手法といえる。
というわけで、WSL2ではLinuxカーネルが持つTCP/IPスタックがそのまま使われる。となると、Win32と同じIPアドレスを持つことはできない。一般に仮想マシンでは、ネットワークインターフェースを仮想化し、仮想的なネットワークに接続させることが多い。Hyper-Vでも、仮想ネットワークインターフェースと仮想ネットワークを作って、こ実際の物理ネットワークインタフェースが接続する物理ネットワークの間でルーティングやブリッジを行なう。
WSL2も同じような構成になっている。WSL2を動かすと、「イーサーネットアダプター vEthernet(WSL)」という仮想ネットワークインターフェースが出現する。これが、仮想ネットワークのWin32側の接続点であり、WSL2側のデフォルトネットワークインターフェース(eth0)と同じ仮想ネットワークに接続している。
こうした構成であるため、Build 18945より前のWSL2では、WSL2側のネットワークサービスに接続する際には、WSL2の仮想ネットワークインターフェース(eth0)のIPアドレスを指定する必要があった。しかし、仮想ネットワークに接続する仮想イーサーネットインターフェースのIPアドレスは、再起動するたびに毎回違ったIPアドレスが割り当てられていた。このため、接続の指定をスクリプトなどに記述しておくことが困難だった。
Build 18945で進められた改良
Build 18945では、WSL2への接続に際してIPアドレスをlocalhostとして指定することが可能になった。ただし、localhostは、自分自身のIPアドレスでもあり、Win32側のネットワークサービスに接続する場合にも利用される。そもそもlocalhostや127.0.0.1と呼ばれるIPアドレスは、自分自身を表すIPアドレス、ドメイン名として定義されている。
ただしTCP/IPでは、接続する場合に接続される側がポート番号で待ち受けする。これを「Listen Port」と呼ぶ。つまり、同じIPアドレスであっても、宛先としてポート番号が指定され、そのポート番号ごとに待ち受けるソフトウェアを指定できる。
たとえば、httpであれば、80というポート番号が割り当てられている。ウェブブラウザなどでは、URLでポート番号が明示的に指定されない場合、httpプロトコルはポート番号80で待ち受けしていると仮定して接続する。
ポート番号を指定して待ち受けするには、そのためのAPIを利用して、ポート番号を確保する必要がある。逆にいうとシステムは、どのポート番号が待ち受けに使われているのかを把握できる。WSL2では、これを利用して、WSL2側で待ち受けが行われているポート番号をWin32側で動作しているwslhost.exeが代わって確保して待ち受けする。
WSL2側でPort Xで待ち受けを行うと、win32側でもwslhost.exeがPort XをListen Portに指定して待ち受けする。つまり、localhostのPortXに対する接続はすべてwslhost.exeが受けることになる。wslhost.exeは、受け取ったパケットをなんらかの方法でWSL2側に転送する。WSL2の挙動をみるに、仮想ネットワーク経由での転送ではなく、WSL2側のネットワークサービスからは、localhostからのアクセスのように見える。

この連載の記事
- 第340回 Windowsのシステム引っ越し作業にWingetを使って、アプリインストールを楽にするのを試みる
- 第339回 この先、Windowsはどうなる? 2024年にWindows 12が登場する可能性がある?
- 第338回 今更ながらコンピュータにおけるエンディアンの話
- 第337回 Windowsでコンソールのウィンドウタイトルを書き換える
- 第336回 Windows 10/11で位置情報を扱う
- 第335回 Windowsの基本機能 クリップボードをさらに活用する
- 第334回 地道な改良が進む、Windows Terminal Preview v1.13/1.14の改良点を見る
- 第333回 Windows 11の大型アップデート「Ver.22H2」ではこんな改良点がある【システム&設定アプリ】
- 第332回 Windows 11の大型アップデート「Ver.22H2」ではこんな改良点がある【エクスプローラー&タスクマネージャー】
- 第331回 Windows 11の大型アップデート「Ver.22H2」ではこんな改良点がある【タスクバーとスナップレイアウト】
- 第330回 Windows 11で初めての大型アップデート、Ver.22H2はこうなる
- この連載の一覧へ