This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Re: Network TCP Handler: stale socket disposal
- From: John Mills <johnmills at speakeasy dot net>
- To: eCos RTOS Patches <ecos-patches at ecos dot sourceware dot org>
- Cc: Andrew Lunn <andrew at lunn dot ch>
- Date: Wed, 29 Aug 2007 15:54:37 -0500 (EST)
- Subject: Re: Network TCP Handler: stale socket disposal
- Reply-to: John Mills <john dot m dot mills at alum dot mit dot edu>
On Wed, 29 Aug 2007, Andrew Lunn wrote:
> > } else if (so->so_state & SS_COMP) {
> > + if((so->so_error == ECONNRESET) ||
> > + (so->so_error == ECONNREFUSED)){ // forced drop if flagged
> > + TAILQ_REMOVE(&head->so_comp, so, so_list);
> > + head->so_qlen--;
> > + } else {
> > /*
> > * We must not decommission a socket that's
> > * on the accept(2) queue. If we do, then
> > @@ -249,11 +258,13 @@
> > * that the listening socket was ready.
> > */
>
> The full comment is:
>
> /*
> * We must not decommission a socket that's
> * on the accept(2) queue. If we do, then
> * accept(2) may hang after select(2) indicated
> * that the listening socket was ready.
> */
>
> Are you sure the socket is not on the accept queue? I wounder if the
> accept code should free the socket?
>
> Andrew
Good question. I'm way beyond my 'threshold of incompetence' here and may
have opened another vulnerability with my patch.
I looked where those error flags are set in 'tcp_input()' and found this,
suggesting that I could rely on testing ECONNREFUSED and ECONNRESET to
kill off the connection:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
* States other than LISTEN or SYN_SENT.
* First check the RST flag and sequence number since reset
segments
* are exempt from the timestamp and connection count tests.
...
* If the RST bit is set, check the sequence number to see
* if this is a valid reset segment.
...
* If the reset segment passes the sequence number test 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 STATES:
* Close the tcb.
* TIME_WAIT STATE:
* Drop the segment - see Stevens, vol. 2, p. 964 and
* 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)) {
switch (tp->t_state) {
case TCPS_SYN_RECEIVED:
so->so_error = ECONNREFUSED;
goto close;
case TCPS_ESTABLISHED:
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;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++