diff --git a/lib/hostares.c b/lib/hostares.c
index a0374db..daefd06 100644
--- a/lib/hostares.c
+++ b/lib/hostares.c
@@ -304,6 +304,27 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
   return rc;
 }
 
+CURLcode Curl_ares_callback(void *arg, /* "struct connectdata *" */
+                            int status,
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+                            int timeouts,
+#endif
+                            struct hostent *hostent)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct Curl_addrinfo * ai = NULL;
+    
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+  (void)timeouts; /* ignored */
+#endif
+
+  if (status == CURL_ASYNC_SUCCESS) {
+    ai = Curl_he2ai(hostent, conn->async.port);
+  }
+ 
+  return Curl_addrinfo_callback(arg, status, ai);
+}
+
 
 /*
  * Curl_getaddrinfo() - when using ares
@@ -369,7 +390,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
 
     /* areschannel is already setup in the Curl_open() function */
     ares_gethostbyname(data->state.areschannel, hostname, family,
-                       (ares_host_callback)Curl_addrinfo4_callback, conn);
+                       (ares_host_callback)Curl_ares_callback, conn);
 
     *waitp = TRUE; /* please wait for the response */
   }
diff --git a/lib/hostasyn.c b/lib/hostasyn.c
index 2773f82..309a8e5 100644
--- a/lib/hostasyn.c
+++ b/lib/hostasyn.c
@@ -73,37 +73,21 @@
  **********************************************************************/
 #ifdef CURLRES_ASYNCH
 /*
- * addrinfo_callback() gets called by ares, gethostbyname_thread() or
+ * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread() or
  * getaddrinfo_thread() when we got the name resolved (or not!).
  *
- * If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the
- * address field since it might be freed when this function returns. This
- * operation stores the resolved data in the DNS cache.
- *
- * NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same
- * pointer it is given as argument!
- *
- * The storage operation locks and unlocks the DNS cache.
+ * This function takes ownership of the Curl_addrinfo passed.
  */
-static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
-                                  int status,
-                                  void *addr)
+CURLcode Curl_addrinfo_callback(struct connectdata * conn,
+                                int status,
+                                struct Curl_addrinfo *ai)
 {
-  struct connectdata *conn = (struct connectdata *)arg;
   struct Curl_dns_entry *dns = NULL;
   CURLcode rc = CURLE_OK;
 
   conn->async.status = status;
 
   if(CURL_ASYNC_SUCCESS == status) {
-
-    /*
-     * IPv4/ares: Curl_addrinfo_copy() copies the address and returns an
-     * allocated version.
-     *
-     * IPv6: Curl_addrinfo_copy() returns the input pointer!
-     */
-    Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port);
     if(ai) {
       struct SessionHandle *data = conn->data;
 
@@ -138,35 +122,4 @@ static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
   return rc;
 }
 
-CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
-                                 int status,
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-                                 int timeouts,
-#endif
-                                 struct hostent *hostent)
-{
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-  (void)timeouts; /* ignored */
-#endif
-  return addrinfo_callback(arg, status, hostent);
-}
-
-#ifdef CURLRES_IPV6
-CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
-                                 int status,
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-                                 int timeouts,
-#endif
-                                 Curl_addrinfo *ai)
-{
- /* NOTE: for CURLRES_ARES, the 'ai' argument is really a
-  * 'struct hostent' pointer.
-  */
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-  (void)timeouts; /* ignored */
-#endif
-  return addrinfo_callback(arg, status, ai);
-}
-#endif
-
 #endif /* CURLRES_ASYNC */
diff --git a/lib/hostip.c b/lib/hostip.c
index b139ee6..f2195bc 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -712,20 +712,4 @@ struct curl_hash *Curl_mk_dnscache(void)
   return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
 }
 
-#ifdef CURLRES_ADDRINFO_COPY
 
-/* align on even 64bit boundaries */
-#define MEMALIGN(x) ((x)+(8-(((unsigned long)(x))&0x7)))
-
-/*
- * Curl_addrinfo_copy() performs a "deep" copy of a hostent into a buffer and
- * returns a pointer to the malloc()ed copy. You need to call free() on the
- * returned buffer when you're done with it.
- */
-Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
-{
-  const struct hostent *orig = org;
-
-  return Curl_he2ai(orig, port);
-}
-#endif /* CURLRES_ADDRINFO_COPY */
diff --git a/lib/hostip.h b/lib/hostip.h
index 5bfa771..ea2b731 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -65,15 +65,6 @@
 #define CURLRES_IPV4
 #endif
 
-#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
-#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
-/* If built for ipv4 and missing gethostbyname_r(), or if using async name
-   resolve, we need the Curl_addrinfo_copy() function (which itself needs the
-   Curl_he2ai() function)) */
-#define CURLRES_ADDRINFO_COPY
-#endif
-#endif /* IPv4/ares-only */
-
 #ifndef CURLRES_ASYNCH
 #define CURLRES_SYNCH
 #endif
@@ -203,26 +194,12 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
                        int line, const char *source);
 #endif
 
-/* This is the callback function that is used when we build with asynch
-   resolve, ipv4 */
-CURLcode Curl_addrinfo4_callback(void *arg,
-                                 int status,
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-                                 int timeouts,
-#endif
-                                 struct hostent *hostent);
-/* This is the callback function that is used when we build with asynch
-   resolve, ipv6 */
-CURLcode Curl_addrinfo6_callback(void *arg,
-                                 int status,
-#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
-                                 int timeouts,
-#endif
-                                 Curl_addrinfo *ai);
-
-
-/* Clone a Curl_addrinfo struct, works protocol independently */
-Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
+/* Handle end of async request processing. Insert ai into hostcache
+   if status == 0. Twiddle fields in conn to indicate async request done.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+                                int status,
+                                Curl_addrinfo *ai);
 
 /*
  * Curl_printable_address() returns a printable version of the 1st address
diff --git a/lib/hostthre.c b/lib/hostthre.c
index b7333c2..6e7665f 100644
--- a/lib/hostthre.c
+++ b/lib/hostthre.c
@@ -219,7 +219,7 @@ void release_thread_sync(struct thread_sync_data * tsd)
 
 #if defined(CURLRES_IPV4)
 /*
- * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback
+ * gethostbyname_thread() resolves a name, calls the Curl_addrinfo_callback
  * and then exits.
  *
  * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on
@@ -254,14 +254,16 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
 
   /* is parent thread waiting for us and are we able to access conn members? */
   if(acquire_thread_sync(&tsd)) {
+    Curl_addrinfo *ai = Curl_he2ai(he, conn->async.port);
+
     /* Mark that we have obtained the information, and that we are calling
      * back with it. */
     SetEvent(td->event_resolved);
-    if(he) {
-      rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
+    if(ai) {
+      rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, ai);
     }
     else {
-      rc = Curl_addrinfo4_callback(conn, SOCKERRNO, NULL);
+      rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL);
     }
     release_thread_sync(&tsd);
   }
@@ -276,7 +278,7 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
 #elif defined(CURLRES_IPV6)
 
 /*
- * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then
+ * getaddrinfo_thread() resolves a name, calls Curl_addrinfo_callback and then
  * exits.
  *
  * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
@@ -320,10 +322,10 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
     SetEvent(td->event_resolved);
 
     if(rc == 0) {
-      rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
+      rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, res);
     }
     else {
-      rc = Curl_addrinfo6_callback(conn, SOCKERRNO, NULL);
+      rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL);
     }
     release_thread_sync(&tsd);
   }
