[telepathy-gabble/master] connection.c: Use WockyConnector and the Wocky API
Guillaume Desmottes
guillaume.desmottes at collabora.co.uk
Fri Sep 11 07:56:16 PDT 2009
---
src/connection.c | 737 +++++++++++++++++++-----------------------------------
1 files changed, 256 insertions(+), 481 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index 74daca2..8c26eb6 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -30,6 +30,7 @@
#include <dbus/dbus-glib-lowlevel.h>
#include <glib-object.h>
#include <loudmouth/loudmouth.h>
+#include <wocky/wocky-connector.h>
#include <telepathy-glib/channel-manager.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/enums.h>
@@ -152,9 +153,10 @@ enum
struct _GabbleConnectionPrivate
{
+ WockyConnector *connector;
+
LmMessageHandler *iq_disco_cb;
LmMessageHandler *iq_unknown_cb;
- LmMessageHandler *stream_error_cb;
LmMessageHandler *pubsub_msg_cb;
LmMessageHandler *olpc_msg_cb;
LmMessageHandler *olpc_presence_cb;
@@ -227,6 +229,9 @@ static void connection_capabilities_update_cb (GabblePresenceCache *cache,
const GabbleCapabilitySet *new_cap_set,
gpointer user_data);
+static gboolean gabble_connection_refresh_capabilities (GabbleConnection *self,
+ GabbleCapabilitySet **old_out);
+
static GPtrArray *
_gabble_connection_create_channel_managers (TpBaseConnection *conn)
{
@@ -389,7 +394,7 @@ gabble_connection_init (GabbleConnection *self)
DEBUG("Initializing (GabbleConnection *)%p", self);
self->priv = priv;
- self->lmconn = lm_connection_new (NULL);
+ self->lmconn = NULL;
/* Override LM domain log handler. */
gabble_lm_debug ();
@@ -897,7 +902,8 @@ _unref_lm_connection (gpointer data)
{
LmConnection *conn = (LmConnection *) data;
- lm_connection_unref (conn);
+ if (conn != NULL)
+ lm_connection_unref (conn);
return FALSE;
}
@@ -950,22 +956,25 @@ gabble_connection_dispose (GObject *object)
g_hash_table_destroy (self->avatar_requests);
- /* if this is not already the case, we'll crash anyway */
- g_assert (!lm_connection_is_open (self->lmconn));
-
g_assert (priv->iq_disco_cb == NULL);
g_assert (priv->iq_unknown_cb == NULL);
- g_assert (priv->stream_error_cb == NULL);
g_assert (priv->pubsub_msg_cb == NULL);
g_assert (priv->olpc_msg_cb == NULL);
g_assert (priv->olpc_presence_cb == NULL);
+ if (priv->connector != NULL)
+ {
+ g_object_unref (priv->connector);
+ priv->connector = NULL;
+ }
+
/*
* The Loudmouth connection can't be unref'd immediately because this
* function might (indirectly) return into Loudmouth code which expects the
* connection to always be there.
*/
g_idle_add (_unref_lm_connection, self->lmconn);
+ lm_connection_shutdown (self->lmconn);
g_hash_table_destroy (priv->client_caps);
gabble_capability_set_free (priv->all_caps);
@@ -1249,38 +1258,212 @@ static LmHandlerResult connection_iq_disco_cb (LmMessageHandler *,
LmConnection *, LmMessage *, gpointer);
static LmHandlerResult connection_iq_unknown_cb (LmMessageHandler *,
LmConnection *, LmMessage *, gpointer);
-static LmHandlerResult connection_stream_error_cb (LmMessageHandler *,
- LmConnection *, LmMessage *, gpointer);
-static LmSSLResponse connection_ssl_cb (LmSSL *, LmSSLStatus, gpointer);
-static void connection_open_cb (LmConnection *, gboolean, gpointer);
-static void connection_auth_cb (LmConnection *, gboolean, gpointer);
static void connection_disco_cb (GabbleDisco *, GabbleDiscoRequest *,
const gchar *, const gchar *, LmMessageNode *, GError *, gpointer);
-static void connection_disconnected_cb (LmConnection *, LmDisconnectReason,
- gpointer);
+static void
+remote_closed_cb (WockyPorter *porter,
+ GabbleConnection *self)
+{
+ TpBaseConnection *base = TP_BASE_CONNECTION (self);
-static gboolean
-do_connect (GabbleConnection *conn, GError **error)
+ if (base->status == TP_CONNECTION_STATUS_DISCONNECTED)
+ /* Ignore if we are already disconnecting/disconnected */
+ return;
+
+ DEBUG ("server closed its XMPP stream; close ours");
+
+ /* Changing the state to Disconnect will call connection_shut_down which
+ * will properly close the porter. */
+ tp_base_connection_change_status ((TpBaseConnection *) self,
+ TP_CONNECTION_STATUS_DISCONNECTED,
+ TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
+}
+
+static void
+force_close_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GError *lmerror = NULL;
+ GabbleConnection *self = GABBLE_CONNECTION (user_data);
+ TpBaseConnection *base = TP_BASE_CONNECTION (self);
+ GError *error = NULL;
- DEBUG ("calling lm_connection_open");
+ if (!wocky_porter_force_close_finish (WOCKY_PORTER (source), res, &error))
+ {
+ DEBUG ("force close failed: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ DEBUG ("connection properly closed (forced)");
+ }
+
+ tp_base_connection_finish_shutdown (base);
+}
+
+static void
+remote_error_cb (WockyPorter *porter,
+ GQuark domain,
+ gint code,
+ gchar *msg,
+ GabbleConnection *self)
+{
+ TpConnectionStatusReason reason = TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED;
+ TpBaseConnection *base = (TpBaseConnection *) self;
- if (!lm_connection_open (conn->lmconn, connection_open_cb,
- conn, NULL, &lmerror))
+ if (base->status == TP_CONNECTION_STATUS_DISCONNECTED)
+ /* Ignore if we are already disconnecting/disconnected */
+ return;
+
+ if (domain == WOCKY_XMPP_STREAM_ERROR)
{
- DEBUG ("lm_connection_open failed %s", lmerror->message);
+ /* stream error */
+ DEBUG ("Received stream error (%u): %s\n", code, msg);
- g_set_error (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR,
- "lm_connection_open failed: %s", lmerror->message);
+ if (code == WOCKY_XMPP_STREAM_ERROR_CONFLICT)
+ {
+ /* Another client with the same resource just appeared, we're going
+ * down. */
+ DEBUG ("Another client appeared with the same resource");
+ reason = TP_CONNECTION_STATUS_REASON_NAME_IN_USE;
+ }
+ }
+ else
+ {
+ DEBUG ("remote error: %s", msg);
+ }
- g_error_free (lmerror);
+ DEBUG ("Force closing of the connection");
+ wocky_porter_force_close_async (self->lmconn, NULL, force_close_cb, self);
- return FALSE;
+ tp_base_connection_change_status ((TpBaseConnection *) self,
+ TP_CONNECTION_STATUS_DISCONNECTED, reason);
+}
+
+/**
+ * connector_connect_cb
+ *
+ * Stage 2 of connecting, this callback if fired once the connect operation
+ * has been finised. It checks if the connection succeed, create and start the
+ * WockyPorter. It sends a discovery request to find the server's features.
+ */
+static void
+connector_connect_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GabbleConnection *self = GABBLE_CONNECTION (user_data);
+ GabbleConnectionPrivate *priv = self->priv;
+ TpBaseConnection *base = (TpBaseConnection *) self;
+ TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
+ TP_HANDLE_TYPE_CONTACT);
+ WockyXmppConnection *conn;
+ GError *error = NULL;
+ gchar *jid = NULL;
+
+ conn = wocky_connector_connect_finish (WOCKY_CONNECTOR (source), res, &error,
+ &jid);
+
+ /* We don't need the connector any more */
+ g_object_unref (priv->connector);
+ priv->connector = NULL;
+
+ if (conn == NULL)
+ {
+ TpConnectionStatusReason reason = \
+ TP_CONNECTION_STATUS_REASON_NETWORK_ERROR;
+
+ DEBUG ("connection failed: %s", error->message);
+
+ if (g_error_matches (error, WOCKY_CONNECTOR_ERROR,
+ WOCKY_CONNECTOR_ERROR_SESSION_DENIED))
+ {
+ reason = TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED;
+ }
+ else if (g_error_matches (error, WOCKY_XMPP_STREAM_ERROR,
+ WOCKY_XMPP_STREAM_ERROR_HOST_UNKNOWN))
+ {
+ /* If we get this while we're logging in, it's because we're trying to
+ * connect to foo at bar.com but the server doesn't know about bar.com,
+ * probably because the user entered a non-GTalk JID into a GTalk
+ * profile that forces the server.
+ */
+ DEBUG ("got <host-unknown> while connecting");
+ reason = TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED;
+ }
+
+ /* FIXME: check SSL errors */
+ tp_base_connection_change_status (base,
+ TP_CONNECTION_STATUS_DISCONNECTED, reason);
+
+ g_error_free (error);
+ return;
}
- return TRUE;
+ DEBUG ("connected (jid: %s)", jid);
+
+ self->lmconn = wocky_porter_new (conn);
+
+ g_signal_connect (self->lmconn, "remote-closed",
+ G_CALLBACK (remote_closed_cb), self);
+ g_signal_connect (self->lmconn, "remote-error",
+ G_CALLBACK (remote_error_cb), self);
+
+ lm_connection_register_previous_handler (self->lmconn);
+ wocky_porter_start (self->lmconn);
+
+ base->self_handle = tp_handle_ensure (contact_handles, jid, NULL, &error);
+
+ if (base->self_handle == 0)
+ {
+ DEBUG ("couldn't get our self handle: %s", error->message);
+
+ g_error_free (error);
+
+ tp_base_connection_change_status ((TpBaseConnection *) self,
+ TP_CONNECTION_STATUS_DISCONNECTED,
+ TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
+
+ return;
+ }
+
+ /* update priv->resource and priv->stream_server from the server's JID */
+ if (!_gabble_connection_set_properties_from_account (self, jid, &error))
+ {
+ DEBUG ("couldn't parse our own JID: %s", error->message);
+
+ g_error_free (error);
+
+ tp_base_connection_change_status ((TpBaseConnection *) self,
+ TP_CONNECTION_STATUS_DISCONNECTED,
+ TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
+
+ return;
+ }
+
+ DEBUG ("Created self handle %d, our JID is %s", base->self_handle, jid);
+
+ /* set initial capabilities */
+ gabble_connection_refresh_capabilities (self, NULL);
+
+ if (!gabble_disco_request_with_timeout (self->disco, GABBLE_DISCO_TYPE_INFO,
+ priv->stream_server, NULL,
+ disco_reply_timeout,
+ connection_disco_cb, self,
+ G_OBJECT (self), &error))
+ {
+ DEBUG ("sending disco request failed: %s",
+ error->message);
+
+ g_error_free (error);
+
+ tp_base_connection_change_status ((TpBaseConnection *) self,
+ TP_CONNECTION_STATUS_DISCONNECTED,
+ TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
+ }
+
+ g_free (jid);
}
static void
@@ -1291,7 +1474,6 @@ connect_callbacks (TpBaseConnection *base)
g_assert (priv->iq_disco_cb == NULL);
g_assert (priv->iq_unknown_cb == NULL);
- g_assert (priv->stream_error_cb == NULL);
g_assert (priv->pubsub_msg_cb == NULL);
g_assert (priv->olpc_msg_cb == NULL);
g_assert (priv->olpc_presence_cb == NULL);
@@ -1308,12 +1490,6 @@ connect_callbacks (TpBaseConnection *base)
LM_MESSAGE_TYPE_IQ,
LM_HANDLER_PRIORITY_LAST);
- priv->stream_error_cb = lm_message_handler_new (connection_stream_error_cb,
- conn, NULL);
- lm_connection_register_message_handler (conn->lmconn, priv->stream_error_cb,
- LM_MESSAGE_TYPE_STREAM_ERROR,
- LM_HANDLER_PRIORITY_LAST);
-
priv->pubsub_msg_cb = lm_message_handler_new (pubsub_msg_event_cb,
conn, NULL);
lm_connection_register_message_handler (conn->lmconn, priv->pubsub_msg_cb,
@@ -1341,7 +1517,6 @@ disconnect_callbacks (TpBaseConnection *base)
g_assert (priv->iq_disco_cb != NULL);
g_assert (priv->iq_unknown_cb != NULL);
- g_assert (priv->stream_error_cb != NULL);
g_assert (priv->pubsub_msg_cb != NULL);
g_assert (priv->olpc_msg_cb != NULL);
g_assert (priv->olpc_presence_cb != NULL);
@@ -1356,11 +1531,6 @@ disconnect_callbacks (TpBaseConnection *base)
lm_message_handler_unref (priv->iq_unknown_cb);
priv->iq_unknown_cb = NULL;
- lm_connection_unregister_message_handler (conn->lmconn,
- priv->stream_error_cb, LM_MESSAGE_TYPE_STREAM_ERROR);
- lm_message_handler_unref (priv->stream_error_cb);
- priv->stream_error_cb = NULL;
-
lm_connection_unregister_message_handler (conn->lmconn, priv->pubsub_msg_cb,
LM_MESSAGE_TYPE_MESSAGE);
lm_message_handler_unref (priv->pubsub_msg_cb);
@@ -1381,14 +1551,12 @@ disconnect_callbacks (TpBaseConnection *base)
* _gabble_connection_connect
*
* Use the stored server & authentication details to commence
- * the stages for connecting to the server and authenticating. Will
- * re-use an existing LmConnection if it is present, or create it
- * if necessary.
+ * the stages for connecting to the server and authenticating.
+ * Will create a WockyConnector.
*
- * Stage 1 is _gabble_connection_connect calling lm_connection_open
- * Stage 2 is connection_open_cb calling lm_connection_authenticate
- * Stage 3 is connection_auth_cb initiating service discovery
- * Stage 4 is connection_disco_cb advertising initial presence, requesting
+ * Stage 1 is _gabble_connection_connect calling wocky_connector_connect_async
+ * Stage 2 is connector_connect_cb initiating service discovery
+ * Stage 3 is connection_disco_cb advertising initial presence, requesting
* the roster and setting the CONNECTED state
*/
static gboolean
@@ -1399,15 +1567,15 @@ _gabble_connection_connect (TpBaseConnection *base,
GabbleConnectionPrivate *priv = conn->priv;
char *jid;
+ g_assert (priv->connector == NULL);
g_assert (priv->port <= G_MAXUINT16);
g_assert (priv->stream_server != NULL);
g_assert (priv->username != NULL);
g_assert (priv->password != NULL);
g_assert (priv->resource != NULL);
- g_assert (lm_connection_is_open (conn->lmconn) == FALSE);
jid = gabble_encode_jid (priv->username, priv->stream_server, NULL);
- lm_connection_set_jid (conn->lmconn, jid);
+ priv->connector = wocky_connector_new (jid, priv->password, priv->resource);
g_free (jid);
/* If the UI explicitly specified a port or a server, pass them to Loudmouth
@@ -1431,123 +1599,82 @@ _gabble_connection_connect (TpBaseConnection *base,
DEBUG ("disabling SRV because \"server\" or \"old-ssl\" was specified "
"or port was not 5222, will connect to %s", server);
- lm_connection_set_server (conn->lmconn, server);
- lm_connection_set_port (conn->lmconn, priv->port);
+ g_object_set (priv->connector,
+ "xmpp-server", server,
+ "xmpp-port", priv->port,
+ NULL);
}
else
{
DEBUG ("letting SRV lookup decide server and port");
}
- if (priv->https_proxy_server)
- {
- LmProxy *proxy;
-
- proxy = lm_proxy_new_with_server (LM_PROXY_TYPE_HTTP,
- priv->https_proxy_server, priv->https_proxy_port);
-
- lm_connection_set_proxy (conn->lmconn, proxy);
-
- lm_proxy_unref (proxy);
- }
+ g_object_set (priv->connector,
+ "ignore-ssl-errors", priv->ignore_ssl_errors,
+ NULL);
if (priv->old_ssl)
{
- LmSSL *ssl = lm_ssl_new (NULL, connection_ssl_cb, conn, NULL);
- lm_connection_set_ssl (conn->lmconn, ssl);
- lm_ssl_unref (ssl);
+ g_object_set (priv->connector,
+ "tls-required", FALSE,
+ NULL);
}
else
{
- LmSSL *ssl = lm_ssl_new (NULL, connection_ssl_cb, conn, NULL);
- lm_connection_set_ssl (conn->lmconn, ssl);
-
- /* Try to use StartTLS if possible, but be careful about
- allowing SSL errors in that default case. */
- lm_ssl_use_starttls (ssl, TRUE, priv->require_encryption);
-
- if (!priv->require_encryption)
- priv->ignore_ssl_errors = TRUE;
-
- lm_ssl_unref (ssl);
+ g_object_set (priv->connector,
+ "tls-required", priv->require_encryption,
+ "plaintext-auth-allowed", !priv->require_encryption,
+ NULL);
}
- lm_connection_set_keep_alive_rate (conn->lmconn, priv->keepalive_interval);
-
- lm_connection_set_disconnect_function (conn->lmconn,
- connection_disconnected_cb,
- conn,
- NULL);
+ /* FIXME: support proxy server */
+ /* FIXME: support keep alive */
+ /* FIXME: support register */
- return do_connect (conn, error);
-}
+ DEBUG ("Start connecting");
+ wocky_connector_connect_async (priv->connector,
+ connector_connect_cb, conn);
+ return TRUE;
+}
static void
-connection_disconnected_cb (LmConnection *lmconn,
- LmDisconnectReason lm_reason,
- gpointer user_data)
+closed_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GabbleConnection *conn = GABBLE_CONNECTION (user_data);
- TpBaseConnection *base = (TpBaseConnection *) user_data;
-
- g_assert (conn->lmconn == lmconn);
-
- DEBUG ("called with reason %u", lm_reason);
+ GabbleConnection *self = GABBLE_CONNECTION (user_data);
+ TpBaseConnection *base = TP_BASE_CONNECTION (self);
+ GError *error = NULL;
- /* if we were expecting this disconnection, we're done so can tell
- * the connection manager to unref us. otherwise it's a network error
- * or some other screw up we didn't expect, so we emit the status
- * change */
- if (base->status == TP_CONNECTION_STATUS_DISCONNECTED)
+ if (!wocky_porter_close_finish (WOCKY_PORTER (source), res, &error))
{
- DEBUG ("expected; emitting DISCONNECTED");
- tp_base_connection_finish_shutdown ((TpBaseConnection *) conn);
+ DEBUG ("close failed: %s", error->message);
+ g_error_free (error);
}
else
{
- DEBUG ("unexpected; calling tp_base_connection_change_status");
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
+ DEBUG ("connection properly closed");
}
- /* Under certain circumstances, Loudmouth would end up calling this twice,
- * because sometimes it calls it in response to a stream error, and sometimes
- * it doesn't. (It depends on the error!) We don't want this to be called
- * twice, so:
- */
- lm_connection_set_disconnect_function (lmconn, NULL, NULL, NULL);
+ tp_base_connection_finish_shutdown (base);
}
-
static void
connection_shut_down (TpBaseConnection *base)
{
- GabbleConnection *conn = GABBLE_CONNECTION (base);
+ GabbleConnection *self = GABBLE_CONNECTION (base);
- g_assert (GABBLE_IS_CONNECTION (conn));
-
- /* If we're shutting down by user request, we don't want to be
- * unreffed until the LM connection actually closes; the event handler
- * will tell the base class that shutdown has finished.
- *
- * On the other hand, if we're shutting down because the connection
- * suffered a network error, the LM connection will already be closed,
- * so just tell the base class to finish shutting down immediately.
- */
- if (lm_connection_is_open (conn->lmconn))
+ if (self->lmconn != NULL)
{
- DEBUG ("still open; calling lm_connection_close");
- lm_connection_close (conn->lmconn, NULL);
+ /* FIXME: set a timer */
+ DEBUG ("connection still open; closing it");
+ wocky_porter_close_async (self->lmconn, NULL, closed_cb, self);
}
else
{
- /* lm_connection_is_open() returns FALSE if LmConnection is in the
- * middle of connecting, so call this just in case */
- lm_connection_cancel_open (conn->lmconn);
- DEBUG ("closed; emitting DISCONNECTED");
+ /* FIXME: cancel connecting if we are connecting */
tp_base_connection_finish_shutdown (base);
}
}
@@ -1911,361 +2038,9 @@ connection_iq_unknown_cb (LmMessageHandler *handler,
}
/**
- * connection_stream_error_cb
- *
- * Called by loudmouth when we get stream error, which means that
- * we're about to close the connection. The message contains the reason
- * for the connection hangup.
- */
-static LmHandlerResult
-connection_stream_error_cb (LmMessageHandler *handler,
- LmConnection *connection,
- LmMessage *message,
- gpointer user_data)
-{
- GabbleConnection *conn = GABBLE_CONNECTION (user_data);
- TpConnectionStatusReason r = TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED;
-
- g_assert (connection == conn->lmconn);
-
- NODE_DEBUG (message->node, "got stream error");
-
- if (lm_message_node_get_child (message->node, "conflict") != NULL)
- {
- /* Another client with the same resource just appeared, we're going down.
- */
- DEBUG ("found <conflict> node");
- r = TP_CONNECTION_STATUS_REASON_NAME_IN_USE;
- }
- else if (lm_message_node_get_child (message->node, "host-unknown") != NULL)
- {
- /* If we get this while we're logging in, it's because we're trying to
- * connect to foo at bar.com but the server doesn't know about bar.com,
- * probably because the user entered a non-GTalk JID into a GTalk profile
- * that forces the server.
- */
- if (conn->parent.status == TP_CONNECTION_STATUS_CONNECTING)
- {
- DEBUG ("found <host-unknown> and we're connecting");
- r = TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED;
- }
- }
-
- if (r != TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED)
- {
- DEBUG ("changing status to Disconnected for reason %u", r);
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED, r);
- }
-
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-}
-
-/**
- * connection_ssl_cb
- *
- * If we're doing old SSL, this function gets called if the certificate
- * is dodgy.
- */
-static LmSSLResponse
-connection_ssl_cb (LmSSL *lmssl,
- LmSSLStatus status,
- gpointer data)
-{
- GabbleConnection *conn = GABBLE_CONNECTION (data);
- GabbleConnectionPrivate *priv = conn->priv;
- const char *reason;
- TpConnectionStatusReason tp_reason;
-
- switch (status) {
- case LM_SSL_STATUS_NO_CERT_FOUND:
- reason = "The server doesn't provide a certificate.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED;
- break;
- case LM_SSL_STATUS_UNTRUSTED_CERT:
- reason = "The certificate can not be trusted.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_UNTRUSTED;
- break;
- case LM_SSL_STATUS_CERT_EXPIRED:
- reason = "The certificate has expired.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_EXPIRED;
- break;
- case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
- reason = "The certificate has not been activated.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED;
- break;
- case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
- reason = "The server hostname doesn't match the one in the certificate.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH;
- break;
- case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH:
- reason = "The fingerprint doesn't match the expected value.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH;
- break;
- case LM_SSL_STATUS_GENERIC_ERROR:
- reason = "An unknown SSL error occurred.";
- tp_reason = TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR;
- break;
- default:
- g_assert_not_reached ();
- reason = "Unknown SSL error code from Loudmouth.";
- tp_reason = TP_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR;
- break;
- }
-
- DEBUG ("called: %s", reason);
-
- if (priv->ignore_ssl_errors)
- {
- return LM_SSL_RESPONSE_CONTINUE;
- }
- else
- {
- priv->ssl_error = tp_reason;
- return LM_SSL_RESPONSE_STOP;
- }
-}
-
-static void
-do_auth (GabbleConnection *conn)
-{
- GabbleConnectionPrivate *priv = conn->priv;
- GError *error = NULL;
-
- DEBUG ("authenticating with username: %s, password: <hidden>, resource: %s",
- priv->username, priv->resource);
-
- if (!lm_connection_authenticate (conn->lmconn, priv->username,
- priv->password, priv->resource, connection_auth_cb, conn, NULL,
- &error))
- {
- DEBUG ("failed: %s", error->message);
- g_error_free (error);
-
- /* the reason this function can fail is through network errors,
- * authentication failures are reported to our auth_cb */
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
- }
-}
-
-static void
-registration_finished_cb (GabbleRegister *reg,
- gboolean success,
- gint err_code,
- const gchar *err_msg,
- gpointer user_data)
-{
- GabbleConnection *conn = GABBLE_CONNECTION (user_data);
- TpBaseConnection *base = (TpBaseConnection *) conn;
-
- if (base->status != TP_CONNECTION_STATUS_CONNECTING)
- {
- g_assert (base->status == TP_CONNECTION_STATUS_DISCONNECTED);
- return;
- }
-
- DEBUG ("%s", (success) ? "succeeded" : "failed");
-
- g_object_unref (reg);
-
- if (success)
- {
- do_auth (conn);
- }
- else
- {
- DEBUG ("err_code = %d, err_msg = '%s'",
- err_code, err_msg);
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- (err_code == TP_ERROR_NOT_YOURS) ?
- TP_CONNECTION_STATUS_REASON_NAME_IN_USE :
- TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED);
- }
-}
-
-static void
-do_register (GabbleConnection *conn)
-{
- GabbleRegister *reg;
-
- reg = gabble_register_new (conn);
-
- g_signal_connect (reg, "finished", (GCallback) registration_finished_cb,
- conn);
-
- gabble_register_start (reg);
-}
-
-/**
- * connection_open_cb
- *
- * Stage 2 of connecting, this function is called by loudmouth after the
- * result of the non-blocking lm_connection_open call is known. It makes
- * a request to authenticate the user with the server, or optionally
- * registers user on the server first.
- */
-static void
-connection_open_cb (LmConnection *lmconn,
- gboolean success,
- gpointer data)
-{
- GabbleConnection *conn = GABBLE_CONNECTION (data);
- GabbleConnectionPrivate *priv = conn->priv;
- TpBaseConnection *base = (TpBaseConnection *) conn;
-
- if ((base->status != TP_CONNECTION_STATUS_CONNECTING) &&
- (base->status != TP_INTERNAL_CONNECTION_STATUS_NEW))
- {
- g_assert (base->status == TP_CONNECTION_STATUS_DISCONNECTED);
- return;
- }
-
- g_assert (priv);
- g_assert (lmconn == conn->lmconn);
-
- if (!success)
- {
- if (lm_connection_get_proxy (lmconn))
- {
- DEBUG ("failed, retrying without proxy");
-
- lm_connection_set_proxy (lmconn, NULL);
-
- if (do_connect (conn, NULL))
- {
- return;
- }
- }
- else
- {
- DEBUG ("failed");
- }
-
- if (priv->ssl_error)
- {
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- priv->ssl_error);
- }
- else
- {
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
- }
-
- return;
- }
-
- if (!priv->do_register)
- do_auth (conn);
- else
- do_register (conn);
-}
-
-/**
- * connection_auth_cb
- *
- * Stage 3 of connecting, this function is called by loudmouth after the
- * result of the non-blocking lm_connection_authenticate call is known.
- * It sends a discovery request to find the server's features.
- */
-static void
-connection_auth_cb (LmConnection *lmconn,
- gboolean success,
- gpointer data)
-{
- GabbleConnection *conn = GABBLE_CONNECTION (data);
- TpBaseConnection *base = (TpBaseConnection *) conn;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GabbleConnectionPrivate *priv = conn->priv;
- GError *error = NULL;
- const gchar *jid;
-
- if (base->status != TP_CONNECTION_STATUS_CONNECTING)
- {
- g_assert (base->status == TP_CONNECTION_STATUS_DISCONNECTED);
- return;
- }
-
- g_assert (priv);
- g_assert (lmconn == conn->lmconn);
-
- if (!success)
- {
- DEBUG ("failed");
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED);
-
- return;
- }
-
-
- jid = lm_connection_get_full_jid (lmconn);
-
- base->self_handle = tp_handle_ensure (contact_handles, jid, NULL, &error);
-
- if (base->self_handle == 0)
- {
- DEBUG ("couldn't get our self handle: %s", error->message);
-
- g_error_free (error);
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
-
- return;
- }
-
- /* update priv->resource and priv->stream_server from the server's JID */
- if (!_gabble_connection_set_properties_from_account (conn, jid, &error))
- {
- DEBUG ("couldn't parse our own JID: %s", error->message);
-
- g_error_free (error);
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
-
- return;
- }
-
- DEBUG ("Created self handle %d, our JID is %s", base->self_handle, jid);
-
- /* set initial capabilities */
- gabble_connection_refresh_capabilities (conn, NULL);
-
- if (!gabble_disco_request_with_timeout (conn->disco, GABBLE_DISCO_TYPE_INFO,
- priv->stream_server, NULL,
- disco_reply_timeout,
- connection_disco_cb, conn,
- G_OBJECT (conn), &error))
- {
- DEBUG ("sending disco request failed: %s",
- error->message);
-
- g_error_free (error);
-
- tp_base_connection_change_status ((TpBaseConnection *) conn,
- TP_CONNECTION_STATUS_DISCONNECTED,
- TP_CONNECTION_STATUS_REASON_NETWORK_ERROR);
- }
-}
-
-/**
* connection_disco_cb
*
- * Stage 4 of connecting, this function is called by GabbleDisco after the
+ * Stage 3 of connecting, this function is called by GabbleDisco after the
* result of the non-blocking server feature discovery call is known. It sends
* the user's initial presence to the server, marking them as available,
* and requests the roster.
--
1.5.6.5
More information about the telepathy-commits
mailing list