From fb4a7a64bd2806ed348b750074a59b56589da9a9 Mon Sep 17 00:00:00 2001 From: qingli Date: Wed, 7 Mar 2007 23:21:59 +0000 Subject: This patch is provided to fix a couple of deployment issues observed in the field. In one situation, one end of the TCP connection sends a back-to-back RST packet, with delayed ack, the last_ack_sent variable has not been update yet. When tcp_insecure_rst is turned off, the code treats the RST as invalid because last_ack_sent instead of rcv_nxt is compared against th_seq. Apparently there is some kind of firewall that sits in between the two ends and that RST packet is the only RST packet received. With short lived HTTP connections, the symptom is a large accumulation of connections over a short period of time . The +/-(1) factor is to take care of implementations out there that generate RST packets with these types of sequence numbers. This behavior has also been observed in live environments. Reviewed by: silby, Mike Karels MFC after: 1 week --- sys/netinet/tcp_input.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'sys/netinet/tcp_input.c') diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 2190a7b..2d88d47 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1655,9 +1655,8 @@ trimthenstep6: * RFC 1337. */ 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)) || - (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { + if (SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) && + SEQ_LEQ(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { switch (tp->t_state) { case TCPS_SYN_RECEIVED: @@ -1665,8 +1664,11 @@ trimthenstep6: goto close; case TCPS_ESTABLISHED: - if (tp->last_ack_sent != th->th_seq && - tcp_insecure_rst == 0) { + if (tcp_insecure_rst == 0 && + !(SEQ_GEQ(th->th_seq, tp->rcv_nxt - 1) && + SEQ_LEQ(th->th_seq, tp->rcv_nxt + 1)) && + !(SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) && + SEQ_LEQ(th->th_seq, tp->last_ack_sent + 1))) { tcpstat.tcps_badrst++; goto drop; } -- cgit v1.1