netstat -s -p tcp で TCP のプロトコルスタック統計が見られます。
その中の項目、「completely duplicate packets」。
こっちから送った ACK が落ちたときに、
向こうからパケットが再送されてカウントされるものです。
せっかくなので MRTG でグラフ化してみたところ、
200packets/minute を叩きだし、「ぇー……」と思って詳しく調査したところ、
思いがけない結論に達したのでメモ書きを残す。
まずは該当する tcpdump -i lo0。
インターフェースが lo0 ってあたり、既に「ぇー…」ですが、
16:06:42.945550 IP6 client.example.net.61971 > server.example.net.ldap: Flags [S], seq 4054001667, win 65535, options [mss 16324,nop,wscale 6,sackOK,TS val 2061573 ecr 0], length 0 16:06:42.945573 IP6 server.example.net.ldap > client.example.net.61971: Flags [S.], seq 1721556881, ack 4054001668, win 65535, options [mss 16324,nop,wscale 6,sackOK,TS val 2786106269 ecr 2061573], length 0 16:06:42.945610 IP6 client.example.net.61971 > server.example.net.ldap: Flags [.], ack 1, win 1274, options [nop,nop,TS val 2061573 ecr 2786106269], length 0 16:06:42.945679 IP6 client.example.net.61971 > server.example.net.ldap: Flags [P.], seq 1:15, ack 1, win 1274, options [nop,nop,TS val 2061573 ecr 2786106269], length 14 16:06:42.945978 IP6 server.example.net.ldap > client.example.net.61971: Flags [P.], seq 1:15, ack 15, win 1274, options [nop,nop,TS val 2786106269 ecr 2061573], length 14 16:06:42.946094 IP6 client.example.net.61971 > server.example.net.ldap: Flags [P.], seq 15:108, ack 15, win 1274, options [nop,nop,TS val 2061573 ecr 2786106269], length 93 16:06:42.946340 IP6 server.example.net.ldap > client.example.net.61971: Flags [P.], seq 15:29, ack 108, win 1274, options [nop,nop,TS val 2786106269 ecr 2061573], length 14 16:06:42.946764 IP6 client.example.net.61971 > server.example.net.ldap: Flags [P.], seq 108:255, ack 29, win 1274, options [nop,nop,TS val 2061574 ecr 2786106269], length 147 16:06:42.947396 IP6 server.example.net.ldap > client.example.net.61971: Flags [P.], seq 29:80, ack 255, win 1274, options [nop,nop,TS val 2786106270 ecr 2061574], length 51 16:06:43.047712 IP6 client.example.net.61971 > server.example.net.ldap: Flags [.], ack 80, win 1274, options [nop,nop,TS val 2061675 ecr 2786106270], length 0 16:11:24.660499 IP6 client.example.net.61971 > server.example.net.ldap: Flags [.], ack 80, win 0, length 0 16:11:24.660609 IP6 server.example.net.ldap > client.example.net.61971: Flags [.], ack 255, win 1274, options [nop,nop,TS val 2786387984 ecr 2061675], length 0
うーん?なんだこの5分後に送られてる謎の ACK は。
しかもなんかおかしい。RFC 1323 に対応するためのオプションデータが載ってない上に
win が 0 になってる。
TCP の keepalive とはタイミングが違う。
net.inet.tcp.keepidle: 7200000 net.inet.tcp.keepintvl: 75000 net.inet.tcp.keepinit: 75000
最終的にはカーネルにパッチをあててまで調査した結果、
ipfw が悪さをしてるところまで特定。
net.inet.ip.fw.dyn_keepalive: 1 net.inet.ip.fw.dyn_short_lifetime: 5 net.inet.ip.fw.dyn_udp_lifetime: 10 net.inet.ip.fw.dyn_rst_lifetime: 1 net.inet.ip.fw.dyn_fin_lifetime: 1 net.inet.ip.fw.dyn_syn_lifetime: 20 net.inet.ip.fw.dyn_ack_lifetime: 300
おまえか!!!!!
というわけでまとめ。
これ、バグじゃないの??
とりあえず、動的フィルタによる keepalive を殺して、
RFC1323 も無効化することでグラフはかなり落ち着いた。
send-pr してみるか...