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

Reply via email to