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>
