From 690738503fbdb3cbf1fb24edd9d25972e2d14206 Mon Sep 17 00:00:00 2001
From: Jason Glasgow <jglasgow@chromium.org>
Date: Wed, 30 Nov 2011 15:23:44 -0500
Subject: [PATCH] multi: handle timeouts on DNS servers by checking for new sockets

If the first name server is not available, the multi interface does
not invoke the socket_cb when the DNS request to the first name server
timesout.  Ensure that the list of sockets are always updated after
calling Curl_resolver_is_resolved.

This bug can be reproduced if Curl is complied with --enable_ares and
your code uses the multi socket interfaces and the
CURLMOPT_SOCKETFUNCTION option.  To test try:
  iptables -I INPUT \
           -s $(sed -n -e '/name/{s/.* //p;q}' /etc/resolv.conf)/32 \
           -j REJECT
and then run a program which uses the multi-interface.
---
 lib/multi.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/lib/multi.c b/lib/multi.c
index ae70851..3059e49 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1085,12 +1085,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       /* check if we have the name resolved by now */
       easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns);
 
-      if(dns) {
-        /* Update sockets here. Mainly because the socket(s) may have been
-           closed and the application thus needs to be told, even if it is
-           likely that the same socket(s) will again be used further down. */
-        singlesocket(multi, easy);
+      /* Update sockets here, because the socket(s) may have been
+         closed and the application thus needs to be told, even if it
+         is likely that the same socket(s) will again be used further
+         down.  If the name has not yet been resolved, it is likely
+         that new sockets have been opened in an attempt to contact
+         another resolver. */
+      singlesocket(multi, easy);
 
+      if(dns) {
         /* Perform the next step in the connection phase, and then move on
            to the WAITCONNECT state */
         easy->result = Curl_async_resolved(easy->easy_conn,
-- 
1.7.3.1

