Commit 89460f3f57b6efa906263a19b982f8a7859b15c9

Carlos Martín Nieto 2012-05-03T14:07:55

ssl: teardown the connection on close This should help us free some resources, though the libraries do keep some buffers allocated regardless.

diff --git a/src/netops.c b/src/netops.c
index 67a361e..7ee720d 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -166,9 +166,35 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
 	buf->offset -= cons;
 }
 
+int gitno_ssl_teardown(git_transport *t)
+{
+	int ret = ret;
+
+	if (!t->encrypt)
+		return 0;
+
 #ifdef GIT_GNUTLS
+	gnutls_deinit(t->ssl.session);
+	gnutls_certificate_free_credentials(t->ssl.cred);
+	gnutls_global_deinit();
+#elif defined(GIT_OPENSSL)
+
+	do {
+		ret = SSL_shutdown(t->ssl.ssl);
+	} while (ret == 0);
+	if (ret < 0)
+		return ssl_set_error(&t->ssl, ret);
+
+	SSL_free(t->ssl.ssl);
+	SSL_CTX_free(t->ssl.ctx);
+#endif
+	return 0;
+}
+
+
 static int ssl_setup(git_transport *t)
 {
+#ifdef GIT_GNUTLS
 	int ret;
 
 	if ((ret = gnutls_global_init()) < 0)
@@ -199,11 +225,9 @@ static int ssl_setup(git_transport *t)
 
 on_error:
 	gnutls_deinit(t->ssl.session);
+	gnutls_global_deinit();
 	return -1;
-}
 #elif defined(GIT_OPENSSL)
-static int ssl_setup(git_transport *t)
-{
 	int ret;
 
 	SSL_library_init();
@@ -225,9 +249,11 @@ static int ssl_setup(git_transport *t)
 		return ssl_set_error(&t->ssl, ret);
 
 	return 0;
-}
+#else
+	GIT_UNUSED(t);
+	return 0;
 #endif
-
+}
 int gitno_connect(git_transport *t, const char *host, const char *port)
 {
 	struct addrinfo *info = NULL, *p;
@@ -268,10 +294,8 @@ int gitno_connect(git_transport *t, const char *host, const char *port)
 	t->socket = s;
 	freeaddrinfo(info);
 
-#ifdef GIT_SSL
 	if (t->encrypt && ssl_setup(t) < 0)
 		return -1;
-#endif
 
 	return 0;
 }
diff --git a/src/netops.h b/src/netops.h
index 8591a8e..4976f87 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -30,6 +30,7 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons);
 int gitno_connect(git_transport *t, const char *host, const char *port);
 int gitno_send(git_transport *t, const char *msg, size_t len, int flags);
 int gitno_close(GIT_SOCKET s);
+int gitno_ssl_teardown(git_transport *t);
 int gitno_send_chunk_size(int s, size_t len);
 int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
 
diff --git a/src/transports/http.c b/src/transports/http.c
index 6746f68..36cc66c 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -605,6 +605,9 @@ on_error:
 
 static int http_close(git_transport *transport)
 {
+	if (gitno_ssl_teardown(transport) < 0)
+		return -1;
+
 	if (gitno_close(transport->socket) < 0) {
 		giterr_set(GITERR_OS, "Failed to close the socket: %s", strerror(errno));
 		return -1;