diff options
author | Thomas Lopatic <lopatic@yahoo-inc.com> | 2010-03-22 21:57:48 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2010-03-22 21:57:48 +0100 |
commit | 6657f12fff9e7b14e56da3790f0a271989c8b6a2 (patch) | |
tree | a212aaf8da554ad0f991d5d0458af315d938dd6d | |
parent | 3cd5b1cfb078cd7e96d7cd490740d955b7905caf (diff) |
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().
-rw-r--r-- | lib/hostip.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/hostip.c b/lib/hostip.c index 4acf1217e..68ceedc6d 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -571,15 +571,6 @@ int Curl_resolv_timeout(struct connectdata *conn, return CURLRESOLV_TIMEDOUT; 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 * 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 will abort system calls */ 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 @@ -621,6 +625,8 @@ int Curl_resolv_timeout(struct connectdata *conn, */ rc = Curl_resolv(conn, hostname, port, entry); +clean_up: + #ifdef USE_ALARM_TIMEOUT if (timeout > 0) { |