]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
Pavel Orehov reported memory problems with the multi interface in bug report
authorDaniel Stenberg <daniel@haxx.se>
Mon, 10 Jan 2005 10:07:07 +0000 (10:07 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 10 Jan 2005 10:07:07 +0000 (10:07 +0000)
#1098843. In short, a shared DNS cache was setup for a multi handle and when
the shared cache was deleted before the individual easy handles, the latter
cleanups caused read/writes to already freed memory.

CHANGES
RELEASE-NOTES
lib/easy.c
lib/easy.h [new file with mode: 0644]
lib/multi.c
lib/multi.h [new file with mode: 0644]
lib/url.c
lib/urldata.h

diff --git a/CHANGES b/CHANGES
index e9b187d3ec220987d21d41b2805f2a2bf4730bfb..0f7336b2df2a00a028e4647192027749d3e856b0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,11 @@
 
 
 Daniel (10 January 2005)
+- Pavel Orehov reported memory problems with the multi interface in bug report
+  #1098843. In short, a shared DNS cache was setup for a multi handle and when
+  the shared cache was deleted before the individual easy handles, the latter
+  cleanups caused read/writes to already freed memory.
+
 - Hzhijun reported a memory leak in the SSL certificate code, that leaked the
   remote certificate name when it didn't match the used host name.
 
index c336b1927ecb4ba771b8dccdb240d5e90c2ca338..0c0899bb17798dec6bc3f8e27887ff8fa45d477e 100644 (file)
@@ -16,6 +16,7 @@ This release includes the following changes:
 
 This release includes the following bugfixes:
 
+ o memory problem with cleaning up multi interface
  o SSL certificate name memory leak
  o -d with -G to multiple URLs crashed
  o double va_list access crash fixed
@@ -33,6 +34,6 @@ advice from friends like these:
 
  Dan Fandrich, Peter Pentchev, Marcin Konicki, Rune Kleveland, David Shaw,
  Werner Koch, Gisle Vanem, Alex Neblett, Kai Sommerfeld, Marty Kuhrt,
- Hzhijun
+ Hzhijun, Pavel Orehov
 
         Thanks! (and sorry if I forgot to mention someone)
index 0b37748236a6bc9115a51d5901b53d2b574bbaa6..9310b843a91ac0ac957cea0174f70eda52a5f282 100644 (file)
@@ -82,6 +82,7 @@
 #include "share.h"
 #include "memory.h"
 #include "progress.h"
+#include "easy.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -403,6 +404,15 @@ void curl_easy_cleanup(CURL *curl)
   Curl_close(data);
 }
 
+/*
+ * Store a pointed to the multi handle within the easy handle's data struct.
+ */
+void Curl_easy_addmulti(struct SessionHandle *data,
+                        void *multi)
+{
+  data->multi = multi;
+}
+
 /*
  * curl_easy_getinfo() is an external interface that allows an app to retrieve
  * information from a performed transfer and similar.
diff --git a/lib/easy.h b/lib/easy.h
new file mode 100644 (file)
index 0000000..1ef053c
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __EASY_H
+#define __EASY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by easy.c
+ */
+void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
+
+#endif /* __EASY_H */
index 72e953eb17bce1cfeccc3b24404428ddd8e0ae4e..63eb505f561a137a4ab4654e53d5e0e4e169d0a9 100644 (file)
@@ -43,6 +43,7 @@
 #include "connect.h"
 #include "progress.h"
 #include "memory.h"
+#include "easy.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -174,6 +175,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
   if(easy->next)
     easy->next->prev = easy;
 
+  Curl_easy_addmulti(easy_handle, multi_handle);
+
   /* increase the node-counter */
   multi->num_easy++;
 
@@ -584,6 +587,13 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
   return result;
 }
 
+/* This is called when an easy handle is cleanup'ed that is part of a multi
+   handle */
+void Curl_multi_rmeasy(void *multi_handle, CURL *easy_handle)
+{
+  curl_multi_remove_handle(multi_handle, easy_handle);
+}
+
 CURLMcode curl_multi_cleanup(CURLM *multi_handle)
 {
   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
@@ -600,6 +610,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
       nexteasy=easy->next;
       /* clear out the usage of the shared DNS cache */
       easy->easy_handle->hostcache = NULL;
+      easy->easy_handle->multi = NULL;
 
       if (easy->msg)
         free(easy->msg);
diff --git a/lib/multi.h b/lib/multi.h
new file mode 100644 (file)
index 0000000..7c514e6
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __MULTI_H
+#define __MULTI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by multi.c
+ */
+void Curl_multi_rmeasy(void *multi, CURL *data);
+
+#endif /* __MULTI_H */
index bb43643021afbb8b29e54c0726730427fc4f8c73..29c35bf050ec91a083f5463273f8e09815fd2092 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -118,6 +118,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
 #include "http_digest.h"
 #include "http_negotiate.h"
 #include "select.h"
+#include "multi.h"
 
 /* And now for the protocols */
 #include "ftp.h"
@@ -196,6 +197,10 @@ void Curl_safefree(void *ptr)
 
 CURLcode Curl_close(struct SessionHandle *data)
 {
+  if(data->multi) {
+    /* this handle is still part of a multi handle, take care of this first */
+    Curl_multi_rmeasy(data->multi, data);
+  }
   /* Loop through all open connections and kill them one by one */
   while(-1 != ConnectionKillOne(data))
     ; /* empty loop */
@@ -1422,7 +1427,10 @@ CURLcode Curl_disconnect(struct connectdata *conn)
 
   data = conn->data;
 
-  if(conn->dns_entry)
+  if(conn->dns_entry && data->hostcache)
+    /* if the DNS entry is still around, and the host cache is not blanked
+       (which it is for example when a shared one is killed by
+       curl_multi_cleanup() and similar stuff) */
     Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
 
 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
index 1fdaac994ba13885bcb85f52263ee5ce20679d9e..3936b15263a03125cff4bdc07d4c24b81cf30733 100644 (file)
@@ -971,6 +971,8 @@ struct UserDefined {
 
 struct SessionHandle {
   curl_hash *hostcache;
+  void *multi;                 /* if non-NULL, points to the multi handle
+                                  struct of which this "belongs" */
   struct Curl_share *share;    /* Share, handles global variable mutexing */
   struct UserDefined set;      /* values set by the libcurl user */
   struct DynamicStatic change; /* possibly modified userdefined data */