dodaの日記: TTProxy の IPv6 対応
これの続き。
前にも書いたけれど、元々 TTProxy は IPv6 対応する前の Tera Term を対象に作成されている。
TTProxy の想定している動作は、以下のような流れになっている。
- Tera Term が接続するホスト名の入力を受け付ける。
- Tera Term が入力されたホスト名の名前解決を WSAAsyncGetHostByName で行おうとする。
- TTProxy が WSAAsyncGetHostByName をフックする。
- TTProxy はホスト名を覚えておき、名前解決をせずに 0.0.0.1~254 の内のどれかを答えとして返す。覚えた名前は返したアドレスと対応している。
- Tera Term は Socket でソケットを作成する。
- Tera Term は返されたアドレスに対して Connect で接続しようとする。
- TTProxy は Connect をフックする。
- TTProxy はプロトコルを確認し IPv4 ならば以下の処理をおこなう。
IPv4 以外ならば本来の Connect を呼び、以降は処理をスルーする。
- Connect 先の IP アドレスをすり替え、Proxy に接続する。
- Connect で渡された IP アドレスから、元々接続しようとしたホスト名を確認する。
- Proxy に対して、確認したホスト名への接続要求を行う。
- TTProxy から Tera Term へ処理を戻す。
- 以降は通常の通信と同じ。
Tera Term が IPv6 対応した事により、名前解決に WSAAsyncGetAddrInfo を使うようになった。
そのため、TTProxy での名前解決のフックが出来なくなってしまった。
TTProxy では名前解決時には実際には名前解決を行わず、接続時に Proxy にホスト名をそのまま渡す事によって
Proxy 側で名前解決を行わせていたのだが、それが常にローカル側で名前解決を行うようになってしまった。
そのため、ローカル側で名前解決が出来ない状態の時に Proxy を使って接続出来なくなってしまった。(この問題)
また、TTProxy が IPv6 に対応していない問題もある。
例えば、Connect 時にプロトコルが IPv4 の時のみ処理を行う部分。
だが、ここを単純に IPv6 の時も処理を行うようにすればいいという訳ではない。
Connect の時点では既に Socket が作成されている。
そして Socket が作成された時点でプロトコルは決まっているため、Connect の段階で接続先を IPv4 から IPv6 へ掏りかえる事は出来ない。
なので、Socket もフックするようにしてしまうか、名前解決の段階で想定した順番で IPv4/IPv6 の接続を行うように応答を返すようにするかしないといけない。
今までと動作をあわせるとすると後者なのだけれど、どういう応答の仕方にするかとか、内部でのホスト名の記憶の仕方とか色々考えないといけないところで作業が停滞中…
# ここまでは実は 4.68 のリリース前に辿り着いていたのだけれど、その後全然進んでいない
TTProxy は C++ で書かれているのだけれど、自分が C++ に慣れていないという問題もあるよなあ。
TTProxy の IPv6 対応 More ログイン