diff options
author | Youness Alaoui <kakaroto@kakaroto.homelinux.net> | 2014-07-22 21:11:46 -0400 |
---|---|---|
committer | Youness Alaoui <kakaroto@kakaroto.homelinux.net> | 2014-07-22 21:11:46 -0400 |
commit | 5ab7c88349008136ebf847b6bc7dfb31d13bfa70 (patch) | |
tree | 4b9348ff7849c36c3e1be29436f7d0b2ff5ff275 | |
parent | 76f4aeaefef711c0727b9e9957d18c40c3142676 (diff) | |
download | libnice-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.
-rw-r--r-- | socket/udp-turn.c | 56 |
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 (¤t_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); } |