Name resolving
Most transfers libcurl can do involves a name that first needs to betranslated to an Internet address. That is name resolving. Using a numericalIP address directly in the URL usually avoids the name resolve phase, but inmany cases it is not easy to manually replace the name with the IP address.
libcurl tries hard tore-use an existing connection rather than tocreate a new one. The function that checks for an existing connection to useis based purely on the name and is performed before any name resolving isattempted. That is one of the reasons the re-use is so much faster. A transferusing a reused connection does not resolve the hostname again.
If no connection can be reused, libcurl resolves the hostname to the set ofaddresses it resolves to. Typically this means asking for both IPv4 and IPv6addresses and there may be a whole set of those returned to libcurl. That setof addresses is then tried until one works, or it returns failure.
An application can force libcurl to use only an IPv4 or IPv6 resolved addressby settingCURLOPT_IPRESOLVE
to the preferred value. For example, ask toonly use IPv6 addresses:
curl_easy_setopt(easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
Name resolver backends
libcurl can be built to do name resolves in one out of these three differentways and depending on which backend way that is used, it gets a slightlydifferent feature set and sometimes modified behavior.
The default backend is invoking the normal libc resolver functions in a newhelper-thread, so that it can still do fine-grained timeouts if wanted andthere is no blocking calls involved.
On older systems, libcurl uses the standard synchronous name resolverfunctions. They unfortunately make all transfers within a multi handle blockduring its operation and it is much harder to time out nicely.
There is also support for resolving with the c-ares third party library,which supports asynchronous name resolving without the use of threads. Thisscales better to huge number of parallel transfers but it is not always 100%compatible with the native name resolver functionality.
DNS over HTTPS
Independently of what resolver backend that libcurl is built to use, since7.62.0 it also provides a way for the user to ask a specific DoH (DNS overHTTPS) server for the address of a name. This avoids using the normal, nativeresolver method and server and instead asks a dedicated separate one.
A DoH server is specified as a full URL with theCURLOPT_DOH_URL
option likethis:
curl_easy_setopt(easy, CURLOPT_DOH_URL, "https://example.com/doh");
The URL passed to this optionmust be using https:// and it is generallyrecommended that you have HTTP/2 support enabled so that libcurl can performmultiple DoH requests multiplexed over the connection to the DoH server.
Caching
When a name has been resolved, the result is stored in libcurl's in-memorycache so that subsequent resolves of the same name are instant for as long thename is kept in the DNS cache. By default, each entry is kept in the cache for60 seconds, but that value can be changed withCURLOPT_DNS_CACHE_TIMEOUT
.
The DNS cache is kept within the easy handle whencurl_easy_perform
is used,or within the multi handle when the multi interface is used. It can also bemade shared between multiple easy handles using theshare interface.
Custom addresses for hosts
Sometimes it is handy to provide fake, custom addresses for real hostnames sothat libcurl connects to a different address instead of one an actual nameresolve would suggest.
With the help of theCURLOPT_RESOLVE option,an application can pre-populate libcurl's DNS cache with a custom address fora given hostname and port number.
To make libcurl connect to 127.0.0.1 when example.com on port 443 isrequested, an application can do:
struct curl_slist *dns;dns = curl_slist_append(NULL, "example.com:443:127.0.0.1");curl_easy_setopt(curl, CURLOPT_RESOLVE, dns);
Since this puts the fake address into the DNS cache, it works even whenfollowing redirects etc.
Name server options
For libcurl built to use c-ares, there is a few options available that offerfine-grained control of what DNS servers to use and how. This is limited toc-ares build purely because these are powers that are not available when thestandard system calls for name resolving are used.
With
CURLOPT_DNS_SERVERS
, the application can select to use a set ofdedicated DNS servers.With
CURLOPT_DNS_INTERFACE
it can tell libcurl which network interface to speakDNS over instead of the default one.With
CURLOPT_DNS_LOCAL_IP4
andCURLOPT_DNS_LOCAL_IP6
, the applicationcan specify which specific network addresses to bind DNS resolves to.
No global DNS cache
The option calledCURLOPT_DNS_USE_GLOBAL_CACHE
once told curl to use aglobal DNS cache. This functionality has been removed since 7.65.0, so whilethis option still exists it does nothing.