8 static NiceComponentState global_lagent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST };
9 static NiceComponentState global_ragent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST };
10 static guint global_components_ready = 0;
11 static gboolean global_lagent_gathering_done = FALSE;
12 static gboolean global_ragent_gathering_done = FALSE;
13 static int global_lagent_cands = 0;
14 static int global_ragent_cands = 0;
16 #define TURN_USER "toto"
17 #define TURN_PASS "password"
19 static gboolean timer_cb (gpointer pointer)
21 g_debug ("test-turn:%s: %p", G_STRFUNC, pointer);
23 /* signal status via a global variable */
25 /* note: should not be reached, abort */
26 g_error ("ERROR: test has got stuck, aborting...");
31 static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
33 g_debug ("test-fullmode:%s: %p", G_STRFUNC, user_data);
35 /* XXX: dear compiler, these are for you: */
36 (void)agent; (void)stream_id; (void)component_id; (void)buf;
39 * Lets ignore stun packets that got through
43 if (strncmp ("12345678", buf, 8))
46 if (component_id != 1)
50 if (GPOINTER_TO_UINT (user_data) == 2) {
51 global_ragent_read += len;
56 static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data)
58 g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
60 if (GPOINTER_TO_UINT (data) == 1)
61 global_lagent_gathering_done = TRUE;
62 else if (GPOINTER_TO_UINT (data) == 2)
63 global_ragent_gathering_done = TRUE;
67 static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data)
69 gboolean ready_to_connected = FALSE;
70 g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
72 if (GPOINTER_TO_UINT (data) == 1) {
73 if (global_lagent_state[component_id - 1] == NICE_COMPONENT_STATE_READY &&
74 state == NICE_COMPONENT_STATE_CONNECTED)
75 ready_to_connected = TRUE;
76 global_lagent_state[component_id - 1] = state;
77 } else if (GPOINTER_TO_UINT (data) == 2) {
78 if (global_ragent_state[component_id - 1] == NICE_COMPONENT_STATE_READY &&
79 state == NICE_COMPONENT_STATE_CONNECTED)
80 ready_to_connected = TRUE;
81 global_ragent_state[component_id - 1] = state;
84 if (state == NICE_COMPONENT_STATE_READY)
85 global_components_ready++;
86 else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected)
87 global_components_ready--;
88 g_assert (state != NICE_COMPONENT_STATE_FAILED);
90 g_debug ("test-turn: checks READY %u.", global_components_ready);
93 static void cb_new_selected_pair(NiceAgent *agent, guint stream_id,
94 guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data)
96 g_debug ("test-turn:%s: %p", G_STRFUNC, data);
98 if (GPOINTER_TO_UINT (data) == 1)
99 ++global_lagent_cands;
100 else if (GPOINTER_TO_UINT (data) == 2)
101 ++global_ragent_cands;
104 static void cb_closed (GObject *src, GAsyncResult *res, gpointer data)
106 NiceAgent *agent = NICE_AGENT (src);
107 g_debug ("test-turn:%s: %p", G_STRFUNC, agent);
109 *((gboolean *)data) = TRUE;
112 static void set_candidates (NiceAgent *from, guint from_stream,
113 NiceAgent *to, guint to_stream, guint component, gboolean remove_non_relay,
114 gboolean force_relay)
116 GSList *cands = NULL, *i;
118 cands = nice_agent_get_local_candidates (from, from_stream, component);
119 if (remove_non_relay) {
121 for (i = cands; i; i = i->next) {
122 NiceCandidate *cand = i->data;
124 g_assert_cmpint (cand->type, ==, NICE_CANDIDATE_TYPE_RELAYED);
125 if (cand->type != NICE_CANDIDATE_TYPE_RELAYED) {
126 cands = g_slist_remove (cands, cand);
127 nice_candidate_free (cand);
132 nice_agent_set_remote_candidates (to, to_stream, component, cands);
134 for (i = cands; i; i = i->next)
135 nice_candidate_free ((NiceCandidate *) i->data);
136 g_slist_free (cands);
139 static void set_credentials (NiceAgent *lagent, guint lstream,
140 NiceAgent *ragent, guint rstream)
142 gchar *ufrag = NULL, *password = NULL;
144 nice_agent_get_local_credentials(lagent, lstream, &ufrag, &password);
145 nice_agent_set_remote_credentials (ragent, rstream, ufrag, password);
148 nice_agent_get_local_credentials(ragent, rstream, &ufrag, &password);
149 nice_agent_set_remote_credentials (lagent, lstream, ufrag, password);
155 run_test(guint turn_port, gboolean is_ipv6,
156 gboolean ice_udp, gboolean ice_tcp, gboolean force_relay,
157 gboolean remove_non_relay,
158 NiceRelayType turn_type)
160 NiceAgent *lagent, *ragent; /* agent's L and R */
161 const gchar *localhost;
162 NiceAddress localaddr;
165 gboolean lagent_closed = FALSE;
166 gboolean ragent_closed = FALSE;
171 localhost = "127.0.0.1";
173 /* step: initialize variables modified by the callbacks */
174 global_components_ready = 0;
175 global_lagent_gathering_done = FALSE;
176 global_ragent_gathering_done = FALSE;
177 global_lagent_cands = global_ragent_cands = 0;
179 lagent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245);
180 ragent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245);
182 g_object_set (G_OBJECT (lagent), "ice-tcp", ice_tcp, "ice-udp", ice_udp,
183 "force-relay", force_relay, NULL);
184 g_object_set (G_OBJECT (ragent), "ice-tcp", ice_tcp, "ice-udp", ice_udp,
185 "force-relay", force_relay, NULL);
187 g_object_set (G_OBJECT (lagent), "upnp", FALSE, NULL);
188 g_object_set (G_OBJECT (ragent), "upnp", FALSE, NULL);
189 nice_agent_set_software (lagent, "Test-turn, Left Agent");
190 nice_agent_set_software (ragent, "Test-turn, Right Agent");
192 timer_id = g_timeout_add (30000, timer_cb, NULL);
195 if (!nice_address_set_from_string (&localaddr, localhost))
196 g_assert_not_reached ();
197 nice_agent_add_local_address (lagent, &localaddr);
198 nice_agent_add_local_address (ragent, &localaddr);
200 g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done",
201 G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1));
202 g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done",
203 G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2));
204 g_signal_connect (G_OBJECT (lagent), "component-state-changed",
205 G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1));
206 g_signal_connect (G_OBJECT (ragent), "component-state-changed",
207 G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2));
208 g_signal_connect (G_OBJECT (lagent), "new-selected-pair",
209 G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1));
210 g_signal_connect (G_OBJECT (ragent), "new-selected-pair",
211 G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2));
213 g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
214 g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
216 ls_id = nice_agent_add_stream (lagent, 1);
217 rs_id = nice_agent_add_stream (ragent, 1);
218 g_assert_cmpuint (ls_id, >, 0);
219 g_assert_cmpuint (rs_id, >, 0);
220 nice_agent_set_relay_info(lagent, ls_id, 1,
221 localhost, turn_port, TURN_USER, TURN_PASS, turn_type);
222 nice_agent_set_relay_info(ragent, rs_id, 1,
223 localhost, turn_port, TURN_USER, TURN_PASS, turn_type);
225 g_assert (global_lagent_gathering_done == FALSE);
226 g_assert (global_ragent_gathering_done == FALSE);
227 g_debug ("test-turn: Added streams, running context until 'candidate-gathering-done'...");
229 /* Gather candidates and test nice_agent_set_port_range */
230 g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE);
231 g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE);
233 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
234 g_main_context_default (), cb_nice_recv, GUINT_TO_POINTER (1));
235 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
236 g_main_context_default (), cb_nice_recv, GUINT_TO_POINTER (2));
238 while (!global_lagent_gathering_done)
239 g_main_context_iteration (NULL, TRUE);
240 g_assert (global_lagent_gathering_done == TRUE);
241 while (!global_ragent_gathering_done)
242 g_main_context_iteration (NULL, TRUE);
243 g_assert (global_ragent_gathering_done == TRUE);
245 set_credentials (lagent, ls_id, ragent, rs_id);
247 set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
248 remove_non_relay, force_relay);
249 set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
250 remove_non_relay, force_relay);
252 while (global_lagent_state[0] != NICE_COMPONENT_STATE_READY ||
253 global_ragent_state[0] != NICE_COMPONENT_STATE_READY)
254 g_main_context_iteration (NULL, TRUE);
255 g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
256 g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
258 nice_agent_remove_stream (lagent, ls_id);
259 nice_agent_remove_stream (ragent, rs_id);
261 nice_agent_close_async (lagent, cb_closed, &lagent_closed);
262 nice_agent_close_async (ragent, cb_closed, &ragent_closed);
264 g_clear_object(&lagent);
265 g_clear_object(&ragent);
267 while (!lagent_closed || !ragent_closed) {
268 g_main_context_iteration (NULL, TRUE);
271 g_source_remove (timer_id);
275 guint global_turn_port;
278 udp_no_force_no_remove_udp (void)
280 run_test(global_turn_port, FALSE /* is_ipv6 */,
283 FALSE /* force_relay */,
284 FALSE /* remove_non_relay */,
285 NICE_RELAY_TYPE_TURN_UDP);
289 udp_no_force_remove_udp (void)
291 run_test(global_turn_port, FALSE /* is_ipv6 */,
294 FALSE /* force_relay */,
295 TRUE /* remove_non_relay */,
296 NICE_RELAY_TYPE_TURN_UDP);
300 udp_force_no_remove_udp (void)
302 run_test(global_turn_port, FALSE /* is_ipv6 */,
305 TRUE /* force_relay */,
306 FALSE /* remove_non_relay */,
307 NICE_RELAY_TYPE_TURN_UDP);
311 udp_no_force_no_remove_tcp (void)
313 run_test(global_turn_port, FALSE /* is_ipv6 */,
316 FALSE /* force_relay */,
317 FALSE /* remove_non_relay */,
318 NICE_RELAY_TYPE_TURN_TCP);
322 udp_no_force_remove_tcp (void)
324 run_test(global_turn_port, FALSE /* is_ipv6 */,
327 FALSE /* force_relay */,
328 TRUE /* remove_non_relay */,
329 NICE_RELAY_TYPE_TURN_TCP);
333 udp_force_no_remove_tcp (void)
335 run_test(global_turn_port, FALSE /* is_ipv6 */,
338 TRUE /* force_relay */,
339 FALSE /* remove_non_relay */,
340 NICE_RELAY_TYPE_TURN_TCP);
348 main (int argc, char **argv)
351 GError *error = NULL;
354 gchar *out_str = NULL;
355 gchar *err_str = NULL;
357 g_test_init (&argc, &argv, NULL);
359 global_turn_port = g_random_int_range (10000, 60000);
360 snprintf(portstr, 9, "%u", global_turn_port);
362 if (g_spawn_command_line_sync ("turnserver --help", &out_str, &err_str, NULL,
364 if (!strstr(err_str, "--user")) {
365 g_print ("rfc5766-turn-server not installed, skipping turn test\n");
369 g_print ("rfc5766-turn-server not installed, skipping turn test\n");
375 sp = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, &error,
377 "--user", "toto:0xaae440b3348d50265b63703117c7bfd5",
379 "--listening-port", portstr,
382 g_test_add_func ("/nice/turn/udp", udp_no_force_no_remove_udp);
383 g_test_add_func ("/nice/turn/udp/remove_non_turn",
384 udp_no_force_remove_udp);
385 g_test_add_func ("/nice/turn/udp/force_relay",
386 udp_force_no_remove_udp);
387 g_test_add_func ("/nice/turn/udp/over-tcp", udp_no_force_no_remove_tcp);
388 g_test_add_func ("/nice/turn/udp/over-tcp/remove_non_turn",
389 udp_no_force_remove_tcp);
390 g_test_add_func ("/nice/turn/udp/over-tcp/force_relay",
391 udp_force_no_remove_tcp);
395 g_subprocess_force_exit (sp);
396 g_subprocess_wait (sp, NULL, NULL);
397 g_clear_object (&sp);