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 <wengzhe@xiaomi.com>
This commit is contained in:
parent
4aa54e8405
commit
9dc5a59d50
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user