[En-Nut-Discussion] TCP RST handling

Mike Cornelius mikec at call-direct.com.au
Tue Aug 26 12:02:01 CEST 2003


Hi All (and Harald in particular),
 
I have found the following oddity in the TCP state machine:-
 
If I do an active open from Nut/OS and the destination machine's server
software is not running the destination machine will correctly return a
RST to Nut/OS.
 
At this point the TCP state machine is in TCPS_SYN_SENT state and the
incomming RST correctly sets:-
sock->so_last_error = ECONNREFUSED;
sock->so_state = TCPS_CLOSE_WAIT;
 
It does not however remove the original active open SYN packet from the
send queue.
 
Soon enough the retransmit timer expires and Nut/OS re-sends the
original SYN packet, which again attracts a RST.
This repeats until the socket times out and closes and generates a LOT
of useless traffic.
 
This should not happen, RFC 793 goes into quite some detail about how
RSTs should be handled but in summary:-
All socket send and receive queues should be flushed.
The TCB should be deleted.
The Application should be notified.
The socket should go directly to the CLOSED state.
 
Looking through tcpsm it seems Nut/OS does not handle RST's correctly
regardless of the current state.
 
I've added the following function to tcpsm.c
 
/*!
 * \brief RST processing.
 *
 * \param sock Socket descriptor. This pointer must have been 
 *             retrieved by calling NutTcpCreateSocket().
 *
 */
static void NutTcpProcessRst(TCPSOCKET * sock)
{
 NETBUF *nb;
 
 // Immediatly set state to closed
 sock->so_state = TCPS_CLOSED;
 
 // Delete anything in the buffer
 if (sock->so_rx_buf) {
        NutHeapFree(sock->so_rx_buf);
        sock->so_rx_cnt = 0;
        sock->so_rx_buf = 0;
    }
    while ((nb = sock->so_tx_nbq) != 0) {
        sock->so_tx_nbq = nb->nb_next;
        NutNetBufFree(nb);
    }
    while ((nb = sock->so_rx_nbq) != 0) {
        sock->so_rx_nbq = nb->nb_next;
        NutNetBufFree(nb);
    }
 
 // Notify changes
    NutEventBroadcast(&sock->so_rx_tq);
    NutEventBroadcast(&sock->so_tx_tq);
    NutEventBroadcast(&sock->so_pc_tq);
    NutEventBroadcast(&sock->so_ac_tq);
}
 
And call it as appropriate when a RST is received, which seems to work
for me.
 
Regards,
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
Mike Cornelius                      Internet: mikec at call-direct.com.au
Call Direct Cellular Solutions      Phone:    +61 2 9209-4259
Suite 145                           FAX:      +61 2 9209-4196
National Innovation Centre     URL:      http://www.call-direct.com.au
<http://www.call-direct.com.au/> 
Australian Technology Park
Eveleigh NSW 1430
Australia                  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.egnite.de/pipermail/en-nut-discussion/attachments/20030826/dc708a5a/attachment.html>


More information about the En-Nut-Discussion mailing list