blob: f176dc5b23d21929689032e88930779d8820ddd6 [file] [log] [blame]
Benny Prijonofb9d9872007-03-21 22:05:58 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "test.h"
20
Benny Prijono7e0d52c2007-03-26 13:25:07 +000021#define THIS_FILE "ice_test.c"
Benny Prijonofb9d9872007-03-21 22:05:58 +000022
23
24struct ice_data
25{
Benny Prijono2532b9d2007-03-22 01:16:37 +000026 const char *obj_name;
Benny Prijonofb9d9872007-03-21 22:05:58 +000027 pj_bool_t complete;
28 pj_status_t err_code;
29 unsigned rx_rtp_cnt;
30 unsigned rx_rtcp_cnt;
Benny Prijono2532b9d2007-03-22 01:16:37 +000031
Benny Prijonofd7f1472007-03-22 11:59:03 +000032 unsigned rx_rtp_count;
33 char last_rx_rtp_data[32];
34 unsigned rx_rtcp_count;
35 char last_rx_rtcp_data[32];
Benny Prijonofb9d9872007-03-21 22:05:58 +000036};
37
38static pj_stun_config stun_cfg;
39
Benny Prijonoa6bd7582007-03-28 15:49:48 +000040static void on_ice_complete(pj_ice_strans *icest,
Benny Prijonofb9d9872007-03-21 22:05:58 +000041 pj_status_t status)
42{
Benny Prijonoff49ab72007-03-22 21:00:53 +000043 struct ice_data *id = (struct ice_data*) icest->user_data;
Benny Prijonofb9d9872007-03-21 22:05:58 +000044 id->complete = PJ_TRUE;
45 id->err_code = status;
Benny Prijono7e0d52c2007-03-26 13:25:07 +000046 PJ_LOG(3,(THIS_FILE, " ICE %s complete %s", id->obj_name,
Benny Prijono2532b9d2007-03-22 01:16:37 +000047 (status==PJ_SUCCESS ? "successfully" : "with failure")));
Benny Prijonofb9d9872007-03-21 22:05:58 +000048}
49
50
Benny Prijonoa6bd7582007-03-28 15:49:48 +000051static void on_rx_data(pj_ice_strans *icest, unsigned comp_id,
Benny Prijonofb9d9872007-03-21 22:05:58 +000052 void *pkt, pj_size_t size,
53 const pj_sockaddr_t *src_addr,
54 unsigned src_addr_len)
55{
Benny Prijonoff49ab72007-03-22 21:00:53 +000056 struct ice_data *id = (struct ice_data*) icest->user_data;
Benny Prijono2532b9d2007-03-22 01:16:37 +000057
Benny Prijonoff49ab72007-03-22 21:00:53 +000058 if (comp_id == 1) {
59 id->rx_rtp_cnt++;
60 pj_memcpy(id->last_rx_rtp_data, pkt, size);
61 id->last_rx_rtp_data[size] = '\0';
62 } else if (comp_id == 2) {
63 id->rx_rtcp_cnt++;
64 pj_memcpy(id->last_rx_rtcp_data, pkt, size);
65 id->last_rx_rtcp_data[size] = '\0';
66 } else {
67 pj_assert(!"Invalid component ID");
68 }
Benny Prijono2532b9d2007-03-22 01:16:37 +000069
70 PJ_UNUSED_ARG(src_addr);
71 PJ_UNUSED_ARG(src_addr_len);
Benny Prijonofb9d9872007-03-21 22:05:58 +000072}
73
74
75static void handle_events(unsigned msec_timeout)
76{
77 pj_time_val delay;
78
79 pj_timer_heap_poll(stun_cfg.timer_heap, NULL);
80
81 delay.sec = 0;
82 delay.msec = msec_timeout;
83 pj_time_val_normalize(&delay);
84
85 pj_ioqueue_poll(stun_cfg.ioqueue, &delay);
86}
87
88
89/* Basic create and destroy test */
90static int ice_basic_create_destroy_test()
91{
Benny Prijonoa6bd7582007-03-28 15:49:48 +000092 pj_ice_strans *im;
93 pj_ice_strans_cb icest_cb;
Benny Prijonofb9d9872007-03-21 22:05:58 +000094 pj_status_t status;
95
96 PJ_LOG(3,(THIS_FILE, "...basic create/destroy"));
97
Benny Prijonoff49ab72007-03-22 21:00:53 +000098 pj_bzero(&icest_cb, sizeof(icest_cb));
99 icest_cb.on_ice_complete = &on_ice_complete;
100 icest_cb.on_rx_data = &on_rx_data;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000101
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000102 status = pj_ice_strans_create(&stun_cfg, "icetest", 2, NULL, &icest_cb, &im);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000103 if (status != PJ_SUCCESS)
104 return -10;
105
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000106 pj_ice_strans_destroy(im);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000107
108 return 0;
109}
110
111
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000112static pj_status_t start_ice(pj_ice_strans *ist, pj_ice_strans *remote)
Benny Prijonofb9d9872007-03-21 22:05:58 +0000113{
Benny Prijonoff49ab72007-03-22 21:00:53 +0000114 unsigned count;
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000115 pj_ice_sess_cand cand[PJ_ICE_MAX_CAND];
Benny Prijonofb9d9872007-03-21 22:05:58 +0000116 pj_status_t status;
117
Benny Prijonoff49ab72007-03-22 21:00:53 +0000118 count = PJ_ARRAY_SIZE(cand);
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000119 status = pj_ice_strans_enum_cands(remote, &count, cand);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000120 if (status != PJ_SUCCESS)
121 return status;
122
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000123 return pj_ice_strans_start_ice(ist, &remote->ice->rx_ufrag, &remote->ice->rx_pass,
Benny Prijonoff49ab72007-03-22 21:00:53 +0000124 count, cand);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000125}
126
127
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000128struct dummy_cand
129{
130 unsigned comp_id;
131 pj_ice_cand_type type;
132 const char *addr;
133 unsigned port;
134};
135
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000136static int init_ice_st(pj_ice_strans *ice_st,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000137 pj_bool_t add_valid_comp,
138 unsigned dummy_cnt,
139 struct dummy_cand cand[])
140{
141 pj_str_t a;
142 pj_status_t status;
143 unsigned i;
144
145 /* Create components */
146 for (i=0; i<ice_st->comp_cnt; ++i) {
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000147 status = pj_ice_strans_create_comp(ice_st, i+1, PJ_ICE_ST_OPT_DONT_ADD_CAND, NULL);
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000148 if (status != PJ_SUCCESS)
149 return -21;
150 }
151
152 /* Add dummy candidates */
153 for (i=0; i<dummy_cnt; ++i) {
154 pj_sockaddr_in addr;
155
156 pj_sockaddr_in_init(&addr, pj_cstr(&a, cand[i].addr), (pj_uint16_t)cand[i].port);
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000157 status = pj_ice_strans_add_cand(ice_st, cand[i].comp_id, cand[i].type,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000158 65535, &addr, PJ_FALSE);
159 if (status != PJ_SUCCESS)
160 return -22;
161 }
162
163 /* Add the real candidate */
164 if (add_valid_comp) {
165 for (i=0; i<ice_st->comp_cnt; ++i) {
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000166 status = pj_ice_strans_add_cand(ice_st, i+1, PJ_ICE_CAND_TYPE_HOST, 65535,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000167 &ice_st->comp[i]->local_addr.ipv4, PJ_TRUE);
168 if (status != PJ_SUCCESS)
169 return -23;
170 }
171 }
172
173 return 0;
174}
175
176
177/* When ICE completes, both agents should agree on the same candidate pair.
178 * Check that the remote address selected by agent1 is equal to the
179 * local address of selected by agent 2.
180 */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000181static int verify_address(pj_ice_strans *agent1, pj_ice_strans *agent2,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000182 unsigned comp_id)
183{
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000184 pj_ice_sess_cand *rcand, *lcand;
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000185 int lcand_id;
186
187 if (agent1->ice->comp[comp_id-1].valid_check == NULL) {
188 PJ_LOG(3,(THIS_FILE, "....error: valid_check not set for comp_id %d", comp_id));
189 return -60;
190 }
191
192 /* Get default remote candidate of agent 1 */
193 rcand = agent1->ice->comp[comp_id-1].valid_check->rcand;
194
195 /* Get default local candidate of agent 2 */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000196 pj_ice_sess_find_default_cand(agent2->ice, comp_id, &lcand_id);
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000197 if (lcand_id < 0)
198 return -62;
199
200 lcand = &agent2->ice->lcand[lcand_id];
201
202 if (pj_memcmp(&rcand->addr, &lcand->addr, sizeof(pj_sockaddr_in))!=0) {
203 PJ_LOG(3,(THIS_FILE, "....error: the selected addresses are incorrect for comp_id %d", comp_id));
204 return -64;
205 }
206
207 return 0;
208}
209
Benny Prijonoff49ab72007-03-22 21:00:53 +0000210
Benny Prijono2532b9d2007-03-22 01:16:37 +0000211/* Perform ICE test with the following parameters:
212 *
213 * - title: The title of the test
214 * - ocand_cnt,
215 * ocand Additional candidates to be added to offerer
216 * - acand_cnt,
217 * acand Additional candidates to be added to answerer
218 *
Benny Prijonofd7f1472007-03-22 11:59:03 +0000219 * The additional candidates are normally invalid candidates, meaning
220 * they won't be reachable by the agents. They are used to "confuse"
Benny Prijono2532b9d2007-03-22 01:16:37 +0000221 * ICE processing.
222 */
223static int perform_ice_test(const char *title,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000224 pj_bool_t expected_success,
225 unsigned comp_cnt,
226 pj_bool_t add_valid_comp,
Benny Prijonofd7f1472007-03-22 11:59:03 +0000227 unsigned wait_before_send,
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000228 unsigned max_total_time,
229 unsigned ocand_cnt,
230 struct dummy_cand ocand[],
231 unsigned acand_cnt,
232 struct dummy_cand acand[])
Benny Prijonofb9d9872007-03-21 22:05:58 +0000233{
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000234 pj_ice_strans *im1, *im2;
235 pj_ice_strans_cb icest_cb;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000236 struct ice_data *id1, *id2;
Benny Prijono2532b9d2007-03-22 01:16:37 +0000237 pj_timestamp t_start, t_end;
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000238 unsigned i;
Benny Prijonofd7f1472007-03-22 11:59:03 +0000239 pj_str_t data_from_offerer, data_from_answerer;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000240 pj_status_t status;
241
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000242#define CHECK_COMPLETE() if (id1->complete && id2->complete) { \
243 if (t_end.u32.lo==0) pj_get_timestamp(&t_end); \
244 } else {}
245
Benny Prijono2532b9d2007-03-22 01:16:37 +0000246 PJ_LOG(3,(THIS_FILE, "...%s", title));
Benny Prijonofb9d9872007-03-21 22:05:58 +0000247
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000248 pj_bzero(&t_end, sizeof(t_end));
249
Benny Prijonoff49ab72007-03-22 21:00:53 +0000250 pj_bzero(&icest_cb, sizeof(icest_cb));
251 icest_cb.on_ice_complete = &on_ice_complete;
252 icest_cb.on_rx_data = &on_rx_data;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000253
254 /* Create first ICE */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000255 status = pj_ice_strans_create(&stun_cfg, "offerer", comp_cnt, NULL, &icest_cb, &im1);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000256 if (status != PJ_SUCCESS)
257 return -20;
258
259 id1 = PJ_POOL_ZALLOC_T(im1->pool, struct ice_data);
Benny Prijono2532b9d2007-03-22 01:16:37 +0000260 id1->obj_name = "offerer";
Benny Prijonofb9d9872007-03-21 22:05:58 +0000261 im1->user_data = id1;
262
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000263 /* Init components */
264 status = init_ice_st(im1, add_valid_comp, ocand_cnt, ocand);
265 if (status != 0)
266 return status;
Benny Prijono2532b9d2007-03-22 01:16:37 +0000267
Benny Prijonofb9d9872007-03-21 22:05:58 +0000268 /* Create second ICE */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000269 status = pj_ice_strans_create(&stun_cfg, "answerer", comp_cnt, NULL, &icest_cb, &im2);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000270 if (status != PJ_SUCCESS)
271 return -25;
272
273 id2 = PJ_POOL_ZALLOC_T(im2->pool, struct ice_data);
Benny Prijono2532b9d2007-03-22 01:16:37 +0000274 id2->obj_name = "answerer";
Benny Prijonofb9d9872007-03-21 22:05:58 +0000275 im2->user_data = id2;
276
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000277 /* Init components */
278 status = init_ice_st(im2, add_valid_comp, acand_cnt, acand);
279 if (status != 0)
280 return status;
Benny Prijono2532b9d2007-03-22 01:16:37 +0000281
Benny Prijonofb9d9872007-03-21 22:05:58 +0000282
Benny Prijonoff49ab72007-03-22 21:00:53 +0000283 /* Init ICE on im1 */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000284 status = pj_ice_strans_init_ice(im1, PJ_ICE_SESS_ROLE_CONTROLLING, NULL, NULL);
Benny Prijonoff49ab72007-03-22 21:00:53 +0000285 if (status != PJ_SUCCESS)
286 return -29;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000287
Benny Prijonoff49ab72007-03-22 21:00:53 +0000288 /* Init ICE on im2 */
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000289 status = pj_ice_strans_init_ice(im2, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL);
Benny Prijonoff49ab72007-03-22 21:00:53 +0000290 if (status != PJ_SUCCESS)
291 return -29;
292
293 /* Start ICE on im2 */
294 status = start_ice(im2, im1);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000295 if (status != PJ_SUCCESS)
296 return -30;
297
Benny Prijonoff49ab72007-03-22 21:00:53 +0000298 /* Start ICE on im1 */
299 status = start_ice(im1, im2);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000300 if (status != PJ_SUCCESS)
301 return -35;
302
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000303 /* Apply delay to let other checks commence */
304 pj_thread_sleep(40);
305
Benny Prijono2532b9d2007-03-22 01:16:37 +0000306 /* Mark start time */
307 pj_get_timestamp(&t_start);
308
Benny Prijonofd7f1472007-03-22 11:59:03 +0000309 /* Poll for wait_before_send msecs before we send the first data */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000310 if (expected_success) {
311 for (;;) {
312 pj_timestamp t_now;
Benny Prijonofd7f1472007-03-22 11:59:03 +0000313
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000314 handle_events(1);
Benny Prijonofd7f1472007-03-22 11:59:03 +0000315
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000316 CHECK_COMPLETE();
317
318 pj_get_timestamp(&t_now);
319 if (pj_elapsed_msec(&t_start, &t_now) >= wait_before_send)
320 break;
321 }
322
323 /* Send data. It must be successful! */
324 data_from_offerer = pj_str("from offerer");
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000325 status = pj_ice_sess_send_data(im1->ice, 1, data_from_offerer.ptr, data_from_offerer.slen);
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000326 if (status != PJ_SUCCESS)
327 return -47;
328
329 data_from_answerer = pj_str("from answerer");
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000330 status = pj_ice_sess_send_data(im2->ice, 1, data_from_answerer.ptr, data_from_answerer.slen);
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000331 if (status != PJ_SUCCESS)
332 return -48;
333
334 /* Poll to allow data to be received */
335 for (;;) {
336 pj_timestamp t_now;
337 handle_events(1);
338 CHECK_COMPLETE();
339 pj_get_timestamp(&t_now);
340 if (pj_elapsed_msec(&t_start, &t_now) >= (wait_before_send + 200))
341 break;
342 }
Benny Prijonofd7f1472007-03-22 11:59:03 +0000343 }
344
Benny Prijonofb9d9872007-03-21 22:05:58 +0000345 /* Just wait until both completes, or timed out */
Benny Prijono2532b9d2007-03-22 01:16:37 +0000346 while (!id1->complete || !id2->complete) {
347 pj_timestamp t_now;
348
Benny Prijonofb9d9872007-03-21 22:05:58 +0000349 handle_events(1);
350
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000351 CHECK_COMPLETE();
Benny Prijono2532b9d2007-03-22 01:16:37 +0000352 pj_get_timestamp(&t_now);
Benny Prijonofd7f1472007-03-22 11:59:03 +0000353 if (pj_elapsed_msec(&t_start, &t_now) >= max_total_time) {
Benny Prijono2532b9d2007-03-22 01:16:37 +0000354 PJ_LOG(3,(THIS_FILE, "....error: timed-out"));
355 return -50;
356 }
357 }
Benny Prijonofb9d9872007-03-21 22:05:58 +0000358
Benny Prijono2532b9d2007-03-22 01:16:37 +0000359 /* Mark end-time */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000360 CHECK_COMPLETE();
361
362 /* If expected to fail, then just check that both fail */
363 if (!expected_success) {
364 /* Check status */
365 if (id1->err_code == PJ_SUCCESS)
366 return -51;
367 if (id2->err_code == PJ_SUCCESS)
368 return -52;
369 goto on_return;
370 }
Benny Prijono2532b9d2007-03-22 01:16:37 +0000371
372 /* Check status */
373 if (id1->err_code != PJ_SUCCESS)
374 return -53;
375 if (id2->err_code != PJ_SUCCESS)
376 return -56;
377
378 /* Verify that offerer gets answerer's transport address */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000379 for (i=0; i<comp_cnt; ++i) {
380 status = verify_address(im1, im2, i+1);
381 if (status != 0)
382 return status;
Benny Prijono2532b9d2007-03-22 01:16:37 +0000383 }
384
385 /* And the other way around */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000386 for (i=0; i<comp_cnt; ++i) {
387 status = verify_address(im2, im1, i+1);
388 if (status != 0)
389 return status;
Benny Prijono2532b9d2007-03-22 01:16:37 +0000390 }
391
Benny Prijonofd7f1472007-03-22 11:59:03 +0000392 /* Check that data is received in offerer */
393 if (id1->rx_rtp_cnt != 1) {
394 PJ_LOG(3,(THIS_FILE, "....error: data not received in offerer"));
395 return -80;
396 }
397 if (pj_strcmp2(&data_from_answerer, id1->last_rx_rtp_data) != 0) {
398 PJ_LOG(3,(THIS_FILE, "....error: data mismatch in offerer"));
399 return -82;
400 }
401
402 /* And the same in answerer */
403 if (id2->rx_rtp_cnt != 1) {
404 PJ_LOG(3,(THIS_FILE, "....error: data not received in answerer"));
405 return -84;
406 }
407 if (pj_strcmp2(&data_from_offerer, id2->last_rx_rtp_data) != 0) {
408 PJ_LOG(3,(THIS_FILE, "....error: data mismatch in answerer"));
409 return -82;
410 }
411
412
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000413on_return:
414
Benny Prijono2532b9d2007-03-22 01:16:37 +0000415 /* Done */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000416 PJ_LOG(3,(THIS_FILE, "....success: ICE completed in %d msec, waiting..",
Benny Prijono2532b9d2007-03-22 01:16:37 +0000417 pj_elapsed_msec(&t_start, &t_end)));
418
419 /* Wait for some more time */
Benny Prijono2532b9d2007-03-22 01:16:37 +0000420 for (;;) {
421 pj_timestamp t_now;
422
423 pj_get_timestamp(&t_now);
Benny Prijonofd7f1472007-03-22 11:59:03 +0000424 if (pj_elapsed_msec(&t_start, &t_now) > max_total_time)
Benny Prijono2532b9d2007-03-22 01:16:37 +0000425 break;
426
427 handle_events(1);
428 }
429
430
Benny Prijonoa6bd7582007-03-28 15:49:48 +0000431 pj_ice_strans_destroy(im1);
432 pj_ice_strans_destroy(im2);
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000433 handle_events(100);
Benny Prijono2532b9d2007-03-22 01:16:37 +0000434 return 0;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000435}
436
437
438int ice_test(void)
439{
440 int rc = 0;
441 pj_pool_t *pool;
442 pj_ioqueue_t *ioqueue;
443 pj_timer_heap_t *timer_heap;
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000444 enum { D1=500, D2=5000, D3=15000 };
445 struct dummy_cand ocand[] =
446 {
447 {1, PJ_ICE_CAND_TYPE_SRFLX, "127.1.1.1", 65534 },
448 {2, PJ_ICE_CAND_TYPE_SRFLX, "127.1.1.1", 65535 },
449 };
450 struct dummy_cand acand[] =
451 {
452 {1, PJ_ICE_CAND_TYPE_SRFLX, "127.2.2.2", 65534 },
453 {2, PJ_ICE_CAND_TYPE_SRFLX, "127.2.2.2", 65535 },
454 };
Benny Prijono2532b9d2007-03-22 01:16:37 +0000455
Benny Prijonofb9d9872007-03-21 22:05:58 +0000456 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
457 pj_ioqueue_create(pool, 12, &ioqueue);
458 pj_timer_heap_create(pool, 100, &timer_heap);
459
460 pj_stun_config_init(&stun_cfg, mem, 0, ioqueue, timer_heap);
461
Benny Prijonofd70c9b2007-03-27 11:00:38 +0000462#if 1
463 pj_log_set_level(5);
464#endif
465
466 goto test;
Benny Prijonofb9d9872007-03-21 22:05:58 +0000467
Benny Prijono2532b9d2007-03-22 01:16:37 +0000468 /* Basic create/destroy */
Benny Prijonofb9d9872007-03-21 22:05:58 +0000469 rc = ice_basic_create_destroy_test();
470 if (rc != 0)
471 goto on_return;
472
Benny Prijono2532b9d2007-03-22 01:16:37 +0000473 /* Direct communication */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000474 rc = perform_ice_test("Simple test (1 component)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 0, NULL, 0, NULL);
475 if (rc != 0)
476 goto on_return;
477
478 /* Failure case (all checks fail) */
479 rc = perform_ice_test("Failure case (all checks fail)", PJ_FALSE, 1, PJ_FALSE, D3, D3, 1, ocand, 1, acand);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000480 if (rc != 0)
481 goto on_return;
482
Benny Prijono2532b9d2007-03-22 01:16:37 +0000483 /* Direct communication with invalid address */
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000484 rc = perform_ice_test("With 1 unreachable address", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 0, NULL);
485 if (rc != 0)
486 goto on_return;
487
488 /* Direct communication with invalid address */
489 rc = perform_ice_test("With 2 unreachable addresses (one each)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 1, acand);
Benny Prijono2532b9d2007-03-22 01:16:37 +0000490 if (rc != 0)
491 goto on_return;
492
Benny Prijonofd7f1472007-03-22 11:59:03 +0000493 /* Direct communication with two components */
Benny Prijonofd70c9b2007-03-27 11:00:38 +0000494test:
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000495 rc = perform_ice_test("With two components (RTP and RTCP)", PJ_TRUE, 2, PJ_TRUE, D1, D2, 0, NULL, 0, NULL);
496 if (rc != 0)
497 goto on_return;
498
Benny Prijonofd70c9b2007-03-27 11:00:38 +0000499 goto on_return;
500
Benny Prijono7e0d52c2007-03-26 13:25:07 +0000501 /* Direct communication with mismatch number of components */
502
503 /* Direct communication with 2 components and 2 invalid address */
504 rc = perform_ice_test("With 2 two components and 2 unreachable address", PJ_TRUE, 2, PJ_TRUE, D1, D2, 1, ocand, 1, acand);
Benny Prijonofd7f1472007-03-22 11:59:03 +0000505 if (rc != 0)
506 goto on_return;
507
508
Benny Prijono2532b9d2007-03-22 01:16:37 +0000509
Benny Prijonofb9d9872007-03-21 22:05:58 +0000510on_return:
Benny Prijonofd70c9b2007-03-27 11:00:38 +0000511 pj_log_set_level(3);
Benny Prijonofb9d9872007-03-21 22:05:58 +0000512 pj_ioqueue_destroy(stun_cfg.ioqueue);
513 pj_pool_release(pool);
514 return rc;
515}
516