From 836fa69e2e9bafca263bc6a51527960ddf3dad92 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 7 May 2008 21:20:45 +0000
Subject: [PATCH] - 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.

---
 ares/CHANGES                |  4 ++++
 ares/ares_parse_ptr_reply.c | 29 +++++++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/ares/CHANGES b/ares/CHANGES
index 88d95cc55f..0acc94c157 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 8b87c9b874..7025158fb9 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);
-- 
GitLab