summaryrefslogtreecommitdiff
path: root/socket
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.homelinux.net>2014-07-22 21:11:46 -0400
committerYouness Alaoui <kakaroto@kakaroto.homelinux.net>2014-07-22 21:11:46 -0400
commit5ab7c88349008136ebf847b6bc7dfb31d13bfa70 (patch)
tree4b9348ff7849c36c3e1be29436f7d0b2ff5ff275 /socket
parent76f4aeaefef711c0727b9e9957d18c40c3142676 (diff)
downloadlibnice-5ab7c88349008136ebf847b6bc7dfb31d13bfa70.tar.gz
Fix timer for TURN CreatePermission.
The TURN CreatePermission is a list of multiple permissions but the timer is created and overwrites the old one, so some of them don't get triggered at the right time. This patch was suggested by Livio Madaro. We create a timer for the minimal amount of time, and trigger the retransmissions on the permissions that timed out, then reschedule for the next retransmissions.
Diffstat (limited to 'socket')
-rw-r--r--socket/udp-turn.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/socket/udp-turn.c b/socket/udp-turn.c
index e4fd270..0314203 100644
--- a/socket/udp-turn.c
+++ b/socket/udp-turn.c
@@ -1647,8 +1647,6 @@ priv_retransmissions_create_permission_tick_unlocked (UdpTurnPriv *priv, GList *
}
}
- if (ret)
- priv_schedule_tick (priv);
return ret;
}
@@ -1681,7 +1679,6 @@ static gboolean
priv_retransmissions_create_permission_tick (gpointer pointer)
{
UdpTurnPriv *priv = pointer;
- GList *i, *next;
agent_lock ();
if (g_source_is_destroyed (g_main_current_source ())) {
@@ -1691,17 +1688,11 @@ priv_retransmissions_create_permission_tick (gpointer pointer)
return FALSE;
}
- for (i = priv->pending_permissions; i; i = next) {
- next = i->next;
+ /* This will call priv_retransmissions_create_permission_tick_unlocked() for
+ * every pending permission with an expired timer and will create a new timer
+ * if there are pending permissions that require it */
+ priv_schedule_tick (priv);
- if (!priv_retransmissions_create_permission_tick_unlocked (priv, i)) {
- if (priv->tick_source_create_permission != NULL) {
- g_source_destroy (priv->tick_source_create_permission);
- g_source_unref (priv->tick_source_create_permission);
- priv->tick_source_create_permission = NULL;
- }
- }
- }
agent_unlock ();
return FALSE;
@@ -1710,8 +1701,9 @@ priv_retransmissions_create_permission_tick (gpointer pointer)
static void
priv_schedule_tick (UdpTurnPriv *priv)
{
- GList *i, *next;
+ GList *i, *next, *prev;
TURNMessage *current_create_permission_msg;
+ guint min_timeout = G_MAXUINT;
if (priv->tick_source_channel_bind != NULL) {
g_source_destroy (priv->tick_source_channel_bind);
@@ -1730,7 +1722,13 @@ priv_schedule_tick (UdpTurnPriv *priv)
}
}
- for (i = priv->pending_permissions; i; i = next) {
+ if (priv->tick_source_create_permission != NULL) {
+ g_source_destroy (priv->tick_source_create_permission);
+ g_source_unref (priv->tick_source_create_permission);
+ priv->tick_source_create_permission = NULL;
+ }
+
+ for (i = priv->pending_permissions, prev = NULL; i; i = next) {
guint timeout;
current_create_permission_msg = (TURNMessage *)i->data;
@@ -1739,19 +1737,27 @@ priv_schedule_tick (UdpTurnPriv *priv)
timeout = stun_timer_remainder (&current_create_permission_msg->timer);
if (timeout > 0) {
- if (priv->tick_source_create_permission) {
- g_source_destroy (priv->tick_source_create_permission);
- g_source_unref (priv->tick_source_create_permission);
- }
- priv->tick_source_create_permission =
- priv_timeout_add_with_context (priv, FALSE,
- timeout,
- priv_retransmissions_create_permission_tick,
- priv);
+ min_timeout = MIN (min_timeout, timeout);
+ prev = i;
} else {
+ /* This could either delete the permission from the list, or it could
+ * refresh it, changing its timeout value */
priv_retransmissions_create_permission_tick_unlocked (priv, i);
+ if (prev == NULL)
+ next = priv->pending_permissions;
+ else
+ next = prev->next;
}
}
+
+ /* We create one timer for the minimal timeout we need */
+ if (min_timeout != G_MAXUINT) {
+ priv->tick_source_create_permission =
+ priv_timeout_add_with_context (priv, FALSE,
+ min_timeout,
+ priv_retransmissions_create_permission_tick,
+ priv);
+ }
}
static void
@@ -1845,8 +1851,8 @@ priv_send_create_permission(UdpTurnPriv *priv, StunMessage *resp,
STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
}
- priv_schedule_tick (priv);
priv->pending_permissions = g_list_append (priv->pending_permissions, msg);
+ priv_schedule_tick (priv);
} else {
g_free(msg);
}