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;
}