Date: Tue, 27 Mar 2012 15:13:42 -0700 From: Navdeep Parhar <np@FreeBSD.org> To: freebsd-net@freebsd.org Subject: seq# of RST in tcp_dropwithreset Message-ID: <CAPFoGT9eEmMwvpO3O3nLmWCpj=NQis9K1DD_WyZDVwMCZjT6Fg@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
When the kernel decides to respond with a RST to an incoming TCP segment, it uses its ack# (if valid) as the seq# of the RST. See this in tcp_dropwithreset: if (th->th_flags & TH_ACK) { tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, th->th_ack, TH_RST); } else { if (th->th_flags & TH_SYN) tlen++; tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); } This can have some unexpected results. I observed this on a link with a very high delay (B is FreeBSD, A could be anything). 1. There is a segment in flight from A to B. The ack# is X (all tx from B to A is up to date and acknowledged). 2. socket is closed on B. B sends a FIN with seq# X. 3. The segment from A arrives and elicits a RST from B. The seq# of this RST will again be X. A receives the FIN and then the RST with identical sequence numbers. The situation resolves itself eventually, when A retransmits and the retransmitted segment ACKs the FIN too and so the next time around B sends a RST with the "correct" seq# (one after the FIN). If there is a local tcpcb for the connection with state >= ESTABLISHED, wouldn't it be more accurate to use its snd_max as the seq# of the RST? Regards, Navdeep
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPFoGT9eEmMwvpO3O3nLmWCpj=NQis9K1DD_WyZDVwMCZjT6Fg>