You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/01/21 14:30:58 UTC

[incubator-nuttx] 02/04: net/tcp, udp: Move tcp/udp close operation into tcp/udp folder

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit e869a10c1892094aa568d8d5d739c78a74813246
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Jan 21 14:11:29 2020 +0800

    net/tcp, udp:  Move tcp/udp close operation into tcp/udp folder
    
    Move tcp/udp close operation into tcp/udp folder and remove inet_close.c
---
 net/inet/Make.defs                         |   4 +-
 net/inet/inet_sockif.c                     | 117 ++++++++++++++
 net/tcp/Make.defs                          |   2 +-
 net/tcp/tcp.h                              |  16 ++
 net/{inet/inet_close.c => tcp/tcp_close.c} | 241 +++--------------------------
 net/udp/Make.defs                          |   2 +-
 net/udp/udp.h                              |  16 ++
 net/udp/udp_close.c                        | 138 +++++++++++++++++
 8 files changed, 314 insertions(+), 222 deletions(-)

diff --git a/net/inet/Make.defs b/net/inet/Make.defs
index 980db1b..c27b728 100644
--- a/net/inet/Make.defs
+++ b/net/inet/Make.defs
@@ -38,10 +38,10 @@
 SOCK_CSRCS += inet_txdrain.c
 
 ifeq ($(CONFIG_NET_IPv4),y)
-SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_close.c
+SOCK_CSRCS += inet_sockif.c inet_recvfrom.c
 SOCK_CSRCS += inet_globals.c
 else ifeq ($(CONFIG_NET_IPv6),y)
-SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_close.c
+SOCK_CSRCS += inet_sockif.c inet_recvfrom.c
 SOCK_CSRCS += inet_globals.c
 endif
 
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 5a05fda..5ce865f 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -1281,6 +1281,123 @@ static ssize_t inet_sendfile(FAR struct socket *psock,
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: inet_close
+ *
+ * Description:
+ *   Performs the close operation on an AF_INET or AF_INET6 socket instance
+ *
+ * Input Parameters:
+ *   psock   Socket instance
+ *
+ * Returned Value:
+ *   0 on success; -1 on error with errno set appropriately.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int inet_close(FAR struct socket *psock)
+{
+  /* Perform some pre-close operations for the AF_INET/AF_INET6 address
+   * types.
+   */
+
+  switch (psock->s_type)
+    {
+#ifdef CONFIG_NET_TCP
+      case SOCK_STREAM:
+        {
+#ifdef NET_TCP_HAVE_STACK
+          FAR struct tcp_conn_s *conn = psock->s_conn;
+          int ret;
+
+          /* Is this the last reference to the connection structure (there
+           * could be more if the socket was dup'ed).
+           */
+
+          if (conn->crefs <= 1)
+            {
+              /* Yes... Clost the socket */
+
+              ret = tcp_close(psock);
+              if (ret < 0)
+                {
+                  /* This would normally occur only if there is a timeout
+                   * from a lingering close.
+                   */
+
+                  nerr("ERROR: tcp_close failed: %d\n", ret);
+                  return ret;
+                }
+            }
+          else
+            {
+              /* No.. Just decrement the reference count */
+
+              conn->crefs--;
+
+              /* Stop monitor for this socket only */
+
+              tcp_close_monitor(psock);
+            }
+#else
+        nwarn("WARNING: SOCK_STREAM support is not available in this "
+              "configuration\n");
+        return -EAFNOSUPPORT;
+#endif /* NET_TCP_HAVE_STACK */
+        }
+        break;
+#endif /* CONFIG_NET_TCP */
+
+#ifdef CONFIG_NET_UDP
+      case SOCK_DGRAM:
+        {
+#ifdef NET_UDP_HAVE_STACK
+          FAR struct udp_conn_s *conn = psock->s_conn;
+          int ret;
+
+          /* Is this the last reference to the connection structure (there
+           * could be more if the socket was dup'ed).
+           */
+
+          if (conn->crefs <= 1)
+            {
+              /* Yes... Clost the socket */
+
+              ret = udp_close(psock);
+              if (ret < 0)
+                {
+                  /* This would normally occur only if there is a timeout
+                   * from a lingering close.
+                   */
+
+                  nerr("ERROR: udp_close failed: %d\n", ret);
+                  return ret;
+                }
+            }
+          else
+            {
+              /* No.. Just decrement the reference count */
+
+              conn->crefs--;
+            }
+#else
+          nwarn("WARNING: SOCK_DGRAM support is not available in this "
+                "configuration\n");
+          return -EAFNOSUPPORT;
+#endif /* NET_UDP_HAVE_STACK */
+        }
+        break;
+#endif /* CONFIG_NET_UDP */
+
+      default:
+        return -EBADF;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
  * Name: inet_sockif
  *
  * Description:
diff --git a/net/tcp/Make.defs b/net/tcp/Make.defs
index 4cc27db..8b165da 100644
--- a/net/tcp/Make.defs
+++ b/net/tcp/Make.defs
@@ -66,7 +66,7 @@ endif
 # Transport layer
 
 NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
-NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c
+NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c tcp_close.c
 NET_CSRCS += tcp_monitor.c tcp_callback.c tcp_backlog.c tcp_ipselect.c
 NET_CSRCS += tcp_recvwindow.c tcp_netpoll.c
 
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index af62dab..93e3cf6 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -668,6 +668,22 @@ void tcp_lost_connection(FAR struct socket *psock,
                          FAR struct devif_callback_s *cb, uint16_t flags);
 
 /****************************************************************************
+ * Name: tcp_close
+ *
+ * Description:
+ *   Break any current TCP connection
+ *
+ * Input Parameters:
+ *   psock - An instance of the internal socket structure.
+ *
+ * Assumptions:
+ *   Called from normal user-level logic
+ *
+ ****************************************************************************/
+
+int tcp_close(FAR struct socket *psock);
+
+/****************************************************************************
  * Name: tcp_ipv4_select
  *
  * Description:
diff --git a/net/inet/inet_close.c b/net/tcp/tcp_close.c
similarity index 67%
rename from net/inet/inet_close.c
rename to net/tcp/tcp_close.c
index dd5dd83..d326c3e 100644
--- a/net/inet/inet_close.c
+++ b/net/tcp/tcp_close.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * net/inet/inet_close.c
+ * net/tcp/tcp_close.c
  *
- *   Copyright (C) 2007-2017, 2019 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,38 +38,25 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#ifdef CONFIG_NET_TCP
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdint.h>
-#include <stdbool.h>
 #include <errno.h>
 #include <debug.h>
 #include <assert.h>
 
-#include <arch/irq.h>
-
-#include <nuttx/semaphore.h>
 #include <nuttx/net/net.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/tcp.h>
-#include <nuttx/net/udp.h>
 
 #include "netdev/netdev.h"
 #include "devif/devif.h"
 #include "tcp/tcp.h"
-#include "udp/udp.h"
-#include "pkt/pkt.h"
-#include "local/local.h"
 #include "socket/socket.h"
-#include "usrsock/usrsock.h"
-#include "inet/inet.h"
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
 struct tcp_close_s
 {
   FAR struct devif_callback_s *cl_cb;     /* Reference to TCP callback instance */
@@ -77,7 +64,6 @@ struct tcp_close_s
   sem_t                        cl_sem;    /* Signals disconnect completion */
   int                          cl_result; /* The result of the close */
 };
-#endif
 
 /****************************************************************************
  * Private Functions
@@ -85,22 +71,8 @@ struct tcp_close_s
 
 /****************************************************************************
  * Name: tcp_close_eventhandler
- *
- * Description:
- *   Handle network callback events.
- *
- * Input Parameters:
- *   conn - TCP connection structure
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   Called from normal user-level logic
- *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
 static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev,
                                        FAR void *pvconn, FAR void *pvpriv,
                                        uint16_t flags)
@@ -197,7 +169,6 @@ end_wait:
   ninfo("Resuming\n");
   return flags;
 }
-#endif /* NET_TCP_HAVE_STACK */
 
 /****************************************************************************
  * Name: tcp_close_txnotify
@@ -215,7 +186,6 @@ end_wait:
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
 static inline void tcp_close_txnotify(FAR struct socket *psock,
                                       FAR struct tcp_conn_s *conn)
 {
@@ -246,7 +216,6 @@ static inline void tcp_close_txnotify(FAR struct socket *psock,
     }
 #endif /* CONFIG_NET_IPv6 */
 }
-#endif /* NET_TCP_HAVE_STACK */
 
 /****************************************************************************
  * Name: tcp_close_disconnect
@@ -265,7 +234,6 @@ static inline void tcp_close_txnotify(FAR struct socket *psock,
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
 static inline int tcp_close_disconnect(FAR struct socket *psock)
 {
   struct tcp_close_s state;
@@ -389,215 +357,52 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
   net_unlock();
   return ret;
 }
-#endif /* NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: udp_close
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tcp_close
  *
  * Description:
- *   Break any current UDP connection
+ *   Break any current TCP connection
  *
  * Input Parameters:
- *   conn - UDP connection structure
- *
- * Returned Value:
- *   None
+ *   psock - An instance of the internal socket structure.
  *
  * Assumptions:
  *   Called from normal user-level logic
  *
  ****************************************************************************/
 
-#ifdef NET_UDP_HAVE_STACK
-static inline int udp_close(FAR struct socket *psock)
+int tcp_close(FAR struct socket *psock)
 {
-  FAR struct udp_conn_s *conn;
-  unsigned int timeout = UINT_MAX;
+  FAR struct tcp_conn_s *conn = psock->s_conn;
   int ret;
 
-  /* Interrupts are disabled here to avoid race conditions */
+  /* Perform the disconnection now */
 
-  net_lock();
+  tcp_unlisten(conn); /* No longer accepting connections */
+  conn->crefs = 0;    /* Discard our reference to the connection */
 
-  conn = (FAR struct udp_conn_s *)psock->s_conn;
-  DEBUGASSERT(conn != NULL);
-
-#ifdef CONFIG_NET_SOLINGER
-  /* SO_LINGER
-   *   Lingers on a close() if data is present. This option controls the
-   *   action taken when unsent messages queue on a socket and close() is
-   *   performed. If SO_LINGER is set, the system shall block the calling
-   *   thread during close() until it can transmit the data or until the
-   *   time expires. If SO_LINGER is not specified, and close() is issued,
-   *   the system handles the call in a way that allows the calling thread
-   *   to continue as quickly as possible. This option takes a linger
-   *   structure, as defined in the <sys/socket.h> header, to specify the
-   *   state of the option and linger interval.
-   */
-
-  if (_SO_GETOPT(psock->s_options, SO_LINGER))
-    {
-      timeout = _SO_TIMEOUT(psock->s_linger);
-    }
-#endif
-
-  /* Wait until for the buffered TX data to be sent. */
+  /* Break any current connections and close the socket */
 
-  ret = udp_txdrain(psock, timeout);
+  ret = tcp_close_disconnect(psock);
   if (ret < 0)
     {
-      /* udp_txdrain may fail, but that won't stop us from closing
-       * the socket.
+      /* This would normally occur only if there is a timeout
+       * from a lingering close.
        */
 
-      nerr("ERROR: udp_txdrain() failed: %d\n", ret);
-    }
-
-#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
-  /* Free any semi-permanent write buffer callback in place. */
-
-  if (psock->s_sndcb != NULL)
-    {
-      udp_callback_free(conn->dev, conn, psock->s_sndcb);
-      psock->s_sndcb = NULL;
+      nerr("ERROR: tcp_close_disconnect failed: %d\n", ret);
+      return ret;
     }
-#endif
 
-  /* And free the connection structure */
+  /* Stop the network monitor for all sockets */
 
-  conn->crefs = 0;
-  udp_free(psock->s_conn);
-  net_unlock();
+  tcp_stop_monitor(conn, TCP_CLOSE);
   return OK;
 }
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
 
-/****************************************************************************
- * Name: inet_close
- *
- * Description:
- *   Performs the close operation on an AF_INET or AF_INET6 socket instance
- *
- * Input Parameters:
- *   psock   Socket instance
- *
- * Returned Value:
- *   0 on success; -1 on error with errno set appropriately.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-int inet_close(FAR struct socket *psock)
-{
-  /* Perform some pre-close operations for the AF_INET/AF_INET6 address
-   * types.
-   */
-
-  switch (psock->s_type)
-    {
-#ifdef CONFIG_NET_TCP
-      case SOCK_STREAM:
-        {
-#ifdef NET_TCP_HAVE_STACK
-          FAR struct tcp_conn_s *conn = psock->s_conn;
-          int ret;
-
-          /* Is this the last reference to the connection structure (there
-           * could be more if the socket was dup'ed).
-           */
-
-          if (conn->crefs <= 1)
-            {
-              /* Yes... then perform the disconnection now */
-
-              tcp_unlisten(conn); /* No longer accepting connections */
-              conn->crefs = 0;    /* Discard our reference to the connection */
-
-              /* Break any current connections and close the socket */
-
-              ret = tcp_close_disconnect(psock);
-              if (ret < 0)
-                {
-                  /* This would normally occur only if there is a timeout
-                   * from a lingering close.
-                   */
-
-                  nerr("ERROR: tcp_close_disconnect failed: %d\n", ret);
-                  return ret;
-                }
-
-              /* Stop the network monitor for all sockets */
-
-              tcp_stop_monitor(conn, TCP_CLOSE);
-            }
-          else
-            {
-              /* No.. Just decrement the reference count */
-
-              conn->crefs--;
-
-              /* Stop monitor for this socket only */
-
-              tcp_close_monitor(psock);
-            }
-#else
-        nwarn("WARNING: SOCK_STREAM support is not available in this "
-              "configuration\n");
-        return -EAFNOSUPPORT;
-#endif /* NET_TCP_HAVE_STACK */
-        }
-        break;
 #endif /* CONFIG_NET_TCP */
-
-#ifdef CONFIG_NET_UDP
-      case SOCK_DGRAM:
-        {
-#ifdef NET_UDP_HAVE_STACK
-          FAR struct udp_conn_s *conn = psock->s_conn;
-          int ret;
-
-          /* Is this the last reference to the connection structure (there
-           * could be more if the socket was dup'ed).
-           */
-
-          if (conn->crefs <= 1)
-            {
-              /* Yes... Clost the socket */
-
-              ret = udp_close(psock);
-              if (ret < 0)
-                {
-                  /* This would normally occur only if there is a timeout
-                   * from a lingering close.
-                   */
-
-                  nerr("ERROR: udp_close failed: %d\n", ret);
-                  return ret;
-                }
-            }
-          else
-            {
-              /* No.. Just decrement the reference count */
-
-              conn->crefs--;
-            }
-#else
-          nwarn("WARNING: SOCK_DGRAM support is not available in this "
-                "configuration\n");
-          return -EAFNOSUPPORT;
-#endif /* NET_UDP_HAVE_STACK */
-        }
-        break;
-#endif /* CONFIG_NET_UDP */
-
-      default:
-        return -EBADF;
-    }
-
-  return OK;
-}
diff --git a/net/udp/Make.defs b/net/udp/Make.defs
index 0501ae4..1c9487a 100644
--- a/net/udp/Make.defs
+++ b/net/udp/Make.defs
@@ -60,7 +60,7 @@ endif
 # Transport layer
 
 NET_CSRCS += udp_conn.c udp_devpoll.c udp_send.c udp_input.c udp_finddev.c
-NET_CSRCS += udp_callback.c udp_ipselect.c udp_netpoll.c
+NET_CSRCS += udp_close.c udp_callback.c udp_ipselect.c udp_netpoll.c
 
 # UDP write buffering
 
diff --git a/net/udp/udp.h b/net/udp/udp.h
index aa1caef..40d3a97 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -301,6 +301,22 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr);
 int udp_connect(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr);
 
 /****************************************************************************
+ * Name: udp_close
+ *
+ * Description:
+ *   Break any current UDP connection
+ *
+ * Input Parameters:
+ *   psock - An instance of the internal socket structure.
+ *
+ * Assumptions:
+ *   Called from normal user-level logic
+ *
+ ****************************************************************************/
+
+int udp_close(FAR struct socket *psock);
+
+/****************************************************************************
  * Name: udp_ipv4_select
  *
  * Description:
diff --git a/net/udp/udp_close.c b/net/udp/udp_close.c
new file mode 100644
index 0000000..ec735c4
--- /dev/null
+++ b/net/udp/udp_close.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * net/udp/udp_close.c
+ *
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@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_UDP)
+
+#include <errno.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <nuttx/net/net.h>
+#include <nuttx/net/udp.h>
+
+#include "devif/devif.h"
+#include "udp/udp.h"
+#include "socket/socket.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: udp_close
+ *
+ * Description:
+ *   Break any current UDP connection
+ *
+ * Input Parameters:
+ *   conn - UDP connection structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called from normal user-level logic
+ *
+ ****************************************************************************/
+
+int udp_close(FAR struct socket *psock)
+{
+  FAR struct udp_conn_s *conn;
+  unsigned int timeout = UINT_MAX;
+  int ret;
+
+  /* Interrupts are disabled here to avoid race conditions */
+
+  net_lock();
+
+  conn = (FAR struct udp_conn_s *)psock->s_conn;
+  DEBUGASSERT(conn != NULL);
+
+#ifdef CONFIG_NET_SOLINGER
+  /* SO_LINGER
+   *   Lingers on a close() if data is present. This option controls the
+   *   action taken when unsent messages queue on a socket and close() is
+   *   performed. If SO_LINGER is set, the system shall block the calling
+   *   thread during close() until it can transmit the data or until the
+   *   time expires. If SO_LINGER is not specified, and close() is issued,
+   *   the system handles the call in a way that allows the calling thread
+   *   to continue as quickly as possible. This option takes a linger
+   *   structure, as defined in the <sys/socket.h> header, to specify the
+   *   state of the option and linger interval.
+   */
+
+  if (_SO_GETOPT(psock->s_options, SO_LINGER))
+    {
+      timeout = _SO_TIMEOUT(psock->s_linger);
+    }
+#endif
+
+  /* Wait until for the buffered TX data to be sent. */
+
+  UNUSED(timeout);
+  ret = udp_txdrain(psock, timeout);
+  if (ret < 0)
+    {
+      /* udp_txdrain may fail, but that won't stop us from closing
+       * the socket.
+       */
+
+      nerr("ERROR: udp_txdrain() failed: %d\n", ret);
+    }
+
+#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
+  /* Free any semi-permanent write buffer callback in place. */
+
+  if (psock->s_sndcb != NULL)
+    {
+      udp_callback_free(conn->dev, conn, psock->s_sndcb);
+      psock->s_sndcb = NULL;
+    }
+#endif
+
+  /* And free the connection structure */
+
+  conn->crefs = 0;
+  udp_free(psock->s_conn);
+  net_unlock();
+  return OK;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */