curl / Mailing Lists / curl-library / Single Mail

curl-library

Re: a couple of questions re CURLOPT_RESOLVE

From: Ray Satiro via curl-library <curl-library_at_cool.haxx.se>
Date: Fri, 30 Dec 2016 16:40:28 -0500

On 12/30/2016 10:23 AM, Vadim Grinshpun wrote:
> I'm looking to make use of CURLOPT_RESOLVE, and would like to get a
> couple clarifications on its semantics.
>
> The basic question is this: is the list that the application provides
> as the argument to CURLOPT_RESOLVE
> treated as incremental updates to an internal DNS cache, or is it
> effectively the cache itself?
>
> Or, more specifically:
>
> 1: what is the expected lifetime of the list? Can it be freed
> immediately after the curl_easy_setopt(h, CURLOPT_RESOLVE,list) call
> completes?
> (The example seems to imply that the list needs to persist while a
> handle is using it; however this is not explicitly stated anywhere I
> could find).
>
> 2. If the list must persist after the setopt call: how should updates
> be handled? E.g.:
> - providing a new list to curl
> - updating the existing list, still having to call ...setopt()
> - updating the existing list, expecting curl to just pick up the
> change next time it resolves

libcurl has internal DNS caches that are per handle or shared amongst a
number of handles. By default each easy handle has its own dns cache but
if the easy is added to a multi handle it will use a shared dns cache in
the multi. You can use CURL_LOCK_DATA_DNS [1] to share a dns cache among
easy handles without putting them in a multi. If you don't want the
hosts you are adding to be shared even in a multi something like
CURLOPT_CONNECT_TO [2] may work.

Any list provided for resolve is processed and its effects are settled
during pretransfer which is the stage immediately before a transfer
takes place. Internally it is in the initialization stage
CURLM_STATE_INIT. That information I don't believe is documented and
therefore is subject to change.

Once a host has been added to the DNS cache via CURLOPT_RESOLVE you
would have to explicitly remove it by setting a list that contains
-host:port before the next transfer takes place and though not
documented the removal would actually be carried out during that next
pretransfer stage. You can use the - to remove any host in the DNS
cache. If an entry is in use at the time you try to remove it then it is
marked for removal but will not be removed immediately, even in pretransfer.

Do not rely on undocumented behavior: Set a changed list via
CURLOPT_RESOLVE again that explicitly adds and removes otherwise your
modifications could have no effect depending on what state the handle is
in and whether the list was already processed or not. For example if you
had a list that set foo and bar host entries and then you modified that
list to set a qux host entry there is no guarantee libcurl will process
that unless you call CURLOPT_RESOLVE to set the list again.

So basically you have to keep your list around until you set
CURLOPT_RESOLVE to some other list (or NULL) or cleanup the handle, and
yes you can update an existing resolve list but you have to do it by
explicitly removing and then adding hosts and call CURLOPT_RESOLVE
again, otherwise unwanted entries from the previous list may remain in
the cache. If you have some example scenario you are trying to figure
out pose it and someone might be able to help.

[1]: https://curl.haxx.se/libcurl/c/curl_share_setopt.html
[2]: https://curl.haxx.se/libcurl/c/CURLOPT_CONNECT_TO.html

-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2016-12-30