]> granicus.if.org Git - curl/commitdiff
threaded-resolver: shutdown the resolver thread without error message
authorDaniel Stenberg <daniel@haxx.se>
Thu, 28 Feb 2019 19:34:36 +0000 (20:34 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 1 Mar 2019 08:31:34 +0000 (09:31 +0100)
When a transfer is done, the resolver thread will be brought down. That
could accidentally generate an error message in the error buffer even
though this is not an error situationand the transfer would still return
OK.  An application that still reads the error buffer could find a
"Could not resolve host: [host name]" message there and get confused.

Reported-by: Michael Schmid
Fixes #3629
Closes #3630

lib/asyn-thread.c

index a9679d062e7da0d4def685cf1d516bb2c5c04266..55e0811c5cdc8144d4d57d4afa28f3b81118d90e 100644 (file)
@@ -461,6 +461,42 @@ static CURLcode resolver_error(struct connectdata *conn)
   return result;
 }
 
+static CURLcode thread_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry,
+                                   bool report)
+{
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  CURLcode result = CURLE_OK;
+
+  DEBUGASSERT(conn && td);
+  DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
+
+  /* wait for the thread to resolve the name */
+  if(Curl_thread_join(&td->thread_hnd)) {
+    if(entry)
+      result = getaddrinfo_complete(conn);
+  }
+  else
+    DEBUGASSERT(0);
+
+  conn->async.done = TRUE;
+
+  if(entry)
+    *entry = conn->async.dns;
+
+  if(!conn->async.dns && report)
+    /* a name was not resolved, report error */
+    result = resolver_error(conn);
+
+  destroy_async_data(&conn->async);
+
+  if(!conn->async.dns && report)
+    connclose(conn, "asynch resolve failed");
+
+  return result;
+}
+
+
 /*
  * Until we gain a way to signal the resolver threads to stop early, we must
  * simply wait for them and ignore their results.
@@ -473,7 +509,7 @@ void Curl_resolver_kill(struct connectdata *conn)
      unfortunately.  Otherwise, we can simply cancel to clean up any resolver
      data. */
   if(td && td->thread_hnd != curl_thread_t_null)
-    (void)Curl_resolver_wait_resolv(conn, NULL);
+    (void)thread_wait_resolv(conn, NULL, FALSE);
   else
     Curl_resolver_cancel(conn);
 }
@@ -494,35 +530,7 @@ void Curl_resolver_kill(struct connectdata *conn)
 CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
                                    struct Curl_dns_entry **entry)
 {
-  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
-  CURLcode result = CURLE_OK;
-
-  DEBUGASSERT(conn && td);
-  DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
-
-  /* wait for the thread to resolve the name */
-  if(Curl_thread_join(&td->thread_hnd)) {
-    if(entry)
-      result = getaddrinfo_complete(conn);
-  }
-  else
-    DEBUGASSERT(0);
-
-  conn->async.done = TRUE;
-
-  if(entry)
-    *entry = conn->async.dns;
-
-  if(!conn->async.dns)
-    /* a name was not resolved, report error */
-    result = resolver_error(conn);
-
-  destroy_async_data(&conn->async);
-
-  if(!conn->async.dns)
-    connclose(conn, "asynch resolve failed");
-
-  return result;
+  return thread_wait_resolv(conn, entry, TRUE);
 }
 
 /*