mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Constantine Sapuntzakis refactoring of async callbacks, allowing
removal of Curl_addrinfo_copy(), Curl_addrinfo6_callback(), and Curl_addrinfo4_callback()
This commit is contained in:
parent
5af20c70e4
commit
bfc4c33985
@ -304,6 +304,31 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ares_query_completed_cb() is the callback that ares will call when
|
||||||
|
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
||||||
|
* when using ares, is completed either successfully or with failure.
|
||||||
|
*/
|
||||||
|
static void ares_query_completed_cb(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)Curl_addrinfo_callback(arg, status, ai);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_getaddrinfo() - when using ares
|
* Curl_getaddrinfo() - when using ares
|
||||||
@ -369,7 +394,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||||
(ares_host_callback)Curl_addrinfo4_callback, conn);
|
(ares_host_callback)ares_query_completed_cb, conn);
|
||||||
|
|
||||||
*waitp = TRUE; /* please wait for the response */
|
*waitp = TRUE; /* please wait for the response */
|
||||||
}
|
}
|
||||||
|
@ -72,38 +72,27 @@
|
|||||||
* Only for builds using asynchronous name resolves
|
* Only for builds using asynchronous name resolves
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef CURLRES_ASYNCH
|
#ifdef CURLRES_ASYNCH
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addrinfo_callback() gets called by ares, gethostbyname_thread() or
|
* Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
|
||||||
* getaddrinfo_thread() when we got the name resolved (or not!).
|
* 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
|
* If the status argument is CURL_ASYNC_SUCCESS, this function takes
|
||||||
* address field since it might be freed when this function returns. This
|
* ownership of the Curl_addrinfo passed, storing the resolved data
|
||||||
* operation stores the resolved data in the DNS cache.
|
* 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.
|
* The storage operation locks and unlocks the DNS cache.
|
||||||
*/
|
*/
|
||||||
static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
|
CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
||||||
int status,
|
int status,
|
||||||
void *addr)
|
struct Curl_addrinfo *ai)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = (struct connectdata *)arg;
|
|
||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
CURLcode rc = CURLE_OK;
|
CURLcode rc = CURLE_OK;
|
||||||
|
|
||||||
conn->async.status = status;
|
conn->async.status = status;
|
||||||
|
|
||||||
if(CURL_ASYNC_SUCCESS == 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) {
|
if(ai) {
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
@ -138,35 +127,4 @@ static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
|
#endif /* CURLRES_ASYNCH */
|
||||||
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 */
|
|
||||||
|
18
lib/hostip.c
18
lib/hostip.c
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -712,20 +712,4 @@ struct curl_hash *Curl_mk_dnscache(void)
|
|||||||
return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
|
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 */
|
|
||||||
|
44
lib/hostip.h
44
lib/hostip.h
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -65,23 +65,10 @@
|
|||||||
#define CURLRES_IPV4
|
#define CURLRES_IPV4
|
||||||
#endif
|
#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
|
#ifndef CURLRES_ASYNCH
|
||||||
#define CURLRES_SYNCH
|
#define CURLRES_SYNCH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USE_LIBIDN
|
|
||||||
#define CURLRES_IDN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allocate enough memory to hold the full name information structs and
|
/* Allocate enough memory to hold the full name information structs and
|
||||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||||
* required for storing all possible aliases and IP numbers is according to
|
* required for storing all possible aliases and IP numbers is according to
|
||||||
@ -203,26 +190,15 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
|||||||
int line, const char *source);
|
int line, const char *source);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the callback function that is used when we build with asynch
|
/*
|
||||||
resolve, ipv4 */
|
* Curl_addrinfo_callback() is used when we build with any asynch specialty.
|
||||||
CURLcode Curl_addrinfo4_callback(void *arg,
|
* Handles end of async request processing. Inserts ai into hostcache when
|
||||||
int status,
|
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
* request completed wether successfull or failed.
|
||||||
int timeouts,
|
*/
|
||||||
#endif
|
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||||
struct hostent *hostent);
|
int status,
|
||||||
/* This is the callback function that is used when we build with asynch
|
Curl_addrinfo *ai);
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_printable_address() returns a printable version of the 1st address
|
* Curl_printable_address() returns a printable version of the 1st address
|
||||||
|
@ -75,20 +75,6 @@
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef CURLRES_IPV6
|
#ifdef CURLRES_IPV6
|
||||||
|
|
||||||
#ifndef CURLRES_ARES
|
|
||||||
#ifdef CURLRES_ASYNCH
|
|
||||||
/*
|
|
||||||
* Curl_addrinfo_copy() is used by the asynch callback to copy a given
|
|
||||||
* address. But this is an ipv6 build and then we don't copy the address, we
|
|
||||||
* just return the same pointer!
|
|
||||||
*/
|
|
||||||
Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port)
|
|
||||||
{
|
|
||||||
(void) port;
|
|
||||||
return (Curl_addrinfo*)orig;
|
|
||||||
}
|
|
||||||
#endif /* CURLRES_ASYNCH */
|
|
||||||
#endif /* CURLRES_ARES */
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
|
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
|
||||||
/* These are strictly for memory tracing and are using the same style as the
|
/* These are strictly for memory tracing and are using the same style as the
|
||||||
@ -249,5 +235,5 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif /* !USE_THREADING_GETADDRINFO && !CURLRES_ARES */
|
#endif /* !USE_THREADING_GETADDRINFO && !CURLRES_ARES */
|
||||||
#endif /* ipv6 */
|
#endif /* CURLRES_IPV6 */
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -219,7 +219,7 @@ void release_thread_sync(struct thread_sync_data * tsd)
|
|||||||
|
|
||||||
#if defined(CURLRES_IPV4)
|
#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.
|
* and then exits.
|
||||||
*
|
*
|
||||||
* For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on
|
* 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? */
|
/* is parent thread waiting for us and are we able to access conn members? */
|
||||||
if(acquire_thread_sync(&tsd)) {
|
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
|
/* Mark that we have obtained the information, and that we are calling
|
||||||
* back with it. */
|
* back with it. */
|
||||||
SetEvent(td->event_resolved);
|
SetEvent(td->event_resolved);
|
||||||
if(he) {
|
if(ai) {
|
||||||
rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
|
rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, ai);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = Curl_addrinfo4_callback(conn, SOCKERRNO, NULL);
|
rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL);
|
||||||
}
|
}
|
||||||
release_thread_sync(&tsd);
|
release_thread_sync(&tsd);
|
||||||
}
|
}
|
||||||
@ -276,7 +278,7 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
|
|||||||
#elif defined(CURLRES_IPV6)
|
#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.
|
* exits.
|
||||||
*
|
*
|
||||||
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
|
* 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);
|
SetEvent(td->event_resolved);
|
||||||
|
|
||||||
if(rc == 0) {
|
if(rc == 0) {
|
||||||
rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
|
rc = Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, res);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = Curl_addrinfo6_callback(conn, SOCKERRNO, NULL);
|
rc = Curl_addrinfo_callback(conn, SOCKERRNO, NULL);
|
||||||
}
|
}
|
||||||
release_thread_sync(&tsd);
|
release_thread_sync(&tsd);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user