- Timestamp:
- Mar 26, 2007 1:25:07 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r1104 r1106 154 154 { 155 155 struct transport_ice *tp_ice = (struct transport_ice*)tp; 156 unsigned comp_id;157 156 pj_status_t status; 158 157 … … 161 160 return status; 162 161 163 status = pj_ice_st_create_comp(tp_ice->ice_st, 1, options, start_addr, 164 &comp_id); 162 status = pj_ice_st_create_comp(tp_ice->ice_st, 1, options, start_addr); 165 163 if (status != PJ_SUCCESS) 166 164 return status; … … 168 166 if (tp_ice->ice_st->comp_cnt > 1) { 169 167 pj_sockaddr_in addr; 168 pj_uint16_t port; 170 169 171 170 pj_memcpy(&addr, &tp_ice->ice_st->comp[0]->local_addr.ipv4, … … 176 175 addr.sin_addr.s_addr = 0; 177 176 178 addr.sin_port = (pj_uint16_t)(pj_ntohs(addr.sin_port)+1); 179 status = pj_ice_st_create_comp(tp_ice->ice_st, 2, options, 180 &addr, &comp_id); 177 port = pj_ntohs(addr.sin_port); 178 ++port; 179 addr.sin_port = pj_htons(port); 180 status = pj_ice_st_create_comp(tp_ice->ice_st, 2, options, &addr); 181 181 if (status != PJ_SUCCESS) 182 182 return status; … … 482 482 pj_assert(comp->default_cand >= 0); 483 483 info->rtp_sock = comp->sock; 484 pj_memcpy(&info->rt p_addr_name,484 pj_memcpy(&info->rtcp_addr_name, 485 485 &comp->cand_list[comp->default_cand].addr, 486 486 sizeof(pj_sockaddr_in)); -
pjproject/trunk/pjnath/build/pjnath_test.dsp
r1095 r1106 51 51 LINK32=link.exe 52 52 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 # ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-release.exe"53 # ADD LINK32 mswsock.lib iphlpapi.lib netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-release.exe" 54 54 55 55 !ELSEIF "$(CFG)" == "pjnath_test - Win32 Debug" … … 75 75 LINK32=link.exe 76 76 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 # ADD LINK32 netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-debug.exe" /pdbtype:sept77 # ADD LINK32 iphlpapi.lib netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-debug.exe" /pdbtype:sept 78 78 79 79 !ENDIF -
pjproject/trunk/pjnath/include/pjnath/ice.h
r1104 r1106 69 69 70 70 typedef struct pj_ice pj_ice; 71 71 typedef struct pj_ice_check pj_ice_check; 72 72 73 73 #define PJ_ICE_MAX_CAND 16 … … 81 81 typedef struct pj_ice_comp 82 82 { 83 unsigned comp_id; 84 int nominated_check_id; 83 pj_ice_check *valid_check; 85 84 } pj_ice_comp; 86 85 … … 111 110 112 111 113 typedefstruct pj_ice_check112 struct pj_ice_check 114 113 { 115 114 pj_ice_cand *lcand; … … 118 117 pj_uint64_t prio; 119 118 pj_ice_check_state state; 119 pj_stun_tx_data *tdata; 120 120 pj_bool_t nominated; 121 121 pj_status_t err_code; 122 } pj_ice_check;122 }; 123 123 124 124 … … 206 206 pj_ice_checklist valid_list; 207 207 }; 208 209 PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type); 208 210 209 211 -
pjproject/trunk/pjnath/include/pjnath/ice_stream_transport.h
r1104 r1106 61 61 enum pj_ice_st_option 62 62 { 63 PJ_ICE_ST_OPT_DISABLE_STUN = 1, 64 PJ_ICE_ST_OPT_DISABLE_RELAY = 2, 65 PJ_ICE_ST_OPT_NO_PORT_RETRY = 4, 63 PJ_ICE_ST_OPT_DONT_ADD_CAND = 1, 64 PJ_ICE_ST_OPT_DISABLE_STUN = 2, 65 PJ_ICE_ST_OPT_DISABLE_RELAY = 4, 66 PJ_ICE_ST_OPT_NO_PORT_RETRY = 8, 66 67 }; 67 68 … … 144 145 unsigned comp_id, 145 146 pj_uint32_t options, 146 const pj_sockaddr_in *addr, 147 unsigned *p_itf_id); 147 const pj_sockaddr_in *addr); 148 PJ_DECL(pj_status_t) pj_ice_st_add_cand(pj_ice_st *ice_st, 149 unsigned comp_id, 150 pj_ice_cand_type type, 151 pj_uint16_t local_pref, 152 const pj_sockaddr_in *addr, 153 pj_bool_t set_default); 148 154 149 155 PJ_DECL(pj_status_t) pj_ice_st_get_comps_status(pj_ice_st *ice_st); -
pjproject/trunk/pjnath/include/pjnath/stun_session.h
r1091 r1106 319 319 320 320 /** 321 * Cancel outgoing STUN transaction. This operation is only valid for outgoing 322 * STUN request, to cease retransmission of the request and destroy the 323 * STUN client transaction that is used to send the request. 324 * 325 * @param sess The STUN session instance. 326 * @param tdata The request message previously sent. 327 * @param notify Specify whether \a on_request_complete() callback should 328 * be called. 329 * @param status If \a on_request_complete() callback is to be called, 330 * specify the error status to be given when calling the 331 * callback. This error status MUST NOT be PJ_SUCCESS. 332 * 333 * @return PJ_SUCCESS if transaction is successfully cancelled. 334 */ 335 PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess, 336 pj_stun_tx_data *tdata, 337 pj_bool_t notify, 338 pj_status_t status); 339 340 /** 321 341 * Application must call this function to notify the STUN session about 322 342 * the arrival of STUN packet. The STUN packet MUST have been checked -
pjproject/trunk/pjnath/src/pjnath-test/ice_test.c
r1100 r1106 19 19 #include "test.h" 20 20 21 #define THIS_FILE "ice .c"21 #define THIS_FILE "ice_test.c" 22 22 23 23 … … 44 44 id->complete = PJ_TRUE; 45 45 id->err_code = status; 46 PJ_LOG(3,(THIS_FILE, " ICE %s complete %s", id->obj_name,46 PJ_LOG(3,(THIS_FILE, " ICE %s complete %s", id->obj_name, 47 47 (status==PJ_SUCCESS ? "successfully" : "with failure"))); 48 48 } 49 49 50 50 51 static void on_rx_data(pj_ice_st *icest, 52 unsigned comp_id, unsigned cand_id, 51 static void on_rx_data(pj_ice_st *icest, unsigned comp_id, 53 52 void *pkt, pj_size_t size, 54 53 const pj_sockaddr_t *src_addr, … … 69 68 } 70 69 71 PJ_UNUSED_ARG(cand_id);72 70 PJ_UNUSED_ARG(src_addr); 73 71 PJ_UNUSED_ARG(src_addr_len); … … 102 100 icest_cb.on_rx_data = &on_rx_data; 103 101 104 status = pj_ice_st_create(&stun_cfg, NULL, NULL, &icest_cb, &im);102 status = pj_ice_st_create(&stun_cfg, "icetest", 2, NULL, &icest_cb, &im); 105 103 if (status != PJ_SUCCESS) 106 104 return -10; … … 127 125 } 128 126 127 128 struct dummy_cand 129 { 130 unsigned comp_id; 131 pj_ice_cand_type type; 132 const char *addr; 133 unsigned port; 134 }; 135 136 static int init_ice_st(pj_ice_st *ice_st, 137 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) { 147 status = pj_ice_st_create_comp(ice_st, i+1, PJ_ICE_ST_OPT_DONT_ADD_CAND, NULL); 148 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); 157 status = pj_ice_st_add_cand(ice_st, cand[i].comp_id, cand[i].type, 158 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) { 166 status = pj_ice_st_add_cand(ice_st, i+1, PJ_ICE_CAND_TYPE_HOST, 65535, 167 &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 */ 181 static int verify_address(pj_ice_st *agent1, pj_ice_st *agent2, 182 unsigned comp_id) 183 { 184 pj_ice_cand *rcand, *lcand; 185 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 */ 196 pj_ice_find_default_cand(agent2->ice, comp_id, &lcand_id); 197 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 } 129 209 130 210 … … 142 222 */ 143 223 static int perform_ice_test(const char *title, 224 pj_bool_t expected_success, 225 unsigned comp_cnt, 226 pj_bool_t add_valid_comp, 144 227 unsigned wait_before_send, 145 unsigned max_total_time) 228 unsigned max_total_time, 229 unsigned ocand_cnt, 230 struct dummy_cand ocand[], 231 unsigned acand_cnt, 232 struct dummy_cand acand[]) 146 233 { 147 234 pj_ice_st *im1, *im2; … … 149 236 struct ice_data *id1, *id2; 150 237 pj_timestamp t_start, t_end; 151 pj_ice_cand *rcand;238 unsigned i; 152 239 pj_str_t data_from_offerer, data_from_answerer; 153 240 pj_status_t status; 154 241 242 #define CHECK_COMPLETE() if (id1->complete && id2->complete) { \ 243 if (t_end.u32.lo==0) pj_get_timestamp(&t_end); \ 244 } else {} 245 155 246 PJ_LOG(3,(THIS_FILE, "...%s", title)); 247 248 pj_bzero(&t_end, sizeof(t_end)); 156 249 157 250 pj_bzero(&icest_cb, sizeof(icest_cb)); … … 160 253 161 254 /* Create first ICE */ 162 status = pj_ice_st_create(&stun_cfg, "offerer", NULL, &icest_cb, &im1);255 status = pj_ice_st_create(&stun_cfg, "offerer", comp_cnt, NULL, &icest_cb, &im1); 163 256 if (status != PJ_SUCCESS) 164 257 return -20; … … 168 261 im1->user_data = id1; 169 262 170 /* Add first component */ 171 status = pj_ice_st_add_comp(im1, 1); 172 if (status != PJ_SUCCESS) 173 return -21; 174 175 /* Add host candidate */ 176 status = pj_ice_st_add_host_interface(im1, 1, 65535, NULL, NULL); 177 if (status != PJ_SUCCESS) 178 return -21; 263 /* Init components */ 264 status = init_ice_st(im1, add_valid_comp, ocand_cnt, ocand); 265 if (status != 0) 266 return status; 179 267 180 268 /* Create second ICE */ 181 status = pj_ice_st_create(&stun_cfg, "answerer", NULL, &icest_cb, &im2);269 status = pj_ice_st_create(&stun_cfg, "answerer", comp_cnt, NULL, &icest_cb, &im2); 182 270 if (status != PJ_SUCCESS) 183 271 return -25; … … 187 275 im2->user_data = id2; 188 276 189 /* Add first component */ 190 status = pj_ice_st_add_comp(im2, 1); 191 if (status != PJ_SUCCESS) 192 return -26; 193 194 /* Add host candidate */ 195 status = pj_ice_st_add_host_interface(im2, 1, 65535, NULL, NULL); 196 if (status != PJ_SUCCESS) 197 return -27; 277 /* Init components */ 278 status = init_ice_st(im2, add_valid_comp, acand_cnt, acand); 279 if (status != 0) 280 return status; 281 198 282 199 283 /* Init ICE on im1 */ … … 217 301 return -35; 218 302 303 /* Apply delay to let other checks commence */ 304 pj_thread_sleep(40); 305 219 306 /* Mark start time */ 220 307 pj_get_timestamp(&t_start); 221 308 222 309 /* Poll for wait_before_send msecs before we send the first data */ 223 for (;;) { 224 pj_timestamp t_now; 225 226 handle_events(1); 227 228 pj_get_timestamp(&t_now); 229 if (pj_elapsed_msec(&t_start, &t_now) >= wait_before_send) 230 break; 231 } 232 233 /* Send data. It must be successful! */ 234 data_from_offerer = pj_str("from offerer"); 235 status = pj_ice_send_data(im1->ice, 1, data_from_offerer.ptr, data_from_offerer.slen); 236 if (status != PJ_SUCCESS) 237 return -47; 238 239 data_from_answerer = pj_str("from answerer"); 240 status = pj_ice_send_data(im2->ice, 1, data_from_answerer.ptr, data_from_answerer.slen); 241 if (status != PJ_SUCCESS) 242 return -48; 243 244 /* Poll to allow data to be received */ 245 for (;;) { 246 pj_timestamp t_now; 247 handle_events(1); 248 pj_get_timestamp(&t_now); 249 if (pj_elapsed_msec(&t_start, &t_now) >= (wait_before_send + 200)) 250 break; 251 } 252 310 if (expected_success) { 311 for (;;) { 312 pj_timestamp t_now; 313 314 handle_events(1); 315 316 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"); 325 status = pj_ice_send_data(im1->ice, 1, data_from_offerer.ptr, data_from_offerer.slen); 326 if (status != PJ_SUCCESS) 327 return -47; 328 329 data_from_answerer = pj_str("from answerer"); 330 status = pj_ice_send_data(im2->ice, 1, data_from_answerer.ptr, data_from_answerer.slen); 331 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 } 343 } 253 344 254 345 /* Just wait until both completes, or timed out */ … … 258 349 handle_events(1); 259 350 351 CHECK_COMPLETE(); 260 352 pj_get_timestamp(&t_now); 261 353 if (pj_elapsed_msec(&t_start, &t_now) >= max_total_time) { … … 266 358 267 359 /* Mark end-time */ 268 pj_get_timestamp(&t_end); 360 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 } 269 371 270 372 /* Check status */ … … 275 377 276 378 /* Verify that offerer gets answerer's transport address */ 277 rcand = im1->ice->clist.checks[im1->ice->comp[0].nominated_check_id].rcand;278 if (pj_memcmp(&rcand->addr, &im2->ice->lcand[0].addr, sizeof(pj_sockaddr_in))!=0) { 279 PJ_LOG(3,(THIS_FILE, "....error: address mismatch"));280 return -60;379 for (i=0; i<comp_cnt; ++i) { 380 status = verify_address(im1, im2, i+1); 381 if (status != 0) 382 return status; 281 383 } 282 384 283 385 /* And the other way around */ 284 rcand = im2->ice->clist.checks[im2->ice->comp[0].nominated_check_id].rcand;285 if (pj_memcmp(&rcand->addr, &im1->ice->lcand[0].addr, sizeof(pj_sockaddr_in))!=0) { 286 PJ_LOG(3,(THIS_FILE, "....error: address mismatch"));287 return -70;386 for (i=0; i<comp_cnt; ++i) { 387 status = verify_address(im2, im1, i+1); 388 if (status != 0) 389 return status; 288 390 } 289 391 … … 309 411 310 412 413 on_return: 414 311 415 /* Done */ 312 PJ_LOG(3,(THIS_FILE, "....success: ICE completed in %d msec ",416 PJ_LOG(3,(THIS_FILE, "....success: ICE completed in %d msec, waiting..", 313 417 pj_elapsed_msec(&t_start, &t_end))); 314 418 315 419 /* Wait for some more time */ 316 PJ_LOG(3,(THIS_FILE, ".....waiting.."));317 420 for (;;) { 318 421 pj_timestamp t_now; … … 328 431 pj_ice_st_destroy(im1); 329 432 pj_ice_st_destroy(im2); 433 handle_events(100); 330 434 return 0; 331 435 } … … 338 442 pj_ioqueue_t *ioqueue; 339 443 pj_timer_heap_t *timer_heap; 444 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 }; 340 455 341 456 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL); … … 345 460 pj_stun_config_init(&stun_cfg, mem, 0, ioqueue, timer_heap); 346 461 347 pj_log_set_level(5);462 //pj_log_set_level(4); 348 463 349 464 /* Basic create/destroy */ … … 353 468 354 469 /* Direct communication */ 355 rc = perform_ice_test("Direct connection", 500, 1000); 470 rc = perform_ice_test("Simple test (1 component)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 0, NULL, 0, NULL); 471 if (rc != 0) 472 goto on_return; 473 474 /* Failure case (all checks fail) */ 475 rc = perform_ice_test("Failure case (all checks fail)", PJ_FALSE, 1, PJ_FALSE, D3, D3, 1, ocand, 1, acand); 356 476 if (rc != 0) 357 477 goto on_return; 358 478 359 479 /* Direct communication with invalid address */ 360 rc = perform_ice_test("Direct connection with 1 invalid address", 500, 1000); 480 rc = perform_ice_test("With 1 unreachable address", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 0, NULL); 481 if (rc != 0) 482 goto on_return; 483 484 /* Direct communication with invalid address */ 485 rc = perform_ice_test("With 2 unreachable addresses (one each)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 1, acand); 361 486 if (rc != 0) 362 487 goto on_return; 363 488 364 489 /* Direct communication with two components */ 365 rc = perform_ice_test("Direct connection with two components", 500, 1000); 490 rc = perform_ice_test("With two components (RTP and RTCP)", PJ_TRUE, 2, PJ_TRUE, D1, D2, 0, NULL, 0, NULL); 491 if (rc != 0) 492 goto on_return; 493 494 /* Direct communication with mismatch number of components */ 495 496 /* Direct communication with 2 components and 2 invalid address */ 497 rc = perform_ice_test("With 2 two components and 2 unreachable address", PJ_TRUE, 2, PJ_TRUE, D1, D2, 1, ocand, 1, acand); 366 498 if (rc != 0) 367 499 goto on_return; … … 370 502 371 503 on_return: 372 pj_log_set_level(3);504 //pj_log_set_level(3); 373 505 pj_ioqueue_destroy(stun_cfg.ioqueue); 374 506 pj_pool_release(pool); -
pjproject/trunk/pjnath/src/pjnath-test/test.c
r1094 r1106 50 50 mem = &caching_pool.factory; 51 51 52 #if 053 52 pj_log_set_level(3); 54 53 pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | 55 54 PJ_LOG_HAS_MICRO_SEC); 56 #endif57 55 58 56 rc = pj_init(); -
pjproject/trunk/pjnath/src/pjnath/ice.c
r1104 r1106 57 57 }; 58 58 59 #define CHECK_NAME_LEN 60 #define LOG4(expr) 61 #define LOG5(expr) 62 #define GET_LCAND_ID(cand) 63 #define GET_CHECK_ID(c hk) (chk - ice->clist.checks)59 #define CHECK_NAME_LEN 128 60 #define LOG4(expr) PJ_LOG(4,expr) 61 #define LOG5(expr) PJ_LOG(4,expr) 62 #define GET_LCAND_ID(cand) (cand - ice->lcand) 63 #define GET_CHECK_ID(cl, chk) (chk - (cl)->checks) 64 64 65 65 … … 131 131 132 132 133 PJ_DEF(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type) 134 { 135 return cand_type_names[type]; 136 } 137 138 133 139 /* 134 140 * Create ICE stream session. … … 177 183 pj_ice_comp *comp; 178 184 comp = &ice->comp[i]; 179 comp->comp_id = i+1; 180 comp->nominated_check_id = -1; 185 comp->valid_check = NULL; 181 186 } 182 187 … … 412 417 foundation && addr && base_addr && addr_len, 413 418 PJ_EINVAL); 419 PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL); 414 420 415 421 pj_mutex_lock(ice->mutex); … … 499 505 500 506 PJ_ASSERT_RETURN(ice && comp_id && cand_id, PJ_EINVAL); 507 PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL); 501 508 502 509 *cand_id = -1; … … 586 593 587 594 static const char *dump_check(char *buffer, unsigned bufsize, 588 const pj_ice *ice,595 const pj_ice_checklist *clist, 589 596 const pj_ice_check *check) 590 597 { … … 598 605 if (lcand->addr.addr.sa_family == PJ_AF_INET) { 599 606 len = pj_ansi_snprintf(buffer, bufsize, 600 "%d: %s:%d-->%s:%d", 601 GET_CHECK_ID(check), 607 "%d: [%d] %s:%d-->%s:%d", 608 GET_CHECK_ID(clist, check), 609 check->lcand->comp_id, 602 610 laddr, (int)pj_ntohs(lcand->addr.ipv4.sin_port), 603 611 pj_inet_ntoa(rcand->addr.ipv4.sin_addr), … … 628 636 const pj_ice_check *c = &clist->checks[i]; 629 637 LOG4((ice->obj_name, " %s (%s, state=%s)", 630 dump_check(buffer, sizeof(buffer), ice, c),638 dump_check(buffer, sizeof(buffer), clist, c), 631 639 (c->nominated ? "nominated" : "not nominated"), 632 640 check_state_name[c->state])); … … 647 655 648 656 LOG5((ice->obj_name, "Check %s: state changed from %s to %s", 649 dump_check(buf, sizeof(buf), ice, check),657 dump_check(buf, sizeof(buf), &ice->clist, check), 650 658 check_state_name[check->state], 651 659 check_state_name[st])); … … 760 768 761 769 LOG5((ice->obj_name, "Check %s pruned", 762 dump_check(buf, sizeof(buf), ice, &clist->checks[j]))); 770 dump_check(buf, sizeof(buf), &ice->clist, 771 &clist->checks[j]))); 763 772 764 773 pj_array_erase(clist->checks, sizeof(clist->checks[0]), … … 813 822 if (check->err_code==PJ_SUCCESS && check->nominated) { 814 823 pj_ice_comp *comp; 824 char buf[CHECK_NAME_LEN]; 815 825 816 826 LOG5((ice->obj_name, "Check %d is successful and nominated", 817 GET_CHECK_ID( check)));827 GET_CHECK_ID(&ice->clist, check))); 818 828 819 829 for (i=0; i<ice->clist.count; ++i) { 820 830 pj_ice_check *c = &ice->clist.checks[i]; 821 if (c->lcand->comp_id == check->lcand->comp_id && 822 (c->state==PJ_ICE_CHECK_STATE_FROZEN || 823 c->state==PJ_ICE_CHECK_STATE_WAITING)) 824 { 825 LOG5((ice->obj_name, 826 "Check %d to be failed because state is %s", 827 i, check_state_name[c->state])); 828 check_set_state(ice, c, PJ_ICE_CHECK_STATE_FAILED, 829 PJ_ECANCELLED); 831 if (c->lcand->comp_id == check->lcand->comp_id) { 832 if (c->state < PJ_ICE_CHECK_STATE_IN_PROGRESS) { 833 /* Just fail Frozen/Waiting check */ 834 LOG5((ice->obj_name, 835 "Check %s to be failed because state is %s", 836 dump_check(buf, sizeof(buf), &ice->clist, c), 837 check_state_name[c->state])); 838 check_set_state(ice, c, PJ_ICE_CHECK_STATE_FAILED, 839 PJ_ECANCELLED); 840 841 } else if (c->state == PJ_ICE_CHECK_STATE_IN_PROGRESS) { 842 /* State is IN_PROGRESS, cancel transaction */ 843 if (c->tdata) { 844 LOG5((ice->obj_name, 845 "Cancelling check %s (In Progress)", 846 dump_check(buf, sizeof(buf), &ice->clist, c))); 847 pj_stun_session_cancel_req(c->lcand->stun_sess, 848 c->tdata, PJ_FALSE, 0); 849 c->tdata = NULL; 850 check_set_state(ice, c, PJ_ICE_CHECK_STATE_FAILED, 851 PJ_ECANCELLED); 852 } 853 } 830 854 } 831 855 } … … 833 857 /* Update the nominated check for the component */ 834 858 comp = find_comp(ice, check->lcand->comp_id); 835 if (comp-> nominated_check_id < 0) {836 comp-> nominated_check_id = GET_CHECK_ID(check);859 if (comp->valid_check == NULL) { 860 comp->valid_check = check; 837 861 } else { 838 pj_ice_check *nom_check; 839 nom_check = &ice->clist.checks[comp->nominated_check_id]; 840 if (nom_check->prio < check->prio) 841 comp->nominated_check_id = GET_CHECK_ID(check); 862 if (comp->valid_check->prio < check->prio) 863 comp->valid_check = check; 842 864 } 843 865 } … … 878 900 */ 879 901 for (i=0; i<ice->comp_cnt; ++i) { 880 if (ice->comp[i]. nominated_check_id == -1)902 if (ice->comp[i].valid_check == NULL) 881 903 break; 882 904 } … … 950 972 ice->rcand_cnt = 0; 951 973 for (i=0; i<rcand_cnt; ++i) { 952 pj_ice_cand *cn = &ice->rcand[ice->rcand_cnt++]; 974 pj_ice_cand *cn = &ice->rcand[ice->rcand_cnt]; 975 976 /* Ignore candidate which has no matching component ID */ 977 pj_assert(rcand[i].comp_id > 0); 978 if (rcand[i].comp_id==0 || rcand[i].comp_id > ice->comp_cnt) { 979 continue; 980 } 981 953 982 pj_memcpy(cn, &rcand[i], sizeof(pj_ice_cand)); 954 983 pj_strdup(ice->pool, &cn->foundation, &rcand[i].foundation); 984 ice->rcand_cnt++; 955 985 } 956 986 … … 967 997 pj_mutex_unlock(ice->mutex); 968 998 return PJ_ETOOMANY; 969 } else { 970 clist->count++; 971 } 999 } 972 1000 973 1001 /* A local candidate is paired with a remote candidate if … … 987 1015 988 1016 chk->prio = CALC_CHECK_PRIO(ice, lcand, rcand); 1017 1018 clist->count++; 989 1019 } 990 1020 } … … 1027 1057 unsigned check_id) 1028 1058 { 1029 pj_stun_tx_data *tdata;1030 1059 pj_ice_comp *comp; 1031 1060 struct req_data *rd; … … 1044 1073 LOG5((ice->obj_name, 1045 1074 "Sending connectivity check for check %s", 1046 dump_check(buffer, sizeof(buffer), ice, check)));1075 dump_check(buffer, sizeof(buffer), clist, check))); 1047 1076 1048 1077 /* Create request */ 1049 1078 status = pj_stun_session_create_req(lcand->stun_sess, 1050 PJ_STUN_BINDING_REQUEST, &tdata); 1079 PJ_STUN_BINDING_REQUEST, 1080 &check->tdata); 1051 1081 if (status != PJ_SUCCESS) 1052 1082 return status; … … 1055 1085 * completes and on_stun_request_complete() callback is called. 1056 1086 */ 1057 rd = PJ_POOL_ZALLOC_T( tdata->pool, struct req_data);1087 rd = PJ_POOL_ZALLOC_T(check->tdata->pool, struct req_data); 1058 1088 rd->ice = ice; 1059 1089 rd->clist = clist; 1060 1090 rd->ckid = check_id; 1061 tdata->user_data = (void*) rd;1091 check->tdata->user_data = (void*) rd; 1062 1092 1063 1093 /* Add PRIORITY */ 1064 1094 prio = CALC_CAND_PRIO(PJ_ICE_CAND_TYPE_PRFLX, 65535, 1065 1095 lcand->comp_id); 1066 pj_stun_msg_add_uint_attr( tdata->pool, tdata->msg, PJ_STUN_ATTR_PRIORITY,1067 prio);1096 pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg, 1097 PJ_STUN_ATTR_PRIORITY, prio); 1068 1098 1069 1099 /* Add USE-CANDIDATE and set this check to nominated */ 1070 1100 if (ice->role == PJ_ICE_ROLE_CONTROLLING) { 1071 pj_stun_msg_add_empty_attr( tdata->pool,tdata->msg,1101 pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg, 1072 1102 PJ_STUN_ATTR_USE_CANDIDATE); 1073 1103 check->nominated = PJ_TRUE; … … 1081 1111 status = pj_stun_session_send_msg(lcand->stun_sess, PJ_FALSE, 1082 1112 &rcand->addr, 1083 sizeof(pj_sockaddr_in), tdata); 1084 if (status != PJ_SUCCESS) 1113 sizeof(pj_sockaddr_in), check->tdata); 1114 if (status != PJ_SUCCESS) { 1115 check->tdata = NULL; 1085 1116 return status; 1117 } 1086 1118 1087 1119 check_set_state(ice, check, PJ_ICE_CHECK_STATE_IN_PROGRESS, PJ_SUCCESS); … … 1250 1282 clist = rd->clist; 1251 1283 1284 /* Mark STUN transaction as complete */ 1285 pj_assert(tdata == check->tdata); 1286 check->tdata = NULL; 1287 1252 1288 pj_mutex_lock(ice->mutex); 1253 1289 … … 1259 1295 LOG4((ice->obj_name, 1260 1296 "Check %s%s: connectivity check %s", 1261 dump_check(buffer, sizeof(buffer), ice, check),1297 dump_check(buffer, sizeof(buffer), &ice->clist, check), 1262 1298 (check->nominated ? " (nominated)" : " (not nominated)"), 1263 1299 (status==PJ_SUCCESS ? "SUCCESS" : "FAILED"))); … … 1501 1537 if (i == ice->rcand_cnt) { 1502 1538 rcand = &ice->rcand[ice->rcand_cnt++]; 1503 rcand->comp_id = comp->comp_id;1539 rcand->comp_id = lcand->comp_id; 1504 1540 rcand->type = PJ_ICE_CAND_TYPE_PRFLX; 1505 1541 rcand->prio = ap->value; … … 1649 1685 pj_ice_comp *comp; 1650 1686 unsigned cand_id; 1651 pj_ice_check *check; 1652 1653 PJ_ASSERT_RETURN(ice, PJ_EINVAL); 1687 1688 PJ_ASSERT_RETURN(ice && comp_id && comp_id <= ice->comp_cnt, PJ_EINVAL); 1654 1689 1655 1690 pj_mutex_lock(ice->mutex); … … 1661 1696 } 1662 1697 1663 if (comp-> nominated_check_id == -1) {1698 if (comp->valid_check == NULL) { 1664 1699 status = PJNATH_EICEINPROGRESS; 1665 1700 goto on_return; 1666 1701 } 1667 1702 1668 check = &ice->clist.checks[comp->nominated_check_id]; 1669 cand_id = GET_LCAND_ID(check->lcand); 1670 1703 cand_id = GET_LCAND_ID(comp->valid_check->lcand); 1671 1704 status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand_id, data, data_len, 1672 &c heck->rcand->addr,1705 &comp->valid_check->rcand->addr, 1673 1706 sizeof(pj_sockaddr_in)); 1674 1707 -
pjproject/trunk/pjnath/src/pjnath/ice_stream_transport.c
r1104 r1106 61 61 62 62 /* Utility: print error */ 63 #if PJ_LOG_MAX_LEVEL >= 3 63 64 static void ice_st_perror(pj_ice_st *ice_st, const char *title, 64 65 pj_status_t status) … … 67 68 68 69 pj_strerror(status, errmsg, sizeof(errmsg)); 69 PJ_LOG(1,(ice_st->obj_name, "%s: %s", title, errmsg)); 70 } 70 PJ_LOG(3,(ice_st->obj_name, "%s: %s", title, errmsg)); 71 } 72 #else 73 # define ice_st_perror(ice_st, title, status) 74 #endif 71 75 72 76 … … 225 229 } 226 230 231 /* Add new candidate */ 232 static pj_status_t add_cand( pj_ice_st *ice_st, 233 pj_ice_st_comp *comp, 234 unsigned comp_id, 235 pj_ice_cand_type type, 236 pj_uint16_t local_pref, 237 const pj_sockaddr_in *addr, 238 pj_bool_t set_default) 239 { 240 pj_ice_st_cand *cand; 241 242 PJ_ASSERT_RETURN(ice_st && comp && addr, PJ_EINVAL); 243 PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_ALIASES, PJ_ETOOMANY); 244 245 cand = &comp->cand_list[comp->cand_cnt]; 246 247 pj_bzero(cand, sizeof(*cand)); 248 cand->type = type; 249 cand->status = PJ_SUCCESS; 250 pj_memcpy(&cand->addr, addr, sizeof(pj_sockaddr_in)); 251 cand->cand_id = -1; 252 cand->local_pref = local_pref; 253 cand->foundation = calc_foundation(ice_st->pool, type, &addr->sin_addr); 254 255 if (set_default) 256 comp->default_cand = comp->cand_cnt; 257 258 PJ_LOG(5,(ice_st->obj_name, 259 "Candidate %s:%d (type=%s) added to component %d", 260 pj_inet_ntoa(addr->sin_addr), 261 (int)pj_ntohs(addr->sin_port), 262 pj_ice_get_cand_type_name(type), 263 comp_id)); 264 265 comp->cand_cnt++; 266 return PJ_SUCCESS; 267 } 268 227 269 /* Create new component (i.e. socket) */ 228 270 static pj_status_t create_component(pj_ice_st *ice_st, … … 301 343 * cand_list. 302 344 */ 303 if (comp->local_addr.ipv4.sin_addr.s_addr == 0) { 345 if (((options & PJ_ICE_ST_OPT_DONT_ADD_CAND)==0) && 346 comp->local_addr.ipv4.sin_addr.s_addr == 0) 347 { 304 348 /* Socket is bound to INADDR_ANY */ 305 349 unsigned i, ifs_cnt; … … 318 362 status = pj_gethostip(&comp->local_addr.ipv4.sin_addr); 319 363 if (status != PJ_SUCCESS) 320 return status;364 goto on_error; 321 365 322 366 /* Add candidate entry for each interface */ 323 367 for (i=0; i<ifs_cnt; ++i) { 324 pj_ice_st_cand *cand = &comp->cand_list[i]; 325 326 cand->type = PJ_ICE_CAND_TYPE_HOST; 327 cand->status = PJ_SUCCESS; 328 pj_memcpy(&cand->addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 329 cand->addr.ipv4.sin_addr.s_addr = ifs[i].s_addr; 330 cand->cand_id = -1; 331 cand->local_pref = 65535; 332 cand->foundation = calc_foundation(ice_st->pool, 333 PJ_ICE_CAND_TYPE_HOST, 334 &cand->addr.ipv4.sin_addr); 368 pj_sockaddr_in cand_addr; 369 pj_bool_t set_default; 370 371 /* Ignore 127.0.0.0/24 address */ 372 if ((pj_ntohl(ifs[i].s_addr) >> 24)==127) 373 continue; 374 375 pj_memcpy(&cand_addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 376 cand_addr.sin_addr.s_addr = ifs[i].s_addr; 377 335 378 336 379 /* If the IP address is equal to local address, assign it 337 380 * as default candidate. 338 381 */ 339 if ( cand->addr.ipv4.sin_addr.s_addr ==340 comp->local_addr.ipv4.sin_addr.s_addr)341 {342 comp->default_cand = i;382 if (ifs[i].s_addr == comp->local_addr.ipv4.sin_addr.s_addr) { 383 set_default = PJ_TRUE; 384 } else { 385 set_default = PJ_FALSE; 343 386 } 344 387 345 PJ_LOG(5,(ice_st->obj_name, 346 "Interface %s:%d added to component %d", 347 pj_inet_ntoa(cand->addr.ipv4.sin_addr), 348 (int)pj_ntohs(cand->addr.ipv4.sin_port), comp_id)); 388 status = add_cand(ice_st, comp, comp_id, 389 PJ_ICE_CAND_TYPE_HOST, 390 (pj_uint16_t)(65535-i), &cand_addr, 391 set_default); 392 if (status != PJ_SUCCESS) 393 goto on_error; 349 394 } 350 comp->cand_cnt = ifs_cnt; 351 352 353 } else { 395 396 397 } else if ((options & PJ_ICE_ST_OPT_DONT_ADD_CAND)==0) { 354 398 /* Socket is bound to specific address. 355 399 * In this case only add that address as a single entry in the 356 400 * cand_list table. 357 401 */ 358 pj_ice_st_cand *cand = &comp->cand_list[0]; 359 360 cand->type = PJ_ICE_CAND_TYPE_HOST; 361 cand->status = PJ_SUCCESS; 362 pj_memcpy(&cand->addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 363 cand->cand_id = -1; 364 cand->local_pref = 65535; 365 cand->foundation = calc_foundation(ice_st->pool, 366 PJ_ICE_CAND_TYPE_HOST, 367 &cand->addr.ipv4.sin_addr); 368 369 comp->cand_cnt = 1; 370 comp->default_cand = 0; 371 372 PJ_LOG(5,(ice_st->obj_name, 373 "Interface %s:%d added to component %d", 374 pj_inet_ntoa(cand->addr.ipv4.sin_addr), 375 (int)pj_ntohs(cand->addr.ipv4.sin_port), comp_id)); 376 377 } 402 status = add_cand(ice_st, comp, comp_id, 403 PJ_ICE_CAND_TYPE_HOST, 404 65535, &comp->local_addr.ipv4, 405 PJ_TRUE); 406 if (status != PJ_SUCCESS) 407 goto on_error; 408 409 } else if (options & PJ_ICE_ST_OPT_DONT_ADD_CAND) { 410 /* If application doesn't want to add candidate, just fix local_addr 411 * in case its value is zero. 412 */ 413 if (comp->local_addr.ipv4.sin_addr.s_addr == 0) { 414 status = pj_gethostip(&comp->local_addr.ipv4.sin_addr); 415 if (status != PJ_SUCCESS) 416 return status; 417 } 418 } 419 378 420 379 421 /* Done */ … … 569 611 unsigned comp_id, 570 612 pj_uint32_t options, 571 const pj_sockaddr_in *addr, 572 unsigned *p_itf_id) 613 const pj_sockaddr_in *addr) 573 614 { 574 615 pj_ice_st_comp *comp; … … 602 643 603 644 /* Store this component */ 604 if (p_itf_id)605 *p_itf_id = ice_st->comp_cnt;606 607 645 ice_st->comp[comp_id-1] = comp; 608 646 609 647 return PJ_SUCCESS; 648 } 649 650 651 PJ_DEF(pj_status_t) pj_ice_st_add_cand( pj_ice_st *ice_st, 652 unsigned comp_id, 653 pj_ice_cand_type type, 654 pj_uint16_t local_pref, 655 const pj_sockaddr_in *addr, 656 pj_bool_t set_default) 657 { 658 pj_ice_st_comp *comp; 659 660 661 PJ_ASSERT_RETURN(ice_st && comp_id && addr, PJ_EINVAL); 662 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJ_EINVAL); 663 PJ_ASSERT_RETURN(ice_st->comp[comp_id-1] != NULL, PJ_EINVALIDOP); 664 665 comp = ice_st->comp[comp_id-1]; 666 return add_cand(ice_st, comp, comp_id, type, local_pref, addr, 667 set_default); 610 668 } 611 669 … … 652 710 /* Must not have ICE */ 653 711 PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EINVALIDOP); 712 /* Components must have been created */ 713 PJ_ASSERT_RETURN(ice_st->comp[0] != NULL, PJ_EINVALIDOP); 654 714 655 715 /* Init callback */ -
pjproject/trunk/pjnath/src/pjnath/stun_session.c
r1099 r1106 678 678 } 679 679 680 /* 681 * Cancel outgoing STUN transaction. 682 */ 683 PJ_DEF(pj_status_t) pj_stun_session_cancel_req( pj_stun_session *sess, 684 pj_stun_tx_data *tdata, 685 pj_bool_t notify, 686 pj_status_t notify_status) 687 { 688 PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL); 689 PJ_ASSERT_RETURN(!notify || notify_status!=PJ_SUCCESS, PJ_EINVAL); 690 PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 691 692 pj_mutex_lock(sess->mutex); 693 694 if (notify) { 695 (sess->cb.on_request_complete)(sess, notify_status, tdata, NULL); 696 } 697 698 /* Just destroy tdata. This will destroy the transaction as well */ 699 pj_stun_msg_destroy_tdata(sess, tdata); 700 701 pj_mutex_unlock(sess->mutex); 702 return PJ_SUCCESS; 703 704 } 680 705 681 706 /* Send response */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r1104 r1106 564 564 int next_port; 565 565 566 status = pjmedia_ice_create(pjsua_var.med_endpt, NULL, 1,566 status = pjmedia_ice_create(pjsua_var.med_endpt, NULL, 2, 567 567 &pjsua_var.stun_cfg, 568 568 &pjsua_var.calls[i].med_tp);
Note: See TracChangeset
for help on using the changeset viewer.