KUSONEKOの見る世界

RDPで最近知ったこと - MTUと3-way UDP handshake

 WindowsのリモートデスクトップのプロトコルであるRDPを調べていて知ったことを書いておこうと思う。

知ることになったきっかけは、VPN接続の際にリモートデスクトップでUDP通信を行うと、データサイズはどうなるのかという疑問からだった。

私はVPNのMTUについては五月蠅い方なのだが、TCPはSYNの際にiptablesやnftablesでMSSを書き換えていたこともあり、ほとんどの通信は最適化されるためあまり気にしていなかった。

しかし最近リモートデスクトップがもっと快適にならないかと考え、UDPについて見直そうと考えた。

VPNクライアント ⇔ リモートクライアントのUDP通信

まず、VPNクライアント → リモートクライアントへUDP通信は、VPNインターフェースのMTUで決定されるはずだ。
VPNクライアントからの通信は、netshコマンドで最適MTUを設定すれば、途中経路でフラグメントは起こらなくなる。

しかし、リモートクライアント側は、相手がVPNかどうかは分からないため、通常のインターフェースのMTU1500で通信をしてしまう。
そのため、VPNゲートウェイでUDPのフラグメントが起こり、非効率な通信となってしまう。

リモートクライアントの通常のインターフェースのMTUをVPNに合わせて小さくすれば良いが、それでは普段の通信が遅くなってしまう。

どうにかならいかとインターネットで検索をしていたら、マイクロソフトのサイトが引っ掛かってきた。

RDPの仕様

ここには、RDPがMTUのネゴシエーションを行う旨が書いてあった。

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeudp/ffbc66ef-e79f-49f7-b208-76d4a68339e8

要約すると、以下となる。

  • このプロトコルを介して転送できるMTUを3-way UDP handshakeでネゴシエートする
  • RDPクライアントが送信できる最大MTUと受信できる最大MTUをSYNに乗せる
  • サーバ側のMTUと比較し、最小のMTUが選ばれ、SYN ACKを返す
  • MTUは1132~1232の間+RDPUDP_ACK_OF_ACKVECTOR_HEADERの最大サイズ?でIPヘッダ等は含まない

結果的に、(1232+α)+UDPヘッダ+IPヘッダになるため、大したサイズではなかった。

ただ、RDPをキャプチャしてみると、なぜかRDPのペイロードが1259になっているパケットも見られ、IPヘッダまで含めると1301バイトになる物もあった。
RDPUDP_ACK_OF_ACKVECTOR_HEADERは4バイトだと思うのだが、ここまで大きくなる理由はよく分からない。

まあ、我が家のVPNのMTUは1390で、RDPのUDPがフラグメントすることはないので、今回の調査はここまでとする。

最後に

今回の調査で、VPNのMTUサイズが、RDPのUDPにパフォーマンスの影響を与えないことが分かった。
VPNのパフォーマンスを上げたい場合は、インターネット回線やLAN、VPNの暗号化アルゴリズムやCPUを見直したほうが良いと思う。

VPNの暗号化アルゴリズムについては以下で書いている。
> IPsec VPN 高セキュリティ&爆速? AES-GCM + ECP に変更した

何より今回一番の衝撃は、3-way UDP handshakeという言葉に出会ったことだった。