1 #ifndef HEADER_CURL_ASYN_H 2 #define HEADER_CURL_ASYN_H 3 /*************************************************************************** 4 * _ _ ____ _ 5 * Project ___| | | | _ \| | 6 * / __| | | | |_) | | 7 * | (__| |_| | _ <| |___ 8 * \___|\___/|_| \_\_____| 9 * 10 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 11 * 12 * This software is licensed as described in the file COPYING, which 13 * you should have received as part of this distribution. The terms 14 * are also available at https://curl.se/docs/copyright.html. 15 * 16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 * copies of the Software, and permit persons to whom the Software is 18 * furnished to do so, under the terms of the COPYING file. 19 * 20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 * KIND, either express or implied. 22 * 23 * SPDX-License-Identifier: curl 24 * 25 ***************************************************************************/ 26 27 #include "curl_setup.h" 28 #include "curl_addrinfo.h" 29 #include "httpsrr.h" 30 31 struct addrinfo; 32 struct hostent; 33 struct Curl_easy; 34 struct connectdata; 35 struct Curl_dns_entry; 36 37 #ifdef CURLRES_THREADED 38 #include "curl_threads.h" 39 40 /* Data for synchronization between resolver thread and its parent */ 41 struct thread_sync_data { 42 curl_mutex_t *mtx; 43 bool done; 44 int port; 45 char *hostname; /* hostname to resolve, Curl_async.hostname 46 duplicate */ 47 #ifndef CURL_DISABLE_SOCKETPAIR 48 struct Curl_easy *data; 49 curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */ 50 #endif 51 int sock_error; 52 struct Curl_addrinfo *res; 53 #ifdef HAVE_GETADDRINFO 54 struct addrinfo hints; 55 #endif 56 struct thread_data *td; /* for thread-self cleanup */ 57 }; 58 59 struct thread_data { 60 curl_thread_t thread_hnd; 61 unsigned int poll_interval; 62 timediff_t interval_end; 63 struct thread_sync_data tsd; 64 #if defined(USE_HTTPSRR) && defined(USE_ARES) 65 struct Curl_https_rrinfo hinfo; 66 ares_channel channel; 67 #endif 68 }; 69 70 #elif defined(CURLRES_ARES) /* CURLRES_THREADED */ 71 72 struct thread_data { 73 int num_pending; /* number of outstanding c-ares requests */ 74 struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares 75 parts */ 76 int last_status; 77 #ifndef HAVE_CARES_GETADDRINFO 78 struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ 79 #endif 80 #ifdef USE_HTTPSRR 81 struct Curl_https_rrinfo hinfo; 82 #endif 83 char hostname[1]; 84 }; 85 86 #endif /* CURLRES_ARES */ 87 88 #ifdef USE_ARES 89 #include <ares.h> 90 91 /* for HTTPS RR purposes as well */ 92 int Curl_ares_getsock(struct Curl_easy *data, 93 ares_channel channel, 94 curl_socket_t *socks); 95 int Curl_ares_perform(ares_channel channel, 96 timediff_t timeout_ms); 97 #endif 98 99 100 /* 101 * This header defines all functions in the internal asynch resolver interface. 102 * All asynch resolvers need to provide these functions. 103 * asyn-ares.c and asyn-thread.c are the current implementations of asynch 104 * resolver backends. 105 */ 106 107 /* 108 * Curl_resolver_global_init() 109 * 110 * Called from curl_global_init() to initialize global resolver environment. 111 * Returning anything else than CURLE_OK fails curl_global_init(). 112 */ 113 int Curl_resolver_global_init(void); 114 115 /* 116 * Curl_resolver_global_cleanup() 117 * Called from curl_global_cleanup() to destroy global resolver environment. 118 */ 119 void Curl_resolver_global_cleanup(void); 120 121 /* 122 * Curl_resolver_init() 123 * Called from curl_easy_init() -> Curl_open() to initialize resolver 124 * URL-state specific environment ('resolver' member of the UrlState 125 * structure). Should fill the passed pointer by the initialized handler. 126 * Returning anything else than CURLE_OK fails curl_easy_init() with the 127 * correspondent code. 128 */ 129 CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver); 130 131 /* 132 * Curl_resolver_cleanup() 133 * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver 134 * URL-state specific environment ('resolver' member of the UrlState 135 * structure). Should destroy the handler and free all resources connected to 136 * it. 137 */ 138 void Curl_resolver_cleanup(void *resolver); 139 140 /* 141 * Curl_resolver_duphandle() 142 * Called from curl_easy_duphandle() to duplicate resolver URL-state specific 143 * environment ('resolver' member of the UrlState structure). Should 144 * duplicate the 'from' handle and pass the resulting handle to the 'to' 145 * pointer. Returning anything else than CURLE_OK causes failed 146 * curl_easy_duphandle() call. 147 */ 148 CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, 149 void *from); 150 151 /* 152 * Curl_resolver_cancel(). 153 * 154 * It is called from inside other functions to cancel currently performing 155 * resolver request. Should also free any temporary resources allocated to 156 * perform a request. This never waits for resolver threads to complete. 157 * 158 * It is safe to call this when conn is in any state. 159 */ 160 void Curl_resolver_cancel(struct Curl_easy *data); 161 162 /* 163 * Curl_resolver_kill(). 164 * 165 * This acts like Curl_resolver_cancel() except it will block until any threads 166 * associated with the resolver are complete. This never blocks for resolvers 167 * that do not use threads. This is intended to be the "last chance" function 168 * that cleans up an in-progress resolver completely (before its owner is about 169 * to die). 170 * 171 * It is safe to call this when conn is in any state. 172 */ 173 void Curl_resolver_kill(struct Curl_easy *data); 174 175 /* Curl_resolver_getsock() 176 * 177 * This function is called from the multi_getsock() function. 'sock' is a 178 * pointer to an array to hold the file descriptors, with 'numsock' being the 179 * size of that array (in number of entries). This function is supposed to 180 * return bitmask indicating what file descriptors (referring to array indexes 181 * in the 'sock' array) to wait for, read/write. 182 */ 183 int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *sock); 184 185 /* 186 * Curl_resolver_is_resolved() 187 * 188 * Called repeatedly to check if a previous name resolve request has 189 * completed. It should also make sure to time-out if the operation seems to 190 * take too long. 191 * 192 * Returns normal CURLcode errors. 193 */ 194 CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, 195 struct Curl_dns_entry **dns); 196 197 /* 198 * Curl_resolver_wait_resolv() 199 * 200 * Waits for a resolve to finish. This function should be avoided since using 201 * this risk getting the multi interface to "hang". 202 * 203 * If 'entry' is non-NULL, make it point to the resolved dns entry 204 * 205 * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, 206 * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. 207 */ 208 CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, 209 struct Curl_dns_entry **dnsentry); 210 211 /* 212 * Curl_resolver_getaddrinfo() - when using this resolver 213 * 214 * Returns name information about the given hostname and port number. If 215 * successful, the 'hostent' is returned and the fourth argument will point to 216 * memory we need to free after use. That memory *MUST* be freed with 217 * Curl_freeaddrinfo(), nothing else. 218 * 219 * Each resolver backend must of course make sure to return data in the 220 * correct format to comply with this. 221 */ 222 struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, 223 const char *hostname, 224 int port, 225 int *waitp); 226 227 #ifndef CURLRES_ASYNCH 228 /* convert these functions if an asynch resolver is not used */ 229 #define Curl_resolver_cancel(x) Curl_nop_stmt 230 #define Curl_resolver_kill(x) Curl_nop_stmt 231 #define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST 232 #define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST 233 #define Curl_resolver_duphandle(x,y,z) CURLE_OK 234 #define Curl_resolver_init(x,y) CURLE_OK 235 #define Curl_resolver_global_init() CURLE_OK 236 #define Curl_resolver_global_cleanup() Curl_nop_stmt 237 #define Curl_resolver_cleanup(x) Curl_nop_stmt 238 #endif 239 240 #ifdef CURLRES_ASYNCH 241 #define Curl_resolver_asynch() 1 242 #else 243 #define Curl_resolver_asynch() 0 244 #endif 245 246 247 /********** end of generic resolver interface functions *****************/ 248 #endif /* HEADER_CURL_ASYN_H */ 249