[libnice] [RFC PATCH] Handling multiple candidates with same foundation in a component.

Philip Withnall philip at tecnocode.co.uk
Tue Dec 15 16:03:48 PST 2015


Hi Simone,

Thanks for the patch — from a quick glance, it looks like a reasonable
explanation and fix for your problem.

Can you please attach it to Phabricator? We prefer the patch review
interface there. :-)  CC me to the report (pwithnall).

Philip

On Mon, 2015-12-14 at 13:44 +0100, Simone Gotti wrote:
> Hi,
> 
> I debugged some strange webrtc failed connections between browsers
> (firefox
> and chrome) and janus gateway and noticed that they were caused by
> libnice
> sending data to the wrong remote candidate udp port. libnice debug
> reported the
> right pair candidates addresses but then the wrong remote candidates
> were used.
> 
> I noticed that the cause was related to having multiple remote
> candidates with
> identical foundation in the same component These remote candidates
> were of
> two kind:
> 
> *) peer reflexive remote candidates discovered by libnice (more than
> one
> candidate with foundation named "remote-1").
> 
> *) remote candidates added by janus (in this case they were wrongly
> added and
> I have a fix for janus, but adding multiple remote candidates with
> same
> foundation can probably happen).
> 
> in agent/component.c:nice_component_find_pair, the candidate's
> foundation is
> used to find the related candidate in the component. When multiple
> candidates
> have the same foundation the first one is returned but it cannot be
> the right
> one.
> 
> If I read the ICE rfc correctly, multiple candidate with the same
> foundation in
> a component should be handled.
> 
> I made this RFC patch and it fixed the problem. Perhaps there can be
> better ways to handle this but I think it can be a good start for a
> discussion.
> If I need to use phabricator please let me know (I feel more
> comfortable
> with emails).
> 
> Thanks!
> 
> Simone
> 
> 
> 
> From 0376dd3373c1740fc5ef86254669a7d153ae2201 Mon Sep 17 00:00:00
> 2001
> From: Simone Gotti <simone.gotti at gmail.com>
> Date: Sun, 13 Dec 2015 17:28:53 +0100
> Subject: [PATCH] agent: handle multiple candidates with same
> foundation per
>  component.
> 
> nice_component_find_pair finds the local and remote candidates using
> the
> provided foundations, since there can be multiple candidates with the
> same
> foundation, the wrong candidate can be chosen.
> 
> This patch changes nice_component_find_pair to also check the
> candidate
> address.
> 
> The previous version of nice_component_find_pair has been renamed to
> nice_component_find_pair_by_foundation since it's used by the
> exported function
> nice_agent_set_selected_pair.
> 
> Signed-off-by: Simone Gotti <simone.gotti at gmail.com>
> ---
>  agent/agent.c     |  2 +-
>  agent/component.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
>  agent/component.h |  7 ++++++-
>  agent/conncheck.c |  4 ++--
>  4 files changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/agent/agent.c b/agent/agent.c
> index 279e7cd..1dc6ef2 100644
> --- a/agent/agent.c
> +++ b/agent/agent.c
> @@ -5048,7 +5048,7 @@ nice_agent_set_selected_pair (
>      goto done;
>    }
>  
> -  if (!nice_component_find_pair (component, agent, lfoundation,
> rfoundation, &pair)){
> +  if (!nice_component_find_pair_by_foundation (component, agent,
> lfoundation, rfoundation, &pair)){
>      goto done;
>    }
>  
> diff --git a/agent/component.c b/agent/component.c
> index d6712f4..1c795be 100644
> --- a/agent/component.c
> +++ b/agent/component.c
> @@ -286,18 +286,57 @@ nice_component_close (NiceComponent *cmp)
>  }
>  
>  /*
> - * Finds a candidate pair that has matching foundation ids.
> + * Finds a candidate pair that has matching local and remote
> candidates.
>   *
>   * @return TRUE if pair found, pointer to pair stored at 'pair'
>   */
>  gboolean
> -nice_component_find_pair (NiceComponent *cmp, NiceAgent *agent,
> const gchar *lfoundation, const gchar *rfoundation, CandidatePair
> *pair)
> +nice_component_find_pair (NiceComponent *cmp, NiceAgent *agent,
> NiceCandidate *lcandidate, NiceCandidate *rcandidate, CandidatePair
> *pair)
>  {
>    GSList *i;
>    CandidatePair result = { 0, };
>  
>    for (i = cmp->local_candidates; i; i = i->next) {
>      NiceCandidate *candidate = i->data;
> +    if (strncmp (candidate->foundation, lcandidate->foundation,
> NICE_CANDIDATE_MAX_FOUNDATION) == 0 &&
> +        nice_address_equal(&candidate->addr, &lcandidate->addr)) {
> +      result.local = candidate;
> +      break;
> +    }
> +  }
> +
> +  for (i = cmp->remote_candidates; i; i = i->next) {
> +    NiceCandidate *candidate = i->data;
> +    if (strncmp (candidate->foundation, rcandidate->foundation,
> NICE_CANDIDATE_MAX_FOUNDATION) == 0 &&
> +        nice_address_equal(&candidate->addr, &rcandidate->addr)) {
> +      result.remote = candidate;
> +      break;
> +    }
> +  }
> +
> +  if (result.local && result.remote) {
> +    result.priority = agent_candidate_pair_priority (agent,
> result.local, result.remote);
> +    if (pair)
> +      *pair = result;
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/*
> + * Finds a candidate pair that has matching foundation ids.
> + *
> + * @return TRUE if pair found, pointer to pair stored at 'pair'
> + */
> +gboolean
> +nice_component_find_pair_by_foundation (NiceComponent *cmp,
> NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation,
> CandidatePair *pair)
> +{
> +  GSList *i;
> +  CandidatePair result = { 0, };
> +
> + for (i = cmp->local_candidates; i; i = i->next) {
> +    NiceCandidate *candidate = i->data;
>      if (strncmp (candidate->foundation, lfoundation,
> NICE_CANDIDATE_MAX_FOUNDATION) == 0) {
>        result.local = candidate;
>        break;
> @@ -322,6 +361,7 @@ nice_component_find_pair (NiceComponent *cmp,
> NiceAgent *agent, const gchar *lfo
>    return FALSE;
>  }
>  
> +
>  /*
>   * Resets the component state to that of a ICE restarted
>   * session.
> diff --git a/agent/component.h b/agent/component.h
> index bc5d0c7..e4e0dab 100644
> --- a/agent/component.h
> +++ b/agent/component.h
> @@ -238,9 +238,14 @@ void
>  nice_component_close (NiceComponent *component);
>  
>  gboolean
> -nice_component_find_pair (NiceComponent *component, NiceAgent
> *agent,
> +nice_component_find_pair (NiceComponent *cmp, NiceAgent *agent,
> +    NiceCandidate *lcandidate, NiceCandidate *rcandidate,
> CandidatePair *pair);
> +
> +gboolean
> +nice_component_find_pair_by_foundation (NiceComponent *component,
> NiceAgent *agent,
>      const gchar *lfoundation, const gchar *rfoundation,
> CandidatePair *pair);
>  
> +
>  void
>  nice_component_restart (NiceComponent *component);
>  
> diff --git a/agent/conncheck.c b/agent/conncheck.c
> index 60d2fbf..3fce9dd 100644
> --- a/agent/conncheck.c
> +++ b/agent/conncheck.c
> @@ -1212,8 +1212,8 @@ static gboolean priv_update_selected_pair
> (NiceAgent *agent, NiceComponent *comp
>    g_assert (component);
>    g_assert (pair);
>    if (pair->priority > component->selected_pair.priority &&
> -      nice_component_find_pair (component, agent, pair->local-
> >foundation,
> -          pair->remote->foundation, &cpair)) {
> +      nice_component_find_pair (component, agent, pair->local,
> +          pair->remote, &cpair)) {
>      nice_debug ("Agent %p : changing SELECTED PAIR for component %u:
> %s:%s "
>          "(prio:%" G_GUINT64_FORMAT ").", agent, component->id,
>          pair->local->foundation, pair->remote->foundation, pair-
> >priority);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/nice/attachments/20151216/e4ec3b5b/attachment.sig>


More information about the nice mailing list