1 #ifndef __HOSTIP_H
2 #define __HOSTIP_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) 1998 - 2008, 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 http://curl.haxx.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  * $Id: hostip.h,v 1.69 2008-11-06 17:19:57 yangtse Exp $
24  ***************************************************************************/
25 
26 #include "setup.h"
27 #include "hash.h"
28 #include "curl_addrinfo.h"
29 
30 #ifdef HAVE_SETJMP_H
31 #include <setjmp.h>
32 #endif
33 
34 #ifdef NETWARE
35 #undef in_addr_t
36 #define in_addr_t unsigned long
37 #endif
38 
39 /*
40  * Setup comfortable CURLRES_* defines to use in the host*.c sources.
41  */
42 
43 #ifdef USE_ARES
44 #include <ares_version.h>
45 #endif
46 
47 #ifdef USE_ARES
48 #define CURLRES_ASYNCH
49 #define CURLRES_ARES
50 #endif
51 
52 #ifdef USE_THREADING_GETHOSTBYNAME
53 #define CURLRES_ASYNCH
54 #define CURLRES_THREADED
55 #endif
56 
57 #ifdef USE_THREADING_GETADDRINFO
58 #define CURLRES_ASYNCH
59 #define CURLRES_THREADED
60 #endif
61 
62 #ifdef ENABLE_IPV6
63 #define CURLRES_IPV6
64 #else
65 #define CURLRES_IPV4
66 #endif
67 
68 #if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
69 #if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
70 /* If built for ipv4 and missing gethostbyname_r(), or if using async name
71    resolve, we need the Curl_addrinfo_copy() function (which itself needs the
72    Curl_he2ai() function)) */
73 #define CURLRES_ADDRINFO_COPY
74 #endif
75 #endif /* IPv4/ares-only */
76 
77 #ifndef CURLRES_ASYNCH
78 #define CURLRES_SYNCH
79 #endif
80 
81 #ifndef USE_LIBIDN
82 #define CURLRES_IDN
83 #endif
84 
85 /* Allocate enough memory to hold the full name information structs and
86  * everything. OSF1 is known to require at least 8872 bytes. The buffer
87  * required for storing all possible aliases and IP numbers is according to
88  * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
89  */
90 #define CURL_HOSTENT_SIZE 9000
91 
92 #define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
93                                     many seconds for a name resolve */
94 
95 #ifdef CURLRES_ARES
96 #define CURL_ASYNC_SUCCESS ARES_SUCCESS
97 #if ARES_VERSION >= 0x010500
98 /* c-ares 1.5.0 or later, the callback proto is modified */
99 #define HAVE_CARES_CALLBACK_TIMEOUTS 1
100 #endif
101 #else
102 #define CURL_ASYNC_SUCCESS CURLE_OK
103 #define ares_cancel(x) do {} while(0)
104 #define ares_destroy(x) do {} while(0)
105 #endif
106 
107 struct addrinfo;
108 struct hostent;
109 struct SessionHandle;
110 struct connectdata;
111 
112 /*
113  * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
114  * Global DNS cache is general badness. Do not use. This will be removed in
115  * a future version. Use the share interface instead!
116  *
117  * Returns a struct curl_hash pointer on success, NULL on failure.
118  */
119 struct curl_hash *Curl_global_host_cache_init(void);
120 void Curl_global_host_cache_dtor(void);
121 
122 struct Curl_dns_entry {
123   Curl_addrinfo *addr;
124   time_t timestamp;
125   long inuse;      /* use-counter, make very sure you decrease this
126                       when you're done using the address you received */
127 };
128 
129 /*
130  * Curl_resolv() returns an entry with the info for the specified host
131  * and port.
132  *
133  * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
134  * use, or we'll leak memory!
135  */
136 /* return codes */
137 #define CURLRESOLV_TIMEDOUT -2
138 #define CURLRESOLV_ERROR    -1
139 #define CURLRESOLV_RESOLVED  0
140 #define CURLRESOLV_PENDING   1
141 int Curl_resolv(struct connectdata *conn, const char *hostname,
142                 int port, struct Curl_dns_entry **dnsentry);
143 int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
144                         int port, struct Curl_dns_entry **dnsentry,
145                         long timeoutms);
146 
147 /*
148  * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
149  * been set and returns TRUE if they are OK.
150  */
151 bool Curl_ipvalid(struct SessionHandle *data);
152 
153 /*
154  * Curl_getaddrinfo() is the generic low-level name resolve API within this
155  * source file. There are several versions of this function - for different
156  * name resolve layers (selected at build-time). They all take this same set
157  * of arguments
158  */
159 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
160                                 const char *hostname,
161                                 int port,
162                                 int *waitp);
163 
164 CURLcode Curl_is_resolved(struct connectdata *conn,
165                           struct Curl_dns_entry **dns);
166 CURLcode Curl_wait_for_resolv(struct connectdata *conn,
167                               struct Curl_dns_entry **dnsentry);
168 
169 /* Curl_resolv_getsock() is a generic function that exists in multiple
170    versions depending on what name resolve technology we've built to use. The
171    function is called from the multi_getsock() function.  'sock' is a pointer
172    to an array to hold the file descriptors, with 'numsock' being the size of
173    that array (in number of entries). This function is supposed to return
174    bitmask indicating what file descriptors (referring to array indexes in the
175    'sock' array) to wait for, read/write. */
176 int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock,
177                         int numsocks);
178 
179 /* unlock a previously resolved dns entry */
180 void Curl_resolv_unlock(struct SessionHandle *data,
181                         struct Curl_dns_entry *dns);
182 
183 /* for debugging purposes only: */
184 void Curl_scan_cache_used(void *user, void *ptr);
185 
186 /* make a new dns cache and return the handle */
187 struct curl_hash *Curl_mk_dnscache(void);
188 
189 /* prune old entries from the DNS cache */
190 void Curl_hostcache_prune(struct SessionHandle *data);
191 
192 /* Return # of adresses in a Curl_addrinfo struct */
193 int Curl_num_addresses (const Curl_addrinfo *addr);
194 
195 #if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
196 int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
197                        GETNAMEINFO_TYPE_ARG2 salen,
198                        char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
199                        char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
200                        GETNAMEINFO_TYPE_ARG7 flags,
201                        int line, const char *source);
202 #endif
203 
204 /* This is the callback function that is used when we build with asynch
205    resolve, ipv4 */
206 CURLcode Curl_addrinfo4_callback(void *arg,
207                                  int status,
208 #ifdef HAVE_CARES_CALLBACK_TIMEOUTS
209                                  int timeouts,
210 #endif
211                                  struct hostent *hostent);
212 /* This is the callback function that is used when we build with asynch
213    resolve, ipv6 */
214 CURLcode Curl_addrinfo6_callback(void *arg,
215                                  int status,
216 #ifdef HAVE_CARES_CALLBACK_TIMEOUTS
217                                  int timeouts,
218 #endif
219                                  Curl_addrinfo *ai);
220 
221 
222 /* Clone a Curl_addrinfo struct, works protocol independently */
223 Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
224 
225 /*
226  * Curl_printable_address() returns a printable version of the 1st address
227  * given in the 'ip' argument. The result will be stored in the buf that is
228  * bufsize bytes big.
229  */
230 const char *Curl_printable_address(const Curl_addrinfo *ip,
231                                    char *buf, size_t bufsize);
232 
233 /*
234  * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
235  *
236  * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
237  */
238 struct Curl_dns_entry *
239 Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
240                 const char *hostname, int port);
241 
242 /*
243  * Curl_destroy_thread_data() cleans up async resolver data.
244  * Complementary of ares_destroy.
245  */
246 struct Curl_async; /* forward-declaration */
247 void Curl_destroy_thread_data(struct Curl_async *async);
248 
249 #ifndef INADDR_NONE
250 #define CURL_INADDR_NONE (in_addr_t) ~0
251 #else
252 #define CURL_INADDR_NONE INADDR_NONE
253 #endif
254 
255 #ifdef HAVE_SIGSETJMP
256 /* Forward-declaration of variable defined in hostip.c. Beware this
257  * is a global and unique instance. This is used to store the return
258  * address that we can jump back to from inside a signal handler.
259  * This is not thread-safe stuff.
260  */
261 extern sigjmp_buf curl_jmpenv;
262 #endif
263 
264 #endif
265