diff options
author | Steinar H. Gunderson <sesse@google.com> | 2007-09-28 14:26:11 +0000 |
---|---|---|
committer | Steinar H. Gunderson <sesse@google.com> | 2007-09-28 14:26:11 +0000 |
commit | a6a159dcad51c729e7601eee75c82ffc7045e4bb (patch) | |
tree | f3136430e7cfeace1900496ec916c6a3dbbd4682 /ares_process.c | |
parent | c97d91e3493873020ea0ad4799348f439fa8885b (diff) | |
download | c-ares-a6a159dcad51c729e7601eee75c82ffc7045e4bb.tar.gz c-ares-a6a159dcad51c729e7601eee75c82ffc7045e4bb.tar.bz2 c-ares-a6a159dcad51c729e7601eee75c82ffc7045e4bb.zip |
Don't skip a server if it's the only one. (Bugfix from the Google tree.)
Diffstat (limited to 'ares_process.c')
-rw-r--r-- | ares_process.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/ares_process.c b/ares_process.c index b4073bf..1b58029 100644 --- a/ares_process.c +++ b/ares_process.c @@ -65,6 +65,8 @@ static void process_timeouts(ares_channel channel, time_t now); static void process_answer(ares_channel channel, unsigned char *abuf, int alen, int whichserver, int tcp, time_t now); static void handle_error(ares_channel channel, int whichserver, time_t now); +static void skip_server(ares_channel channel, struct query *query, + int whichserver); static struct query *next_server(ares_channel channel, struct query *query, time_t now); static int open_tcp_socket(ares_channel channel, struct server_state *server); static int open_udp_socket(ares_channel channel, struct server_state *server); @@ -474,7 +476,7 @@ static void process_answer(ares_channel channel, unsigned char *abuf, { if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) { - query->skip_server[whichserver] = 1; + skip_server(channel, query, whichserver); if (query->server == whichserver) next_server(channel, query, now); return; @@ -506,12 +508,28 @@ static void handle_error(ares_channel channel, int whichserver, time_t now) next = query->next; if (query->server == whichserver) { - query->skip_server[whichserver] = 1; + skip_server(channel, query, whichserver); next = next_server(channel, query, now); } } } +static void skip_server(ares_channel channel, struct query *query, + int whichserver) { + /* The given server gave us problems with this query, so if we have + * the luxury of using other servers, then let's skip the + * potentially broken server and just use the others. If we only + * have one server and we need to retry then we should just go ahead + * and re-use that server, since it's our only hope; perhaps we + * just got unlucky, and retrying will work (eg, the server timed + * out our TCP connection just as we were sending another request). + */ + if (channel->nservers > 1) + { + query->skip_server[whichserver] = 1; + } +} + static struct query *next_server(ares_channel channel, struct query *query, time_t now) { /* Advance to the next server or try. */ @@ -553,7 +571,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) { if (open_tcp_socket(channel, server) == -1) { - query->skip_server[query->server] = 1; + skip_server(channel, query, query->server); next_server(channel, query, now); return; } @@ -583,7 +601,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) { if (open_udp_socket(channel, server) == -1) { - query->skip_server[query->server] = 1; + skip_server(channel, query, query->server); next_server(channel, query, now); return; } @@ -591,7 +609,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) { /* FIXME: Handle EAGAIN here since it likely can happen. */ - query->skip_server[query->server] = 1; + skip_server(channel, query, query->server); next_server(channel, query, now); return; } |