- Timestamp:
- Dec 28, 2016 3:40:07 AM (8 years ago)
- Location:
- pjproject/branches/projects/uwp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/uwp
- Property svn:mergeinfo changed
/pjproject/trunk (added) merged: 5209,5212-5234,5237-5253,5255,5257-5292,5294-5297,5299-5332,5334-5394,5396-5438,5440-5469,5471-5496,5498-5510
- Property svn:mergeinfo changed
-
pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c
r5151 r5513 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. */ 155 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]; 166 167 pj_bool_t creating; /**< Is creating the candidates?*/ 156 168 unsigned cand_cnt; /**< # of candidates/aliaes. */ 157 169 pj_ice_sess_cand cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */ … … 188 200 189 201 202 /** 203 * This structure describe user data for STUN/TURN sockets of the 204 * ICE stream transport. 205 */ 206 typedef struct sock_user_data 207 { 208 pj_ice_strans_comp *comp; 209 pj_uint8_t transport_id; 210 211 } sock_user_data; 212 213 190 214 /* Validate configuration */ 191 215 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) … … 209 233 210 234 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 235 pj_ice_strans_stun_cfg_default(&cfg->stun); 236 pj_ice_strans_turn_cfg_default(&cfg->turn); 215 237 pj_ice_sess_options_default(&cfg->opt); 238 } 239 240 241 /* 242 * Initialize ICE STUN transport configuration with default values. 243 */ 244 PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg) 245 { 246 pj_bzero(cfg, sizeof(*cfg)); 216 247 217 248 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; 249 cfg->port = PJ_STUN_PORT; 250 cfg->max_host_cands = 64; 251 cfg->ignore_stun_error = PJ_FALSE; 252 pj_stun_sock_cfg_default(&cfg->cfg); 253 } 254 255 256 /* 257 * Initialize ICE TURN transport configuration with default values. 258 */ 259 PJ_DEF(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg) 260 { 261 pj_bzero(cfg, sizeof(*cfg)); 262 263 cfg->af = pj_AF_INET(); 264 cfg->conn_type = PJ_TURN_TP_UDP; 265 pj_turn_alloc_param_default(&cfg->alloc_param); 266 pj_turn_sock_cfg_default(&cfg->cfg); 223 267 } 224 268 … … 231 275 const pj_ice_strans_cfg *src) 232 276 { 277 unsigned i; 278 233 279 pj_memcpy(dst, src, sizeof(*src)); 234 280 235 281 if (src->stun.server.slen) 236 282 pj_strdup(pool, &dst->stun.server, &src->stun.server); 283 284 for (i = 0; i < src->stun_tp_cnt; ++i) { 285 if (src->stun_tp[i].server.slen) 286 pj_strdup(pool, &dst->stun_tp[i].server, 287 &src->stun_tp[i].server); 288 } 289 237 290 if (src->turn.server.slen) 238 291 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); 292 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, &src->turn.auth_cred); 293 294 for (i = 0; i < src->turn_tp_cnt; ++i) { 295 if (src->turn_tp[i].server.slen) 296 pj_strdup(pool, &dst->turn_tp[i].server, 297 &src->turn_tp[i].server); 298 pj_stun_auth_cred_dup(pool, &dst->turn_tp[i].auth_cred, 299 &src->turn_tp[i].auth_cred); 300 } 241 301 } 242 302 … … 246 306 */ 247 307 static pj_status_t add_update_turn(pj_ice_strans *ice_st, 248 pj_ice_strans_comp *comp) 249 { 308 pj_ice_strans_comp *comp, 309 unsigned idx) 310 { 311 pj_ice_sess_cand *cand = NULL; 312 pj_ice_strans_turn_cfg *turn_cfg = &ice_st->cfg.turn_tp[idx]; 313 pj_turn_sock_cfg *sock_cfg = &turn_cfg->cfg; 314 unsigned comp_idx = comp->comp_id - 1; 250 315 pj_turn_sock_cb turn_sock_cb; 251 pj_ice_sess_cand *cand = NULL;316 sock_user_data *data; 252 317 unsigned i; 318 pj_uint8_t tp_id; 253 319 pj_status_t status; 254 320 321 /* Check if TURN transport is configured */ 322 if (turn_cfg->server.slen == 0) 323 return PJ_SUCCESS; 324 255 325 /* Find relayed candidate in the component */ 326 tp_id = CREATE_TP_ID(TP_TURN, idx); 256 327 for (i=0; i<comp->cand_cnt; ++i) { 257 if (comp->cand_list[i].t ype == PJ_ICE_CAND_TYPE_RELAYED) {328 if (comp->cand_list[i].transport_id == tp_id) { 258 329 cand = &comp->cand_list[i]; 259 330 break; … … 287 358 288 359 /* 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 } 360 if (ice_st->cfg.comp[comp_idx].qos_type) 361 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 362 if (ice_st->cfg.comp[comp_idx].qos_params.flags) 363 pj_memcpy(&sock_cfg->qos_params, 364 &ice_st->cfg.comp[comp_idx].qos_params, 365 sizeof(sock_cfg->qos_params)); 298 366 299 367 /* 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 } 368 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) 369 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 370 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) 371 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 372 373 /* Add relayed candidate with pending status if there's no existing one */ 374 if (cand == NULL) { 375 cand = &comp->cand_list[comp->cand_cnt]; 376 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 377 cand->status = PJ_EPENDING; 378 cand->local_pref = RELAY_PREF; 379 cand->transport_id = CREATE_TP_ID(TP_TURN, idx); 380 cand->comp_id = (pj_uint8_t) comp->comp_id; 381 } 382 383 /* Allocate and initialize TURN socket data */ 384 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 385 data->comp = comp; 386 data->transport_id = cand->transport_id; 308 387 309 388 /* 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);389 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, turn_cfg->af, 390 turn_cfg->conn_type, 391 &turn_sock_cb, sock_cfg, 392 data, &comp->turn[idx].sock); 314 393 if (status != PJ_SUCCESS) { 315 394 return status; … … 320 399 321 400 /* Start allocation */ 322 status=pj_turn_sock_alloc(comp->turn _sock,323 & ice_st->cfg.turn.server,324 ice_st->cfg.turn.port,401 status=pj_turn_sock_alloc(comp->turn[idx].sock, 402 &turn_cfg->server, 403 turn_cfg->port, 325 404 ice_st->cfg.resolver, 326 & ice_st->cfg.turn.auth_cred,327 & ice_st->cfg.turn.alloc_param);405 &turn_cfg->auth_cred, 406 &turn_cfg->alloc_param); 328 407 if (status != PJ_SUCCESS) { 329 408 ///sess_dec_ref(ice_st); … … 331 410 } 332 411 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 } 412 /* Commit the relayed candidate. */ 413 comp->cand_cnt++; 342 414 343 415 PJ_LOG(4,(ice_st->obj_name, … … 348 420 } 349 421 422 static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand, 423 pj_ice_sess_cand *rcand) 424 { 425 if (lcand == NULL && rcand == NULL){ 426 return PJ_TRUE; 427 } 428 if (lcand == NULL || rcand == NULL){ 429 return PJ_FALSE; 430 } 431 432 if (lcand->type != rcand->type 433 || lcand->status != rcand->status 434 || lcand->comp_id != rcand->comp_id 435 || lcand->transport_id != rcand->transport_id 436 || lcand->local_pref != rcand->local_pref 437 || lcand->prio != rcand->prio 438 || pj_sockaddr_cmp(&lcand->addr, &rcand->addr) != 0 439 || pj_sockaddr_cmp(&lcand->base_addr, &rcand->base_addr) != 0) 440 { 441 return PJ_FALSE; 442 } 443 444 return PJ_TRUE; 445 } 446 447 448 static pj_status_t add_stun_and_host(pj_ice_strans *ice_st, 449 pj_ice_strans_comp *comp, 450 unsigned idx) 451 { 452 pj_ice_sess_cand *cand; 453 pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx]; 454 pj_stun_sock_cfg *sock_cfg = &stun_cfg->cfg; 455 unsigned comp_idx = comp->comp_id - 1; 456 pj_stun_sock_cb stun_sock_cb; 457 sock_user_data *data; 458 pj_status_t status; 459 460 /* Check if STUN transport or host candidate is configured */ 461 if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0) 462 return PJ_SUCCESS; 463 464 /* Initialize STUN socket callback */ 465 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 466 stun_sock_cb.on_rx_data = &stun_on_rx_data; 467 stun_sock_cb.on_status = &stun_on_status; 468 stun_sock_cb.on_data_sent = &stun_on_data_sent; 469 470 /* Override component specific QoS settings, if any */ 471 if (ice_st->cfg.comp[comp_idx].qos_type) { 472 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 473 } 474 if (ice_st->cfg.comp[comp_idx].qos_params.flags) { 475 pj_memcpy(&sock_cfg->qos_params, 476 &ice_st->cfg.comp[comp_idx].qos_params, 477 sizeof(sock_cfg->qos_params)); 478 } 479 480 /* Override component specific socket buffer size settings, if any */ 481 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) { 482 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 483 } 484 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) { 485 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 486 } 487 488 /* Prepare srflx candidate with pending status. */ 489 cand = &comp->cand_list[comp->cand_cnt]; 490 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 491 cand->status = PJ_EPENDING; 492 cand->local_pref = SRFLX_PREF; 493 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 494 cand->comp_id = (pj_uint8_t) comp->comp_id; 495 496 /* Allocate and initialize STUN socket data */ 497 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 498 data->comp = comp; 499 data->transport_id = cand->transport_id; 500 501 /* Create the STUN transport */ 502 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 503 stun_cfg->af, &stun_sock_cb, 504 sock_cfg, data, &comp->stun[idx].sock); 505 if (status != PJ_SUCCESS) 506 return status; 507 508 /* Start STUN Binding resolution and add srflx candidate 509 * only if server is set 510 */ 511 if (stun_cfg->server.slen) { 512 pj_stun_sock_info stun_sock_info; 513 514 /* Add pending job */ 515 ///sess_add_ref(ice_st); 516 517 PJ_LOG(4,(ice_st->obj_name, 518 "Comp %d: srflx candidate starts Binding discovery", 519 comp->comp_id)); 520 521 pj_log_push_indent(); 522 523 /* Start Binding resolution */ 524 status = pj_stun_sock_start(comp->stun[idx].sock, &stun_cfg->server, 525 stun_cfg->port, ice_st->cfg.resolver); 526 if (status != PJ_SUCCESS) { 527 ///sess_dec_ref(ice_st); 528 pj_log_pop_indent(); 529 return status; 530 } 531 532 /* Enumerate addresses */ 533 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 534 if (status != PJ_SUCCESS) { 535 ///sess_dec_ref(ice_st); 536 pj_log_pop_indent(); 537 return status; 538 } 539 540 /* Update and commit the srflx candidate. */ 541 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 542 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 543 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 544 cand->type, &cand->base_addr); 545 comp->cand_cnt++; 546 547 /* Set default candidate to srflx */ 548 comp->default_cand = (unsigned)(cand - comp->cand_list); 549 550 pj_log_pop_indent(); 551 } 552 553 /* Add local addresses to host candidates, unless max_host_cands 554 * is set to zero. 555 */ 556 if (stun_cfg->max_host_cands) { 557 pj_stun_sock_info stun_sock_info; 558 unsigned i; 559 560 /* Enumerate addresses */ 561 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 562 if (status != PJ_SUCCESS) 563 return status; 564 565 for (i=0; i<stun_sock_info.alias_cnt && 566 i<stun_cfg->max_host_cands; ++i) 567 { 568 unsigned j; 569 pj_bool_t cand_duplicate = PJ_FALSE; 570 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 571 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 572 573 /* Leave one candidate for relay */ 574 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 575 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 576 break; 577 } 578 579 /* Ignore loopback addresses if cfg->stun.loop_addr is unset */ 580 if (stun_cfg->loop_addr==PJ_FALSE) { 581 if (stun_cfg->af == pj_AF_INET() && 582 (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) 583 { 584 continue; 585 } 586 else if (stun_cfg->af == pj_AF_INET6()) { 587 pj_in6_addr in6addr = {{0}}; 588 in6addr.s6_addr[15] = 1; 589 if (pj_memcmp(&in6addr, &addr->ipv6.sin6_addr, 590 sizeof(in6addr))==0) 591 { 592 continue; 593 } 594 } 595 } 596 597 /* Ignore IPv6 link-local address */ 598 if (stun_cfg->af == pj_AF_INET6()) { 599 const pj_in6_addr *a = &addr->ipv6.sin6_addr; 600 if (a->s6_addr[0] == 0xFE && (a->s6_addr[1] & 0xC0) == 0x80) 601 continue; 602 } 603 604 cand = &comp->cand_list[comp->cand_cnt]; 605 606 cand->type = PJ_ICE_CAND_TYPE_HOST; 607 cand->status = PJ_SUCCESS; 608 cand->local_pref = HOST_PREF; 609 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 610 cand->comp_id = (pj_uint8_t) comp->comp_id; 611 pj_sockaddr_cp(&cand->addr, addr); 612 pj_sockaddr_cp(&cand->base_addr, addr); 613 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 614 615 /* Check if not already in list */ 616 for (j=0; j<comp->cand_cnt; j++) { 617 if (ice_cand_equals(cand, &comp->cand_list[j])) { 618 cand_duplicate = PJ_TRUE; 619 break; 620 } 621 } 622 623 if (cand_duplicate) { 624 PJ_LOG(4, (ice_st->obj_name, 625 "Comp %d: host candidate %s is a duplicate", 626 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 627 sizeof(addrinfo), 3))); 628 629 pj_bzero(&cand->addr, sizeof(cand->addr)); 630 pj_bzero(&cand->base_addr, sizeof(cand->base_addr)); 631 continue; 632 } else { 633 comp->cand_cnt+=1; 634 } 635 636 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 637 cand->type, &cand->base_addr); 638 639 PJ_LOG(4,(ice_st->obj_name, 640 "Comp %d: host candidate %s added", 641 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 642 sizeof(addrinfo), 3))); 643 } 644 } 645 646 return PJ_SUCCESS; 647 } 648 350 649 351 650 /* … … 355 654 { 356 655 pj_ice_strans_comp *comp = NULL; 656 unsigned i; 357 657 pj_status_t status; 358 658 … … 367 667 comp->ice_st = ice_st; 368 668 comp->comp_id = comp_id; 669 comp->creating = PJ_TRUE; 369 670 370 671 ice_st->comp[comp_id-1] = comp; … … 374 675 375 676 /* Create STUN transport if configured */ 376 if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) { 377 pj_stun_sock_cb stun_sock_cb; 378 pj_ice_sess_cand *cand; 379 380 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 381 stun_sock_cb.on_rx_data = &stun_on_rx_data; 382 stun_sock_cb.on_status = &stun_on_status; 383 stun_sock_cb.on_data_sent = &stun_on_data_sent; 384 385 /* Override component specific QoS settings, if any */ 386 if (ice_st->cfg.comp[comp_id-1].qos_type) { 387 ice_st->cfg.stun.cfg.qos_type = 388 ice_st->cfg.comp[comp_id-1].qos_type; 389 } 390 if (ice_st->cfg.comp[comp_id-1].qos_params.flags) { 391 pj_memcpy(&ice_st->cfg.stun.cfg.qos_params, 392 &ice_st->cfg.comp[comp_id-1].qos_params, 393 sizeof(ice_st->cfg.stun.cfg.qos_params)); 394 } 395 396 /* Override component specific socket buffer size settings, if any */ 397 if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) { 398 ice_st->cfg.stun.cfg.so_rcvbuf_size = 399 ice_st->cfg.comp[comp_id-1].so_rcvbuf_size; 400 } 401 if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) { 402 ice_st->cfg.stun.cfg.so_sndbuf_size = 403 ice_st->cfg.comp[comp_id-1].so_sndbuf_size; 404 } 405 406 /* Create the STUN transport */ 407 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 408 ice_st->cfg.af, &stun_sock_cb, 409 &ice_st->cfg.stun.cfg, 410 comp, &comp->stun_sock); 411 if (status != PJ_SUCCESS) 412 return status; 413 414 /* Start STUN Binding resolution and add srflx candidate 415 * only if server is set 416 */ 417 if (ice_st->cfg.stun.server.slen) { 418 pj_stun_sock_info stun_sock_info; 419 420 /* Add pending job */ 421 ///sess_add_ref(ice_st); 422 423 PJ_LOG(4,(ice_st->obj_name, 424 "Comp %d: srflx candidate starts Binding discovery", 425 comp_id)); 426 427 pj_log_push_indent(); 428 429 /* Start Binding resolution */ 430 status = pj_stun_sock_start(comp->stun_sock, 431 &ice_st->cfg.stun.server, 432 ice_st->cfg.stun.port, 433 ice_st->cfg.resolver); 434 if (status != PJ_SUCCESS) { 435 ///sess_dec_ref(ice_st); 436 pj_log_pop_indent(); 437 return status; 438 } 439 440 /* Enumerate addresses */ 441 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 442 if (status != PJ_SUCCESS) { 443 ///sess_dec_ref(ice_st); 444 pj_log_pop_indent(); 445 return status; 446 } 447 448 /* Add srflx candidate with pending status. */ 449 cand = &comp->cand_list[comp->cand_cnt++]; 450 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 451 cand->status = PJ_EPENDING; 452 cand->local_pref = SRFLX_PREF; 453 cand->transport_id = TP_STUN; 454 cand->comp_id = (pj_uint8_t) comp_id; 455 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 456 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 457 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 458 cand->type, &cand->base_addr); 459 460 /* Set default candidate to srflx */ 461 comp->default_cand = (unsigned)(cand - comp->cand_list); 462 463 pj_log_pop_indent(); 464 } 465 466 /* Add local addresses to host candidates, unless max_host_cands 467 * is set to zero. 468 */ 469 if (ice_st->cfg.stun.max_host_cands) { 470 pj_stun_sock_info stun_sock_info; 471 unsigned i; 472 473 /* Enumerate addresses */ 474 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 475 if (status != PJ_SUCCESS) 476 return status; 477 478 for (i=0; i<stun_sock_info.alias_cnt && 479 i<ice_st->cfg.stun.max_host_cands; ++i) 480 { 481 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 482 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 483 484 /* Leave one candidate for relay */ 485 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 486 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 487 break; 488 } 489 490 /* Ignore loopback addresses unless cfg->stun.loop_addr 491 * is set 492 */ 493 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) { 494 if (ice_st->cfg.stun.loop_addr==PJ_FALSE) 495 continue; 496 } 497 498 cand = &comp->cand_list[comp->cand_cnt++]; 499 500 cand->type = PJ_ICE_CAND_TYPE_HOST; 501 cand->status = PJ_SUCCESS; 502 cand->local_pref = HOST_PREF; 503 cand->transport_id = TP_STUN; 504 cand->comp_id = (pj_uint8_t) comp_id; 505 pj_sockaddr_cp(&cand->addr, addr); 506 pj_sockaddr_cp(&cand->base_addr, addr); 507 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 508 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 509 cand->type, &cand->base_addr); 510 511 PJ_LOG(4,(ice_st->obj_name, 512 "Comp %d: host candidate %s added", 513 comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 514 sizeof(addrinfo), 3))); 515 } 677 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) { 678 status = add_stun_and_host(ice_st, comp, i); 679 if (status != PJ_SUCCESS) { 680 PJ_PERROR(3,(ice_st->obj_name, status, 681 "Failed creating STUN transport #%d for comp %d", 682 i, comp->comp_id)); 683 //return status; 516 684 } 517 685 } 518 686 519 687 /* Create TURN relay if configured. */ 520 if (ice_st->cfg.turn.server.slen) { 521 add_update_turn(ice_st, comp); 522 } 688 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) { 689 status = add_update_turn(ice_st, comp, i); 690 if (status != PJ_SUCCESS) { 691 PJ_PERROR(3,(ice_st->obj_name, status, 692 "Failed creating TURN transport #%d for comp %d", 693 i, comp->comp_id)); 694 //return status; 695 } 696 } 697 698 /* Done creating all the candidates */ 699 comp->creating = PJ_FALSE; 523 700 524 701 /* It's possible that we end up without any candidates */ … … 582 759 583 760 pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg); 584 ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock; 585 ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock; 761 762 /* To maintain backward compatibility, check if old/deprecated setting is set 763 * and the new setting is not, copy the value to the new setting. 764 */ 765 if (cfg->stun_tp_cnt == 0 && 766 (cfg->stun.server.slen || cfg->stun.max_host_cands)) 767 { 768 ice_st->cfg.stun_tp_cnt = 1; 769 ice_st->cfg.stun_tp[0] = ice_st->cfg.stun; 770 } 771 if (cfg->turn_tp_cnt == 0 && cfg->turn.server.slen) { 772 ice_st->cfg.turn_tp_cnt = 1; 773 ice_st->cfg.turn_tp[0] = ice_st->cfg.turn; 774 } 775 776 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) 777 ice_st->cfg.stun_tp[i].cfg.grp_lock = ice_st->grp_lock; 778 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) 779 ice_st->cfg.turn_tp[i].cfg.grp_lock = ice_st->grp_lock; 586 780 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 587 781 … … 661 855 for (i=0; i<ice_st->comp_cnt; ++i) { 662 856 if (ice_st->comp[i]) { 663 if (ice_st->comp[i]->stun_sock) { 664 pj_stun_sock_destroy(ice_st->comp[i]->stun_sock); 665 ice_st->comp[i]->stun_sock = NULL; 666 } 667 if (ice_st->comp[i]->turn_sock) { 668 pj_turn_sock_destroy(ice_st->comp[i]->turn_sock); 669 ice_st->comp[i]->turn_sock = NULL; 857 pj_ice_strans_comp *comp = ice_st->comp[i]; 858 unsigned j; 859 for (j = 0; j < ice_st->cfg.stun_tp_cnt; ++j) { 860 if (comp->stun[j].sock) { 861 pj_stun_sock_destroy(comp->stun[j].sock); 862 comp->stun[j].sock = NULL; 863 } 864 } 865 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 866 if (comp->turn[j].sock) { 867 pj_turn_sock_destroy(comp->turn[j].sock); 868 comp->turn[j].sock = NULL; 869 } 670 870 } 671 871 } … … 738 938 pj_ice_strans_comp *comp = ice_st->comp[i]; 739 939 940 /* This function can be called when all components or candidates 941 * have not been created. 942 */ 943 if (!comp || comp->creating) return; 944 740 945 for (j=0; j<comp->cand_cnt; ++j) { 741 946 pj_ice_sess_cand *cand = &comp->cand_list[j]; … … 864 1069 865 1070 /* Re-enable logging for Send/Data indications */ 866 if ( comp->turn_sock) {1071 if (ice_st->cfg.turn_tp_cnt) { 867 1072 PJ_LOG(5,(ice_st->obj_name, 868 " Disabling STUN Indication logging for "1073 "Enabling STUN Indication logging for " 869 1074 "component %d", i+1)); 870 pj_turn_sock_set_log(comp->turn_sock, 0xFFFF); 871 comp->turn_log_off = PJ_FALSE; 1075 } 1076 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 1077 if (comp->turn[j].sock) { 1078 pj_turn_sock_set_log(comp->turn[j].sock, 0xFFFF); 1079 comp->turn[j].log_off = PJ_FALSE; 1080 } 872 1081 } 873 1082 … … 1075 1284 const pj_ice_sess_cand rem_cand[]) 1076 1285 { 1286 unsigned n; 1077 1287 pj_status_t status; 1078 1288 … … 1090 1300 1091 1301 /* If we have TURN candidate, now is the time to create the permissions */ 1092 if (ice_st->comp[0]->turn_sock) {1302 for (n = 0; n < ice_st->cfg.turn_tp_cnt; ++n) { 1093 1303 unsigned i; 1094 1304 … … 1100 1310 /* Gather remote addresses for this component */ 1101 1311 for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) { 1102 if (rem_cand[j].comp_id==i+1) { 1103 pj_memcpy(&addrs[count++], &rem_cand[j].addr, 1104 pj_sockaddr_get_len(&rem_cand[j].addr)); 1312 if (rem_cand[j].comp_id==i+1 && 1313 rem_cand[j].addr.addr.sa_family== 1314 ice_st->cfg.turn_tp[n].af) 1315 { 1316 pj_sockaddr_cp(&addrs[count++], &rem_cand[j].addr); 1105 1317 } 1106 1318 } 1107 1319 1108 if (count ) {1109 status = pj_turn_sock_set_perm(comp->turn _sock, count,1320 if (count && !comp->turn[n].err_cnt && comp->turn[n].sock) { 1321 status = pj_turn_sock_set_perm(comp->turn[n].sock, count, 1110 1322 addrs, 0); 1111 1323 if (status != PJ_SUCCESS) { … … 1180 1392 { 1181 1393 pj_ice_strans_comp *comp; 1182 unsigneddef_cand;1394 pj_ice_sess_cand *def_cand; 1183 1395 pj_status_t status; 1184 1396 … … 1189 1401 1190 1402 /* Check that default candidate for the component exists */ 1191 def_cand = comp->default_cand; 1192 if (def_cand >= comp->cand_cnt) 1403 if (comp->default_cand >= comp->cand_cnt) 1193 1404 return PJ_EINVALIDOP; 1194 1405 … … 1214 1425 1215 1426 pj_grp_lock_release(ice_st->grp_lock); 1427 1428 def_cand = &comp->cand_list[comp->default_cand]; 1216 1429 1217 if (comp->cand_list[def_cand].status == PJ_SUCCESS) { 1218 1219 if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) { 1430 if (def_cand->status == PJ_SUCCESS) { 1431 unsigned tp_idx = GET_TP_IDX(def_cand->transport_id); 1432 1433 if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 1220 1434 1221 1435 enum { … … 1226 1440 1227 1441 /* https://trac.pjsip.org/repos/ticket/1316 */ 1228 if (comp->turn _sock == NULL) {1442 if (comp->turn[tp_idx].sock == NULL) { 1229 1443 /* TURN socket error */ 1230 1444 return PJ_EINVALIDOP; 1231 1445 } 1232 1446 1233 if (!comp->turn _log_off) {1447 if (!comp->turn[tp_idx].log_off) { 1234 1448 /* Disable logging for Send/Data indications */ 1235 1449 PJ_LOG(5,(ice_st->obj_name, 1236 1450 "Disabling STUN Indication logging for " 1237 1451 "component %d", comp->comp_id)); 1238 pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind); 1239 comp->turn_log_off = PJ_TRUE; 1240 } 1241 1242 status = pj_turn_sock_sendto(comp->turn_sock, 1452 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1453 msg_disable_ind); 1454 comp->turn[tp_idx].log_off = PJ_TRUE; 1455 } 1456 1457 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1243 1458 (const pj_uint8_t*)data, 1244 1459 (unsigned)data_len, … … 1247 1462 PJ_SUCCESS : status; 1248 1463 } else { 1249 status = pj_stun_sock_sendto(comp->stun _sock, NULL, data,1464 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 1250 1465 (unsigned)data_len, 0, dst_addr, 1251 1466 dst_addr_len); … … 1295 1510 for (i=0; i<ice_st->comp_cnt; ++i) { 1296 1511 const pj_ice_sess_check *check; 1512 pj_ice_strans_comp *comp = ice_st->comp[i]; 1297 1513 1298 1514 check = pj_ice_strans_get_valid_pair(ice_st, i+1); … … 1300 1516 char lip[PJ_INET6_ADDRSTRLEN+10]; 1301 1517 char rip[PJ_INET6_ADDRSTRLEN+10]; 1518 unsigned tp_idx = GET_TP_IDX(check->lcand->transport_id); 1519 unsigned tp_typ = GET_TP_TYPE(check->lcand->transport_id); 1302 1520 1303 1521 pj_sockaddr_print(&check->lcand->addr, lip, … … 1306 1524 sizeof(rip), 3); 1307 1525 1308 if ( check->lcand->transport_id== TP_TURN) {1526 if (tp_typ == TP_TURN) { 1309 1527 /* Activate channel binding for the remote address 1310 1528 * for more efficient data transfer using TURN. 1311 1529 */ 1312 1530 status = pj_turn_sock_bind_channel( 1313 ice_st->comp[i]->turn_sock,1531 comp->turn[tp_idx].sock, 1314 1532 &check->rcand->addr, 1315 1533 sizeof(check->rcand->addr)); … … 1319 1537 "Disabling STUN Indication logging for " 1320 1538 "component %d", i+1)); 1321 pj_turn_sock_set_log( ice_st->comp[i]->turn_sock,1539 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1322 1540 msg_disable_ind); 1323 ice_st->comp[i]->turn_log_off = PJ_TRUE;1541 comp->turn[tp_idx].log_off = PJ_TRUE; 1324 1542 } 1325 1543 … … 1369 1587 char daddr[PJ_INET6_ADDRSTRLEN]; 1370 1588 #endif 1589 unsigned tp_idx = GET_TP_IDX(transport_id); 1590 unsigned tp_typ = GET_TP_TYPE(transport_id); 1371 1591 1372 1592 PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); … … 1379 1599 pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0), 1380 1600 pj_sockaddr_get_port(dst_addr), 1381 t ransport_id));1382 1383 if (t ransport_id== TP_TURN) {1384 if (comp->turn _sock) {1385 status = pj_turn_sock_sendto(comp->turn _sock,1601 tp_typ)); 1602 1603 if (tp_typ == TP_TURN) { 1604 if (comp->turn[tp_idx].sock) { 1605 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1386 1606 (const pj_uint8_t*)pkt, 1387 1607 (unsigned)size, … … 1390 1610 status = PJ_EINVALIDOP; 1391 1611 } 1392 } else if (t ransport_id== TP_STUN) {1393 status = pj_stun_sock_sendto(comp->stun _sock, NULL,1612 } else if (tp_typ == TP_STUN) { 1613 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 1394 1614 pkt, (unsigned)size, 0, 1395 1615 dst_addr, dst_addr_len); … … 1431 1651 unsigned addr_len) 1432 1652 { 1653 sock_user_data *data; 1433 1654 pj_ice_strans_comp *comp; 1434 1655 pj_ice_strans *ice_st; 1435 1656 pj_status_t status; 1436 1657 1437 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);1438 if ( comp== NULL) {1658 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1659 if (data == NULL) { 1439 1660 /* We have disassociated ourselves from the STUN socket */ 1440 1661 return PJ_FALSE; 1441 1662 } 1442 1663 1664 comp = data->comp; 1443 1665 ice_st = comp->ice_st; 1444 1666 … … 1459 1681 /* Hand over the packet to ICE session */ 1460 1682 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1461 TP_STUN, pkt, pkt_len, 1683 data->transport_id, 1684 pkt, pkt_len, 1462 1685 src_addr, addr_len); 1463 1686 … … 1489 1712 pj_status_t status) 1490 1713 { 1714 sock_user_data *data; 1491 1715 pj_ice_strans_comp *comp; 1492 1716 pj_ice_strans *ice_st; 1493 1717 pj_ice_sess_cand *cand = NULL; 1494 1718 unsigned i; 1719 int tp_idx; 1495 1720 1496 1721 pj_assert(status != PJ_EPENDING); 1497 1722 1498 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 1723 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1724 comp = data->comp; 1499 1725 ice_st = comp->ice_st; 1500 1726 … … 1506 1732 /* Find the srflx cancidate */ 1507 1733 for (i=0; i<comp->cand_cnt; ++i) { 1508 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) { 1734 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX && 1735 comp->cand_list[i].transport_id == data->transport_id) 1736 { 1509 1737 cand = &comp->cand_list[i]; 1510 1738 break; … … 1522 1750 } 1523 1751 1752 tp_idx = GET_TP_IDX(data->transport_id); 1753 1524 1754 switch (op) { 1525 1755 case PJ_STUN_SOCK_DNS_OP: … … 1528 1758 if (cand) 1529 1759 cand->status = status; 1530 if (!ice_st->cfg.stun .ignore_stun_error) {1760 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1531 1761 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1532 1762 "DNS resolution failed", status); … … 1593 1823 1594 1824 sess_init_update(ice_st); 1825 1826 if (op == PJ_STUN_SOCK_MAPPED_ADDR_CHANGE && 1827 ice_st->cb.on_ice_complete) 1828 { 1829 (*ice_st->cb.on_ice_complete)(ice_st, 1830 PJ_ICE_STRANS_OP_ADDR_CHANGE, 1831 status); 1832 } 1595 1833 } 1596 1834 } … … 1600 1838 if (cand) 1601 1839 cand->status = status; 1602 if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) { 1840 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error || 1841 comp->cand_cnt==1) 1842 { 1603 1843 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1604 1844 "STUN binding request failed", status); … … 1625 1865 pj_assert(cand != NULL); 1626 1866 cand->status = status; 1627 if (!ice_st->cfg.stun .ignore_stun_error) {1867 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1628 1868 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1629 1869 "STUN keep-alive failed", status); … … 1646 1886 { 1647 1887 pj_ice_strans_comp *comp; 1888 sock_user_data *data; 1648 1889 pj_status_t status; 1649 1890 1650 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);1651 if ( comp== NULL) {1891 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1892 if (data == NULL) { 1652 1893 /* We have disassociated ourselves from the TURN socket */ 1653 1894 return; 1654 1895 } 1896 1897 comp = data->comp; 1655 1898 1656 1899 pj_grp_lock_add_ref(comp->ice_st->grp_lock); … … 1671 1914 /* Hand over the packet to ICE */ 1672 1915 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1673 TP_TURN, pkt, pkt_len,1916 data->transport_id, pkt, pkt_len, 1674 1917 peer_addr, addr_len); 1675 1918 … … 1690 1933 { 1691 1934 pj_ice_strans_comp *comp; 1692 1693 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 1694 if (comp == NULL) { 1935 sock_user_data *data; 1936 int tp_idx; 1937 1938 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1939 if (data == NULL) { 1695 1940 /* Not interested in further state notification once the relay is 1696 1941 * disconnecting. … … 1698 1943 return; 1699 1944 } 1945 1946 comp = data->comp; 1947 tp_idx = GET_TP_IDX(data->transport_id); 1700 1948 1701 1949 PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", … … 1711 1959 unsigned i; 1712 1960 1713 comp->turn _err_cnt = 0;1961 comp->turn[tp_idx].err_cnt = 0; 1714 1962 1715 1963 /* Get allocation info */ … … 1721 1969 /* Find relayed candidate in the component */ 1722 1970 for (i=0; i<comp->cand_cnt; ++i) { 1723 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 1971 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 1972 comp->cand_list[i].transport_id == data->transport_id) 1973 { 1724 1974 cand = &comp->cand_list[i]; 1725 1975 break; … … 1742 1992 comp->default_cand = (unsigned)(cand - comp->cand_list); 1743 1993 1994 /* Prefer IPv4 relay as default candidate for better connectivity 1995 * with IPv4 endpoints. 1996 */ 1997 if (cand->addr.addr.sa_family != pj_AF_INET()) { 1998 for (i=0; i<comp->cand_cnt; ++i) { 1999 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 2000 comp->cand_list[i].addr.addr.sa_family == pj_AF_INET() && 2001 comp->cand_list[i].status == PJ_SUCCESS) 2002 { 2003 comp->default_cand = i; 2004 break; 2005 } 2006 } 2007 } 2008 1744 2009 PJ_LOG(4,(comp->ice_st->obj_name, 1745 2010 "Comp %d: TURN allocation complete, relay address is %s", … … 1750 2015 sess_init_update(comp->ice_st); 1751 2016 2017 } else if ((old_state == PJ_TURN_STATE_RESOLVING || 2018 old_state == PJ_TURN_STATE_RESOLVED) && 2019 new_state == PJ_TURN_STATE_DESTROYING) 2020 { 2021 pj_ice_sess_cand *cand = NULL; 2022 unsigned i; 2023 2024 /* DNS resolution or TURN transport creation/allocation 2025 * has failed. 2026 */ 2027 ++comp->turn[tp_idx].err_cnt; 2028 2029 /* Unregister ourself from the TURN relay */ 2030 pj_turn_sock_set_user_data(turn_sock, NULL); 2031 comp->turn[tp_idx].sock = NULL; 2032 2033 /* Wait until initialization completes */ 2034 pj_grp_lock_acquire(comp->ice_st->grp_lock); 2035 2036 /* Find relayed candidate in the component */ 2037 for (i=0; i<comp->cand_cnt; ++i) { 2038 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 2039 comp->cand_list[i].transport_id == data->transport_id) 2040 { 2041 cand = &comp->cand_list[i]; 2042 break; 2043 } 2044 } 2045 2046 pj_grp_lock_release(comp->ice_st->grp_lock); 2047 2048 /* If the error happens during pj_turn_sock_create() or 2049 * pj_turn_sock_alloc(), the candidate hasn't been added 2050 * to the list. 2051 */ 2052 if (cand) cand->status = PJ_ERESOLVE; 2053 2054 sess_init_update(comp->ice_st); 2055 1752 2056 } else if (new_state >= PJ_TURN_STATE_DEALLOCATING) { 1753 2057 pj_turn_session_info info; 1754 2058 1755 ++comp->turn _err_cnt;2059 ++comp->turn[tp_idx].err_cnt; 1756 2060 1757 2061 pj_turn_sock_get_info(turn_sock, &info); … … 1759 2063 /* Unregister ourself from the TURN relay */ 1760 2064 pj_turn_sock_set_user_data(turn_sock, NULL); 1761 comp->turn _sock = NULL;2065 comp->turn[tp_idx].sock = NULL; 1762 2066 1763 2067 /* Set session to fail on error. last_status PJ_SUCCESS means normal … … 1769 2073 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT, 1770 2074 "TURN allocation failed", info.last_status); 1771 } else if (comp->turn _err_cnt > 1) {2075 } else if (comp->turn[tp_idx].err_cnt > 1) { 1772 2076 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE, 1773 2077 "TURN refresh failed", info.last_status); … … 1776 2080 "Comp %d: TURN allocation failed, retrying", 1777 2081 comp->comp_id)); 1778 add_update_turn(comp->ice_st, comp );2082 add_update_turn(comp->ice_st, comp, tp_idx); 1779 2083 } 1780 2084 }
Note: See TracChangeset
for help on using the changeset viewer.