summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2016-06-14 21:32:26 +0200
committerOlivier CrĂȘte <olivier.crete@collabora.com>2017-06-21 16:05:57 -0400
commitd516fca1b0e0a6606afec797bdc0690104e779a9 (patch)
tree8a73e4471c0771a7371120287759c84c23f1f644
parentf19d209decac432a1597d84c3d5809d2208f7457 (diff)
downloadlibnice-d516fca1b0e0a6606afec797bdc0690104e779a9.tar.gz
conncheck: adjust recheck on timeout strategy
The pair recheck on timeout can easily cause repetitive rechecks in a ping-pong effect, if both peers with the same behaviour try to check the same pair almost simultaneously, and if the network rtt is greater than the initial timer rto. The reply to the initial stun request may arrive after the in-progress conncheck cancellation (described in RFC 5245, sect 7.2.1.4). Cancellation creates a new stun request, and forgets the initial one. The conncheck timer is restarted with the same initial value, so the same situation happens again later. We choose to avoid resetting the timer in such situation. After enough retransmissions, the timeout delay, that doubles after each timeout, becomes longer than the rtt, and the stun reply can be handled. Differential Revision: https://phabricator.freedesktop.org/D1115
-rw-r--r--agent/conncheck.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 4b785b5..88d2534 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -591,7 +591,6 @@ priv_conn_recheck_on_timeout (NiceAgent *agent, CandidateCheckPair *p)
*/
nice_debug ("Agent %p : pair %p was cancelled, "
"triggering a new connection check", agent, p);
- p->recheck_on_timeout = FALSE;
priv_add_pair_to_triggered_check_queue (agent, p);
return TRUE;
}
@@ -2650,9 +2649,32 @@ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair)
if (nice_socket_is_reliable(pair->sockptr)) {
stun_timer_start_reliable(&pair->timer, agent->stun_reliable_timeout);
} else {
- stun_timer_start (&pair->timer,
- priv_compute_conncheck_timer (agent, stream),
- agent->stun_max_retransmissions);
+ StunTimer *timer = &pair->timer;
+
+ if (pair->recheck_on_timeout)
+ /* The pair recheck on timeout can easily cause repetitive rechecks in
+ * a ping-pong effect, if both peers with the same behaviour try to
+ * check the same pair almost simultaneously, and if the network rtt
+ * is greater than the initial timer rto. The reply to the initial
+ * stun request may arrive after the in-progress conncheck
+ * cancellation (described in RFC 5245, sect 7.2.1.4). Cancellation
+ * creates a new stun request, and forgets the initial one.
+ * The conncheck timer is restarted with the same initial value,
+ * so the same situation happens again later.
+ *
+ * We choose to avoid resetting the timer in such situation.
+ * After enough retransmissions, the timeout delay becomes
+ * longer than the rtt, and the stun reply can be handled.
+ */
+ nice_debug("Agent %p : reusing timer of pair %p: %d/%d %d/%dms",
+ agent, pair,
+ timer->retransmissions, timer->max_retransmissions,
+ timer->delay - stun_timer_remainder (timer), timer->delay);
+ else
+ stun_timer_start (timer,
+ priv_compute_conncheck_timer (agent, stream),
+ agent->stun_max_retransmissions);
+ pair->recheck_on_timeout = FALSE;
}
/* TCP-ACTIVE candidate must create a new socket before sending