Fix race condition that can cause close of socket to hang
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2037 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
c8dec461fc
commit
80113f7d41
@ -860,3 +860,6 @@
|
||||
bug in polling for connections. The logic worked if the poll was inplace
|
||||
before the connection was received; but the poll failed to awaken if the
|
||||
connection was already pending in the backlog when poll() was called.
|
||||
* net/net_close.c. Fixed another important TCP/IP race condition bug: If
|
||||
the host closes the TCP connection just before the target calls close(), then
|
||||
the close operation may hang indefinitely!
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: September 10, 2009</p>
|
||||
<p>Last Updated: September 11, 2009</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1521,6 +1521,9 @@ nuttx-0.4.11 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
bug in polling for connections. The logic worked if the poll was inplace
|
||||
before the connection was received; but the poll failed to awaken if the
|
||||
connection was already pending in the backlog when poll() was called.
|
||||
* net/net_close.c. Fixed another important TCP/IP race condition bug: If
|
||||
the host closes the TCP connection just before the target calls close(), then
|
||||
the close operation may hang indefinitely!
|
||||
|
||||
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -158,30 +158,35 @@ static inline void netclose_disconnect(FAR struct socket *psock)
|
||||
{
|
||||
struct uip_conn *conn = (struct uip_conn*)psock->s_conn;
|
||||
|
||||
/* Set up to receive TCP data event callbacks */
|
||||
/* Check for the case where the host beat us and disconnected first */
|
||||
|
||||
state.cl_cb = uip_tcpcallbackalloc(conn);
|
||||
if (state.cl_cb)
|
||||
if (conn->tcpstateflags == UIP_ESTABLISHED)
|
||||
{
|
||||
state.cl_psock = psock;
|
||||
sem_init(&state.cl_sem, 0, 0);
|
||||
/* Set up to receive TCP data event callbacks */
|
||||
|
||||
state.cl_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT;
|
||||
state.cl_cb->priv = (void*)&state;
|
||||
state.cl_cb->event = netclose_interrupt;
|
||||
state.cl_cb = uip_tcpcallbackalloc(conn);
|
||||
if (state.cl_cb)
|
||||
{
|
||||
state.cl_psock = psock;
|
||||
sem_init(&state.cl_sem, 0, 0);
|
||||
|
||||
/* Notify the device driver of the availaibilty of TX data */
|
||||
state.cl_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT;
|
||||
state.cl_cb->priv = (void*)&state;
|
||||
state.cl_cb->event = netclose_interrupt;
|
||||
|
||||
netdev_txnotify(&conn->ripaddr);
|
||||
/* Notify the device driver of the availaibilty of TX data */
|
||||
|
||||
/* Wait for the disconnect event */
|
||||
netdev_txnotify(&conn->ripaddr);
|
||||
|
||||
(void)sem_wait(&state.cl_sem);
|
||||
/* Wait for the disconnect event */
|
||||
|
||||
/* We are now disconnected */
|
||||
(void)sem_wait(&state.cl_sem);
|
||||
|
||||
sem_destroy(&state.cl_sem);
|
||||
uip_tcpcallbackfree(conn, state.cl_cb);
|
||||
/* We are now disconnected */
|
||||
|
||||
sem_destroy(&state.cl_sem);
|
||||
uip_tcpcallbackfree(conn, state.cl_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,7 @@ void uip_tcpinput(struct uip_driver_s *dev)
|
||||
* least queue it it for acceptance).
|
||||
*/
|
||||
|
||||
conn->tcpstateflags = UIP_ESTABLISHED;
|
||||
if (uip_accept(dev, conn, tmp16) != OK)
|
||||
{
|
||||
/* No, then we have to give the connection back */
|
||||
|
Loading…
Reference in New Issue
Block a user