Timeout slow ares name lookups. This is based on the patch brought by
Dirk Manske, but modified by me.
This commit is contained in:
parent
580a2fe72b
commit
12fa877f00
33
lib/hostip.c
33
lib/hostip.c
@ -481,27 +481,46 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode rc=CURLE_OK;
|
CURLcode rc=CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct timeval now = Curl_tvnow();
|
||||||
|
bool timedout = FALSE;
|
||||||
|
long timeout = 300; /* default name resolve timeout in seconds */
|
||||||
|
long elapsed = 0; /* time taken so far */
|
||||||
|
|
||||||
|
/* now, see if there's a connect timeout or a regular timeout to
|
||||||
|
use instead of the default one */
|
||||||
|
if(conn->data->set.connecttimeout)
|
||||||
|
timeout = conn->data->set.connecttimeout;
|
||||||
|
else if(conn->data->set.timeout)
|
||||||
|
timeout = conn->data->set.timeout;
|
||||||
|
|
||||||
/* Wait for the name resolve query to complete. */
|
/* Wait for the name resolve query to complete. */
|
||||||
while (1) {
|
while (1) {
|
||||||
int nfds=0;
|
int nfds=0;
|
||||||
fd_set read_fds, write_fds;
|
fd_set read_fds, write_fds;
|
||||||
struct timeval *tvp, tv;
|
struct timeval *tvp, tv, store;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
store.tv_sec = timeout - elapsed;
|
||||||
|
store.tv_usec = 0;
|
||||||
|
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||||
if (nfds == 0)
|
if (nfds == 0)
|
||||||
break;
|
break;
|
||||||
tvp = ares_timeout(data->state.areschannel,
|
tvp = ares_timeout(data->state.areschannel,
|
||||||
NULL, /* pass in our maximum time here */
|
&store, &tv);
|
||||||
&tv);
|
|
||||||
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||||
if (count < 0 && errno != EINVAL)
|
if (count < 0 && errno != EINVAL)
|
||||||
break;
|
break;
|
||||||
|
else if(!count) {
|
||||||
|
/* timeout */
|
||||||
|
timedout = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||||
|
|
||||||
|
elapsed = Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operation complete, if the lookup was successful we now have the entry
|
/* Operation complete, if the lookup was successful we now have the entry
|
||||||
@ -515,7 +534,11 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
/* a name was not resolved */
|
/* a name was not resolved */
|
||||||
if(conn->async.done) {
|
if(timedout) {
|
||||||
|
failf(data, "Resolving host timed out: %s", conn->name);
|
||||||
|
rc = CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
else if(conn->async.done) {
|
||||||
failf(data, "Could not resolve host: %s", conn->name);
|
failf(data, "Could not resolve host: %s", conn->name);
|
||||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user