1 #ifndef HEADER_CURL_HOSTIP_H 2 #define HEADER_CURL_HOSTIP_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 "hash.h" 29 #include "curl_addrinfo.h" 30 #include "timeval.h" /* for timediff_t */ 31 #include "asyn.h" 32 33 #ifdef HAVE_SETJMP_H 34 #include <setjmp.h> 35 #endif 36 37 /* Allocate enough memory to hold the full name information structs and 38 * everything. OSF1 is known to require at least 8872 bytes. The buffer 39 * required for storing all possible aliases and IP numbers is according to 40 * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes! 41 */ 42 #define CURL_HOSTENT_SIZE 9000 43 44 #define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this 45 many seconds for a name resolve */ 46 47 #define CURL_ASYNC_SUCCESS CURLE_OK 48 49 struct addrinfo; 50 struct hostent; 51 struct Curl_easy; 52 struct connectdata; 53 54 /* 55 * Curl_global_host_cache_init() initializes and sets up a global DNS cache. 56 * Global DNS cache is general badness. Do not use. This will be removed in 57 * a future version. Use the share interface instead! 58 * 59 * Returns a struct Curl_hash pointer on success, NULL on failure. 60 */ 61 struct Curl_hash *Curl_global_host_cache_init(void); 62 63 struct Curl_dns_entry { 64 struct Curl_addrinfo *addr; 65 /* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (doesn't time out) */ 66 time_t timestamp; 67 /* use-counter, use Curl_resolv_unlock to release reference */ 68 long inuse; 69 }; 70 71 bool Curl_host_is_ipnum(const char *hostname); 72 73 /* 74 * Curl_resolv() returns an entry with the info for the specified host 75 * and port. 76 * 77 * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after 78 * use, or we'll leak memory! 79 */ 80 /* return codes */ 81 enum resolve_t { 82 CURLRESOLV_TIMEDOUT = -2, 83 CURLRESOLV_ERROR = -1, 84 CURLRESOLV_RESOLVED = 0, 85 CURLRESOLV_PENDING = 1 86 }; 87 enum resolve_t Curl_resolv(struct Curl_easy *data, 88 const char *hostname, 89 int port, 90 bool allowDOH, 91 struct Curl_dns_entry **dnsentry); 92 enum resolve_t Curl_resolv_timeout(struct Curl_easy *data, 93 const char *hostname, int port, 94 struct Curl_dns_entry **dnsentry, 95 timediff_t timeoutms); 96 97 #ifdef ENABLE_IPV6 98 /* 99 * Curl_ipv6works() returns TRUE if IPv6 seems to work. 100 */ 101 bool Curl_ipv6works(struct Curl_easy *data); 102 #else 103 #define Curl_ipv6works(x) FALSE 104 #endif 105 106 /* 107 * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've 108 * been set and returns TRUE if they are OK. 109 */ 110 bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn); 111 112 113 /* 114 * Curl_getaddrinfo() is the generic low-level name resolve API within this 115 * source file. There are several versions of this function - for different 116 * name resolve layers (selected at build-time). They all take this same set 117 * of arguments 118 */ 119 struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, 120 const char *hostname, 121 int port, 122 int *waitp); 123 124 125 /* unlock a previously resolved dns entry */ 126 void Curl_resolv_unlock(struct Curl_easy *data, 127 struct Curl_dns_entry *dns); 128 129 /* init a new dns cache */ 130 void Curl_init_dnscache(struct Curl_hash *hash, int hashsize); 131 132 /* prune old entries from the DNS cache */ 133 void Curl_hostcache_prune(struct Curl_easy *data); 134 135 /* Return # of addresses in a Curl_addrinfo struct */ 136 int Curl_num_addresses(const struct Curl_addrinfo *addr); 137 138 /* IPv4 threadsafe resolve function used for synch and asynch builds */ 139 struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port); 140 141 CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_connect); 142 143 /* 144 * Curl_addrinfo_callback() is used when we build with any asynch specialty. 145 * Handles end of async request processing. Inserts ai into hostcache when 146 * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async 147 * request completed whether successful or failed. 148 */ 149 CURLcode Curl_addrinfo_callback(struct Curl_easy *data, 150 int status, 151 struct Curl_addrinfo *ai); 152 153 /* 154 * Curl_printable_address() returns a printable version of the 1st address 155 * given in the 'ip' argument. The result will be stored in the buf that is 156 * bufsize bytes big. 157 */ 158 void Curl_printable_address(const struct Curl_addrinfo *ip, 159 char *buf, size_t bufsize); 160 161 /* 162 * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache. 163 * 164 * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. 165 * 166 * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after 167 * use, or we'll leak memory! 168 */ 169 struct Curl_dns_entry * 170 Curl_fetch_addr(struct Curl_easy *data, 171 const char *hostname, 172 int port); 173 174 /* 175 * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. 176 * 177 * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. 178 */ 179 struct Curl_dns_entry * 180 Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr, 181 const char *hostname, size_t hostlen, int port); 182 183 #ifndef INADDR_NONE 184 #define CURL_INADDR_NONE (in_addr_t) ~0 185 #else 186 #define CURL_INADDR_NONE INADDR_NONE 187 #endif 188 189 #ifdef HAVE_SIGSETJMP 190 /* Forward-declaration of variable defined in hostip.c. Beware this 191 * is a global and unique instance. This is used to store the return 192 * address that we can jump back to from inside a signal handler. 193 * This is not thread-safe stuff. 194 */ 195 extern sigjmp_buf curl_jmpenv; 196 #endif 197 198 /* 199 * Function provided by the resolver backend to set DNS servers to use. 200 */ 201 CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers); 202 203 /* 204 * Function provided by the resolver backend to set 205 * outgoing interface to use for DNS requests 206 */ 207 CURLcode Curl_set_dns_interface(struct Curl_easy *data, 208 const char *interf); 209 210 /* 211 * Function provided by the resolver backend to set 212 * local IPv4 address to use as source address for DNS requests 213 */ 214 CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, 215 const char *local_ip4); 216 217 /* 218 * Function provided by the resolver backend to set 219 * local IPv6 address to use as source address for DNS requests 220 */ 221 CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, 222 const char *local_ip6); 223 224 /* 225 * Clean off entries from the cache 226 */ 227 void Curl_hostcache_clean(struct Curl_easy *data, struct Curl_hash *hash); 228 229 /* 230 * Populate the cache with specified entries from CURLOPT_RESOLVE. 231 */ 232 CURLcode Curl_loadhostpairs(struct Curl_easy *data); 233 CURLcode Curl_resolv_check(struct Curl_easy *data, 234 struct Curl_dns_entry **dns); 235 int Curl_resolv_getsock(struct Curl_easy *data, 236 curl_socket_t *socks); 237 238 CURLcode Curl_resolver_error(struct Curl_easy *data); 239 #endif /* HEADER_CURL_HOSTIP_H */ 240