IRC

未だにIRCをけっこう使ってるんだけども、ここ数ヶ月様子がおかしい。 発言の多いチャンネル(にJOINしているサーバ)からランダムに切断されるようになってしまった。 正確には、クライアントが切断と判断して再接続するんだけど、サーバ側にはまだ自分が残っていて、しばらくするとtimeoutするという状態。 IRCクライアントの設定を色々いじったけど全く改善しないので、根本的に原因を調べることにした。

というわけでまずはWireShark(旧Ethereal)をインストールしてパケットを観察。うっかりHDDに残っていたEtherealをインストールしようとしてできなかったのは秘密だ。 フィルタを「ip.addr == xxx.xxx.xxx.xxx」(IRCサーバのアドレス)に設定。IRCクライアントの方もラウンドロビンのホストではなく、サーバを決め打ちに設定しておく。 そして流れの速いチャンネルに繋ぎ、じーっと観察。

5558 19:33:08.121560 192.168.xxx.xxx xxx.xxx.xxx.xxx TCP [TCP Retransmission] agentsease-db > ircu [PSH, ACK] Seq=2650 Ack=61672 Win=65361 Len=47

が7回流れた後に切れた。パケットの中身は発言だったり、クライアントが定期的に送信しているCTCP PONGだったり色々。 どうもこちらから何かアクションを起こした時にTCPの再送を繰り返して、それが一定回数になるとクライアント側が切断してしまうらしい。 何度か見ていると、毎回7回再送→切断というパターンになっている。

次に、ルータ(FreeBSD)でtcpdumpを起動して調べてみる。ちなみにipfilterを使っているので、kernelは既にプロミスキャスモードが可能なようにコンパイルされている。

tcpdump -vv -l -n -i ng0 host xxx.xxx.xxx.xxx | tee tcpdump.log

とかやってログを取りつつ観察。ちなみにng0はPPPoEドライバmpd4のインターフェイス名。

切断された時に、Wiresharkと付き合わせて同じシーケンス番号のパケットを探す。

19:33:06.599574 IP (tos 0x0, ttl 127, id 45469, offset 0, flags [DF], proto: TCP (6), length: 40) zzz.zzz.zzz.zzz.3997 > xxx.xxx.xxx.xxx.6669: ., cksum 0xa883 (correct), 2650:2650(0) ack 61672 win 65361

うーん、よくわからない(こら) まぁ少なくともng0からは出て行ってるので(zzz.zzz.zzz.zzzはWAN側アドレス)、ipfilterがブロックしてるとかNATが働いてないとかいうのではなさそう。 tcpdumpはちっと分かりにくいので、他のパケットダンプを試してみよう。以下次号。