cpw.malu.xmpp.jingle_ft: d15cbf4d: Generate <streamhost/> elements in the s..

malu at pidgin.im malu at pidgin.im
Sat Mar 28 11:10:30 EDT 2009


-----------------------------------------------------------------
Revision: d15cbf4d8fa793ec2ec7643f689b690f6fcf810d
Ancestor: cfec577f9630d1d540a495aa4ff114f37044a721
Author: malu at pidgin.im
Date: 2009-03-28T15:06:27
Branch: im.pidgin.cpw.malu.xmpp.jingle_ft
URL: http://d.pidgin.im/viewmtn/revision/info/d15cbf4d8fa793ec2ec7643f689b690f6fcf810d

Modified files:
        libpurple/protocols/jabber/jingle/file-transfer.c
        libpurple/protocols/jabber/jingle/s5b.c
        libpurple/protocols/jabber/jingle/s5b.h

ChangeLog: 

Generate <streamhost/> elements in the session-initiate for the initiator
Starts listen on local socket
Still only generates local streamhosts

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jingle/file-transfer.c	00de102ab0091f30eeab6b24c4b340408d20f40d
+++ libpurple/protocols/jabber/jingle/file-transfer.c	badab4bdd30bbcc6e84090f30c2e25991ce8393c
@@ -435,8 +435,14 @@ jingle_file_transfer_xfer_init(PurpleXfe
 		g_free(jid);
 		xfer->data = content;
 		
-		jabber_iq_send(jingle_session_to_packet(session, 
-			JINGLE_SESSION_INITIATE));
+		if (JINGLE_IS_IBB(transport)) {
+			/* if it's IBB, send session-intitate directly */
+			jabber_iq_send(jingle_session_to_packet(session, 
+				JINGLE_SESSION_INITIATE));
+		} else if (JINGLE_IS_S5B(transport)) {
+			/* start local listen on the S5B transport */
+			jingle_s5b_gather_streamhosts(session, JINGLE_S5B(transport));
+		}	
 	} else {
 		JingleContent *content = (JingleContent *) xfer->data;
 		JingleSession *session = jingle_content_get_session(content);
============================================================
--- libpurple/protocols/jabber/jingle/s5b.c	2e2688af85818c61cd76746a8dd8963dc415e8cd
+++ libpurple/protocols/jabber/jingle/s5b.c	72fb7ea54f99a4c2fa2ef0f234697776c9cdc5a5
@@ -21,11 +21,63 @@
 #include "content.h"
 #include "s5b.h"
 #include "debug.h"
+#include "network.h"
 #include "xmlnode.h"
 
+/* auxillary functions to handle JabberBytestreamsStreamhosts, maybe this
+ should be in a separtate module, used by si.c and other places as well */
+
+static JabberBytestreamsStreamhost *
+jingle_s5b_streamhost_create(const gchar *jid, const gchar *host, int port,
+	const gchar *zeroconf)
+{
+	JabberBytestreamsStreamhost *sh = g_new0(JabberBytestreamsStreamhost, 1);
+	
+	sh->jid = g_strdup(jid);
+	sh->host = g_strdup(host);
+	sh->port = port;
+	if (zeroconf)
+		sh->zeroconf = g_strdup(zeroconf);
+	
+	return sh;
+}
+
+static void
+jingle_s5b_streamhost_destroy(JabberBytestreamsStreamhost *sh)
+{
+	g_free(sh->jid);
+	g_free(sh->host);
+	if (sh->zeroconf)
+		g_free(sh->zeroconf);
+	g_free(sh);
+}
+
+xmlnode *
+jingle_s5b_streamhost_to_xml(const JabberBytestreamsStreamhost *sh)
+{
+	xmlnode *streamhost = xmlnode_new("streamhost");
+	gchar port[10];
+	
+	if (streamhost) {
+		g_snprintf(port, 10, "%d", sh->port);
+		xmlnode_set_attrib(streamhost, "jid", sh->jid);
+		xmlnode_set_attrib(streamhost, "host", sh->host);
+		xmlnode_set_attrib(streamhost, "port", port);
+		if (sh->zeroconf)
+			xmlnode_set_attrib(streamhost, "zeroconf", sh->zeroconf);
+	}
+	
+	return streamhost;
+}
+
+
 struct _JingleS5BPrivate {
 	/* S5B stuff here... */
 	guint fd;
+	PurpleProxyConnectData *connect_data;
+	PurpleNetworkListenData *listen_data;
+	GList *remote_streamhosts;
+	GList *local_streamhosts;
 };
 
 #define JINGLE_S5B_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_S5B, JingleS5BPrivate))
@@ -88,6 +140,8 @@ jingle_s5b_init (JingleS5B *s5b)
 {	
 	s5b->priv = JINGLE_S5B_GET_PRIVATE(s5b);
 	memset(s5b->priv, 0, sizeof(s5b->priv));
+	s5b->priv->local_streamhosts = NULL;
+	s5b->priv->remote_streamhosts = NULL;
 }
 
 static void
@@ -96,6 +150,22 @@ jingle_s5b_finalize (GObject *s5b)
 	JingleS5BPrivate *priv = JINGLE_S5B_GET_PRIVATE(s5b);
 	purple_debug_info("jingle-s5b","jingle_s5b_finalize\n");
 	
+	/* free the local streamhosts */
+	while (priv->local_streamhosts) {
+		jingle_s5b_streamhost_destroy(
+			(JabberBytestreamsStreamhost *)priv->local_streamhosts->data);
+		priv->local_streamhosts = g_list_delete_link(priv->local_streamhosts, 
+			priv->local_streamhosts);
+	}
+	
+	/* free the remote streamhosts */
+	while (priv->local_streamhosts) {
+		jingle_s5b_streamhost_destroy(
+			(JabberBytestreamsStreamhost *)priv->remote_streamhosts->data);
+		priv->remote_streamhosts = g_list_delete_link(priv->remote_streamhosts, 
+			priv->remote_streamhosts);
+	}
+	
 	G_OBJECT_CLASS(parent_class)->finalize(s5b);
 }
 
@@ -145,9 +215,90 @@ jingle_s5b_to_xml_internal(JingleTranspo
 	JingleActionType action)
 {
 	xmlnode *node = parent_class->to_xml(transport, content, action);
-
+	const GList *iter;
+	JingleS5B *s5b = JINGLE_S5B(transport);
+	
 	purple_debug_info("jingle", "jingle_ibb_to_xml_internal\n");
+	if (action == JINGLE_SESSION_INITIATE || action == JINGLE_SESSION_ACCEPT) {
+		for (iter = JINGLE_S5B_GET_PRIVATE(s5b)->local_streamhosts; 
+			iter; 
+			iter = g_list_next(iter)) {
+			JabberBytestreamsStreamhost *sh = 
+				(JabberBytestreamsStreamhost *) iter->data;
+			xmlnode_insert_child(node, jingle_s5b_streamhost_to_xml(sh));
+		}
+	}
 
 	return node;
 }
 
+typedef struct {
+	JingleSession *session;
+	JingleS5B *s5b;
+} JingleS5BListenData;
+
+static void
+jingle_s5b_listen_cb(int sock, gpointer data)
+{
+	JingleS5B *s5b = ((JingleS5BListenData *) data)->s5b;
+	JingleSession *session = ((JingleS5BListenData *) data)->session;
+	
+	JINGLE_S5B_GET_PRIVATE(s5b)->listen_data = NULL;
+	
+	g_free(data);
+	
+	if (sock > 0) {
+		guint local_port = purple_network_get_port_from_fd(sock);
+		JabberStream *js = jingle_session_get_js(session);
+		const gchar *local_ip = purple_network_get_local_system_ip(js->fd);
+		const gchar *public_ip = purple_network_get_my_ip(js->fd);
+		const gchar *jid = g_strdup_printf("%s@%s/%s", js->user->node,
+			js->user->domain, js->user->resource);
+
+		purple_debug_info("jingle-s5b", "successfully open port %d locally\n",
+			local_port);
+
+		if (!purple_strequal(local_ip, "0.0.0.0")) {
+			JabberBytestreamsStreamhost *sh =
+				jingle_s5b_streamhost_create(jid, local_ip, local_port, NULL);
+			JINGLE_S5B_GET_PRIVATE(s5b)->local_streamhosts =
+				g_list_append(JINGLE_S5B_GET_PRIVATE(s5b)->local_streamhosts,
+					sh);
+		}
+
+		if (!purple_strequal(local_ip, public_ip) && 
+			!purple_strequal(public_ip, "0.0.0.0")) {
+			JabberBytestreamsStreamhost *sh =
+				jingle_s5b_streamhost_create(jid, public_ip, local_port, NULL);
+			JINGLE_S5B_GET_PRIVATE(s5b)->local_streamhosts =
+				g_list_append(JINGLE_S5B_GET_PRIVATE(s5b)->local_streamhosts,
+					sh);	
+		}
+
+		g_free(jid);
+	}
+	
+	/* should gather proxies here */
+	
+	/* if we are the initiator send session-initiate */
+	if (jingle_session_is_initiator(session)) {
+		jabber_iq_send(jingle_session_to_packet(session, 
+			JINGLE_SESSION_INITIATE));
+	} else {
+		jabber_iq_send(jingle_session_to_packet(session,
+			JINGLE_SESSION_ACCEPT));
+	}
+	g_object_unref(session);
+}
+
+void
+jingle_s5b_gather_streamhosts(JingleSession *session, JingleS5B *s5b)
+{
+	JingleS5BListenData *data = g_new0(JingleS5BListenData, 1);
+	data->session = session;
+	data->s5b = s5b;
+	g_object_ref(session);
+	JINGLE_S5B_GET_PRIVATE(s5b)->listen_data = 
+		purple_network_listen_range(0, 0, SOCK_STREAM, jingle_s5b_listen_cb,
+			data);
+}
============================================================
--- libpurple/protocols/jabber/jingle/s5b.h	b10ecd3a14448792df79e4356fdac0de79a28941
+++ libpurple/protocols/jabber/jingle/s5b.h	4e6fd5070a99265110276fb2557cf518a00ffe36
@@ -65,6 +65,10 @@ GType jingle_s5b_get_type(void);
  */
 GType jingle_s5b_get_type(void);
 
+/* start discovering streamhosts, initiator will send session-initiate when
+	done, receiver will send transport-info */
+void jingle_s5b_gather_streamhosts(JingleSession *session, JingleS5B *s5b);
+
 #ifdef __cplusplus
 }
 #endif


More information about the Commits mailing list