diff --git a/libs/libc/netdb/lib_dnsquery.c b/libs/libc/netdb/lib_dnsquery.c index 37074dd3ee0..ba7789d9a70 100644 --- a/libs/libc/netdb/lib_dnsquery.c +++ b/libs/libc/netdb/lib_dnsquery.c @@ -57,6 +57,7 @@ #include +#include #include #include @@ -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; }