]> granicus.if.org Git - curl/commitdiff
c-ares: fix cancelled resolves
authorDaniel Stenberg <daniel@haxx.se>
Mon, 27 Dec 2010 08:55:13 +0000 (09:55 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 27 Dec 2010 09:01:44 +0000 (10:01 +0100)
When built IPv6-enabled, we could do Curl_done() with one of the two
resolves having returned already, so when ares_cancel() is called the
resolve callback ends up doing funny things (sometimes resulting in a
segfault) since it would try to actually store the previous resolve even
though we're shutting down the resolve.

This bug was introduced in commit 8ab137b2bc9630ce so it hasn't been
included in any public release.

Bug: http://curl.haxx.se/bug/view.cgi?id=3145445
Reported by: Pedro Larroy

lib/hostasyn.c
lib/hostip.h
lib/url.c

index 7d35fa0e7c79451109fdccee602417d3a47c86ec..7a65cb1b80dce8fdb8b30f72fc1c36e2fc15adcd 100644 (file)
  **********************************************************************/
 #ifdef CURLRES_ASYNCH
 
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_async_cancel(struct connectdata *conn)
+{
+  /* If we have a "half" response already received, we first clear that off
+     so that nothing is tempted to use it */
+  if(conn->async.temp_ai) {
+    Curl_freeaddrinfo(conn->async.temp_ai);
+    conn->async.temp_ai = NULL;
+  }
+
+  /* for ares-using, make sure all possible outstanding requests are properly
+     cancelled before we proceed */
+  ares_cancel(conn->data->state.areschannel);
+}
+
+
 /*
  * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
  * or getaddrinfo_thread() when we got the name resolved (or not!).
  *
  * The storage operation locks and unlocks the DNS cache.
  */
-CURLcode Curl_addrinfo_callback(struct connectdata * conn,
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
                                 int status,
                                 struct Curl_addrinfo *ai)
 {
index 2f8d4b56c9cd43172c3679af6239cb3adc893a35..3f27a2b87614a4299ea0866335ece07c9271bcf2 100644 (file)
@@ -70,6 +70,12 @@ struct hostent;
 struct SessionHandle;
 struct connectdata;
 
+#ifdef CURLRES_ASYNCH
+void Curl_async_cancel(struct connectdata *conn);
+#else
+#define Curl_async_cancel(x) do {} while(0)
+#endif
+
 /*
  * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
  * Global DNS cache is general badness. Do not use. This will be removed in
index 95d024d52f8de46fe92f20596d7f4bf490ce1810..470b4c94c2d8a17ced99908a0a926ce9d001b442 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -5210,10 +5210,6 @@ CURLcode Curl_done(struct connectdata **connp,
     data->state.tempwrite = NULL;
   }
 
-  /* for ares-using, make sure all possible outstanding requests are properly
-     cancelled before we proceed */
-  ares_cancel(data->state.areschannel);
-
   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
      forced us to close this no matter what we think.