Add win32 directory to EXTRA_DIST
[sipe-libnice.git] / tests / test-new-dribble.c
blob930245537e021ffe90d894681a7698f38a599c7e
1 /*
2 * This file is part of the Nice GLib ICE library.
4 * Unit test for ICE in dribble mode (adding remote candidates while gathering
5 * local candidates).
7 * (C) 2012 Collabora Ltd.
8 * Contact: Rohan Garg
9 * Youness Alaoui
11 * The contents of this file are subject to the Mozilla Public License Version
12 * 1.1 (the "License"); you may not use this file except in compliance with
13 * the License. You may obtain a copy of the License at
14 * http://www.mozilla.org/MPL/
16 * Software distributed under the License is distributed on an "AS IS" basis,
17 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
18 * for the specific language governing rights and limitations under the
19 * License.
21 * The Original Code is the Nice GLib ICE library.
23 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
24 * Corporation.
26 * Contributors:
27 * Rohan Garg
29 * Alternatively, the contents of this file may be used under the terms of the
30 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
31 * case the provisions of LGPL are applicable instead of those above. If you
32 * wish to allow use of your version of this file only under the terms of the
33 * LGPL and not to allow others to use your version of this file under the
34 * MPL, indicate your decision by deleting the provisions above and replace
35 * them with the notice and other provisions required by the LGPL. If you do
36 * not delete the provisions above, a recipient may use your version of this
37 * file under either the MPL or the LGPL.
40 #include <glib.h>
41 #include <glib-object.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <stdio.h>
45 #include <sys/types.h>
46 #include <arpa/inet.h>
47 #include <sys/socket.h>
48 #include <netdb.h>
49 #include <netinet/in.h>
51 #include "stunagent.h"
52 #include "agent-priv.h"
53 #include "agent.h"
55 #define IPPORT_STUN 3456
56 #define USE_UPNP 0
57 #define LEFT_AGENT GINT_TO_POINTER(1)
58 #define RIGHT_AGENT GINT_TO_POINTER(2)
60 #if !GLIB_CHECK_VERSION(2,31,8)
61 static GMutex *stun_mutex_ptr = NULL;
62 static GCond *stun_signal_ptr = NULL;
63 static GMutex *stun_thread_mutex_ptr = NULL;
64 static GCond *stun_thread_signal_ptr = NULL
65 #else
66 static GMutex stun_mutex;
67 static GMutex *stun_mutex_ptr = &stun_mutex;
68 static GCond stun_signal;
69 static GCond *stun_signal_ptr = &stun_signal;
70 static GMutex stun_thread_mutex;
71 static GMutex *stun_thread_mutex_ptr = &stun_thread_mutex;
72 static GCond stun_thread_signal;
73 static GCond *stun_thread_signal_ptr = &stun_thread_signal;
74 #endif
76 static GMainLoop *global_mainloop;
77 static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST;
78 static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST;
79 static gboolean exit_stun_thread = FALSE;
80 static gboolean lagent_candidate_gathering_done = FALSE;
81 static gboolean ragent_candidate_gathering_done = FALSE;
82 static guint global_ls_id, global_rs_id;
83 static gboolean data_received = FALSE;
84 static gboolean drop_stun_packets = FALSE;
86 static const uint16_t known_attributes[] = {
91 * Creates a listening socket
93 static int listen_socket (unsigned int port)
95 struct sockaddr_in addr;
96 int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
98 if (fd == -1) {
99 perror ("Error opening IP port");
100 return -1;
103 memset (&addr, 0, sizeof (addr));
104 addr.sin_family = AF_INET;
105 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
106 addr.sin_port = htons(port);
108 if (bind (fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in))) {
109 perror ("Error opening IP port");
110 goto error;
113 return fd;
115 error:
116 close (fd);
117 return -1;
120 static int dgram_process (int sock, StunAgent *oldagent, StunAgent *newagent)
122 struct sockaddr_storage addr;
123 socklen_t addr_len;
124 uint8_t buf[STUN_MAX_MESSAGE_SIZE];
125 size_t buf_len = 0;
126 size_t len = 0;
127 StunMessage request;
128 StunMessage response;
129 StunValidationStatus validation;
130 StunAgent *agent = NULL;
131 gint ret;
133 addr_len = sizeof (struct sockaddr_in);
135 recv_packet:
136 len = recvfrom (sock, buf, sizeof(buf), 0,
137 (struct sockaddr *)&addr, &addr_len);
139 if (drop_stun_packets) {
140 g_debug ("Dropping STUN packet as requested");
141 return -1;
144 if (len == (size_t)-1) {
145 return -1;
148 validation = stun_agent_validate (newagent, &request, buf, len, NULL, 0);
150 if (validation == STUN_VALIDATION_SUCCESS) {
151 agent = newagent;
152 } else {
153 validation = stun_agent_validate (oldagent, &request, buf, len, NULL, 0);
154 agent = oldagent;
157 /* Unknown attributes */
158 if (validation == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE) {
159 buf_len = stun_agent_build_unknown_attributes_error (agent, &response, buf,
160 sizeof (buf), &request);
161 goto send_buf;
164 /* Mal-formatted packets */
165 if (validation != STUN_VALIDATION_SUCCESS ||
166 stun_message_get_class (&request) != STUN_REQUEST) {
167 goto recv_packet;
170 switch (stun_message_get_method (&request)) {
171 case STUN_BINDING:
172 stun_agent_init_response (agent, &response, buf, sizeof (buf), &request);
173 if (stun_message_has_cookie (&request))
174 stun_message_append_xor_addr (&response,
175 STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
176 (struct sockaddr *)&addr, addr_len);
177 else
178 stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS,
179 (struct sockaddr *)&addr, addr_len);
180 break;
182 default:
183 if (!stun_agent_init_error (agent, &response, buf, sizeof (buf),
184 &request, STUN_ERROR_BAD_REQUEST)) {
185 g_debug ("STUN error message not initialized properly");
186 g_assert_not_reached();
190 buf_len = stun_agent_finish_message (agent, &response, NULL, 0);
192 send_buf:
193 g_main_loop_quit (global_mainloop);
194 g_debug ("Ready to send a STUN response");
195 g_assert (g_mutex_trylock (stun_mutex_ptr));
196 while (global_lagent_state < NICE_COMPONENT_STATE_CONNECTING) {
197 g_debug ("Waiting for signal. State is %d", global_lagent_state);
198 g_cond_wait (stun_signal_ptr, stun_mutex_ptr);
200 g_mutex_unlock (stun_mutex_ptr);
201 len = sendto (sock, buf, buf_len, 0,
202 (struct sockaddr *)&addr, addr_len);
203 g_debug ("STUN response sent");
204 drop_stun_packets = TRUE;
205 ret = (len < buf_len) ? -1 : 0;
206 return ret;
210 static gpointer stun_thread_func (const gpointer user_data)
212 StunAgent oldagent;
213 StunAgent newagent;
214 int sock;
215 int exit_code = -1;
217 sock = listen_socket (IPPORT_STUN);
219 if (sock == -1) {
220 g_assert_not_reached ();
223 g_mutex_lock (stun_thread_mutex_ptr);
224 g_cond_signal (stun_thread_signal_ptr);
225 g_mutex_unlock (stun_thread_mutex_ptr);
227 stun_agent_init (&oldagent, known_attributes,
228 STUN_COMPATIBILITY_RFC3489, 0);
229 stun_agent_init (&newagent, known_attributes,
230 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
232 while (!exit_stun_thread) {
233 g_debug ("Ready to process next datagram");
234 dgram_process (sock, &oldagent, &newagent);
237 exit_code = close (sock);
238 g_thread_exit (GINT_TO_POINTER (exit_code));
239 return NULL;
242 static void set_credentials (NiceAgent *lagent, guint lstream,
243 NiceAgent *ragent, guint rstream)
245 gchar *ufrag = NULL, *password = NULL;
247 nice_agent_get_local_credentials (lagent, lstream, &ufrag, &password);
248 nice_agent_set_remote_credentials (ragent, rstream, ufrag, password);
250 g_free (ufrag);
251 g_free (password);
253 nice_agent_get_local_credentials (ragent, rstream, &ufrag, &password);
254 nice_agent_set_remote_credentials (lagent, lstream, ufrag, password);
256 g_free (ufrag);
257 g_free (password);
260 static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data)
262 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data);
264 if (GPOINTER_TO_UINT(data) == 1) {
265 g_debug ("lagent finished gathering candidates");
266 lagent_candidate_gathering_done = TRUE;
267 } else if (GPOINTER_TO_UINT(data) == 2) {
268 g_debug ("ragent finished gathering candidates");
269 ragent_candidate_gathering_done = TRUE;
271 g_main_loop_quit(global_mainloop);
274 static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
276 gint ret;
278 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data);
280 ret = strncmp ("0000", buf, 4);
281 if (ret == 0) {
282 ret = strncmp ("00001234567812345678", buf, 16);
283 g_assert (ret == 0);
285 g_debug ("test-dribblemode:%s: ragent recieved %d bytes : quit mainloop",
286 G_STRFUNC, len);
287 data_received = TRUE;
288 g_main_loop_quit (global_mainloop);
292 static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data)
294 gint ret;
296 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data);
298 if(GPOINTER_TO_UINT(data) == 1) {
299 global_lagent_state = state;
300 g_debug ("lagent state is %d", state);
301 } else if (GPOINTER_TO_UINT(data) == 2) {
302 g_debug ("ragent state is %d", state);
303 global_ragent_state = state;
306 if (GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_FAILED) {
307 g_debug ("Signalling STUN response since connchecks failed");
308 g_mutex_lock (stun_mutex_ptr);
309 g_cond_signal (stun_signal_ptr);
310 g_mutex_unlock (stun_mutex_ptr);
311 g_main_loop_quit (global_mainloop);
314 if(GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_READY) {
315 /* note: test payload send and receive */
316 ret = nice_agent_send (agent, stream_id, component_id,
317 20, "00001234567812345678");
318 g_debug ("Sent %d bytes", ret);
319 g_assert (ret == 20);
323 static void swap_candidates(NiceAgent *local, guint local_id, NiceAgent *remote, guint remote_id, gboolean signal_stun_reply)
325 GSList *cands = NULL;
327 g_debug ("test-dribblemode:%s", G_STRFUNC);
328 cands = nice_agent_get_local_candidates(local, local_id,
329 NICE_COMPONENT_TYPE_RTP);
330 g_assert(nice_agent_set_remote_candidates(remote, remote_id,
331 NICE_COMPONENT_TYPE_RTP, cands));
333 if (signal_stun_reply) {
334 g_mutex_lock (stun_mutex_ptr);
335 g_cond_signal (stun_signal_ptr);
336 g_mutex_unlock (stun_mutex_ptr);
339 g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free);
342 static void cb_agent_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer user_data)
344 NiceAgent *other = g_object_get_data (G_OBJECT (agent), "other-agent");
345 GSList *cands = nice_agent_get_local_candidates (agent, stream_id,
346 component_id);
347 GSList *i = NULL;
348 GSList *remote_cands = NULL;
349 NiceCandidate* temp;
350 gpointer tmp;
351 guint id;
353 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data);
355 tmp = g_object_get_data (G_OBJECT (other), "id");
356 id = GPOINTER_TO_UINT (tmp);
358 for (i = cands; i; i = i->next) {
359 temp = (NiceCandidate*) i->data;
360 if (g_strcmp0(temp->foundation, foundation) == 0) {
361 g_debug ("Adding new local candidate to other agent's connchecks");
362 remote_cands = g_slist_prepend (remote_cands, nice_candidate_copy(temp));
363 g_assert (nice_agent_set_remote_candidates (other, id,
364 NICE_COMPONENT_TYPE_RTP,
365 remote_cands));
369 g_slist_free_full (remote_cands, (GDestroyNotify) nice_candidate_free);
370 g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free);
374 static void add_bad_candidate (NiceAgent *agent, guint stream_id, NiceCandidate *cand)
376 NiceAddress bad_addr;
377 GSList *cand_list = NULL;
379 g_assert (nice_address_set_from_string (&bad_addr, "172.1.0.1"));
381 cand = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
382 cand->stream_id = stream_id;
383 cand->component_id = NICE_COMPONENT_TYPE_RTP;
384 cand->addr = bad_addr;
386 nice_agent_get_local_credentials (agent, stream_id,
387 &cand->username, &cand->password);
388 cand_list = g_slist_prepend (cand_list, cand);
390 g_debug ("Adding buggy candidate to the agent %p", agent);
391 g_assert (nice_agent_set_remote_candidates (agent, stream_id,
392 NICE_COMPONENT_TYPE_RTP,
393 cand_list));
395 g_slist_free_full (cand_list, (GDestroyNotify) nice_candidate_free);
399 static void init_test(NiceAgent *lagent, NiceAgent *ragent, gboolean connect_new_candidate_signal)
401 global_lagent_state = NICE_COMPONENT_STATE_DISCONNECTED;
402 global_ragent_state = NICE_COMPONENT_STATE_DISCONNECTED;
404 lagent_candidate_gathering_done = FALSE;
405 ragent_candidate_gathering_done = FALSE;
407 global_ls_id = nice_agent_add_stream (lagent, 1);
408 global_rs_id = nice_agent_add_stream (ragent, 1);
410 g_assert (global_ls_id > 0);
411 g_assert (global_rs_id > 0);
413 g_debug ("lagent stream is : %d and ragent stream is %d",
414 global_ls_id,
415 global_rs_id);
417 g_object_set_data (G_OBJECT (lagent), "id", GUINT_TO_POINTER (global_ls_id));
418 g_object_set_data (G_OBJECT (ragent), "id", GUINT_TO_POINTER (global_rs_id));
420 if (connect_new_candidate_signal) {
421 g_signal_connect (G_OBJECT(lagent), "new-candidate",
422 G_CALLBACK(cb_agent_new_candidate), LEFT_AGENT);
423 g_signal_connect (G_OBJECT(ragent), "new-candidate",
424 G_CALLBACK(cb_agent_new_candidate), RIGHT_AGENT);
425 } else {
426 g_signal_handlers_disconnect_by_func (G_OBJECT(lagent), cb_agent_new_candidate,
427 LEFT_AGENT);
428 g_signal_handlers_disconnect_by_func (G_OBJECT(ragent), cb_agent_new_candidate,
429 RIGHT_AGENT);
432 data_received = FALSE;
434 nice_agent_attach_recv (lagent, global_ls_id, NICE_COMPONENT_TYPE_RTP,
435 g_main_loop_get_context(global_mainloop),
436 cb_nice_recv, LEFT_AGENT);
437 nice_agent_attach_recv (ragent, global_rs_id, NICE_COMPONENT_TYPE_RTP,
438 g_main_loop_get_context(global_mainloop),
439 cb_nice_recv, RIGHT_AGENT);
442 static void cleanup(NiceAgent *lagent, NiceAgent *ragent)
444 g_debug ("Cleaning up");
445 drop_stun_packets = FALSE;
446 nice_agent_remove_stream (lagent, global_ls_id);
447 nice_agent_remove_stream (ragent, global_rs_id);
450 static void standard_test(NiceAgent *lagent, NiceAgent *ragent)
452 g_debug ("test-dribblemode:%s", G_STRFUNC);
454 init_test (lagent, ragent, FALSE);
456 nice_agent_gather_candidates (lagent, global_ls_id);
457 g_main_loop_run (global_mainloop);
458 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
459 !lagent_candidate_gathering_done);
461 nice_agent_gather_candidates (ragent, global_rs_id);
462 if (!ragent_candidate_gathering_done) {
463 g_main_loop_run (global_mainloop);
464 g_assert (ragent_candidate_gathering_done);
467 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
469 g_debug ("Setting local candidates of ragent as remote candidates of lagent");
470 swap_candidates (ragent, global_rs_id,
471 lagent, global_ls_id,
472 TRUE);
474 g_main_loop_run (global_mainloop);
475 g_assert (global_lagent_state >= NICE_COMPONENT_STATE_CONNECTED &&
476 data_received);
478 g_debug ("Setting local candidates of lagent as remote candidates of ragent");
479 swap_candidates (lagent, global_ls_id,
480 ragent, global_rs_id,
481 FALSE);
482 g_main_loop_run (global_mainloop);
484 g_assert (lagent_candidate_gathering_done);
486 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
487 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
489 cleanup (lagent, ragent);
492 static void bad_credentials_test(NiceAgent *lagent, NiceAgent *ragent)
494 g_debug ("test-dribblemode:%s", G_STRFUNC);
496 init_test (lagent, ragent, FALSE);
498 nice_agent_set_remote_credentials (lagent, global_ls_id,
499 "wrong", "wrong");
500 nice_agent_set_remote_credentials (ragent, global_rs_id,
501 "wrong2", "wrong2");
503 nice_agent_gather_candidates (lagent, global_ls_id);
504 g_main_loop_run (global_mainloop);
505 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
506 !lagent_candidate_gathering_done);
508 nice_agent_gather_candidates (ragent, global_rs_id);
509 if (!ragent_candidate_gathering_done) {
510 g_main_loop_run (global_mainloop);
511 g_assert (ragent_candidate_gathering_done);
514 swap_candidates (ragent, global_rs_id,
515 lagent, global_ls_id,
516 FALSE);
517 g_main_loop_run (global_mainloop);
518 g_assert (global_lagent_state == NICE_COMPONENT_STATE_FAILED);
520 // Set the correct credentials and swap candidates
521 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
522 swap_candidates (ragent, global_rs_id,
523 lagent, global_ls_id,
524 FALSE);
526 swap_candidates (lagent, global_ls_id,
527 ragent, global_rs_id,
528 FALSE);
530 g_main_loop_run (global_mainloop);
532 g_assert (data_received);
533 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
534 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
536 // Wait for lagent to finish gathering candidates
537 g_main_loop_run (global_mainloop);
538 g_assert (lagent_candidate_gathering_done);
540 cleanup (lagent, ragent);
543 static void bad_candidate_test(NiceAgent *lagent,NiceAgent *ragent)
545 NiceCandidate *cand = NULL;
547 g_debug ("test-dribblemode:%s", G_STRFUNC);
549 init_test (lagent, ragent, FALSE);
551 nice_agent_gather_candidates (lagent, global_ls_id);
552 g_main_loop_run (global_mainloop);
553 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
554 !lagent_candidate_gathering_done);
556 nice_agent_gather_candidates (ragent, global_rs_id);
557 if (!ragent_candidate_gathering_done) {
558 g_main_loop_run (global_mainloop);
559 g_assert (ragent_candidate_gathering_done);
562 add_bad_candidate (lagent, global_ls_id, cand);
564 // lagent will finish candidate gathering causing this mainloop to quit
565 g_main_loop_run (global_mainloop);
567 // connchecks will fail causing this mainloop to quit
568 g_main_loop_run (global_mainloop);
570 g_assert (global_lagent_state == NICE_COMPONENT_STATE_FAILED &&
571 !data_received);
572 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
574 swap_candidates (ragent, global_rs_id,
575 lagent, global_ls_id,
576 FALSE);
578 swap_candidates (lagent, global_ls_id,
579 ragent, global_rs_id,
580 FALSE);
582 g_main_loop_run (global_mainloop);
584 g_assert (lagent_candidate_gathering_done);
586 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
587 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
589 cleanup (lagent, ragent);
592 static void new_candidate_test(NiceAgent *lagent, NiceAgent *ragent)
594 g_debug ("test-dribblemode:%s", G_STRFUNC);
596 init_test (lagent, ragent, TRUE);
597 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
599 nice_agent_gather_candidates (lagent, global_ls_id);
600 g_main_loop_run (global_mainloop);
601 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
602 !lagent_candidate_gathering_done);
604 nice_agent_gather_candidates (ragent, global_rs_id);
605 if (!ragent_candidate_gathering_done) {
606 g_main_loop_run (global_mainloop);
609 // Wait for data
610 g_main_loop_run (global_mainloop);
611 g_assert (data_received);
613 // Data arrived, signal STUN thread to send STUN response
614 g_mutex_lock (stun_mutex_ptr);
615 g_cond_signal (stun_signal_ptr);
616 g_mutex_unlock (stun_mutex_ptr);
618 // Wait for lagent to finish gathering candidates
619 g_main_loop_run (global_mainloop);
621 g_assert (lagent_candidate_gathering_done);
622 g_assert (ragent_candidate_gathering_done);
624 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
625 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
627 cleanup (lagent, ragent);
630 static void send_dummy_data(void)
632 int sockfd = listen_socket (4567);
633 struct sockaddr_in addr;
635 memset (&addr, 0, sizeof (addr));
636 addr.sin_family = AF_INET;
637 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
638 addr.sin_port = htons (IPPORT_STUN);
640 g_debug ("Sending dummy data to close STUN thread");
641 sendto (sockfd, "close socket", 12, 0,
642 (struct sockaddr *)&addr, sizeof (addr));
645 int main(void)
647 NiceAgent *lagent = NULL, *ragent = NULL;
648 GThread *stun_thread = NULL;
649 NiceAddress baseaddr;
651 g_type_init();
653 global_mainloop = g_main_loop_new (NULL, FALSE);
655 #if !GLIB_CHECK_VERSION(2,31,8)
656 g_thread_init (NULL);
657 stun_thread = g_thread_create (stun_thread_func,
658 global_mainloop,
659 TRUE, NULL);
660 stun_mutex_ptr = g_mutex_new ();
661 stun_signal_ptr = g_cond_new ();
662 #else
663 stun_thread = g_thread_new ("listen for STUN requests",
664 stun_thread_func, NULL);
665 #endif
667 // Once the the thread is forked, we want to listen for a signal
668 // that the socket was opened successfully
669 g_mutex_lock (stun_thread_mutex_ptr);
670 g_cond_wait (stun_thread_signal_ptr, stun_thread_mutex_ptr);
672 lagent = nice_agent_new (g_main_loop_get_context (global_mainloop),
673 NICE_COMPATIBILITY_RFC5245);
674 ragent = nice_agent_new (g_main_loop_get_context (global_mainloop),
675 NICE_COMPATIBILITY_RFC5245);
677 g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
678 g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
680 g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL);
681 g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL);
683 g_object_set (G_OBJECT (lagent), "stun-server", "127.0.0.1", NULL);
684 g_object_set (G_OBJECT (lagent), "stun-server-port", IPPORT_STUN, NULL);
686 g_object_set_data (G_OBJECT (lagent), "other-agent", ragent);
687 g_object_set_data (G_OBJECT (ragent), "other-agent", lagent);
689 g_assert (nice_address_set_from_string (&baseaddr, "127.0.0.1"));
690 nice_agent_add_local_address (lagent, &baseaddr);
691 nice_agent_add_local_address (ragent, &baseaddr);
693 g_signal_connect(G_OBJECT(lagent), "candidate-gathering-done",
694 G_CALLBACK(cb_candidate_gathering_done), LEFT_AGENT);
695 g_signal_connect(G_OBJECT(ragent), "candidate-gathering-done",
696 G_CALLBACK(cb_candidate_gathering_done), RIGHT_AGENT);
697 g_signal_connect(G_OBJECT(lagent), "component-state-changed",
698 G_CALLBACK(cb_component_state_changed), LEFT_AGENT);
699 g_signal_connect(G_OBJECT(ragent), "component-state-changed",
700 G_CALLBACK(cb_component_state_changed), RIGHT_AGENT);
702 standard_test (lagent, ragent);
703 bad_credentials_test (lagent, ragent);
704 bad_candidate_test (lagent, ragent);
705 new_candidate_test (lagent, ragent);
707 // Do this to make sure the STUN thread exits
708 exit_stun_thread = TRUE;
709 drop_stun_packets = TRUE;
710 send_dummy_data ();
712 g_object_unref (lagent);
713 g_object_unref (ragent);
715 g_thread_join (stun_thread);
716 #if !GLIB_CHECK_VERSION(2,31,8)
717 g_mutex_free (stun_mutex_ptr);
718 g_cond_free (stun_signal_ptr);
719 #endif
720 g_main_loop_unref (global_mainloop);
722 return 0;