<div dir="ltr"><div class="gmail_quote"><div lang="EN-US" link="#0563C1" vlink="#954F72"><div class="m_-8993483861822013067WordSection1"><p class="MsoNormal">Hi,<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">When the controlled agent is in a private network behind a NAT and the controlling agent is in a public network:<u></u><u></u></p><p class="MsoNormal">I try to use the threaded-example.c to do a test, but I got a failed result:<u></u><u></u></p><p class="MsoNormal">   Only the controlling agent got a ready state and the controlled agent <span style="background:yellow">could not get ready state</span>.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="m_-8993483861822013067MsoListParagraph"><u></u><span>1.<span style="font:7.0pt "Times New Roman"">      </span></span><u></u>Gathering candidates:<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph">Controlled agent gathered: left_local_address and left_server_reflex_address<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph">Controlling agent gathered: right_local_address<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph"><u></u><span>2.<span style="font:7.0pt "Times New Roman"">      </span></span><u></u>Connectivity checks and Negotiation:<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in"><u></u><span>1)<span style="font:7.0pt "Times New Roman"">     </span></span><u></u>Controlling agent<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">11) make a nominated pair: <span style="background:yellow">[right_local_address, left_server_reflex_address];</span><u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">22) send a stun request;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">33) get a stun successful response;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">44) Negotiation complete;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in"><u></u><span>2)<span style="font:7.0pt "Times New Roman"">     </span></span><u></u>Controlled agent:<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">11) Receive a stun request from controlling agent;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">22) Send a stun response to controlling agent;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">33) According to a stun request from controlling agent and get a nominated pair: <span style="background:yellow">[left_local_address, right_local_address];</span><u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">44) Send a stun request with this nominated pair to controlling agent.<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">55) Receive a stun response from controlling agent and get a mapped address and make a new discovery pair <span style="background:yellow">[left_server_reflex_address, right_local_address]</span>;<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">66) The new discover pair is a valid pair, but it cannot become a nominated pair in current master code.<u></u><u></u></p><p class="m_-8993483861822013067MsoListParagraph" style="margin-left:.75in">77) Negotiation failed. <u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">I look up the source code and find maybe there is two mistakes in the code, I think <span style="background:yellow">if the nominated value in the new discovery pair can inherit from the parent pairt.</span><u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">The fix code is in red with yellow background.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">//////////////////////////////<wbr>///////<u></u><u></u></p><p class="MsoNormal">static CandidateCheckPair *<span style="background:yellow">priv_add_peer_reflexive_pair</span> (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local_cand, CandidateCheckPair *parent_pair)<u></u><u></u></p><p class="MsoNormal">{<u></u><u></u></p><p class="MsoNormal">  CandidateCheckPair *pair = g_slice_new0 (CandidateCheckPair);<u></u><u></u></p><p class="MsoNormal">  NiceStream *stream = agent_find_stream (agent, stream_id);<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  pair->agent = agent;<u></u><u></u></p><p class="MsoNormal">  pair->stream_id = stream_id;<u></u><u></u></p><p class="MsoNormal">  pair->component_id = component->id;;<u></u><u></u></p><p class="MsoNormal">  pair->local = local_cand;<u></u><u></u></p><p class="MsoNormal">  pair->remote = parent_pair->remote;<u></u><u></u></p><p class="MsoNormal">  pair->sockptr = local_cand->sockptr;<u></u><u></u></p><p class="MsoNormal">  pair->state = NICE_CHECK_DISCOVERED;<u></u><u></u></p><p class="MsoNormal">  nice_debug ("Agent %p : new pair %p state DISCOVERED", agent, pair);<u></u><u></u></p><p class="MsoNormal">  {<u></u><u></u></p><p class="MsoNormal">      gchar tmpbuf1[INET6_ADDRSTRLEN];<u></u><u></u></p><p class="MsoNormal">      gchar tmpbuf2[INET6_ADDRSTRLEN];<u></u><u></u></p><p class="MsoNormal">      nice_address_to_string (&pair->local->addr, tmpbuf1);<u></u><u></u></p><p class="MsoNormal">      nice_address_to_string (&pair->remote->addr, tmpbuf2);<u></u><u></u></p><p class="MsoNormal">      nice_debug ("Agent %p : new pair %p : [%s]:%u --> [%s]:%u", agent, pair,<u></u><u></u></p><p class="MsoNormal">          tmpbuf1, nice_address_get_port (&pair->local->addr),<u></u><u></u></p><p class="MsoNormal">          tmpbuf2, nice_address_get_port (&pair->remote->addr));<u></u><u></u></p><p class="MsoNormal">  }<u></u><u></u></p><p class="MsoNormal">  g_snprintf (pair->foundation, NICE_CANDIDATE_PAIR_MAX_<wbr>FOUNDATION, "%s:%s",<u></u><u></u></p><p class="MsoNormal">      local_cand->foundation, parent_pair->remote-><wbr>foundation);<u></u><u></u></p><p class="MsoNormal">  if (agent->controlling_mode == TRUE)<u></u><u></u></p><p class="MsoNormal">    pair->priority = nice_candidate_pair_priority (pair->local->priority,<u></u><u></u></p><p class="MsoNormal">        pair->remote->priority);<u></u><u></u></p><p class="MsoNormal">  else<u></u><u></u></p><p class="MsoNormal">    pair->priority = nice_candidate_pair_priority (pair->remote->priority,<u></u><u></u></p><p class="MsoNormal">        pair->local->priority);<u></u><u></u></p><p class="MsoNormal">  <span style="background:yellow">pair->nominated = FALSE;</span>  -------------<span style="font-family:Wingdings">à</span> <span style="color:red;background:yellow">pair->nominated = parent_pai-> nominated</span><span style="background:yellow">;</span><u></u><u></u></p><p class="MsoNormal">  pair->prflx_priority = ensure_unique_priority (component,<u></u><u></u></p><p class="MsoNormal">      peer_reflexive_candidate_<wbr>priority (agent, local_cand));<u></u><u></u></p><p class="MsoNormal">  nice_debug ("Agent %p : added a new peer-discovered pair with foundation of '%s'.",  agent, pair->foundation);<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair,<u></u><u></u></p><p class="MsoNormal">      (GCompareFunc)conn_check_<wbr>compare);<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  return pair;<u></u><u></u></p><p class="MsoNormal">}<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">static CandidateCheckPair *<span style="background:yellow">priv_process_response_check_<wbr>for_reflexive</span>(NiceAgent *agent, NiceStream *stream, NiceComponent *component, CandidateCheckPair *p, NiceSocket *sockptr, struct sockaddr *mapped_sockaddr, NiceCandidate *local_candidate, NiceCandidate *remote_candidate)<u></u><u></u></p><p class="MsoNormal">{<u></u><u></u></p><p class="MsoNormal">  CandidateCheckPair *new_pair = NULL;<u></u><u></u></p><p class="MsoNormal">  NiceAddress mapped;<u></u><u></u></p><p class="MsoNormal">  GSList *i, *j;<u></u><u></u></p><p class="MsoNormal">  NiceCandidate *local_cand = NULL;<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  nice_address_set_from_sockaddr (&mapped, mapped_sockaddr);<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  for (j = component->local_candidates; j; j = j->next) {<u></u><u></u></p><p class="MsoNormal">    NiceCandidate *cand = j->data;<u></u><u></u></p><p class="MsoNormal">    if (nice_address_equal (&mapped, &cand->addr)) {<u></u><u></u></p><p class="MsoNormal">      local_cand = cand;<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">      /* We always need to select the peer-reflexive Candidate Pair in the case<u></u><u></u></p><p class="MsoNormal">       * of a TCP-ACTIVE local candidate, so we find it even if an incoming<u></u><u></u></p><p class="MsoNormal">       * check matched an existing pair because it could be the original<u></u><u></u></p><p class="MsoNormal">       * ACTIVE-PASSIVE candidate pair which was retriggered */<u></u><u></u></p><p class="MsoNormal">      for (i = stream->conncheck_list; i; i = i->next) {<u></u><u></u></p><p class="MsoNormal">        CandidateCheckPair *pair = i->data;<u></u><u></u></p><p class="MsoNormal">        if (pair->local == cand && remote_candidate == pair->remote) {<u></u><u></u></p><p class="MsoNormal">          new_pair = pair;<u></u><u></u></p><p class="MsoNormal">          break;<u></u><u></u></p><p class="MsoNormal">        }<u></u><u></u></p><p class="MsoNormal">      }<u></u><u></u></p><p class="MsoNormal">      break;<u></u><u></u></p><p class="MsoNormal">    }<u></u><u></u></p><p class="MsoNormal">  }<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  if (new_pair) {<u></u><u></u></p><p class="MsoNormal" style="text-indent:10.2pt">p->state = NICE_CHECK_SUCCEEDED;<u></u><u></u></p><p class="MsoNormal" style="text-indent:10.2pt"><span style="color:red;background:yellow">new_pair-> nominated  = p-> nominated</span><span style="background:yellow">;</span><u></u><u></u></p><p class="MsoNormal">    nice_debug ("Agent %p : conncheck %p SUCCEEDED.", agent, p);<u></u><u></u></p><p class="MsoNormal">    priv_conn_check_unfreeze_<wbr>related (agent, stream, p);<u></u><u></u></p><p class="MsoNormal">    nice_component_add_valid_<wbr>candidate (component, remote_candidate);<u></u><u></u></p><p class="MsoNormal">  }<u></u><u></u></p><p class="MsoNormal">  else {<u></u><u></u></p><p class="MsoNormal">    if (!local_cand) {<u></u><u></u></p><p class="MsoNormal">      if (!agent->force_relay)<u></u><u></u></p><p class="MsoNormal">        local_cand = discovery_add_peer_reflexive_<wbr>candidate (agent,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                               stream->id,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                               component->id,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                              &mapped,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                               sockptr,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                               local_candidate,<u></u><u></u></p><p class="MsoNormal">                              <wbr>                               remote_<wbr>candidate);<u></u><u></u></p><p class="MsoNormal">      p->state = NICE_CHECK_FAILED;<u></u><u></u></p><p class="MsoNormal">      nice_debug ("Agent %p : pair %p state FAILED", agent, p);<u></u><u></u></p><p class="MsoNormal">    }<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">    /* step: add a new discovered pair (see RFC 5245 7.1.3.2.2<u></u><u></u></p><p class="MsoNormal">                      "Constructing a Valid Pair") */<u></u><u></u></p><p class="MsoNormal">    if (local_cand)<u></u><u></u></p><p class="MsoNormal">      new_pair = priv_add_peer_reflexive_pair (agent, stream->id, component,<u></u><u></u></p><p class="MsoNormal">          local_cand, p);<u></u><u></u></p><p class="MsoNormal">    nice_debug ("Agent %p : conncheck %p FAILED, %p DISCOVERED.", agent, p, new_pair);<u></u><u></u></p><p class="MsoNormal">  }<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  /* note: this is same as "adding to VALID LIST" in the spec<u></u><u></u></p><p class="MsoNormal">     text */<u></u><u></u></p><p class="MsoNormal">  if (new_pair) {<u></u><u></u></p><p class="MsoNormal">    new_pair->valid = TRUE;<u></u><u></u></p><p class="MsoNormal">    nice_component_add_valid_<wbr>candidate (component, remote_candidate);<u></u><u></u></p><p class="MsoNormal">  }<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">  return new_pair;<u></u><u></u></p><p class="MsoNormal">}<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">//////////////////////////////<wbr>///////<span class="HOEnZb"><font color="#888888"><u></u><u></u></font></span></p><span class="HOEnZb"><font color="#888888"><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Hui<u></u><u></u></p></font></span></div></div></div><br></div>