aboutsummaryrefslogtreecommitdiff
path: root/ares
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-05-07 21:20:45 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-05-07 21:20:45 +0000
commit836fa69e2e9bafca263bc6a51527960ddf3dad92 (patch)
tree6857a663410f9e8eb8ca2f59697d9fbf83773869 /ares
parent9026dc2da4f7dbb7e0df54c3a8f5e19c4840d762 (diff)
- Sebastian made c-ares able to return all PTR-records when doing reverse
lookups. It is not common practice to have multiple PTR-Records for a single IP, but its perfectly legal and some sites have those.
Diffstat (limited to 'ares')
-rw-r--r--ares/CHANGES4
-rw-r--r--ares/ares_parse_ptr_reply.c29
2 files changed, 31 insertions, 2 deletions
diff --git a/ares/CHANGES b/ares/CHANGES
index 88d95cc55..0acc94c15 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -2,6 +2,10 @@
* May 7 2008 (Daniel Stenberg)
+- Sebastian made c-ares able to return all PTR-records when doing reverse
+ lookups. It is not common practice to have multiple PTR-Records for a single
+ IP, but its perfectly legal and some sites have those.
+
- Doug Goldstein provided a configure patch: updates autoconf 2.13 usage to
autoconf 2.57 usage (which is the version you have specified as the minimum
version). It's a minor change but it does clean up some warnings with newer
diff --git a/ares/ares_parse_ptr_reply.c b/ares/ares_parse_ptr_reply.c
index 8b87c9b87..7025158fb 100644
--- a/ares/ares_parse_ptr_reply.c
+++ b/ares/ares_parse_ptr_reply.c
@@ -44,6 +44,8 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
const unsigned char *aptr;
char *ptrname, *hostname, *rr_name, *rr_data;
struct hostent *hostent;
+ int aliascnt = 0;
+ char ** aliases;
/* Set *host to NULL for all failure cases. */
*host = NULL;
@@ -72,6 +74,12 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
/* Examine each answer resource record (RR) in turn. */
hostname = NULL;
+ aliases = (char **) malloc(8 * sizeof(char *));
+ if (!aliases)
+ {
+ free(ptrname);
+ return ARES_ENOMEM;
+ }
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
@@ -99,6 +107,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
if (hostname)
free(hostname);
hostname = rr_data;
+ aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char *));
+ if (!aliases[aliascnt])
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
+ aliascnt++;
+ if ((aliascnt%8)==0)
+ aliases = (char **) realloc(aliases, (aliascnt/16+1) * sizeof(char *));
}
if (rr_class == C_IN && rr_type == T_CNAME)
@@ -134,17 +152,20 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
hostent->h_addr_list[0] = malloc(addrlen);
if (hostent->h_addr_list[0])
{
- hostent->h_aliases = malloc(sizeof (char *));
+ hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *));
if (hostent->h_aliases)
{
/* Fill in the hostent and return successfully. */
hostent->h_name = hostname;
- hostent->h_aliases[0] = NULL;
+ for (i=0 ; i<aliascnt ; i++)
+ hostent->h_aliases[i] = aliases[i];
+ hostent->h_aliases[aliascnt] = NULL;
hostent->h_addrtype = family;
hostent->h_length = addrlen;
memcpy(hostent->h_addr_list[0], addr, addrlen);
hostent->h_addr_list[1] = NULL;
*host = hostent;
+ free(aliases);
free(ptrname);
return ARES_SUCCESS;
}
@@ -156,6 +177,10 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
}
status = ARES_ENOMEM;
}
+ for (i=0 ; i<aliascnt ; i++)
+ if (aliases[i])
+ free(aliases[i]);
+ free(aliases);
if (hostname)
free(hostname);
free(ptrname);