Changeset 5339 for pjproject/trunk/pjnath/src/pjnath/ice_strans.c
- Timestamp:
- Jun 8, 2016 3:17:45 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/ice_strans.c
r5282 r5339 49 49 }; 50 50 51 52 #define CREATE_TP_ID(type, idx) (pj_uint8_t)((type << 6) | idx) 53 #define GET_TP_TYPE(transport_id) ((transport_id & 0xC0) >> 6) 54 #define GET_TP_IDX(transport_id) (transport_id & 0x3F) 55 56 51 57 /* Candidate's local preference values. This is mostly used to 52 58 * specify preference among candidates with the same type. Since … … 149 155 unsigned comp_id; /**< Component ID. */ 150 156 151 pj_stun_sock *stun_sock; /**< STUN transport. */ 152 pj_turn_sock *turn_sock; /**< TURN relay transport. */ 153 pj_bool_t turn_log_off; /**< TURN loggin off? */ 154 unsigned turn_err_cnt; /**< TURN disconnected count. */ 157 struct { 158 pj_stun_sock *sock; /**< STUN transport. */ 159 } stun[PJ_ICE_MAX_STUN]; 160 161 struct { 162 pj_turn_sock *sock; /**< TURN relay transport. */ 163 pj_bool_t log_off; /**< TURN loggin off? */ 164 unsigned err_cnt; /**< TURN disconnected count. */ 165 } turn[PJ_ICE_MAX_TURN]; 155 166 156 167 unsigned cand_cnt; /**< # of candidates/aliaes. */ … … 188 199 189 200 201 /** 202 * This structure describe user data for STUN/TURN sockets of the 203 * ICE stream transport. 204 */ 205 typedef struct sock_user_data 206 { 207 pj_ice_strans_comp *comp; 208 pj_uint8_t transport_id; 209 210 } sock_user_data; 211 212 190 213 /* Validate configuration */ 191 214 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) … … 209 232 210 233 pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL); 211 pj_stun_sock_cfg_default(&cfg->stun.cfg); 212 pj_turn_alloc_param_default(&cfg->turn.alloc_param); 213 pj_turn_sock_cfg_default(&cfg->turn.cfg); 214 234 pj_ice_strans_stun_cfg_default(&cfg->stun); 235 pj_ice_strans_turn_cfg_default(&cfg->turn); 215 236 pj_ice_sess_options_default(&cfg->opt); 237 } 238 239 240 /* 241 * Initialize ICE STUN transport configuration with default values. 242 */ 243 PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg) 244 { 245 pj_bzero(cfg, sizeof(*cfg)); 216 246 217 247 cfg->af = pj_AF_INET(); 218 cfg->stun.port = PJ_STUN_PORT; 219 cfg->turn.conn_type = PJ_TURN_TP_UDP; 220 221 cfg->stun.max_host_cands = 64; 222 cfg->stun.ignore_stun_error = PJ_FALSE; 248 cfg->port = PJ_STUN_PORT; 249 cfg->max_host_cands = 64; 250 cfg->ignore_stun_error = PJ_FALSE; 251 pj_stun_sock_cfg_default(&cfg->cfg); 252 } 253 254 255 /* 256 * Initialize ICE TURN transport configuration with default values. 257 */ 258 PJ_DEF(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg) 259 { 260 pj_bzero(cfg, sizeof(*cfg)); 261 262 cfg->af = pj_AF_INET(); 263 cfg->conn_type = PJ_TURN_TP_UDP; 264 pj_turn_alloc_param_default(&cfg->alloc_param); 265 pj_turn_sock_cfg_default(&cfg->cfg); 223 266 } 224 267 … … 231 274 const pj_ice_strans_cfg *src) 232 275 { 276 unsigned i; 277 233 278 pj_memcpy(dst, src, sizeof(*src)); 234 279 235 280 if (src->stun.server.slen) 236 281 pj_strdup(pool, &dst->stun.server, &src->stun.server); 282 283 for (i = 0; i < src->stun_tp_cnt; ++i) { 284 if (src->stun_tp[i].server.slen) 285 pj_strdup(pool, &dst->stun_tp[i].server, 286 &src->stun_tp[i].server); 287 } 288 237 289 if (src->turn.server.slen) 238 290 pj_strdup(pool, &dst->turn.server, &src->turn.server); 239 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, 240 &src->turn.auth_cred); 291 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, &src->turn.auth_cred); 292 293 for (i = 0; i < src->turn_tp_cnt; ++i) { 294 if (src->turn_tp[i].server.slen) 295 pj_strdup(pool, &dst->turn_tp[i].server, 296 &src->turn_tp[i].server); 297 pj_stun_auth_cred_dup(pool, &dst->turn_tp[i].auth_cred, 298 &src->turn_tp[i].auth_cred); 299 } 241 300 } 242 301 … … 246 305 */ 247 306 static pj_status_t add_update_turn(pj_ice_strans *ice_st, 248 pj_ice_strans_comp *comp) 249 { 307 pj_ice_strans_comp *comp, 308 unsigned idx) 309 { 310 pj_ice_sess_cand *cand = NULL; 311 pj_ice_strans_turn_cfg *turn_cfg = &ice_st->cfg.turn_tp[idx]; 312 pj_turn_sock_cfg *sock_cfg = &turn_cfg->cfg; 313 unsigned comp_idx = comp->comp_id - 1; 250 314 pj_turn_sock_cb turn_sock_cb; 251 pj_ice_sess_cand *cand = NULL;315 sock_user_data *data; 252 316 unsigned i; 317 pj_uint8_t tp_id; 253 318 pj_status_t status; 254 319 320 /* Check if TURN transport is configured */ 321 if (turn_cfg->server.slen == 0) 322 return PJ_SUCCESS; 323 255 324 /* Find relayed candidate in the component */ 325 tp_id = CREATE_TP_ID(TP_TURN, idx); 256 326 for (i=0; i<comp->cand_cnt; ++i) { 257 if (comp->cand_list[i].t ype == PJ_ICE_CAND_TYPE_RELAYED) {327 if (comp->cand_list[i].transport_id == tp_id) { 258 328 cand = &comp->cand_list[i]; 259 329 break; … … 287 357 288 358 /* Override with component specific QoS settings, if any */ 289 if (ice_st->cfg.comp[comp->comp_id-1].qos_type) { 290 ice_st->cfg.turn.cfg.qos_type = 291 ice_st->cfg.comp[comp->comp_id-1].qos_type; 292 } 293 if (ice_st->cfg.comp[comp->comp_id-1].qos_params.flags) { 294 pj_memcpy(&ice_st->cfg.turn.cfg.qos_params, 295 &ice_st->cfg.comp[comp->comp_id-1].qos_params, 296 sizeof(ice_st->cfg.turn.cfg.qos_params)); 297 } 359 if (ice_st->cfg.comp[comp_idx].qos_type) 360 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 361 if (ice_st->cfg.comp[comp_idx].qos_params.flags) 362 pj_memcpy(&sock_cfg->qos_params, 363 &ice_st->cfg.comp[comp_idx].qos_params, 364 sizeof(sock_cfg->qos_params)); 298 365 299 366 /* Override with component specific socket buffer size settings, if any */ 300 if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) { 301 ice_st->cfg.turn.cfg.so_rcvbuf_size = 302 ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size; 303 } 304 if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) { 305 ice_st->cfg.turn.cfg.so_sndbuf_size = 306 ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size; 307 } 367 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) 368 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 369 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) 370 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 371 372 /* Add relayed candidate with pending status if there's no existing one */ 373 if (cand == NULL) { 374 cand = &comp->cand_list[comp->cand_cnt]; 375 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 376 cand->status = PJ_EPENDING; 377 cand->local_pref = RELAY_PREF; 378 cand->transport_id = CREATE_TP_ID(TP_TURN, idx); 379 cand->comp_id = (pj_uint8_t) comp->comp_id; 380 } 381 382 /* Allocate and initialize TURN socket data */ 383 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 384 data->comp = comp; 385 data->transport_id = cand->transport_id; 308 386 309 387 /* Create the TURN transport */ 310 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af,311 ice_st->cfg.turn.conn_type,312 &turn_sock_cb, &ice_st->cfg.turn.cfg,313 comp, &comp->turn_sock);388 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, turn_cfg->af, 389 turn_cfg->conn_type, 390 &turn_sock_cb, sock_cfg, 391 data, &comp->turn[idx].sock); 314 392 if (status != PJ_SUCCESS) { 315 393 return status; … … 320 398 321 399 /* Start allocation */ 322 status=pj_turn_sock_alloc(comp->turn _sock,323 & ice_st->cfg.turn.server,324 ice_st->cfg.turn.port,400 status=pj_turn_sock_alloc(comp->turn[idx].sock, 401 &turn_cfg->server, 402 turn_cfg->port, 325 403 ice_st->cfg.resolver, 326 & ice_st->cfg.turn.auth_cred,327 & ice_st->cfg.turn.alloc_param);404 &turn_cfg->auth_cred, 405 &turn_cfg->alloc_param); 328 406 if (status != PJ_SUCCESS) { 329 407 ///sess_dec_ref(ice_st); … … 331 409 } 332 410 333 /* Add relayed candidate with pending status if there's no existing one */ 334 if (cand == NULL) { 335 cand = &comp->cand_list[comp->cand_cnt++]; 336 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 337 cand->status = PJ_EPENDING; 338 cand->local_pref = RELAY_PREF; 339 cand->transport_id = TP_TURN; 340 cand->comp_id = (pj_uint8_t) comp->comp_id; 341 } 411 /* Commit the relayed candidate. */ 412 comp->cand_cnt++; 342 413 343 414 PJ_LOG(4,(ice_st->obj_name, … … 373 444 } 374 445 446 447 static pj_status_t add_stun_and_host(pj_ice_strans *ice_st, 448 pj_ice_strans_comp *comp, 449 unsigned idx) 450 { 451 pj_ice_sess_cand *cand; 452 pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx]; 453 pj_stun_sock_cfg *sock_cfg = &stun_cfg->cfg; 454 unsigned comp_idx = comp->comp_id - 1; 455 pj_stun_sock_cb stun_sock_cb; 456 sock_user_data *data; 457 pj_status_t status; 458 459 /* Check if STUN transport or host candidate is configured */ 460 if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0) 461 return PJ_SUCCESS; 462 463 /* Initialize STUN socket callback */ 464 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 465 stun_sock_cb.on_rx_data = &stun_on_rx_data; 466 stun_sock_cb.on_status = &stun_on_status; 467 stun_sock_cb.on_data_sent = &stun_on_data_sent; 468 469 /* Override component specific QoS settings, if any */ 470 if (ice_st->cfg.comp[comp_idx].qos_type) { 471 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 472 } 473 if (ice_st->cfg.comp[comp_idx].qos_params.flags) { 474 pj_memcpy(&sock_cfg->qos_params, 475 &ice_st->cfg.comp[comp_idx].qos_params, 476 sizeof(sock_cfg->qos_params)); 477 } 478 479 /* Override component specific socket buffer size settings, if any */ 480 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) { 481 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 482 } 483 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) { 484 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 485 } 486 487 /* Prepare srflx candidate with pending status. */ 488 cand = &comp->cand_list[comp->cand_cnt]; 489 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 490 cand->status = PJ_EPENDING; 491 cand->local_pref = SRFLX_PREF; 492 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 493 cand->comp_id = (pj_uint8_t) comp->comp_id; 494 495 /* Allocate and initialize STUN socket data */ 496 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 497 data->comp = comp; 498 data->transport_id = cand->transport_id; 499 500 /* Create the STUN transport */ 501 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 502 stun_cfg->af, &stun_sock_cb, 503 sock_cfg, data, &comp->stun[idx].sock); 504 if (status != PJ_SUCCESS) 505 return status; 506 507 /* Start STUN Binding resolution and add srflx candidate 508 * only if server is set 509 */ 510 if (stun_cfg->server.slen) { 511 pj_stun_sock_info stun_sock_info; 512 513 /* Add pending job */ 514 ///sess_add_ref(ice_st); 515 516 PJ_LOG(4,(ice_st->obj_name, 517 "Comp %d: srflx candidate starts Binding discovery", 518 comp->comp_id)); 519 520 pj_log_push_indent(); 521 522 /* Start Binding resolution */ 523 status = pj_stun_sock_start(comp->stun[idx].sock, &stun_cfg->server, 524 stun_cfg->port, ice_st->cfg.resolver); 525 if (status != PJ_SUCCESS) { 526 ///sess_dec_ref(ice_st); 527 pj_log_pop_indent(); 528 return status; 529 } 530 531 /* Enumerate addresses */ 532 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 533 if (status != PJ_SUCCESS) { 534 ///sess_dec_ref(ice_st); 535 pj_log_pop_indent(); 536 return status; 537 } 538 539 /* Update and commit the srflx candidate. */ 540 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 541 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 542 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 543 cand->type, &cand->base_addr); 544 comp->cand_cnt++; 545 546 /* Set default candidate to srflx */ 547 comp->default_cand = (unsigned)(cand - comp->cand_list); 548 549 pj_log_pop_indent(); 550 } 551 552 /* Add local addresses to host candidates, unless max_host_cands 553 * is set to zero. 554 */ 555 if (stun_cfg->max_host_cands) { 556 pj_stun_sock_info stun_sock_info; 557 unsigned i; 558 559 /* Enumerate addresses */ 560 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 561 if (status != PJ_SUCCESS) 562 return status; 563 564 for (i=0; i<stun_sock_info.alias_cnt && 565 i<stun_cfg->max_host_cands; ++i) 566 { 567 unsigned j; 568 pj_bool_t cand_duplicate = PJ_FALSE; 569 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 570 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 571 572 /* Leave one candidate for relay */ 573 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 574 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 575 break; 576 } 577 578 /* Ignore loopback addresses if cfg->stun.loop_addr is unset */ 579 if (stun_cfg->loop_addr==PJ_FALSE) { 580 if (stun_cfg->af == pj_AF_INET() && 581 (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) 582 { 583 continue; 584 } 585 else if (stun_cfg->af == pj_AF_INET6()) { 586 pj_in6_addr in6addr = {0}; 587 in6addr.s6_addr[15] = 1; 588 if (pj_memcmp(&in6addr, &addr->ipv6.sin6_addr, 589 sizeof(in6addr))==0) 590 { 591 continue; 592 } 593 } 594 } 595 596 cand = &comp->cand_list[comp->cand_cnt]; 597 598 cand->type = PJ_ICE_CAND_TYPE_HOST; 599 cand->status = PJ_SUCCESS; 600 cand->local_pref = HOST_PREF; 601 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 602 cand->comp_id = (pj_uint8_t) comp->comp_id; 603 pj_sockaddr_cp(&cand->addr, addr); 604 pj_sockaddr_cp(&cand->base_addr, addr); 605 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 606 607 /* Check if not already in list */ 608 for (j=0; j<comp->cand_cnt; j++) { 609 if (ice_cand_equals(cand, &comp->cand_list[j])) { 610 cand_duplicate = PJ_TRUE; 611 break; 612 } 613 } 614 615 if (cand_duplicate) { 616 PJ_LOG(4, (ice_st->obj_name, 617 "Comp %d: host candidate %s is a duplicate", 618 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 619 sizeof(addrinfo), 3))); 620 621 pj_bzero(&cand->addr, sizeof(cand->addr)); 622 pj_bzero(&cand->base_addr, sizeof(cand->base_addr)); 623 continue; 624 } else { 625 comp->cand_cnt+=1; 626 } 627 628 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 629 cand->type, &cand->base_addr); 630 631 PJ_LOG(4,(ice_st->obj_name, 632 "Comp %d: host candidate %s added", 633 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 634 sizeof(addrinfo), 3))); 635 } 636 } 637 638 return PJ_SUCCESS; 639 } 640 641 375 642 /* 376 643 * Create the component. … … 379 646 { 380 647 pj_ice_strans_comp *comp = NULL; 648 unsigned i; 381 649 pj_status_t status; 382 650 … … 398 666 399 667 /* Create STUN transport if configured */ 400 if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) { 401 pj_stun_sock_cb stun_sock_cb; 402 pj_ice_sess_cand *cand; 403 404 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 405 stun_sock_cb.on_rx_data = &stun_on_rx_data; 406 stun_sock_cb.on_status = &stun_on_status; 407 stun_sock_cb.on_data_sent = &stun_on_data_sent; 408 409 /* Override component specific QoS settings, if any */ 410 if (ice_st->cfg.comp[comp_id-1].qos_type) { 411 ice_st->cfg.stun.cfg.qos_type = 412 ice_st->cfg.comp[comp_id-1].qos_type; 413 } 414 if (ice_st->cfg.comp[comp_id-1].qos_params.flags) { 415 pj_memcpy(&ice_st->cfg.stun.cfg.qos_params, 416 &ice_st->cfg.comp[comp_id-1].qos_params, 417 sizeof(ice_st->cfg.stun.cfg.qos_params)); 418 } 419 420 /* Override component specific socket buffer size settings, if any */ 421 if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) { 422 ice_st->cfg.stun.cfg.so_rcvbuf_size = 423 ice_st->cfg.comp[comp_id-1].so_rcvbuf_size; 424 } 425 if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) { 426 ice_st->cfg.stun.cfg.so_sndbuf_size = 427 ice_st->cfg.comp[comp_id-1].so_sndbuf_size; 428 } 429 430 /* Create the STUN transport */ 431 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 432 ice_st->cfg.af, &stun_sock_cb, 433 &ice_st->cfg.stun.cfg, 434 comp, &comp->stun_sock); 668 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) { 669 status = add_stun_and_host(ice_st, comp, i); 435 670 if (status != PJ_SUCCESS) 436 671 return status; 437 438 /* Start STUN Binding resolution and add srflx candidate439 * only if server is set440 */441 if (ice_st->cfg.stun.server.slen) {442 pj_stun_sock_info stun_sock_info;443 444 /* Add pending job */445 ///sess_add_ref(ice_st);446 447 PJ_LOG(4,(ice_st->obj_name,448 "Comp %d: srflx candidate starts Binding discovery",449 comp_id));450 451 pj_log_push_indent();452 453 /* Start Binding resolution */454 status = pj_stun_sock_start(comp->stun_sock,455 &ice_st->cfg.stun.server,456 ice_st->cfg.stun.port,457 ice_st->cfg.resolver);458 if (status != PJ_SUCCESS) {459 ///sess_dec_ref(ice_st);460 pj_log_pop_indent();461 return status;462 }463 464 /* Enumerate addresses */465 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);466 if (status != PJ_SUCCESS) {467 ///sess_dec_ref(ice_st);468 pj_log_pop_indent();469 return status;470 }471 472 /* Add srflx candidate with pending status. */473 cand = &comp->cand_list[comp->cand_cnt++];474 cand->type = PJ_ICE_CAND_TYPE_SRFLX;475 cand->status = PJ_EPENDING;476 cand->local_pref = SRFLX_PREF;477 cand->transport_id = TP_STUN;478 cand->comp_id = (pj_uint8_t) comp_id;479 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]);480 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr);481 pj_ice_calc_foundation(ice_st->pool, &cand->foundation,482 cand->type, &cand->base_addr);483 484 /* Set default candidate to srflx */485 comp->default_cand = (unsigned)(cand - comp->cand_list);486 487 pj_log_pop_indent();488 }489 490 /* Add local addresses to host candidates, unless max_host_cands491 * is set to zero.492 */493 if (ice_st->cfg.stun.max_host_cands) {494 pj_stun_sock_info stun_sock_info;495 unsigned i;496 497 /* Enumerate addresses */498 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);499 if (status != PJ_SUCCESS)500 return status;501 502 for (i=0; i<stun_sock_info.alias_cnt &&503 i<ice_st->cfg.stun.max_host_cands; ++i)504 {505 unsigned j;506 pj_bool_t cand_duplicate = PJ_FALSE;507 char addrinfo[PJ_INET6_ADDRSTRLEN+10];508 const pj_sockaddr *addr = &stun_sock_info.aliases[i];509 510 /* Leave one candidate for relay */511 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) {512 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));513 break;514 }515 516 /* Ignore loopback addresses unless cfg->stun.loop_addr517 * is set518 */519 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) {520 if (ice_st->cfg.stun.loop_addr==PJ_FALSE)521 continue;522 }523 524 cand = &comp->cand_list[comp->cand_cnt];525 526 cand->type = PJ_ICE_CAND_TYPE_HOST;527 cand->status = PJ_SUCCESS;528 cand->local_pref = HOST_PREF;529 cand->transport_id = TP_STUN;530 cand->comp_id = (pj_uint8_t) comp_id;531 pj_sockaddr_cp(&cand->addr, addr);532 pj_sockaddr_cp(&cand->base_addr, addr);533 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));534 535 /* Check if not already in list */536 for (j=0; j<comp->cand_cnt; j++) {537 if (ice_cand_equals(cand, &comp->cand_list[j])) {538 cand_duplicate = PJ_TRUE;539 break;540 }541 }542 543 if (cand_duplicate) {544 PJ_LOG(4, (ice_st->obj_name,545 "Comp %d: host candidate %s is a duplicate",546 comp_id, pj_sockaddr_print(&cand->addr, addrinfo,547 sizeof(addrinfo), 3)));548 549 pj_bzero(&cand->addr, sizeof(cand->addr));550 pj_bzero(&cand->base_addr, sizeof(cand->base_addr));551 continue;552 } else {553 comp->cand_cnt+=1;554 }555 556 pj_ice_calc_foundation(ice_st->pool, &cand->foundation,557 cand->type, &cand->base_addr);558 559 PJ_LOG(4,(ice_st->obj_name,560 "Comp %d: host candidate %s added",561 comp_id, pj_sockaddr_print(&cand->addr, addrinfo,562 sizeof(addrinfo), 3)));563 }564 }565 672 } 566 673 567 674 /* Create TURN relay if configured. */ 568 if (ice_st->cfg.turn.server.slen) { 569 add_update_turn(ice_st, comp); 675 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) { 676 status = add_update_turn(ice_st, comp, i); 677 if (status != PJ_SUCCESS) 678 return status; 570 679 } 571 680 … … 630 739 631 740 pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg); 632 ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock; 633 ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock; 741 742 /* To maintain backward compatibility, check if old/deprecated setting is set 743 * and the new setting is not, copy the value to the new setting. 744 */ 745 if (cfg->stun_tp_cnt == 0 && 746 (cfg->stun.server.slen || cfg->stun.max_host_cands)) 747 { 748 ice_st->cfg.stun_tp_cnt = 1; 749 ice_st->cfg.stun_tp[0] = ice_st->cfg.stun; 750 } 751 if (cfg->turn_tp_cnt == 0 && cfg->turn.server.slen) { 752 ice_st->cfg.turn_tp_cnt = 1; 753 ice_st->cfg.turn_tp[0] = ice_st->cfg.turn; 754 } 755 756 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) 757 ice_st->cfg.stun_tp[i].cfg.grp_lock = ice_st->grp_lock; 758 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) 759 ice_st->cfg.turn_tp[i].cfg.grp_lock = ice_st->grp_lock; 634 760 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 635 761 … … 709 835 for (i=0; i<ice_st->comp_cnt; ++i) { 710 836 if (ice_st->comp[i]) { 711 if (ice_st->comp[i]->stun_sock) { 712 pj_stun_sock_destroy(ice_st->comp[i]->stun_sock); 713 ice_st->comp[i]->stun_sock = NULL; 837 pj_ice_strans_comp *comp = ice_st->comp[i]; 838 unsigned j; 839 for (j = 0; j < ice_st->cfg.stun_tp_cnt; ++j) { 840 if (comp->stun[j].sock) { 841 pj_stun_sock_destroy(comp->stun[j].sock); 842 comp->stun[j].sock = NULL; 843 } 714 844 } 715 if (ice_st->comp[i]->turn_sock) { 716 pj_turn_sock_destroy(ice_st->comp[i]->turn_sock); 717 ice_st->comp[i]->turn_sock = NULL; 845 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 846 if (comp->turn[j].sock) { 847 pj_turn_sock_destroy(comp->turn[j].sock); 848 comp->turn[j].sock = NULL; 849 } 718 850 } 719 851 } … … 912 1044 913 1045 /* Re-enable logging for Send/Data indications */ 914 if ( comp->turn_sock) {1046 if (ice_st->cfg.turn_tp_cnt) { 915 1047 PJ_LOG(5,(ice_st->obj_name, 916 " Disabling STUN Indication logging for "1048 "Enabling STUN Indication logging for " 917 1049 "component %d", i+1)); 918 pj_turn_sock_set_log(comp->turn_sock, 0xFFFF); 919 comp->turn_log_off = PJ_FALSE; 1050 } 1051 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 1052 if (comp->turn[j].sock) { 1053 pj_turn_sock_set_log(comp->turn[j].sock, 0xFFFF); 1054 comp->turn[j].log_off = PJ_FALSE; 1055 } 920 1056 } 921 1057 … … 1123 1259 const pj_ice_sess_cand rem_cand[]) 1124 1260 { 1261 unsigned n; 1125 1262 pj_status_t status; 1126 1263 … … 1138 1275 1139 1276 /* If we have TURN candidate, now is the time to create the permissions */ 1140 if (ice_st->comp[0]->turn_sock) {1277 for (n = 0; n < ice_st->cfg.turn_tp_cnt; ++n) { 1141 1278 unsigned i; 1142 1279 … … 1148 1285 /* Gather remote addresses for this component */ 1149 1286 for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) { 1150 if (rem_cand[j].comp_id==i+1) { 1151 pj_memcpy(&addrs[count++], &rem_cand[j].addr, 1152 pj_sockaddr_get_len(&rem_cand[j].addr)); 1287 if (rem_cand[j].comp_id==i+1 && 1288 rem_cand[j].addr.addr.sa_family== 1289 ice_st->cfg.turn_tp[n].af) 1290 { 1291 pj_sockaddr_cp(&addrs[count++], &rem_cand[j].addr); 1153 1292 } 1154 1293 } 1155 1294 1156 1295 if (count) { 1157 status = pj_turn_sock_set_perm(comp->turn _sock, count,1296 status = pj_turn_sock_set_perm(comp->turn[n].sock, count, 1158 1297 addrs, 0); 1159 1298 if (status != PJ_SUCCESS) { … … 1228 1367 { 1229 1368 pj_ice_strans_comp *comp; 1230 unsigneddef_cand;1369 pj_ice_sess_cand *def_cand; 1231 1370 pj_status_t status; 1232 1371 … … 1237 1376 1238 1377 /* Check that default candidate for the component exists */ 1239 def_cand = comp->default_cand; 1240 if (def_cand >= comp->cand_cnt) 1378 if (comp->default_cand >= comp->cand_cnt) 1241 1379 return PJ_EINVALIDOP; 1242 1380 … … 1262 1400 1263 1401 pj_grp_lock_release(ice_st->grp_lock); 1402 1403 def_cand = &comp->cand_list[comp->default_cand]; 1264 1404 1265 if (comp->cand_list[def_cand].status == PJ_SUCCESS) { 1266 1267 if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) { 1405 if (def_cand->status == PJ_SUCCESS) { 1406 unsigned tp_idx = GET_TP_IDX(def_cand->transport_id); 1407 1408 if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 1268 1409 1269 1410 enum { … … 1274 1415 1275 1416 /* https://trac.pjsip.org/repos/ticket/1316 */ 1276 if (comp->turn _sock == NULL) {1417 if (comp->turn[tp_idx].sock == NULL) { 1277 1418 /* TURN socket error */ 1278 1419 return PJ_EINVALIDOP; 1279 1420 } 1280 1421 1281 if (!comp->turn _log_off) {1422 if (!comp->turn[tp_idx].log_off) { 1282 1423 /* Disable logging for Send/Data indications */ 1283 1424 PJ_LOG(5,(ice_st->obj_name, 1284 1425 "Disabling STUN Indication logging for " 1285 1426 "component %d", comp->comp_id)); 1286 pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind); 1287 comp->turn_log_off = PJ_TRUE; 1427 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1428 msg_disable_ind); 1429 comp->turn[tp_idx].log_off = PJ_TRUE; 1288 1430 } 1289 1431 1290 status = pj_turn_sock_sendto(comp->turn _sock,1432 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1291 1433 (const pj_uint8_t*)data, 1292 1434 (unsigned)data_len, … … 1295 1437 PJ_SUCCESS : status; 1296 1438 } else { 1297 status = pj_stun_sock_sendto(comp->stun _sock, NULL, data,1439 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 1298 1440 (unsigned)data_len, 0, dst_addr, 1299 1441 dst_addr_len); … … 1343 1485 for (i=0; i<ice_st->comp_cnt; ++i) { 1344 1486 const pj_ice_sess_check *check; 1487 pj_ice_strans_comp *comp = ice_st->comp[i]; 1345 1488 1346 1489 check = pj_ice_strans_get_valid_pair(ice_st, i+1); … … 1348 1491 char lip[PJ_INET6_ADDRSTRLEN+10]; 1349 1492 char rip[PJ_INET6_ADDRSTRLEN+10]; 1493 unsigned tp_idx = GET_TP_IDX(check->lcand->transport_id); 1494 unsigned tp_typ = GET_TP_TYPE(check->lcand->transport_id); 1350 1495 1351 1496 pj_sockaddr_print(&check->lcand->addr, lip, … … 1354 1499 sizeof(rip), 3); 1355 1500 1356 if ( check->lcand->transport_id== TP_TURN) {1501 if (tp_typ == TP_TURN) { 1357 1502 /* Activate channel binding for the remote address 1358 1503 * for more efficient data transfer using TURN. 1359 1504 */ 1360 1505 status = pj_turn_sock_bind_channel( 1361 ice_st->comp[i]->turn_sock,1506 comp->turn[tp_idx].sock, 1362 1507 &check->rcand->addr, 1363 1508 sizeof(check->rcand->addr)); … … 1367 1512 "Disabling STUN Indication logging for " 1368 1513 "component %d", i+1)); 1369 pj_turn_sock_set_log( ice_st->comp[i]->turn_sock,1514 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1370 1515 msg_disable_ind); 1371 ice_st->comp[i]->turn_log_off = PJ_TRUE;1516 comp->turn[tp_idx].log_off = PJ_TRUE; 1372 1517 } 1373 1518 … … 1417 1562 char daddr[PJ_INET6_ADDRSTRLEN]; 1418 1563 #endif 1564 unsigned tp_idx = GET_TP_IDX(transport_id); 1565 unsigned tp_typ = GET_TP_TYPE(transport_id); 1419 1566 1420 1567 PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); … … 1427 1574 pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0), 1428 1575 pj_sockaddr_get_port(dst_addr), 1429 t ransport_id));1430 1431 if (t ransport_id== TP_TURN) {1432 if (comp->turn _sock) {1433 status = pj_turn_sock_sendto(comp->turn _sock,1576 tp_typ)); 1577 1578 if (tp_typ == TP_TURN) { 1579 if (comp->turn[tp_idx].sock) { 1580 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1434 1581 (const pj_uint8_t*)pkt, 1435 1582 (unsigned)size, … … 1438 1585 status = PJ_EINVALIDOP; 1439 1586 } 1440 } else if (t ransport_id== TP_STUN) {1441 status = pj_stun_sock_sendto(comp->stun _sock, NULL,1587 } else if (tp_typ == TP_STUN) { 1588 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 1442 1589 pkt, (unsigned)size, 0, 1443 1590 dst_addr, dst_addr_len); … … 1479 1626 unsigned addr_len) 1480 1627 { 1628 sock_user_data *data; 1481 1629 pj_ice_strans_comp *comp; 1482 1630 pj_ice_strans *ice_st; 1483 1631 pj_status_t status; 1484 1632 1485 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);1486 if ( comp== NULL) {1633 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1634 if (data == NULL) { 1487 1635 /* We have disassociated ourselves from the STUN socket */ 1488 1636 return PJ_FALSE; 1489 1637 } 1490 1638 1639 comp = data->comp; 1491 1640 ice_st = comp->ice_st; 1492 1641 … … 1507 1656 /* Hand over the packet to ICE session */ 1508 1657 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1509 TP_STUN, pkt, pkt_len, 1658 data->transport_id, 1659 pkt, pkt_len, 1510 1660 src_addr, addr_len); 1511 1661 … … 1537 1687 pj_status_t status) 1538 1688 { 1689 sock_user_data *data; 1539 1690 pj_ice_strans_comp *comp; 1540 1691 pj_ice_strans *ice_st; 1541 1692 pj_ice_sess_cand *cand = NULL; 1542 1693 unsigned i; 1694 int tp_idx; 1543 1695 1544 1696 pj_assert(status != PJ_EPENDING); 1545 1697 1546 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 1698 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1699 comp = data->comp; 1547 1700 ice_st = comp->ice_st; 1548 1701 … … 1554 1707 /* Find the srflx cancidate */ 1555 1708 for (i=0; i<comp->cand_cnt; ++i) { 1556 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) { 1709 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX && 1710 comp->cand_list[i].transport_id == data->transport_id) 1711 { 1557 1712 cand = &comp->cand_list[i]; 1558 1713 break; … … 1570 1725 } 1571 1726 1727 tp_idx = GET_TP_IDX(data->transport_id); 1728 1572 1729 switch (op) { 1573 1730 case PJ_STUN_SOCK_DNS_OP: … … 1576 1733 if (cand) 1577 1734 cand->status = status; 1578 if (!ice_st->cfg.stun .ignore_stun_error) {1735 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1579 1736 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1580 1737 "DNS resolution failed", status); … … 1656 1813 if (cand) 1657 1814 cand->status = status; 1658 if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) { 1815 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error || 1816 comp->cand_cnt==1) 1817 { 1659 1818 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1660 1819 "STUN binding request failed", status); … … 1681 1840 pj_assert(cand != NULL); 1682 1841 cand->status = status; 1683 if (!ice_st->cfg.stun .ignore_stun_error) {1842 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1684 1843 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1685 1844 "STUN keep-alive failed", status); … … 1702 1861 { 1703 1862 pj_ice_strans_comp *comp; 1863 sock_user_data *data; 1704 1864 pj_status_t status; 1705 1865 1706 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);1707 if ( comp== NULL) {1866 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1867 if (data == NULL) { 1708 1868 /* We have disassociated ourselves from the TURN socket */ 1709 1869 return; 1710 1870 } 1871 1872 comp = data->comp; 1711 1873 1712 1874 pj_grp_lock_add_ref(comp->ice_st->grp_lock); … … 1727 1889 /* Hand over the packet to ICE */ 1728 1890 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1729 TP_TURN, pkt, pkt_len,1891 data->transport_id, pkt, pkt_len, 1730 1892 peer_addr, addr_len); 1731 1893 … … 1746 1908 { 1747 1909 pj_ice_strans_comp *comp; 1748 1749 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 1750 if (comp == NULL) { 1910 sock_user_data *data; 1911 int tp_idx; 1912 1913 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1914 if (data == NULL) { 1751 1915 /* Not interested in further state notification once the relay is 1752 1916 * disconnecting. … … 1754 1918 return; 1755 1919 } 1920 1921 comp = data->comp; 1922 tp_idx = GET_TP_IDX(data->transport_id); 1756 1923 1757 1924 PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", … … 1767 1934 unsigned i; 1768 1935 1769 comp->turn _err_cnt = 0;1936 comp->turn[tp_idx].err_cnt = 0; 1770 1937 1771 1938 /* Get allocation info */ … … 1777 1944 /* Find relayed candidate in the component */ 1778 1945 for (i=0; i<comp->cand_cnt; ++i) { 1779 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 1946 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 1947 comp->cand_list[i].transport_id == data->transport_id) 1948 { 1780 1949 cand = &comp->cand_list[i]; 1781 1950 break; … … 1809 1978 pj_turn_session_info info; 1810 1979 1811 ++comp->turn _err_cnt;1980 ++comp->turn[tp_idx].err_cnt; 1812 1981 1813 1982 pj_turn_sock_get_info(turn_sock, &info); … … 1815 1984 /* Unregister ourself from the TURN relay */ 1816 1985 pj_turn_sock_set_user_data(turn_sock, NULL); 1817 comp->turn _sock = NULL;1986 comp->turn[tp_idx].sock = NULL; 1818 1987 1819 1988 /* Set session to fail on error. last_status PJ_SUCCESS means normal … … 1825 1994 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT, 1826 1995 "TURN allocation failed", info.last_status); 1827 } else if (comp->turn _err_cnt > 1) {1996 } else if (comp->turn[tp_idx].err_cnt > 1) { 1828 1997 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE, 1829 1998 "TURN refresh failed", info.last_status); … … 1832 2001 "Comp %d: TURN allocation failed, retrying", 1833 2002 comp->comp_id)); 1834 add_update_turn(comp->ice_st, comp );2003 add_update_turn(comp->ice_st, comp, tp_idx); 1835 2004 } 1836 2005 }
Note: See TracChangeset
for help on using the changeset viewer.