[telepathy-gabble/master] track SOCKS5 proxy available in bytestream-factory and offer API to access to them
Guillaume Desmottes
guillaume.desmottes at collabora.co.uk
Fri Apr 3 08:41:32 PDT 2009
---
src/bytestream-factory.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++
src/bytestream-factory.h | 9 ++++
2 files changed, 129 insertions(+), 0 deletions(-)
diff --git a/src/bytestream-factory.c b/src/bytestream-factory.c
index 49d04db..2f6014b 100644
--- a/src/bytestream-factory.c
+++ b/src/bytestream-factory.c
@@ -37,6 +37,7 @@
#include "bytestream-socks5.h"
#include "connection.h"
#include "debug.h"
+#include "disco.h"
#include "namespaces.h"
#include "presence-cache.h"
#include "private-tubes-factory.h"
@@ -105,6 +106,31 @@ bytestream_id_free (gpointer v)
g_slice_free (BytestreamIdentifier, bsid);
}
+static GabbleSocks5Proxy *
+gabble_socks5_proxy_new (const gchar *jid,
+ const gchar *host,
+ const gchar *port)
+{
+ GabbleSocks5Proxy *proxy;
+
+ proxy = g_slice_new (GabbleSocks5Proxy);
+ proxy->jid = g_strdup (jid);
+ proxy->host = g_strdup (host);
+ proxy->port = g_strdup (port);
+
+ return proxy;
+}
+
+static void
+gabble_socks5_proxy_free (GabbleSocks5Proxy *proxy)
+{
+ g_free (proxy->jid);
+ g_free (proxy->host);
+ g_free (proxy->port);
+
+ g_slice_free (GabbleSocks5Proxy, proxy);
+}
+
struct _GabbleBytestreamFactoryPrivate
{
GabbleConnection *conn;
@@ -131,6 +157,9 @@ struct _GabbleBytestreamFactoryPrivate
* BytestreamIdentifier -> GabbleBytestreamMultiple */
GHashTable *multiple_bytestreams;
+ /* List of GabbleSocks5Proxy discovered on the connection */
+ GSList *socks5_proxies;
+
gboolean dispose_has_run;
};
@@ -173,6 +202,74 @@ gabble_bytestream_factory_init (GabbleBytestreamFactory *self)
bytestream_id_equal, bytestream_id_free, g_object_unref);
}
+static LmHandlerResult
+socks5_proxy_query_reply_cb (GabbleConnection *conn,
+ LmMessage *sent_msg,
+ LmMessage *reply_msg,
+ GObject *obj,
+ gpointer user_data)
+{
+ GabbleBytestreamFactory *self = GABBLE_BYTESTREAM_FACTORY (user_data);
+ GabbleBytestreamFactoryPrivate *priv = GABBLE_BYTESTREAM_FACTORY_GET_PRIVATE (
+ self);
+ LmMessageNode *query, *streamhost;
+ const gchar *jid, *host, *port;
+ GabbleSocks5Proxy *proxy;
+
+ if (lm_message_get_sub_type (reply_msg) != LM_MESSAGE_SUB_TYPE_RESULT)
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+
+ query = lm_message_node_get_child_with_namespace (reply_msg->node, "query",
+ NS_BYTESTREAMS);
+ if (query == NULL)
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+
+ streamhost = lm_message_node_get_child (query, "streamhost");
+ if (streamhost == NULL)
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+
+ jid = lm_message_node_get_attribute (streamhost, "jid");
+ host = lm_message_node_get_attribute (streamhost, "host");
+ port = lm_message_node_get_attribute (streamhost, "port");
+
+ if (jid == NULL || host == NULL || port == NULL)
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+
+ DEBUG ("Found SOCKS5 proxy: %s %s:%s", jid, host, port);
+
+ proxy = gabble_socks5_proxy_new (jid, host, port);
+ priv->socks5_proxies = g_slist_prepend (priv->socks5_proxies, proxy);
+
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static void
+disco_item_found_cb (GabbleDisco *disco,
+ GabbleDiscoItem *item,
+ GabbleBytestreamFactory *self)
+{
+ GabbleBytestreamFactoryPrivate *priv = GABBLE_BYTESTREAM_FACTORY_GET_PRIVATE (
+ self);
+ LmMessage *query;
+
+ if (tp_strdiff (item->category, "proxy") ||
+ tp_strdiff (item->type, "bytestreams"))
+ return;
+
+ DEBUG ("send SOCKS5 query to %s", item->jid);
+
+ query = lm_message_build (item->jid, LM_MESSAGE_TYPE_IQ,
+ '@', "type", "get",
+ '(', "query", "",
+ '@', "xmlns", NS_BYTESTREAMS,
+ ')', NULL);
+
+ _gabble_connection_send_with_reply (priv->conn, query,
+ socks5_proxy_query_reply_cb, G_OBJECT (self), self, NULL);
+
+ lm_message_unref (query);
+}
+
static GObject *
gabble_bytestream_factory_constructor (GType type,
guint n_props,
@@ -208,6 +305,10 @@ gabble_bytestream_factory_constructor (GType type,
lm_connection_register_message_handler (priv->conn->lmconn,
priv->iq_socks5_cb, LM_MESSAGE_TYPE_IQ, LM_HANDLER_PRIORITY_FIRST);
+ /* Track SOCKS5 proxy available on the connection */
+ gabble_signal_connect_weak (priv->conn->disco, "item-found",
+ G_CALLBACK (disco_item_found_cb), G_OBJECT (self));
+
return obj;
}
@@ -217,6 +318,7 @@ gabble_bytestream_factory_dispose (GObject *object)
GabbleBytestreamFactory *self = GABBLE_BYTESTREAM_FACTORY (object);
GabbleBytestreamFactoryPrivate *priv =
GABBLE_BYTESTREAM_FACTORY_GET_PRIVATE (self);
+ GSList *l;
if (priv->dispose_has_run)
return;
@@ -252,6 +354,15 @@ gabble_bytestream_factory_dispose (GObject *object)
g_hash_table_destroy (priv->multiple_bytestreams);
priv->multiple_bytestreams = NULL;
+ for (l = priv->socks5_proxies; l != NULL; l = g_slist_next (l))
+ {
+ GabbleSocks5Proxy *proxy = (GabbleSocks5Proxy *) l->data;
+
+ gabble_socks5_proxy_free (proxy);
+ }
+ g_slist_free (priv->socks5_proxies);
+ priv->socks5_proxies = NULL;
+
if (G_OBJECT_CLASS (gabble_bytestream_factory_parent_class)->dispose)
G_OBJECT_CLASS (gabble_bytestream_factory_parent_class)->dispose (object);
}
@@ -1761,3 +1872,12 @@ gabble_bytestream_factory_make_multi_accept_iq (const gchar *full_jid,
return msg;
}
+
+const GSList *
+gabble_bytestream_factory_get_socks_proxies (GabbleBytestreamFactory *self)
+{
+ GabbleBytestreamFactoryPrivate *priv = GABBLE_BYTESTREAM_FACTORY_GET_PRIVATE (
+ self);
+
+ return priv->socks5_proxies;
+}
diff --git a/src/bytestream-factory.h b/src/bytestream-factory.h
index bdfbbeb..fcefe14 100644
--- a/src/bytestream-factory.h
+++ b/src/bytestream-factory.h
@@ -66,6 +66,12 @@ GType gabble_bytestream_factory_get_type (void);
(G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_BYTESTREAM_FACTORY,\
GabbleBytestreamFactoryClass))
+typedef struct {
+ gchar *jid;
+ gchar *host;
+ gchar *port;
+} GabbleSocks5Proxy;
+
typedef void (* GabbleBytestreamFactoryNegotiateReplyFunc) (
GabbleBytestreamIface *bytestream, const gchar *stream_id, LmMessage *msg,
GObject *object, gpointer user_data);
@@ -100,6 +106,9 @@ gboolean gabble_bytestream_factory_negotiate_stream (
gchar *gabble_bytestream_factory_generate_stream_id (void);
+const GSList *gabble_bytestream_factory_get_socks_proxies (
+ GabbleBytestreamFactory *self);
+
G_END_DECLS
#endif /* #ifndef __BYTESTREAM_FACTORY_H__ */
--
1.5.6.5
More information about the telepathy-commits
mailing list