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