cURL / Mailing Lists / curl-library / Single Mail

curl-library

multi curl hangs during DNS resolution on FreeBSD

From: Kevin Day <toasty_at_dragondata.com>
Date: Tue, 26 Aug 2014 09:40:08 -0500

We’ve got a custom application using libcurl that is very very infrequently seeing a hang somewhere in libcurl, but it’s such a rare bug that we’ve never been able to track it down. It only happens on FreeBSD hosts, and it seems timing related during DNS resolution. Switching from the threaded to the c-ares resolver makes it go away, so we didn’t look too deeply into it since I could never catch it in the debugger.

I just found what looks like the same issue in the PHP curl binding, except that it happens 100% of the time. On a FreeBSD 10.0 box, do:

# pkg install php55 php55-curl

Then run this script:

// Works
$c = curl_init("http://curl.haxx.se/404");
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_VERBOSE, true);
curl_exec($c);

Which works fine. Then do the same thing using the multi interface, and it hangs:

// Hangs
$c = curl_init("http://curl.haxx.se/404");
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_VERBOSE, true);
$m = curl_multi_init();
curl_multi_add_handle($m, $c);

$active = null;
do {
    $mrc = curl_multi_exec($m, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($m) != -1) {
        do {
            $mrc = curl_multi_exec($m, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

Tracing what’s going on in the process shows that it makes a DNS request, gets a response, calls getsockname() on the addresses in the response, then hangs. If you “prime” the cache by making a non-multi request for the same hostname, then using multi for cached hostnames it works as expected.

If I compile libcurl with debugging, running the above produces:

* STATE: INIT => CONNECT handle 0x80273b008; line 1028 (connection #-5000)
* Hostname was NOT found in DNS cache
* STATE: CONNECT => WAITRESOLVE handle 0x80273b008; line 1060 (connection #0)

Recompiling using c-ares instead of the default threaded resolver makes it work fine.

Is this a known issue anywhere? Anything I can do to help debug this?

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2014-08-26