Skip site navigation (1)Skip section navigation (2)
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>