TCPが遅すぎる?QUICを使おう!
「それ、QUIC使えないの?」
それがなんであれ、QUICを使うことを主張することで、みんなが「なんか良くわからないけど、TCPを置き換えたほうがいいのかな?」と思うようになるはず。全てのアプリケーションを、TCPの代わりにQUICを使うように修正するとなれば、この先10年間ぐらい、エンジニアみんなの仕事を作ることができます。業界愛ですね。
すでに、SSHやDNSのQUIC対応は始められています。既存のアプリケーションをQUICに対応させる難しさを調査するために、RustでBGP over QUICを実装してみました。
QUICの実装
QUICは、TCPと同じく、パケットの再送、輻輳制御など、信頼性のある通信を実現するトランスポートプロトコルです。実装面の大きな違いは、TCPがオペレーティングシステムのプロトコルスタックの一機能として実装されるのに対して、QUICはアプリケーションで実装される点です。アプリケーションが、パケット処理の一部を実行することになります。
将来的には、オペレーティングシステムがQUICをサポートする可能性もありますが、現在は、アプリケーションのライブラリとして、C、Rust、Java、Go、Python、Erlang、JavaScriptなどの様々な言語のQUIC実装があります。Microsoft、Google、Facebookなど、おしゃれな会社は、独自のOSSのQUIC実装を開発しており、今時は、おしゃれなオフィスを作る代わりに、自社のQUICを開発することで、おしゃれな会社であることをアピールすることができるはずです。
Rustでやってみよう
一般にC言語で実装されているオペレーティングシステムのパケット処理と同程度の性能を実現するためには、C言語と同程度の処理速度の言語でアプリケーションを実装する必要がありそうです。そうです、Rustしかありませんね。
RustのQUIC実装には、MozillaのNeqo、Cloudflareのquiche、Quinnの3種類がありますが、最初の2つは、Cのライブラリを利用しており、Rustへの愛が足りないので、Quinnを利用します。
BGP over QUIC
200行程度の変更で、RustのBGP実装をQUICに対応させることができました。Quinnは、Rustでネットワークアプリケーションを実装する際に人気のtokioライブラリと一緒に動作し、tokioのTCPのAPIと類似のQUICのAPIを提供しているので、tokioライブラリを利用しているアプリケーションであれば、比較的容易にQUICに対応させることができそうです。
ここから先は、「QUICでBGPセッション!!」と心が震える少数派の方々以外は、読み飛ばして、「まとめ」に進んでください。
デーモンを起動した状態で、TCPが179番ポートをlistenするのではなく、UDPで使われています。
$ lsof -P -c daemon|grep UDP
daemon 26132 root 7u IPv4 55772 0t0 UDP *:179
ピアをacceptすると、IPとUDPポートが表示されます。
$ ./target/debug/daemon --as-number 65001 --router-id 1.1.1.1 --any-peers
Hello, RustyBGP!
accpeted new quic conn V4(172.31.22.144:53760)
実際に接続されていることを確認します。
$ gobgp neighbor
Peer AS Up/Down State |#Received Accepted
172.31.22.144 65002 00:01:40 Establ | 0 0
ピアのホストで、UDPの53760番を利用していることが確認できました。
$ lsof -c daemon|grep UDP
daemon 13238 root 7u IPv4 66927 0t0 UDP *:179
daemon 13238 root 8u IPv4 66956 0t0 UDP *:53760
まとめ
既存のアプリケーションをQUICに対応するためのポイントは、QUICを考慮した言語やライブラリで実装されていること、ということが分かりました。
早速、明日から、全てのアプリケーションをRustで再実装していきましょう、QUICでモバイルファースト時代ですからね。NTTでは、仲間を募集中です。連絡お待ちしています。