pidgin: 15e75311: Add support for using multiple "xmpp-cli...
datallah at pidgin.im
datallah at pidgin.im
Sun Jul 27 18:40:44 EDT 2008
-----------------------------------------------------------------
Revision: 15e75311f3c17e8f6415b5402bd75382239031d0
Ancestor: 7d23f027f9930d251c8b02cffe010c08b3fc906f
Author: datallah at pidgin.im
Date: 2008-07-27T22:34:32
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/15e75311f3c17e8f6415b5402bd75382239031d0
Modified files:
libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/jabber.h
ChangeLog:
Add support for using multiple "xmpp-client" records on a domain, by trying the
records in order until one succeeds (or we exhaust them all).
This currently will also fall back to the server based on the user's jid.
Fixes #6436.
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jabber.c f005b3dede749de2f533f11c1c70a8575f2ef47a
+++ libpurple/protocols/jabber/jabber.c 3a2f2be65d204fb20ab6f34b6ef55ea578c61d1f
@@ -63,6 +63,7 @@ static void jabber_unregister_account_cb
GList *jabber_features = NULL;
static void jabber_unregister_account_cb(JabberStream *js);
+static void try_srv_connect(JabberStream *js);
static void jabber_stream_init(JabberStream *js)
{
@@ -520,15 +521,23 @@ jabber_login_callback(gpointer data, gin
JabberStream *js = gc->proto_data;
if (source < 0) {
- gchar *tmp;
- tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),
- error);
- purple_connection_error_reason (gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- g_free(tmp);
+ if (js->srv_rec != NULL) {
+ purple_debug_error("jabber", "Unable to connect to server: %s. Trying next SRV record.\n", error);
+ try_srv_connect(js);
+ } else {
+ gchar *tmp;
+ tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),
+ error);
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ g_free(tmp);
+ }
return;
}
+ g_free(js->srv_rec);
+ js->srv_rec = NULL;
+
js->fd = source;
if(js->state == JABBER_STREAM_CONNECTING)
@@ -563,37 +572,62 @@ static void tls_init(JabberStream *js)
jabber_login_callback_ssl, jabber_ssl_connect_failure, js->certificate_CN, js->gc);
}
-static void jabber_login_connect(JabberStream *js, const char *domain, const char *host, int port)
+static gboolean jabber_login_connect(JabberStream *js, const char *domain, const char *host, int port,
+ gboolean fatal_failure)
{
/* host should be used in preference to domain to
* allow SASL authentication to work with FQDN of the server,
* but we use domain as fallback for when users enter IP address
* in connect server */
+ g_free(js->serverFQDN);
if (purple_ip_address_is_valid(host))
js->serverFQDN = g_strdup(domain);
else
js->serverFQDN = g_strdup(host);
if (purple_proxy_connect(js->gc, js->gc->account, host,
- port, jabber_login_callback, js->gc) == NULL)
- purple_connection_error_reason (js->gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to create socket"));
+ port, jabber_login_callback, js->gc) == NULL) {
+ if (fatal_failure) {
+ purple_connection_error_reason (js->gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Unable to create socket"));
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
}
+static void try_srv_connect(JabberStream *js)
+{
+ while (js->srv_rec != NULL && js->srv_rec_idx < js->max_srv_rec_idx) {
+ PurpleSrvResponse *tmp_resp = js->srv_rec + (js->srv_rec_idx++);
+ if (jabber_login_connect(js, tmp_resp->hostname, tmp_resp->hostname, tmp_resp->port, FALSE))
+ return;
+ }
+
+ g_free(js->srv_rec);
+ js->srv_rec = NULL;
+
+ /* Fall back to the defaults (I'm not sure if we should actually do this) */
+ jabber_login_connect(js, js->user->domain, js->user->domain,
+ purple_account_get_int(js->gc->account, "port", 5222), TRUE);
+}
+
static void srv_resolved_cb(PurpleSrvResponse *resp, int results, gpointer data)
{
- JabberStream *js;
-
- js = data;
+ JabberStream *js = data;
js->srv_query_data = NULL;
if(results) {
- jabber_login_connect(js, resp->hostname, resp->hostname, resp->port);
- g_free(resp);
+ js->srv_rec = resp;
+ js->srv_rec_idx = 0;
+ js->max_srv_rec_idx = results;
+ try_srv_connect(js);
} else {
jabber_login_connect(js, js->user->domain, js->user->domain,
- purple_account_get_int(js->gc->account, "port", 5222));
+ purple_account_get_int(js->gc->account, "port", 5222), TRUE);
}
}
@@ -675,7 +709,7 @@ jabber_login(PurpleAccount *account)
* invoke the magic of SRV lookups, to figure out host and port */
if(!js->gsc) {
if(connect_server[0]) {
- jabber_login_connect(js, js->user->domain, connect_server, purple_account_get_int(account, "port", 5222));
+ jabber_login_connect(js, js->user->domain, connect_server, purple_account_get_int(account, "port", 5222), TRUE);
} else {
js->srv_query_data = purple_srv_resolve("xmpp-client",
"tcp", js->user->domain, srv_resolved_cb, js);
@@ -1156,7 +1190,7 @@ void jabber_register_account(PurpleAccou
if (connect_server[0]) {
jabber_login_connect(js, js->user->domain, server,
purple_account_get_int(account,
- "port", 5222));
+ "port", 5222), TRUE);
} else {
js->srv_query_data = purple_srv_resolve("xmpp-client",
"tcp",
@@ -1327,9 +1361,12 @@ void jabber_close(PurpleConnection *gc)
if (js->keepalive_timeout != -1)
purple_timeout_remove(js->keepalive_timeout);
-
+
g_free(js);
+ g_free(js->srv_rec);
+ js->srv_rec = NULL;
+
gc->proto_data = NULL;
}
============================================================
--- libpurple/protocols/jabber/jabber.h 9ac68a50935a4f775fff15e205e9dc61dff2843c
+++ libpurple/protocols/jabber/jabber.h 5db2ebb103d8d20a03087bd9cf27aab964a68bb3
@@ -201,6 +201,10 @@ struct _JabberStream
/* A purple timeout tag for the keepalive */
int keepalive_timeout;
+
+ PurpleSrvResponse *srv_rec;
+ guint srv_rec_idx;
+ guint max_srv_rec_idx;
};
typedef gboolean (JabberFeatureEnabled)(JabberStream *js, const gchar *shortname, const gchar *namespace);
More information about the Commits
mailing list