From: Olivier CrĂȘte Date: Wed, 16 Apr 2014 02:52:30 +0000 (-0400) Subject: component: Clear turn local candidates when clearing turn servers X-Git-Tag: 0.1.6~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=69749bad4e2660db6dcf6460b3ac60235715ef5c;p=platform%2Fupstream%2Flibnice.git component: Clear turn local candidates when clearing turn servers But keep the turn connection that's currently being used if it is the selected candidate. Also clear the TURN candidate refresh. --- diff --git a/agent/component.c b/agent/component.c index 3cd4855..3c2d6a2 100644 --- a/agent/component.c +++ b/agent/component.c @@ -51,6 +51,7 @@ #include "debug.h" #include "component.h" +#include "discovery.h" #include "agent-priv.h" @@ -148,9 +149,48 @@ component_new (guint id, NiceAgent *agent, Stream *stream) void component_clean_turn_servers (Component *cmp) { + GSList *i; g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref); cmp->turn_servers = NULL; + + for (i = cmp->local_candidates; i;) { + NiceCandidate *candidate = i->data; + GSList *next = i->next; + + if (candidate->type != NICE_CANDIDATE_TYPE_RELAYED) { + i = next; + continue; + } + + /* note: do not remove the remote candidate that is + * currently part of the 'selected pair', see ICE + * 9.1.1.1. "ICE Restarts" (ID-19) + * + * So what we do instead is that we put the selected candidate + * in a special location and keep it "alive" that way. This is + * especially important for TURN, because refresh requests to the + * server need to keep happening. + */ + if (candidate == cmp->selected_pair.local) { + if (cmp->turn_candidate) { + refresh_prune_candidate (cmp->agent, cmp->turn_candidate); + component_detach_socket (cmp, cmp->turn_candidate->sockptr); + nice_candidate_free (cmp->turn_candidate); + } + /* Bring the priority down to 0, so that it will be replaced + * on the new run. + */ + cmp->selected_pair.priority = 0; + cmp->turn_candidate = candidate; + } else { + refresh_prune_candidate (cmp->agent, candidate); + component_detach_socket (cmp, candidate->sockptr); + nice_candidate_free (candidate); + } + cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); + i = next; + } } void @@ -174,6 +214,10 @@ component_free (Component *cmp) nice_candidate_free (cmp->restart_candidate), cmp->restart_candidate = NULL; + if (cmp->turn_candidate) + nice_candidate_free (cmp->turn_candidate), + cmp->turn_candidate = NULL; + for (i = cmp->incoming_checks; i; i = i->next) { IncomingCheck *icheck = i->data; g_free (icheck->username); @@ -181,9 +225,12 @@ component_free (Component *cmp) } g_slist_free (cmp->local_candidates); + cmp->local_candidates = NULL; g_slist_free (cmp->remote_candidates); + cmp->remote_candidates = NULL; component_free_socket_sources (cmp); g_slist_free (cmp->incoming_checks); + cmp->incoming_checks = NULL; component_clean_turn_servers (cmp); @@ -285,7 +332,7 @@ component_restart (Component *cmp) for (i = cmp->remote_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; - /* note: do not remove the remote candidate that is + /* note: do not remove the local candidate that is * currently part of the 'selected pair', see ICE * 9.1.1.1. "ICE Restarts" (ID-19) */ if (candidate == cmp->selected_pair.remote) { diff --git a/agent/component.h b/agent/component.h index b1e6507..207fdcb 100644 --- a/agent/component.h +++ b/agent/component.h @@ -149,7 +149,7 @@ struct _Component CandidatePair selected_pair; /**< independent from checklists, see ICE 11.1. "Sending Media" (ID-19) */ NiceCandidate *restart_candidate; /**< for storing active remote candidate during a restart */ - + NiceCandidate *turn_candidate; /**< for storing active turn candidate if turn servers have been cleared */ /* I/O handling. The main context must always be non-NULL, and is used for all * socket recv() operations. All io_callback emissions are invoked in this * context too. diff --git a/agent/conncheck.c b/agent/conncheck.c index 376fb18..e697cb6 100644 --- a/agent/conncheck.c +++ b/agent/conncheck.c @@ -1128,6 +1128,14 @@ static gboolean priv_update_selected_pair (NiceAgent *agent, Component *componen component->selected_pair.keepalive.tick_source = NULL; } + if (component->selected_pair.local && + component->selected_pair.local == component->turn_candidate) { + refresh_prune_candidate (agent, component->turn_candidate); + component_detach_socket (component, component->turn_candidate->sockptr); + nice_candidate_free (component->turn_candidate); + component->turn_candidate = NULL; + } + memset (&component->selected_pair, 0, sizeof(CandidatePair)); component->selected_pair.local = pair->local; component->selected_pair.remote = pair->remote; diff --git a/agent/discovery.c b/agent/discovery.c index 6866f57..a484d72 100644 --- a/agent/discovery.c +++ b/agent/discovery.c @@ -206,7 +206,7 @@ void refresh_free (NiceAgent *agent) /* * Prunes the list of discovery processes for items related - * to stream 'stream_id'. + * to stream 'stream_id'. * * @return TRUE on success, FALSE on a fatal error */ @@ -218,6 +218,9 @@ void refresh_prune_stream (NiceAgent *agent, guint stream_id) CandidateRefresh *cand = i->data; GSList *next = i->next; + /* Don't free the candidate refresh to the currently selected local candidate + * unless the whole pair is being destroyed. + */ if (cand->stream->id == stream_id) { agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); refresh_free_item (cand); @@ -228,6 +231,23 @@ void refresh_prune_stream (NiceAgent *agent, guint stream_id) } +void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate) +{ + GSList *i; + + for (i = agent->refresh_list; i;) { + GSList *next = i->next; + CandidateRefresh *refresh = i->data; + + if (refresh->candidate == candidate) { + agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); + refresh_free_item (refresh); + } + + i = next; + } +} + void refresh_cancel (CandidateRefresh *refresh) { refresh->agent->refresh_list = g_slist_remove (refresh->agent->refresh_list, @@ -235,6 +255,7 @@ void refresh_cancel (CandidateRefresh *refresh) refresh_free_item (refresh); } + /* * Adds a new local candidate. Implements the candidate pruning * defined in ICE spec section 4.1.3 "Eliminating Redundant diff --git a/agent/discovery.h b/agent/discovery.h index e4cc20a..f6d3bdd 100644 --- a/agent/discovery.h +++ b/agent/discovery.h @@ -84,6 +84,7 @@ typedef struct void refresh_free (NiceAgent *agent); void refresh_prune_stream (NiceAgent *agent, guint stream_id); +void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate); void refresh_cancel (CandidateRefresh *refresh);