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#ifdef HAVE_SYS_SOCKET_H 26#include <sys/socket.h> 27#endif 28#ifdef HAVE_NETINET_IN_H 29#include <netinet/in.h> 30#endif 31#ifdef HAVE_NETDB_H 32#include <netdb.h> 33#endif 34#ifdef HAVE_ARPA_INET_H 35#include <arpa/inet.h> 36#endif 37#ifdef HAVE_UNISTD_H 38#include <unistd.h> /* for the close() proto */ 39#endif 40#ifdef __VMS 41#include <in.h> 42#include <inet.h> 43#endif 44 45#ifdef HAVE_PROCESS_H 46#include <process.h> 47#endif 48 49#include "urldata.h" 50#include "sendf.h" 51#include "hostip.h" 52#include "hash.h" 53#include "share.h" 54#include "strerror.h" 55#include "url.h" 56 57#define _MPRINTF_REPLACE /* use our functions only */ 58#include <curl/mprintf.h> 59 60#include "curl_memory.h" 61/* The last #include file should be: */ 62#include "memdebug.h" 63 64/*********************************************************************** 65 * Only for builds using asynchronous name resolves 66 **********************************************************************/ 67#ifdef CURLRES_ASYNCH 68 69/* 70 * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread() 71 * or getaddrinfo_thread() when we got the name resolved (or not!). 72 * 73 * If the status argument is CURL_ASYNC_SUCCESS, this function takes 74 * ownership of the Curl_addrinfo passed, storing the resolved data 75 * in the DNS cache. 76 * 77 * The storage operation locks and unlocks the DNS cache. 78 */ 79CURLcode Curl_addrinfo_callback(struct connectdata *conn, 80 int status, 81 struct Curl_addrinfo *ai) 82{ 83 struct Curl_dns_entry *dns = NULL; 84 CURLcode rc = CURLE_OK; 85 86 conn->async.status = status; 87 88 if(CURL_ASYNC_SUCCESS == status) { 89 if(ai) { 90 struct SessionHandle *data = conn->data; 91 92 if(data->share) 93 Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); 94 95 dns = Curl_cache_addr(data, ai, 96 conn->async.hostname, 97 conn->async.port); 98 if(!dns) { 99 /* failed to store, cleanup and return error */ 100 Curl_freeaddrinfo(ai); 101 rc = CURLE_OUT_OF_MEMORY; 102 } 103 104 if(data->share) 105 Curl_share_unlock(data, CURL_LOCK_DATA_DNS); 106 } 107 else { 108 rc = CURLE_OUT_OF_MEMORY; 109 } 110 } 111 112 conn->async.dns = dns; 113 114 /* Set async.done TRUE last in this function since it may be used multi- 115 threaded and once this is TRUE the other thread may read fields from the 116 async struct */ 117 conn->async.done = TRUE; 118 119 /* ipv4: The input hostent struct will be freed by ares when we return from 120 this function */ 121 return rc; 122} 123 124/* Call this function after Curl_connect() has returned async=TRUE and 125 then a successful name resolve has been received. 126 127 Note: this function disconnects and frees the conn data in case of 128 resolve failure */ 129CURLcode Curl_async_resolved(struct connectdata *conn, 130 bool *protocol_done) 131{ 132 CURLcode code; 133 134 if(conn->async.dns) { 135 conn->dns_entry = conn->async.dns; 136 conn->async.dns = NULL; 137 } 138 139 code = Curl_setup_conn(conn, protocol_done); 140 141 if(code) 142 /* We're not allowed to return failure with memory left allocated 143 in the connectdata struct, free those here */ 144 Curl_disconnect(conn, FALSE); /* close the connection */ 145 146 return code; 147} 148 149/* 150 * Curl_getaddrinfo() is the generic low-level name resolve API within this 151 * source file. There are several versions of this function - for different 152 * name resolve layers (selected at build-time). They all take this same set 153 * of arguments 154 */ 155Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, 156 const char *hostname, 157 int port, 158 int *waitp) 159{ 160 return Curl_resolver_getaddrinfo(conn, hostname, port, waitp); 161} 162 163#endif /* CURLRES_ASYNCH */ 164