Hi,

I think there is a memory leak in the GnuTLS part of wget. When downloading multiple files from a HTTPS server, wget with GnuTLS uses a lot of memory.

Perhaps an explanation for this can be found in src/http.c. The gethttp calls ssl_init for each download:

> /* Initialize the SSL context.  After this has once been done,
>    it becomes a no-op.  */
> if (!ssl_init ())

The OpenSSL version of ssl_init, in src/openssl.c, checks if SSL has already been initialized and doesn't repeat the work.

But the GnuTLS version doesn't:

> bool
> ssl_init ()
> {
>   const char *ca_directory;
>   DIR *dir;
>
>   gnutls_global_init ();
>   gnutls_certificate_allocate_credentials (&credentials);

GnuTLS is initialized again and again, but there is never a call to gnutls_global_deinit.

I've attached a small patch to add a check to ssl_init in src/gnutls.c, similar to the check already in src/openssl.c. With it, wget can still download over HTTPS and the memory usage stays within reasonable limits.

Thanks,

Gijs
=== modified file 'src/gnutls.c'
--- src/gnutls.c	2011-09-04 11:30:01 +0000
+++ src/gnutls.c	2011-10-31 22:58:38 +0000
@@ -59,10 +59,17 @@
    confused with actual gnutls functions -- such as the gnutls_read
    preprocessor macro.  */
 
+/* Becomes true if GnuTLS is initialized. */
+static bool ssl_initialized = false;
+
 static gnutls_certificate_credentials credentials;
 bool
 ssl_init ()
 {
+  /* GnuTLS should be initialized only once. */
+  if (ssl_initialized)
+    return true;
+
   const char *ca_directory;
   DIR *dir;
 
@@ -104,6 +111,9 @@
   if (opt.ca_cert)
     gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
                                             GNUTLS_X509_FMT_PEM);
+
+  ssl_initialized = true;
+
   return true;
 }
 

Reply via email to