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