* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
*
***************************************************************************/
-#include "setup.h"
+#include "curl_setup.h"
-#include <string.h>
+/***********************************************************************
+ * Only for builds using asynchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_ASYNCH
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
#ifdef __VMS
#include <in.h>
#include <inet.h>
-#include <stdlib.h>
#endif
#ifdef HAVE_PROCESS_H
#include "share.h"
#include "strerror.h"
#include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
-/***********************************************************************
- * Only for builds using asynchronous name resolves
- **********************************************************************/
-#ifdef CURLRES_ASYNCH
-
-/*
- * Cancel all possibly still on-going resolves for this connection.
- */
-void Curl_async_cancel(struct connectdata *conn)
-{
- /* If we have a "half" response already received, we first clear that off
- so that nothing is tempted to use it */
- if(conn->async.temp_ai) {
- Curl_freeaddrinfo(conn->async.temp_ai);
- conn->async.temp_ai = NULL;
- }
-
- /* for ares-using, make sure all possible outstanding requests are properly
- cancelled before we proceed */
- ares_cancel(conn->data->state.areschannel);
-}
-
-
/*
* Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
* or getaddrinfo_thread() when we got the name resolved (or not!).
struct Curl_addrinfo *ai)
{
struct Curl_dns_entry *dns = NULL;
- CURLcode rc = CURLE_OK;
+ CURLcode result = CURLE_OK;
conn->async.status = status;
if(CURL_ASYNC_SUCCESS == status) {
if(ai) {
- struct SessionHandle *data = conn->data;
-
-#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
- Curl_addrinfo *ai_tail = ai;
+ struct Curl_easy *data = conn->data;
- while (ai_tail->ai_next)
- ai_tail = ai_tail->ai_next;
-
- /* Add the new results to the list of old results. */
- ai_tail->ai_next = conn->async.temp_ai;
- conn->async.temp_ai = ai;
-
- if(--conn->async.num_pending > 0)
- /* We are not done yet. Just return. */
- return CURLE_OK;
-#endif
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
if(!dns) {
/* failed to store, cleanup and return error */
Curl_freeaddrinfo(ai);
- rc = CURLE_OUT_OF_MEMORY;
+ result = CURLE_OUT_OF_MEMORY;
}
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
else {
-#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
- if(--conn->async.num_pending > 0) {
- /* We are not done yet. Clean up and return.
- This function will be called again. */
- if(conn->async.temp_ai)
- Curl_freeaddrinfo(conn->async.temp_ai);
- return CURLE_OUT_OF_MEMORY;
- }
-#endif
- rc = CURLE_OUT_OF_MEMORY;
+ result = CURLE_OUT_OF_MEMORY;
}
}
-#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
- else
- {
- if(--conn->async.num_pending > 0)
- /* We are not done yet. Just return. */
- return CURLE_OK;
-
- if(conn->async.temp_ai) {
- /* We are done, and while this latest request
- failed, some previous results exist. */
- struct SessionHandle *data = conn->data;
-
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- dns = Curl_cache_addr(data, conn->async.temp_ai,
- conn->async.hostname,
- conn->async.port);
- if(!dns) {
- /* failed to store, cleanup and return error */
- Curl_freeaddrinfo(conn->async.temp_ai);
- rc = CURLE_OUT_OF_MEMORY;
- }
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
- }
- }
-#endif
conn->async.dns = dns;
async struct */
conn->async.done = TRUE;
- /* ipv4: The input hostent struct will be freed by ares when we return from
+ /* IPv4: The input hostent struct will be freed by ares when we return from
this function */
- return rc;
+ return result;
+}
+
+/* Call this function after Curl_connect() has returned async=TRUE and
+ then a successful name resolve has been received.
+
+ Note: this function disconnects and frees the conn data in case of
+ resolve failure */
+CURLcode Curl_async_resolved(struct connectdata *conn,
+ bool *protocol_done)
+{
+ CURLcode result;
+
+ if(conn->async.dns) {
+ conn->dns_entry = conn->async.dns;
+ conn->async.dns = NULL;
+ }
+
+ result = Curl_setup_conn(conn, protocol_done);
+
+ if(result)
+ /* We're not allowed to return failure with memory left allocated
+ in the connectdata struct, free those here */
+ Curl_disconnect(conn, FALSE); /* close the connection */
+
+ return result;
+}
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
}
#endif /* CURLRES_ASYNCH */