• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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