Loading lib/hostip.c +41 −32 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ #include <setjmp.h> #endif #ifdef WIN32 #include <process.h> #endif #if (defined(NETWARE) && defined(__NOVELL_LIBC__)) #undef in_addr_t #define in_addr_t unsigned long Loading @@ -70,6 +74,7 @@ #include "hostip.h" #include "hash.h" #include "share.h" #include "strerror.h" #include "url.h" #define _MPRINTF_REPLACE /* use our functions only */ Loading Loading @@ -108,12 +113,8 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, char *hostname, int port, int *waitp); #ifndef ENABLE_IPV6 #if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \ defined(USE_THREADING_GETHOSTBYNAME) static struct hostent* pack_hostent(char** buf, struct hostent* orig); #endif #endif #ifdef USE_THREADING_GETHOSTBYNAME #ifdef DEBUG_THREADING_GETHOSTBYNAME Loading @@ -126,12 +127,11 @@ static void trace_it (const char *fmt, ...); #define TRACE(x) #endif static struct hostent* pack_hostent (char** buf, struct hostent* orig); static bool init_gethostbyname_thread (struct connectdata *conn, const char *hostname, int port); struct thread_data { HANDLE thread_hnd; DWORD thread_id; unsigned thread_id; DWORD thread_status; }; #endif Loading Loading @@ -1319,8 +1319,10 @@ static void trace_it (const char *fmt, ...) static int do_trace = -1; va_list args; if (do_trace == -1) do_trace = getenv("CURL_TRACE") ? 1 : 0; if (do_trace == -1) { const char *env = getenv("CURL_TRACE"); do_trace = (env && atoi(env) > 0); } if (!do_trace) return; va_start (args, fmt); Loading @@ -1336,7 +1338,7 @@ static void trace_it (const char *fmt, ...) * * For builds without ARES/USE_IPV6, create a resolver thread and wait on it. */ static DWORD WINAPI gethostbyname_thread (void *arg) static unsigned __stdcall gethostbyname_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct hostent *he; Loading @@ -1355,19 +1357,21 @@ static DWORD WINAPI gethostbyname_thread (void *arg) TRACE(("Winsock-error %d, addr %s\n", conn->async.status, he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); return (rc); /* An implicit ExitThread() here */ /* An implicit _endthreadex() here */ } /* complementary of ares_destroy /* * destroy_thread_data() cleans up async resolver data. * Complementary of ares_destroy. */ static void destroy_thread_data (struct connectdata *conn) static void destroy_thread_data (struct Curl_async *async) { if (conn->async.hostname) free(conn->async.hostname); if (conn->async.os_specific) free(conn->async.os_specific); conn->async.hostname = NULL; conn->async.os_specific = NULL; if (async->hostname) free(async->hostname); if (async->os_specific) free(async->os_specific); async->hostname = NULL; async->os_specific = NULL; } /* Loading @@ -1377,14 +1381,13 @@ static void destroy_thread_data (struct connectdata *conn) static bool init_gethostbyname_thread (struct connectdata *conn, const char *hostname, int port) { struct thread_data *td = malloc(sizeof(*td)); struct thread_data *td = calloc(sizeof(*td), 1); if (!td) { SetLastError(ENOMEM); return (0); } memset (td, 0, sizeof(*td)); Curl_safefree(conn->async.hostname); conn->async.hostname = strdup(hostname); if (!conn->async.hostname) { Loading @@ -1399,11 +1402,12 @@ static bool init_gethostbyname_thread (struct connectdata *conn, conn->async.dns = NULL; conn->async.os_specific = (void*) td; td->thread_hnd = CreateThread(NULL, 0, gethostbyname_thread, td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, gethostbyname_thread, conn, 0, &td->thread_id); if (!td->thread_hnd) { TRACE(("CreateThread() failed; %lu\n", GetLastError())); destroy_thread_data(conn); SetLastError(errno); TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno))); destroy_thread_data(&conn->async); return (0); } return (1); Loading Loading @@ -1438,19 +1442,23 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout); if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) { /* Thread finished before timeout; propagate Winsock error to this thread */ /* Thread finished before timeout; propagate Winsock error to this thread. * 'conn->async.done = TRUE' is set in host_callback(). */ WSASetLastError(conn->async.status); GetExitCodeThread(td->thread_hnd, &td->thread_status); TRACE(("status %lu, thread-status %08lX\n", status, td->thread_status)); TRACE(("gethostbyname_thread() status %lu, thread retval %lu, ", status, td->thread_status)); } else { conn->async.done = TRUE; TerminateThread(td->thread_hnd, (DWORD)-1); td->thread_status = (DWORD)-1; TRACE(("gethostbyname_thread() timeout, ")); } TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n", td->thread_status, GetTickCount()-ticks)); TRACE(("elapsed %lu ms\n", GetTickCount()-ticks)); CloseHandle(td->thread_hnd); if(entry) *entry = conn->async.dns; Loading @@ -1464,13 +1472,14 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, rc = CURLE_OPERATION_TIMEDOUT; } else if(conn->async.done) { failf(data, "Could not resolve host: %s (code %lu)", conn->name, conn->async.status); failf(data, "Could not resolve host: %s; %s", conn->name, Curl_strerror(conn,conn->async.status)); rc = CURLE_COULDNT_RESOLVE_HOST; } else rc = CURLE_OPERATION_TIMEDOUT; destroy_thread_data(conn); destroy_thread_data(&conn->async); /* close the connection, since we can't return failure here without cleaning up this connection properly */ Curl_disconnect(conn); Loading @@ -1490,7 +1499,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn, if (conn->async.done) { /* we're done */ destroy_thread_data(conn); destroy_thread_data(&conn->async); if (!conn->async.dns) { TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n")); return CURLE_COULDNT_RESOLVE_HOST; Loading Loading
lib/hostip.c +41 −32 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ #include <setjmp.h> #endif #ifdef WIN32 #include <process.h> #endif #if (defined(NETWARE) && defined(__NOVELL_LIBC__)) #undef in_addr_t #define in_addr_t unsigned long Loading @@ -70,6 +74,7 @@ #include "hostip.h" #include "hash.h" #include "share.h" #include "strerror.h" #include "url.h" #define _MPRINTF_REPLACE /* use our functions only */ Loading Loading @@ -108,12 +113,8 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, char *hostname, int port, int *waitp); #ifndef ENABLE_IPV6 #if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \ defined(USE_THREADING_GETHOSTBYNAME) static struct hostent* pack_hostent(char** buf, struct hostent* orig); #endif #endif #ifdef USE_THREADING_GETHOSTBYNAME #ifdef DEBUG_THREADING_GETHOSTBYNAME Loading @@ -126,12 +127,11 @@ static void trace_it (const char *fmt, ...); #define TRACE(x) #endif static struct hostent* pack_hostent (char** buf, struct hostent* orig); static bool init_gethostbyname_thread (struct connectdata *conn, const char *hostname, int port); struct thread_data { HANDLE thread_hnd; DWORD thread_id; unsigned thread_id; DWORD thread_status; }; #endif Loading Loading @@ -1319,8 +1319,10 @@ static void trace_it (const char *fmt, ...) static int do_trace = -1; va_list args; if (do_trace == -1) do_trace = getenv("CURL_TRACE") ? 1 : 0; if (do_trace == -1) { const char *env = getenv("CURL_TRACE"); do_trace = (env && atoi(env) > 0); } if (!do_trace) return; va_start (args, fmt); Loading @@ -1336,7 +1338,7 @@ static void trace_it (const char *fmt, ...) * * For builds without ARES/USE_IPV6, create a resolver thread and wait on it. */ static DWORD WINAPI gethostbyname_thread (void *arg) static unsigned __stdcall gethostbyname_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct hostent *he; Loading @@ -1355,19 +1357,21 @@ static DWORD WINAPI gethostbyname_thread (void *arg) TRACE(("Winsock-error %d, addr %s\n", conn->async.status, he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); return (rc); /* An implicit ExitThread() here */ /* An implicit _endthreadex() here */ } /* complementary of ares_destroy /* * destroy_thread_data() cleans up async resolver data. * Complementary of ares_destroy. */ static void destroy_thread_data (struct connectdata *conn) static void destroy_thread_data (struct Curl_async *async) { if (conn->async.hostname) free(conn->async.hostname); if (conn->async.os_specific) free(conn->async.os_specific); conn->async.hostname = NULL; conn->async.os_specific = NULL; if (async->hostname) free(async->hostname); if (async->os_specific) free(async->os_specific); async->hostname = NULL; async->os_specific = NULL; } /* Loading @@ -1377,14 +1381,13 @@ static void destroy_thread_data (struct connectdata *conn) static bool init_gethostbyname_thread (struct connectdata *conn, const char *hostname, int port) { struct thread_data *td = malloc(sizeof(*td)); struct thread_data *td = calloc(sizeof(*td), 1); if (!td) { SetLastError(ENOMEM); return (0); } memset (td, 0, sizeof(*td)); Curl_safefree(conn->async.hostname); conn->async.hostname = strdup(hostname); if (!conn->async.hostname) { Loading @@ -1399,11 +1402,12 @@ static bool init_gethostbyname_thread (struct connectdata *conn, conn->async.dns = NULL; conn->async.os_specific = (void*) td; td->thread_hnd = CreateThread(NULL, 0, gethostbyname_thread, td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, gethostbyname_thread, conn, 0, &td->thread_id); if (!td->thread_hnd) { TRACE(("CreateThread() failed; %lu\n", GetLastError())); destroy_thread_data(conn); SetLastError(errno); TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno))); destroy_thread_data(&conn->async); return (0); } return (1); Loading Loading @@ -1438,19 +1442,23 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout); if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) { /* Thread finished before timeout; propagate Winsock error to this thread */ /* Thread finished before timeout; propagate Winsock error to this thread. * 'conn->async.done = TRUE' is set in host_callback(). */ WSASetLastError(conn->async.status); GetExitCodeThread(td->thread_hnd, &td->thread_status); TRACE(("status %lu, thread-status %08lX\n", status, td->thread_status)); TRACE(("gethostbyname_thread() status %lu, thread retval %lu, ", status, td->thread_status)); } else { conn->async.done = TRUE; TerminateThread(td->thread_hnd, (DWORD)-1); td->thread_status = (DWORD)-1; TRACE(("gethostbyname_thread() timeout, ")); } TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n", td->thread_status, GetTickCount()-ticks)); TRACE(("elapsed %lu ms\n", GetTickCount()-ticks)); CloseHandle(td->thread_hnd); if(entry) *entry = conn->async.dns; Loading @@ -1464,13 +1472,14 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, rc = CURLE_OPERATION_TIMEDOUT; } else if(conn->async.done) { failf(data, "Could not resolve host: %s (code %lu)", conn->name, conn->async.status); failf(data, "Could not resolve host: %s; %s", conn->name, Curl_strerror(conn,conn->async.status)); rc = CURLE_COULDNT_RESOLVE_HOST; } else rc = CURLE_OPERATION_TIMEDOUT; destroy_thread_data(conn); destroy_thread_data(&conn->async); /* close the connection, since we can't return failure here without cleaning up this connection properly */ Curl_disconnect(conn); Loading @@ -1490,7 +1499,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn, if (conn->async.done) { /* we're done */ destroy_thread_data(conn); destroy_thread_data(&conn->async); if (!conn->async.dns) { TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n")); return CURLE_COULDNT_RESOLVE_HOST; Loading