cURL / Mailing Lists / curl-library / Single Mail

curl-library

Bug Found and Fix.

From: Roy Shan <rshan_at_viacit.com>
Date: Wed, 31 Mar 2004 13:20:02 -0600 (CST)

I wrote up a dummy dns server which never responds to query. So I can
reproduce the timeout problem easily. Soon, I found the ares_process was
never called in Curl_is_resolved. I figure out the line 493 in hostip.c is
wrong.

count = select(nfds, &read_fds, &write_fds, NULL,
                 (struct timeval *)&tv);
if(count)
    ares_process(data->state.areschannel, &read_fds, &write_fds);

if the dns server drops some query, select always returns 0. In that case,
ares_process never gets called. Then, it never times out.

My fix is: remove line 493. That is always calling ares_process after select.

Questions:
1. each handle has its own areschannel. Can the design be handles sharing
a channel?
2. Curl_wait_for_resolv blocks and waits. Can it become non-blocking?

Those questions are non-critical. Just wanna know if there's space to
improve.

> On Mon, 29 Mar 2004, Roy Shan wrote:
>
>> After adding debugging code as you advised, I did observe that handles
>> got
>> stuck in the state of CURLM_STATE_WAITRESOLVE.
>
> Ok, having that verified it is pretty obvious that we don't handle name
> lookup
> timeouts properly in there. I was naively assuming that ares took care of
> those automatically.
>
>> I guess there's a bug in the Curl_is_resolved() or host_callback(),
>> although
>> I can't figure it out now.
>
> Can you try to apply the following patch to see if it makes these lookups
> timeout properly? I'm not sure 180 seconds is a very good timeout value to
> use
> but it seems useful in a first shot just to see if this cures your
> problem.
>
> --- hostip.c 29 Mar 2004 21:29:24 -0000 1.131
> +++ hostip.c 30 Mar 2004 08:12:00 -0000
> @@ -482,9 +482,20 @@
> int count;
> struct SessionHandle *data = conn->data;
> int nfds;
> + long diff;
>
> FD_ZERO(&read_fds);
> FD_ZERO(&write_fds);
> +
> + diff = Curl_tvdiff(Curl_tvnow(),
> + data->progress.t_startsingle)/1000;
> +
> + if(diff > 180) {
> + /* Waited >180 seconds, this is a name resolve timeout! */
> + failf(data, "Name resolve timeout after %ld seconds", diff);
> + return CURLE_OPERATION_TIMEDOUT;
> + }
> +
> nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
>
> count = select(nfds, &read_fds, &write_fds, NULL,
>
>
> --
> Daniel Stenberg -- http://curl.haxx.se -- http://daniel.haxx.se
> Dedicated custom curl help for hire: http://haxx.se/curl.html
>
Received on 2004-03-31