1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-11 20:15:03 -05:00

fix the alarm()-based DNS timeout

Looking at the code of Curl_resolv_timeout() in hostip.c, I think
that in case of a timeout, the signal handler for SIGALRM never
gets removed. I think that in my case it gets executed at some
point later on when execution has long left Curl_resolv_timeout()
or even the cURL library.

The code that is jumped to with siglongjmp() simply sets the
error message to "name lookup timed out" and then returns with
CURLRESOLV_ERROR. I guess that instead of simply returning
without cleaning up, the code should have a goto that jumps to
the spot right after the call to Curl_resolv().
This commit is contained in:
Thomas Lopatic 2010-03-22 21:57:48 +01:00 committed by Daniel Stenberg
parent 3cd5b1cfb0
commit 6657f12fff

View File

@ -571,15 +571,6 @@ int Curl_resolv_timeout(struct connectdata *conn,
return CURLRESOLV_TIMEDOUT; return CURLRESOLV_TIMEDOUT;
if (timeout > 0) { if (timeout > 0) {
/* This allows us to time-out from the name resolver, as the timeout
will generate a signal and we will siglongjmp() from that here.
This technique has problems (see alarmfunc). */
if(sigsetjmp(curl_jmpenv, 1)) {
/* this is coming from a siglongjmp() after an alarm signal */
failf(data, "name lookup timed out");
return CURLRESOLV_ERROR;
}
/************************************************************* /*************************************************************
* Set signal handler to catch SIGALRM * Set signal handler to catch SIGALRM
* Store the old value to be able to set it back later! * Store the old value to be able to set it back later!
@ -605,6 +596,19 @@ int Curl_resolv_timeout(struct connectdata *conn,
/* alarm() makes a signal get sent when the timeout fires off, and that /* alarm() makes a signal get sent when the timeout fires off, and that
will abort system calls */ will abort system calls */
prev_alarm = alarm((unsigned int) (timeout/1000L)); prev_alarm = alarm((unsigned int) (timeout/1000L));
/* This allows us to time-out from the name resolver, as the timeout
will generate a signal and we will siglongjmp() from that here.
This technique has problems (see alarmfunc).
This should be the last thing we do before calling Curl_resolv(),
as otherwise we'd have to worry about variables that get modified
before we invoke Curl_resolv() (and thus use "volatile"). */
if(sigsetjmp(curl_jmpenv, 1)) {
/* this is coming from a siglongjmp() after an alarm signal */
failf(data, "name lookup timed out");
rc = CURLRESOLV_ERROR;
goto clean_up;
}
} }
#else #else
@ -621,6 +625,8 @@ int Curl_resolv_timeout(struct connectdata *conn,
*/ */
rc = Curl_resolv(conn, hostname, port, entry); rc = Curl_resolv(conn, hostname, port, entry);
clean_up:
#ifdef USE_ALARM_TIMEOUT #ifdef USE_ALARM_TIMEOUT
if (timeout > 0) { if (timeout > 0) {