*
* The storage operation locks and unlocks the DNS cache.
*/
-static void addrinfo_callback(void *arg, /* "struct connectdata *" */
- int status,
- void *addr)
+static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
+ int status,
+ void *addr)
{
struct connectdata *conn = (struct connectdata *)arg;
struct Curl_dns_entry *dns = NULL;
+ CURLcode rc = CURLE_OK;
conn->async.status = status;
dns = Curl_cache_addr(data, ai,
conn->async.hostname,
conn->async.port);
- if(!dns)
+ if(!dns) {
/* failed to store, cleanup and return error */
Curl_freeaddrinfo(ai);
+ rc = CURLE_OUT_OF_MEMORY;
+ }
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
+ else
+ rc = CURLE_OUT_OF_MEMORY;
}
conn->async.dns = dns;
/* ipv4: The input hostent struct will be freed by ares when we return from
this function */
+ return rc;
}
-void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
- int status,
- struct hostent *hostent)
+CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
+ int status,
+ struct hostent *hostent)
{
- addrinfo_callback(arg, status, hostent);
+ return addrinfo_callback(arg, status, hostent);
}
#ifdef CURLRES_IPV6
-void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
- int status,
- struct addrinfo *ai)
+CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
+ int status,
+ struct addrinfo *ai)
{
- addrinfo_callback(arg, status, ai);
+ return addrinfo_callback(arg, status, ai);
}
#endif
/* This is the callback function that is used when we build with asynch
resolve, ipv4 */
-void Curl_addrinfo4_callback(void *arg,
- int status,
- struct hostent *hostent);
+CURLcode Curl_addrinfo4_callback(void *arg,
+ int status,
+ struct hostent *hostent);
/* This is the callback function that is used when we build with asynch
resolve, ipv6 */
-void Curl_addrinfo6_callback(void *arg,
- int status,
- struct addrinfo *ai);
+CURLcode Curl_addrinfo6_callback(void *arg,
+ int status,
+ struct addrinfo *ai);
/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP
curr_proc, &mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */
- return 0;
+ return -1;
}
/* Sharing the same _iob[] element with our parent thread should
SetEvent(td->event_resolved);
if (he) {
- Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
- rc = 1;
+ rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
}
else {
- Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
- rc = 0;
+ rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
}
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
curr_proc, &mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */
- return 0;
+ return -1;
}
#ifndef _WIN32_WCE
#ifdef DEBUG_THREADING_GETADDRINFO
dump_addrinfo (conn, res);
#endif
- Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
+ rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
}
else {
- Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
+ rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
TRACE(("Winsock-error %d, no address\n", conn->async.status));
}
}
if (!conn->async.dns) {
/* a name was not resolved */
- if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
+ if (td->thread_status == CURLE_OUT_OF_MEMORY) {
+ rc = CURLE_OUT_OF_MEMORY;
+ failf(data, "Could not resolve host: %s", curl_easy_strerror(rc));
+ }
+ else if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
failf(data, "Resolving host timed out: %s", conn->host.name);
rc = CURLE_OPERATION_TIMEDOUT;
}
destroy_thread_data(&conn->async);
- if(CURLE_OK != rc)
- /* close the connection, since we must not return failure from here
- without cleaning up this connection properly */
- Curl_disconnect(conn);
+ if(!conn->async.dns)
+ conn->bits.close = TRUE;
return (rc);
}