summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2017-06-26 20:36:35 +0200
committerOlivier CrĂȘte <olivier.crete@collabora.com>2017-09-05 14:51:18 -0400
commit25be00271a4c8c684a2d435d29ae0811dbf5e21c (patch)
treeb063cf90fdb35a26c054b163a2b24c56b5b6ffa5
parent5a42089aeb2dbbb52d820cd1b6efdfcfbe9b055e (diff)
downloadlibnice-25be00271a4c8c684a2d435d29ae0811dbf5e21c.tar.gz
conncheck: reorder some chunks of code
With this patch we simplify the levels of code indentation. Differential Revision: https://phabricator.freedesktop.org/D1758
-rw-r--r--agent/conncheck.c858
1 files changed, 422 insertions, 436 deletions
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 8945e0f..874f7b1 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -608,106 +608,106 @@ static gboolean priv_conn_check_tick_stream (NiceStream *stream, NiceAgent *agen
gboolean keep_timer_going = FALSE;
GSList *i;
CandidateCheckPair *pair;
+ unsigned int timeout;
/* step: process ongoing STUN transactions */
for (i = stream->conncheck_list; i ; i = i->next) {
CandidateCheckPair *p = i->data;
+ gchar tmpbuf1[INET6_ADDRSTRLEN], tmpbuf2[INET6_ADDRSTRLEN];
+ NiceComponent *component;
+
+ if (!agent_find_component (agent, p->stream_id, p->component_id,
+ NULL, &component))
+ continue;
+
+ if (p->state != NICE_CHECK_IN_PROGRESS)
+ continue;
- if (p->state == NICE_CHECK_IN_PROGRESS) {
- if (p->stun_message.buffer == NULL) {
- nice_debug ("Agent %p : STUN connectivity check was cancelled, marking as done.", agent);
- p->state = NICE_CHECK_FAILED;
- nice_debug ("Agent %p : pair %p state FAILED", agent, p);
- } else if (priv_timer_expired (&p->next_tick, now)) {
- switch (stun_timer_refresh (&p->timer)) {
- case STUN_USAGE_TIMER_RETURN_TIMEOUT:
- {
- gchar tmpbuf1[INET6_ADDRSTRLEN], tmpbuf2[INET6_ADDRSTRLEN];
- NiceComponent *component;
+ if (p->stun_message.buffer == NULL) {
+ nice_debug ("Agent %p : STUN connectivity check was cancelled, marking as done.", agent);
+ p->state = NICE_CHECK_FAILED;
+ nice_debug ("Agent %p : pair %p state FAILED", agent, p);
+ continue;
+ }
+ if (!priv_timer_expired (&p->next_tick, now))
+ continue;
+
+ switch (stun_timer_refresh (&p->timer)) {
+ case STUN_USAGE_TIMER_RETURN_TIMEOUT:
timer_timeout:
- /* case: conncheck cancelled due to in-progress incoming
- * check, requeing the pair, ICE spec, sect 7.2.1.4
- * "Triggered Checks", "If the state of that pair is
- * In-Progress..."
- */
- if (priv_conn_recheck_on_timeout (agent, p))
- break;
+ /* case: conncheck cancelled due to in-progress incoming
+ * check, requeing the pair, ICE spec, sect 7.2.1.4
+ * "Triggered Checks", "If the state of that pair is
+ * In-Progress..."
+ */
+ if (priv_conn_recheck_on_timeout (agent, p))
+ break;
- /* case: error, abort processing */
- nice_address_to_string (&p->local->addr, tmpbuf1);
- nice_address_to_string (&p->remote->addr, tmpbuf2);
- nice_debug ("Agent %p : Retransmissions failed, giving up on connectivity check %p", agent, p);
- nice_debug ("Agent %p : Failed pair is [%s]:%u --> [%s]:%u", agent,
- tmpbuf1, nice_address_get_port (&p->local->addr),
- tmpbuf2, nice_address_get_port (&p->remote->addr));
- candidate_check_pair_fail (stream, agent, p);
- priv_print_conn_check_lists (agent, G_STRFUNC,
- ", retransmission failed");
-
- /* perform a check if a transition state from connected to
- * ready can be performed. This may happen here, when the last
- * in-progress pair has expired its retransmission count
- * in priv_conn_check_tick_stream(), which is a condition to
- * make the transition connected to ready.
- */
- if (agent_find_component (agent, p->stream_id, p->component_id,
- NULL, &component))
- priv_update_check_list_state_for_ready (agent, stream,
- component);
- break;
- }
- case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
- {
- unsigned int timeout = stun_timer_remainder (&p->timer);
+ /* case: error, abort processing */
+ nice_address_to_string (&p->local->addr, tmpbuf1);
+ nice_address_to_string (&p->remote->addr, tmpbuf2);
+ nice_debug ("Agent %p : Retransmissions failed, giving up on connectivity check %p", agent, p);
+ nice_debug ("Agent %p : Failed pair is [%s]:%u --> [%s]:%u", agent,
+ tmpbuf1, nice_address_get_port (&p->local->addr),
+ tmpbuf2, nice_address_get_port (&p->remote->addr));
+ candidate_check_pair_fail (stream, agent, p);
+ priv_print_conn_check_lists (agent, G_STRFUNC,
+ ", retransmission failed");
+
+ /* perform a check if a transition state from connected to
+ * ready can be performed. This may happen here, when the last
+ * in-progress pair has expired its retransmission count
+ * in priv_conn_check_tick_stream(), which is a condition to
+ * make the transition connected to ready.
+ */
+ priv_update_check_list_state_for_ready (agent, stream, component);
+ break;
+ case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
+ timeout = stun_timer_remainder (&p->timer);
- /* case: retransmission stopped, due to the nomination of
- * a pair with a higher priority than this in-progress pair,
- * ICE spec, sect 8.1.2 "Updating States", item 2.2
- */
- if (!p->retransmit_on_timeout)
- goto timer_timeout;
+ /* case: retransmission stopped, due to the nomination of
+ * a pair with a higher priority than this in-progress pair,
+ * ICE spec, sect 8.1.2 "Updating States", item 2.2
+ */
+ if (!p->retransmit_on_timeout)
+ goto timer_timeout;
- /* case: conncheck cancelled due to in-progress incoming
- * check, requeing the pair, ICE spec, sect 7.2.1.4
- * "Triggered Checks", "If the state of that pair is
- * In-Progress..."
- */
- if (priv_conn_recheck_on_timeout (agent, p))
- break;
+ /* case: conncheck cancelled due to in-progress incoming
+ * check, requeing the pair, ICE spec, sect 7.2.1.4
+ * "Triggered Checks", "If the state of that pair is
+ * In-Progress..."
+ */
+ if (priv_conn_recheck_on_timeout (agent, p))
+ break;
- /* case: not ready, so schedule a new timeout */
- nice_debug ("Agent %p :STUN transaction retransmitted on pair %p "
- "(timeout %dms, delay=%dms, retrans=%d).",
- agent, p, timeout, p->timer.delay, p->timer.retransmissions);
+ /* case: not ready, so schedule a new timeout */
+ nice_debug ("Agent %p :STUN transaction retransmitted on pair %p "
+ "(timeout %dms, delay=%dms, retrans=%d).",
+ agent, p, timeout, p->timer.delay, p->timer.retransmissions);
- agent_socket_send (p->sockptr, &p->remote->addr,
- stun_message_length (&p->stun_message),
- (gchar *)p->stun_buffer);
+ agent_socket_send (p->sockptr, &p->remote->addr,
+ stun_message_length (&p->stun_message),
+ (gchar *)p->stun_buffer);
- /* note: convert from milli to microseconds for g_time_val_add() */
- p->next_tick = *now;
- g_time_val_add (&p->next_tick, timeout * 1000);
+ /* note: convert from milli to microseconds for g_time_val_add() */
+ p->next_tick = *now;
+ g_time_val_add (&p->next_tick, timeout * 1000);
- return TRUE;
- }
- case STUN_USAGE_TIMER_RETURN_SUCCESS:
- {
- unsigned int timeout = stun_timer_remainder (&p->timer);
+ return TRUE;
+ case STUN_USAGE_TIMER_RETURN_SUCCESS:
+ timeout = stun_timer_remainder (&p->timer);
- /* note: convert from milli to microseconds for g_time_val_add() */
- p->next_tick = *now;
- g_time_val_add (&p->next_tick, timeout * 1000);
+ /* note: convert from milli to microseconds for g_time_val_add() */
+ p->next_tick = *now;
+ g_time_val_add (&p->next_tick, timeout * 1000);
- keep_timer_going = TRUE;
- break;
- }
- default:
- /* Nothing to do. */
- break;
- }
- }
+ keep_timer_going = TRUE;
+ break;
+ default:
+ /* Nothing to do. */
+ break;
}
}
@@ -2628,27 +2628,23 @@ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair)
if (NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2 (agent)) {
switch (agent->nomination_mode) {
case NICE_NOMINATION_MODE_REGULAR:
- {
- /* We are doing regular nomination, so we set the use-candidate
- * attrib, when the controlling agent decided which valid pair to
- * resend with this flag in priv_conn_check_tick_stream()
- */
- cand_use = pair->use_candidate_on_next_check;
- nice_debug ("Agent %p : %s: set cand_use=%d "
- "(regular nomination).", agent, G_STRFUNC, cand_use);
- break;
- }
+ /* We are doing regular nomination, so we set the use-candidate
+ * attrib, when the controlling agent decided which valid pair to
+ * resend with this flag in priv_conn_check_tick_stream()
+ */
+ cand_use = pair->use_candidate_on_next_check;
+ nice_debug ("Agent %p : %s: set cand_use=%d "
+ "(regular nomination).", agent, G_STRFUNC, cand_use);
+ break;
case NICE_NOMINATION_MODE_AGGRESSIVE:
- {
- /* We are doing aggressive nomination, we set the use-candidate
- * attrib in every check we send, when we are the controlling
- * agent, RFC 5245, 8.1.1.2
- */
- cand_use = controlling;
- nice_debug ("Agent %p : %s: set cand_use=%d "
- "(aggressive nomination).", agent, G_STRFUNC, cand_use);
- break;
- }
+ /* We are doing aggressive nomination, we set the use-candidate
+ * attrib in every check we send, when we are the controlling
+ * agent, RFC 5245, 8.1.1.2
+ */
+ cand_use = controlling;
+ nice_debug ("Agent %p : %s: set cand_use=%d "
+ "(aggressive nomination).", agent, G_STRFUNC, cand_use);
+ break;
default:
/* Nothing to do. */
break;
@@ -2656,107 +2652,105 @@ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair)
} else if (cand_use)
pair->nominated = controlling;
- if (uname_len > 0) {
- buffer_len = stun_usage_ice_conncheck_create (&component->stun_agent,
- &pair->stun_message, pair->stun_buffer, sizeof(pair->stun_buffer),
- uname, uname_len, password, password_len,
- cand_use, controlling, pair->prflx_priority,
- agent->tie_breaker,
- pair->local->foundation,
- agent_to_ice_compatibility (agent));
+ if (uname_len == 0) {
+ nice_debug ("Agent %p: no credentials found, cancelling conncheck", agent);
+ pair->stun_message.buffer = NULL;
+ pair->stun_message.buffer_len = 0;
+ return -1;
+ }
- nice_debug ("Agent %p: conncheck created %zd - %p", agent, buffer_len,
- pair->stun_message.buffer);
+ buffer_len = stun_usage_ice_conncheck_create (&component->stun_agent,
+ &pair->stun_message, pair->stun_buffer, sizeof(pair->stun_buffer),
+ uname, uname_len, password, password_len,
+ cand_use, controlling, pair->prflx_priority,
+ agent->tie_breaker,
+ pair->local->foundation,
+ agent_to_ice_compatibility (agent));
- if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
- agent->compatibility == NICE_COMPATIBILITY_OC2007) {
- g_free (password);
- }
+ nice_debug ("Agent %p: conncheck created %zd - %p", agent, buffer_len,
+ pair->stun_message.buffer);
- if (buffer_len > 0) {
- if (nice_socket_is_reliable(pair->sockptr)) {
- stun_timer_start_reliable(&pair->timer, agent->stun_reliable_timeout);
- } else {
- 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;
- }
+ if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
+ agent->compatibility == NICE_COMPATIBILITY_OC2007) {
+ g_free (password);
+ }
- /* TCP-ACTIVE candidate must create a new socket before sending
- * by connecting to the peer. The new socket is stored in the candidate
- * check pair, until we discover a new local peer reflexive */
- if (pair->sockptr->fileno == NULL &&
- pair->sockptr->type != NICE_SOCKET_TYPE_UDP_TURN &&
- pair->local->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) {
- NiceStream *stream2 = NULL;
- NiceComponent *component2 = NULL;
- NiceSocket *new_socket;
-
- if (agent_find_component (agent, pair->stream_id, pair->component_id,
- &stream2, &component2)) {
- new_socket = nice_tcp_active_socket_connect (pair->sockptr,
- &pair->remote->addr);
- if (new_socket) {
- pair->sockptr = new_socket;
- _priv_set_socket_tos (agent, pair->sockptr, stream2->tos);
-
- if (agent->reliable) {
- nice_socket_set_writable_callback (pair->sockptr,
- _tcp_sock_is_writable, component2);
- }
+ if (buffer_len == 0) {
+ nice_debug ("Agent %p: buffer is empty, cancelling conncheck", agent);
+ pair->stun_message.buffer = NULL;
+ pair->stun_message.buffer_len = 0;
+ return -1;
+ }
- nice_component_attach_socket (component2, new_socket);
- }
- }
- }
- /* send the conncheck */
- agent_socket_send (pair->sockptr, &pair->remote->addr,
- buffer_len, (gchar *)pair->stun_buffer);
+ if (nice_socket_is_reliable(pair->sockptr))
+ stun_timer_start_reliable(&pair->timer, agent->stun_reliable_timeout);
+ else {
+ 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;
+ }
- if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
- ms_ice2_legacy_conncheck_send (&pair->stun_message, pair->sockptr,
- &pair->remote->addr);
+ /* TCP-ACTIVE candidate must create a new socket before sending
+ * by connecting to the peer. The new socket is stored in the candidate
+ * check pair, until we discover a new local peer reflexive */
+ if (pair->sockptr->fileno == NULL &&
+ pair->sockptr->type != NICE_SOCKET_TYPE_UDP_TURN &&
+ pair->local->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) {
+ NiceStream *stream2 = NULL;
+ NiceComponent *component2 = NULL;
+ NiceSocket *new_socket;
+
+ if (agent_find_component (agent, pair->stream_id, pair->component_id,
+ &stream2, &component2)) {
+ new_socket = nice_tcp_active_socket_connect (pair->sockptr,
+ &pair->remote->addr);
+ if (new_socket) {
+ pair->sockptr = new_socket;
+ _priv_set_socket_tos (agent, pair->sockptr, stream2->tos);
+
+ if (agent->reliable)
+ nice_socket_set_writable_callback (pair->sockptr,
+ _tcp_sock_is_writable, component2);
+
+ nice_component_attach_socket (component2, new_socket);
}
-
- timeout = stun_timer_remainder (&pair->timer);
- /* note: convert from milli to microseconds for g_time_val_add() */
- g_get_current_time (&pair->next_tick);
- g_time_val_add (&pair->next_tick, timeout * 1000);
- } else {
- nice_debug ("Agent %p: buffer is empty, cancelling conncheck", agent);
- pair->stun_message.buffer = NULL;
- pair->stun_message.buffer_len = 0;
- return -1;
}
- } else {
- nice_debug ("Agent %p: no credentials found, cancelling conncheck", agent);
- pair->stun_message.buffer = NULL;
- pair->stun_message.buffer_len = 0;
- return -1;
}
+ /* send the conncheck */
+ agent_socket_send (pair->sockptr, &pair->remote->addr,
+ buffer_len, (gchar *)pair->stun_buffer);
+
+ if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2)
+ ms_ice2_legacy_conncheck_send (&pair->stun_message, pair->sockptr,
+ &pair->remote->addr);
+
+ timeout = stun_timer_remainder (&pair->timer);
+ /* note: convert from milli to microseconds for g_time_val_add() */
+ g_get_current_time (&pair->next_tick);
+ g_time_val_add (&pair->next_tick, timeout * 1000);
return 0;
}
@@ -2876,74 +2870,74 @@ static gboolean priv_schedule_triggered_check (NiceAgent *agent, NiceStream *str
nice_debug ("Agent %p : Found a matching pair %p (%s) (state=%c) ...",
agent, p, p->foundation, priv_state_to_gchar (p->state));
- if (p->state == NICE_CHECK_WAITING ||
- p->state == NICE_CHECK_FROZEN) {
- nice_debug ("Agent %p : pair %p added for a triggered check.",
- agent, p);
- priv_add_pair_to_triggered_check_queue (agent, p);
- }
- else if (p->state == NICE_CHECK_IN_PROGRESS) {
- /* note: according to ICE SPEC sect 7.2.1.4 "Triggered Checks"
- * we cancel the in-progress transaction, and after the
- * retransmission timeout, we create a new connectivity check
- * for that pair. The controlling role of this new check may
- * be different from the role of this cancelled check.
- *
- * note: the flag retransmit_on_timeout unset means that
- * another pair, with a higher priority is already nominated,
- * so there's no reason to recheck this pair, since it can in
- * no way replace the nominated one.
- */
- if (!nice_socket_is_reliable (p->sockptr)) {
- if (p->retransmit_on_timeout) {
- nice_debug ("Agent %p : pair %p will be rechecked "
- "on stun timer timeout.", agent, p);
- /* this flag will determine the action at the retransmission
- * timeout of the stun timer
- */
- p->recheck_on_timeout = TRUE;
- } else
- nice_debug ("Agent %p : pair %p won't be retransmitted.",
- agent, p);
- }
- }
- else if (p->state == NICE_CHECK_SUCCEEDED) {
- nice_debug ("Agent %p : nothing to do for pair %p.", agent, p);
- /* note: this is a bit unsure corner-case -- let's do the
- same state update as for processing responses to our own checks */
- /* note: this update is required by the dribble test, to
- * ensure the transition ready -> connected -> ready, because
- * an incoming stun request generates a discovered peer reflexive,
- * that causes the ready -> connected transition.
- */
- priv_update_check_list_state_for_ready (agent, stream, component);
- } else if (p->state == NICE_CHECK_FAILED) {
- /* 7.2.1.4 Triggered Checks
- * If the state of the pair is Failed, it is changed to Waiting
- * and the agent MUST create a new connectivity check for that
- * pair (representing a new STUN Binding request transaction), by
- * enqueueing the pair in the triggered check queue.
- *
- * note: the flag retransmit_on_timeout unset means that
- * another pair, with a higher priority is already nominated,
- * we apply the same strategy than with an in-progress pair
- * above.
- */
- if (p->retransmit_on_timeout) {
- nice_debug ("Agent %p : pair %p added for a triggered check.",
+ switch (p->state) {
+ case NICE_CHECK_WAITING:
+ case NICE_CHECK_FROZEN:
+ nice_debug ("Agent %p : pair %p added for a triggered check.",
agent, p);
priv_add_pair_to_triggered_check_queue (agent, p);
- /* If the component for this pair is in failed state, move it
- * back to connecting, and reinitiate the timers
+ break;
+ case NICE_CHECK_IN_PROGRESS:
+ /* note: according to ICE SPEC sect 7.2.1.4 "Triggered Checks"
+ * we cancel the in-progress transaction, and after the
+ * retransmission timeout, we create a new connectivity check
+ * for that pair. The controlling role of this new check may
+ * be different from the role of this cancelled check.
+ *
+ * note: the flag retransmit_on_timeout unset means that
+ * another pair, with a higher priority is already nominated,
+ * so there's no reason to recheck this pair, since it can in
+ * no way replace the nominated one.
*/
- if (component->state == NICE_COMPONENT_STATE_FAILED) {
- agent_signal_component_state_change (agent, stream->id,
- component->id, NICE_COMPONENT_STATE_CONNECTING);
- conn_check_schedule_next (agent);
+ if (!nice_socket_is_reliable (p->sockptr) &&
+ p->retransmit_on_timeout) {
+ nice_debug ("Agent %p : pair %p will be rechecked "
+ "on stun timer timeout.", agent, p);
+ /* this flag will determine the action at the retransmission
+ * timeout of the stun timer
+ */
+ p->recheck_on_timeout = TRUE;
}
- } else
- nice_debug ("Agent %p : pair %p won't be retransmitted.",
- agent, p);
+ break;
+ case NICE_CHECK_SUCCEEDED:
+ nice_debug ("Agent %p : nothing to do for pair %p.", agent, p);
+ /* note: this is a bit unsure corner-case -- let's do the
+ same state update as for processing responses to our own checks */
+ /* note: this update is required by the dribble test, to
+ * ensure the transition ready -> connected -> ready, because
+ * an incoming stun request generates a discovered peer reflexive,
+ * that causes the ready -> connected transition.
+ */
+ priv_update_check_list_state_for_ready (agent, stream, component);
+ break;
+ case NICE_CHECK_FAILED:
+ /* 7.2.1.4 Triggered Checks
+ * If the state of the pair is Failed, it is changed to Waiting
+ * and the agent MUST create a new connectivity check for that
+ * pair (representing a new STUN Binding request transaction), by
+ * enqueueing the pair in the triggered check queue.
+ *
+ * note: the flag retransmit_on_timeout unset means that
+ * another pair, with a higher priority is already nominated,
+ * we apply the same strategy than with an in-progress pair
+ * above.
+ */
+ if (p->retransmit_on_timeout) {
+ nice_debug ("Agent %p : pair %p added for a triggered check.",
+ agent, p);
+ priv_add_pair_to_triggered_check_queue (agent, p);
+ /* If the component for this pair is in failed state, move it
+ * back to connecting, and reinitiate the timers
+ */
+ if (component->state == NICE_COMPONENT_STATE_FAILED) {
+ agent_signal_component_state_change (agent, stream->id,
+ component->id, NICE_COMPONENT_STATE_CONNECTING);
+ conn_check_schedule_next (agent);
+ }
+ }
+ break;
+ default:
+ break;
}
/* note: the spec says the we SHOULD retransmit in-progress
@@ -3271,208 +3265,200 @@ static gboolean priv_map_reply_to_conn_check_request (NiceAgent *agent, NiceStre
socklen_t socklen = sizeof (sockaddr);
GSList *i;
StunUsageIceReturn res;
- gboolean trans_found = FALSE;
StunTransactionId discovery_id;
StunTransactionId response_id;
stun_message_id (resp, response_id);
- for (i = stream->conncheck_list; i && trans_found != TRUE; i = i->next) {
+ for (i = stream->conncheck_list; i; i = i->next) {
CandidateCheckPair *p = i->data;
- if (p->stun_message.buffer) {
- stun_message_id (&p->stun_message, discovery_id);
+ if (p->stun_message.buffer == NULL)
+ continue;
- if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) {
- res = stun_usage_ice_conncheck_process (resp,
- &sockaddr.storage, &socklen,
- agent_to_ice_compatibility (agent));
- nice_debug ("Agent %p : stun_bind_process/conncheck for %p res %d "
- "(controlling=%d).", agent, p, (int)res, agent->controlling_mode);
-
- if (res == STUN_USAGE_ICE_RETURN_SUCCESS ||
- res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) {
- /* case: found a matching connectivity check request */
-
- CandidateCheckPair *ok_pair = NULL;
-
- nice_debug ("Agent %p : conncheck %p MATCHED.", agent, p);
- p->stun_message.buffer = NULL;
- p->stun_message.buffer_len = 0;
-
- /* step: verify that response came from the same IP address we
- * sent the original request to (see 7.1.2.1. "Failure
- * Cases") */
- if (nice_address_equal (from, &p->remote->addr) != TRUE) {
-
- p->state = NICE_CHECK_FAILED;
- if (nice_debug_is_enabled ()) {
- gchar tmpbuf[INET6_ADDRSTRLEN];
- gchar tmpbuf2[INET6_ADDRSTRLEN];
- nice_debug ("Agent %p : conncheck %p FAILED"
- " (mismatch of source address).", agent, p);
- nice_address_to_string (&p->remote->addr, tmpbuf);
- nice_address_to_string (from, tmpbuf2);
- nice_debug ("Agent %p : '%s:%u' != '%s:%u'", agent,
- tmpbuf, nice_address_get_port (&p->remote->addr),
- tmpbuf2, nice_address_get_port (from));
- }
- trans_found = TRUE;
- break;
- }
+ stun_message_id (&p->stun_message, discovery_id);
- /* note: CONNECTED but not yet READY, see docs */
-
- /* step: handle the possible case of a peer-reflexive
- * candidate where the mapped-address in response does
- * not match any local candidate, see 7.1.2.2.1
- * "Discovering Peer Reflexive Candidates" ICE ID-19) */
-
- if (res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) {
- /* note: this is same as "adding to VALID LIST" in the spec
- text */
- p->state = NICE_CHECK_SUCCEEDED;
- p->valid = TRUE;
- g_assert_not_reached ();
- nice_debug ("Agent %p : Mapped address not found."
- " conncheck %p SUCCEEDED.", agent, p);
- nice_component_add_valid_candidate (component, p->remote);
- } else {
- ok_pair = priv_process_response_check_for_reflexive (agent,
- stream, component, p, sockptr, &sockaddr.addr,
- local_candidate, remote_candidate);
- }
+ if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)))
+ continue;
- /* note: The success of this check might also
- * cause the state of other checks to change as well, ICE
- * spec 7.1.3.2.3
- */
- priv_conn_check_unfreeze_related (agent, stream, p);
-
- /* Note: this assignment helps to reduce the numbers of cases
- * to be tested. If ok_pair and p refer to distinct pairs, it
- * means that ok_pair is a discovered peer reflexive one,
- * caused by the check made on pair p. In that case, the
- * flags to be tested are on p, but the nominated flag will be
- * set on ok_pair. When there's no discovered pair, p and
- * ok_pair refer to the same pair.
- * To summarize : p is a SUCCEEDED pair, ok_pair is a
- * DISCOVERED, VALID, and eventually NOMINATED pair.
- */
- if (!ok_pair)
- ok_pair = p;
-
- /* step: updating nominated flag (ICE 7.1.2.2.4 "Updating the
- Nominated Flag" (ID-19) */
- if (NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2 (agent)) {
- nice_debug ("Agent %p : Updating nominated flag (%s): "
- "ok_pair=%p (%d/%d) p=%p (%d/%d) (ucnc/mnora)",
- agent, p->local->transport == NICE_CANDIDATE_TRANSPORT_UDP ?
- "UDP" : "TCP",
- ok_pair, ok_pair->use_candidate_on_next_check,
- ok_pair->mark_nominated_on_response_arrival,
- p, p->use_candidate_on_next_check,
- p->mark_nominated_on_response_arrival);
-
- if (agent->controlling_mode) {
- switch (agent->nomination_mode) {
- case NICE_NOMINATION_MODE_REGULAR:
- if (p->use_candidate_on_next_check) {
- nice_debug ("Agent %p : marking pair %p (%s) as nominated "
- "(regular nomination, control=1, "
- "use_cand_on_next_check=1).",
- agent, ok_pair, ok_pair->foundation);
- ok_pair->nominated = TRUE;
- }
- break;
- case NICE_NOMINATION_MODE_AGGRESSIVE:
- if (!p->nominated) {
- nice_debug ("Agent %p : marking pair %p (%s) as nominated "
- "(aggressive nomination, control=1).",
- agent, ok_pair, ok_pair->foundation);
- ok_pair->nominated = TRUE;
- }
- break;
- default:
- /* Nothing to do */
- break;
+ res = stun_usage_ice_conncheck_process (resp,
+ &sockaddr.storage, &socklen,
+ agent_to_ice_compatibility (agent));
+ nice_debug ("Agent %p : stun_bind_process/conncheck for %p res %d "
+ "(controlling=%d).", agent, p, (int)res, agent->controlling_mode);
+
+ if (res == STUN_USAGE_ICE_RETURN_SUCCESS ||
+ res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) {
+ /* case: found a matching connectivity check request */
+
+ CandidateCheckPair *ok_pair = NULL;
+
+ nice_debug ("Agent %p : conncheck %p MATCHED.", agent, p);
+ p->stun_message.buffer = NULL;
+ p->stun_message.buffer_len = 0;
+
+ /* step: verify that response came from the same IP address we
+ * sent the original request to (see 7.1.2.1. "Failure
+ * Cases") */
+ if (nice_address_equal (from, &p->remote->addr) == FALSE) {
+
+ p->state = NICE_CHECK_FAILED;
+ if (nice_debug_is_enabled ()) {
+ gchar tmpbuf[INET6_ADDRSTRLEN];
+ gchar tmpbuf2[INET6_ADDRSTRLEN];
+ nice_debug ("Agent %p : conncheck %p FAILED"
+ " (mismatch of source address).", agent, p);
+ nice_address_to_string (&p->remote->addr, tmpbuf);
+ nice_address_to_string (from, tmpbuf2);
+ nice_debug ("Agent %p : '%s:%u' != '%s:%u'", agent,
+ tmpbuf, nice_address_get_port (&p->remote->addr),
+ tmpbuf2, nice_address_get_port (from));
+ }
+ return TRUE;
+ }
+
+ /* note: CONNECTED but not yet READY, see docs */
+
+ /* step: handle the possible case of a peer-reflexive
+ * candidate where the mapped-address in response does
+ * not match any local candidate, see 7.1.2.2.1
+ * "Discovering Peer Reflexive Candidates" ICE ID-19) */
+
+ if (res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) {
+ p->state = NICE_CHECK_SUCCEEDED;
+ p->valid = TRUE;
+ nice_debug ("Agent %p : Mapped address not found."
+ " conncheck %p SUCCEEDED.", agent, p);
+ nice_component_add_valid_candidate (component, p->remote);
+ } else
+ ok_pair = priv_process_response_check_for_reflexive (agent,
+ stream, component, p, sockptr, &sockaddr.addr,
+ local_candidate, remote_candidate);
+
+ /* note: The success of this check might also
+ * cause the state of other checks to change as well, ICE
+ * spec 7.1.3.2.3
+ */
+ priv_conn_check_unfreeze_related (agent, stream, p);
+
+ /* Note: this assignment helps to reduce the numbers of cases
+ * to be tested. If ok_pair and p refer to distinct pairs, it
+ * means that ok_pair is a discovered peer reflexive one,
+ * caused by the check made on pair p. In that case, the
+ * flags to be tested are on p, but the nominated flag will be
+ * set on ok_pair. When there's no discovered pair, p and
+ * ok_pair refer to the same pair.
+ * To summarize : p is a SUCCEEDED pair, ok_pair is a
+ * DISCOVERED, VALID, and eventually NOMINATED pair.
+ */
+ if (!ok_pair)
+ ok_pair = p;
+
+ /* step: updating nominated flag (ICE 7.1.2.2.4 "Updating the
+ Nominated Flag" (ID-19) */
+ if (NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2 (agent)) {
+ nice_debug ("Agent %p : Updating nominated flag (%s): "
+ "ok_pair=%p (%d/%d) p=%p (%d/%d) (ucnc/mnora)",
+ agent, p->local->transport == NICE_CANDIDATE_TRANSPORT_UDP ?
+ "UDP" : "TCP",
+ ok_pair, ok_pair->use_candidate_on_next_check,
+ ok_pair->mark_nominated_on_response_arrival,
+ p, p->use_candidate_on_next_check,
+ p->mark_nominated_on_response_arrival);
+
+ if (agent->controlling_mode) {
+ switch (agent->nomination_mode) {
+ case NICE_NOMINATION_MODE_REGULAR:
+ if (p->use_candidate_on_next_check) {
+ nice_debug ("Agent %p : marking pair %p (%s) as nominated "
+ "(regular nomination, control=1, "
+ "use_cand_on_next_check=1).",
+ agent, ok_pair, ok_pair->foundation);
+ ok_pair->nominated = TRUE;
}
- } else {
- if (p->mark_nominated_on_response_arrival) {
+ break;
+ case NICE_NOMINATION_MODE_AGGRESSIVE:
+ if (!p->nominated) {
nice_debug ("Agent %p : marking pair %p (%s) as nominated "
- "(%s nomination, control=0, mark_on_response=1).",
- agent, ok_pair, ok_pair->foundation,
- agent->nomination_mode == NICE_NOMINATION_MODE_AGGRESSIVE ?
- "aggressive" : "regular");
+ "(aggressive nomination, control=1).",
+ agent, ok_pair, ok_pair->foundation);
ok_pair->nominated = TRUE;
}
- }
+ break;
+ default:
+ /* Nothing to do */
+ break;
}
-
- if (ok_pair->nominated == TRUE) {
- priv_update_selected_pair (agent, component, ok_pair);
- priv_print_conn_check_lists (agent, G_STRFUNC,
- ", got a nominated pair");
-
- /* Do not step down to CONNECTED if we're already at state READY*/
- if (component->state != NICE_COMPONENT_STATE_READY) {
- /* step: notify the client of a new component state (must be done
- * before the possible check list state update step */
- agent_signal_component_state_change (agent,
- stream->id, component->id, NICE_COMPONENT_STATE_CONNECTED);
- }
+ } else {
+ if (p->mark_nominated_on_response_arrival) {
+ nice_debug ("Agent %p : marking pair %p (%s) as nominated "
+ "(%s nomination, control=0, mark_on_response=1).",
+ agent, ok_pair, ok_pair->foundation,
+ agent->nomination_mode == NICE_NOMINATION_MODE_AGGRESSIVE ?
+ "aggressive" : "regular");
+ ok_pair->nominated = TRUE;
}
+ }
+ }
- /* step: update pair states (ICE 7.1.2.2.3 "Updating pair
- states" and 8.1.2 "Updating States", ID-19) */
- priv_update_check_list_state_for_ready (agent, stream, component);
+ if (ok_pair->nominated == TRUE) {
+ priv_update_selected_pair (agent, component, ok_pair);
+ priv_print_conn_check_lists (agent, G_STRFUNC,
+ ", got a nominated pair");
- trans_found = TRUE;
- } else if (res == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT) {
- /* case: role conflict error, need to restart with new role */
- nice_debug ("Agent %p : conncheck %p ROLE CONFLICT, restarting", agent, p);
-
- /* note: this res value indicates that the role of the peer
- * agent has not changed after the tie-breaker comparison, so
- * this is our role that must change. see ICE sect. 7.1.3.1
- * "Failure Cases". Our role might already have changed due to
- * an earlier incoming request, but if not, change role now.
- *
- * Sect. 7.1.3.1 is not clear on this point, but we choose to
- * put the candidate pair in the triggered check list even
- * when the agent did not switch its role. The reason for this
- * interpretation is that the reception of the stun reply, even
- * an error reply, is a good sign that this pair will be
- * valid, if we retry the check after the role of both peers
- * has been fixed.
- */
+ /* Do not step down to CONNECTED if we're already at state READY*/
+ if (component->state != NICE_COMPONENT_STATE_READY)
+ /* step: notify the client of a new component state (must be done
+ * before the possible check list state update step */
+ agent_signal_component_state_change (agent,
+ stream->id, component->id, NICE_COMPONENT_STATE_CONNECTED);
+ }
- if (p->stun_message.buffer != NULL) {
- guint64 tie;
- gboolean controlled_mode;
+ /* step: update pair states (ICE 7.1.2.2.3 "Updating pair
+ states" and 8.1.2 "Updating States", ID-19) */
+ priv_update_check_list_state_for_ready (agent, stream, component);
+ } else if (res == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT) {
+ /* case: role conflict error, need to restart with new role */
+ nice_debug ("Agent %p : conncheck %p ROLE CONFLICT, restarting", agent, p);
+
+ /* note: this res value indicates that the role of the peer
+ * agent has not changed after the tie-breaker comparison, so
+ * this is our role that must change. see ICE sect. 7.1.3.1
+ * "Failure Cases". Our role might already have changed due to
+ * an earlier incoming request, but if not, change role now.
+ *
+ * Sect. 7.1.3.1 is not clear on this point, but we choose to
+ * put the candidate pair in the triggered check list even
+ * when the agent did not switch its role. The reason for this
+ * interpretation is that the reception of the stun reply, even
+ * an error reply, is a good sign that this pair will be
+ * valid, if we retry the check after the role of both peers
+ * has been fixed.
+ */
- controlled_mode = (stun_message_find64 (&p->stun_message,
- STUN_ATTRIBUTE_ICE_CONTROLLED, &tie) ==
- STUN_MESSAGE_RETURN_SUCCESS);
+ if (p->stun_message.buffer != NULL) {
+ guint64 tie;
+ gboolean controlled_mode;
- priv_check_for_role_conflict (agent, controlled_mode);
+ controlled_mode = (stun_message_find64 (&p->stun_message,
+ STUN_ATTRIBUTE_ICE_CONTROLLED, &tie) ==
+ STUN_MESSAGE_RETURN_SUCCESS);
- p->stun_message.buffer = NULL;
- p->stun_message.buffer_len = 0;
- priv_add_pair_to_triggered_check_queue (agent, p);
- }
- trans_found = TRUE;
- } else {
- /* case: STUN error, the check STUN context was freed */
- nice_debug ("Agent %p : conncheck %p FAILED.", agent, p);
- p->stun_message.buffer = NULL;
- p->stun_message.buffer_len = 0;
- trans_found = TRUE;
- }
+ priv_check_for_role_conflict (agent, controlled_mode);
+
+ p->stun_message.buffer = NULL;
+ p->stun_message.buffer_len = 0;
+ priv_add_pair_to_triggered_check_queue (agent, p);
}
+ } else {
+ /* case: STUN error, the check STUN context was freed */
+ nice_debug ("Agent %p : conncheck %p FAILED.", agent, p);
+ p->stun_message.buffer = NULL;
+ p->stun_message.buffer_len = 0;
}
+ return TRUE;
}
- return trans_found;
+ return FALSE;
}
/*