From 7de2f9271c68c10ee7057c10741b0406bca6c156 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Jan 2011 00:10:35 +0100 Subject: [PATCH] async resolvers: further cleanups asyn-ares.c and asyn-thread.c are two separate backends that implement the same (internal) async resolver API for libcurl to use. Backend is specified at build time. The internal resolver API is defined in asyn.h for asynch resolvers. --- lib/Makefile.inc | 21 ++-- lib/{hostares.c => asyn-ares.c} | 45 ++++---- lib/{hostthre.c => asyn-thread.c} | 49 +++++---- lib/asyn.h | 169 ++++++++++++++++++++++++++++++ lib/connect.c | 2 +- lib/ftp.c | 6 +- lib/hostasyn.c | 39 +++++++ lib/hostip.c | 4 +- lib/hostip.h | 70 +------------ lib/hostsyn.c | 102 ------------------ lib/multi.c | 4 +- lib/socks.c | 4 +- lib/transfer.c | 4 +- lib/url.c | 78 +++----------- lib/url.h | 4 +- 15 files changed, 302 insertions(+), 299 deletions(-) rename lib/{hostares.c => asyn-ares.c} (92%) rename lib/{hostthre.c => asyn-thread.c} (91%) create mode 100644 lib/asyn.h diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 0e77b68d6..04285b533 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -15,14 +15,14 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \ content_encoding.c share.c http_digest.c md4.c md5.c curl_rand.c \ http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \ - hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \ - inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \ - strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \ - socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c \ - curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c \ - warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c\ - gopher.c axtls.c idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c \ - non-ascii.c + hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \ + select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \ + qssl.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ + curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \ + pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \ + curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \ + idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \ + asyn-ares.c asyn-thread.c HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ @@ -36,6 +36,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \ tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \ curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h \ curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h \ - warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \ - gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h - + warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \ + gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h diff --git a/lib/hostares.c b/lib/asyn-ares.c similarity index 92% rename from lib/hostares.c rename to lib/asyn-ares.c index cc60016e1..6b71e0384 100644 --- a/lib/hostares.c +++ b/lib/asyn-ares.c @@ -62,6 +62,8 @@ /*********************************************************************** * Only for ares-enabled builds + * And only for functions that fulfill the asynch resolver backend API + * as defined in asyn.h, nothing else belongs in this file! **********************************************************************/ #ifdef CURLRES_ARES @@ -180,10 +182,11 @@ int Curl_resolver_duphandle(void **to, void *from) } static void destroy_async_data (struct Curl_async *async); + /* * Cancel all possibly still on-going resolves for this connection. */ -void Curl_async_cancel(struct connectdata *conn) +void Curl_resolver_cancel(struct connectdata *conn) { if( conn && conn->data && conn->data->state.resolver ) ares_cancel((ares_channel)conn->data->state.resolver); @@ -214,7 +217,7 @@ static void destroy_async_data (struct Curl_async *async) } /* - * Curl_resolv_fdset() is called when someone from the outside world (using + * Curl_resolver_fdset() is called when someone from the outside world (using * curl_multi_fdset()) wants to get our fd_set setup and we're talking with * ares. The caller must make sure that this function is only called when we * have a working ares channel. @@ -222,9 +225,9 @@ static void destroy_async_data (struct Curl_async *async) * Returns: CURLE_OK always! */ -int Curl_resolv_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) +int Curl_resolver_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) { struct timeval maxtime; @@ -309,14 +312,14 @@ static int waitperform(struct connectdata *conn, int timeout_ms) } /* - * Curl_is_resolved() is called repeatedly to check if a previous name resolve - * request has completed. It should also make sure to time-out if the - * operation seems to take too long. + * Curl_resolver_is_resolved() is called repeatedly to check if a previous + * name resolve request has completed. It should also make sure to time-out if + * the operation seems to take too long. * * Returns normal CURLcode errors. */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns) +CURLcode Curl_resolver_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns) { struct SessionHandle *data = conn->data; struct ResolverResults *res = (struct ResolverResults *) @@ -344,16 +347,18 @@ CURLcode Curl_is_resolved(struct connectdata *conn, } /* - * Curl_wait_for_resolv() waits for a resolve to finish. This function should - * be avoided since using this risk getting the multi interface to "hang". + * Curl_resolver_wait_resolv() + * + * waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". * * If 'entry' is non-NULL, make it point to the resolved dns entry * * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and * CURLE_OPERATION_TIMEDOUT if a time-out occurred. */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry) { CURLcode rc=CURLE_OK; struct SessionHandle *data = conn->data; @@ -388,7 +393,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, timeout_ms = 1000; waitperform(conn, timeout_ms); - Curl_is_resolved(conn,&temp_entry); + Curl_resolver_is_resolved(conn,&temp_entry); if(conn->async.done) break; @@ -507,17 +512,17 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */ } /* - * Curl_getaddrinfo() - when using ares + * Curl_resolver_getaddrinfo() - when using ares * * Returns name information about the given hostname and port number. If * successful, the 'hostent' is returned and the forth argument will point to * memory we need to free after use. That memory *MUST* be freed with * Curl_freeaddrinfo(), nothing else. */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) { char *bufp; struct SessionHandle *data = conn->data; diff --git a/lib/hostthre.c b/lib/asyn-thread.c similarity index 91% rename from lib/hostthre.c rename to lib/asyn-thread.c index 2313546dd..a3cd4d896 100644 --- a/lib/hostthre.c +++ b/lib/asyn-thread.c @@ -144,10 +144,11 @@ int Curl_resolver_duphandle(void **to, void *from) } static void destroy_async_data(struct Curl_async *); + /* * Cancel all possibly still on-going resolves for this connection. */ -void Curl_async_cancel(struct connectdata *conn) +void Curl_resolver_cancel(struct connectdata *conn) { destroy_async_data(&conn->async); } @@ -374,7 +375,7 @@ static bool init_resolve_thread (struct connectdata *conn, goto err_exit; #ifdef WIN32 - /* This socket is only to keep Curl_resolv_fdset() and select() happy; + /* This socket is only to keep Curl_resolver_fdset() and select() happy; * should never become signalled for read since it's unbound but * Windows needs at least 1 socket in select(). */ @@ -408,15 +409,17 @@ static bool init_resolve_thread (struct connectdata *conn, /* - * Curl_wait_for_resolv() waits for a resolve to finish. This function should - * be avoided since using this risk getting the multi interface to "hang". + * Curl_resolver_wait_resolv() + * + * waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". * * If 'entry' is non-NULL, make it point to the resolved dns entry * * This is the version for resolves-in-a-thread. */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry) { struct thread_data *td = (struct thread_data*) conn->async.os_specific; struct SessionHandle *data = conn->data; @@ -458,12 +461,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, } /* - * Curl_is_resolved() is called repeatedly to check if a previous name resolve - * request has completed. It should also make sure to time-out if the - * operation seems to take too long. + * Curl_resolver_is_resolved() is called repeatedly to check if a previous + * name resolve request has completed. It should also make sure to time-out if + * the operation seems to take too long. */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **entry) +CURLcode Curl_resolver_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; @@ -513,9 +516,9 @@ CURLcode Curl_is_resolved(struct connectdata *conn, return CURLE_OK; } -int Curl_resolv_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) +int Curl_resolver_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) { const struct thread_data *td = (const struct thread_data *) conn->async.os_specific; @@ -535,10 +538,10 @@ int Curl_resolv_getsock(struct connectdata *conn, /* * Curl_getaddrinfo() - for platforms without getaddrinfo */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) { struct in_addr in; @@ -561,12 +564,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, #else /* !HAVE_GETADDRINFO */ /* - * Curl_getaddrinfo() - for getaddrinfo + * Curl_resolver_getaddrinfo() - for getaddrinfo */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) { struct addrinfo hints; Curl_addrinfo *res; diff --git a/lib/asyn.h b/lib/asyn.h new file mode 100644 index 000000000..801ae79c4 --- /dev/null +++ b/lib/asyn.h @@ -0,0 +1,169 @@ +#ifndef HEADER_CURL_ASYN_H +#define HEADER_CURL_ASYN_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , 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. + * + * 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 + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "setup.h" +#include "curl_addrinfo.h" + +struct addrinfo; +struct hostent; +struct SessionHandle; +struct connectdata; +struct Curl_dns_entry; + +/* + * This header defines all functions in the internal asynch resolver interface. + * All asynch resolvers need to provide these functions. + * asyn-ares.c and asyn-thread.c are the current implementations of asynch + * resolver backends. + */ + +/* + * Curl_resolver_global_init() + * + * Called from curl_global_init() to initialize global resolver environment. + * Returning anything else than CURLE_OK fails curl_global_init(). + */ +int Curl_resolver_global_init(void); + +/* + * Curl_resolver_global_cleanup() + * Called from curl_global_cleanup() to destroy global resolver environment. + */ +void Curl_resolver_global_cleanup(void); + +/* + * Curl_resolver_init() + * Called from curl_easy_init() -> Curl_open() to initialize resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Should fill the passed pointer by the initialized handler. + * Returning anything else than CURLE_OK fails curl_easy_init() with the + * correspondent code. + */ +int Curl_resolver_init(void **resolver); + +/* + * Curl_resolver_cleanup() + * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Should destroy the handler and free all resources connected to + * it. + */ +void Curl_resolver_cleanup(void *resolver); + +/* + * Curl_resolver_duphandle() + * Called from curl_easy_duphandle() to duplicate resolver URL-state specific + * environment ('resolver' member of the UrlState structure). Should + * duplicate the 'from' handle and pass the resulting handle to the 'to' + * pointer. Returning anything else than CURLE_OK causes failed + * curl_easy_duphandle() call. + */ +int Curl_resolver_duphandle(void **to, void *from); + +/* + * Curl_resolver_cancel(). + * + * It is called from inside other functions to cancel currently performing + * resolver request. Should also free any temporary resources allocated to + * perform a request. + */ +void Curl_resolver_cancel(struct connectdata *conn); + +/* Curl_resolver_getsock() + * + * This function is called from the multi_getsock() function. 'sock' is a + * pointer to an array to hold the file descriptors, with 'numsock' being the + * size of that array (in number of entries). This function is supposed to + * return bitmask indicating what file descriptors (referring to array indexes + * in the 'sock' array) to wait for, read/write. + */ +int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock, + int numsocks); + +/* + * Curl_resolver_is_resolved() + * + * Called repeatedly to check if a previous name resolve request has + * completed. It should also make sure to time-out if the operation seems to + * take too long. + * + * Returns normal CURLcode errors. + */ +CURLcode Curl_resolver_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns); + +/* + * Curl_resolver_wait_resolv() + * + * waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". + * + * If 'entry' is non-NULL, make it point to the resolved dns entry + * + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and + * CURLE_OPERATION_TIMEDOUT if a time-out occurred. + + */ +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **dnsentry); + +/* + * Curl_resolver_getaddrinfo() - when using this resolver + * + * Returns name information about the given hostname and port number. If + * successful, the 'hostent' is returned and the forth argument will point to + * memory we need to free after use. That memory *MUST* be freed with + * Curl_freeaddrinfo(), nothing else. + * + * Each resolver backend must of course make sure to return data in the + * correct format to comply with this. + */ +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp); + +#ifndef CURLRES_ASYNCH +/* convert these functions if an asynch resolver isn't used */ +#define Curl_resolver_cancel(x) +#define Curl_async_resolved(x,y) CURLE_OK +#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST +#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST +#define Curl_resolver_getsock(x,y,z) 0 +#define Curl_resolver_duphandle(x,y) CURLE_OK +#define Curl_resolver_init(x) CURLE_OK +#define Curl_resolver_global_init() CURLE_OK +#define Curl_resolver_global_cleanup() +#define Curl_resolver_cleanup(x) +#endif + +#ifdef CURLRES_ASYNCH +#define Curl_resolver_asynch() 1 +#else +#define Curl_resolver_asynch() 0 +#endif + + +/********** end of generic resolver interface functions *****************/ +#endif /* HEADER_CURL_ASYN_H */ diff --git a/lib/connect.c b/lib/connect.c index 69d84c359..e876e7641 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -324,7 +324,7 @@ static CURLcode bindlocal(struct connectdata *conn, rc = Curl_resolv(conn, dev, 0, &h); if(rc == CURLRESOLV_PENDING) - (void)Curl_wait_for_resolv(conn, &h); + (void)Curl_resolver_wait_resolv(conn, &h); conn->ip_version = ipver; if(h) { diff --git a/lib/ftp.c b/lib/ftp.c index 9be8ed997..c8180b8b1 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -840,7 +840,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, /* resolv ip/host to ip */ rc = Curl_resolv(conn, host, 0, &h); if(rc == CURLRESOLV_PENDING) - (void)Curl_wait_for_resolv(conn, &h); + (void)Curl_resolver_wait_resolv(conn, &h); if(h) { res = h->addr; /* when we return from this function, we can forget about this entry @@ -1656,7 +1656,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, if(rc == CURLRESOLV_PENDING) /* BLOCKING, ignores the return code but 'addr' will be NULL in case of failure */ - (void)Curl_wait_for_resolv(conn, &addr); + (void)Curl_resolver_wait_resolv(conn, &addr); connectport = (unsigned short)conn->port; /* we connect to the proxy's port */ @@ -1672,7 +1672,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, rc = Curl_resolv(conn, newhost, newport, &addr); if(rc == CURLRESOLV_PENDING) /* BLOCKING */ - (void)Curl_wait_for_resolv(conn, &addr); + (void)Curl_resolver_wait_resolv(conn, &addr); connectport = newport; /* we connect to the remote port */ diff --git a/lib/hostasyn.c b/lib/hostasyn.c index 5269c08dc..50f6b01fb 100644 --- a/lib/hostasyn.c +++ b/lib/hostasyn.c @@ -127,4 +127,43 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn, return rc; } +/* 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 code; + + if(conn->async.dns) { + conn->dns_entry = conn->async.dns; + conn->async.dns = NULL; + } + + code = Curl_setup_conn(conn, protocol_done); + + if(code) + /* 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 code; +} + +/* + * 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 */ diff --git a/lib/hostip.c b/lib/hostip.c index 3db5b4967..9dddc0c06 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -464,7 +464,7 @@ int Curl_resolv(struct connectdata *conn, /* the response to our resolve call will come asynchronously at a later time, good or bad */ /* First, check that we haven't received the info by now */ - result = Curl_is_resolved(conn, &dns); + result = Curl_resolver_is_resolved(conn, &dns); if(result) /* error detected */ return CURLRESOLV_ERROR; if(dns) diff --git a/lib/hostip.h b/lib/hostip.h index 5c9250991..15a84c467 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -25,6 +25,7 @@ #include "setup.h" #include "hash.h" #include "curl_addrinfo.h" +#include "asyn.h" #ifdef HAVE_SETJMP_H #include @@ -104,52 +105,6 @@ bool Curl_ipv6works(void); */ bool Curl_ipvalid(struct connectdata *conn); -/********* functions in the internal asynch resolver interface ****** */ - -/* - * Curl_resolver_global_init() - * - * Called from curl_global_init() to initialize global resolver environment. - * Returning anything else than CURLE_OK fails curl_global_init(). - */ -int Curl_resolver_global_init(void); - -/* - * Curl_resolver_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - */ -void Curl_resolver_global_cleanup(void); - -/* - * Curl_resolver_init() - * Called from curl_easy_init() -> Curl_open() to initialize resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Should fill the passed pointer by the initialized handler. - * Returning anything else than CURLE_OK fails curl_easy_init() with the - * correspondent code. - */ -int Curl_resolver_init(void **resolver); - -/* - * Curl_resolver_cleanup() - * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Should destroy the handler and free all resources connected to - * it. - */ -void Curl_resolver_cleanup(void *resolver); - -/* - * Curl_resolver_duphandle() - * Called from curl_easy_duphandle() to duplicate resolver URL-state specific - * environment ('resolver' member of the UrlState structure). Should - * duplicate the 'from' handle and pass the resulting handle to the 'to' - * pointer. Returning anything else than CURLE_OK causes failed - * curl_easy_duphandle() call. - */ -int Curl_resolver_duphandle(void **to, void *from); - -/********** end of generic resolver interface functions *****************/ /* * Curl_getaddrinfo() is the generic low-level name resolve API within this @@ -162,29 +117,6 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, int port, int *waitp); -#ifdef CURLRES_ASYNCH -/* - * Curl_async_cancel() is the generic low-level asynchronous name resolve API. - * It is called from inside other functions to cancel currently performing resolver - * request. Should also free any temporary resources allocated to perform a request. - */ -void Curl_async_cancel(struct connectdata *conn); -#endif - -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns); -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **dnsentry); - -/* Curl_resolv_getsock() is a generic function that exists in multiple - versions depending on what name resolve technology we've built to use. The - function is called from the multi_getsock() function. 'sock' is a pointer - to an array to hold the file descriptors, with 'numsock' being the size of - that array (in number of entries). This function is supposed to return - bitmask indicating what file descriptors (referring to array indexes in the - 'sock' array) to wait for, read/write. */ -int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock, - int numsocks); /* unlock a previously resolved dns entry */ void Curl_resolv_unlock(struct SessionHandle *data, diff --git a/lib/hostsyn.c b/lib/hostsyn.c index 01d028979..a5e97658e 100644 --- a/lib/hostsyn.c +++ b/lib/hostsyn.c @@ -72,107 +72,5 @@ **********************************************************************/ #ifdef CURLRES_SYNCH -/* - * Curl_resolver_global_init() - * Called from curl_global_init() to initialize global resolver environment. - * Does nothing here. - */ -int Curl_resolver_global_init(void) -{ - return CURLE_OK; -} - -/* - * Curl_resolver_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - * Does nothing here. - */ -void Curl_resolver_global_cleanup(void) -{ -} - -/* - * Curl_resolver_init() - * Called from curl_easy_init() -> Curl_open() to initialize resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. - */ -int Curl_resolver_init(void **resolver) -{ - (void)resolver; - return CURLE_OK; -} - -/* - * Curl_resolver_cleanup() - * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. - */ -void Curl_resolver_cleanup(void *resolver) -{ - (void)resolver; -} - -/* - * Curl_resolver_duphandle() - * Called from curl_easy_duphandle() to duplicate resolver URL state-specific - * environment ('resolver' member of the UrlState structure). Does nothing - * here. - */ -int Curl_resolver_duphandle(void **to, void *from) -{ - (void)to; - (void)from; - return CURLE_OK; -} - -/* - * Curl_wait_for_resolv() for synch-builds. Curl_resolv() can never return - * wait==TRUE, so this function will never be called. If it still gets called, - * we return failure at once. - * - * We provide this function only to allow multi.c to remain unaware if we are - * doing asynch resolves or not. - */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - (void)conn; - *entry=NULL; - return CURLE_COULDNT_RESOLVE_HOST; -} - -/* - * This function will never be called when synch-built. If it still gets - * called, we return failure at once. - * - * We provide this function only to allow multi.c to remain unaware if we are - * doing asynch resolves or not. - */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns) -{ - (void)conn; - *dns = NULL; - - return CURLE_COULDNT_RESOLVE_HOST; -} - -/* - * We just return OK, this function is never actually used for synch builds. - * It is present here to keep #ifdefs out from multi.c - */ - -int Curl_resolv_getsock(struct connectdata *conn, - curl_socket_t *sock, - int numsocks) -{ - (void)conn; - (void)sock; - (void)numsocks; - - return 0; /* no bits since we don't use any socks */ -} #endif /* truly sync */ diff --git a/lib/multi.c b/lib/multi.c index 40a341d29..650be6836 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -855,7 +855,7 @@ static int multi_getsock(struct Curl_one_easy *easy, return 0; case CURLM_STATE_WAITRESOLVE: - return Curl_resolv_getsock(easy->easy_conn, socks, numsocks); + return Curl_resolver_getsock(easy->easy_conn, socks, numsocks); case CURLM_STATE_PROTOCONNECT: return Curl_protocol_getsock(easy->easy_conn, socks, numsocks); @@ -1071,7 +1071,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct Curl_dns_entry *dns = NULL; /* check if we have the name resolved by now */ - easy->result = Curl_is_resolved(easy->easy_conn, &dns); + easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns); if(dns) { /* Update sockets here. Mainly because the socket(s) may have been diff --git a/lib/socks.c b/lib/socks.c index 08e4f66f6..5424d54af 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -175,7 +175,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, if(rc == CURLRESOLV_PENDING) /* ignores the return code, but 'dns' remains NULL on failure */ - (void)Curl_wait_for_resolv(conn, &dns); + (void)Curl_resolver_wait_resolv(conn, &dns); /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It @@ -603,7 +603,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, if(rc == CURLRESOLV_PENDING) { /* this requires that we're in "wait for resolve" state */ - code = Curl_wait_for_resolv(conn, &dns); + code = Curl_resolver_wait_resolv(conn, &dns); if(code != CURLE_OK) return code; } diff --git a/lib/transfer.c b/lib/transfer.c index 6a93bf059..ee817568c 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1995,7 +1995,7 @@ connect_host(struct SessionHandle *data, if((CURLE_OK == res) && async) { /* Now, if async is TRUE here, we need to wait for the name to resolve */ - res = Curl_wait_for_resolv(*conn, NULL); + res = Curl_resolver_wait_resolv(*conn, NULL); if(CURLE_OK == res) /* Resolved, continue with the connection */ res = Curl_async_resolved(*conn, &protocol_done); @@ -2047,7 +2047,7 @@ Curl_reconnect_request(struct connectdata **connp) if(async) { /* Now, if async is TRUE here, we need to wait for the name to resolve */ - result = Curl_wait_for_resolv(conn, NULL); + result = Curl_resolver_wait_resolv(conn, NULL); if(result) return result; diff --git a/lib/url.c b/lib/url.c index 592763f89..054b866ae 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2514,9 +2514,7 @@ static void conn_free(struct connectdata *conn) return; /* possible left-overs from the async name resolvers */ -#if defined(CURLRES_ASYNCH) - Curl_async_cancel(conn); -#endif + Curl_resolver_cancel(conn); /* close the SSL stuff before we close any sockets since they will/may write to the sockets */ @@ -2553,15 +2551,7 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->pend_pipe, NULL); Curl_llist_destroy(conn->done_pipe, NULL); - /* possible left-overs from the async name resolvers */ -#if defined(CURLRES_THREADED) - Curl_destroy_thread_data(&conn->async); -#elif defined(CURLRES_ASYNCH) - Curl_safefree(conn->async.hostname); - Curl_safefree(conn->async.os_specific); -#endif Curl_safefree(conn->localdev); - Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -2896,16 +2886,16 @@ ConnectionExists(struct SessionHandle *data, continue; } -#ifdef CURLRES_ASYNCH - /* ip_addr_str[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't re-use this connection */ - if(!check->ip_addr_str[0]) { - infof(data, - "Connection #%ld hasn't finished name resolve, can't reuse\n", - check->connectindex); - continue; + if(Curl_resolver_asynch()) { + /* ip_addr_str[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't re-use this connection */ + if(!check->ip_addr_str[0]) { + infof(data, + "Connection #%ld hasn't finished name resolve, can't reuse\n", + check->connectindex); + continue; + } } -#endif if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { /* Don't pick a connection that hasn't connected yet or that is going @@ -4633,7 +4623,7 @@ static void reuse_conn(struct connectdata *old_conn, * @param data The sessionhandle pointer * @param in_connect is set to the next connection data pointer * @param async is set TRUE when an async DNS resolution is pending - * @see setup_conn() + * @see Curl_setup_conn() * * *NOTE* this function assigns the conn->data pointer! */ @@ -4976,16 +4966,16 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } -/* setup_conn() is called after the name resolve initiated in +/* Curl_setup_conn() is called after the name resolve initiated in * create_conn() is all done. * - * setup_conn() also handles reused connections + * Curl_setup_conn() also handles reused connections * * conn->data MUST already have been setup fine (in create_conn) */ -static CURLcode setup_conn(struct connectdata *conn, - bool *protocol_done) +CURLcode Curl_setup_conn(struct connectdata *conn, + bool *protocol_done) { CURLcode result=CURLE_OK; struct SessionHandle *data = conn->data; @@ -5108,7 +5098,7 @@ CURLcode Curl_connect(struct SessionHandle *data, /* DNS resolution is done: that's either because this is a reused connection, in which case DNS was unnecessary, or because DNS really did finish already (synch resolver/fast async resolve) */ - code = setup_conn(*in_connect, protocol_done); + code = Curl_setup_conn(*in_connect, protocol_done); } } @@ -5122,38 +5112,6 @@ CURLcode Curl_connect(struct SessionHandle *data, return code; } -/* 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) -{ -#ifdef CURLRES_ASYNCH - CURLcode code; - - if(conn->async.dns) { - conn->dns_entry = conn->async.dns; - conn->async.dns = NULL; - } - - code = setup_conn(conn, protocol_done); - - if(code) - /* 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 code; -#else - (void)conn; - (void)protocol_done; - return CURLE_OK; -#endif -} - - CURLcode Curl_done(struct connectdata **connp, CURLcode status, /* an error if this is called after an error was detected */ @@ -5193,9 +5151,7 @@ CURLcode Curl_done(struct connectdata **connp, data->req.location = NULL; } -#if defined(CURLRES_ASYNCH) - Curl_async_cancel(conn); -#endif + Curl_resolver_cancel(conn); if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ diff --git a/lib/url.h b/lib/url.h index 241dc28c0..d6bb068c7 100644 --- a/lib/url.h +++ b/lib/url.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,6 +47,8 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); void Curl_safefree(void *ptr); +CURLcode Curl_setup_conn(struct connectdata *conn, + bool *protocol_done); /* create a connection cache */ struct conncache *Curl_mk_connc(int type, long amount);