summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-11 19:31:52 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-11 19:31:52 +0000
commita9fda6c0afe5659aa78c92f3b12d3d2bd38bba65 (patch)
tree73408179fdc50341857372673bcb5a51041235d8
parent163c619378cab13dce25ab7c933aee34749353ab (diff)
downloadpx4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.tar.gz
px4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.tar.bz2
px4-nuttx-a9fda6c0afe5659aa78c92f3b12d3d2bd38bba65.zip
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
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/Documentation/NuttX.html5
-rw-r--r--nuttx/net/net_close.c35
-rw-r--r--nuttx/net/uip/uip_tcpinput.c1
4 files changed, 28 insertions, 16 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index b26a42e3a..93150d588 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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!
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 37caa7933..9c7269825 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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 &lt;spudmonkey@racsa.co.cr&gt;
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 &lt;spudmonkey@racsa.co.cr&gt;
diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c
index eb7dbd711..b05fc338f 100644
--- a/nuttx/net/net_close.c
+++ b/nuttx/net/net_close.c
@@ -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);
+ }
}
}
diff --git a/nuttx/net/uip/uip_tcpinput.c b/nuttx/net/uip/uip_tcpinput.c
index 3fc491f6b..f417c2c7b 100644
--- a/nuttx/net/uip/uip_tcpinput.c
+++ b/nuttx/net/uip/uip_tcpinput.c
@@ -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 */