[libnice] Fwd: Controlled agent will be not ready when it is behind a NAT in our latest master branch
hui yu
huiyupet2002 at gmail.com
Tue Apr 25 03:28:32 UTC 2017
Hi,
When the controlled agent is in a private network behind a NAT and the
controlling agent is in a public network:
I try to use the threaded-example.c to do a test, but I got a failed result:
Only the controlling agent got a ready state and the controlled agent could
not get ready state.
1. Gathering candidates:
Controlled agent gathered: left_local_address and left_server_reflex_address
Controlling agent gathered: right_local_address
2. Connectivity checks and Negotiation:
1) Controlling agent
11) make a nominated pair: [right_local_address,
left_server_reflex_address];
22) send a stun request;
33) get a stun successful response;
44) Negotiation complete;
2) Controlled agent:
11) Receive a stun request from controlling agent;
22) Send a stun response to controlling agent;
33) According to a stun request from controlling agent and get a nominated
pair: [left_local_address, right_local_address];
44) Send a stun request with this nominated pair to controlling agent.
55) Receive a stun response from controlling agent and get a mapped address
and make a new discovery pair [left_server_reflex_address,
right_local_address];
66) The new discover pair is a valid pair, but it cannot become a nominated
pair in current master code.
77) Negotiation failed.
I look up the source code and find maybe there is two mistakes in the code,
I think if the nominated value in the new discovery pair can inherit from
the parent pairt.
The fix code is in red with yellow background.
/////////////////////////////////////
static CandidateCheckPair *priv_add_peer_reflexive_pair (NiceAgent *agent,
guint stream_id, NiceComponent *component, NiceCandidate *local_cand,
CandidateCheckPair *parent_pair)
{
CandidateCheckPair *pair = g_slice_new0 (CandidateCheckPair);
NiceStream *stream = agent_find_stream (agent, stream_id);
pair->agent = agent;
pair->stream_id = stream_id;
pair->component_id = component->id;;
pair->local = local_cand;
pair->remote = parent_pair->remote;
pair->sockptr = local_cand->sockptr;
pair->state = NICE_CHECK_DISCOVERED;
nice_debug ("Agent %p : new pair %p state DISCOVERED", agent, pair);
{
gchar tmpbuf1[INET6_ADDRSTRLEN];
gchar tmpbuf2[INET6_ADDRSTRLEN];
nice_address_to_string (&pair->local->addr, tmpbuf1);
nice_address_to_string (&pair->remote->addr, tmpbuf2);
nice_debug ("Agent %p : new pair %p : [%s]:%u --> [%s]:%u", agent,
pair,
tmpbuf1, nice_address_get_port (&pair->local->addr),
tmpbuf2, nice_address_get_port (&pair->remote->addr));
}
g_snprintf (pair->foundation, NICE_CANDIDATE_PAIR_MAX_FOUNDATION, "%s:%s",
local_cand->foundation, parent_pair->remote->foundation);
if (agent->controlling_mode == TRUE)
pair->priority = nice_candidate_pair_priority (pair->local->priority,
pair->remote->priority);
else
pair->priority = nice_candidate_pair_priority (pair->remote->priority,
pair->local->priority);
pair->nominated = FALSE; -------------à pair->nominated = parent_pai->
nominated;
pair->prflx_priority = ensure_unique_priority (component,
peer_reflexive_candidate_priority (agent, local_cand));
nice_debug ("Agent %p : added a new peer-discovered pair with foundation
of '%s'.", agent, pair->foundation);
stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list,
pair,
(GCompareFunc)conn_check_compare);
return pair;
}
static CandidateCheckPair *priv_process_response_check_for_reflexive(NiceAgent
*agent, NiceStream *stream, NiceComponent *component, CandidateCheckPair
*p, NiceSocket *sockptr, struct sockaddr *mapped_sockaddr, NiceCandidate
*local_candidate, NiceCandidate *remote_candidate)
{
CandidateCheckPair *new_pair = NULL;
NiceAddress mapped;
GSList *i, *j;
NiceCandidate *local_cand = NULL;
nice_address_set_from_sockaddr (&mapped, mapped_sockaddr);
for (j = component->local_candidates; j; j = j->next) {
NiceCandidate *cand = j->data;
if (nice_address_equal (&mapped, &cand->addr)) {
local_cand = cand;
/* We always need to select the peer-reflexive Candidate Pair in the
case
* of a TCP-ACTIVE local candidate, so we find it even if an incoming
* check matched an existing pair because it could be the original
* ACTIVE-PASSIVE candidate pair which was retriggered */
for (i = stream->conncheck_list; i; i = i->next) {
CandidateCheckPair *pair = i->data;
if (pair->local == cand && remote_candidate == pair->remote) {
new_pair = pair;
break;
}
}
break;
}
}
if (new_pair) {
p->state = NICE_CHECK_SUCCEEDED;
new_pair-> nominated = p-> nominated;
nice_debug ("Agent %p : conncheck %p SUCCEEDED.", agent, p);
priv_conn_check_unfreeze_related (agent, stream, p);
nice_component_add_valid_candidate (component, remote_candidate);
}
else {
if (!local_cand) {
if (!agent->force_relay)
local_cand = discovery_add_peer_reflexive_candidate (agent,
stream->id,
component->id,
&mapped,
sockptr,
local_candidate,
remote_
candidate);
p->state = NICE_CHECK_FAILED;
nice_debug ("Agent %p : pair %p state FAILED", agent, p);
}
/* step: add a new discovered pair (see RFC 5245 7.1.3.2.2
"Constructing a Valid Pair") */
if (local_cand)
new_pair = priv_add_peer_reflexive_pair (agent, stream->id, component,
local_cand, p);
nice_debug ("Agent %p : conncheck %p FAILED, %p DISCOVERED.", agent, p,
new_pair);
}
/* note: this is same as "adding to VALID LIST" in the spec
text */
if (new_pair) {
new_pair->valid = TRUE;
nice_component_add_valid_candidate (component, remote_candidate);
}
return new_pair;
}
/////////////////////////////////////
Hui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/nice/attachments/20170425/dadc5868/attachment.html>
More information about the nice
mailing list