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