From owner-freebsd-bugs Wed Oct 1 04:19:36 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id EAA06946 for bugs-outgoing; Wed, 1 Oct 1997 04:19:36 -0700 (PDT) Received: from gatekeeper.tsc.tdk.com (root@gatekeeper.tsc.tdk.com [207.113.159.21]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id EAA06938; Wed, 1 Oct 1997 04:19:29 -0700 (PDT) Received: from sunrise.gv.tsc.tdk.com (root@sunrise.gv.tsc.tdk.com [192.168.241.191]) by gatekeeper.tsc.tdk.com (8.8.4/8.8.4) with ESMTP id EAA27657; Wed, 1 Oct 1997 04:19:05 -0700 (PDT) Received: from salsa.gv.tsc.tdk.com (salsa.gv.tsc.tdk.com [192.168.241.194]) by sunrise.gv.tsc.tdk.com (8.8.5/8.8.5) with ESMTP id EAA08918; Wed, 1 Oct 1997 04:19:04 -0700 (PDT) Received: (from gdonl@localhost) by salsa.gv.tsc.tdk.com (8.8.5/8.8.5) id EAA14305; Wed, 1 Oct 1997 04:19:03 -0700 (PDT) From: Don Lewis Message-Id: <199710011119.EAA14305@salsa.gv.tsc.tdk.com> Date: Wed, 1 Oct 1997 04:19:03 -0700 In-Reply-To: Richard Jones "Re: FreeBSD TCP stack and RST processing [subj changed]" (Oct 1, 7:48pm) X-Mailer: Mail User's Shell (7.2.6 alpha(3) 7/19/95) To: Richard Jones , dg@root.com Subject: Re: FreeBSD TCP stack and RST processing [subj changed] Cc: hackers@FreeBSD.ORG, bugs@FreeBSD.ORG Sender: owner-freebsd-bugs@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk On Oct 1, 7:48pm, Richard Jones wrote: } Subject: Re: FreeBSD TCP stack and RST processing [subj changed] } } Ok the other system tested was 2-2 Stable. implode.root.com exhibits the } same behaviour as does 204.216.27.21 (the real freefall as pointed out by } you in a later mail). The main reason I didn't provide version info } was that I thought it was an easy enough situation to replicate if it was } indeed replicatable. Unfortunately I know of no systems that are running } CURRENT to test upon. I think this bug exists in all versions including -current ... Fortunately, I have my copy of TCP/IP Illustrated Volume 2 here in the office :-) The initial faked SYN will put is in the SYN_RECEIVED state. This is the code from tcp_input() in -current that is supposed handle this situation, and it appears to be the same in 2.1 and 2.2: /* * If the RST bit is set examine the state: * SYN_RECEIVED STATE: * If passive open, return to LISTEN state. * If active open, inform user that connection was refused. * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: * Inform user that connection was reset, and close tcb. * CLOSING, LAST_ACK, TIME_WAIT STATES * Close the tcb. */ if (tiflags&TH_RST) switch (tp->t_state) { case TCPS_SYN_RECEIVED: so->so_error = ECONNREFUSED; goto close; This code appears to be correct, and agrees with what's in the book. However ... there is some code *earlier* in tcp_input() that looks like it botches this situation: /* * If the state is SYN_RECEIVED: * do just the ack and RST checks from SYN_SENT state. * If the state is SYN_SENT: * if seg contains an ACK, but not for our SYN, drop the input. * if seg contains a RST, then drop the connection. * if seg does not contain SYN, then drop it. * Otherwise this is an acceptable SYN segment * initialize tp->rcv_nxt and tp->irs * if seg contains ack then advance tp->snd_una * if SYN has been acked change to ESTABLISHED else SYN_RCVD state * arrange for segment to be acked (eventually) * continue processing rest of data/controls, beginning with URG */ case TCPS_SYN_RECEIVED: case TCPS_SYN_SENT: if ((taop = tcp_gettaocache(inp)) == NULL) { taop = &tao_noncached; bzero(taop, sizeof(*taop)); } if ((tiflags & TH_ACK) && (SEQ_LEQ(ti->ti_ack, tp->iss) || SEQ_GT(ti->ti_ack, tp->snd_max))) { /* * If we have a cached CCsent for the remote host, * hence we haven't just crashed and restarted, * do not send a RST. This may be a retransmission * from the other side after our earlier ACK was lost. * Our new SYN, when it arrives, will serve as the * needed ACK. */ if (taop->tao_ccsent != 0) goto drop; else goto dropwithreset; } if (tiflags & TH_RST) { if (tiflags & TH_ACK) tp = tcp_drop(tp, ECONNREFUSED); goto drop; } if (tp->t_state == TCPS_SYN_RECEIVED) break; It looks like we just drop the packet containing the RST! The example code in the book does not execute this code in the SYN_RECEIVED state. I don't know the history of this code, so I don't know why it was changed. copied to freebsd-bugs --- Truck