From b7cb7361aaaa05fa411b258db0fcacb3c137792d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 25 Jan 2015 07:36:16 -0600 Subject: Networking: A litle more Unix domain socket logic --- nuttx/net/local/Make.defs | 2 +- nuttx/net/local/local.h | 14 ++- nuttx/net/local/local_conn.c | 102 +++++++++++++++++ nuttx/net/pkt/pkt.h | 2 +- nuttx/net/pkt/pkt_conn.c | 3 +- nuttx/net/socket/net_close.c | 58 +++++----- nuttx/net/socket/socket.c | 265 ++++++++++++++++++++++++++++--------------- 7 files changed, 317 insertions(+), 129 deletions(-) create mode 100644 nuttx/net/local/local_conn.c 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 #include +#include #include #include @@ -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 + * + * 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 +#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL) + +#include +#include +#include + +#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 @@ -53,6 +53,152 @@ #include "pkt/pkt.h" #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 -- cgit v1.2.3