Commit c8a2a789 authored by Olivier Crête's avatar Olivier Crête

Merge remote-tracking branch 'origin/master' into eliminate-reliable-3-remerged

parents 17d8474e ce33747e
......@@ -106,7 +106,6 @@ nice_input_message_iter_compare (const NiceInputMessageIter *a,
#define NICE_AGENT_TIMER_TA_DEFAULT 20 /* timer Ta, msecs (impl. defined) */
#define NICE_AGENT_TIMER_TR_DEFAULT 25000 /* timer Tr, msecs (impl. defined) */
#define NICE_AGENT_TIMER_TR_MIN 15000 /* timer Tr, msecs (ICE ID-19) */
#define NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT 100 /* see spec 5.7.3 (ID-19) */
#define NICE_AGENT_KEEPALIVE_DEFAULT_TIMEOUT 200 /* Start at 200ms, then doube 6 times for a total of 25.4s */
......@@ -154,6 +153,9 @@ struct _NiceAgent
guint max_conn_checks; /* property: max connectivity checks */
gboolean force_relay; /* property: force relay */
gboolean turn_short_term; /* property: turn short term credentials */
guint stun_max_retransmissions; /* property: stun max retransmissions, Rc */
guint stun_initial_timeout; /* property: stun initial timeout, RTO */
guint stun_reliable_timeout; /* property: stun reliable timeout */
NiceNominationMode nomination_mode; /* property: Nomination mode */
GSList *local_addresses; /* list of NiceAddresses for local
......
......@@ -112,7 +112,10 @@ enum
PROP_KEEPALIVE_CONNCHECK,
PROP_FORCE_RELAY,
PROP_TURN_SHORT_TERM,
PROP_NOMINATION_MODE
PROP_STUN_MAX_RETRANSMISSIONS,
PROP_STUN_INITIAL_TIMEOUT,
PROP_STUN_RELIABLE_TIMEOUT,
PROP_NOMINATION_MODE,
};
......@@ -436,7 +439,7 @@ nice_agent_class_init (NiceAgentClass *klass)
* the selection of valid pairs to be used upstream.
* <para> See also: #NiceNominationMode </para>
*
* Since: UNRELEASED
* Since: 0.1.15
*/
g_object_class_install_property (gobject_class, PROP_NOMINATION_MODE,
g_param_spec_enum (
......@@ -721,6 +724,76 @@ nice_agent_class_init (NiceAgentClass *klass)
FALSE,
G_PARAM_READWRITE));
/**
* NiceAgent:stun-max-retransmissions
*
* The maximum number of retransmissions of the STUN binding requests
* used in the gathering stage, to find our local candidates, and used
* in the connection check stage, to test the validity of each
* constructed pair. This property is described as 'Rc' in the RFC
* 5389, with a default value of 7. The timeout of each STUN request
* is doubled for each retransmission, so the choice of this value has
* a direct impact on the time needed to move from the CONNECTED state
* to the READY state, and on the time needed to complete the GATHERING
* state.
*
* Since: 0.1.15
*/
g_object_class_install_property (gobject_class, PROP_STUN_MAX_RETRANSMISSIONS,
g_param_spec_uint (
"stun-max-retransmissions",
"STUN Max Retransmissions",
"Maximum number of STUN binding requests retransmissions "
"described as 'Rc' in the STUN specification.",
1, 99,
STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* NiceAgent:stun-initial-timeout
*
* The initial timeout (msecs) of the STUN binding requests
* used in the gathering stage, to find our local candidates.
* This property is described as 'RTO' in the RFC 5389 and RFC 5245.
* This timeout is doubled for each retransmission, until
* #NiceAgent:stun-max-retransmissions have been done,
* with an exception for the last restransmission, where the timeout is
* divided by two instead (RFC 5389 indicates that a customisable
* multiplier 'Rm' to 'RTO' should be used).
*
* Since: 0.1.15
*/
g_object_class_install_property (gobject_class, PROP_STUN_INITIAL_TIMEOUT,
g_param_spec_uint (
"stun-initial-timeout",
"STUN Initial Timeout",
"STUN timeout in msecs of the initial binding requests used in the "
"gathering state, described as 'RTO' in the ICE specification.",
20, 9999,
STUN_TIMER_DEFAULT_TIMEOUT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* NiceAgent:stun-reliable-timeout
*
* The initial timeout of the STUN binding requests used
* for a reliable timer.
*
* Since: 0.1.15
*/
g_object_class_install_property (gobject_class, PROP_STUN_RELIABLE_TIMEOUT,
g_param_spec_uint (
"stun-reliable-timeout",
"STUN Reliable Timeout",
"STUN timeout in msecs of the initial binding requests used for "
"a reliable timer.",
20, 99999,
STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/* install signals */
/**
......@@ -1056,6 +1129,24 @@ nice_agent_new_regular_nomination (GMainContext *ctx, NiceCompatibility compat)
}
NICEAPI_EXPORT NiceAgent *
nice_agent_new_full (GMainContext *ctx,
NiceCompatibility compat,
NiceAgentOption flags)
{
NiceAgent *agent = g_object_new (NICE_TYPE_AGENT,
"compatibility", compat,
"main-context", ctx,
"reliable", (flags & NICE_AGENT_OPTION_RELIABLE) ? TRUE : FALSE,
"nomination-mode", (flags & NICE_AGENT_OPTION_REGULAR_NOMINATION) ?
NICE_NOMINATION_MODE_REGULAR : NICE_NOMINATION_MODE_AGGRESSIVE,
"full-mode", (flags & NICE_AGENT_OPTION_LITE_MODE) ? FALSE : TRUE,
NULL);
return agent;
}
static void
nice_agent_get_property (
GObject *object,
......@@ -1169,6 +1260,18 @@ nice_agent_get_property (
g_value_set_boolean (value, agent->turn_short_term);
break;
case PROP_STUN_MAX_RETRANSMISSIONS:
g_value_set_uint (value, agent->stun_max_retransmissions);
break;
case PROP_STUN_INITIAL_TIMEOUT:
g_value_set_uint (value, agent->stun_initial_timeout);
break;
case PROP_STUN_RELIABLE_TIMEOUT:
g_value_set_uint (value, agent->stun_reliable_timeout);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
......@@ -1360,6 +1463,18 @@ nice_agent_set_property (
agent->turn_short_term = g_value_get_boolean (value);
break;
case PROP_STUN_MAX_RETRANSMISSIONS:
agent->stun_max_retransmissions = g_value_get_uint (value);
break;
case PROP_STUN_INITIAL_TIMEOUT:
agent->stun_initial_timeout = g_value_get_uint (value);
break;
case PROP_STUN_RELIABLE_TIMEOUT:
agent->stun_reliable_timeout = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
......@@ -3177,6 +3292,23 @@ agent_recv_message_unlocked (
g_free (big_buf);
}
if (!nice_component_verify_remote_candidate (component,
message->from, nicesock)) {
if (nice_debug_is_verbose ()) {
gchar str[INET6_ADDRSTRLEN];
nice_address_to_string (message->from, str);
nice_debug_verbose ("Agent %p : %d:%d DROPPING packet from unknown source"
" %s:%d sock-type: %d", agent, stream->id, component->id, str,
nice_address_get_port (message->from), nicesock->type);
}
retval = RECV_OOB;
goto done;
}
agent->media_after_tick = TRUE;
done:
/* Clear local modifications. */
if (message->from == &from) {
......@@ -3495,7 +3627,7 @@ nice_agent_recv_cancelled_cb (GCancellable *cancellable, gpointer user_data)
{
GError **error = user_data;
if (error && *error)
if (error && !*error)
g_cancellable_set_error_if_cancelled (cancellable, error);
return G_SOURCE_REMOVE;
}
......@@ -4970,7 +5102,7 @@ _generate_candidate_sdp (NiceAgent *agent,
g_string_append_printf (sdp, " typ %s", _cand_type_to_sdp (candidate->type));
if (nice_address_is_valid (&candidate->base_addr) &&
!nice_address_equal (&candidate->addr, &candidate->base_addr)) {
port = nice_address_get_port (&candidate->addr);
port = nice_address_get_port (&candidate->base_addr);
nice_address_to_string (&candidate->base_addr, ip4);
g_string_append_printf (sdp, " raddr %s rport %d", ip4,
port == 0 ? 9 : port);
......
......@@ -385,7 +385,7 @@ typedef enum
* faster, than the regular mode, potentially causing the nominated
* pair to change until the connection check completes.
*
* Since: UNRELEASED
* Since: 0.1.15
*/
typedef enum
{
......@@ -393,6 +393,25 @@ typedef enum
NICE_NOMINATION_MODE_AGGRESSIVE,
} NiceNominationMode;
/**
* NiceAgentOption:
* @NICE_AGENT_OPTION_REGULAR_NOMINATION: Enables regular nomination, default
* is aggrssive mode (see #NiceNominationMode).
* @NICE_AGENT_OPTION_RELIABLE: Enables reliable mode, possibly using PseudoTCP, * see nice_agent_new_reliable().
* @NICE_AGENT_OPTION_LITE_MODE: Enable lite mode
*
* These are options that can be passed to nice_agent_new_full(). They set
* various properties on the agent. Not including them sets the property to
* the other value.
*
* Since: 0.1.15
*/
typedef enum {
NICE_AGENT_OPTION_REGULAR_NOMINATION = 1 << 0,
NICE_AGENT_OPTION_RELIABLE = 1 << 1,
NICE_AGENT_OPTION_LITE_MODE = 1 << 2,
} NiceAgentOption;
/**
* NiceAgentRecvFunc:
* @agent: The #NiceAgent Object
......@@ -444,6 +463,26 @@ nice_agent_new (GMainContext *ctx, NiceCompatibility compat);
NiceAgent *
nice_agent_new_regular_nomination (GMainContext *ctx, NiceCompatibility compat);
/**
* nice_agent_new_full:
* @ctx: The Glib Mainloop Context to use for timers
* @compat: The compatibility mode of the agent
* @flags: Flags to set the properties
*
* Create a new #NiceAgent with parameters that must be be defined at
* construction time.
* The returned object must be freed with g_object_unref()
* <para> See also: #NiceNominationMode and #NiceAgentOption</para>
*
* Since: 0.1.15
*
* Returns: The new agent GObject
*/
NiceAgent *
nice_agent_new_full (GMainContext *ctx,
NiceCompatibility compat,
NiceAgentOption flags);
/**
* nice_agent_add_local_address:
* @agent: The #NiceAgent Object
......@@ -463,7 +502,6 @@ nice_agent_new_regular_nomination (GMainContext *ctx, NiceCompatibility compat);
gboolean
nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr);
/**
* nice_agent_add_stream:
* @agent: The #NiceAgent Object
......
......@@ -1081,7 +1081,6 @@ nice_component_class_init (NiceComponentClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static gboolean
dummy_callback (gpointer data)
{
......@@ -1670,7 +1669,7 @@ nice_component_add_valid_candidate (NiceComponent *component,
char str[INET6_ADDRSTRLEN];
nice_address_to_string (&candidate->addr, str);
nice_debug ("Agent %p : %d:%d Adding valid source"
" candidate: %s:%d trans: %d\n", component->agent,
" candidate: %s:%d trans: %d", component->agent,
candidate->stream_id, candidate->component_id, str,
nice_address_get_port (&candidate->addr), candidate->transport);
}
......
......@@ -107,6 +107,54 @@ priv_state_to_gchar (NiceCheckState state)
}
}
static const gchar *
priv_state_to_string (NiceCheckState state)
{
switch (state) {
case NICE_CHECK_WAITING:
return "waiting";
case NICE_CHECK_IN_PROGRESS:
return "in progress";
case NICE_CHECK_SUCCEEDED:
return "succeeded";
case NICE_CHECK_FAILED:
return "failed";
case NICE_CHECK_FROZEN:
return "frozen";
case NICE_CHECK_DISCOVERED:
return "discovered";
default:
g_assert_not_reached ();
}
}
static const gchar *
priv_ice_return_to_string (StunUsageIceReturn ice_return)
{
switch (ice_return) {
case STUN_USAGE_ICE_RETURN_SUCCESS:
return "success";
case STUN_USAGE_ICE_RETURN_ERROR:
return "error";
case STUN_USAGE_ICE_RETURN_INVALID:
return "invalid";
case STUN_USAGE_ICE_RETURN_ROLE_CONFLICT:
return "role conflict";
case STUN_USAGE_ICE_RETURN_INVALID_REQUEST:
return "invalid request";
case STUN_USAGE_ICE_RETURN_INVALID_METHOD:
return "invalid method";
case STUN_USAGE_ICE_RETURN_MEMORY_ERROR:
return "memory error";
case STUN_USAGE_ICE_RETURN_INVALID_ADDRESS:
return "invalid address";
case STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS:
return "no mapped address";
default:
g_assert_not_reached ();
}
}
static const gchar *
priv_candidate_type_to_string (NiceCandidateType type)
{
......@@ -577,27 +625,7 @@ candidate_check_pair_fail (NiceStream *stream, NiceAgent *agent, CandidateCheckP
static gboolean
priv_conn_recheck_on_timeout (NiceAgent *agent, CandidateCheckPair *p)
{
/* 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 a make a unique recheck per pair to avoid this bouncing
* effect. Another workaround could be a 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.
* The problem is that a given stun request may not be given enough
* individual retransmissions.
*/
if (p->recheck_on_timeout && p->recheck_on_timeout_count > 0)
nice_debug ("Agent %p : pair %p has already been cancelled once, "
"ignoring recheck_on_timeout", agent, p);
if (p->recheck_on_timeout && p->recheck_on_timeout_count == 0) {
if (p->recheck_on_timeout) {
g_assert (p->state == NICE_CHECK_IN_PROGRESS);
/* this cancelled pair may have the flag 'mark nominated
* on response arrival' set, we want to keep it, because
......@@ -609,8 +637,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;
p->recheck_on_timeout_count++;
priv_add_pair_to_triggered_check_queue (agent, p);
return TRUE;
}
......@@ -630,106 +656,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 (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 (!agent_find_component (agent, p->stream_id, p->component_id,
NULL, &component))
continue;
if (p->state != NICE_CHECK_IN_PROGRESS)
continue;
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->stop_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;
}
}
......@@ -1324,8 +1350,9 @@ static gboolean priv_conn_keepalive_tick_unlocked (NiceAgent *agent)
agent, buf_len, p->keepalive.stun_message.buffer);
if (buf_len > 0) {
stun_timer_start (&p->keepalive.timer, NICE_AGENT_KEEPALIVE_DEFAULT_TIMEOUT,
STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
stun_timer_start (&p->keepalive.timer,
agent->stun_initial_timeout,
agent->stun_max_retransmissions);
agent->media_after_tick = FALSE;
......@@ -1552,8 +1579,9 @@ static void priv_turn_allocate_refresh_tick_unlocked (CandidateRefresh *cand)
}
if (buffer_len > 0) {
stun_timer_start (&cand->timer, STUN_TIMER_DEFAULT_TIMEOUT,
STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
stun_timer_start (&cand->timer,
cand->agent->stun_initial_timeout,
cand->agent->stun_max_retransmissions);
/* send the refresh */
agent_socket_send (cand->nicesock, &cand->server,
......@@ -2143,6 +2171,7 @@ static CandidateCheckPair *priv_add_new_check_pair (NiceAgent *agent,
}
pair->prflx_priority = ensure_unique_priority (component,
peer_reflexive_candidate_priority (agent, local));
pair->retransmit_on_timeout = TRUE;
stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair,
(GCompareFunc)conn_check_compare);
......@@ -2573,6 +2602,11 @@ static unsigned int priv_compute_conncheck_timer (NiceAgent *agent, NiceStream *
n = priv_number_of_active_check_lists (agent);
rto = agent->timer_ta * n * waiting_and_in_progress;
/* We assume non-reliable streams are RTP, so we use 100 as the max */
nice_debug ("Agent %p : timer set to %dms, "
"waiting+in_progress=%d, nb_active=%d",
agent, MAX (rto, 100),
waiting_and_in_progress, n);
return MAX (rto, 100);
}
......@@ -2625,7 +2659,7 @@ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair)
nice_address_to_string (&pair->remote->addr, tmpbuf2);
nice_debug ("Agent %p : STUN-CC REQ [%s]:%u --> [%s]:%u, socket=%u, "
"pair=%s (c-id:%u), tie=%llu, username='%.*s' (%" G_GSIZE_FORMAT "), "
"password='%.*s' (%" G_GSIZE_FORMAT "), prio=%u, cont=%d.", agent,
"password='%.*s' (%" G_GSIZE_FORMAT "), prio=%u, %s.", agent,
tmpbuf1, nice_address_get_port (&pair->local->addr),
tmpbuf2, nice_address_get_port (&pair->remote->addr),
pair->sockptr->fileno ? g_socket_get_fd(pair->sockptr->fileno) : -1,
......@@ -2633,33 +2667,30 @@ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair)
(unsigned long long)agent->tie_breaker,
(int) uname_len, uname, uname_len,
(int) password_len, password, password_len,
pair->prflx_priority, controlling);
pair->prflx_priority,
controlling ? "controlling" : "controlled");
}
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;
......@@ -2667,78 +2698,101 @@ 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->