Commit a6112cec authored by Jakub Adam's avatar Jakub Adam Committed by Olivier Crête

agent: trickle ICE mode

In this mode, activated by setting "ice-trickle" property of a
NiceAgent to TRUE, a component without a successful connectivity check
will wait indefinitely for more remote candidates to come.

nice_agent_peer_candidate_gathering_done() must be called after
receiving the last remote candidate for the component to finally change
its state to NICE_COMPONENT_STATE_FAILED.
parent 14b27084
...@@ -190,6 +190,7 @@ struct _NiceAgent ...@@ -190,6 +190,7 @@ struct _NiceAgent
guint16 rfc4571_expecting_length; guint16 rfc4571_expecting_length;
gboolean use_ice_udp; gboolean use_ice_udp;
gboolean use_ice_tcp; gboolean use_ice_tcp;
gboolean use_ice_trickle;
guint conncheck_timer_grace_period; /* ongoing delay before timer stop */ guint conncheck_timer_grace_period; /* ongoing delay before timer stop */
gboolean controlling_mode; /* controlling mode used by the gboolean controlling_mode; /* controlling mode used by the
......
...@@ -118,6 +118,7 @@ enum ...@@ -118,6 +118,7 @@ enum
PROP_STUN_INITIAL_TIMEOUT, PROP_STUN_INITIAL_TIMEOUT,
PROP_STUN_RELIABLE_TIMEOUT, PROP_STUN_RELIABLE_TIMEOUT,
PROP_NOMINATION_MODE, PROP_NOMINATION_MODE,
PROP_ICE_TRICKLE,
}; };
...@@ -806,6 +807,24 @@ nice_agent_class_init (NiceAgentClass *klass) ...@@ -806,6 +807,24 @@ nice_agent_class_init (NiceAgentClass *klass)
STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT, STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* NiceAgent:ice-trickle
*
* Whether to perform Trickle ICE as per draft-ietf-ice-trickle-ice-21.
* When %TRUE, the agent will postpone changing a component state to
* %NICE_COMPONENT_STATE_FAILED until nice_agent_peer_candidate_gathering_done()
* has been called with the ID of the component's stream.
*
* Since: 0.1.16
*/
g_object_class_install_property (gobject_class, PROP_ICE_TRICKLE,
g_param_spec_boolean (
"ice-trickle",
"Trickle ICE",
"Whether to perform Trickle ICE as per draft-ietf-ice-trickle-ice-21.",
FALSE,
G_PARAM_READWRITE));
/* install signals */ /* install signals */
/** /**
...@@ -1226,6 +1245,7 @@ nice_agent_new_full (GMainContext *ctx, ...@@ -1226,6 +1245,7 @@ nice_agent_new_full (GMainContext *ctx,
"nomination-mode", (flags & NICE_AGENT_OPTION_REGULAR_NOMINATION) ? "nomination-mode", (flags & NICE_AGENT_OPTION_REGULAR_NOMINATION) ?
NICE_NOMINATION_MODE_REGULAR : NICE_NOMINATION_MODE_AGGRESSIVE, NICE_NOMINATION_MODE_REGULAR : NICE_NOMINATION_MODE_AGGRESSIVE,
"full-mode", (flags & NICE_AGENT_OPTION_LITE_MODE) ? FALSE : TRUE, "full-mode", (flags & NICE_AGENT_OPTION_LITE_MODE) ? FALSE : TRUE,
"ice-trickle", (flags & NICE_AGENT_OPTION_ICE_TRICKLE) ? TRUE : FALSE,
NULL); NULL);
return agent; return agent;
...@@ -1364,6 +1384,10 @@ nice_agent_get_property ( ...@@ -1364,6 +1384,10 @@ nice_agent_get_property (
g_value_set_uint (value, agent->stun_reliable_timeout); g_value_set_uint (value, agent->stun_reliable_timeout);
break; break;
case PROP_ICE_TRICKLE:
g_value_set_boolean (value, agent->use_ice_trickle);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
...@@ -1567,6 +1591,10 @@ nice_agent_set_property ( ...@@ -1567,6 +1591,10 @@ nice_agent_set_property (
agent->stun_reliable_timeout = g_value_get_uint (value); agent->stun_reliable_timeout = g_value_get_uint (value);
break; break;
case PROP_ICE_TRICKLE:
agent->use_ice_trickle = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
...@@ -6575,3 +6603,23 @@ nice_agent_get_component_state (NiceAgent *agent, ...@@ -6575,3 +6603,23 @@ nice_agent_get_component_state (NiceAgent *agent,
return state; return state;
} }
gboolean
nice_agent_peer_candidate_gathering_done (NiceAgent *agent, guint stream_id)
{
NiceStream *stream;
gboolean result = FALSE;
agent_lock (agent);
stream = agent_find_stream (agent, stream_id);
if (stream) {
stream->peer_gathering_done = TRUE;
result = TRUE;
}
agent_unlock (agent);
return result;
}
...@@ -404,6 +404,7 @@ typedef enum ...@@ -404,6 +404,7 @@ typedef enum
* is aggrssive mode (see #NiceNominationMode). * is aggrssive mode (see #NiceNominationMode).
* @NICE_AGENT_OPTION_RELIABLE: Enables reliable mode, possibly using PseudoTCP, * see nice_agent_new_reliable(). * @NICE_AGENT_OPTION_RELIABLE: Enables reliable mode, possibly using PseudoTCP, * see nice_agent_new_reliable().
* @NICE_AGENT_OPTION_LITE_MODE: Enable lite mode * @NICE_AGENT_OPTION_LITE_MODE: Enable lite mode
* @NICE_AGENT_OPTION_ICE_TRICKLE: Enable ICE trickle mode
* *
* These are options that can be passed to nice_agent_new_full(). They set * 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 * various properties on the agent. Not including them sets the property to
...@@ -415,6 +416,7 @@ typedef enum { ...@@ -415,6 +416,7 @@ typedef enum {
NICE_AGENT_OPTION_REGULAR_NOMINATION = 1 << 0, NICE_AGENT_OPTION_REGULAR_NOMINATION = 1 << 0,
NICE_AGENT_OPTION_RELIABLE = 1 << 1, NICE_AGENT_OPTION_RELIABLE = 1 << 1,
NICE_AGENT_OPTION_LITE_MODE = 1 << 2, NICE_AGENT_OPTION_LITE_MODE = 1 << 2,
NICE_AGENT_OPTION_ICE_TRICKLE = 1 << 3,
} NiceAgentOption; } NiceAgentOption;
/** /**
...@@ -1631,6 +1633,29 @@ nice_agent_get_component_state (NiceAgent *agent, ...@@ -1631,6 +1633,29 @@ nice_agent_get_component_state (NiceAgent *agent,
guint stream_id, guint stream_id,
guint component_id); guint component_id);
/**
* nice_agent_peer_candidate_gathering_done:
* @agent: The #NiceAgent Object
* @stream_id: The ID of the stream
*
* Notifies the agent that the remote peer has concluded candidate gathering and
* thus no more remote candidates are expected to arrive for @stream_id.
*
* This will allow the stream components without a successful connectivity check
* to stop waiting for more candidates to come and finally transit into
* %NICE_COMPONENT_STATE_FAILED.
*
* Calling the function has an effect only when #NiceAgent:trickle-ice is %TRUE.
*
* Returns: %FALSE if the stream could not be found, %TRUE otherwise
*
* Since: 0.1.16
*/
gboolean
nice_agent_peer_candidate_gathering_done (
NiceAgent *agent,
guint stream_id);
G_END_DECLS G_END_DECLS
#endif /* __LIBNICE_AGENT_H__ */ #endif /* __LIBNICE_AGENT_H__ */
...@@ -1106,6 +1106,9 @@ static gboolean priv_conn_check_tick_agent_locked (NiceAgent *agent, ...@@ -1106,6 +1106,9 @@ static gboolean priv_conn_check_tick_agent_locked (NiceAgent *agent,
agent, stream->id); agent, stream->id);
keep_timer_going = priv_conn_check_unfreeze_next (agent, stream); keep_timer_going = priv_conn_check_unfreeze_next (agent, stream);
} }
if (!keep_timer_going && !stream->peer_gathering_done) {
keep_timer_going = TRUE;
}
} }
} }
......
...@@ -77,6 +77,8 @@ nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent) ...@@ -77,6 +77,8 @@ nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent)
stream->n_components = n_components; stream->n_components = n_components;
stream->peer_gathering_done = !agent->use_ice_trickle;
return stream; return stream;
} }
......
...@@ -87,6 +87,7 @@ struct _NiceStream { ...@@ -87,6 +87,7 @@ struct _NiceStream {
gchar remote_password[NICE_STREAM_MAX_PWD]; gchar remote_password[NICE_STREAM_MAX_PWD];
gboolean gathering; gboolean gathering;
gboolean gathering_started; gboolean gathering_started;
gboolean peer_gathering_done;
gint tos; gint tos;
guint tick_counter; guint tick_counter;
}; };
......
...@@ -109,6 +109,10 @@ ...@@ -109,6 +109,10 @@
<title>Index of new symbols in 0.1.15</title> <title>Index of new symbols in 0.1.15</title>
<xi:include href="xml/api-index-0.1.15.xml"><xi:fallback/></xi:include> <xi:include href="xml/api-index-0.1.15.xml"><xi:fallback/></xi:include>
</index> </index>
<index role="0.1.16">
<title>Index of new symbols in 0.1.16</title>
<xi:include href="xml/api-index-0.1.16.xml"><xi:fallback/></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</part> </part>
</book> </book>
...@@ -29,6 +29,7 @@ nice_agent_set_remote_candidates ...@@ -29,6 +29,7 @@ nice_agent_set_remote_candidates
nice_agent_get_remote_candidates nice_agent_get_remote_candidates
nice_agent_get_local_candidates nice_agent_get_local_candidates
nice_agent_get_selected_pair nice_agent_get_selected_pair
nice_agent_peer_candidate_gathering_done
nice_agent_send nice_agent_send
nice_agent_send_messages_nonblocking nice_agent_send_messages_nonblocking
nice_agent_recv nice_agent_recv
......
...@@ -44,6 +44,7 @@ nice_agent_option_get_type ...@@ -44,6 +44,7 @@ nice_agent_option_get_type
nice_agent_parse_remote_candidate_sdp nice_agent_parse_remote_candidate_sdp
nice_agent_parse_remote_sdp nice_agent_parse_remote_sdp
nice_agent_parse_remote_stream_sdp nice_agent_parse_remote_stream_sdp
nice_agent_peer_candidate_gathering_done
nice_agent_remove_stream nice_agent_remove_stream
nice_agent_restart nice_agent_restart
nice_agent_restart_stream nice_agent_restart_stream
......
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