cpw.malu.xmpp.jingle_ft: b68662aa: Connecting through a Jabber bytestream p...
malu at pidgin.im
malu at pidgin.im
Sun Apr 19 18:30:48 EDT 2009
-----------------------------------------------------------------
Revision: b68662aa9d1bbb591c8b4d1f5ed64ba6926c2051
Ancestor: d75bba8d59e50c8a44f09ed5f474c6c6b5ae2ac3
Author: malu at pidgin.im
Date: 2009-04-19T22:28:42
Branch: im.pidgin.cpw.malu.xmpp.jingle_ft
URL: http://d.pidgin.im/viewmtn/revision/info/b68662aa9d1bbb591c8b4d1f5ed64ba6926c2051
Modified files:
libpurple/protocols/jabber/jingle/s5b.c
ChangeLog:
Connecting through a Jabber bytestream proxy should kinda work now...
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jingle/s5b.c 200dd7d6366d4bbd02382a161c47fe512e361f40
+++ libpurple/protocols/jabber/jingle/s5b.c b0d8f586c97027b524ae7da7e196c8bf67a40741
@@ -148,6 +148,7 @@ struct _JingleS5BPrivate {
GList *local_streamhosts;
GList *remaining_streamhosts; /* pointer to untested remote SHs */
JabberBytestreamsStreamhost *successfull_remote_streamhost;
+ JabberBytestreamsStreamhost *accepted_streamhost;
JingleS5BConnectCallback *connect_cb;
JingleS5BErrorCallback *error_cb;
JingleContent *connect_content; /* used for the connect callback */
@@ -849,7 +850,7 @@ jingle_s5b_listen_cb(int sock, gpointer
const GList *iter;
JINGLE_S5B_GET_PRIVATE(s5b)->listen_data = NULL;
-
+
if (sock > 0) {
guint local_port = purple_network_get_port_from_fd(sock);
const gchar *local_ip = purple_network_get_local_system_ip(js->fd);
@@ -885,7 +886,7 @@ jingle_s5b_listen_cb(int sock, gpointer
g_free(jid);
}
-
+
/* add bytestream proxies */
for (iter = js->bs_proxies ; iter ; iter = g_list_next(iter)) {
JabberBytestreamsStreamhost *sh =
@@ -1046,7 +1047,7 @@ jingle_s5b_connect_to_streamhost(JingleS
static void
jingle_s5b_connect_to_streamhost(JingleS5BConnectData *data,
- JabberBytestreamsStreamhost *sh,
+ const JabberBytestreamsStreamhost *sh,
void (*connect_cb)(gpointer, gint, const gchar *),
GSourceFunc timeout_cb)
{
@@ -1133,10 +1134,6 @@ jingle_s5b_attempt_connect(JingleSession
jingle_s5b_attempt_connect_internal(data);
}
-
-
-
-
static gboolean
jingle_s5b_streamhost_is_local(JabberStream *js, const gchar *jid)
{
@@ -1157,11 +1154,104 @@ jingle_s5b_streamhost_is_local(JabberStr
return equal;
}
+static JabberBytestreamsStreamhost *
+jingle_s5b_find_local_streamhost(JingleS5B *s5b, const gchar *jid)
+{
+ const GList *iter = s5b->priv->local_streamhosts;
+
+ for (; iter ; iter = g_list_next(iter)) {
+ JabberBytestreamsStreamhost *sh =
+ (JabberBytestreamsStreamhost *) iter->data;
+ if (purple_strequal(sh->jid, jid)) {
+ return sh;
+ }
+ }
+ return NULL;
+}
+
+static gboolean
+jingle_s5b_proxy_timeout_cb(gpointer data)
+{
+ purple_debug_info("jingle-s5b", "timeout when connecting to proxy\n");
+ return FALSE;
+}
+
static void
+jingle_s5b_proxy_activate_cb(JabberStream *js, const char *from,
+ JabberIqType type, const char *id, xmlnode *packet, gpointer data)
+{
+ JingleS5B *s5b = ((JingleS5BConnectData *) data)->s5b;
+
+ if (type == JABBER_IQ_RESULT) {
+ /* we are connected to the proxy, let's start */
+ if (s5b->priv->connect_cb && s5b->priv->connect_content) {
+ s5b->priv->connect_cb(s5b->priv->connect_content);
+ }
+ } else {
+ /* error */
+ purple_debug_error("jingle-s5b",
+ "got an error response to the proxy activation request\n");
+ }
+
+ g_free(data);
+}
+
+static void
+jingle_s5b_proxy_connect_cb(gpointer data, gint source, const gchar *error_message)
+{
+ JabberIq *iq = NULL;
+ xmlnode *query = NULL;
+ xmlnode *activate = NULL;
+ JingleSession *session = ((JingleS5BConnectData *) data)->session;
+ JingleS5B *s5b = ((JingleS5BConnectData *) data)->s5b;
+
+ purple_debug_info("jingle-s5b", "connect to bytestreams proxy\n");
+ /* cancel timeout if set */
+ if (s5b->priv->connect_timeout) {
+ purple_timeout_remove(s5b->priv->connect_timeout);
+ s5b->priv->connect_timeout = 0;
+ }
+
+ if (source < 0) {
+ /* failed to connect */
+ purple_debug_error("jingle-s5b", "failed to connect to our own proxy\n");
+ g_free(data);
+ return;
+ }
+
+ purple_debug_info("jingle-s5b", "Successful in connecting to proxy!\n");
+ s5b->priv->fd = source;
+
+ /* active the streamhost */
+ iq = jabber_iq_new_query(jingle_session_get_js(session), JABBER_IQ_SET,
+ "http://jabber.org/protocol/bytestreams");
+ xmlnode_set_attrib(iq->node, "to", s5b->priv->accepted_streamhost->jid);
+ query = xmlnode_get_child(iq->node, "query");
+ xmlnode_set_attrib(query, "sid", s5b->priv->sid);
+ activate = xmlnode_new_child(query, "activate");
+ xmlnode_insert_data(activate, jingle_session_get_remote_jid(session), -1);
+ jabber_iq_set_callback(iq, jingle_s5b_proxy_activate_cb, data);
+ jabber_iq_send(iq);
+}
+
+static void
jingle_s5b_connect_to_proxy(JingleSession *session, JingleS5B *s5b,
- const gchar *jid)
+ JabberBytestreamsStreamhost *sh)
{
purple_debug_info("jingle-s5b", "in jingle_s5b_connect_to_proxy\n");
+ if (sh) {
+ JingleS5BConnectData *data = g_new0(JingleS5BConnectData, 1);
+
+ data->session = session;
+ data->s5b = s5b;
+ jingle_s5b_connect_to_streamhost(data, sh, jingle_s5b_proxy_connect_cb,
+ jingle_s5b_proxy_timeout_cb);
+ } else {
+ purple_debug_error("jingle-s5b",
+ "did not find the local streamhost specified in the "
+ "transport-accept message\n");
+ /* TODO: should we offer fallback to IBB here? */
+ }
}
void
@@ -1173,7 +1263,11 @@ jingle_s5b_handle_transport_accept(Jingl
if (streamhost_used) {
const gchar *jid = xmlnode_get_attrib(streamhost_used, "jid");
JabberStream *js = jingle_session_get_js(session);
-
+ JabberBytestreamsStreamhost *sh =
+ jingle_s5b_find_local_streamhost(s5b, jid);
+
+ s5b->priv->accepted_streamhost = sh;
+
purple_debug_info("jingle-ft", "got streamhost-used\n");
/* stop connection attempts */
jingle_s5b_stop_connection_attempts(s5b);
@@ -1194,7 +1288,7 @@ jingle_s5b_handle_transport_accept(Jingl
purple_debug_info("jingle-ft",
"got transport-accept on a proxy, "
"need to connect to the proxy\n");
- jingle_s5b_connect_to_proxy(session, s5b, jid);
+ jingle_s5b_connect_to_proxy(session, s5b, sh);
} else {
/* start transfer */
if (s5b->priv->connect_cb && s5b->priv->connect_content) {
More information about the Commits
mailing list