Commit f997215d authored by Fabrice Bellet's avatar Fabrice Bellet Committed by Olivier Crête
Browse files

candidate: ensuring stun priority uniqueness no more needed

The uniqueness of candidate priorities is achieved by the iteration on
the ip local addresses for local host candidates, and also on their base
address for reflexive and relay candidates. Helper function checking
its uniqueness at allocation time is not required anyore.

The priority of the stun request (prflx_priority) is built from the
priority of the local candidate of the pair, according the RFC 5245,
section 7.1.2.1. This priority must be identical to a virtual "local
candidate of type peer-reflexive that would be learned as a consequence
of a check from this local candidate."

Outgoing stun requests will come from local candidates of type host or
type relayed. The priority uniqueness of local candidates of type host
implies the uniqueness of the computed peer-reflexive priority.  And
relay local candidates cannot produce a peer-reflexive local candidate
by design, so we can safely use their unique local priority too in
the stun request.
parent ab14d9ed
......@@ -1482,6 +1482,26 @@ static guint32 peer_reflexive_candidate_priority (NiceAgent *agent,
return priority;
}
/* Returns the priority of a local candidate of type peer-reflexive that
* would be learned as a consequence of a check from this local
* candidate. See RFC 5245, section 7.1.2.1. "PRIORITY and USE-CANDIDATE".
* RFC 5245 is more explanatory than RFC 8445 on this detail.
*
* Apply to local candidates of type host only, because candidates of type
* relay are supposed to have a public IP address, that wont generate
* a peer-reflexive address. Server-reflexive candidates are not
* concerned too, because no STUN request is sent with a local candidate
* of this type.
*/
static guint32 stun_request_prflx_priority (NiceAgent *agent,
NiceCandidate *local_candidate)
{
if (local_candidate->type == NICE_CANDIDATE_TYPE_HOST)
return peer_reflexive_candidate_priority (agent, local_candidate);
else
return local_candidate->priority;
}
static void ms_ice2_legacy_conncheck_send(StunMessage *msg, NiceSocket *sock,
const NiceAddress *remote_addr)
{
......@@ -2407,69 +2427,6 @@ static void priv_mark_pair_nominated (NiceAgent *agent, NiceStream *stream, Nice
}
}
guint32
ensure_unique_priority (NiceStream *stream, NiceComponent *component,
guint32 priority)
{
GSList *item;
again:
if (priority == 0)
priority--;
for (item = component->local_candidates; item; item = item->next) {
NiceCandidate *cand = item->data;
if (cand->priority == priority) {
priority--;
goto again;
}
}
return priority;
}
static guint32
ensure_unique_prflx_priority (NiceStream *stream, NiceComponent *component,
guint32 local_priority, guint32 prflx_priority)
{
GSList *item;
/* First, ensure we provide the same value for pairs having
* the same local candidate, ie the same local candidate priority
* for the sake of coherency with the stun server behaviour that
* stores a unique priority value per remote candidate, from the
* first stun request it receives (it depends on the kind of NAT
* typically, but for NAT that preserves the binding this is required).
*/
for (item = stream->conncheck_list; item; item = item->next) {
CandidateCheckPair *p = item->data;
if (p->component_id == component->id &&
p->local->priority == local_priority) {
return p->prflx_priority;
}
}
/* Second, ensure uniqueness across all other prflx_priority values */
again:
if (prflx_priority == 0)
prflx_priority--;
for (item = stream->conncheck_list; item; item = item->next) {
CandidateCheckPair *p = item->data;
if (p->component_id == component->id &&
p->prflx_priority == prflx_priority) {
prflx_priority--;
goto again;
}
}
return prflx_priority;
}
/*
* Creates a new connectivity check pair and adds it to
* the agent's list of checks.
......@@ -2513,8 +2470,7 @@ static CandidateCheckPair *priv_add_new_check_pair (NiceAgent *agent,
tmpbuf1, nice_address_get_port (&pair->local->addr),
tmpbuf2, nice_address_get_port (&pair->remote->addr));
}
pair->prflx_priority = ensure_unique_prflx_priority (stream, component,
local->priority, peer_reflexive_candidate_priority (agent, local));
pair->prflx_priority = stun_request_prflx_priority (agent, local);
stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair,
(GCompareFunc)conn_check_compare);
......
......@@ -118,8 +118,6 @@ void
conn_check_prune_socket (NiceAgent *agent, NiceStream *stream, NiceComponent *component,
NiceSocket *sock);
guint32 ensure_unique_priority (NiceStream *stream, NiceComponent *component,
guint32 priority);
void recalculate_pair_priorities (NiceAgent *agent);
void conn_check_update_selected_pair (NiceAgent *agent,
NiceComponent *component, CandidateCheckPair *pair);
......
......@@ -645,8 +645,6 @@ HostCandidateResult discovery_add_local_host_candidate (
agent->reliable, FALSE);
}
candidate->priority = ensure_unique_priority (stream, component,
candidate->priority);
priv_generate_candidate_credentials (agent, candidate);
priv_assign_foundation (agent, candidate);
......@@ -737,8 +735,6 @@ discovery_add_server_reflexive_candidate (
agent->reliable, nat_assisted);
}
candidate->priority = ensure_unique_priority (stream, component,
candidate->priority);
priv_generate_candidate_credentials (agent, candidate);
priv_assign_foundation (agent, candidate);
......@@ -856,8 +852,6 @@ discovery_add_relay_candidate (
agent->reliable, FALSE);
}
candidate->priority = ensure_unique_priority (stream, component,
candidate->priority);
priv_generate_candidate_credentials (agent, candidate);
/* Google uses the turn username as the candidate username */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment