You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/01/18 02:44:27 UTC

[incubator-nuttx-apps] 01/02: webclient: Implement AF_LOCAL

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

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

commit 1131cbe14d8fc32f300ed34310d0a171e3aa899f
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Thu Jan 14 12:22:47 2021 +0900

    webclient: Implement AF_LOCAL
---
 include/netutils/webclient.h   | 20 ++++++-----
 netutils/webclient/webclient.c | 78 ++++++++++++++++++++++++++++++++----------
 2 files changed, 72 insertions(+), 26 deletions(-)

diff --git a/include/netutils/webclient.h b/include/netutils/webclient.h
index 7aaa5d7..8725d2f 100644
--- a/include/netutils/webclient.h
+++ b/include/netutils/webclient.h
@@ -186,18 +186,22 @@ struct webclient_context
 {
   /* request parameters
    *
-   *   method       - HTTP method like "GET", "POST".
-   *                  The default value is "GET".
-   *   url          - A pointer to a string containing the full URL.
-   *                  (e.g., http://www.nutt.org/index.html, or
-   *                   http://192.168.23.1:80/index.html)
-   *   headers      - An array of pointers to the extra headers.
-   *   nheaders     - The number of elements in the "headers" array.
-   *   bodylen      - The size of the request body.
+   *   method           - HTTP method like "GET", "POST".
+   *                      The default value is "GET".
+   *   url              - A pointer to a string containing the full URL.
+   *                      (e.g., http://www.nutt.org/index.html, or
+   *                       http://192.168.23.1:80/index.html)
+   *   unix_socket_path - If not NULL, the path to an AF_LOCAL socket.
+   *   headers          - An array of pointers to the extra headers.
+   *   nheaders         - The number of elements in the "headers" array.
+   *   bodylen          - The size of the request body.
    */
 
   FAR const char *method;
   FAR const char *url;
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+  FAR const char *unix_socket_path;
+#endif
   FAR const char * FAR const *headers;
   unsigned int nheaders;
   size_t bodylen;
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index 26b4d1b..73c18dc 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -67,6 +67,9 @@
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+#include <sys/un.h>
+#endif
 
 #include <nuttx/version.h>
 
@@ -649,7 +652,6 @@ static int wget_gethostip(FAR char *hostname, FAR struct in_addr *dest)
 
 int webclient_perform(FAR struct webclient_context *ctx)
 {
-  struct sockaddr_in server;
   struct wget_s *ws;
   struct timeval tv;
   bool redirected;
@@ -722,15 +724,70 @@ int webclient_perform(FAR struct webclient_context *ctx)
         {
           char port_str[sizeof("65535")];
 
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+          if (ctx->unix_socket_path != NULL)
+            {
+              nerr("ERROR: TLS on AF_LOCAL socket is not implemented\n");
+              free(ws);
+              return -ENOTSUP;
+            }
+#endif
+
           snprintf(port_str, sizeof(port_str), "%u", ws->port);
           ret = tls_ops->connect(tls_ctx, ws->hostname, port_str,
                                  CONFIG_WEBCLIENT_TIMEOUT, &conn.tls_conn);
         }
       else
         {
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+          struct sockaddr_un server_un;
+#endif
+          struct sockaddr_in server_in;
+          int domain;
+          const struct sockaddr *server_address;
+          socklen_t server_address_len;
+
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+          if (ctx->unix_socket_path != NULL)
+            {
+              domain = PF_LOCAL;
+
+              memset(&server_un, 0, sizeof(server_un));
+              server_un.sun_family = AF_LOCAL;
+              strncpy(server_un.sun_path, ctx->unix_socket_path,
+                      sizeof(server_un.sun_path));
+#if !defined(__NuttX__) && !defined(__linux__)
+              server_un.sun_len = SUN_LEN(&server_un);
+#endif
+              server_address = (const struct sockaddr *)&server_un;
+              server_address_len = sizeof(server_un);
+            }
+          else
+#endif
+            {
+              domain = PF_INET;
+
+              /* Get the server address from the host name */
+
+              server_in.sin_family = AF_INET;
+              server_in.sin_port   = htons(ws->port);
+              ret = wget_gethostip(ws->hostname, &server_in.sin_addr);
+              if (ret < 0)
+                {
+                  /* Could not resolve host (or malformed IP address) */
+
+                  nwarn("WARNING: Failed to resolve hostname\n");
+                  ret = -EHOSTUNREACH;
+                  goto errout_with_errno;
+                }
+
+              server_address = (const struct sockaddr *)&server_in;
+              server_address_len = sizeof(struct sockaddr_in);
+            }
+
           /* Create a socket */
 
-          conn.sockfd = socket(AF_INET, SOCK_STREAM, 0);
+          conn.sockfd = socket(domain, SOCK_STREAM, 0);
           if (conn.sockfd < 0)
             {
               /* socket failed.  It will set the errno appropriately */
@@ -750,27 +807,12 @@ int webclient_perform(FAR struct webclient_context *ctx)
           setsockopt(conn.sockfd, SOL_SOCKET, SO_SNDTIMEO,
                      (FAR const void *)&tv, sizeof(struct timeval));
 
-          /* Get the server address from the host name */
-
-          server.sin_family = AF_INET;
-          server.sin_port   = htons(ws->port);
-          ret = wget_gethostip(ws->hostname, &server.sin_addr);
-          if (ret < 0)
-            {
-              /* Could not resolve host (or malformed IP address) */
-
-              nwarn("WARNING: Failed to resolve hostname\n");
-              ret = -EHOSTUNREACH;
-              goto errout_with_errno;
-            }
-
           /* Connect to server.  First we have to set some fields in the
            * 'server' address structure.  The system will assign me an
            * arbitrary local port that is not in use.
            */
 
-          ret = connect(conn.sockfd, (struct sockaddr *)&server,
-                        sizeof(struct sockaddr_in));
+          ret = connect(conn.sockfd, server_address, server_address_len);
           if (ret == -1)
             {
               ret = -errno;