"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib/ares_parse_ptr_reply.c" between
c-ares-1.17.1.tar.gz and c-ares-1.17.2.tar.gz

About: c-ares is a C library for asynchronous DNS requests (including name resolves).

ares_parse_ptr_reply.c  (c-ares-1.17.1):ares_parse_ptr_reply.c  (c-ares-1.17.2)
skipping to change at line 25 skipping to change at line 25
*/ */
#include "ares_setup.h" #include "ares_setup.h"
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H
# include <netdb.h> # include <netdb.h>
#endif #endif
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h> #include "ares_nameser.h"
#else
# include "nameser.h"
#endif
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
# include <arpa/nameser_compat.h>
#endif
#ifdef HAVE_STRINGS_H #ifdef HAVE_STRINGS_H
# include <strings.h> # include <strings.h>
#endif #endif
#include "ares.h" #include "ares.h"
#include "ares_dns.h" #include "ares_dns.h"
#include "ares_nowarn.h" #include "ares_nowarn.h"
#include "ares_private.h" #include "ares_private.h"
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
int addrlen, int family, struct hostent **host) int addrlen, int family, struct hostent **host)
{ {
unsigned int qdcount, ancount; unsigned int qdcount, ancount;
int status, i, rr_type, rr_class, rr_len; int status, i, rr_type, rr_class, rr_len;
long len; long len;
const unsigned char *aptr; const unsigned char *aptr;
char *ptrname, *hostname, *rr_name, *rr_data; char *ptrname, *hostname, *rr_name, *rr_data;
struct hostent *hostent; struct hostent *hostent = NULL;
int aliascnt = 0; int aliascnt = 0;
int alias_alloc = 8; int alias_alloc = 8;
char ** aliases; char ** aliases;
size_t rr_data_len; size_t rr_data_len;
/* Set *host to NULL for all failure cases. */ /* Set *host to NULL for all failure cases. */
*host = NULL; *host = NULL;
/* Give up if abuf doesn't have room for a header. */ /* Give up if abuf doesn't have room for a header. */
if (alen < HFIXEDSZ) if (alen < HFIXEDSZ)
return ARES_EBADRESP; return ARES_EBADRESP;
/* Fetch the question and answer count from the header. */ /* Fetch the question and answer count from the header. */
qdcount = DNS_HEADER_QDCOUNT(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf);
ancount = DNS_HEADER_ANCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf);
if (qdcount != 1) if (qdcount != 1)
return ARES_EBADRESP; return ARES_EBADRESP;
/* Expand the name from the question, and skip past the question. */ /* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ; aptr = abuf + HFIXEDSZ;
status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len); status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len, 0);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
return status; return status;
if (aptr + len + QFIXEDSZ > abuf + alen) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
ares_free(ptrname); ares_free(ptrname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; aptr += len + QFIXEDSZ;
/* Examine each answer resource record (RR) in turn. */ /* Examine each answer resource record (RR) in turn. */
hostname = NULL; hostname = NULL;
aliases = ares_malloc(alias_alloc * sizeof(char *)); aliases = ares_malloc(alias_alloc * sizeof(char *));
if (!aliases) if (!aliases)
{ {
ares_free(ptrname); ares_free(ptrname);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
for (i = 0; i < (int)ancount; i++) for (i = 0; i < (int)ancount; i++)
{ {
/* Decode the RR up to the data field. */ /* Decode the RR up to the data field. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len, 0);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
break; break;
aptr += len; aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen) if (aptr + RRFIXEDSZ > abuf + alen)
{ {
ares_free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
rr_type = DNS_RR_TYPE(aptr); rr_type = DNS_RR_TYPE(aptr);
skipping to change at line 119 skipping to change at line 113
ares_free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
if (rr_class == C_IN && rr_type == T_PTR if (rr_class == C_IN && rr_type == T_PTR
&& strcasecmp(rr_name, ptrname) == 0) && strcasecmp(rr_name, ptrname) == 0)
{ {
/* Decode the RR data and set hostname to it. */ /* Decode the RR data and set hostname to it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len); &len, 1);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
ares_free(rr_name); ares_free(rr_name);
break; break;
} }
if (hostname) if (hostname)
ares_free(hostname); ares_free(hostname);
hostname = rr_data; hostname = rr_data;
rr_data_len = strlen(rr_data)+1; rr_data_len = strlen(rr_data)+1;
aliases[aliascnt] = ares_malloc(rr_data_len * sizeof(char)); aliases[aliascnt] = ares_malloc(rr_data_len * sizeof(char));
skipping to change at line 155 skipping to change at line 149
break; break;
} }
aliases = ptr; aliases = ptr;
} }
} }
if (rr_class == C_IN && rr_type == T_CNAME) if (rr_class == C_IN && rr_type == T_CNAME)
{ {
/* Decode the RR data and replace ptrname with it. */ /* Decode the RR data and replace ptrname with it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len); &len, 1);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
ares_free(rr_name); ares_free(rr_name);
break; break;
} }
ares_free(ptrname); ares_free(ptrname);
ptrname = rr_data; ptrname = rr_data;
} }
ares_free(rr_name); ares_free(rr_name);
skipping to change at line 178 skipping to change at line 172
{ /* LCOV_EXCL_START: already checked above */ { /* LCOV_EXCL_START: already checked above */
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} /* LCOV_EXCL_STOP */ } /* LCOV_EXCL_STOP */
} }
if (status == ARES_SUCCESS && !hostname) if (status == ARES_SUCCESS && !hostname)
status = ARES_ENODATA; status = ARES_ENODATA;
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
/* We got our answer. Allocate memory to build the host entry. */ /* If we don't reach the end, we must have failed due to out of memory */
hostent = ares_malloc(sizeof(struct hostent));
if (hostent)
{
hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
if (hostent->h_addr_list)
{
hostent->h_addr_list[0] = ares_malloc(addrlen);
if (hostent->h_addr_list[0])
{
hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *
));
if (hostent->h_aliases)
{
/* Fill in the hostent and return successfully. */
hostent->h_name = hostname;
for (i=0 ; i<aliascnt ; i++)
hostent->h_aliases[i] = aliases[i];
hostent->h_aliases[aliascnt] = NULL;
hostent->h_addrtype = aresx_sitoss(family);
hostent->h_length = aresx_sitoss(addrlen);
memcpy(hostent->h_addr_list[0], addr, addrlen);
hostent->h_addr_list[1] = NULL;
*host = hostent;
ares_free(aliases);
ares_free(ptrname);
return ARES_SUCCESS;
}
ares_free(hostent->h_addr_list[0]);
}
ares_free(hostent->h_addr_list);
}
ares_free(hostent);
}
status = ARES_ENOMEM; status = ARES_ENOMEM;
/* We got our answer. Allocate memory to build the host entry. */
hostent = ares_malloc(sizeof(*hostent));
if (!hostent)
goto fail;
/* If we don't memset here, cleanups may fail */
memset(hostent, 0, sizeof(*hostent));
hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
if (!hostent->h_addr_list)
goto fail;
if (addr && addrlen) {
hostent->h_addr_list[0] = ares_malloc(addrlen);
if (!hostent->h_addr_list[0])
goto fail;
} else {
hostent->h_addr_list[0] = NULL;
}
hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *));
if (!hostent->h_aliases)
goto fail;
/* Fill in the hostent and return successfully. */
hostent->h_name = hostname;
for (i=0 ; i<aliascnt ; i++)
hostent->h_aliases[i] = aliases[i];
hostent->h_aliases[aliascnt] = NULL;
hostent->h_addrtype = aresx_sitoss(family);
hostent->h_length = aresx_sitoss(addrlen);
if (addr && addrlen)
memcpy(hostent->h_addr_list[0], addr, addrlen);
hostent->h_addr_list[1] = NULL;
*host = hostent;
ares_free(aliases);
ares_free(ptrname);
return ARES_SUCCESS;
} }
fail:
ares_free_hostent(hostent);
for (i=0 ; i<aliascnt ; i++) for (i=0 ; i<aliascnt ; i++)
if (aliases[i]) if (aliases[i])
ares_free(aliases[i]); ares_free(aliases[i]);
ares_free(aliases); ares_free(aliases);
if (hostname) if (hostname)
ares_free(hostname); ares_free(hostname);
ares_free(ptrname); ares_free(ptrname);
return status; return status;
} }
 End of changes. 9 change blocks. 
47 lines changed or deleted 52 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)