seq# of RST in tcp_dropwithreset

George Neville-Neil gnn at neville-neil.com
Thu Jun 7 20:28:40 UTC 2012


On Mar 27, 2012, at 18:13 , Navdeep Parhar wrote:

> 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?
> 

Hi Navdeep,

Sorry I missed this so many months ago, but jhb@ was kind enough to point this
query out to me.  My understanding of correct operation in this case, is that we 
do not want to move the sequence number until we have received the ACK of our
FIN, as any other value would indicate to the TCP on A that we have received their
ACK of our FIN, which, in this case, we have not.  The fact that there isn't a better
way to indicate the error is a tad annoying, but, and others can correct me if they think
I'm wrong, this is the correct way for the stacks to come to eventual agreement
on the closing of the connection.

Best,
George




More information about the freebsd-net mailing list