This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Network TCP Handler: stale socket disposal


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;

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]