Date: Wed, 1 Oct 1997 04:19:03 -0700 From: Don Lewis <Don.Lewis@tsc.tdk.com> To: Richard Jones <richard@a42.deep-thought.org>, dg@root.com Cc: hackers@FreeBSD.ORG, bugs@FreeBSD.ORG Subject: Re: FreeBSD TCP stack and RST processing [subj changed] Message-ID: <199710011119.EAA14305@salsa.gv.tsc.tdk.com> In-Reply-To: Richard Jones <richard@a42.deep-thought.org> "Re: FreeBSD TCP stack and RST processing [subj changed]" (Oct 1, 7:48pm)
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710011119.EAA14305>