summaryrefslogtreecommitdiff
path: root/nuttx/net
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-15 18:58:22 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-15 18:58:22 +0000
commitf2675bf333e0378c842717a94a13c73dabb76a52 (patch)
tree6a460f3749d40743ca8d1d1dfb95481342860110 /nuttx/net
parent6ee68a773a24586f6e6cfaccdf7dce064d213e88 (diff)
downloadpx4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.tar.gz
px4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.tar.bz2
px4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.zip
dup() and dup2() support for socket descriptors
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1884 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net')
-rw-r--r--nuttx/net/Makefile2
-rw-r--r--nuttx/net/accept.c13
-rw-r--r--nuttx/net/net_clone.c117
-rw-r--r--nuttx/net/net_close.c80
-rw-r--r--nuttx/net/net_dup.c134
-rw-r--r--nuttx/net/net_dup2.c126
-rw-r--r--nuttx/net/net_internal.h22
-rw-r--r--nuttx/net/socket.c35
-rw-r--r--nuttx/net/uip/uip_tcpbacklog.c6
-rw-r--r--nuttx/net/uip/uip_tcpconn.c1
-rw-r--r--nuttx/net/uip/uip_udpconn.c2
11 files changed, 503 insertions, 35 deletions
diff --git a/nuttx/net/Makefile b/nuttx/net/Makefile
index 7880a974e..8802e01d7 100644
--- a/nuttx/net/Makefile
+++ b/nuttx/net/Makefile
@@ -38,7 +38,7 @@
ifeq ($(CONFIG_NET),y)
SOCK_ASRCS =
SOCK_CSRCS = socket.c bind.c connect.c sendto.c recv.c recvfrom.c \
- net_sockets.c net_close.c
+ net_sockets.c net_close.c net_dup.c net_dup2.c net_clone.c
ifeq ($(CONFIG_NET_TCP),y)
SOCK_CSRCS += send.c listen.c accept.c
diff --git a/nuttx/net/accept.c b/nuttx/net/accept.c
index a3a2e067e..a9701b2d5 100644
--- a/nuttx/net/accept.c
+++ b/nuttx/net/accept.c
@@ -149,6 +149,14 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
pstate->acpt_newconn = conn;
pstate->acpt_result = OK;
+
+ /* Set a reference of one on the new connection */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+
+ /* Wake-up the waiting caller thread */
+
sem_post(&pstate->acpt_sem);
/* Stop any further callbacks */
@@ -405,7 +413,10 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
}
irqrestore(save);
- /* Initialize the socket structure and mark the socket as connected */
+ /* Initialize the socket structure and mark the socket as connected.
+ * (The reference count on the new connection structure was set in the
+ * interrupt handler).
+ */
pnewsock->s_type = SOCK_STREAM;
pnewsock->s_conn = state.acpt_newconn;
diff --git a/nuttx/net/net_clone.c b/nuttx/net/net_clone.c
new file mode 100644
index 000000000..e23016073
--- /dev/null
+++ b/nuttx/net/net_clone.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * net/net_clone.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: net_clone
+ *
+ * Description:
+ * Performs the low level, common portion of net_dup() and net_dup2()
+ *
+ ****************************************************************************/
+
+int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
+{
+ irqstate_t flags;
+ int ret = OK;
+
+ /* Parts of this operation need to be atomic */
+
+ flags = irqsave();
+
+ /* Duplicate the socket state */
+
+ psock2->s_type = psock1->s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
+ psock2->s_flags = psock1->s_flags; /* See _SF_* definitions */
+#ifdef CONFIG_NET_SOCKOPTS
+ psock2->s_options = psock1->s_options; /* Selected socket options */
+#endif
+#ifndef CONFIG_DISABLE_CLOCK
+ psock2->s_rcvtimeo = psock1->s_rcvtimeo; /* Receive timeout value (in deciseconds) */
+ psock2->s_sndtimeo = psock1->s_sndtimeo; /* Send timeout value (in deciseconds) */
+#endif
+ psock2->s_conn = psock1->s_conn; /* UDP or TCP connection structure */
+
+ /* Increment the reference count on the connection */
+
+#ifdef CONFIG_NET_TCP
+ if (psock2->s_type == SOCK_STREAM)
+ {
+ struct uip_conn *conn = psock2->s_conn;
+ DEBUGASSERT(conn->crefs > 0);
+ conn->crefs++;
+ }
+ else
+#endif
+#ifdef CONFIG_NET_UDP
+ if (psock2->s_type == SOCK_DGRAM)
+ {
+ struct uip_udp_conn *conn = psock2->s_conn;
+ DEBUGASSERT(conn->crefs > 0);
+ conn->crefs++;
+ }
+ else
+#endif
+ {
+ ndbg("Unsupported type: %d\n", psock2->s_type);
+ ret = -EBADF;
+ }
+
+ irqrestore(flags);
+ return ret;
+}
+
+#endif /* CONFIG_NET */
+
+
diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c
index 7ce1f9fa4..f8de0614a 100644
--- a/nuttx/net/net_close.c
+++ b/nuttx/net/net_close.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/net_close.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,7 @@ struct tcp_close_s
{
FAR struct socket *cl_psock; /* Reference to the TCP socket */
FAR struct uip_callback_s *cl_cb; /* Reference to TCP callback instance */
- sem_t cl_sem; /* Semaphore signals disconnect completion */
+ sem_t cl_sem; /* Semaphore signals disconnect completion */
};
#endif
@@ -222,33 +222,75 @@ int net_close(int sockfd)
goto errout;
}
- /* Perform uIP side of the close depending on the protocol type */
+ /* We perform the uIP close operation only if this is the last count on the socket.
+ * (actually, I think the socket crefs only takes the values 0 and 1 right now).
+ */
- switch (psock->s_type)
+ if (psock->s_crefs <= 1)
{
-#ifdef CONFIG_NET_TCP
- case SOCK_STREAM:
+ /* Perform uIP side of the close depending on the protocol type */
+
+ switch (psock->s_type)
{
- struct uip_conn *conn = psock->s_conn;
- uip_unlisten(conn); /* No longer accepting connections */
- netclose_disconnect(psock); /* Break any current connections */
- uip_tcpfree(conn); /* Free uIP resources */
- }
- break;
+#ifdef CONFIG_NET_TCP
+ case SOCK_STREAM:
+ {
+ struct uip_conn *conn = psock->s_conn;
+
+ /* Is this the last reference to the connection structure (there
+ * could be more if the socket was dup'ed.
+ */
+
+ if (conn->crefs <= 1)
+ {
+ /* Yes... free the connection structure */
+
+ uip_unlisten(conn); /* No longer accepting connections */
+ netclose_disconnect(psock); /* Break any current connections */
+ uip_tcpfree(conn); /* Free uIP resources */
+ }
+ else
+ {
+ /* No.. Just decrement the reference count */
+
+ conn->crefs--;
+ }
+ }
+ break;
#endif
#ifdef CONFIG_NET_UDP
- case SOCK_DGRAM:
- uip_udpfree(psock->s_conn); /* Free uIP resources */
- break;
+ case SOCK_DGRAM:
+ {
+ struct uip_udp_conn *conn = psock->s_conn;
+
+ /* Is this the last reference to the connection structure (there
+ * could be more if the socket was dup'ed.
+ */
+
+ if (conn->crefs <= 1)
+ {
+ /* Yes... free the connection structure */
+
+ uip_udpfree(psock->s_conn); /* Free uIP resources */
+ }
+ else
+ {
+ /* No.. Just decrement the reference count */
+
+ conn->crefs--;
+ }
+ }
+ break;
#endif
- default:
- err = EBADF;
- goto errout;
+ default:
+ err = EBADF;
+ goto errout;
+ }
}
- /* Then release the socket structure containing the connection */
+ /* Then release our reference on the socket structure containing the connection */
sockfd_release(sockfd);
return OK;
diff --git a/nuttx/net/net_dup.c b/nuttx/net/net_dup.c
new file mode 100644
index 000000000..f4ee15abe
--- /dev/null
+++ b/nuttx/net/net_dup.c
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * net/net_dup.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "net_internal.h"
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: net_dup OR dup
+ *
+ * Description:
+ * Clone a socket descriptor to an arbitray descriptor number. If file
+ * descriptors are implemented, then this is called by dup() for the case
+ * of socket file descriptors. If file descriptors are not implemented,
+ * then this function IS dup().
+ *
+ ****************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTOR > 0
+int net_dup(int sockfd)
+#else
+int dup(int sockfd)
+#endif
+{
+ FAR struct socket *psock1 = sockfd_socket(sockfd);
+ FAR struct socket *psock2;
+ int sockfd2;
+ int err;
+ int ret;
+
+ /* Lock the scheduler throughout the following */
+
+ sched_lock();
+
+ /* Get the socket structure underlying sockfd */
+
+ psock1 = sockfd_socket(sockfd);
+
+ /* Verify that the sockfd corresponds to valid, allocated socket */
+
+ if (!psock1 || psock1->s_crefs <= 0)
+ {
+ err = EBADF;
+ goto errout;
+ }
+
+ /* Allocate a new socket descriptor */
+
+ sockfd2 = sockfd_allocate();
+ if (sockfd2 < 0)
+ {
+ err = ENFILE;
+ goto errout;
+ }
+
+ /* Get the socket structure underlying the new descriptor */
+
+ psock2 = sockfd_socket(sockfd2);
+ if (!psock2)
+ {
+ err = ENOSYS; /* should not happen */
+ goto errout;
+ }
+
+ /* Duplicate the socket state */
+
+ ret = net_clone(psock1, psock2);
+ if (ret < 0)
+ {
+ err = -ret;
+ goto errout;
+
+ }
+
+ sched_unlock();
+ return sockfd2;
+
+errout:
+ sched_unlock();
+ errno = err;
+ return ERROR;
+}
+
+#endif /* defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 */
+
+
diff --git a/nuttx/net/net_dup2.c b/nuttx/net/net_dup2.c
new file mode 100644
index 000000000..8992ec226
--- /dev/null
+++ b/nuttx/net/net_dup2.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * net/net_dup2.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "net_internal.h"
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: net_dup2
+ *
+ * Description:
+ * Clone a socket descriptor to an arbitray descriptor number. If file
+ * descriptors are implemented, then this is called by dup2() for the case
+ * of socket file descriptors. If file descriptors are not implemented,
+ * then this function IS dup2().
+ *
+ ****************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTOR > 0
+int net_dup2(int sockfd1, int sockfd2)
+#else
+int dup2(int sockfd1, int sockfd2)
+#endif
+{
+ FAR struct socket *psock1;
+ FAR struct socket *psock2;
+ int err;
+ int ret;
+
+ /* Lock the scheduler throughout the following */
+
+ sched_lock();
+
+ /* Get the socket structures underly both descriptors */
+
+ psock1 = sockfd_socket(sockfd1);
+ psock2 = sockfd_socket(sockfd2);
+
+ /* Verify that the sockfd1 and sockfd2 both refer to valid socket
+ * descriptors and that sockfd2 corresponds to allocated socket
+ */
+
+ if (!psock1 || !psock2 || psock1->s_crefs <= 0)
+ {
+ err = EBADF;
+ goto errout;
+ }
+
+ /* If sockfd2 also valid, allocated socket, then we will have to
+ * close it!
+ */
+
+ if (psock2->s_crefs > 0)
+ {
+ net_close(sockfd2);
+ }
+
+ /* Duplicate the socket state */
+
+ ret = net_clone(psock1, psock2);
+ if (ret < 0)
+ {
+ err = -ret;
+ goto errout;
+ }
+
+ sched_unlock();
+ return OK;
+
+errout:
+ sched_unlock();
+ errno = err;
+ return ERROR;
+}
+
+#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS > 0 */
+
+
diff --git a/nuttx/net/net_internal.h b/nuttx/net/net_internal.h
index ebef372f9..ea3fdd5a6 100644
--- a/nuttx/net/net_internal.h
+++ b/nuttx/net/net_internal.h
@@ -1,7 +1,7 @@
/****************************************************************************
- * net/net-internal.h
+ * net/net_internal.h
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -142,7 +142,7 @@ extern "C" {
#define EXTERN extern
#endif
-/* net-sockets.c *************************************************************/
+/* net_sockets.c *************************************************************/
EXTERN int sockfd_allocate(void);
EXTERN void sockfd_release(int sockfd);
@@ -156,38 +156,42 @@ EXTERN socktimeo_t net_timeval2dsec(struct timeval *tv);
EXTERN void net_dsec2timeval(uint16 dsec, struct timeval *tv);
#endif
-/* net-register.c ************************************************************/
+/* net_clone.c ***************************************************************/
+
+EXTERN int net_clone(FAR struct socket *psock1, FAR struct socket *psock2);
+
+/* net_register.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN void netdev_semtake(void);
# define netdev_semgive() sem_post(&g_netdev_sem)
#endif
-/* net-findbyname.c **********************************************************/
+/* net_findbyname.c **********************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN FAR struct uip_driver_s *netdev_findbyname(const char *ifname);
#endif
-/* net-findbyaddr.c **********************************************************/
+/* net_findbyaddr.c **********************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t *raddr);
#endif
-/* net-txnotify.c ************************************************************/
+/* net_txnotify.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN void netdev_txnotify(const uip_ipaddr_t *raddr);
#endif
-/* net-count.c ***************************************************************/
+/* net_count.c ***************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN int netdev_count(void);
#endif
-/* net-arptimer.c ************************************************************/
+/* net_arptimer.c ************************************************************/
EXTERN void arptimer_init(void);
diff --git a/nuttx/net/socket.c b/nuttx/net/socket.c
index 161866272..fddff2ccc 100644
--- a/nuttx/net/socket.c
+++ b/nuttx/net/socket.c
@@ -43,6 +43,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
+#include <assert.h>
#include <debug.h>
#include "net_internal.h"
@@ -155,13 +156,43 @@ int socket(int domain, int type, int protocol)
{
#ifdef CONFIG_NET_TCP
case SOCK_STREAM:
- psock->s_conn = uip_tcpalloc();
+ {
+ /* Allocate the TCP connection structure and save in the new
+ * socket instance.
+ */
+
+ struct uip_conn *conn = uip_tcpalloc();
+ psock->s_conn = conn;
+
+ /* Set the reference count on the connection structure. This
+ * reference count will be increment only if the socket is
+ * dup'ed
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+ }
break;
#endif
#ifdef CONFIG_NET_UDP
case SOCK_DGRAM:
- psock->s_conn = uip_udpalloc();
+ {
+ /* Allocate the UDP connection structure and save in the new
+ * socket instance.
+ */
+
+ struct uip_udp_conn *conn = uip_udpalloc();
+ psock->s_conn = conn;
+
+ /* Set the reference count on the connection structure. This
+ * reference count will be increment only if the socket is
+ * dup'ed
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+ }
break;
#endif
diff --git a/nuttx/net/uip/uip_tcpbacklog.c b/nuttx/net/uip/uip_tcpbacklog.c
index 1eecdf9ad..e27c70a51 100644
--- a/nuttx/net/uip/uip_tcpbacklog.c
+++ b/nuttx/net/uip/uip_tcpbacklog.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/uip/uip_tcpbacklog.c
*
- * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@
*
* Description:
* Called from the listen() logic to setup the backlog as specified in the
- * the listen arguments *.
+ * the listen arguments.
*
* Assumptions:
* Called from normal user code. Interrupts may be disabled.
@@ -213,7 +213,7 @@ int uip_backlogdestroy(FAR struct uip_conn *conn)
*
* Description:
* Called uip_listen when a new connection is made with a listener socket
- * but when there is not accept() in place to receive the connection. This
+ * but when there is no accept() in place to receive the connection. This
* function adds the new connection to the backlog.
*
* Assumptions:
diff --git a/nuttx/net/uip/uip_tcpconn.c b/nuttx/net/uip/uip_tcpconn.c
index af61bab46..12451a47f 100644
--- a/nuttx/net/uip/uip_tcpconn.c
+++ b/nuttx/net/uip/uip_tcpconn.c
@@ -294,6 +294,7 @@ void uip_tcpfree(struct uip_conn *conn)
* operation.
*/
+ DEBUGASSERT(conn->crefs == 0);
flags = irqsave();
/* UIP_ALLOCATED means that that the connection is not in the active list
diff --git a/nuttx/net/uip/uip_udpconn.c b/nuttx/net/uip/uip_udpconn.c
index ce23d2504..061f7dd78 100644
--- a/nuttx/net/uip/uip_udpconn.c
+++ b/nuttx/net/uip/uip_udpconn.c
@@ -271,6 +271,8 @@ void uip_udpfree(struct uip_udp_conn *conn)
* is protected by a semaphore (that behaves like a mutex).
*/
+ DEBUGASSERT(conn->crefs == 0);
+
_uip_semtake(&g_free_sem);
conn->lport = 0;
dq_addlast(&conn->node, &g_free_udp_connections);