summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2016-04-12 13:30:04 +0200
committerOlivier CrĂȘte <olivier.crete@collabora.com>2017-06-21 16:05:56 -0400
commit3916b8bcbf7e78e1dcb6b77882075c2c22719b4e (patch)
tree1bec553cd31e77d85ae86defb17bc212b958bd7d
parent9103a5f2e184211fc160d1d3070ce4d043c71ff0 (diff)
downloadlibnice-3916b8bcbf7e78e1dcb6b77882075c2c22719b4e.tar.gz
conncheck: fix a nomination corner case
This patch add two supplementary cases, not covered by the ICE spec, sect 7.2.1.5 "Updating the Nominated Flag" when a controlled agent receives a STUN request with the USE-CANDIDATE flag, for a pair that is in the waiting state. We consider that this case is similar to the in-progress state, and should be handled in the same way. We also accept when the pair is in frozen state. This latter case happens in the new-dribble test, when an agent replays incoming early connchecks. Differential Revision: https://phabricator.freedesktop.org/D880
-rw-r--r--agent/conncheck.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 79685df..4f4af40 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -1963,6 +1963,29 @@ static void priv_mark_pair_nominated (NiceAgent *agent, NiceStream *stream, Nice
"will be nominated on response receipt.",
agent, pair, pair->foundation);
}
+ /* note: this case is not covered by the ICE spec, 7.2.1.5,
+ * "Updating the Nominated Flag", but a pair in waiting state
+ * deserves the same treatment than a pair in-progress.
+ */
+ if (pair->state == NICE_CHECK_WAITING) {
+ pair->mark_nominated_on_response_arrival = TRUE;
+ nice_debug ("Agent %p : pair %p (%s) is waiting, "
+ "will be nominated on response receipt.",
+ agent, pair, pair->foundation);
+ }
+ /* note: this case is not covered by the ICE spec, 7.2.1.5,
+ * "Updating the Nominated Flag" either, but a pair in frozen
+ * state, and in the triggered check list should also be
+ * considered like a pair in-progress. This case happens with
+ * the new-dribble test, when an agent replays incoming early
+ * connchecks.
+ */
+ if (pair->state == NICE_CHECK_FROZEN) {
+ pair->mark_nominated_on_response_arrival = TRUE;
+ nice_debug ("Agent %p : pair %p (%s) is frozen, "
+ "will be nominated on response receipt.",
+ agent, pair, pair->foundation);
+ }
} else if (pair->local == localcand && pair->remote == remotecand) {
nice_debug ("Agent %p : marking pair %p (%s) as nominated", agent, pair, pair->foundation);
pair->nominated = TRUE;
@@ -2703,17 +2726,25 @@ static guint priv_prune_pending_checks (NiceStream *stream, guint component_id)
"is %" G_GUINT64_FORMAT, highest_nominated_priority);
/* step: cancel all FROZEN and WAITING pairs for the component */
+ /* note: this case is not covered by the ICE spec, 8.1.2
+ * "Updating States", but a pair in waiting state which will be
+ * nominated on response receipt should be treated the same way
+ * that an in-progress pair.
+ */
for (i = stream->conncheck_list; i; i = i->next) {
CandidateCheckPair *p = i->data;
if (p->component_id == component_id) {
if (p->state == NICE_CHECK_FROZEN ||
- p->state == NICE_CHECK_WAITING) {
+ (p->state == NICE_CHECK_WAITING &&
+ !p->mark_nominated_on_response_arrival)) {
p->state = NICE_CHECK_CANCELLED;
nice_debug ("Agent XXX : pair %p state CANCELED", p);
}
/* note: a SHOULD level req. in ICE 8.1.2. "Updating States" (ID-19) */
- if (p->state == NICE_CHECK_IN_PROGRESS) {
+ if (p->state == NICE_CHECK_IN_PROGRESS ||
+ (p->state == NICE_CHECK_WAITING &&
+ p->mark_nominated_on_response_arrival)) {
if (highest_nominated_priority != 0 &&
p->priority < highest_nominated_priority) {
p->stun_message.buffer = NULL;