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