Commit f4bff9d6 authored by Ghislain MARY's avatar Ghislain MARY

Fix possible infinite loop in the ICE processing.

Wait for retransmission timeout before triggering a new binding request for an InProgress pair on reception of a binding response.
parent a3b9c7c4
......@@ -135,6 +135,7 @@ typedef struct _IceCandidatePair {
IceRole role; /**< Role of the agent when the connectivity check has been sent for the candidate pair */
bool_t is_default; /**< Boolean value telling whether this candidate pair is a default candidate pair or not */
bool_t is_nominated;
bool_t wait_transaction_timeout; /**< Boolean value telling to create a new binding request on retransmission timeout */
} IceCandidatePair;
/**
......
......@@ -228,6 +228,7 @@ static IceCandidatePair *ice_pair_new(IceCheckList *cl, IceCandidate* local_cand
ice_pair_set_state(pair, ICP_Frozen);
pair->is_default = FALSE;
pair->is_nominated = FALSE;
pair->wait_transaction_timeout = FALSE;
if ((pair->local->is_default == TRUE) && (pair->remote->is_default == TRUE)) pair->is_default = TRUE;
else pair->is_default = FALSE;
memset(&pair->transactionID, 0, sizeof(pair->transactionID));
......@@ -449,6 +450,14 @@ static void ice_send_binding_request(IceCheckList *cl, IceCandidatePair *pair, R
int socket = 0;
if (pair->state == ICP_InProgress) {
if (pair->wait_transaction_timeout == TRUE) {
/* Special case where a binding response triggers a binding request for an InProgress pair. */
/* In this case we wait for the transmission timeout before creating a new binding request for the pair. */
pair->wait_transaction_timeout = FALSE;
ice_pair_set_state(pair, ICP_Waiting);
ice_check_list_queue_triggered_check(cl, pair);
return;
}
/* This is a retransmission: update the number of retransmissions, the retransmission timer value, and the transmission time. */
pair->retransmissions++;
if (pair->retransmissions > ICE_MAX_RETRANSMISSIONS) {
......@@ -805,11 +814,14 @@ static IceCandidatePair * ice_trigger_connectivity_check_on_binding_request(IceC
switch (pair->state) {
case ICP_Waiting:
case ICP_Frozen:
case ICP_InProgress:
case ICP_Failed:
ice_pair_set_state(pair, ICP_Waiting);
ice_check_list_queue_triggered_check(cl, pair);
break;
case ICP_InProgress:
/* Wait transaction timeout before creating a new binding request for this pair. */
pair->wait_transaction_timeout = TRUE;
break;
case ICP_Succeeded:
/* Nothing to be done. */
break;
......
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