telepathy-idle: Connection: fix a crash on Disconnect() during TLS verification
Simon McVittie
smcv at kemper.freedesktop.org
Wed May 1 09:01:42 PDT 2013
Module: telepathy-idle
Branch: master
Commit: fd4661d6e05b80536b48fa23566dc3db1f01d7ce
URL: http://cgit.freedesktop.org/telepathy/telepathy-idle/commit/?id=fd4661d6e05b80536b48fa23566dc3db1f01d7ce
Author: Will Thompson <will.thompson at collabora.co.uk>
Date: Tue Apr 30 15:21:13 2013 +0100
Connection: fix a crash on Disconnect() during TLS verification
Previously, priv->conn was NULL until the TCP session was established,
so _iface_shut_down() would take the "no connection yet; call
_finish_shutdown_idle_func in an idle" path. But the TLS channel would
get closed (because the TLSManager listens for state changes to
Disconnected and closes all channels), causing the ServerConnection to
call the connect_async() callback and emit ::disconnected, and hence
finish shutting down the connection there. Then the idle would crash,
because it doesn't take a ref to the connection.
We should really cancel the connect_async() call in the new path in
_iface_shut_down() to cope with the case where we're still waiting for
the TCP connection to be established for some other reason. That, and a
test for that, will follow.
---
src/idle-connection.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/idle-connection.c b/src/idle-connection.c
index 4176fef..b881295 100644
--- a/src/idle-connection.c
+++ b/src/idle-connection.c
@@ -593,7 +593,7 @@ static void _iface_disconnected(TpBaseConnection *self) {
/* we never got around to actually creating the connection
* iface object because we were still trying to connect, so
* don't try to send any traffic down it */
- if (priv->conn == NULL) {
+ if (!priv->sconn_connected) {
return;
}
@@ -619,6 +619,8 @@ static void _iface_shut_down(TpBaseConnection *base) {
* don't try to send any traffic down it */
if (priv->conn == NULL) {
g_idle_add(_finish_shutdown_idle_func, self);
+ } else if (!priv->sconn_connected) {
+ IDLE_DEBUG("TODO: cancel connecting");
} else {
idle_server_connection_disconnect_async(priv->conn, NULL, NULL, NULL);
}
@@ -710,11 +712,9 @@ static void _connection_connect_ready(GObject *source_object, GAsyncResult *res,
IDLE_DEBUG("idle_server_connection_connect failed: %s", error->message);
_connection_disconnect_with_gerror(conn, TP_CONNECTION_STATUS_REASON_NETWORK_ERROR, "debug-message", error);
g_error_free(error);
- g_object_unref(sconn);
return;
}
- priv->conn = sconn;
priv->sconn_connected = TRUE;
g_signal_connect(sconn, "received", (GCallback)(sconn_received_cb), conn);
@@ -761,6 +761,7 @@ static void _start_connecting_continue(IdleConnection *conn) {
g_signal_connect(sconn, "disconnected", (GCallback)(sconn_disconnected_cb), conn);
+ priv->conn = sconn;
idle_server_connection_connect_async(sconn, NULL, _connection_connect_ready, conn);
}
@@ -793,8 +794,8 @@ static void sconn_disconnected_cb(IdleServerConnection *sconn, IdleServerConnect
if (priv->quitting)
tp_reason = TP_CONNECTION_STATUS_REASON_REQUESTED;
- connection_disconnect_cb(conn, tp_reason);
priv->sconn_connected = FALSE;
+ connection_disconnect_cb(conn, tp_reason);
}
static void sconn_received_cb(IdleServerConnection *sconn, gchar *raw_msg, IdleConnection *conn) {
More information about the telepathy-commits
mailing list