Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Aug 2000 23:09:03 +0200
From:      Guido van Rooij <guido@gvr.org>
To:        freebsd-net@freebsd.org
Cc:        John Polstra <jdp@polstra.com>
Subject:   Re: Perhaps a TCP stack problem?
Message-ID:  <20000810230903.A25260@gvr.gvr.org>
In-Reply-To: <20000810223937.A24172@gvr.gvr.org>; from Guido van Rooij on Thu, Aug 10, 2000 at 10:39:37PM %2B0200
References:  <20000810095049.C17481@gvr.gvr.org> <XFMail.000810065353.jdp@polstra.com> <20000810223937.A24172@gvr.gvr.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Aug 10, 2000 at 10:39:37PM +0200, Guido van Rooij wrote:
> A couple of days ago, I discovered that the cvsup server kept sending
> my system ACKs where my firewall in between thought that the connection
> was long gone. The firewall does have the policy to just send a RST
> in response. However, the RST sent was incorrect:
> 
> 22:14:52.807104 AAA.BBB.CCC.DDD.5999 > UUU.VVV.WWW.XXX.1035: . 145135143:145135144(1) ack 40231428 win 17520 (DF)
> 22:14:52.808313 UUU.VVV.WWW.XXX.1035 > AAA.BBB.CCC.DDD.5999: R 4254735869:4254735869(0) ack 0 win 0

When looking further, the RST _is_ correct. It is just my tcpdump that was
broken. Here are the packets:
                         4500 0029 de3e 4000 3406 73a6 AAAA BBBB
                         CCCC DDDD 176f 040b 08a6 9627 0265 e204
                         5010 4470 7cc7 0000 5b

                         4500 0028 4fb3 0000 4006 3633 CCCC DDDD
                         AAAA BBBB 040b 176f 0000 0000 08a6 9627
                         5014 0000 009f 0000

The SEQ field in the RST packet is set to 0. Looking at the relevant
section in ip_input.c:
        if (thflags & TH_RST) {
                if (SEQ_GEQ(th->th_seq, tp->last_ack_sent) &&
                    SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) {
                        switch (tp->t_state) {
		 	....
                        case TCPS_FIN_WAIT_1:
                        case TCPS_FIN_WAIT_2:
                        case TCPS_CLOSE_WAIT:
                                so->so_error = ECONNRESET;
                        close:
                                tp->t_state = TCPS_CLOSED;
                                tcpstat.tcps_drops++;
                                tp = tcp_close(tp);
                                break; 
			....
			} /* here we want an else clause; see below */
		}
                goto drop;

That means that if the RST does not contain a sequence number we expect,
we just drop the packet.
But that is certainly broken: if a host goes down and comes backup
before the persist state was timed out, we will never timeout as the RST
do have unexpected sequence numbers with rather high probability.

IMHO, tp->t_rcvtime should be reset in an else {} clause just above
the 'goto drop;' statement in the above piece of code.

-Guido

-Guido


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000810230903.A25260>