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 <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <nuttx/lib/lib.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/dns.h>
|
#include <nuttx/net/dns.h>
|
||||||
|
|
||||||
@ -79,6 +80,7 @@
|
|||||||
|
|
||||||
#define SEND_BUFFER_SIZE (16 + CONFIG_NETDB_DNSCLIENT_NAMESIZE + 2)
|
#define SEND_BUFFER_SIZE (16 + CONFIG_NETDB_DNSCLIENT_NAMESIZE + 2)
|
||||||
#define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
|
#define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
|
||||||
|
#define QUERY_BUFFER_SIZE MAX(SEND_BUFFER_SIZE, RECV_BUFFER_SIZE)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
@ -104,6 +106,13 @@ struct dns_query_info_s
|
|||||||
* encoded format + NUL */
|
* 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
|
* 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,
|
static int dns_send_query(int sd, FAR const char *name,
|
||||||
FAR union dns_addr_u *uaddr, uint16_t rectype,
|
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 struct dns_header_s *hdr;
|
||||||
FAR uint8_t *dest;
|
FAR uint8_t *dest;
|
||||||
@ -205,7 +215,6 @@ static int dns_send_query(int sd, FAR const char *name,
|
|||||||
FAR char *qname;
|
FAR char *qname;
|
||||||
FAR char *qptr;
|
FAR char *qptr;
|
||||||
FAR const char *src;
|
FAR const char *src;
|
||||||
uint8_t buffer[SEND_BUFFER_SIZE];
|
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
int ret;
|
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,
|
static int dns_recv_response(int sd, FAR union dns_addr_u *addr, int naddr,
|
||||||
FAR struct dns_query_info_s *qinfo,
|
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 *nameptr;
|
||||||
FAR uint8_t *namestart;
|
FAR uint8_t *namestart;
|
||||||
FAR uint8_t *endofbuffer;
|
FAR uint8_t *endofbuffer;
|
||||||
char buffer[RECV_BUFFER_SIZE];
|
|
||||||
FAR struct dns_answer_s *ans;
|
FAR struct dns_answer_s *ans;
|
||||||
FAR struct dns_header_s *hdr;
|
FAR struct dns_header_s *hdr;
|
||||||
FAR struct dns_question_s *que;
|
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;
|
hdr = (FAR struct dns_header_s *)buffer;
|
||||||
endofbuffer = (FAR uint8_t *)buffer + ret;
|
endofbuffer = buffer + ret;
|
||||||
|
|
||||||
ninfo("ID %d\n", NTOHS(hdr->id));
|
ninfo("ID %d\n", NTOHS(hdr->id));
|
||||||
ninfo("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
|
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.
|
* matches against the name in the question.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namestart = (uint8_t *)buffer + sizeof(*hdr);
|
namestart = buffer + sizeof(*hdr);
|
||||||
nameptr = dns_parse_name(namestart, endofbuffer);
|
nameptr = dns_parse_name(namestart, endofbuffer);
|
||||||
if (nameptr == 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,
|
static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
||||||
FAR socklen_t addrlen)
|
FAR socklen_t addrlen)
|
||||||
{
|
{
|
||||||
FAR struct dns_query_s *query = (FAR struct dns_query_s *)arg;
|
FAR struct dns_query_data_s *qdata = arg;
|
||||||
FAR struct dns_query_info_s qinfo;
|
FAR struct dns_query_s *query = &qdata->query;
|
||||||
int next = 0;
|
int next = 0;
|
||||||
int retries;
|
int retries;
|
||||||
int ret;
|
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,
|
ret = dns_send_query(sd, query->hostname,
|
||||||
(FAR union dns_addr_u *)addr,
|
(FAR union dns_addr_u *)addr,
|
||||||
DNS_RECTYPE_AAAA, &qinfo);
|
DNS_RECTYPE_AAAA, &qdata->qinfo, qdata->buffer);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dns_query_error("ERROR: IPv6 dns_send_query failed",
|
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 */
|
/* Obtain the IPv6 response */
|
||||||
|
|
||||||
ret = dns_recv_response(sd, &query->addr[next],
|
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)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
next += ret;
|
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,
|
ret = dns_send_query(sd, query->hostname,
|
||||||
(FAR union dns_addr_u *)addr,
|
(FAR union dns_addr_u *)addr,
|
||||||
DNS_RECTYPE_A, &qinfo);
|
DNS_RECTYPE_A, &qdata->qinfo, qdata->buffer);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dns_query_error("ERROR: IPv4 dns_send_query failed",
|
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 */
|
/* Obtain the IPv4 response */
|
||||||
|
|
||||||
ret = dns_recv_response(sd, &query->addr[next],
|
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)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
next += ret;
|
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,
|
int dns_query(FAR const char *hostname, FAR union dns_addr_u *addr,
|
||||||
FAR int *naddr)
|
FAR int *naddr)
|
||||||
{
|
{
|
||||||
FAR struct dns_query_s query;
|
FAR struct dns_query_data_s *qdata = lib_malloc(sizeof(*qdata));
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (qdata == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up the query info structure */
|
/* Set up the query info structure */
|
||||||
|
|
||||||
query.result = -EADDRNOTAVAIL;
|
qdata->query.result = -EADDRNOTAVAIL;
|
||||||
query.hostname = hostname;
|
qdata->query.hostname = hostname;
|
||||||
query.addr = addr;
|
qdata->query.addr = addr;
|
||||||
query.naddr = naddr;
|
qdata->query.naddr = naddr;
|
||||||
|
|
||||||
/* Perform the query. dns_foreach_nameserver() will return:
|
/* 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)
|
* <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)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
/* The lookup was successful */
|
/* 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)
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
ret = query.result;
|
ret = qdata->query.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free the query data */
|
||||||
|
|
||||||
|
lib_free(qdata);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user