summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Adam <jakub.adam@ktknet.cz>2015-09-11 11:56:02 +0100
committerPhilip Withnall <philip.withnall@collabora.co.uk>2015-09-11 11:56:17 +0100
commit02852728ef347f5cb4c9227848b266c72b5fe38b (patch)
treea4db54b62fa267fe3f7aed10db828998d39f61f3
parent84eaa12b0b1a76c45ce2d77294e0477c10552cd4 (diff)
downloadlibnice-02852728ef347f5cb4c9227848b266c72b5fe38b.tar.gz
conncheck: generate candidate pair for valid srflx candidate
In priv_process_response_check_for_peer_reflexive(), mere presence of a candidate in local_candidates doesn't mean there's also some candidate pair in conncheck_list using it - for instance that candidate may be server reflexive, for which no check pairs are initially created (see conn_check_add_for_candidate_pair()). If we fail to find corresponding pair upon receiving such candidate's IP in a conncheck response's XOR-MAPPED-ADDRESS attribute, we shall add a new one in a similar way we would add a new pair for a just discovered peer reflexive candidate. Previous priv_process_response_check_for_peer_reflexive() implementation would return NULL, causing a CandidateCheckPair with local candidate of type HOST to be wrongly selected even though the local host IP might not be directly accessible by the remote counterpart (e.g. it's an address on a private network segment). In practice this was coming through as a duplex connection that libnice was reporting as properly established, but only one direction of the communication was actually working. Maniphest Tasks: https://phabricator.freedesktop.org/T115 Differential Revision: https://phabricator.freedesktop.org/D242 Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
-rw-r--r--agent/conncheck.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 7832339..643113e 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -2292,14 +2292,14 @@ static CandidateCheckPair *priv_process_response_check_for_peer_reflexive(NiceAg
CandidateCheckPair *new_pair = NULL;
NiceAddress mapped;
GSList *i, *j;
- gboolean local_cand_matches = FALSE;
+ 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_matches = TRUE;
+ 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
@@ -2316,7 +2316,7 @@ static CandidateCheckPair *priv_process_response_check_for_peer_reflexive(NiceAg
}
}
- if (local_cand_matches == TRUE) {
+ if (new_pair) {
/* note: this is same as "adding to VALID LIST" in the spec
text */
p->state = NICE_CHECK_SUCCEEDED;
@@ -2324,20 +2324,22 @@ static CandidateCheckPair *priv_process_response_check_for_peer_reflexive(NiceAg
priv_conn_check_unfreeze_related (agent, stream, p);
}
else {
- NiceCandidate *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);
+ if (!local_cand) {
+ 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") */
- new_pair = priv_add_peer_reflexive_pair (agent, stream->id, component->id, cand, p);
+ new_pair = priv_add_peer_reflexive_pair (agent, stream->id, component->id,
+ local_cand, p);
nice_debug ("Agent %p : conncheck %p FAILED, %p DISCOVERED.", agent, p, new_pair);
}