TCP/QUIC相互変換のポートフォワードツールを書いた

TCP/QUICのポートフォワードツールを書いた。

概要

IETFで標準化が進められているトランスポートプロトコルQUIC。

UDPを利用しており、エンドポイントのIPアドレスが変わってもコネクションが切れなかったり、より良い再送制御が行えたりと長所は多くある。しかし、QUICをサポートしているアプリケーションプロトコル、実装が現状多くはない。

QUICの恩恵に預かるために、TCPとQUICを相互変換するポートフォワードツール 「t2q2t」 を書いた。(実態としてはただのProxy)
github.com


ただし、ハンドシェイク回数が増えるのでコネクション確立時のオーバーヘッドは高い

利用例

ユースケースとしては例えば:

f:id:ASnoKaze:20190818085413p:plain
クライアントとサーバそれぞれでt2q2tを実行する。

  • クライアント: TCPで0.0.0.0:2022でリッスンし、QUICで192.168.0.1:22に転送する
  • サーバ: QUICで0.0.0.0:2022でリッスンし、TCP127.0.0.1:22に転送する
# t2q2t <convert mode> <listen addr> <connect addr>

# クライアントサイド (TCP <-> QUIC)
$ ./t2q2t t2q 0.0.0.0:2022 192.168.0.1:2022

# サーバサイド (TCP <-> QUIC)
$ ./t2q2t q2t 0.0.0.0:2022 127.0.0.1:22

t2q2tとはローカルホスト通信を行い、ホスト間ではSSH over QUICを利用できるようになる。
(2重に暗号化処理を行うことになるが、QUICの特性であるロスリカバリの恩恵を受けるほか、IPアドレスが変わってもコネクションとかは切れないはず)

convert mode

サブコマンドは2種類。それぞれリッスン "アドレス:ポート"と、転送先 "アドレス:ポート" を引数にとる

  • t2q: TCPでリッスンして、QUICで転送する
  • q2t: QUICでリッスンして、TCPで転送する

その他

一応、SSHが問題なくフォワードされ。ログインできることは確認した。

注意事項として、t2q2tは、ALPN識別子として「t2q2t」を使用します。 他のQUIC実装と通信することは意図していない。

実装として、エラーハンドリングが雑なのでまだまだ怪しい。QUIC使う部分は毎回コネクション貼ってるので、ストリームの多重化を利用したいところ(8/22 対応済み)。簡単に挙動を確認したところ、単一コネクションになったので、複数TCPコネクションが帯域を食い合うこともなくなった。輻輳制御上も有利なはず。

性能評価や細かい改善とかはおいおい

t2q2tの読み方

決めてない...orz