1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23#include "setup.h" 24 25#include <string.h> 26 27#ifdef HAVE_SYS_SOCKET_H 28#include <sys/socket.h> 29#endif 30#ifdef HAVE_NETINET_IN_H 31#include <netinet/in.h> 32#endif 33#ifdef HAVE_NETDB_H 34#include <netdb.h> 35#endif 36#ifdef HAVE_ARPA_INET_H 37#include <arpa/inet.h> 38#endif 39#ifdef HAVE_STDLIB_H 40#include <stdlib.h> /* required for free() prototypes */ 41#endif 42#ifdef HAVE_UNISTD_H 43#include <unistd.h> /* for the close() proto */ 44#endif 45#ifdef __VMS 46#include <in.h> 47#include <inet.h> 48#include <stdlib.h> 49#endif 50 51#ifdef HAVE_PROCESS_H 52#include <process.h> 53#endif 54 55#include "urldata.h" 56#include "sendf.h" 57#include "hostip.h" 58#include "hash.h" 59#include "share.h" 60#include "strerror.h" 61#include "url.h" 62 63#define _MPRINTF_REPLACE /* use our functions only */ 64#include <curl/mprintf.h> 65 66#include "curl_memory.h" 67/* The last #include file should be: */ 68#include "memdebug.h" 69 70/*********************************************************************** 71 * Only for builds using asynchronous name resolves 72 **********************************************************************/ 73#ifdef CURLRES_ASYNCH 74 75/* 76 * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread() 77 * or getaddrinfo_thread() when we got the name resolved (or not!). 78 * 79 * If the status argument is CURL_ASYNC_SUCCESS, this function takes 80 * ownership of the Curl_addrinfo passed, storing the resolved data 81 * in the DNS cache. 82 * 83 * The storage operation locks and unlocks the DNS cache. 84 */ 85CURLcode Curl_addrinfo_callback(struct connectdata *conn, 86 int status, 87 struct Curl_addrinfo *ai) 88{ 89 struct Curl_dns_entry *dns = NULL; 90 CURLcode rc = CURLE_OK; 91 92 conn->async.status = status; 93 94 if(CURL_ASYNC_SUCCESS == status) { 95 if(ai) { 96 struct SessionHandle *data = conn->data; 97 98 if(data->share) 99 Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); 100 101 dns = Curl_cache_addr(data, ai, 102 conn->async.hostname, 103 conn->async.port); 104 if(!dns) { 105 /* failed to store, cleanup and return error */ 106 Curl_freeaddrinfo(ai); 107 rc = CURLE_OUT_OF_MEMORY; 108 } 109 110 if(data->share) 111 Curl_share_unlock(data, CURL_LOCK_DATA_DNS); 112 } 113 else { 114 rc = CURLE_OUT_OF_MEMORY; 115 } 116 } 117 118 conn->async.dns = dns; 119 120 /* Set async.done TRUE last in this function since it may be used multi- 121 threaded and once this is TRUE the other thread may read fields from the 122 async struct */ 123 conn->async.done = TRUE; 124 125 /* ipv4: The input hostent struct will be freed by ares when we return from 126 this function */ 127 return rc; 128} 129 130/* Call this function after Curl_connect() has returned async=TRUE and 131 then a successful name resolve has been received. 132 133 Note: this function disconnects and frees the conn data in case of 134 resolve failure */ 135CURLcode Curl_async_resolved(struct connectdata *conn, 136 bool *protocol_done) 137{ 138 CURLcode code; 139 140 if(conn->async.dns) { 141 conn->dns_entry = conn->async.dns; 142 conn->async.dns = NULL; 143 } 144 145 code = Curl_setup_conn(conn, protocol_done); 146 147 if(code) 148 /* We're not allowed to return failure with memory left allocated 149 in the connectdata struct, free those here */ 150 Curl_disconnect(conn, FALSE); /* close the connection */ 151 152 return code; 153} 154 155/* 156 * Curl_getaddrinfo() is the generic low-level name resolve API within this 157 * source file. There are several versions of this function - for different 158 * name resolve layers (selected at build-time). They all take this same set 159 * of arguments 160 */ 161Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, 162 const char *hostname, 163 int port, 164 int *waitp) 165{ 166 return Curl_resolver_getaddrinfo(conn, hostname, port, waitp); 167} 168 169#endif /* CURLRES_ASYNCH */ 170