アライドテレシスのルーター(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とデータは別になってるよなぁ)
特に問題にはなっていないので、アリなんだとは思うが、あとで調べてみよう。