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:56 UTC

[incubator-nuttx] branch master updated (389e882 -> 6d4b86f)

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

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


    from 389e882  sim/x64: Enable cxx new long (#139)
     new 677536c  net/udp:  Rename udp_psock_sendto_xxx.c to udp_sendto_xxx.c like TCP
     new e869a10  net/tcp, udp:  Move tcp/udp close operation into tcp/udp folder
     new e75b5e9  net/tcp and udp:  Move tcp/udp recvfrom into tcp/udp folder
     new 6d4b86f  net/tcp/tcp.h:  Correct spacing error introduced with the last PR.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 net/inet/Make.defs                                 |   4 +-
 net/inet/inet.h                                    |  35 -
 net/inet/inet_sockif.c                             | 243 ++++++-
 net/tcp/Make.defs                                  |   4 +-
 net/tcp/tcp.h                                      |  40 ++
 net/{inet/inet_close.c => tcp/tcp_close.c}         | 241 +------
 net/{inet/inet_recvfrom.c => tcp/tcp_recvfrom.c}   | 708 ++-------------------
 net/udp/Make.defs                                  |   8 +-
 net/udp/udp.h                                      |  37 +-
 net/{socket/net_close.c => udp/udp_close.c}        | 115 ++--
 net/udp/udp_psock_send.c                           |  88 ---
 net/udp/udp_recvfrom.c                             | 707 ++++++++++++++++++++
 ...ock_sendto_buffered.c => udp_sendto_buffered.c} |   2 +-
 ...sendto_unbuffered.c => udp_sendto_unbuffered.c} |   2 +-
 14 files changed, 1160 insertions(+), 1074 deletions(-)
 rename net/{inet/inet_close.c => tcp/tcp_close.c} (67%)
 rename net/{inet/inet_recvfrom.c => tcp/tcp_recvfrom.c} (52%)
 copy net/{socket/net_close.c => udp/udp_close.c} (55%)
 delete mode 100644 net/udp/udp_psock_send.c
 create mode 100644 net/udp/udp_recvfrom.c
 rename net/udp/{udp_psock_sendto_buffered.c => udp_sendto_buffered.c} (99%)
 rename net/udp/{udp_psock_sendto_unbuffered.c => udp_sendto_unbuffered.c} (99%)


[incubator-nuttx] 04/04: net/tcp/tcp.h: Correct spacing error introduced with the last PR.

Posted by gn...@apache.org.
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 6d4b86ff06f823d89fd3097968806cb73b10600d
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Tue Jan 21 08:23:50 2020 -0600

    net/tcp/tcp.h:  Correct spacing error introduced with the last PR.
---
 net/tcp/tcp.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index e1ae766..58751e7 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -1267,7 +1267,6 @@ int tcp_backlogdelete(FAR struct tcp_conn_s *conn,
 int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
                      FAR socklen_t *addrlen, FAR void **newconn);
 
-
 /****************************************************************************
  * Name: psock_tcp_recvfrom
  *


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

Posted by gn...@apache.org.
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 */


[incubator-nuttx] 03/04: net/tcp and udp: Move tcp/udp recvfrom into tcp/udp folder

Posted by gn...@apache.org.
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 e75b5e9d86db281e22a97c58605aea5192c6035a
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Jan 21 15:50:39 2020 +0800

    net/tcp and udp:  Move tcp/udp recvfrom into tcp/udp folder
    
    Move tcp/udp recvfrom into tcp/udp folder and remove inet_recvfrom.c
---
 net/inet/Make.defs                               |   4 +-
 net/inet/inet.h                                  |  35 --
 net/inet/inet_sockif.c                           | 120 ++++
 net/tcp/Make.defs                                |   2 +-
 net/tcp/tcp.h                                    |  25 +
 net/{inet/inet_recvfrom.c => tcp/tcp_recvfrom.c} | 708 ++---------------------
 net/udp/Make.defs                                |   2 +
 net/udp/udp.h                                    |  24 +
 net/udp/udp_recvfrom.c                           | 707 ++++++++++++++++++++++
 9 files changed, 930 insertions(+), 697 deletions(-)

diff --git a/net/inet/Make.defs b/net/inet/Make.defs
index c27b728..6503ff9 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
+SOCK_CSRCS += inet_sockif.c
 SOCK_CSRCS += inet_globals.c
 else ifeq ($(CONFIG_NET_IPv6),y)
-SOCK_CSRCS += inet_sockif.c inet_recvfrom.c
+SOCK_CSRCS += inet_sockif.c
 SOCK_CSRCS += inet_globals.c
 endif
 
diff --git a/net/inet/inet.h b/net/inet/inet.h
index eef1f36..81f923c 100644
--- a/net/inet/inet.h
+++ b/net/inet/inet.h
@@ -241,41 +241,6 @@ int ipv6_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr,
 #endif
 
 /****************************************************************************
- * Name: inet_recvfrom
- *
- * Description:
- *   Implements the socket recvfrom interface for the case of the AF_INET
- *   and AF_INET6 address families.  inet_recvfrom() receives messages from
- *   a socket, and may be used to receive data on a socket whether or not it
- *   is connection-oriented.
- *
- *   If 'from' is not NULL, and the underlying protocol provides the source
- *   address, this source address is filled in.  The argument 'fromlen' is
- *   initialized to the size of the buffer associated with from, and
- *   modified on return to indicate the actual size of the address stored
- *   there.
- *
- * Input Parameters:
- *   psock    A pointer to a NuttX-specific, internal socket structure
- *   buf      Buffer to receive data
- *   len      Length of buffer
- *   flags    Receive flags
- *   from     Address of source (may be NULL)
- *   fromlen  The length of the address structure
- *
- * Returned Value:
- *   On success, returns the number of characters received.  If no data is
- *   available to be received and the peer has performed an orderly shutdown,
- *   recv() will return 0.  Otherwise, on errors, a negated errno value is
- *   returned (see recvfrom() for the list of appropriate error values).
- *
- ****************************************************************************/
-
-ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                      int flags, FAR struct sockaddr *from,
-                      FAR socklen_t *fromlen);
-
-/****************************************************************************
  * Name: inet_close
  *
  * Description:
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 5ce865f..8a66b89 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -90,6 +90,9 @@ static ssize_t    inet_sendto(FAR struct socket *psock, FAR const void *buf,
 static ssize_t    inet_sendfile(FAR struct socket *psock, FAR struct file *infile,
                     FAR off_t *offset, size_t count);
 #endif
+static ssize_t    inet_recvfrom(FAR struct socket *psock, FAR void *buf,
+                    size_t len, int flags, FAR struct sockaddr *from,
+                    FAR socklen_t *fromlen);
 
 /****************************************************************************
  * Private Data
@@ -1274,6 +1277,123 @@ static ssize_t inet_sendfile(FAR struct socket *psock,
 }
 #endif
 
+/****************************************************************************
+ * Name: inet_recvfrom
+ *
+ * Description:
+ *   Implements the socket recvfrom interface for the case of the AF_INET
+ *   and AF_INET6 address families.  inet_recvfrom() receives messages from
+ *   a socket, and may be used to receive data on a socket whether or not it
+ *   is connection-oriented.
+ *
+ *   If 'from' is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in.  The argument 'fromlen' is
+ *   initialized to the size of the buffer associated with from, and
+ *   modified on return to indicate the actual size of the address stored
+ *   there.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     Address of source (may be NULL)
+ *   fromlen  The length of the address structure
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  If no data is
+ *   available to be received and the peer has performed an orderly shutdown,
+ *   recv() will return 0.  Otherwise, on errors, a negated errno value is
+ *   returned (see recvfrom() for the list of appropriate error values).
+ *
+ ****************************************************************************/
+
+static ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf,
+                             size_t len, int flags, FAR struct sockaddr *from,
+                             FAR socklen_t *fromlen)
+{
+  ssize_t ret;
+
+  /* If a 'from' address has been provided, verify that it is large
+   * enough to hold this address family.
+   */
+
+  if (from)
+    {
+      socklen_t minlen;
+
+      /* Get the minimum socket length */
+
+      switch (psock->s_domain)
+        {
+#ifdef CONFIG_NET_IPv4
+        case PF_INET:
+          {
+            minlen = sizeof(struct sockaddr_in);
+          }
+          break;
+#endif
+
+#ifdef CONFIG_NET_IPv6
+        case PF_INET6:
+          {
+            minlen = sizeof(struct sockaddr_in6);
+          }
+          break;
+#endif
+
+        default:
+          DEBUGPANIC();
+          return -EINVAL;
+        }
+
+      if (*fromlen < minlen)
+        {
+          return -EINVAL;
+        }
+    }
+
+  /* Read from the network interface driver buffer.
+   * Or perform the TCP/IP or UDP recv() operation.
+   */
+
+  switch (psock->s_type)
+    {
+#ifdef CONFIG_NET_TCP
+    case SOCK_STREAM:
+      {
+#ifdef NET_TCP_HAVE_STACK
+        ret = psock_tcp_recvfrom(psock, buf, len, from, fromlen);
+#else
+        ret = -ENOSYS;
+#endif
+      }
+      break;
+#endif /* CONFIG_NET_TCP */
+
+#ifdef CONFIG_NET_UDP
+    case SOCK_DGRAM:
+      {
+#ifdef NET_UDP_HAVE_STACK
+        ret = psock_udp_recvfrom(psock, buf, len, from, fromlen);
+#else
+        ret = -ENOSYS;
+#endif
+      }
+      break;
+#endif /* CONFIG_NET_UDP */
+
+    default:
+      {
+        nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
+        ret = -ENOSYS;
+      }
+      break;
+    }
+
+  return ret;
+}
+
 #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
 
 /****************************************************************************
diff --git a/net/tcp/Make.defs b/net/tcp/Make.defs
index 8b165da..595f137 100644
--- a/net/tcp/Make.defs
+++ b/net/tcp/Make.defs
@@ -40,7 +40,7 @@ ifneq ($(CONFIG_NET_TCP_NO_STACK),y)
 
 # Socket layer
 
-SOCK_CSRCS += tcp_connect.c tcp_accept.c
+SOCK_CSRCS += tcp_connect.c tcp_accept.c tcp_recvfrom.c
 
 ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y)
 SOCK_CSRCS += tcp_send_buffered.c
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index 93e3cf6..e1ae766 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -1267,6 +1267,31 @@ int tcp_backlogdelete(FAR struct tcp_conn_s *conn,
 int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
                      FAR socklen_t *addrlen, FAR void **newconn);
 
+
+/****************************************************************************
+ * Name: psock_tcp_recvfrom
+ *
+ * Description:
+ *   Perform the recvfrom operation for a TCP/IP SOCK_STREAM
+ *
+ * Input Parameters:
+ *   psock  Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf    Buffer to receive data
+ *   len    Length of buffer
+ *   from   INET address of source (may be NULL)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  On  error,
+ *   -errno is returned (see recvfrom for list of errnos).
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
+                           size_t len, FAR struct sockaddr *from,
+                           FAR socklen_t *fromlen);
+
 /****************************************************************************
  * Name: psock_tcp_send
  *
diff --git a/net/inet/inet_recvfrom.c b/net/tcp/tcp_recvfrom.c
similarity index 52%
rename from net/inet/inet_recvfrom.c
rename to net/tcp/tcp_recvfrom.c
index 7d56b54..e3aa345 100644
--- a/net/inet/inet_recvfrom.c
+++ b/net/tcp/tcp_recvfrom.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * net/inet/inet_recvfrom.c
+ * net/tcp/tcp_recvfrom.c
  *
- *   Copyright (C) 2007-2009, 2011-2018 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,37 +38,23 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#ifdef CONFIG_NET_TCP
 
-#ifdef CONFIG_NET
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdint.h>
 #include <string.h>
 #include <errno.h>
 #include <debug.h>
 #include <assert.h>
 
-#include <arch/irq.h>
-
-#include <nuttx/semaphore.h>
-#include <nuttx/cancelpt.h>
 #include <nuttx/net/net.h>
 #include <nuttx/mm/iob.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/ip.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"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -77,9 +63,6 @@
 #define IPv4BUF    ((struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
 #define IPv6BUF    ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
 
-#define UDPIPv4BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN])
-#define UDPIPv6BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
-
 #define TCPIPv4BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN])
 #define TCPIPv6BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
 
@@ -87,8 +70,7 @@
  * Private Types
  ****************************************************************************/
 
-#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
-struct inet_recvfrom_s
+struct tcp_recvfrom_s
 {
   FAR struct socket       *ir_sock;      /* The parent socket structure */
   FAR struct devif_callback_s *ir_cb;    /* Reference to callback instance */
@@ -100,19 +82,17 @@ struct inet_recvfrom_s
   ssize_t                  ir_recvlen;   /* The received length */
   int                      ir_result;    /* Success:OK, failure:negated errno */
 };
-#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: inet_update_recvlen
+ * Name: tcp_update_recvlen
  *
  * Description:
  *   Update information about space available for new data and update size
- *   of data in buffer,  This logic accounts for the case where
- *   inet_udp_readahead() sets state.ir_recvlen == -1 .
+ *   of data in buffer.
  *
  * Input Parameters:
  *   pstate   recvfrom state structure
@@ -123,10 +103,8 @@ struct inet_recvfrom_s
  *
  ****************************************************************************/
 
-#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
-
-static inline void inet_update_recvlen(FAR struct inet_recvfrom_s *pstate,
-                                       size_t recvlen)
+static inline void tcp_update_recvlen(FAR struct tcp_recvfrom_s *pstate,
+                                      size_t recvlen)
 {
   if (pstate->ir_recvlen < 0)
     {
@@ -137,10 +115,9 @@ static inline void inet_update_recvlen(FAR struct inet_recvfrom_s *pstate,
   pstate->ir_buffer  += recvlen;
   pstate->ir_buflen  -= recvlen;
 }
-#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_recvfrom_newdata
+ * Name: tcp_recvfrom_newdata
  *
  * Description:
  *   Copy the read data from the packet
@@ -157,9 +134,8 @@ static inline void inet_update_recvlen(FAR struct inet_recvfrom_s *pstate,
  *
  ****************************************************************************/
 
-#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
-static size_t inet_recvfrom_newdata(FAR struct net_driver_s *dev,
-                                    FAR struct inet_recvfrom_s *pstate)
+static size_t tcp_recvfrom_newdata(FAR struct net_driver_s *dev,
+                                   FAR struct tcp_recvfrom_s *pstate)
 {
   size_t recvlen;
 
@@ -181,14 +157,13 @@ static size_t inet_recvfrom_newdata(FAR struct net_driver_s *dev,
 
   /* Update the accumulated size of the data read */
 
-  inet_update_recvlen(pstate, recvlen);
+  tcp_update_recvlen(pstate, recvlen);
 
   return recvlen;
 }
-#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_tcp_newdata
+ * Name: tcp_newdata
  *
  * Description:
  *   Copy the read data from the packet
@@ -205,13 +180,12 @@ static size_t inet_recvfrom_newdata(FAR struct net_driver_s *dev,
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
-static inline void inet_tcp_newdata(FAR struct net_driver_s *dev,
-                                    FAR struct inet_recvfrom_s *pstate)
+static inline void tcp_newdata(FAR struct net_driver_s *dev,
+                               FAR struct tcp_recvfrom_s *pstate)
 {
   /* Take as much data from the packet as we can */
 
-  size_t recvlen = inet_recvfrom_newdata(dev, pstate);
+  size_t recvlen = tcp_recvfrom_newdata(dev, pstate);
 
   /* If there is more data left in the packet that we could not buffer, then
    * add it to the read-ahead buffers.
@@ -253,42 +227,9 @@ static inline void inet_tcp_newdata(FAR struct net_driver_s *dev,
 
   dev->d_len = 0;
 }
-#endif /* NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_udp_newdata
- *
- * Description:
- *   Copy the read data from the packet
- *
- * Input Parameters:
- *   dev      The sructure of the network driver that generated the event
- *   pstate   recvfrom state structure
- *
- * Returned Value:
- *   None.
- *
- * Assumptions:
- *   The network is locked.
- *
- ****************************************************************************/
-
-#ifdef NET_UDP_HAVE_STACK
-static inline void inet_udp_newdata(FAR struct net_driver_s *dev,
-                                    FAR struct inet_recvfrom_s *pstate)
-{
-  /* Take as much data from the packet as we can */
-
-  inet_recvfrom_newdata(dev, pstate);
-
-  /* Indicate no data in the buffer */
-
-  dev->d_len = 0;
-}
-#endif /* NET_UDP_HAVE_STACK */
-
-/****************************************************************************
- * Name: inet_tcp_readahead and inet_udp_readahead
+ * Name: tcp_readahead
  *
  * Description:
  *   Copy the read-ahead data from the packet
@@ -304,8 +245,7 @@ static inline void inet_udp_newdata(FAR struct net_driver_s *dev,
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
-static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate)
+static inline void tcp_readahead(struct tcp_recvfrom_s *pstate)
 {
   FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->ir_sock->s_conn;
   FAR struct iob_s *iob;
@@ -329,7 +269,7 @@ static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate)
 
       /* Update the accumulated size of the data read */
 
-      inet_update_recvlen(pstate, recvlen);
+      tcp_update_recvlen(pstate, recvlen);
 
       /* If we took all of the data from the I/O buffer chain is empty, then
        * release it.  If there is still data available in the I/O buffer
@@ -365,98 +305,9 @@ static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate)
         }
     }
 }
-#endif /* NET_TCP_HAVE_STACK */
-
-#ifdef NET_UDP_HAVE_STACK
-
-static inline void inet_udp_readahead(struct inet_recvfrom_s *pstate)
-{
-  FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
-  FAR struct iob_s *iob;
-  int recvlen;
-
-  /* Check there is any UDP datagram already buffered in a read-ahead
-   * buffer.
-   */
-
-  pstate->ir_recvlen = -1;
-
-  if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
-    {
-      FAR struct iob_s *tmp;
-      uint8_t src_addr_size;
-
-      DEBUGASSERT(iob->io_pktlen > 0);
-
-      /* Transfer that buffered data from the I/O buffer chain into
-       * the user buffer.
-       */
-
-      recvlen = iob_copyout(&src_addr_size, iob, sizeof(uint8_t), 0);
-      if (recvlen != sizeof(uint8_t))
-        {
-          goto out;
-        }
-
-      if (0
-#ifdef CONFIG_NET_IPv6
-          || src_addr_size == sizeof(struct sockaddr_in6)
-#endif
-#ifdef CONFIG_NET_IPv4
-          || src_addr_size == sizeof(struct sockaddr_in)
-#endif
-        )
-        {
-          if (pstate->ir_from)
-            {
-              socklen_t len = *pstate->ir_fromlen;
-              len = (socklen_t)src_addr_size > len ? len : (socklen_t)src_addr_size;
-
-              recvlen = iob_copyout((FAR uint8_t *)pstate->ir_from, iob,
-                                    len, sizeof(uint8_t));
-              if (recvlen != len)
-                {
-                  goto out;
-                }
-            }
-        }
-
-      if (pstate->ir_buflen > 0)
-        {
-          recvlen = iob_copyout(pstate->ir_buffer, iob, pstate->ir_buflen,
-                                src_addr_size + sizeof(uint8_t));
-
-          ninfo("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
-
-          /* Update the accumulated size of the data read */
-
-          pstate->ir_recvlen  = recvlen;
-          pstate->ir_buffer  += recvlen;
-          pstate->ir_buflen  -= recvlen;
-        }
-      else
-        {
-          pstate->ir_recvlen = 0;
-        }
-
-out:
-      /* Remove the I/O buffer chain from the head of the read-ahead
-       * buffer queue.
-       */
-
-      tmp = iob_remove_queue(&conn->readahead);
-      DEBUGASSERT(tmp == iob);
-      UNUSED(tmp);
-
-      /* And free the I/O buffer chain */
-
-      iob_free_chain(iob, IOBUSER_NET_UDP_READAHEAD);
-    }
-}
-#endif
 
 /****************************************************************************
- * Name: inet_tcp_sender
+ * Name: tcp_sender
  *
  * Description:
  *   Getting the sender's address from the UDP packet
@@ -473,9 +324,8 @@ out:
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
-static inline void inet_tcp_sender(FAR struct net_driver_s *dev,
-                                   FAR struct inet_recvfrom_s *pstate)
+static inline void tcp_sender(FAR struct net_driver_s *dev,
+                              FAR struct tcp_recvfrom_s *pstate)
 {
   /* Get the family from the packet type, IP address from the IP header, and
    * the port number from the TCP header.
@@ -524,10 +374,9 @@ static inline void inet_tcp_sender(FAR struct net_driver_s *dev,
     }
 #endif /* CONFIG_NET_IPv4 */
 }
-#endif /* NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_tcp_eventhandler
+ * Name: tcp_eventhandler
  *
  * Description:
  *   This function is called with the network locked to perform the actual
@@ -546,12 +395,11 @@ static inline void inet_tcp_sender(FAR struct net_driver_s *dev,
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
-static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev,
-                                      FAR void *pvconn, FAR void *pvpriv,
-                                      uint16_t flags)
+static uint16_t tcp_eventhandler(FAR struct net_driver_s *dev,
+                                 FAR void *pvconn, FAR void *pvpriv,
+                                 uint16_t flags)
 {
-  FAR struct inet_recvfrom_s *pstate = (struct inet_recvfrom_s *)pvpriv;
+  FAR struct tcp_recvfrom_s *pstate = (struct tcp_recvfrom_s *)pvpriv;
 
 #if 0 /* REVISIT: The assertion fires.  Why? */
   FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
@@ -581,11 +429,11 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev,
            * packet in the read-ahead buffer).
            */
 
-          inet_tcp_newdata(dev, pstate);
+          tcp_newdata(dev, pstate);
 
           /* Save the sender's address in the caller's 'from' location */
 
-          inet_tcp_sender(dev, pstate);
+          tcp_sender(dev, pstate);
 
           /* Indicate that the data has been consumed and that an ACK
            * should be sent.
@@ -672,223 +520,9 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev,
 
   return flags;
 }
-#endif /* NET_TCP_HAVE_STACK */
-
-/****************************************************************************
- * Name: inet_udp_sender
- *
- * Description:
- *   Getting the sender's address from the UDP packet
- *
- * Input Parameters:
- *   dev    - The device driver data structure
- *   pstate - the recvfrom state structure
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   The network is locked.
- *
- ****************************************************************************/
-
-#ifdef NET_UDP_HAVE_STACK
-static inline void inet_udp_sender(FAR struct net_driver_s *dev,
-                                   FAR struct inet_recvfrom_s *pstate)
-{
-  /* Get the family from the packet type, IP address from the IP header, and
-   * the port number from the UDP header.
-   */
-
-#ifdef CONFIG_NET_IPv6
-#ifdef CONFIG_NET_IPv4
-  if (IFF_IS_IPv6(dev->d_flags))
-#endif
-    {
-      FAR struct sockaddr_in6 *infrom =
-        (FAR struct sockaddr_in6 *)pstate->ir_from;
-      FAR socklen_t *fromlen = pstate->ir_fromlen;
-
-      if (infrom)
-        {
-          FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
-          FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
-
-          infrom->sin6_family = AF_INET6;
-          infrom->sin6_port   = udp->srcport;
-          *fromlen = sizeof(struct sockaddr_in6);
-
-          net_ipv6addr_copy(infrom->sin6_addr.s6_addr, ipv6->srcipaddr);
-        }
-    }
-#endif /* CONFIG_NET_IPv6 */
-
-#ifdef CONFIG_NET_IPv4
-#ifdef CONFIG_NET_IPv6
-  else
-#endif
-    {
-      FAR struct sockaddr_in *infrom  =
-        (FAR struct sockaddr_in *)pstate->ir_from;
-
-      if (infrom)
-        {
-#ifdef CONFIG_NET_IPv6
-          FAR struct udp_conn_s *conn =
-            (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
-
-          /* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
-           * class of addresses, the IPv4-mapped IPv6 addresses.
-           */
-
-          if (conn->domain == PF_INET6)
-            {
-              FAR struct sockaddr_in6 *infrom6 = (FAR struct sockaddr_in6 *)infrom;
-              FAR socklen_t *fromlen = pstate->ir_fromlen;
-              FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
-              FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
-              in_addr_t ipv4addr;
-
-              /* Encode the IPv4 address as an IPv4-mapped IPv6 address */
-
-              infrom6->sin6_family = AF_INET6;
-              infrom6->sin6_port = udp->srcport;
-              *fromlen = sizeof(struct sockaddr_in6);
-
-              ipv4addr = net_ip4addr_conv32(ipv6->srcipaddr);
-              ip6_map_ipv4addr(ipv4addr, infrom6->sin6_addr.s6_addr16);
-            }
-          else
-#endif
-            {
-              FAR struct udp_hdr_s *udp   = UDPIPv4BUF;
-              FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
-
-              infrom->sin_family = AF_INET;
-              infrom->sin_port   = udp->srcport;
-
-              net_ipv4addr_copy(infrom->sin_addr.s_addr,
-                                net_ip4addr_conv32(ipv4->srcipaddr));
-            }
-        }
-    }
-#endif /* CONFIG_NET_IPv4 */
-}
-#endif /* NET_UDP_HAVE_STACK */
-
-/****************************************************************************
- * Name: inet_udp_terminate
- *
- * Description:
- *   Terminate the UDP transfer.
- *
- * Input Parameters:
- *   pstate - The recvfrom state structure
- *   result - The result of the operation
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-#ifdef NET_UDP_HAVE_STACK
-static void inet_udp_terminate(FAR struct inet_recvfrom_s *pstate, int result)
-{
-  /* Don't allow any further UDP call backs. */
-
-  pstate->ir_cb->flags   = 0;
-  pstate->ir_cb->priv    = NULL;
-  pstate->ir_cb->event   = NULL;
-
-  /* Save the result of the transfer */
-
-  pstate->ir_result      = result;
-
-  /* Wake up the waiting thread, returning the number of bytes
-   * actually read.
-   */
-
-  nxsem_post(&pstate->ir_sem);
-}
-#endif /* NET_UDP_HAVE_STACK */
-
-/****************************************************************************
- * Name: inet_udp_eventhandler
- *
- * Description:
- *   This function is called with the network locked to perform the actual
- *   UDP receive operation via by the lower, device interfacing layer.
- *
- * Input Parameters:
- *   dev      The structure of the network driver that generated the event.
- *   pvconn   The connection structure associated with the socket
- *   flags    Set of events describing why the callback was invoked
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   The network is locked.
- *
- ****************************************************************************/
-
-#ifdef NET_UDP_HAVE_STACK
-static uint16_t inet_udp_eventhandler(FAR struct net_driver_s *dev,
-                                      FAR void *pvconn, FAR void *pvpriv,
-                                      uint16_t flags)
-{
-  FAR struct inet_recvfrom_s *pstate = (FAR struct inet_recvfrom_s *)pvpriv;
-
-  ninfo("flags: %04x\n", flags);
-
-  /* 'priv' might be null in some race conditions (?) */
-
-  if (pstate)
-    {
-      /* If the network device has gone down, then we will have terminate
-       * the wait now with an error.
-       */
-
-      if ((flags & NETDEV_DOWN) != 0)
-        {
-          /* Terminate the transfer with an error. */
-
-          nerr("ERROR: Network is down\n");
-          inet_udp_terminate(pstate, -ENETUNREACH);
-        }
-
-      /* If new data is available, then complete the read action. */
-
-      else if ((flags & UDP_NEWDATA) != 0)
-        {
-          /* Copy the data from the packet */
-
-          inet_udp_newdata(dev, pstate);
-
-          /* We are finished. */
-
-          ninfo("UDP done\n");
-
-          /* Save the sender's address in the caller's 'from' location */
-
-          inet_udp_sender(dev, pstate);
-
-          /* Don't allow any further UDP call backs. */
-
-          inet_udp_terminate(pstate, OK);
-
-          /* Indicate that the data has been consumed */
-
-          flags &= ~UDP_NEWDATA;
-        }
-    }
-
-  return flags;
-}
-#endif /* NET_UDP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_recvfrom_initialize
+ * Name: tcp_recvfrom_initialize
  *
  * Description:
  *   Initialize the state structure
@@ -906,15 +540,14 @@ static uint16_t inet_udp_eventhandler(FAR struct net_driver_s *dev,
  *
  ****************************************************************************/
 
-#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
-static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
-                                     size_t len, FAR struct sockaddr *infrom,
-                                     FAR socklen_t *fromlen,
-                                     FAR struct inet_recvfrom_s *pstate)
+static void tcp_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
+                                    size_t len, FAR struct sockaddr *infrom,
+                                    FAR socklen_t *fromlen,
+                                    FAR struct tcp_recvfrom_s *pstate)
 {
   /* Initialize the state structure. */
 
-  memset(pstate, 0, sizeof(struct inet_recvfrom_s));
+  memset(pstate, 0, sizeof(struct tcp_recvfrom_s));
 
   /* This semaphore is used for signaling and, hence, should not have
    * priority inheritance enabled.
@@ -937,12 +570,10 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
  * semaphore.
  */
 
-#define inet_recvfrom_uninitialize(s) nxsem_destroy(&(s)->ir_sem)
-
-#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
+#define tcp_recvfrom_uninitialize(s) nxsem_destroy(&(s)->ir_sem)
 
 /****************************************************************************
- * Name: inet_recvfrom_result
+ * Name: tcp_recvfrom_result
  *
  * Description:
  *   Evaluate the result of the recv operations
@@ -958,8 +589,7 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
  *
  ****************************************************************************/
 
-#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
-static ssize_t inet_recvfrom_result(int result, struct inet_recvfrom_s *pstate)
+static ssize_t tcp_recvfrom_result(int result, struct tcp_recvfrom_s *pstate)
 {
   /* Check for a error/timeout detected by the event handler.  Errors are
    * signaled by negative errno values for the rcv length
@@ -985,131 +615,13 @@ static ssize_t inet_recvfrom_result(int result, struct inet_recvfrom_s *pstate)
 
   return pstate->ir_recvlen;
 }
-#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
 
 /****************************************************************************
- * Name: inet_udp_recvfrom
- *
- * Description:
- *   Perform the recvfrom operation for a UDP SOCK_DGRAM
- *
- * Input Parameters:
- *   psock  Pointer to the socket structure for the SOCK_DRAM socket
- *   buf    Buffer to receive data
- *   len    Length of buffer
- *   from   INET address of source (may be NULL)
- *
- * Returned Value:
- *   On success, returns the number of characters received.  On  error,
- *   -errno is returned (see recvfrom for list of errnos).
- *
- * Assumptions:
- *
+ * Public Functions
  ****************************************************************************/
 
-#ifdef NET_UDP_HAVE_STACK
-static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                                 FAR struct sockaddr *from, FAR socklen_t *fromlen)
-{
-  FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)psock->s_conn;
-  FAR struct net_driver_s *dev;
-  struct inet_recvfrom_s state;
-  int ret;
-
-  /* Perform the UDP recvfrom() operation */
-
-  /* Initialize the state structure.  This is done with the network locked
-   * because we don't want anything to happen until we are ready.
-   */
-
-  net_lock();
-  inet_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
-
-  /* Copy the read-ahead data from the packet */
-
-  inet_udp_readahead(&state);
-
-  /* The default return value is the number of bytes that we just copied
-   * into the user buffer.  We will return this if the socket has become
-   * disconnected or if the user request was completely satisfied with
-   * data from the readahead buffers.
-   */
-
-  ret = state.ir_recvlen;
-
-  /* Handle non-blocking UDP sockets */
-
-  if (_SS_ISNONBLOCK(psock->s_flags))
-    {
-      /* Return the number of bytes read from the read-ahead buffer if
-       * something was received (already in 'ret'); EAGAIN if not.
-       */
-
-      if (ret < 0)
-        {
-          /* Nothing was received */
-
-          ret = -EAGAIN;
-        }
-    }
-
-  /* It is okay to block if we need to.  If there is space to receive anything
-   * more, then we will wait to receive the data.  Otherwise return the number
-   * of bytes read from the read-ahead buffer (already in 'ret').
-   *
-   * NOTE: that inet_udp_readahead() may set state.ir_recvlen == -1.
-   */
-
-  else if (state.ir_recvlen <= 0)
-    {
-      /* Get the device that will handle the packet transfers.  This may be
-       * NULL if the UDP socket is bound to INADDR_ANY.  In that case, no
-       * NETDEV_DOWN notifications will be received.
-       */
-
-      dev = udp_find_laddr_device(conn);
-
-      /* Set up the callback in the connection */
-
-      state.ir_cb = udp_callback_alloc(dev, conn);
-      if (state.ir_cb)
-        {
-          /* Set up the callback in the connection */
-
-          state.ir_cb->flags   = (UDP_NEWDATA | NETDEV_DOWN);
-          state.ir_cb->priv    = (FAR void *)&state;
-          state.ir_cb->event   = inet_udp_eventhandler;
-
-          /* Wait for either the receive to complete or for an error/timeout
-           * to occur.  net_timedwait will also terminate if a signal is
-           * received.
-           */
-
-          ret = net_timedwait(&state. ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo));
-          if (ret == -ETIMEDOUT)
-            {
-              ret = -EAGAIN;
-            }
-
-          /* Make sure that no further events are processed */
-
-          udp_callback_free(dev, conn, state.ir_cb);
-          ret = inet_recvfrom_result(ret, &state);
-        }
-      else
-        {
-          ret = -EBUSY;
-        }
-    }
-
-  net_unlock();
-  inet_recvfrom_uninitialize(&state);
-  return ret;
-}
-#endif /* NET_UDP_HAVE_STACK */
-
 /****************************************************************************
- * Name: inet_tcp_recvfrom
+ * Name: psock_tcp_recvfrom
  *
  * Description:
  *   Perform the recvfrom operation for a TCP/IP SOCK_STREAM
@@ -1128,11 +640,11 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t
  *
  ****************************************************************************/
 
-#ifdef NET_TCP_HAVE_STACK
-static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                                 FAR struct sockaddr *from, FAR socklen_t *fromlen)
+ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
+                           size_t len, FAR struct sockaddr *from,
+                           FAR socklen_t *fromlen)
 {
-  struct inet_recvfrom_s state;
+  struct tcp_recvfrom_s state;
   int               ret;
 
   /* Initialize the state structure.  This is done with the network locked
@@ -1140,14 +652,14 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t
    */
 
   net_lock();
-  inet_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
+  tcp_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
 
   /* Handle any any TCP data already buffered in a read-ahead buffer.  NOTE
    * that there may be read-ahead data to be retrieved even after the
    * socket has been disconnected.
    */
 
-  inet_tcp_readahead(&state);
+  tcp_readahead(&state);
 
   /* The default return value is the number of bytes that we just copied
    * into the user buffer.  We will return this if the socket has become
@@ -1232,7 +744,7 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t
         {
           state.ir_cb->flags   = (TCP_NEWDATA | TCP_DISCONN_EVENTS);
           state.ir_cb->priv    = (FAR void *)&state;
-          state.ir_cb->event   = inet_tcp_eventhandler;
+          state.ir_cb->event   = tcp_eventhandler;
 
           /* Wait for either the receive to complete or for an error/timeout
            * to occur.  net_timedwait will also terminate if a signal isi
@@ -1248,7 +760,7 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t
           /* Make sure that no further events are processed */
 
           tcp_callback_free(conn, state.ir_cb);
-          ret = inet_recvfrom_result(ret, &state);
+          ret = tcp_recvfrom_result(ret, &state);
         }
       else
         {
@@ -1257,130 +769,8 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t
     }
 
   net_unlock();
-  inet_recvfrom_uninitialize(&state);
+  tcp_recvfrom_uninitialize(&state);
   return (ssize_t)ret;
 }
-#endif /* NET_TCP_HAVE_STACK */
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: inet_recvfrom
- *
- * Description:
- *   Implements the socket recvfrom interface for the case of the AF_INET
- *   and AF_INET6 address families.  inet_recvfrom() receives messages from
- *   a socket, and may be used to receive data on a socket whether or not it
- *   is connection-oriented.
- *
- *   If 'from' is not NULL, and the underlying protocol provides the source
- *   address, this source address is filled in.  The argument 'fromlen' is
- *   initialized to the size of the buffer associated with from, and
- *   modified on return to indicate the actual size of the address stored
- *   there.
- *
- * Input Parameters:
- *   psock    A pointer to a NuttX-specific, internal socket structure
- *   buf      Buffer to receive data
- *   len      Length of buffer
- *   flags    Receive flags
- *   from     Address of source (may be NULL)
- *   fromlen  The length of the address structure
- *
- * Returned Value:
- *   On success, returns the number of characters received.  If no data is
- *   available to be received and the peer has performed an orderly shutdown,
- *   recv() will return 0.  Otherwise, on errors, a negated errno value is
- *   returned (see recvfrom() for the list of appropriate error values).
- *
- ****************************************************************************/
-
-ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                      int flags, FAR struct sockaddr *from,
-                      FAR socklen_t *fromlen)
-{
-  ssize_t ret;
-
-  /* If a 'from' address has been provided, verify that it is large
-   * enough to hold this address family.
-   */
-
-  if (from)
-    {
-      socklen_t minlen;
-
-      /* Get the minimum socket length */
-
-      switch (psock->s_domain)
-        {
-#ifdef CONFIG_NET_IPv4
-        case PF_INET:
-          {
-            minlen = sizeof(struct sockaddr_in);
-          }
-          break;
-#endif
 
-#ifdef CONFIG_NET_IPv6
-        case PF_INET6:
-          {
-            minlen = sizeof(struct sockaddr_in6);
-          }
-          break;
-#endif
-
-        default:
-          DEBUGPANIC();
-          return -EINVAL;
-        }
-
-      if (*fromlen < minlen)
-        {
-          return -EINVAL;
-        }
-    }
-
-  /* Read from the network interface driver buffer.
-   * Or perform the TCP/IP or UDP recv() operation.
-   */
-
-  switch (psock->s_type)
-    {
-#ifdef CONFIG_NET_TCP
-    case SOCK_STREAM:
-      {
-#ifdef NET_TCP_HAVE_STACK
-        ret = inet_tcp_recvfrom(psock, buf, len, from, fromlen);
-#else
-        ret = -ENOSYS;
-#endif
-      }
-      break;
 #endif /* CONFIG_NET_TCP */
-
-#ifdef CONFIG_NET_UDP
-    case SOCK_DGRAM:
-      {
-#ifdef NET_UDP_HAVE_STACK
-        ret = inet_udp_recvfrom(psock, buf, len, from, fromlen);
-#else
-        ret = -ENOSYS;
-#endif
-      }
-      break;
-#endif /* CONFIG_NET_UDP */
-
-    default:
-      {
-        nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
-        ret = -ENOSYS;
-      }
-      break;
-    }
-
-  return ret;
-}
-
-#endif /* CONFIG_NET */
diff --git a/net/udp/Make.defs b/net/udp/Make.defs
index 1c9487a..39ca293 100644
--- a/net/udp/Make.defs
+++ b/net/udp/Make.defs
@@ -40,6 +40,8 @@ ifneq ($(CONFIG_NET_UDP_NO_STACK),y)
 
 # Socket layer
 
+SOCK_CSRCS += udp_recvfrom.c
+
 ifeq ($(CONFIG_NET_UDPPROTO_OPTIONS),y)
 SOCK_CSRCS += udp_setsockopt.c
 endif
diff --git a/net/udp/udp.h b/net/udp/udp.h
index 40d3a97..454b29f 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -638,6 +638,30 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
                       FAR struct udp_conn_s *conn, uint16_t flags);
 
 /****************************************************************************
+ * Name: psock_udp_recvfrom
+ *
+ * Description:
+ *   Perform the recvfrom operation for a UDP SOCK_DGRAM
+ *
+ * Input Parameters:
+ *   psock  Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf    Buffer to receive data
+ *   len    Length of buffer
+ *   from   INET address of source (may be NULL)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  On  error,
+ *   -errno is returned (see recvfrom for list of errnos).
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
+                           size_t len, FAR struct sockaddr *from,
+                           FAR socklen_t *fromlen);
+
+/****************************************************************************
  * Name: psock_udp_sendto
  *
  * Description:
diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c
new file mode 100644
index 0000000..3060162
--- /dev/null
+++ b/net/udp/udp_recvfrom.c
@@ -0,0 +1,707 @@
+/****************************************************************************
+ * net/udp/udp_recvfrom.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 <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <nuttx/net/net.h>
+#include <nuttx/mm/iob.h>
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/ip.h>
+#include <nuttx/net/udp.h>
+
+#include "netdev/netdev.h"
+#include "devif/devif.h"
+#include "udp/udp.h"
+#include "socket/socket.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define IPv4BUF    ((struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#define IPv6BUF    ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+
+#define UDPIPv4BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN])
+#define UDPIPv6BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct udp_recvfrom_s
+{
+  FAR struct socket       *ir_sock;      /* The parent socket structure */
+  FAR struct devif_callback_s *ir_cb;    /* Reference to callback instance */
+  sem_t                    ir_sem;       /* Semaphore signals recv completion */
+  size_t                   ir_buflen;    /* Length of receive buffer */
+  uint8_t                 *ir_buffer;    /* Pointer to receive buffer */
+  FAR struct sockaddr     *ir_from;      /* Address of sender */
+  FAR socklen_t           *ir_fromlen;   /* Number of bytes allocated for address of sender */
+  ssize_t                  ir_recvlen;   /* The received length */
+  int                      ir_result;    /* Success:OK, failure:negated errno */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: udp_update_recvlen
+ *
+ * Description:
+ *   Update information about space available for new data and update size
+ *   of data in buffer,  This logic accounts for the case where
+ *   udp_readahead() sets state.ir_recvlen == -1 .
+ *
+ * Input Parameters:
+ *   pstate   recvfrom state structure
+ *   recvlen  size of new data appended to buffer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void udp_update_recvlen(FAR struct udp_recvfrom_s *pstate,
+                                      size_t recvlen)
+{
+  if (pstate->ir_recvlen < 0)
+    {
+      pstate->ir_recvlen = 0;
+    }
+
+  pstate->ir_recvlen += recvlen;
+  pstate->ir_buffer  += recvlen;
+  pstate->ir_buflen  -= recvlen;
+}
+
+/****************************************************************************
+ * Name: udp_recvfrom_newdata
+ *
+ * Description:
+ *   Copy the read data from the packet
+ *
+ * Input Parameters:
+ *   dev      The structure of the network driver that generated the event.
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   The number of bytes taken from the packet.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static size_t udp_recvfrom_newdata(FAR struct net_driver_s *dev,
+                                   FAR struct udp_recvfrom_s *pstate)
+{
+  size_t recvlen;
+
+  /* Get the length of the data to return */
+
+  if (dev->d_len > pstate->ir_buflen)
+    {
+      recvlen = pstate->ir_buflen;
+    }
+  else
+    {
+      recvlen = dev->d_len;
+    }
+
+  /* Copy the new appdata into the user buffer */
+
+  memcpy(pstate->ir_buffer, dev->d_appdata, recvlen);
+  ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len);
+
+  /* Update the accumulated size of the data read */
+
+  udp_update_recvlen(pstate, recvlen);
+
+  return recvlen;
+}
+
+/****************************************************************************
+ * Name: udp_newdata
+ *
+ * Description:
+ *   Copy the read data from the packet
+ *
+ * Input Parameters:
+ *   dev      The sructure of the network driver that generated the event
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   None.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static inline void udp_newdata(FAR struct net_driver_s *dev,
+                               FAR struct udp_recvfrom_s *pstate)
+{
+  /* Take as much data from the packet as we can */
+
+  udp_recvfrom_newdata(dev, pstate);
+
+  /* Indicate no data in the buffer */
+
+  dev->d_len = 0;
+}
+
+static inline void udp_readahead(struct udp_recvfrom_s *pstate)
+{
+  FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
+  FAR struct iob_s *iob;
+  int recvlen;
+
+  /* Check there is any UDP datagram already buffered in a read-ahead
+   * buffer.
+   */
+
+  pstate->ir_recvlen = -1;
+
+  if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
+    {
+      FAR struct iob_s *tmp;
+      uint8_t src_addr_size;
+
+      DEBUGASSERT(iob->io_pktlen > 0);
+
+      /* Transfer that buffered data from the I/O buffer chain into
+       * the user buffer.
+       */
+
+      recvlen = iob_copyout(&src_addr_size, iob, sizeof(uint8_t), 0);
+      if (recvlen != sizeof(uint8_t))
+        {
+          goto out;
+        }
+
+      if (0
+#ifdef CONFIG_NET_IPv6
+          || src_addr_size == sizeof(struct sockaddr_in6)
+#endif
+#ifdef CONFIG_NET_IPv4
+          || src_addr_size == sizeof(struct sockaddr_in)
+#endif
+        )
+        {
+          if (pstate->ir_from)
+            {
+              socklen_t len = *pstate->ir_fromlen;
+              len = (socklen_t)src_addr_size > len ? len : (socklen_t)src_addr_size;
+
+              recvlen = iob_copyout((FAR uint8_t *)pstate->ir_from, iob,
+                                    len, sizeof(uint8_t));
+              if (recvlen != len)
+                {
+                  goto out;
+                }
+            }
+        }
+
+      if (pstate->ir_buflen > 0)
+        {
+          recvlen = iob_copyout(pstate->ir_buffer, iob, pstate->ir_buflen,
+                                src_addr_size + sizeof(uint8_t));
+
+          ninfo("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
+
+          /* Update the accumulated size of the data read */
+
+          pstate->ir_recvlen  = recvlen;
+          pstate->ir_buffer  += recvlen;
+          pstate->ir_buflen  -= recvlen;
+        }
+      else
+        {
+          pstate->ir_recvlen = 0;
+        }
+
+out:
+      /* Remove the I/O buffer chain from the head of the read-ahead
+       * buffer queue.
+       */
+
+      tmp = iob_remove_queue(&conn->readahead);
+      DEBUGASSERT(tmp == iob);
+      UNUSED(tmp);
+
+      /* And free the I/O buffer chain */
+
+      iob_free_chain(iob, IOBUSER_NET_UDP_READAHEAD);
+    }
+}
+
+/****************************************************************************
+ * Name: udp_sender
+ *
+ * Description:
+ *   Getting the sender's address from the UDP packet
+ *
+ * Input Parameters:
+ *   dev    - The device driver data structure
+ *   pstate - the recvfrom state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static inline void udp_sender(FAR struct net_driver_s *dev,
+                              FAR struct udp_recvfrom_s *pstate)
+{
+  /* Get the family from the packet type, IP address from the IP header, and
+   * the port number from the UDP header.
+   */
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+  if (IFF_IS_IPv6(dev->d_flags))
+#endif
+    {
+      FAR struct sockaddr_in6 *infrom =
+        (FAR struct sockaddr_in6 *)pstate->ir_from;
+      FAR socklen_t *fromlen = pstate->ir_fromlen;
+
+      if (infrom)
+        {
+          FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
+          FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
+
+          infrom->sin6_family = AF_INET6;
+          infrom->sin6_port   = udp->srcport;
+          *fromlen = sizeof(struct sockaddr_in6);
+
+          net_ipv6addr_copy(infrom->sin6_addr.s6_addr, ipv6->srcipaddr);
+        }
+    }
+#endif /* CONFIG_NET_IPv6 */
+
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+  else
+#endif
+    {
+      FAR struct sockaddr_in *infrom  =
+        (FAR struct sockaddr_in *)pstate->ir_from;
+
+      if (infrom)
+        {
+#ifdef CONFIG_NET_IPv6
+          FAR struct udp_conn_s *conn =
+            (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
+
+          /* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
+           * class of addresses, the IPv4-mapped IPv6 addresses.
+           */
+
+          if (conn->domain == PF_INET6)
+            {
+              FAR struct sockaddr_in6 *infrom6 = (FAR struct sockaddr_in6 *)infrom;
+              FAR socklen_t *fromlen = pstate->ir_fromlen;
+              FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
+              FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
+              in_addr_t ipv4addr;
+
+              /* Encode the IPv4 address as an IPv4-mapped IPv6 address */
+
+              infrom6->sin6_family = AF_INET6;
+              infrom6->sin6_port = udp->srcport;
+              *fromlen = sizeof(struct sockaddr_in6);
+
+              ipv4addr = net_ip4addr_conv32(ipv6->srcipaddr);
+              ip6_map_ipv4addr(ipv4addr, infrom6->sin6_addr.s6_addr16);
+            }
+          else
+#endif
+            {
+              FAR struct udp_hdr_s *udp   = UDPIPv4BUF;
+              FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
+
+              infrom->sin_family = AF_INET;
+              infrom->sin_port   = udp->srcport;
+
+              net_ipv4addr_copy(infrom->sin_addr.s_addr,
+                                net_ip4addr_conv32(ipv4->srcipaddr));
+            }
+        }
+    }
+#endif /* CONFIG_NET_IPv4 */
+}
+
+/****************************************************************************
+ * Name: udp_terminate
+ *
+ * Description:
+ *   Terminate the UDP transfer.
+ *
+ * Input Parameters:
+ *   pstate - The recvfrom state structure
+ *   result - The result of the operation
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void udp_terminate(FAR struct udp_recvfrom_s *pstate, int result)
+{
+  /* Don't allow any further UDP call backs. */
+
+  pstate->ir_cb->flags   = 0;
+  pstate->ir_cb->priv    = NULL;
+  pstate->ir_cb->event   = NULL;
+
+  /* Save the result of the transfer */
+
+  pstate->ir_result      = result;
+
+  /* Wake up the waiting thread, returning the number of bytes
+   * actually read.
+   */
+
+  nxsem_post(&pstate->ir_sem);
+}
+
+/****************************************************************************
+ * Name: udp_eventhandler
+ *
+ * Description:
+ *   This function is called with the network locked to perform the actual
+ *   UDP receive operation via by the lower, device interfacing layer.
+ *
+ * Input Parameters:
+ *   dev      The structure of the network driver that generated the event.
+ *   pvconn   The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static uint16_t udp_eventhandler(FAR struct net_driver_s *dev,
+                                 FAR void *pvconn, FAR void *pvpriv,
+                                 uint16_t flags)
+{
+  FAR struct udp_recvfrom_s *pstate = (FAR struct udp_recvfrom_s *)pvpriv;
+
+  ninfo("flags: %04x\n", flags);
+
+  /* 'priv' might be null in some race conditions (?) */
+
+  if (pstate)
+    {
+      /* If the network device has gone down, then we will have terminate
+       * the wait now with an error.
+       */
+
+      if ((flags & NETDEV_DOWN) != 0)
+        {
+          /* Terminate the transfer with an error. */
+
+          nerr("ERROR: Network is down\n");
+          udp_terminate(pstate, -ENETUNREACH);
+        }
+
+      /* If new data is available, then complete the read action. */
+
+      else if ((flags & UDP_NEWDATA) != 0)
+        {
+          /* Copy the data from the packet */
+
+          udp_newdata(dev, pstate);
+
+          /* We are finished. */
+
+          ninfo("UDP done\n");
+
+          /* Save the sender's address in the caller's 'from' location */
+
+          udp_sender(dev, pstate);
+
+          /* Don't allow any further UDP call backs. */
+
+          udp_terminate(pstate, OK);
+
+          /* Indicate that the data has been consumed */
+
+          flags &= ~UDP_NEWDATA;
+        }
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: udp_recvfrom_initialize
+ *
+ * Description:
+ *   Initialize the state structure
+ *
+ * Input Parameters:
+ *   psock    Pointer to the socket structure for the socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   pstate   A pointer to the state structure to be initialized
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void udp_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
+                                    size_t len, FAR struct sockaddr *infrom,
+                                    FAR socklen_t *fromlen,
+                                    FAR struct udp_recvfrom_s *pstate)
+{
+  /* Initialize the state structure. */
+
+  memset(pstate, 0, sizeof(struct udp_recvfrom_s));
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  nxsem_init(&pstate->ir_sem, 0, 0); /* Doesn't really fail */
+  nxsem_setprotocol(&pstate->ir_sem, SEM_PRIO_NONE);
+
+  pstate->ir_buflen    = len;
+  pstate->ir_buffer    = buf;
+  pstate->ir_from      = infrom;
+  pstate->ir_fromlen   = fromlen;
+
+  /* Set up the start time for the timeout */
+
+  pstate->ir_sock      = psock;
+}
+
+/* The only un-initialization that has to be performed is destroying the
+ * semaphore.
+ */
+
+#define udp_recvfrom_uninitialize(s) nxsem_destroy(&(s)->ir_sem)
+
+/****************************************************************************
+ * Name: udp_recvfrom_result
+ *
+ * Description:
+ *   Evaluate the result of the recv operations
+ *
+ * Input Parameters:
+ *   result   The result of the net_timedwait operation (may indicate EINTR)
+ *   pstate   A pointer to the state structure to be initialized
+ *
+ * Returned Value:
+ *   The result of the recv operation with errno set appropriately
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static ssize_t udp_recvfrom_result(int result, struct udp_recvfrom_s *pstate)
+{
+  /* Check for a error/timeout detected by the event handler.  Errors are
+   * signaled by negative errno values for the rcv length
+   */
+
+  if (pstate->ir_result < 0)
+    {
+      /* This might return EAGAIN on a timeout or ENOTCONN on loss of
+       * connection (TCP only)
+       */
+
+      return pstate->ir_result;
+    }
+
+  /* If net_timedwait failed, then we were probably reawakened by a signal. In
+   * this case, net_timedwait will have returned negated errno appropriately.
+   */
+
+  if (result < 0)
+    {
+      return result;
+    }
+
+  return pstate->ir_recvlen;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: psock_udp_recvfrom
+ *
+ * Description:
+ *   Perform the recvfrom operation for a UDP SOCK_DGRAM
+ *
+ * Input Parameters:
+ *   psock  Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf    Buffer to receive data
+ *   len    Length of buffer
+ *   from   INET address of source (may be NULL)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  On  error,
+ *   -errno is returned (see recvfrom for list of errnos).
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
+                           size_t len, FAR struct sockaddr *from,
+                           FAR socklen_t *fromlen)
+{
+  FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)psock->s_conn;
+  FAR struct net_driver_s *dev;
+  struct udp_recvfrom_s state;
+  int ret;
+
+  /* Perform the UDP recvfrom() operation */
+
+  /* Initialize the state structure.  This is done with the network locked
+   * because we don't want anything to happen until we are ready.
+   */
+
+  net_lock();
+  udp_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
+
+  /* Copy the read-ahead data from the packet */
+
+  udp_readahead(&state);
+
+  /* The default return value is the number of bytes that we just copied
+   * into the user buffer.  We will return this if the socket has become
+   * disconnected or if the user request was completely satisfied with
+   * data from the readahead buffers.
+   */
+
+  ret = state.ir_recvlen;
+
+  /* Handle non-blocking UDP sockets */
+
+  if (_SS_ISNONBLOCK(psock->s_flags))
+    {
+      /* Return the number of bytes read from the read-ahead buffer if
+       * something was received (already in 'ret'); EAGAIN if not.
+       */
+
+      if (ret < 0)
+        {
+          /* Nothing was received */
+
+          ret = -EAGAIN;
+        }
+    }
+
+  /* It is okay to block if we need to.  If there is space to receive anything
+   * more, then we will wait to receive the data.  Otherwise return the number
+   * of bytes read from the read-ahead buffer (already in 'ret').
+   *
+   * NOTE: that udp_readahead() may set state.ir_recvlen == -1.
+   */
+
+  else if (state.ir_recvlen <= 0)
+    {
+      /* Get the device that will handle the packet transfers.  This may be
+       * NULL if the UDP socket is bound to INADDR_ANY.  In that case, no
+       * NETDEV_DOWN notifications will be received.
+       */
+
+      dev = udp_find_laddr_device(conn);
+
+      /* Set up the callback in the connection */
+
+      state.ir_cb = udp_callback_alloc(dev, conn);
+      if (state.ir_cb)
+        {
+          /* Set up the callback in the connection */
+
+          state.ir_cb->flags   = (UDP_NEWDATA | NETDEV_DOWN);
+          state.ir_cb->priv    = (FAR void *)&state;
+          state.ir_cb->event   = udp_eventhandler;
+
+          /* Wait for either the receive to complete or for an error/timeout
+           * to occur.  net_timedwait will also terminate if a signal is
+           * received.
+           */
+
+          ret = net_timedwait(&state. ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo));
+          if (ret == -ETIMEDOUT)
+            {
+              ret = -EAGAIN;
+            }
+
+          /* Make sure that no further events are processed */
+
+          udp_callback_free(dev, conn, state.ir_cb);
+          ret = udp_recvfrom_result(ret, &state);
+        }
+      else
+        {
+          ret = -EBUSY;
+        }
+    }
+
+  net_unlock();
+  udp_recvfrom_uninitialize(&state);
+  return ret;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */


[incubator-nuttx] 01/04: net/udp: Rename udp_psock_sendto_xxx.c to udp_sendto_xxx.c like TCP

Posted by gn...@apache.org.
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 677536ccf5688ca750b4c8eb689683d7acc525e4
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Jan 21 16:43:14 2020 +0800

    net/udp:  Rename udp_psock_sendto_xxx.c to udp_sendto_xxx.c like TCP
    
     Rename udp_psock_sendto_xxx.c to udp_sendto_xxx.c like TCP and remove udp_psock_send.c
---
 net/inet/inet_sockif.c                             |  6 +-
 net/udp/Make.defs                                  |  6 +-
 net/udp/udp.h                                      | 11 ---
 net/udp/udp_psock_send.c                           | 88 ----------------------
 ...ock_sendto_buffered.c => udp_sendto_buffered.c} |  2 +-
 ...sendto_unbuffered.c => udp_sendto_unbuffered.c} |  2 +-
 6 files changed, 8 insertions(+), 107 deletions(-)

diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index ff856ee..5a05fda 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -1113,13 +1113,15 @@ static ssize_t inet_send(FAR struct socket *psock, FAR const void *buf,
             {
               /* UDP/IP packet send */
 
-              ret = psock_udp_send(psock, buf, len);
+              ret = _SS_ISCONNECTED(psock->s_flags) ?
+                psock_udp_sendto(psock, buf, len, 0, NULL, 0) : -ENOTCONN;
             }
 #endif /* NET_UDP_HAVE_STACK */
 #elif defined(NET_UDP_HAVE_STACK)
           /* Only UDP/IP packet send */
 
-          ret = psock_udp_send(psock, buf, len);
+          ret = _SS_ISCONNECTED(psock->s_flags) ?
+            psock_udp_sendto(psock, buf, len, 0, NULL, 0) : -ENOTCONN;
 #else
           ret = -ENOSYS;
 #endif /* CONFIG_NET_6LOWPAN */
diff --git a/net/udp/Make.defs b/net/udp/Make.defs
index edb0e31..0501ae4 100644
--- a/net/udp/Make.defs
+++ b/net/udp/Make.defs
@@ -40,16 +40,14 @@ ifneq ($(CONFIG_NET_UDP_NO_STACK),y)
 
 # Socket layer
 
-SOCK_CSRCS += udp_psock_send.c
-
 ifeq ($(CONFIG_NET_UDPPROTO_OPTIONS),y)
 SOCK_CSRCS += udp_setsockopt.c
 endif
 
 ifeq ($(CONFIG_NET_UDP_WRITE_BUFFERS),y)
-SOCK_CSRCS += udp_psock_sendto_buffered.c
+SOCK_CSRCS += udp_sendto_buffered.c
 else
-SOCK_CSRCS += udp_psock_sendto_unbuffered.c
+SOCK_CSRCS += udp_sendto_unbuffered.c
 endif
 
 ifeq ($(CONFIG_NET_UDP_NOTIFIER),y)
diff --git a/net/udp/udp.h b/net/udp/udp.h
index 76033fd..aa1caef 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -622,17 +622,6 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
                       FAR struct udp_conn_s *conn, uint16_t flags);
 
 /****************************************************************************
- * Name: psock_udp_send
- *
- * Description:
- *   Implements send() for connected UDP sockets
- *
- ****************************************************************************/
-
-ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf,
-                       size_t len);
-
-/****************************************************************************
  * Name: psock_udp_sendto
  *
  * Description:
diff --git a/net/udp/udp_psock_send.c b/net/udp/udp_psock_send.c
deleted file mode 100644
index 2bbfaff..0000000
--- a/net/udp/udp_psock_send.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
- * net/udp/udp_psock_send.c
- *
- *   Copyright (C) 2015, 2018 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>
-
-#include <sys/types.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <nuttx/net/net.h>
-
-#include "socket/socket.h"
-#include "udp/udp.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: psock_udp_send
- *
- * Description:
- *   Implements send() for connected UDP sockets
- *
- ****************************************************************************/
-
-ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf,
-                       size_t len)
-{
-  DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && psock->s_conn != NULL);
-  DEBUGASSERT(psock->s_type == SOCK_DGRAM);
-
-  /* Was the UDP socket connected via connect()?
-   * REVISIT:  This same test is performed in psock_udp_sendto() where
-   * -EDESTADDRREQ is returned.  There is a fine distinction in the
-   * meaning of the reported errors that I am not sure I have correct.
-   */
-
-  if (!_SS_ISCONNECTED(psock->s_flags))
-    {
-      /* No, then it is not legal to call send() with this socket.
-       * ENOTCONN - The socket is not connected or otherwise has not had
-       * the peer pre-specified.
-       */
-
-      return -ENOTCONN;
-    }
-
-  /* Let psock_sendto() do all of the work work */
-
-  return psock_udp_sendto(psock, buf, len, 0, NULL, 0);
-}
diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_sendto_buffered.c
similarity index 99%
rename from net/udp/udp_psock_sendto_buffered.c
rename to net/udp/udp_sendto_buffered.c
index fbc44de..8428482 100644
--- a/net/udp/udp_psock_sendto_buffered.c
+++ b/net/udp/udp_sendto_buffered.c
@@ -630,7 +630,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
 
   /* Dump the incoming buffer */
 
-  BUF_DUMP("psock_udp_send", buf, len);
+  BUF_DUMP("psock_udp_sendto", buf, len);
 
   if (len > 0)
     {
diff --git a/net/udp/udp_psock_sendto_unbuffered.c b/net/udp/udp_sendto_unbuffered.c
similarity index 99%
rename from net/udp/udp_psock_sendto_unbuffered.c
rename to net/udp/udp_sendto_unbuffered.c
index 3ced869..a714155 100644
--- a/net/udp/udp_psock_sendto_unbuffered.c
+++ b/net/udp/udp_sendto_unbuffered.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * net/udp/udp_psock_sendto_unbuffered.c
+ * net/udp/udp_sendto_unbuffered.c
  *
  *   Copyright (C) 2007-2009, 2011-2016, 2018-2019 Gregory Nutt. All rights
  *     reserved.