summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-12-06 12:26:28 +0000
committerWill Thompson <will.thompson@collabora.co.uk>2012-12-06 12:26:28 +0000
commitde8905b5bb098c6f0468e9a2856006d1583ad80c (patch)
treef90f10732584838536c3bc8bcd414ee8fe02a3a5 /src
parentb735dc9c1320b9a6c206a0856758c60c130428a8 (diff)
parentfbd33aa489c1d9c129e2815ed86678ceacb0ad0d (diff)
Merge branch '25961-stun-srv'
https://bugs.freedesktop.org/show_bug.cgi?id=25961 https://bugs.freedesktop.org/show_bug.cgi?id=25385
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/call-stream.c18
-rw-r--r--src/gtalk-file-collection.c18
-rw-r--r--src/jingle-info-internal.h29
-rw-r--r--src/jingle-info.c241
-rw-r--r--src/jingle-info.h15
-rw-r--r--src/jingle-mint.c11
-rw-r--r--src/media-channel.c17
-rw-r--r--src/media-stream.c27
9 files changed, 272 insertions, 106 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b6c6e7740..bb88ed6f9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -163,6 +163,7 @@ libgabble_convenience_la_SOURCES += \
jingle-content.c \
jingle-factory.h \
jingle-factory.c \
+ jingle-info-internal.h \
jingle-info.c \
jingle-info.h \
jingle-share.h \
@@ -203,6 +204,7 @@ endif
enumtype_sources = \
$(top_srcdir)/src/connection.h \
$(top_srcdir)/src/jingle-types.h \
+ $(top_srcdir)/src/jingle-info-internal.h \
$(top_srcdir)/src/room-config.h \
$(top_srcdir)/src/presence.h
diff --git a/src/call-stream.c b/src/call-stream.c
index ae9ac5e8f..c633a2711 100644
--- a/src/call-stream.c
+++ b/src/call-stream.c
@@ -101,24 +101,24 @@ get_stun_servers (GabbleCallStream *self)
{
GPtrArray *arr;
GabbleJingleFactory *jf;
- gchar *stun_server;
- guint stun_port;
+ GList *stun_servers;
arr = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free);
jf = gabble_jingle_session_get_factory (self->priv->content->session);
+ stun_servers = gabble_jingle_info_get_stun_servers (
+ gabble_jingle_factory_get_jingle_info (jf));
- /* maybe one day we'll support multiple STUN servers */
- if (gabble_jingle_info_get_stun_server (
- gabble_jingle_factory_get_jingle_info (jf),
- &stun_server, &stun_port))
+ while (stun_servers != NULL)
{
+ GabbleStunServer *stun_server = stun_servers->data;
GValueArray *va = tp_value_array_build (2,
- G_TYPE_STRING, stun_server,
- G_TYPE_UINT, stun_port,
+ G_TYPE_STRING, stun_server->address,
+ G_TYPE_UINT, (guint) stun_server->port,
G_TYPE_INVALID);
- g_free (stun_server);
g_ptr_array_add (arr, va);
+
+ stun_servers = g_list_delete_link (stun_servers, stun_servers);
}
return arr;
diff --git a/src/gtalk-file-collection.c b/src/gtalk-file-collection.c
index e13180fe0..b150ddaf5 100644
--- a/src/gtalk-file-collection.c
+++ b/src/gtalk-file-collection.c
@@ -904,8 +904,7 @@ content_new_share_channel_cb (GabbleJingleContent *content, const gchar *name,
NiceAgent *agent = nice_agent_new_reliable (g_main_context_default (),
NICE_COMPATIBILITY_GOOGLE);
guint stream_id = nice_agent_add_stream (agent, 1);
- gchar *stun_server;
- guint stun_port;
+ GList *stun_servers;
GoogleRelaySessionData *relay_data = NULL;
DEBUG ("New Share channel %s was created and linked to id %d", name,
@@ -945,15 +944,18 @@ content_new_share_channel_cb (GabbleJingleContent *content, const gchar *name,
nice_agent_attach_recv (agent, stream_id, share_channel->component_id,
g_main_context_default (), nice_data_received_cb, self);
- if (gabble_jingle_info_get_stun_server (
- gabble_jingle_factory_get_jingle_info (self->priv->jingle_factory),
- &stun_server, &stun_port))
+ stun_servers = gabble_jingle_info_get_stun_servers (
+ gabble_jingle_factory_get_jingle_info (self->priv->jingle_factory));
+ if (stun_servers != NULL)
{
+ GabbleStunServer *stun_server = stun_servers->data;
+
g_object_set (agent,
- "stun-server", stun_server,
- "stun-server-port", stun_port,
+ "stun-server", stun_server->address,
+ "stun-server-port", (guint) stun_server->port,
NULL);
- g_free (stun_server);
+
+ g_list_free (stun_servers);
}
relay_data = g_slice_new0 (GoogleRelaySessionData);
diff --git a/src/jingle-info-internal.h b/src/jingle-info-internal.h
new file mode 100644
index 000000000..1f76ce3bc
--- /dev/null
+++ b/src/jingle-info-internal.h
@@ -0,0 +1,29 @@
+/*
+ * jingle-info-internal.h - internal types for GabbleJingleInfo
+ * Copyright © 2012 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GABBLE_JINGLE_INFO_INTERNAL_H
+#define GABBLE_JINGLE_INFO_INTERNAL_H
+
+typedef enum {
+ GABBLE_STUN_SERVER_USER_SPECIFIED,
+ GABBLE_STUN_SERVER_DISCOVERED,
+ GABBLE_STUN_SERVER_FALLBACK
+} GabbleStunServerSource;
+
+#endif /* GABBLE_JINGLE_INFO_INTERNAL_H */
diff --git a/src/jingle-info.c b/src/jingle-info.c
index bd1f6865d..07f111436 100644
--- a/src/jingle-info.c
+++ b/src/jingle-info.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "jingle-info.h"
+#include "jingle-info-internal.h"
#include <stdlib.h>
#include <telepathy-glib/telepathy-glib.h>
@@ -27,6 +28,7 @@
#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
#include "debug.h"
#include "google-relay.h"
+#include "gabble-enumtypes.h"
#include "gabble-signals-marshal.h"
#include "namespaces.h"
@@ -38,13 +40,13 @@ static gboolean jingle_info_cb (
struct _GabbleJingleInfoPrivate {
WockyPorter *porter;
guint jingle_info_handler_id;
+ gchar *jid_domain;
GabbleGoogleRelayResolver *google_resolver;
- gchar *stun_server;
- guint16 stun_port;
- gchar *fallback_stun_server;
- guint16 fallback_stun_port;
+ GabbleStunServer *stun_server;
+ GabbleStunServer *fallback_stun_server;
+
gchar *relay_token;
/* TRUE if the user has not explicitly specified a STUN server, and hence
@@ -79,6 +81,26 @@ gabble_jingle_info_set_test_mode (void)
test_mode = TRUE;
}
+static GabbleStunServer *
+gabble_stun_server_new (
+ gchar *address,
+ guint16 port)
+{
+ GabbleStunServer stun_server = { address, port };
+
+ return g_slice_dup (GabbleStunServer, &stun_server);
+}
+
+static void
+gabble_stun_server_free (GabbleStunServer *stun_server)
+{
+ if (stun_server != NULL)
+ {
+ g_free (stun_server->address);
+ g_slice_free (GabbleStunServer, stun_server);
+ }
+}
+
G_DEFINE_TYPE (GabbleJingleInfo, gabble_jingle_info, G_TYPE_OBJECT)
static void
@@ -145,11 +167,10 @@ gabble_jingle_info_constructed (GObject *object)
parent_class->constructed (object);
g_assert (priv->porter != NULL);
- priv->jingle_info_handler_id = wocky_c2s_porter_register_handler_from_server (
- WOCKY_C2S_PORTER (priv->porter),
- WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
- WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, jingle_info_cb, self,
- '(', "query", ':', NS_GOOGLE_JINGLE_INFO, ')', NULL);
+
+ if (!wocky_decode_jid (wocky_porter_get_bare_jid (priv->porter), NULL,
+ &priv->jid_domain, NULL))
+ g_assert_not_reached ();
}
static void
@@ -161,8 +182,10 @@ gabble_jingle_info_dispose (GObject *object)
if (priv->porter != NULL)
{
- g_assert (priv->jingle_info_handler_id != 0);
- wocky_porter_unregister_handler (priv->porter, priv->jingle_info_handler_id);
+ if (priv->jingle_info_handler_id != 0)
+ wocky_porter_unregister_handler (priv->porter,
+ priv->jingle_info_handler_id);
+
g_clear_object (&priv->porter);
}
@@ -172,9 +195,11 @@ gabble_jingle_info_dispose (GObject *object)
priv->google_resolver = NULL;
}
- g_free (priv->stun_server);
+ g_free (priv->jid_domain);
+ priv->jid_domain = NULL;
+ gabble_stun_server_free (priv->stun_server);
priv->stun_server = NULL;
- g_free (priv->fallback_stun_server);
+ gabble_stun_server_free (priv->fallback_stun_server);
priv->fallback_stun_server = NULL;
g_free (priv->relay_token);
priv->relay_token = NULL;
@@ -223,7 +248,7 @@ typedef struct {
GabbleJingleInfo *factory;
gchar *stun_server;
guint16 stun_port;
- gboolean fallback;
+ GabbleStunServerSource source;
GCancellable *cancellable;
} PendingStunServer;
@@ -248,8 +273,10 @@ stun_server_resolved_cb (GObject *resolver,
{
PendingStunServer *data = user_data;
GabbleJingleInfo *self = data->factory;
+ GabbleJingleInfoPrivate *priv = self->priv;
GError *e = NULL;
- gchar *stun_server;
+ GabbleStunServer *stun_server;
+ gchar *address;
GList *entries;
if (self != NULL)
@@ -267,29 +294,29 @@ stun_server_resolved_cb (GObject *resolver,
goto out;
}
- stun_server = g_inet_address_to_string (entries->data);
+ address = g_inet_address_to_string (entries->data);
g_resolver_free_addresses (entries);
DEBUG ("Resolved STUN server %s:%u to %s:%u", data->stun_server,
- data->stun_port, stun_server, data->stun_port);
+ data->stun_port, address, data->stun_port);
if (self == NULL)
{
- g_free (stun_server);
+ g_free (address);
goto out;
}
- if (data->fallback)
+ stun_server = gabble_stun_server_new (address, data->stun_port);
+
+ if (data->source == GABBLE_STUN_SERVER_FALLBACK)
{
- g_free (self->priv->fallback_stun_server);
- self->priv->fallback_stun_server = stun_server;
- self->priv->fallback_stun_port = data->stun_port;
+ gabble_stun_server_free (priv->fallback_stun_server);
+ priv->fallback_stun_server = stun_server;
}
else
{
- g_free (self->priv->stun_server);
- self->priv->stun_server = stun_server;
- self->priv->stun_port = data->stun_port;
+ gabble_stun_server_free (priv->stun_server);
+ priv->stun_server = stun_server;
g_signal_emit (self, signals[STUN_SERVER_CHANGED], 0,
stun_server, data->stun_port);
@@ -300,12 +327,12 @@ out:
g_object_unref (resolver);
}
-void
-gabble_jingle_info_take_stun_server (
+static void
+gabble_jingle_info_take_stun_server_internal (
GabbleJingleInfo *self,
gchar *stun_server,
guint16 stun_port,
- gboolean is_fallback)
+ GabbleStunServerSource source)
{
GResolver *resolver;
PendingStunServer *data;
@@ -313,19 +340,20 @@ gabble_jingle_info_take_stun_server (
if (stun_server == NULL)
return;
- if (!is_fallback)
+ if (source == GABBLE_STUN_SERVER_USER_SPECIFIED)
self->priv->get_stun_from_jingle = FALSE;
resolver = g_resolver_get_default ();
data = g_slice_new0 (PendingStunServer);
DEBUG ("Resolving %s STUN server %s:%u",
- is_fallback ? "fallback" : "primary", stun_server, stun_port);
+ wocky_enum_to_nick (GABBLE_TYPE_STUN_SERVER_SOURCE, data->source),
+ stun_server, stun_port);
data->factory = self;
g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->factory);
data->stun_server = stun_server;
data->stun_port = stun_port;
- data->fallback = is_fallback;
+ data->source = source;
data->cancellable = g_cancellable_new ();
g_object_weak_ref (G_OBJECT (self), (GWeakNotify)g_cancellable_cancel,
@@ -335,6 +363,30 @@ gabble_jingle_info_take_stun_server (
data->cancellable, stun_server_resolved_cb, data);
}
+/*
+ * gabble_jingle_info_take_stun_server:
+ * @self: a #GabbleJingleInfo object
+ * @stun_server: (transfer full): the STUN server's address
+ * @stun_port: the STUN server's port
+ * @is_fallback: %TRUE if this is a last resort; %FALSE if this STUN server was
+ * provided by the user (whether by explicitly setting one, or by asking the
+ * user's XMPP server).
+ */
+void
+gabble_jingle_info_take_stun_server (
+ GabbleJingleInfo *self,
+ gchar *stun_server,
+ guint16 stun_port,
+ gboolean is_fallback)
+{
+ GabbleStunServerSource source = is_fallback
+ ? GABBLE_STUN_SERVER_FALLBACK
+ : GABBLE_STUN_SERVER_USER_SPECIFIED;
+
+ gabble_jingle_info_take_stun_server_internal (self, stun_server, stun_port,
+ source);
+}
+
static void
got_jingle_info_stanza (
GabbleJingleInfo *self,
@@ -355,9 +407,11 @@ got_jingle_info_stanza (
if (node != NULL)
{
- node = wocky_node_get_child (node, "server");
+ WockyNodeIter iter;
- if (node != NULL)
+ /* TODO: use more than just the first stun server returned. */
+ wocky_node_iter_init (&iter, node, "server", NULL);
+ if (wocky_node_iter_next (&iter, &node))
{
const gchar *server;
const gchar *port_attr;
@@ -374,8 +428,8 @@ got_jingle_info_stanza (
{
DEBUG ("jingle info: got stun server %s, port %u", server,
port);
- gabble_jingle_info_take_stun_server (self,
- g_strdup (server), port, FALSE);
+ gabble_jingle_info_take_stun_server_internal (self,
+ g_strdup (server), port, GABBLE_STUN_SERVER_DISCOVERED);
}
}
}
@@ -504,8 +558,9 @@ jingle_info_reply_cb (
g_object_unref (self);
}
-void
-gabble_jingle_info_send_request (GabbleJingleInfo *self)
+static void
+gabble_jingle_info_send_google_request (
+ GabbleJingleInfo *self)
{
GabbleJingleInfoPrivate *priv = self->priv;
WockyStanza *stanza = wocky_stanza_build (
@@ -516,36 +571,110 @@ gabble_jingle_info_send_request (GabbleJingleInfo *self)
wocky_porter_send_iq_async (priv->porter, stanza, NULL, jingle_info_reply_cb,
g_object_ref (self));
g_object_unref (stanza);
+
+ priv->jingle_info_handler_id = wocky_c2s_porter_register_handler_from_server (
+ WOCKY_C2S_PORTER (priv->porter),
+ WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
+ WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, jingle_info_cb, self,
+ '(', "query", ':', NS_GOOGLE_JINGLE_INFO, ')', NULL);
}
-gboolean
-gabble_jingle_info_get_stun_server (
- GabbleJingleInfo *self,
- gchar **stun_server,
- guint *stun_port)
+static void
+discover_stun_servers_cb (GObject *resolver,
+ GAsyncResult *result,
+ gpointer user_data)
{
- if (self->priv->stun_server == NULL || self->priv->stun_port == 0)
+ GabbleJingleInfo *self = GABBLE_JINGLE_INFO (user_data);
+ GabbleJingleInfoPrivate *priv = self->priv;
+ GError *error = NULL;
+ GList *targets;
+
+ targets = g_resolver_lookup_service_finish (G_RESOLVER (resolver),
+ result, &error);
+
+ if (error != NULL)
+ {
+ DEBUG ("Failed to discover STUN servers on %s: %s",
+ priv->jid_domain, error->message);
+ g_clear_error (&error);
+ }
+ else
{
- if (self->priv->fallback_stun_server == NULL ||
- self->priv->fallback_stun_port == 0)
- return FALSE;
+ DEBUG ("Discovered %d STUN servers on %s", g_list_length (targets),
+ priv->jid_domain);
+
+ /* TODO: use more than just the first. */
+ if (targets != NULL)
+ {
+ GSrvTarget *target = targets->data;
+ const gchar *hostname = g_srv_target_get_hostname (target);
+ guint16 port = g_srv_target_get_port (target);
- if (stun_server != NULL)
- *stun_server = g_strdup (self->priv->fallback_stun_server);
+ DEBUG ("Found STUN server: %s:%d", hostname, port);
- if (stun_port != NULL)
- *stun_port = self->priv->fallback_stun_port;
+ gabble_jingle_info_take_stun_server (self, g_strdup (hostname), port,
+ FALSE);
+ }
- return TRUE;
+ g_resolver_free_targets (targets);
}
- if (stun_server != NULL)
- *stun_server = g_strdup (self->priv->stun_server);
+ g_object_unref (resolver);
+ g_object_unref (self);
+}
- if (stun_port != NULL)
- *stun_port = self->priv->stun_port;
+static void
+gabble_jingle_info_lookup_srv (
+ GabbleJingleInfo *self)
+{
+ GabbleJingleInfoPrivate *priv = self->priv;
+ GResolver *resolver;
- return TRUE;
+ g_assert (priv->jid_domain != NULL);
+ DEBUG ("Discovering STUN servers on %s", priv->jid_domain);
+
+ resolver = g_resolver_get_default ();
+ g_resolver_lookup_service_async (resolver, "stun", "udp", priv->jid_domain,
+ NULL, discover_stun_servers_cb, g_object_ref (self));
+}
+
+void
+gabble_jingle_info_send_request (
+ GabbleJingleInfo *self,
+ gboolean google_jingleinfo_supported)
+{
+ /* FIXME: we probably don't want to send either query if the user specified a
+ * stun server (that is, get_stun_from_jingle is FALSE).
+ */
+ if (google_jingleinfo_supported)
+ gabble_jingle_info_send_google_request (self);
+ else
+ gabble_jingle_info_lookup_srv (self);
+}
+
+/*
+ * gabble_jingle_info_get_stun_servers:
+ *
+ * Grabs the currently known and resolved stun servers.
+ *
+ * Returns: (transfer container): a list of GabbleJingleInfo structs
+ */
+GList *
+gabble_jingle_info_get_stun_servers (
+ GabbleJingleInfo *self)
+{
+ GabbleJingleInfoPrivate *priv = self->priv;
+ GQueue stun_servers = G_QUEUE_INIT;
+
+ if (priv->stun_server != NULL)
+ g_queue_push_head (&stun_servers, priv->stun_server);
+
+ /* Only add the fallback server as a last resort. */
+ if (stun_servers.length == 0 &&
+ priv->fallback_stun_server != NULL)
+ g_queue_push_tail (&stun_servers, priv->fallback_stun_server);
+
+ return stun_servers.head;
}
const gchar *
diff --git a/src/jingle-info.h b/src/jingle-info.h
index 2ce8111c6..afac05610 100644
--- a/src/jingle-info.h
+++ b/src/jingle-info.h
@@ -47,12 +47,17 @@ void gabble_jingle_info_take_stun_server (
gchar *stun_server,
guint16 stun_port,
gboolean is_fallback);
-void gabble_jingle_info_send_request (GabbleJingleInfo *self);
-
-gboolean gabble_jingle_info_get_stun_server (
+void gabble_jingle_info_send_request (
GabbleJingleInfo *self,
- gchar **stun_server,
- guint *stun_port);
+ gboolean google_jingleinfo_supported);
+
+typedef struct {
+ gchar *address;
+ guint16 port;
+} GabbleStunServer;
+
+GList *gabble_jingle_info_get_stun_servers (
+ GabbleJingleInfo *self);
const gchar *gabble_jingle_info_get_google_relay_token (
GabbleJingleInfo *self);
diff --git a/src/jingle-mint.c b/src/jingle-mint.c
index f575cfd39..2cb6d0e9d 100644
--- a/src/jingle-mint.c
+++ b/src/jingle-mint.c
@@ -229,11 +229,12 @@ connection_status_changed_cb (
gabble_jingle_info_take_stun_server (info,
stun_server, stun_port, TRUE);
- if (priv->conn->features &
- GABBLE_CONNECTION_FEATURES_GOOGLE_JINGLE_INFO)
- {
- gabble_jingle_info_send_request (info);
- }
+ gabble_jingle_info_send_request (info,
+ /* FIXME: one day Wocky will know about caps and then we won't
+ * have to pass in a flag here.
+ */
+ !!(priv->conn->features &
+ GABBLE_CONNECTION_FEATURES_GOOGLE_JINGLE_INFO));
}
break;
diff --git a/src/media-channel.c b/src/media-channel.c
index 47c99d7a8..6b5ebd328 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -327,8 +327,7 @@ gabble_media_channel_constructor (GType type, guint n_props,
TpHandleRepoIface *contact_handles;
GabbleJingleInfo *ji;
const gchar *relay_token;
- gchar *stun_server;
- guint stun_port;
+ GList *stun_servers;
obj = G_OBJECT_CLASS (gabble_media_channel_parent_class)->
constructor (type, n_props, props);
@@ -378,15 +377,17 @@ gabble_media_channel_constructor (GType type, guint n_props,
/* Set up Google relay related properties */
ji = gabble_jingle_mint_get_info (priv->conn->jingle_mint);
-
- if (gabble_jingle_info_get_stun_server (ji, &stun_server,
- &stun_port))
+ stun_servers = gabble_jingle_info_get_stun_servers (ji);
+ if (stun_servers != NULL)
{
+ GabbleStunServer *stun_server = stun_servers->data;
+
g_object_set (obj,
- "stun-server", stun_server,
- "stun-port", stun_port,
+ "stun-server", stun_server->address,
+ "stun-port", (guint) stun_server->port,
NULL);
- g_free (stun_server);
+
+ g_list_free (stun_servers);
}
relay_token = gabble_jingle_info_get_google_relay_token (ji);
diff --git a/src/media-stream.c b/src/media-stream.c
index 300269214..d347c78eb 100644
--- a/src/media-stream.c
+++ b/src/media-stream.c
@@ -268,8 +268,7 @@ gabble_media_stream_constructor (GType type, guint n_props,
GabbleMediaStream *stream;
GabbleMediaStreamPrivate *priv;
GabbleJingleFactory *jf;
- gchar *stun_server;
- guint stun_port;
+ GList *stun_servers;
/* call base class constructor */
obj = G_OBJECT_CLASS (gabble_media_stream_parent_class)->
@@ -283,21 +282,19 @@ gabble_media_stream_constructor (GType type, guint n_props,
* point in waiting for them - either they've already been resolved, or
* we're too late to use them for this stream */
jf = gabble_jingle_session_get_factory (priv->content->session);
-
- /* maybe one day we'll support multiple STUN servers */
- if (gabble_jingle_info_get_stun_server (
- gabble_jingle_factory_get_jingle_info (jf),
- &stun_server, &stun_port))
+ stun_servers = gabble_jingle_info_get_stun_servers (
+ gabble_jingle_factory_get_jingle_info (jf));
+ while (stun_servers != NULL)
{
- GValueArray *va = g_value_array_new (2);
-
- g_value_array_append (va, NULL);
- g_value_array_append (va, NULL);
- g_value_init (va->values + 0, G_TYPE_STRING);
- g_value_init (va->values + 1, G_TYPE_UINT);
- g_value_take_string (va->values + 0, stun_server);
- g_value_set_uint (va->values + 1, stun_port);
+ GabbleStunServer *stun_server = stun_servers->data;
+ GValueArray *va = tp_value_array_build (2,
+ G_TYPE_STRING, stun_server->address,
+ G_TYPE_UINT, (guint) stun_server->port,
+ G_TYPE_INVALID);
+
g_ptr_array_add (priv->stun_servers, va);
+
+ stun_servers = g_list_delete_link (stun_servers, stun_servers);
}
/* go for the bus */