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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 9dc5a59d50 libc/netdb: Move dns query info and buffer out of the stack
9dc5a59d50 is described below

commit 9dc5a59d5067fc14b92598fb7460fd366e74e2c7
Author: Zhe Weng <[email protected]>
AuthorDate: Tue Jul 25 12:48:56 2023 +0800

    libc/netdb: Move dns query info and buffer out of the stack
    
    The length of these buffers come from Kconfig, it isn't safe to allocate
    them on the stack.
    
    Signed-off-by: Zhe Weng <[email protected]>
---
 libs/libc/netdb/lib_dnsquery.c | 61 +++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/libs/libc/netdb/lib_dnsquery.c b/libs/libc/netdb/lib_dnsquery.c
index 37074dd3ee..ba7789d9a7 100644
--- a/libs/libc/netdb/lib_dnsquery.c
+++ b/libs/libc/netdb/lib_dnsquery.c
@@ -57,6 +57,7 @@
 
 #include <arpa/inet.h>
 
+#include <nuttx/lib/lib.h>
 #include <nuttx/net/net.h>
 #include <nuttx/net/dns.h>
 
@@ -77,8 +78,9 @@
  *                    NUL-terminator (1 byte)
  */
 
-#define SEND_BUFFER_SIZE (16 + CONFIG_NETDB_DNSCLIENT_NAMESIZE + 2)
-#define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
+#define SEND_BUFFER_SIZE  (16 + CONFIG_NETDB_DNSCLIENT_NAMESIZE + 2)
+#define RECV_BUFFER_SIZE  CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
+#define QUERY_BUFFER_SIZE MAX(SEND_BUFFER_SIZE, RECV_BUFFER_SIZE)
 
 /****************************************************************************
  * Private Types
@@ -104,6 +106,13 @@ struct dns_query_info_s
                                                     * encoded format + NUL */
 };
 
+struct dns_query_data_s
+{
+  struct dns_query_s query;
+  struct dns_query_info_s qinfo;
+  uint8_t buffer[QUERY_BUFFER_SIZE]; /* Buffer to hold request & response */
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -197,7 +206,8 @@ static inline uint16_t dns_alloc_id(void)
 
 static int dns_send_query(int sd, FAR const char *name,
                           FAR union dns_addr_u *uaddr, uint16_t rectype,
-                          FAR struct dns_query_info_s *qinfo)
+                          FAR struct dns_query_info_s *qinfo,
+                          FAR uint8_t *buffer)
 {
   FAR struct dns_header_s *hdr;
   FAR uint8_t *dest;
@@ -205,7 +215,6 @@ static int dns_send_query(int sd, FAR const char *name,
   FAR char *qname;
   FAR char *qptr;
   FAR const char *src;
-  uint8_t buffer[SEND_BUFFER_SIZE];
   uint16_t id;
   socklen_t addrlen;
   int ret;
@@ -327,12 +336,11 @@ static int dns_send_query(int sd, FAR const char *name,
 
 static int dns_recv_response(int sd, FAR union dns_addr_u *addr, int naddr,
                              FAR struct dns_query_info_s *qinfo,
-                             uint32_t *ttl)
+                             FAR uint32_t *ttl, FAR uint8_t *buffer)
 {
   FAR uint8_t *nameptr;
   FAR uint8_t *namestart;
   FAR uint8_t *endofbuffer;
-  char buffer[RECV_BUFFER_SIZE];
   FAR struct dns_answer_s *ans;
   FAR struct dns_header_s *hdr;
   FAR struct dns_question_s *que;
@@ -366,7 +374,7 @@ static int dns_recv_response(int sd, FAR union dns_addr_u 
*addr, int naddr,
     }
 
   hdr         = (FAR struct dns_header_s *)buffer;
-  endofbuffer = (FAR uint8_t *)buffer + ret;
+  endofbuffer = buffer + ret;
 
   ninfo("ID %d\n", NTOHS(hdr->id));
   ninfo("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
@@ -411,7 +419,7 @@ static int dns_recv_response(int sd, FAR union dns_addr_u 
*addr, int naddr,
    * matches against the name in the question.
    */
 
-  namestart = (uint8_t *)buffer + sizeof(*hdr);
+  namestart = buffer + sizeof(*hdr);
   nameptr   = dns_parse_name(namestart, endofbuffer);
   if (nameptr == endofbuffer)
     {
@@ -620,8 +628,8 @@ static void dns_query_error(FAR const char *prompt, int ret,
 static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
                               FAR socklen_t addrlen)
 {
-  FAR struct dns_query_s *query = (FAR struct dns_query_s *)arg;
-  FAR struct dns_query_info_s qinfo;
+  FAR struct dns_query_data_s *qdata = arg;
+  FAR struct dns_query_s      *query = &qdata->query;
   int next = 0;
   int retries;
   int ret;
@@ -645,7 +653,7 @@ static int dns_query_callback(FAR void *arg, FAR struct 
sockaddr *addr,
 
       ret = dns_send_query(sd, query->hostname,
                           (FAR union dns_addr_u *)addr,
-                           DNS_RECTYPE_AAAA, &qinfo);
+                           DNS_RECTYPE_AAAA, &qdata->qinfo, qdata->buffer);
       if (ret < 0)
         {
           dns_query_error("ERROR: IPv6 dns_send_query failed",
@@ -657,7 +665,8 @@ static int dns_query_callback(FAR void *arg, FAR struct 
sockaddr *addr,
           /* Obtain the IPv6 response */
 
           ret = dns_recv_response(sd, &query->addr[next],
-                                  *query->naddr - next, &qinfo, &query->ttl);
+                                  *query->naddr - next, &qdata->qinfo,
+                                  &query->ttl, qdata->buffer);
           if (ret >= 0)
             {
               next += ret;
@@ -685,7 +694,7 @@ static int dns_query_callback(FAR void *arg, FAR struct 
sockaddr *addr,
 
       ret = dns_send_query(sd, query->hostname,
                            (FAR union dns_addr_u *)addr,
-                           DNS_RECTYPE_A, &qinfo);
+                           DNS_RECTYPE_A, &qdata->qinfo, qdata->buffer);
       if (ret < 0)
         {
           dns_query_error("ERROR: IPv4 dns_send_query failed",
@@ -697,7 +706,8 @@ static int dns_query_callback(FAR void *arg, FAR struct 
sockaddr *addr,
           /* Obtain the IPv4 response */
 
           ret = dns_recv_response(sd, &query->addr[next],
-                                  *query->naddr - next, &qinfo, &query->ttl);
+                                  *query->naddr - next, &qdata->qinfo,
+                                  &query->ttl, qdata->buffer);
           if (ret >= 0)
             {
               next += ret;
@@ -763,15 +773,20 @@ static int dns_query_callback(FAR void *arg, FAR struct 
sockaddr *addr,
 int dns_query(FAR const char *hostname, FAR union dns_addr_u *addr,
               FAR int *naddr)
 {
-  FAR struct dns_query_s query;
+  FAR struct dns_query_data_s *qdata = lib_malloc(sizeof(*qdata));
   int ret;
 
+  if (qdata == NULL)
+    {
+      return -ENOMEM;
+    }
+
   /* Set up the query info structure */
 
-  query.result   = -EADDRNOTAVAIL;
-  query.hostname = hostname;
-  query.addr     = addr;
-  query.naddr    = naddr;
+  qdata->query.result   = -EADDRNOTAVAIL;
+  qdata->query.hostname = hostname;
+  qdata->query.addr     = addr;
+  qdata->query.naddr    = naddr;
 
   /* Perform the query. dns_foreach_nameserver() will return:
    *
@@ -780,7 +795,7 @@ int dns_query(FAR const char *hostname, FAR union 
dns_addr_u *addr,
    * <0 - Some other failure (?, shouldn't happen)
    */
 
-  ret = dns_foreach_nameserver(dns_query_callback, &query);
+  ret = dns_foreach_nameserver(dns_query_callback, qdata);
   if (ret > 0)
     {
       /* The lookup was successful */
@@ -789,8 +804,12 @@ int dns_query(FAR const char *hostname, FAR union 
dns_addr_u *addr,
     }
   else if (ret == 0)
     {
-      ret = query.result;
+      ret = qdata->query.result;
     }
 
+  /* Free the query data */
+
+  lib_free(qdata);
+
   return ret;
 }

Reply via email to