TCP代理応答
アライドテレシスのルーター(AR415S)を使っていて起きたトラブル。
携帯向けのサイトを作っていたのだが、ドコモ携帯からのレスポンスが悪いという現象が発生した。最初は、ドコモだけ電波が悪いのかとも思ったのだが、コンテンツが大きくても小さくても常に1秒遅れるという奇妙な振る舞いだった。
原因を調べていくと、ルーターのTCP代理応答という機能に問題があることが判明。
この機能は、外から中へのTCP SYNパケットに対して、内側の機器が反応する前に、代理で返答してくれるというもの。(SYN Floodに対応するための機能らしい)
具体的には、
クライアント ルーター サーバー
| (1)SYN→ | |
| | (2)SYN→ |
| | (3)←SYN/ACK|
| (4)←SYN/ACK| |
| (5)ACK→ .| |
| | (6)ACK→ .|
| (7)データ→. .| |
| | (8)データ→. .|
| | (9)←ACK .|
| (10)←ACK | |
| … .| |
が
クライアント ルーター サーバー
| (1)SYN→ | |
| (2)←SYN/ACK| (A)SYN→ .|
| | (B)←SYN/ACK.|
| | (C)ACK→ |
| (3)ACK→ .| |
| (4)データ→. .| |
| | (5)データ→. .|
| | (6)←ACK .|
| (7)←ACK .| |
| … .| |
となる。(クライアント~ルーターのハンドシェイク((2)~(3))とルーター~サーバーのハンドシェイク((A)~(C))が独立して行われる。
今回、ドコモで問題となったのは、docomoのゲートウェイ(GW)が、(3)のACKのパケットにデータを乗せてきていたため、
ドコモ GW ルーター サーバー
| (1)SYN→ | |
| (2)←SYN/ACK | (A)SYN→ .|
| | (B)←SYN/ACK |
| | (C)ACK→ |
| (3)ACK+データ→ | |このデータは捨てられてしまう
| | |
| | |GWは(3)に対するACKを待つが、サーバーには届いてないので来ない
| | |
| (4)データ再送→ | |ACKが来ないので再送
| | (5)データ→ |
| | (6)←ACK |
| (7)←ACK | |
| … | |
となっていた。
その後の通信はスムーズに進むため、再送がかかるまでの時間((3)~(4))だけ遅れが発生していた。この時間がちょうど1秒。
体感的にも我慢のできない遅れであり、サーバーでもSYN Floodには対応できるため、この機能はオフにすることに。
DISABLE FIREWALL POLICY=policy TCPSETUPPROXY
というコマンドを入力し無事解決。
ところで、ハンドシェイクのACKにデータを乗せるってのはRFC的にアリなんだろうか???
(教科書的には、ACKとデータは別になってるよなぁ)
特に問題にはなっていないので、アリなんだとは思うが、あとで調べてみよう。