diff options
Diffstat (limited to 'lib/hostthre.c')
-rw-r--r-- | lib/hostthre.c | 629 |
1 files changed, 224 insertions, 405 deletions
diff --git a/lib/hostthre.c b/lib/hostthre.c index 32e946ccb..2205c8fdd 100644 --- a/lib/hostthre.c +++ b/lib/hostthre.c @@ -50,8 +50,14 @@ #include <stdlib.h> #endif -#ifdef HAVE_PROCESS_H -#include <process.h> +#if defined(USE_THREADS_POSIX) +# ifdef HAVE_PTHREAD_H +# include <pthread.h> +# endif +#elif defined(USE_THREADS_WIN32) +# ifdef HAVE_PROCESS_H +# include <process.h> +# endif #endif #if (defined(NETWARE) && defined(__NOVELL_LIBC__)) @@ -68,12 +74,12 @@ #include "url.h" #include "multiif.h" #include "inet_pton.h" +#include "inet_ntop.h" +#include "curl_threads.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> -#include "inet_ntop.h" - #include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" @@ -83,7 +89,7 @@ #endif /*********************************************************************** - * Only for Windows threaded name resolves builds + * Only for threaded name resolves builds **********************************************************************/ #ifdef CURLRES_THREADED @@ -92,251 +98,162 @@ static bool init_resolve_thread(struct connectdata *conn, const char *hostname, int port, const struct addrinfo *hints); -#ifdef CURLRES_IPV4 - #define THREAD_FUNC gethostbyname_thread - #define THREAD_NAME "gethostbyname_thread" -#else - #define THREAD_FUNC getaddrinfo_thread - #define THREAD_NAME "getaddrinfo_thread" -#endif - -struct thread_data { - HANDLE thread_hnd; - unsigned thread_id; - DWORD thread_status; - curl_socket_t dummy_sock; /* dummy for Curl_resolv_fdset() */ - HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */ - HANDLE event_resolved; /* marks that the thread obtained the information */ - HANDLE event_thread_started; /* marks that the thread has initialized and - started */ - HANDLE mutex_terminate; /* serializes access to flag_terminate */ - HANDLE event_terminate; /* flag for thread to terminate instead of calling - callbacks */ -#ifdef CURLRES_IPV6 - struct addrinfo hints; -#endif -}; /* Data for synchronization between resolver thread and its parent */ struct thread_sync_data { - HANDLE mutex_waiting; /* thread_data.mutex_waiting duplicate */ - HANDLE mutex_terminate; /* thread_data.mutex_terminate duplicate */ - HANDLE event_terminate; /* thread_data.event_terminate duplicate */ + curl_mutex_t * mtx; + int done; + char * hostname; /* hostname to resolve, Curl_async.hostname duplicate */ + int port; + int sock_error; + Curl_addrinfo *res; +#ifdef HAVE_GETADDRINFO + struct addrinfo hints; +#endif +}; + +struct thread_data { + curl_thread_t thread_hnd; + curl_socket_t dummy_sock; + unsigned int poll_interval; + int interval_end; + struct thread_sync_data tsd; }; +static struct thread_sync_data * conn_thread_sync_data(struct connectdata *conn) +{ + return &(((struct thread_data *)conn->async.os_specific)->tsd); +} + +#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd); + /* Destroy resolver thread synchronization data */ static void destroy_thread_sync_data(struct thread_sync_data * tsd) { + if (tsd->mtx) { + Curl_mutex_destroy(tsd->mtx); + free(tsd->mtx); + } + if(tsd->hostname) free(tsd->hostname); - if(tsd->event_terminate) - CloseHandle(tsd->event_terminate); - if(tsd->mutex_terminate) - CloseHandle(tsd->mutex_terminate); - if(tsd->mutex_waiting) - CloseHandle(tsd->mutex_waiting); + + if (tsd->res) + Curl_freeaddrinfo(tsd->res); + memset(tsd,0,sizeof(*tsd)); } /* Initialize resolver thread synchronization data */ static -BOOL init_thread_sync_data(struct thread_data * td, +int init_thread_sync_data(struct thread_sync_data * tsd, const char * hostname, - struct thread_sync_data * tsd) + int port, + const struct addrinfo *hints) { - HANDLE curr_proc = GetCurrentProcess(); - memset(tsd, 0, sizeof(*tsd)); - if(!DuplicateHandle(curr_proc, td->mutex_waiting, - curr_proc, &tsd->mutex_waiting, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - /* failed to duplicate the mutex, no point in continuing */ - destroy_thread_sync_data(tsd); - return FALSE; - } - if(!DuplicateHandle(curr_proc, td->mutex_terminate, - curr_proc, &tsd->mutex_terminate, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - /* failed to duplicate the mutex, no point in continuing */ - destroy_thread_sync_data(tsd); - return FALSE; - } - if(!DuplicateHandle(curr_proc, td->event_terminate, - curr_proc, &tsd->event_terminate, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - /* failed to duplicate the event, no point in continuing */ - destroy_thread_sync_data(tsd); - return FALSE; - } + + tsd->port = port; +#ifdef CURLRES_IPV6 + DEBUGASSERT(hints); + tsd->hints = *hints; +#else + (void) hints; +#endif + + tsd->mtx = malloc(sizeof(curl_mutex_t)); + if (tsd->mtx == NULL) goto err_exit; + + Curl_mutex_init(tsd->mtx); + + tsd->sock_error = CURL_ASYNC_SUCCESS; + /* Copying hostname string because original can be destroyed by parent * thread during gethostbyname execution. */ tsd->hostname = strdup(hostname); - if(!tsd->hostname) { - /* Memory allocation failed */ - destroy_thread_sync_data(tsd); - return FALSE; - } - return TRUE; -} + if (!tsd->hostname) goto err_exit; -/* acquire resolver thread synchronization */ -static -BOOL acquire_thread_sync(struct thread_sync_data * tsd) -{ - /* is the thread initiator still waiting for us ? */ - if(WaitForSingleObject(tsd->mutex_waiting, 0) == WAIT_TIMEOUT) { - /* yes, it is */ - - /* Waiting access to event_terminate */ - if(WaitForSingleObject(tsd->mutex_terminate, INFINITE) != WAIT_OBJECT_0) { - /* Something went wrong - now just ignoring */ - } - else { - if(WaitForSingleObject(tsd->event_terminate, 0) != WAIT_TIMEOUT) { - /* Parent thread signaled us to terminate. - * This means that all data in conn->async is now destroyed - * and we cannot use it. - */ - } - else { - return TRUE; - } - } - } - return FALSE; -} + return 1; -/* release resolver thread synchronization */ -static -void release_thread_sync(struct thread_sync_data * tsd) -{ - ReleaseMutex(tsd->mutex_terminate); + err_exit: + /* Memory allocation failed */ + destroy_thread_sync_data(tsd); + return 0; } -#if defined(CURLRES_IPV4) /* - * 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 - * it. + * gethostbyname_thread() resolves a name and then exits. */ -static unsigned __stdcall gethostbyname_thread (void *arg) +static unsigned int CURL_STDCALL gethostbyname_thread (void *arg) { - struct connectdata *conn = (struct connectdata*) arg; - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - struct hostent *he; - int rc = 0; - - /* Duplicate the passed mutex and event handles. - * This allows us to use it even after the container gets destroyed - * due to a resolver timeout. - */ - struct thread_sync_data tsd = { 0,0,0,NULL }; + struct thread_sync_data *tsd = (struct thread_sync_data *)arg; - if(!init_thread_sync_data(td, conn->async.hostname, &tsd)) { - /* thread synchronization data initialization failed */ - return (unsigned)-1; - } - - conn->async.status = NO_DATA; /* pending status */ - SET_SOCKERRNO(conn->async.status); + tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port); - /* Signaling that we have initialized all copies of data and handles we - need */ - SetEvent(td->event_thread_started); + if (!tsd->res) { + tsd->sock_error = SOCKERRNO; + if (tsd->sock_error == 0) + tsd->sock_error = ENOMEM; + } - he = gethostbyname (tsd.hostname); + Curl_mutex_acquire(tsd->mtx); + tsd->done = 1; + Curl_mutex_release(tsd->mtx); - /* 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); + return 0; +} - /* Mark that we have obtained the information, and that we are calling - * back with it. */ - SetEvent(td->event_resolved); - if(ai) { - rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, ai); - } - else { - rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL); - } - release_thread_sync(&tsd); - } +static int getaddrinfo_complete(struct connectdata *conn) +{ + struct thread_sync_data *tsd = conn_thread_sync_data(conn); + int rc; - /* clean up */ - destroy_thread_sync_data(&tsd); + rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res); + /* The tsd->res structure has been copied to async.dns and perhaps the DNS cache. + Set our copy to NULL so destroy_thread_sync_data doesn't free it. + */ + tsd->res = NULL; - return (rc); - /* An implicit _endthreadex() here */ + return rc; } -#elif defined(CURLRES_IPV6) + +#if defined(HAVE_GETADDRINFO) /* - * getaddrinfo_thread() resolves a name, calls Curl_addrinfo_callback and then - * exits. + * getaddrinfo_thread() resolves a name and then exits. * * For builds without ARES, but with ENABLE_IPV6, create a resolver thread * and wait on it. */ -static unsigned __stdcall getaddrinfo_thread (void *arg) +static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg) { - struct connectdata *conn = (struct connectdata*) arg; - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - Curl_addrinfo *res; + struct thread_sync_data *tsd = (struct thread_sync_data*)arg; char service [NI_MAXSERV]; - int rc; - struct addrinfo hints = td->hints; - - /* Duplicate the passed mutex handle. - * This allows us to use it even after the container gets destroyed - * due to a resolver timeout. - */ - struct thread_sync_data tsd = { 0,0,0,NULL }; - - if(!init_thread_sync_data(td, conn->async.hostname, &tsd)) { - /* thread synchronization data initialization failed */ - return -1; - } - - itoa(conn->async.port, service, 10); - - conn->async.status = NO_DATA; /* pending status */ - SET_SOCKERRNO(conn->async.status); + int rc; - /* Signaling that we have initialized all copies of data and handles we - need */ - SetEvent(td->event_thread_started); + snprintf(service, sizeof(service), "%d", tsd->port); - rc = Curl_getaddrinfo_ex(tsd.hostname, service, &hints, &res); + rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res); - /* is parent thread waiting for us and are we able to access conn members? */ - if(acquire_thread_sync(&tsd)) { - /* Mark that we have obtained the information, and that we are calling - back with it. */ - SetEvent(td->event_resolved); - - if(rc == 0) { - rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, res); - } - else { - rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL); - } - release_thread_sync(&tsd); + if (rc != 0) { + tsd->sock_error = SOCKERRNO; + if (tsd->sock_error == 0) + tsd->sock_error = ENOMEM; } - /* clean up */ - destroy_thread_sync_data(&tsd); + Curl_mutex_acquire(tsd->mtx); + tsd->done = 1; + Curl_mutex_release(tsd->mtx); - return (rc); - /* An implicit _endthreadex() here */ + return 0; } -#endif + +#endif /* HAVE_GETADDRINFO */ /* * Curl_destroy_thread_data() cleans up async resolver data and thread handle. @@ -349,39 +266,15 @@ void Curl_destroy_thread_data (struct Curl_async *async) if(async->os_specific) { struct thread_data *td = (struct thread_data*) async->os_specific; - curl_socket_t sock = td->dummy_sock; - - if(td->mutex_terminate && td->event_terminate) { - /* Signaling resolver thread to terminate */ - if(WaitForSingleObject(td->mutex_terminate, INFINITE) == WAIT_OBJECT_0) { - SetEvent(td->event_terminate); - ReleaseMutex(td->mutex_terminate); - } - else { - /* Something went wrong - just ignoring it */ - } - } - - if(td->mutex_terminate) - CloseHandle(td->mutex_terminate); - if(td->event_terminate) - CloseHandle(td->event_terminate); - if(td->event_thread_started) - CloseHandle(td->event_thread_started); - if(sock != CURL_SOCKET_BAD) - sclose(sock); - - /* destroy the synchronization objects */ - if(td->mutex_waiting) - CloseHandle(td->mutex_waiting); - td->mutex_waiting = NULL; - if(td->event_resolved) - CloseHandle(td->event_resolved); - - if(td->thread_hnd) - CloseHandle(td->thread_hnd); + if (td->dummy_sock != CURL_SOCKET_BAD) + sclose(td->dummy_sock); + if (td->thread_hnd != curl_thread_t_null) + Curl_thread_join(&td->thread_hnd); + + destroy_thread_sync_data(&td->tsd); + free(async->os_specific); } async->hostname = NULL; @@ -399,114 +292,58 @@ static bool init_resolve_thread (struct connectdata *conn, const struct addrinfo *hints) { struct thread_data *td = calloc(1, sizeof(struct thread_data)); - HANDLE thread_and_event[2] = {0}; + int err = ENOMEM; - if(!td) { - SET_ERRNO(ENOMEM); - return FALSE; - } - - Curl_safefree(conn->async.hostname); - conn->async.hostname = strdup(hostname); - if(!conn->async.hostname) { - free(td); - SET_ERRNO(ENOMEM); - return FALSE; - } + conn->async.os_specific = (void*) td; + if(!td) + goto err_exit; conn->async.port = port; conn->async.done = FALSE; conn->async.status = 0; conn->async.dns = NULL; - conn->async.os_specific = (void*) td; td->dummy_sock = CURL_SOCKET_BAD; + td->thread_hnd = curl_thread_t_null; - /* Create the mutex used to inform the resolver thread that we're - * still waiting, and take initial ownership. - */ - td->mutex_waiting = CreateMutex(NULL, TRUE, NULL); - if(td->mutex_waiting == NULL) { - Curl_destroy_thread_data(&conn->async); - SET_ERRNO(EAGAIN); - return FALSE; - } + if (!init_thread_sync_data(&td->tsd, hostname, port, hints)) + goto err_exit; - /* Create the event that the thread uses to inform us that it's - * done resolving. Do not signal it. - */ - td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL); - if(td->event_resolved == NULL) { - Curl_destroy_thread_data(&conn->async); - SET_ERRNO(EAGAIN); - return FALSE; - } - /* Create the mutex used to serialize access to event_terminated - * between us and resolver thread. - */ - td->mutex_terminate = CreateMutex(NULL, FALSE, NULL); - if(td->mutex_terminate == NULL) { - Curl_destroy_thread_data(&conn->async); - SET_ERRNO(EAGAIN); - return FALSE; - } - /* Create the event used to signal thread that it should terminate. - */ - td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL); - if(td->event_terminate == NULL) { - Curl_destroy_thread_data(&conn->async); - SET_ERRNO(EAGAIN); - return FALSE; - } - /* Create the event used by thread to inform it has initialized its own data. - */ - td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL); - if(td->event_thread_started == NULL) { - Curl_destroy_thread_data(&conn->async); - SET_ERRNO(EAGAIN); - return FALSE; - } + Curl_safefree(conn->async.hostname); + conn->async.hostname = strdup(hostname); + if(!conn->async.hostname) + goto err_exit; -#ifdef _WIN32_WCE - td->thread_hnd = (HANDLE) CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) THREAD_FUNC, - conn, 0, &td->thread_id); -#else - td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC, - conn, 0, &td->thread_id); +#ifdef WIN32 + /* This socket is only to keep Curl_resolv_fdset() and select() happy; + * should never become signalled for read since it's unbound but + * Windows needs at least 1 socket in select(). + */ + td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (td->dummy_sock == CURL_SOCKET_BAD) + goto err_exit; #endif -#ifdef CURLRES_IPV6 - DEBUGASSERT(hints); - td->hints = *hints; +#ifdef HAVE_GETADDRINFO + td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd); #else - (void) hints; + td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd); #endif if(!td->thread_hnd) { #ifndef _WIN32_WCE - SET_ERRNO(errno); + err = errno; #endif - Curl_destroy_thread_data(&conn->async); - return FALSE; + goto err_exit; } - /* Waiting until the thread will initialize its data or it will exit due errors. - */ - thread_and_event[0] = td->thread_hnd; - thread_and_event[1] = td->event_thread_started; - if(WaitForMultipleObjects(sizeof(thread_and_event) / - sizeof(thread_and_event[0]), - (const HANDLE*)thread_and_event, FALSE, - INFINITE) == WAIT_FAILED) { - /* The resolver thread has been created, - * most probably it works now - ignoring this "minor" error - */ - } - /* This socket is only to keep Curl_resolv_fdset() and select() happy; - * should never become signalled for read/write since it's unbound but - * Windows needs atleast 1 socket in select(). - */ - td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); + return TRUE; + + err_exit: + Curl_destroy_thread_data(&conn->async); + + SET_ERRNO(err); + + return FALSE; } @@ -523,84 +360,33 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, { struct thread_data *td = (struct thread_data*) conn->async.os_specific; struct SessionHandle *data = conn->data; - long timeout; - DWORD status; CURLcode rc; DEBUGASSERT(conn && td); - /* now, see if there's a connect timeout or a regular timeout to - use instead of the default one */ - timeout = - conn->data->set.connecttimeout ? conn->data->set.connecttimeout : - conn->data->set.timeout ? conn->data->set.timeout : - CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */ - /* wait for the thread to resolve the name */ - status = WaitForSingleObject(td->event_resolved, timeout); - - /* mark that we are now done waiting */ - ReleaseMutex(td->mutex_waiting); - - /* close our handle to the mutex, no point in hanging on to it */ - CloseHandle(td->mutex_waiting); - td->mutex_waiting = NULL; - - /* close the event handle, it's useless now */ - CloseHandle(td->event_resolved); - td->event_resolved = NULL; - - /* has the resolver thread succeeded in resolving our query ? */ - if(status == WAIT_OBJECT_0) { - /* wait for the thread to exit, it's in the callback sequence */ - if(WaitForSingleObject(td->thread_hnd, 5000) == WAIT_TIMEOUT) { - TerminateThread(td->thread_hnd, 0); - conn->async.done = TRUE; - td->thread_status = (DWORD)-1; - } - else { - /* Thread finished before timeout; propagate Winsock error to this - * thread. 'conn->async.done = TRUE' is set in - * Curl_addrinfo4/6_callback(). - */ - SET_SOCKERRNO(conn->async.status); - GetExitCodeThread(td->thread_hnd, &td->thread_status); - } - } - else { - conn->async.done = TRUE; - td->thread_status = (DWORD)-1; + if (Curl_thread_join(&td->thread_hnd)) { + rc = getaddrinfo_complete(conn); + } else { + DEBUGASSERT(0); } + conn->async.done = TRUE; + if(entry) *entry = conn->async.dns; - rc = CURLE_OK; - if(!conn->async.dns) { /* a name was not resolved */ - 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(conn->async.done) { - if(conn->bits.httpproxy) { - failf(data, "Could not resolve proxy: %s; %s", - conn->proxy.dispname, Curl_strerror(conn, conn->async.status)); - rc = CURLE_COULDNT_RESOLVE_PROXY; - } - else { - failf(data, "Could not resolve host: %s; %s", - conn->host.name, Curl_strerror(conn, conn->async.status)); - rc = CURLE_COULDNT_RESOLVE_HOST; - } - } - 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; + if (conn->bits.httpproxy) { + failf(data, "Could not resolve proxy: %s; %s", + conn->async.hostname, Curl_strerror(conn, conn->async.status)); + rc = CURLE_COULDNT_RESOLVE_PROXY; + } else { + failf(data, "Could not resolve host: %s; %s", + conn->async.hostname, Curl_strerror(conn, conn->async.status)); + rc = CURLE_COULDNT_RESOLVE_HOST; } - else - rc = CURLE_OPERATION_TIMEDOUT; } Curl_destroy_thread_data(&conn->async); @@ -620,19 +406,57 @@ CURLcode Curl_is_resolved(struct connectdata *conn, struct Curl_dns_entry **entry) { struct SessionHandle *data = conn->data; - + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + int done = 0; + *entry = NULL; - if(conn->async.done) { - /* we're done */ + if (!td) { + DEBUGASSERT(td); + return CURLE_COULDNT_RESOLVE_HOST; + } + + Curl_mutex_acquire(td->tsd.mtx); + done = td->tsd.done; + Curl_mutex_release(td->tsd.mtx); + + if (done) { + getaddrinfo_complete(conn); + if (td->poll_interval != 0) + Curl_expire(conn->data, 0); Curl_destroy_thread_data(&conn->async); + if(!conn->async.dns) { failf(data, "Could not resolve host: %s; %s", conn->host.name, Curl_strerror(conn, conn->async.status)); return CURLE_COULDNT_RESOLVE_HOST; } *entry = conn->async.dns; + } else { + /* poll for name lookup done with exponential backoff up to 250ms */ + int elapsed; + + elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle); + if (elapsed < 0) { + elapsed = 0; + } + + if (td->poll_interval == 0) { + /* Start at 1ms poll interval */ + td->poll_interval = 1; + } else if (elapsed >= td->interval_end) { + /* Back-off exponentially if last interval expired */ + td->poll_interval *= 2; + } + + if (td->poll_interval > 250) + td->poll_interval = 250; + + td->interval_end = elapsed + td->poll_interval; + + Curl_expire(conn->data, td->poll_interval); } + return CURLE_OK; } @@ -645,18 +469,18 @@ int Curl_resolv_getsock(struct connectdata *conn, if(td && td->dummy_sock != CURL_SOCKET_BAD) { if(numsocks) { - /* return one socket waiting for writable, even though this is just + /* return one socket waiting for readable, even though this is just a dummy */ socks[0] = td->dummy_sock; - return GETSOCK_WRITESOCK(0); + return GETSOCK_READSOCK(0); } } return 0; } -#ifdef CURLRES_IPV4 +#if !defined(HAVE_GETADDRINFO) /* - * Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6. + * Curl_getaddrinfo() - for platforms without getaddrinfo */ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, const char *hostname, @@ -667,7 +491,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, struct SessionHandle *data = conn->data; struct in_addr in; - *waitp = 0; /* don't wait, we act synchronously */ + *waitp = 0; /* default to synchronous response */ if(Curl_inet_pton(AF_INET, hostname, &in) > 0) /* This is a dotted IP address 123.123.123.123-style */ @@ -675,27 +499,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, /* fire up a new resolver thread! */ if(init_resolve_thread(conn, hostname, port, NULL)) { - *waitp = TRUE; /* please wait for the response */ + *waitp = 1; /* expect asynchronous response */ return NULL; } /* fall-back to blocking version */ - infof(data, "init_resolve_thread() failed for %s; %s\n", - hostname, Curl_strerror(conn, ERRNO)); - - h = gethostbyname(hostname); - if(!h) { - infof(data, "gethostbyname(2) failed for %s:%d; %s\n", - hostname, port, Curl_strerror(conn, SOCKERRNO)); - return NULL; - } - return Curl_he2ai(h, port); + return Curl_ipv4_resolve_r(hostname, port); } -#endif /* CURLRES_IPV4 */ -#ifdef CURLRES_IPV6 +#else /* HAVE_GETADDRINFO */ + /* - * Curl_getaddrinfo() - for Windows threading IPv6 enabled + * Curl_getaddrinfo() - for getaddrinfo */ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, const char *hostname, @@ -706,11 +521,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, Curl_addrinfo *res; int error; char sbuf[NI_MAXSERV]; - int pf; + int pf = PF_INET; struct SessionHandle *data = conn->data; - *waitp = FALSE; /* default to synch response */ + *waitp = 0; /* default to synchronous response */ +#if !defined(CURLRES_IPV4) /* * Check if a limited name resolve has been requested. */ @@ -743,6 +559,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, sclose(s); } } +#endif /* !CURLRES_IPV4 */ memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; @@ -750,11 +567,11 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, #if 0 /* removed nov 8 2005 before 7.15.1 */ hints.ai_flags = AI_CANONNAME; #endif - itoa(port, sbuf, 10); + snprintf(sbuf, sizeof(sbuf), "%d", port); /* fire up a new resolver thread! */ if(init_resolve_thread(conn, hostname, port, &hints)) { - *waitp = TRUE; /* please wait for the response */ + *waitp = 1; /* expect asynchronous response */ return NULL; } @@ -770,5 +587,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, } return res; } -#endif /* CURLRES_IPV6 */ + +#endif /* HAVE_GETADDRINFO */ + #endif /* CURLRES_THREADED */ |