changeset 14160:c8ebbc0110f4

[gaim-migrate @ 16808] gaim_ssl_connect's are now cancelable (without crashing, anyway) This was relatively easy, because the PRPLs already keep a reference to the GaimSslConnection. I just needed to update the core ssl code to keep track of the GaimProxyConnectInfo, and to call gaim_proxy_connect_cancel() when gaim_ssl_close() is called committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 17 Aug 2006 05:47:10 +0000
parents ff3db5cdeb9f
children 694aae55ab6d
files plugins/ssl/ssl-nss.c src/protocols/irc/irc.c src/sslconn.c src/sslconn.h
diffstat 4 files changed, 52 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/ssl/ssl-nss.c	Thu Aug 17 04:45:11 2006 +0000
+++ b/plugins/ssl/ssl-nss.c	Thu Aug 17 05:47:10 2006 +0000
@@ -237,16 +237,13 @@
 }
 
 static void
-ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond)
+ssl_nss_connect(GaimSslConnection *gsc)
 {
-	GaimSslConnection *gsc = (GaimSslConnection *)data;
 	GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1);
 	PRSocketOptionData socket_opt;
 
 	gsc->private_data = nss_data;
 
-	gsc->fd = source;
-
 	nss_data->fd = PR_ImportTCPSocket(gsc->fd);
 
 	if (nss_data->fd == NULL)
@@ -359,7 +356,7 @@
 {
 	ssl_nss_init,
 	ssl_nss_uninit,
-	ssl_nss_connect_cb,
+	ssl_nss_connect,
 	ssl_nss_close,
 	ssl_nss_read,
 	ssl_nss_write
--- a/src/protocols/irc/irc.c	Thu Aug 17 04:45:11 2006 +0000
+++ b/src/protocols/irc/irc.c	Thu Aug 17 05:47:10 2006 +0000
@@ -450,7 +450,7 @@
 	g_free(irc->inbuf);
 	if (irc->gsc) {
 		gaim_ssl_close(irc->gsc);
-	} else if (irc->fd > 0) {
+	} else if (irc->fd >= 0) {
 		close(irc->fd);
 	}
 	if (irc->timer)
--- a/src/sslconn.c	Thu Aug 17 04:45:11 2006 +0000
+++ b/src/sslconn.c	Thu Aug 17 05:47:10 2006 +0000
@@ -45,10 +45,14 @@
 		gaim_plugin_load(plugin);
 
 	ops = gaim_ssl_get_ops();
-	if (ops != NULL && ops->init != NULL)
-		return ops->init();
-	else
+	if ((ops == NULL) || (ops->init == NULL) || (ops->uninit == NULL) ||
+		(ops->connect == NULL) || (ops->close == NULL) ||
+		(ops->read == NULL) || (ops->write == NULL))
+	{
 		return FALSE;
+	}
+
+	return ops->init();
 }
 
 gboolean
@@ -62,25 +66,42 @@
 #endif
 }
 
+static void
+gaim_ssl_connect_cb(gpointer data, gint source, const gchar *error_message)
+{
+	GaimSslConnection *gsc;
+	GaimSslOps *ops;
+
+	gsc = data;
+	gsc->connect_info = NULL;
+
+	if (source < 0)
+	{
+		if (gsc->error_cb != NULL)
+			gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data);
+
+		gaim_ssl_close(gsc);
+		return;
+	}
+
+	gsc->fd = source;
+
+	ops = gaim_ssl_get_ops();
+	ops->connect(gsc);
+}
+
 GaimSslConnection *
 gaim_ssl_connect(GaimAccount *account, const char *host, int port,
 				 GaimSslInputFunction func, GaimSslErrorFunction error_func,
 				 void *data)
 {
 	GaimSslConnection *gsc;
-	GaimSslOps *ops;
-	GaimProxyConnectInfo *connect_info;
 
 	g_return_val_if_fail(host != NULL,            NULL);
 	g_return_val_if_fail(port != 0 && port != -1, NULL);
 	g_return_val_if_fail(func != NULL,            NULL);
 	g_return_val_if_fail(gaim_ssl_is_supported(), NULL);
 
-	ops = gaim_ssl_get_ops();
-
-	g_return_val_if_fail(ops != NULL, NULL);
-	g_return_val_if_fail(ops->connect_cb != NULL, NULL);
-
 	if (!_ssl_initialized)
 	{
 		if (!ssl_init())
@@ -89,15 +110,16 @@
 
 	gsc = g_new0(GaimSslConnection, 1);
 
+	gsc->fd              = -1;
 	gsc->host            = g_strdup(host);
 	gsc->port            = port;
 	gsc->connect_cb_data = data;
 	gsc->connect_cb      = func;
 	gsc->error_cb        = error_func;
 
-	connect_info = gaim_proxy_connect(account, host, port, ops->connect_cb, gsc);
+	gsc->connect_info = gaim_proxy_connect(account, host, port, gaim_ssl_connect_cb, gsc);
 
-	if (connect_info == NULL)
+	if (gsc->connect_info == NULL)
 	{
 		g_free(gsc->host);
 		g_free(gsc);
@@ -141,11 +163,6 @@
 	g_return_val_if_fail(func != NULL,            NULL);
 	g_return_val_if_fail(gaim_ssl_is_supported(), NULL);
 
-	ops = gaim_ssl_get_ops();
-
-	g_return_val_if_fail(ops != NULL, NULL);
-	g_return_val_if_fail(ops->connect_cb != NULL, NULL);
-
 	if (!_ssl_initialized)
 	{
 		if (!ssl_init())
@@ -157,8 +174,10 @@
 	gsc->connect_cb_data = data;
 	gsc->connect_cb      = func;
 	gsc->error_cb        = error_func;
+	gsc->fd              = fd;
 
-	ops->connect_cb(gsc, fd, GAIM_INPUT_READ);
+	ops = gaim_ssl_get_ops();
+	ops->connect(gsc);
 
 	return (GaimSslConnection *)gsc;
 }
@@ -171,14 +190,15 @@
 	g_return_if_fail(gsc != NULL);
 
 	ops = gaim_ssl_get_ops();
+	(ops->close)(gsc);
 
-	if (gsc->inpa)
+	if (gsc->connect_info != NULL)
+		gaim_proxy_connect_cancel(gsc->connect_info);
+
+	if (gsc->inpa > 0)
 		gaim_input_remove(gsc->inpa);
 
-	if (ops != NULL && ops->close != NULL)
-		(ops->close)(gsc);
-
-	if (gsc->fd != -1)
+	if (gsc->fd >= 0)
 		close(gsc->fd);
 
 	g_free(gsc->host);
@@ -195,11 +215,7 @@
 	g_return_val_if_fail(len  >  0,    0);
 
 	ops = gaim_ssl_get_ops();
-
-	if (ops != NULL && (ops->read) != NULL)
-		return (ops->read)(gsc, data, len);
-
-	return 0;
+	return (ops->read)(gsc, data, len);
 }
 
 size_t
@@ -212,11 +228,7 @@
 	g_return_val_if_fail(len  >  0,    0);
 
 	ops = gaim_ssl_get_ops();
-
-	if (ops != NULL && (ops->write) != NULL)
-		return (ops->write)(gsc, data, len);
-
-	return 0;
+	return (ops->write)(gsc, data, len);
 }
 
 void
@@ -245,9 +257,7 @@
 		return;
 
 	ops = gaim_ssl_get_ops();
-
-	if (ops != NULL && ops->uninit != NULL)
-		ops->uninit();
+	ops->uninit();
 
 	_ssl_initialized = FALSE;
 }
--- a/src/sslconn.h	Thu Aug 17 04:45:11 2006 +0000
+++ b/src/sslconn.h	Thu Aug 17 05:47:10 2006 +0000
@@ -54,6 +54,7 @@
 
 	int fd;
 	int inpa;
+	GaimProxyConnectInfo *connect_info;
 
 	void *private_data;
 };
@@ -61,13 +62,13 @@
 /**
  * SSL implementation operations structure.
  *
- * Every SSL implementation must provide one of these and register it.
+ * Every SSL implementation must provide all of these and register it.
  */
 typedef struct
 {
 	gboolean (*init)(void);
 	void (*uninit)(void);
-	GaimInputFunction connect_cb;
+	void (*connect)(GaimSslConnection *gsc);
 	void (*close)(GaimSslConnection *gsc);
 	size_t (*read)(GaimSslConnection *gsc, void *data, size_t len);
 	size_t (*write)(GaimSslConnection *gsc, const void *data, size_t len);