Skip to content

Commit

Permalink
Initial SM support: handle reconnection
Browse files Browse the repository at this point in the history
  • Loading branch information
rufferson committed Dec 16, 2020
1 parent 7121dbf commit 260c2e9
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#endif

static guint disco_reply_timeout = 5;
static GHashTable *connector_stash = NULL;

#define DISCONNECT_TIMEOUT 5

Expand Down Expand Up @@ -1309,6 +1310,10 @@ gabble_connection_class_init (GabbleConnectionClass *gabble_connection_class)
conn_contact_info_class_init (gabble_connection_class);

tp_base_contact_list_mixin_class_init (parent_class);

/* another static per-process leak */
connector_stash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
}

static void
Expand Down Expand Up @@ -1943,6 +1948,63 @@ next_fallback_server (GabbleConnection *self,
return TRUE;
}

static gboolean
resuming_cb (WockyPorter *porter,
WockyStanza *resume,
GabbleConnection *self)
{
TpBaseConnection *base = TP_BASE_CONNECTION (self);
DEBUG ("");
/* signal state change */
tp_svc_connection_emit_status_changed (base,
TP_CONNECTION_STATUS_CONNECTING, TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
/* we want auto-resumption */
return TRUE;
}

static void
resumed_cb (WockyPorter *porter,
GabbleConnection *self)
{
TpBaseConnection *base = TP_BASE_CONNECTION (self);
DEBUG ("");
tp_svc_connection_emit_status_changed (base,
TP_CONNECTION_STATUS_CONNECTED, TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED);
}

static void
resume_done_cb (WockyPorter *porter,
GabbleConnection *self)
{
DEBUG ("");
}

static gboolean
resume_failed_cb (WockyPorter *porter,
GabbleConnection *self)
{
WockyConnector *connector = NULL;
GError e = { TP_ERROR, TP_ERROR_CONNECTION_LOST,
"Connection resumption not possible, creating new connection" };

DEBUG ("Connection resumption not possible, stealing connector and closing");
g_object_get (G_OBJECT (porter),
"connector", &connector,
NULL);
g_hash_table_insert (connector_stash,
g_strdup (conn_util_get_bare_self_jid (self)), connector);
/* We're gonna die soon, need to break ties with the world of livings */
g_signal_handlers_disconnect_by_data (porter, self);

/* Changing the state to Disconnect will call connection_shut_down which
* will properly close the porter. */
gabble_connection_disconnect_with_tp_error (self, &e,
TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);

/* we want auto-reconnection to be confirmed by the new connection object */
return FALSE;
}

/**
* connector_connected
*
Expand Down Expand Up @@ -2026,6 +2088,20 @@ connector_connected (GabbleConnection *self,
G_CALLBACK (remote_closed_cb), self);
g_signal_connect (priv->porter, "remote-error",
G_CALLBACK (remote_error_cb), self);
#if WOCKY_API_VERSION >= G_ENCODE_VERSION(0,2)
DEBUG ("");
/* SM events - happy path */
g_signal_connect (priv->porter, "resuming",
G_CALLBACK (resuming_cb), self);
g_signal_connect (priv->porter, "resumed",
G_CALLBACK (resumed_cb), self);
g_signal_connect (priv->porter, "resume-done",
G_CALLBACK (resume_done_cb), self);
/* SM events - failure path, we need one of `resume-failed` and `reconnected`
*/
g_signal_connect (priv->porter, "resume-failed",
G_CALLBACK (resume_failed_cb), self);
#endif /* WOCKY_API_VERSION >= 0.2 */

g_signal_emit_by_name (self, "porter-available", priv->porter);
connect_iq_callbacks (self);
Expand Down Expand Up @@ -2253,6 +2329,19 @@ _gabble_connection_connect (TpBaseConnection *base,
g_assert (priv->resource != NULL);

jid = gabble_encode_jid (priv->username, priv->stream_server, NULL);
priv->connector = g_hash_table_lookup (connector_stash, jid);
if (priv->connector != NULL)
{
g_hash_table_remove (connector_stash, jid);
/* fast lane is ready */
DEBUG ("Continue with existing connector");
priv->cancellable = g_cancellable_new ();
wocky_connector_continue_async (priv->connector, priv->cancellable,
connector_connect_cb, conn);
g_free (jid);
return TRUE;
}

tls_handler = WOCKY_TLS_HANDLER (priv->server_tls_manager);
priv->connector = wocky_connector_new (jid, priv->password, priv->resource,
WOCKY_AUTH_REGISTRY (priv->auth_manager),
Expand Down

0 comments on commit 260c2e9

Please sign in to comment.