summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-25 07:36:16 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-25 07:36:16 -0600
commitb7cb7361aaaa05fa411b258db0fcacb3c137792d (patch)
tree3bd0200a5fda34702e8c8b647e7c0b27a7577f23
parent72ceb9b6815c222ce08a01e22bdc97c9f474d196 (diff)
downloadnuttx-b7cb7361aaaa05fa411b258db0fcacb3c137792d.tar.gz
nuttx-b7cb7361aaaa05fa411b258db0fcacb3c137792d.tar.bz2
nuttx-b7cb7361aaaa05fa411b258db0fcacb3c137792d.zip
Networking: A litle more Unix domain socket logic
-rw-r--r--nuttx/net/local/Make.defs2
-rw-r--r--nuttx/net/local/local.h14
-rw-r--r--nuttx/net/local/local_conn.c102
-rw-r--r--nuttx/net/pkt/pkt.h2
-rw-r--r--nuttx/net/pkt/pkt_conn.c3
-rw-r--r--nuttx/net/socket/net_close.c58
-rw-r--r--nuttx/net/socket/socket.c265
7 files changed, 317 insertions, 129 deletions
diff --git a/nuttx/net/local/Make.defs b/nuttx/net/local/Make.defs
index 2a6b3b27f..fc58f7211 100644
--- a/nuttx/net/local/Make.defs
+++ b/nuttx/net/local/Make.defs
@@ -37,7 +37,7 @@
ifeq ($(CONFIG_NET_LOCAL),y)
-# NET_CSRCS +=
+NET_CSRCS += local_conn.c
# Include UDP build support
diff --git a/nuttx/net/local/local.h b/nuttx/net/local/local.h
index 5d8aec50b..e44a1739e 100644
--- a/nuttx/net/local/local.h
+++ b/nuttx/net/local/local.h
@@ -43,6 +43,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
+#include <sys/un.h>
#include <queue.h>
#include <stdint.h>
@@ -60,9 +61,9 @@
struct local_conn_s
{
- dq_entry_t node; /* Supports a doubly linked list */
- int16_t fd; /* File descriptor of underlying file */
- uint8_t crefs; /* Reference counts on this instance */
+ uint8_t lc_crefs; /* Reference counts on this instance */
+ int16_t lc_fd; /* File descriptor of underlying pipe */
+ char lc_path[UNIX_PATH_MAX]; /* Path assigned by bind() */
};
/****************************************************************************
@@ -88,12 +89,13 @@ struct socket; /* Forward reference */
* Name: local_initialize
*
* Description:
- * Initialize the local connection structures. Called once and only from
- * the UIP layer.
+ * Initialize the local, Unix domain connection structures. Called once
+ * and only from the common network initialization logic.
*
****************************************************************************/
-void local_initialize(void);
+/* void local_initialize(void) */
+#define local_initialize()
/****************************************************************************
* Name: local_alloc
diff --git a/nuttx/net/local/local_conn.c b/nuttx/net/local/local_conn.c
new file mode 100644
index 000000000..506b56b40
--- /dev/null
+++ b/nuttx/net/local/local_conn.c
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * net/local/local_conn.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL)
+
+#include <stdlib.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "local/local.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: local_initialize
+ *
+ * Description:
+ * Initialize the local, Unix domain connection structures. Called once
+ * and only from the common network initialization logic.
+ *
+ ****************************************************************************/
+
+/* void local_initialize(void) */
+
+/****************************************************************************
+ * Name: local_alloc()
+ *
+ * Description:
+ * Allocate a new, uninitialized Unix domain socket connection structure.
+ * This is normally something done by the implementation of the socket()
+ * API
+ *
+ ****************************************************************************/
+
+FAR struct local_conn_s *local_alloc(void)
+{
+ return (FAR struct local_conn_s *)malloc(sizeof(struct local_conn_s));
+}
+
+/****************************************************************************
+ * Name: local_free()
+ *
+ * Description:
+ * Free a packet Unix domain connection structure that is no longer in use.
+ * This should be done by the implementation of close().
+ *
+ ****************************************************************************/
+
+void local_free(FAR struct local_conn_s *conn)
+{
+ DEBUGASSERT(conn != NULL);
+ free(conn);
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_LOCAL */
diff --git a/nuttx/net/pkt/pkt.h b/nuttx/net/pkt/pkt.h
index 61fd45387..bf50889d5 100644
--- a/nuttx/net/pkt/pkt.h
+++ b/nuttx/net/pkt/pkt.h
@@ -100,7 +100,7 @@ extern "C"
*
* Description:
* Initialize the packet socket connection structures. Called once and
- * only from the UIP layer.
+ * only from the network initialization logic.
*
****************************************************************************/
diff --git a/nuttx/net/pkt/pkt_conn.c b/nuttx/net/pkt/pkt_conn.c
index 50a71c0c8..c47eea2d1 100644
--- a/nuttx/net/pkt/pkt_conn.c
+++ b/nuttx/net/pkt/pkt_conn.c
@@ -71,7 +71,7 @@ static struct pkt_conn_s g_pkt_connections[CONFIG_NET_PKT_CONNS];
static dq_queue_t g_free_pkt_connections;
static sem_t g_free_sem;
-/* A list of all allocated packet scoket connections */
+/* A list of all allocated packet socket connections */
static dq_queue_t g_active_pkt_connections;
@@ -129,6 +129,7 @@ void pkt_initialize(void)
for (i = 0; i < CONFIG_NET_PKT_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
+
g_pkt_connections[i].ifindex = 0;
dq_addlast(&g_pkt_connections[i].node, &g_free_pkt_connections);
}
diff --git a/nuttx/net/socket/net_close.c b/nuttx/net/socket/net_close.c
index d58d42829..bab3958e3 100644
--- a/nuttx/net/socket/net_close.c
+++ b/nuttx/net/socket/net_close.c
@@ -477,16 +477,16 @@ static void local_close(FAR struct socket *psock)
* be more if the socket was dup'ed).
*/
- if (conn->crefs <= 1)
+ if (conn->lc_crefs <= 1)
{
- conn->crefs = 0;
+ conn->lc_crefs = 0;
local_free(conn);
}
else
{
/* No.. Just decrement the reference count */
- conn->crefs--;
+ conn->lc_crefs--;
}
}
#endif /* CONFIG_NET_LOCAL */
@@ -533,32 +533,6 @@ int psock_close(FAR struct socket *psock)
switch (psock->s_type)
{
-#ifdef CONFIG_NET_PKT
- case SOCK_RAW:
- {
- FAR struct pkt_conn_s *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 */
-
- conn->crefs = 0; /* No more references on the connection */
- pkt_free(psock->s_conn); /* Free uIP resources */
- }
- else
- {
- /* No.. Just decrement the reference count */
-
- conn->crefs--;
- }
- }
- break;
-#endif
-
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL)
case SOCK_STREAM:
{
@@ -659,6 +633,32 @@ int psock_close(FAR struct socket *psock)
break;
#endif
+#ifdef CONFIG_NET_PKT
+ case SOCK_RAW:
+ {
+ FAR struct pkt_conn_s *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 */
+
+ conn->crefs = 0; /* No more references on the connection */
+ pkt_free(psock->s_conn); /* Free uIP resources */
+ }
+ else
+ {
+ /* No.. Just decrement the reference count */
+
+ conn->crefs--;
+ }
+ }
+ break;
+#endif
+
default:
err = EBADF;
goto errout;
diff --git a/nuttx/net/socket/socket.c b/nuttx/net/socket/socket.c
index 8e00143ca..427dd7016 100644
--- a/nuttx/net/socket/socket.c
+++ b/nuttx/net/socket/socket.c
@@ -54,6 +54,152 @@
#include "local/local.h"
/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: psock_tcp_alloc
+ *
+ * Description:
+ * Allocate and attach a TCP connection structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_TCP
+static int psock_tcp_alloc(FAR struct socket *psock)
+{
+ /* Allocate the TCP connection structure */
+
+ FAR struct tcp_conn_s *conn = tcp_alloc(psock->s_domain);
+ if (!conn)
+ {
+ /* Failed to reserve a connection structure */
+
+ return -ENOMEM;
+ }
+
+ /* Set the reference count on the connection structure. This reference
+ * count will be incremented only if the socket is dup'ed
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+
+ /* Save the pre-allocated connection in the socket structure */
+
+ psock->s_conn = conn;
+ return OK;
+}
+#endif /* CONFIG_NET_TCP */
+
+/****************************************************************************
+ * Name: psock_udp_alloc
+ *
+ * Description:
+ * Allocate and attach a UDP connection structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_UDP
+static int psock_udp_alloc(FAR struct socket *psock)
+{
+ /* Allocate the UDP connection structure */
+
+ FAR struct udp_conn_s *conn = udp_alloc(psock->s_domain);
+ if (!conn)
+ {
+ /* Failed to reserve a connection structure */
+
+ return -ENOMEM;
+ }
+
+ /* Set the reference count on the connection structure. This reference
+ * count will be incremented only if the socket is dup'ed
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+
+ /* Save the pre-allocated connection in the socket structure */
+
+ psock->s_conn = conn;
+ return OK;
+}
+#endif /* CONFIG_NET_UDP */
+
+/****************************************************************************
+ * Name: psock_pkt_alloc
+ *
+ * Description:
+ * Allocate and attach a raw packet connection structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_PKT
+static int psock_pkt_alloc(FAR struct socket *psock)
+{
+ /* Allocate the packet socket connection structure and save in the new
+ * socket instance.
+ */
+
+ FAR struct pkt_conn_s *conn = pkt_alloc();
+ if (!conn)
+ {
+ /* Failed to reserve a connection structure */
+
+ return -ENOMEM;
+ }
+
+ /* Set the reference count on the connection structure. This reference
+ * count will be incremented only if the socket is dup'ed
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+ conn->crefs = 1;
+
+ /* Save the pre-allocated connection in the socket structure */
+
+ psock->s_conn = conn;
+ return OK;
+}
+#endif /* CONFIG_NET_PKT */
+
+/****************************************************************************
+ * Name: psock_local_alloc
+ *
+ * Description:
+ * Allocate and attach a local, Unix domain connection structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_LOCAL
+static int psock_local_alloc(FAR struct socket *psock)
+{
+ /* Allocate the local connection structure */
+
+ FAR struct local_conn_s *conn = local_alloc();
+ if (!conn)
+ {
+ /* Failed to reserve a connection structure */
+
+ return -ENOMEM;
+ }
+
+ /* Set the reference count on the connection structure. This reference
+ * count will be incremented only if the socket is dup'ed
+ */
+
+ DEBUGASSERT(conn->lc_crefs == 0);
+ conn->lc_crefs = 1;
+
+ /* Save the pre-allocated connection in the socket structure */
+
+ psock->s_conn = conn;
+ return OK;
+}
+#endif /* CONFIG_NET_LOCAL */
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -101,6 +247,7 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
bool ipdomain = false;
#endif
bool dgramok = false;
+ int ret;
int err;
/* Only PF_INET, PF_INET6 or PF_PACKET domains supported */
@@ -209,27 +356,9 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
if (ipdomain)
#endif
{
- /* Allocate the TCP connection structure */
+ /* Allocate and attach the TCP connection structure */
- FAR struct tcp_conn_s *conn = tcp_alloc(domain);
- if (!conn)
- {
- /* Failed to reserve a connection structure */
-
- goto errout; /* With err == ENFILE or ENOMEM */
- }
-
- /* 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;
-
- /* Save the pre-allocated connection in the socket structure */
-
- psock->s_conn = conn;
+ ret = psock_tcp_alloc(psock);
}
#endif /* CONFIG_NET_TCP */
@@ -238,29 +367,21 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
else
#endif
{
- /* Allocate the local connection structure */
-
- FAR struct local_conn_s *conn = local_alloc();
- if (!conn)
- {
- /* Failed to reserve a connection structure */
+ /* Allocate and attach the local connection structure */
- goto errout; /* With err == ENFILE or ENOMEM */
- }
-
- /* Set the reference count on the connection structure. This
- * reference count will be increment only if the socket is
- * dup'ed
- */
+ ret = psock_local_alloc(psock);
+ }
+#endif /* CONFIG_NET_LOCAL */
- DEBUGASSERT(conn->crefs == 0);
- conn->crefs = 1;
+ /* Check for failures to allocate the connection structure. */
- /* Save the pre-allocated connection in the socket structure */
+ if (ret < 0)
+ {
+ /* Failed to reserve a connection structure */
- psock->s_conn = conn;
+ err = -ret;
+ goto errout;
}
-#endif /* CONFIG_NET_LOCAL */
}
break;
#endif
@@ -273,27 +394,9 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
if (ipdomain)
#endif
{
- /* Allocate the UDP connection structure */
-
- FAR struct udp_conn_s *conn = udp_alloc(domain);
- if (!conn)
- {
- /* Failed to reserve a connection structure */
-
- goto errout; /* With err == ENFILE or ENOMEM */
- }
+ /* Allocate and attach the UDP connection structure */
- /* 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;
-
- /* Save the pre-allocated connection in the socket structure */
-
- psock->s_conn = conn;
+ ret = psock_udp_alloc(psock);
}
#endif /* CONFIG_NET_UDP */
@@ -302,29 +405,21 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
else
#endif
{
- /* Allocate the local connection structure */
-
- FAR struct local_conn_s *conn = local_alloc();
- if (!conn)
- {
- /* Failed to reserve a connection structure */
+ /* Allocate and attach the local connection structure */
- goto errout; /* With err == ENFILE or ENOMEM */
- }
-
- /* Set the reference count on the connection structure. This
- * reference count will be increment only if the socket is
- * dup'ed
- */
+ ret = psock_local_alloc(psock);
+ }
+#endif /* CONFIG_NET_LOCAL */
- DEBUGASSERT(conn->crefs == 0);
- conn->crefs = 1;
+ /* Check for failures to allocate the connection structure. */
- /* Save the pre-allocated connection in the socket structure */
+ if (ret < 0)
+ {
+ /* Failed to reserve a connection structure */
- psock->s_conn = conn;
+ err = -ret;
+ goto errout;
}
-#endif /* CONFIG_NET_LOCAL */
}
break;
#endif
@@ -332,26 +427,14 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
#ifdef CONFIG_NET_PKT
case SOCK_RAW:
{
- /* Allocate the packet socket connection structure and save
- * in the new socket instance.
- */
-
- FAR struct pkt_conn_s *conn = pkt_alloc();
- if (!conn)
+ ret = psock_pkt_alloc(FAR struct socket *psock)
+ if (ret < 0)
{
/* Failed to reserve a connection structure */
+ err = -ret;
goto errout;
}
-
- /* 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);
- psock->s_conn = conn;
- conn->crefs = 1;
}
break;
#endif