GST_FLOW_WRONG_STATE -> GST_FLOW_FLUSHING
[sipe-libnice.git] / tests / test-new-dribble.c
blobadbe71d92c814f36c2fd0beb56bd4a56df7fd048
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 #else
64 static GMutex stun_mutex;
65 static GMutex *stun_mutex_ptr = &stun_mutex;
66 static GCond stun_signal;
67 static GCond *stun_signal_ptr = &stun_signal;
68 #endif
70 static GMainLoop *global_mainloop;
71 static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST;
72 static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST;
73 static gboolean exit_stun_thread = FALSE;
74 static gboolean lagent_candidate_gathering_done = FALSE;
75 static gboolean ragent_candidate_gathering_done = FALSE;
76 static guint global_ls_id, global_rs_id;
77 static gboolean data_received = FALSE;
78 static gboolean drop_stun_packets = FALSE;
80 static const uint16_t known_attributes[] = {
85 * Creates a listening socket
87 static int listen_socket (unsigned int port)
89 struct sockaddr_in addr;
90 int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
92 if (fd == -1) {
93 perror ("Error opening IP port");
94 return -1;
97 memset (&addr, 0, sizeof (addr));
98 addr.sin_family = AF_INET;
99 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
100 addr.sin_port = htons(port);
102 if (bind (fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in))) {
103 perror ("Error opening IP port");
104 goto error;
107 return fd;
109 error:
110 close (fd);
111 return -1;
114 static int dgram_process (int sock, StunAgent *oldagent, StunAgent *newagent)
116 struct sockaddr_storage addr;
117 socklen_t addr_len;
118 uint8_t buf[STUN_MAX_MESSAGE_SIZE];
119 size_t buf_len = 0;
120 size_t len = 0;
121 StunMessage request;
122 StunMessage response;
123 StunValidationStatus validation;
124 StunAgent *agent = NULL;
125 gint ret;
127 addr_len = sizeof (struct sockaddr_in);
129 recv_packet:
130 len = recvfrom (sock, buf, sizeof(buf), 0,
131 (struct sockaddr *)&addr, &addr_len);
133 if (drop_stun_packets) {
134 g_debug ("Dropping STUN packet as requested");
135 return -1;
138 if (len == (size_t)-1) {
139 return -1;
142 validation = stun_agent_validate (newagent, &request, buf, len, NULL, 0);
144 if (validation == STUN_VALIDATION_SUCCESS) {
145 agent = newagent;
146 } else {
147 validation = stun_agent_validate (oldagent, &request, buf, len, NULL, 0);
148 agent = oldagent;
151 /* Unknown attributes */
152 if (validation == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE) {
153 buf_len = stun_agent_build_unknown_attributes_error (agent, &response, buf,
154 sizeof (buf), &request);
155 goto send_buf;
158 /* Mal-formatted packets */
159 if (validation != STUN_VALIDATION_SUCCESS ||
160 stun_message_get_class (&request) != STUN_REQUEST) {
161 goto recv_packet;
164 switch (stun_message_get_method (&request)) {
165 case STUN_BINDING:
166 stun_agent_init_response (agent, &response, buf, sizeof (buf), &request);
167 if (stun_message_has_cookie (&request))
168 stun_message_append_xor_addr (&response,
169 STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
170 (struct sockaddr *)&addr, addr_len);
171 else
172 stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS,
173 (struct sockaddr *)&addr, addr_len);
174 break;
176 default:
177 if (!stun_agent_init_error (agent, &response, buf, sizeof (buf),
178 &request, STUN_ERROR_BAD_REQUEST)) {
179 g_debug ("STUN error message not initialized properly");
180 g_assert_not_reached();
184 buf_len = stun_agent_finish_message (agent, &response, NULL, 0);
186 send_buf:
187 g_main_loop_quit (global_mainloop);
188 g_debug ("Ready to send a STUN response");
189 g_assert (g_mutex_trylock (stun_mutex_ptr));
190 while (global_lagent_state < NICE_COMPONENT_STATE_CONNECTING) {
191 g_debug ("Waiting for signal. State is %d", global_lagent_state);
192 g_cond_wait (stun_signal_ptr, stun_mutex_ptr);
194 g_mutex_unlock (stun_mutex_ptr);
195 len = sendto (sock, buf, buf_len, 0,
196 (struct sockaddr *)&addr, addr_len);
197 g_debug ("STUN response sent");
198 drop_stun_packets = TRUE;
199 ret = (len < buf_len) ? -1 : 0;
200 return ret;
204 static gpointer stun_thread_func (const gpointer user_data)
206 StunAgent oldagent;
207 StunAgent newagent;
208 int sock;
209 int exit_code = -1;
211 sock = listen_socket (IPPORT_STUN);
213 if (sock == -1) {
214 g_assert_not_reached ();
217 stun_agent_init (&oldagent, known_attributes,
218 STUN_COMPATIBILITY_RFC3489, 0);
219 stun_agent_init (&newagent, known_attributes,
220 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
222 while (!exit_stun_thread) {
223 g_debug ("Ready to process next datagram");
224 dgram_process (sock, &oldagent, &newagent);
227 exit_code = close (sock);
228 g_thread_exit (GINT_TO_POINTER (exit_code));
229 return NULL;
232 static void set_credentials (NiceAgent *lagent, guint lstream,
233 NiceAgent *ragent, guint rstream)
235 gchar *ufrag = NULL, *password = NULL;
237 nice_agent_get_local_credentials (lagent, lstream, &ufrag, &password);
238 nice_agent_set_remote_credentials (ragent, rstream, ufrag, password);
240 g_free (ufrag);
241 g_free (password);
243 nice_agent_get_local_credentials (ragent, rstream, &ufrag, &password);
244 nice_agent_set_remote_credentials (lagent, lstream, ufrag, password);
246 g_free (ufrag);
247 g_free (password);
250 static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data)
252 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data);
254 if (GPOINTER_TO_UINT(data) == 1) {
255 g_debug ("lagent finished gathering candidates");
256 lagent_candidate_gathering_done = TRUE;
257 } else if (GPOINTER_TO_UINT(data) == 2) {
258 g_debug ("ragent finished gathering candidates");
259 ragent_candidate_gathering_done = TRUE;
261 g_main_loop_quit(global_mainloop);
264 static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
266 gint ret;
268 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data);
270 ret = strncmp ("0000", buf, 4);
271 if (ret == 0) {
272 ret = strncmp ("00001234567812345678", buf, 16);
273 g_assert (ret == 0);
275 g_debug ("test-dribblemode:%s: ragent recieved %d bytes : quit mainloop",
276 G_STRFUNC, len);
277 data_received = TRUE;
278 g_main_loop_quit (global_mainloop);
282 static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data)
284 gint ret;
286 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data);
288 if(GPOINTER_TO_UINT(data) == 1) {
289 global_lagent_state = state;
290 g_debug ("lagent state is %d", state);
291 } else if (GPOINTER_TO_UINT(data) == 2) {
292 g_debug ("ragent state is %d", state);
293 global_ragent_state = state;
296 if (GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_FAILED) {
297 g_debug ("Signalling STUN response since connchecks failed");
298 g_mutex_lock (stun_mutex_ptr);
299 g_cond_signal (stun_signal_ptr);
300 g_mutex_unlock (stun_mutex_ptr);
301 g_main_loop_quit (global_mainloop);
304 if(GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_READY) {
305 /* note: test payload send and receive */
306 ret = nice_agent_send (agent, stream_id, component_id,
307 20, "00001234567812345678");
308 g_debug ("Sent %d bytes", ret);
309 g_assert (ret == 20);
313 static void swap_candidates(NiceAgent *local, guint local_id, NiceAgent *remote, guint remote_id, gboolean signal_stun_reply)
315 GSList *cands = NULL;
317 g_debug ("test-dribblemode:%s", G_STRFUNC);
318 cands = nice_agent_get_local_candidates(local, local_id,
319 NICE_COMPONENT_TYPE_RTP);
320 g_assert(nice_agent_set_remote_candidates(remote, remote_id,
321 NICE_COMPONENT_TYPE_RTP, cands));
323 if (signal_stun_reply) {
324 g_mutex_lock (stun_mutex_ptr);
325 g_cond_signal (stun_signal_ptr);
326 g_mutex_unlock (stun_mutex_ptr);
329 g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free);
332 static void cb_agent_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer user_data)
334 NiceAgent *other = g_object_get_data (G_OBJECT (agent), "other-agent");
335 GSList *cands = nice_agent_get_local_candidates (agent, stream_id,
336 component_id);
337 GSList *i = NULL;
338 GSList *remote_cands = NULL;
339 NiceCandidate* temp;
340 gpointer tmp;
341 guint id;
343 g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data);
345 tmp = g_object_get_data (G_OBJECT (other), "id");
346 id = GPOINTER_TO_UINT (tmp);
348 for (i = cands; i; i = i->next) {
349 temp = (NiceCandidate*) i->data;
350 if (g_strcmp0(temp->foundation, foundation) == 0) {
351 g_debug ("Adding new local candidate to other agent's connchecks");
352 remote_cands = g_slist_prepend (remote_cands, nice_candidate_copy(temp));
353 g_assert (nice_agent_set_remote_candidates (other, id,
354 NICE_COMPONENT_TYPE_RTP,
355 remote_cands));
359 g_slist_free_full (remote_cands, (GDestroyNotify) nice_candidate_free);
360 g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free);
364 static void add_bad_candidate (NiceAgent *agent, guint stream_id, NiceCandidate *cand)
366 NiceAddress bad_addr;
367 GSList *cand_list = NULL;
369 g_assert (nice_address_set_from_string (&bad_addr, "172.1.0.1"));
371 cand = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
372 cand->stream_id = stream_id;
373 cand->component_id = NICE_COMPONENT_TYPE_RTP;
374 cand->addr = bad_addr;
376 nice_agent_get_local_credentials (agent, stream_id,
377 &cand->username, &cand->password);
378 cand_list = g_slist_prepend (cand_list, cand);
380 g_debug ("Adding buggy candidate to the agent %p", agent);
381 g_assert (nice_agent_set_remote_candidates (agent, stream_id,
382 NICE_COMPONENT_TYPE_RTP,
383 cand_list));
385 g_slist_free_full (cand_list, (GDestroyNotify) nice_candidate_free);
389 static void init_test(NiceAgent *lagent, NiceAgent *ragent, gboolean connect_new_candidate_signal)
391 global_lagent_state = NICE_COMPONENT_STATE_DISCONNECTED;
392 global_ragent_state = NICE_COMPONENT_STATE_DISCONNECTED;
394 lagent_candidate_gathering_done = FALSE;
395 ragent_candidate_gathering_done = FALSE;
397 global_ls_id = nice_agent_add_stream (lagent, 1);
398 global_rs_id = nice_agent_add_stream (ragent, 1);
400 g_assert (global_ls_id > 0);
401 g_assert (global_rs_id > 0);
403 g_debug ("lagent stream is : %d and ragent stream is %d",
404 global_ls_id,
405 global_rs_id);
407 g_object_set_data (G_OBJECT (lagent), "id", GUINT_TO_POINTER (global_ls_id));
408 g_object_set_data (G_OBJECT (ragent), "id", GUINT_TO_POINTER (global_rs_id));
410 if (connect_new_candidate_signal) {
411 g_signal_connect (G_OBJECT(lagent), "new-candidate",
412 G_CALLBACK(cb_agent_new_candidate), LEFT_AGENT);
413 g_signal_connect (G_OBJECT(ragent), "new-candidate",
414 G_CALLBACK(cb_agent_new_candidate), RIGHT_AGENT);
415 } else {
416 g_signal_handlers_disconnect_by_func (G_OBJECT(lagent), cb_agent_new_candidate,
417 LEFT_AGENT);
418 g_signal_handlers_disconnect_by_func (G_OBJECT(ragent), cb_agent_new_candidate,
419 RIGHT_AGENT);
422 data_received = FALSE;
424 nice_agent_attach_recv (lagent, global_ls_id, NICE_COMPONENT_TYPE_RTP,
425 g_main_loop_get_context(global_mainloop),
426 cb_nice_recv, LEFT_AGENT);
427 nice_agent_attach_recv (ragent, global_rs_id, NICE_COMPONENT_TYPE_RTP,
428 g_main_loop_get_context(global_mainloop),
429 cb_nice_recv, RIGHT_AGENT);
432 static void cleanup(NiceAgent *lagent, NiceAgent *ragent)
434 g_debug ("Cleaning up");
435 drop_stun_packets = FALSE;
436 nice_agent_remove_stream (lagent, global_ls_id);
437 nice_agent_remove_stream (ragent, global_rs_id);
440 static void standard_test(NiceAgent *lagent, NiceAgent *ragent)
442 g_debug ("test-dribblemode:%s", G_STRFUNC);
444 init_test (lagent, ragent, FALSE);
446 nice_agent_gather_candidates (lagent, global_ls_id);
447 g_main_loop_run (global_mainloop);
448 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
449 !lagent_candidate_gathering_done);
451 nice_agent_gather_candidates (ragent, global_rs_id);
452 if (!ragent_candidate_gathering_done) {
453 g_main_loop_run (global_mainloop);
454 g_assert (ragent_candidate_gathering_done);
457 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
459 g_debug ("Setting local candidates of ragent as remote candidates of lagent");
460 swap_candidates (ragent, global_rs_id,
461 lagent, global_ls_id,
462 TRUE);
464 g_main_loop_run (global_mainloop);
465 g_assert (global_lagent_state >= NICE_COMPONENT_STATE_CONNECTED &&
466 data_received);
468 g_debug ("Setting local candidates of lagent as remote candidates of ragent");
469 swap_candidates (lagent, global_ls_id,
470 ragent, global_rs_id,
471 FALSE);
472 g_main_loop_run (global_mainloop);
474 g_assert (lagent_candidate_gathering_done);
476 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
477 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
479 cleanup (lagent, ragent);
482 static void bad_credentials_test(NiceAgent *lagent, NiceAgent *ragent)
484 g_debug ("test-dribblemode:%s", G_STRFUNC);
486 init_test (lagent, ragent, FALSE);
488 nice_agent_set_remote_credentials (lagent, global_ls_id,
489 "wrong", "wrong");
490 nice_agent_set_remote_credentials (ragent, global_rs_id,
491 "wrong2", "wrong2");
493 nice_agent_gather_candidates (lagent, global_ls_id);
494 g_main_loop_run (global_mainloop);
495 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
496 !lagent_candidate_gathering_done);
498 nice_agent_gather_candidates (ragent, global_rs_id);
499 if (!ragent_candidate_gathering_done) {
500 g_main_loop_run (global_mainloop);
501 g_assert (ragent_candidate_gathering_done);
504 swap_candidates (ragent, global_rs_id,
505 lagent, global_ls_id,
506 FALSE);
507 g_main_loop_run (global_mainloop);
508 g_assert (global_lagent_state == NICE_COMPONENT_STATE_FAILED);
510 // Set the correct credentials and swap candidates
511 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
512 swap_candidates (ragent, global_rs_id,
513 lagent, global_ls_id,
514 FALSE);
516 swap_candidates (lagent, global_ls_id,
517 ragent, global_rs_id,
518 FALSE);
520 g_main_loop_run (global_mainloop);
522 g_assert (data_received);
523 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
524 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
526 // Wait for lagent to finish gathering candidates
527 g_main_loop_run (global_mainloop);
528 g_assert (lagent_candidate_gathering_done);
530 cleanup (lagent, ragent);
533 static void bad_candidate_test(NiceAgent *lagent,NiceAgent *ragent)
535 NiceCandidate *cand = NULL;
537 g_debug ("test-dribblemode:%s", G_STRFUNC);
539 init_test (lagent, ragent, FALSE);
541 nice_agent_gather_candidates (lagent, global_ls_id);
542 g_main_loop_run (global_mainloop);
543 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
544 !lagent_candidate_gathering_done);
546 nice_agent_gather_candidates (ragent, global_rs_id);
547 if (!ragent_candidate_gathering_done) {
548 g_main_loop_run (global_mainloop);
549 g_assert (ragent_candidate_gathering_done);
552 add_bad_candidate (lagent, global_ls_id, cand);
554 // lagent will finish candidate gathering causing this mainloop to quit
555 g_main_loop_run (global_mainloop);
557 // connchecks will fail causing this mainloop to quit
558 g_main_loop_run (global_mainloop);
560 g_assert (global_lagent_state == NICE_COMPONENT_STATE_FAILED &&
561 !data_received);
562 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
564 swap_candidates (ragent, global_rs_id,
565 lagent, global_ls_id,
566 FALSE);
568 swap_candidates (lagent, global_ls_id,
569 ragent, global_rs_id,
570 FALSE);
572 g_main_loop_run (global_mainloop);
574 g_assert (lagent_candidate_gathering_done);
576 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
577 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
579 cleanup (lagent, ragent);
582 static void new_candidate_test(NiceAgent *lagent, NiceAgent *ragent)
584 g_debug ("test-dribblemode:%s", G_STRFUNC);
586 init_test (lagent, ragent, TRUE);
587 set_credentials (lagent, global_ls_id, ragent, global_rs_id);
589 nice_agent_gather_candidates (lagent, global_ls_id);
590 g_main_loop_run (global_mainloop);
591 g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING &&
592 !lagent_candidate_gathering_done);
594 nice_agent_gather_candidates (ragent, global_rs_id);
595 if (!ragent_candidate_gathering_done) {
596 g_main_loop_run (global_mainloop);
599 // Wait for data
600 g_main_loop_run (global_mainloop);
601 g_assert (data_received);
603 // Data arrived, signal STUN thread to send STUN response
604 g_mutex_lock (stun_mutex_ptr);
605 g_cond_signal (stun_signal_ptr);
606 g_mutex_unlock (stun_mutex_ptr);
608 // Wait for lagent to finish gathering candidates
609 g_main_loop_run (global_mainloop);
611 g_assert (lagent_candidate_gathering_done);
612 g_assert (ragent_candidate_gathering_done);
614 g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
615 g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED);
617 cleanup (lagent, ragent);
620 static void send_dummy_data(void)
622 int sockfd = listen_socket (4567);
623 struct sockaddr_in addr;
625 memset (&addr, 0, sizeof (addr));
626 addr.sin_family = AF_INET;
627 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
628 addr.sin_port = htons (IPPORT_STUN);
630 g_debug ("Sending dummy data to close STUN thread");
631 sendto (sockfd, "close socket", 12, 0,
632 (struct sockaddr *)&addr, sizeof (addr));
635 int main(void)
637 NiceAgent *lagent = NULL, *ragent = NULL;
638 GThread *stun_thread = NULL;
639 NiceAddress baseaddr;
641 g_type_init();
643 global_mainloop = g_main_loop_new (NULL, FALSE);
645 #if !GLIB_CHECK_VERSION(2,31,8)
646 g_thread_init (NULL);
647 stun_thread = g_thread_create (stun_thread_func,
648 global_mainloop,
649 TRUE, NULL);
650 stun_mutex_ptr = g_mutex_new ();
651 stun_signal_ptr = g_cond_new ();
652 #else
653 stun_thread = g_thread_new ("listen for STUN requests",
654 stun_thread_func, NULL);
655 #endif
657 lagent = nice_agent_new (g_main_loop_get_context (global_mainloop),
658 NICE_COMPATIBILITY_RFC5245);
659 ragent = nice_agent_new (g_main_loop_get_context (global_mainloop),
660 NICE_COMPATIBILITY_RFC5245);
662 g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
663 g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
665 g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL);
666 g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL);
668 g_object_set (G_OBJECT (lagent), "stun-server", "127.0.0.1", NULL);
669 g_object_set (G_OBJECT (lagent), "stun-server-port", IPPORT_STUN, NULL);
671 g_object_set_data (G_OBJECT (lagent), "other-agent", ragent);
672 g_object_set_data (G_OBJECT (ragent), "other-agent", lagent);
674 g_assert (nice_address_set_from_string (&baseaddr, "127.0.0.1"));
675 nice_agent_add_local_address (lagent, &baseaddr);
676 nice_agent_add_local_address (ragent, &baseaddr);
678 g_signal_connect(G_OBJECT(lagent), "candidate-gathering-done",
679 G_CALLBACK(cb_candidate_gathering_done), LEFT_AGENT);
680 g_signal_connect(G_OBJECT(ragent), "candidate-gathering-done",
681 G_CALLBACK(cb_candidate_gathering_done), RIGHT_AGENT);
682 g_signal_connect(G_OBJECT(lagent), "component-state-changed",
683 G_CALLBACK(cb_component_state_changed), LEFT_AGENT);
684 g_signal_connect(G_OBJECT(ragent), "component-state-changed",
685 G_CALLBACK(cb_component_state_changed), RIGHT_AGENT);
687 standard_test (lagent, ragent);
688 bad_credentials_test (lagent, ragent);
689 bad_candidate_test (lagent, ragent);
690 new_candidate_test (lagent, ragent);
692 // Do this to make sure the STUN thread exits
693 exit_stun_thread = TRUE;
694 drop_stun_packets = TRUE;
695 send_dummy_data ();
697 g_object_unref (lagent);
698 g_object_unref (ragent);
700 g_thread_join (stun_thread);
701 #if !GLIB_CHECK_VERSION(2,31,8)
702 g_mutex_free (stun_mutex_ptr);
703 g_cond_free (stun_signal_ptr);
704 #endif
705 g_main_loop_unref (global_mainloop);
707 return 0;