Changeset 1126 for pjproject/trunk
- Timestamp:
- Apr 2, 2007 11:30:14 AM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r1114 r1126 89 89 90 90 91 91 /* 92 * Create ICE media transport. 93 */ 92 94 PJ_DEF(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt, 93 95 const char *name, … … 132 134 133 135 136 /* 137 * Destroy ICE media transport. 138 */ 134 139 PJ_DEF(pj_status_t) pjmedia_ice_destroy(pjmedia_transport *tp) 135 140 { … … 138 143 if (tp_ice->ice_st) { 139 144 pj_ice_strans_destroy(tp_ice->ice_st); 140 //Must not touch tp_ice after ice_st is destroyed! 141 //(it has the pool) 142 //tp_ice->ice_st = NULL; 145 /*Must not touch tp_ice after ice_st is destroyed! 146 (it has the pool) 147 tp_ice->ice_st = NULL; 148 */ 143 149 } 144 150 … … 147 153 148 154 155 /* 156 * Start media transport initialization. 157 */ 149 158 PJ_DEF(pj_status_t) pjmedia_ice_start_init( pjmedia_transport *tp, 150 159 unsigned options, … … 186 195 187 196 197 /* 198 * Get the status of media transport initialization. 199 */ 188 200 PJ_DEF(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp) 189 201 { … … 193 205 194 206 207 /* 208 * Get the component for the specified component ID. 209 */ 195 210 PJ_DEF(pj_status_t) pjmedia_ice_get_comp( pjmedia_transport *tp, 196 211 unsigned comp_id, … … 205 220 } 206 221 207 PJ_DEF(pj_ice_strans*) pjmedia_ice_get_ice_st(pjmedia_transport *tp) 208 { 209 struct transport_ice *tp_ice = (struct transport_ice*)tp; 210 return tp_ice->ice_st; 211 } 212 213 222 223 /* 224 * Create ICE! This happens when: 225 * - UAC is ready to send offer 226 * - UAS have just received an offer. 227 */ 214 228 PJ_DEF(pj_status_t) pjmedia_ice_init_ice(pjmedia_transport *tp, 215 229 pj_ice_sess_role role, … … 222 236 223 237 238 /* 239 * For both UAC and UAS, pass in the SDP before sending it to remote. 240 * This will add ICE attributes to the SDP. 241 */ 224 242 PJ_DEF(pj_status_t) pjmedia_ice_modify_sdp(pjmedia_transport *tp, 225 243 pj_pool_t *pool, … … 306 324 307 325 326 /* Parse a=candidate line */ 308 327 static pj_status_t parse_cand(pj_pool_t *pool, 309 328 const pj_str_t *orig_input, … … 391 410 } 392 411 393 static void set_no_ice(struct transport_ice *tp_ice) 412 413 /* Disable ICE when SDP from remote doesn't contain a=candidate line */ 414 static void set_no_ice(struct transport_ice *tp_ice, const char *reason) 394 415 { 395 416 PJ_LOG(4,(tp_ice->ice_st->obj_name, 396 " Remote does not support ICE, disabling local ICE"));417 "Disabling local ICE, reason=%s", reason)); 397 418 pjmedia_ice_stop_ice(&tp_ice->base); 398 419 } 399 420 400 421 422 /* 423 * Start ICE checks when both offer and answer are available. 424 */ 401 425 PJ_DEF(pj_status_t) pjmedia_ice_start_ice(pjmedia_transport *tp, 402 426 pj_pool_t *pool, … … 410 434 const pjmedia_sdp_media *sdp_med; 411 435 pj_bool_t remote_is_lite = PJ_FALSE; 436 pj_bool_t ice_mismatch = PJ_FALSE; 412 437 const pj_str_t STR_CANDIDATE = {"candidate", 9}; 413 438 const pj_str_t STR_ICE_LITE = {"ice-lite", 8}; 439 const pj_str_t STR_ICE_MISMATCH = {"ice-mismatch", 12}; 414 440 pj_str_t uname, pass; 415 441 pj_status_t status; … … 428 454 "ice-ufrag", NULL); 429 455 if (attr == NULL) { 430 set_no_ice(tp_ice );456 set_no_ice(tp_ice, "ice-ufrag attribute not found"); 431 457 return PJ_SUCCESS; 432 458 } … … 442 468 "ice-pwd", NULL); 443 469 if (attr == NULL) { 444 set_no_ice(tp_ice );470 set_no_ice(tp_ice, "ice-pwd attribute not found"); 445 471 return PJ_SUCCESS; 446 472 } … … 455 481 attr = sdp_med->attr[i]; 456 482 457 if (pj_strcmp(&attr->name, &STR_ICE_LITE)==0) 483 if (pj_strcmp(&attr->name, &STR_ICE_LITE)==0) { 458 484 remote_is_lite = PJ_TRUE; 485 continue; 486 } 487 488 if (pj_strcmp(&attr->name, &STR_ICE_MISMATCH)==0) { 489 ice_mismatch = PJ_TRUE; 490 continue; 491 } 459 492 460 493 if (pj_strcmp(&attr->name, &STR_CANDIDATE)!=0) … … 466 499 467 500 cand_cnt++; 501 } 502 503 /* Handle ice-mismatch case */ 504 if (ice_mismatch) { 505 set_no_ice(tp_ice, "ice-mismatch detected"); 506 return PJ_SUCCESS; 468 507 } 469 508 -
pjproject/trunk/pjnath/include/pjnath/config.h
r1110 r1126 31 31 * @{ 32 32 */ 33 34 35 /* ************************************************************************** 36 * GENERAL 37 */ 38 39 /** 40 * The log level for PJNATH error display. 41 * 42 * default 1 43 */ 44 #ifndef PJNATH_ERROR_LEVEL 45 # define PJNATH_ERROR_LEVEL 1 46 #endif 47 33 48 34 49 /* ************************************************************************** -
pjproject/trunk/pjnath/include/pjnath/ice_session.h
r1114 r1126 97 97 } pj_ice_cand_type; 98 98 99 100 /**101 * This enumeration describes the default preference for the ICE102 * candidate types as described by ICE standard.103 */104 enum pj_ice_type_pref105 {106 PJ_ICE_HOST_PREF = 126, /**< Preference value for host. */107 PJ_ICE_SRFLX_PREF = 100, /**< Preference value for SRFLX. */108 PJ_ICE_PRFLX_PREF = 110, /**< Preference value for PRFLX */109 PJ_ICE_RELAYED_PREF = 0 /**< Preference value for relay */110 };111 99 112 100 /** Forward declaration for pj_ice_sess */ … … 274 262 * Check priority. 275 263 */ 276 pj_ uint64_tprio;264 pj_timestamp prio; 277 265 278 266 /** … … 446 434 pj_ice_sess_role role; /**< ICE role. */ 447 435 pj_timestamp tie_breaker; /**< Tie breaker value */ 436 pj_uint8_t *prefs; /**< Type preference. */ 448 437 pj_bool_t is_complete; /**< Complete? */ 449 438 pj_status_t ice_status; /**< Error status. */ … … 567 556 568 557 /** 558 * Assign a custom preference values for ICE candidate types. By assigning 559 * custom preference value, application can control the order of candidates 560 * to be checked first. The default preference settings is to use 126 for 561 * host candidates, 100 for server reflexive candidates, 110 for peer 562 * reflexive candidates, an 0 for relayed candidates. 563 * 564 * Note that this function must be called before any candidates are added 565 * to the ICE session. 566 * 567 * @param ice The ICE session. 568 * @param prefs Array of candidate preference value. The values are 569 * put in the array indexed by the candidate type as 570 * specified in pj_ice_cand_type. 571 * 572 * @return PJ_SUCCESS on success, or the appropriate error code. 573 */ 574 PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice, 575 const pj_uint8_t prefs[4]); 576 577 578 579 /** 569 580 * Add a candidate to this ICE session. Application must add candidates for 570 581 * each components ID before it can start pairing the candidates and … … 596 607 unsigned *p_cand_id); 597 608 609 #if 0 610 /* Temporarily disabled to reduce size, since we don't need this yet */ 611 598 612 /** 599 613 * Find default candidate for the specified component ID, using this … … 613 627 unsigned comp_id, 614 628 int *p_cand_id); 629 #endif 615 630 616 631 /** -
pjproject/trunk/pjnath/include/pjnath/stun_auth.h
r1110 r1126 226 226 * PJ_FALSE, 438 (Stale Nonce) response will be created. 227 227 * 228 * This callback is optional. 229 * 228 230 * @param msg The STUN message where the nonce was received. 229 231 * @param user_data The user data as specified in the credential. -
pjproject/trunk/pjnath/include/pjnath/stun_msg.h
r1114 r1126 1229 1229 * @return The message string output. 1230 1230 */ 1231 #if PJ_LOG_MAX_LEVEL > 0 1231 1232 PJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg, 1232 1233 char *buffer, 1233 1234 unsigned length, 1234 1235 unsigned *printed_len); 1236 #else 1237 # define pj_stun_msg_dump(msg, buf, length, printed_len) "" 1238 #endif 1235 1239 1236 1240 -
pjproject/trunk/pjnath/include/pjnath/types.h
r1114 r1126 38 38 * Initialize pjnath library. 39 39 * 40 * @return Initialization status.40 * @return Initialization status. 41 41 */ 42 42 PJ_DECL(pj_status_t) pjnath_init(void); 43 44 45 /** 46 * Display error to the log. 47 * 48 * @param sender The sender name. 49 * @param title Title message. 50 * @param status The error status. 51 */ 52 #if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL 53 PJ_DECL(void) pjnath_perror(const char *sender, const char *title, 54 pj_status_t status); 55 #else 56 # define pjnath_perror(sender, title, status) 57 #endif 58 43 59 44 60 … … 148 164 * the usage of ICE in SIP/SDP offer/answer. 149 165 * 166 * 150 167 * \subsection PJNATH_ICE_ARCH ICE Library Organization 151 168 * -
pjproject/trunk/pjnath/src/pjnath/errno.c
r1101 r1126 19 19 #include <pjnath/errno.h> 20 20 #include <pjnath/stun_msg.h> 21 #include <pj/log.h> 21 22 #include <pj/string.h> 22 23 … … 166 167 } 167 168 169 170 #if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL 171 172 PJ_DEF(void) pjnath_perror(const char *sender, const char *title, 173 pj_status_t status) 174 { 175 char errmsg[PJ_ERR_MSG_SIZE]; 176 177 pj_strerror(status, errmsg, sizeof(errmsg)); 178 179 #if PJNATH_ERROR_LEVEL==1 180 PJ_LOG(1,(sender, "%s: %s", title, errmsg)); 181 #elif PJNATH_ERROR_LEVEL==2 182 PJ_LOG(2,(sender, "%s: %s", title, errmsg)); 183 #elif PJNATH_ERROR_LEVEL==3 184 PJ_LOG(3,(sender, "%s: %s", title, errmsg)); 185 #elif PJNATH_ERROR_LEVEL==4 186 PJ_LOG(4,(sender, "%s: %s", title, errmsg)); 187 #elif PJNATH_ERROR_LEVEL==5 188 PJ_LOG(5,(sender, "%s: %s", title, errmsg)); 189 #else 190 # error Invalid PJNATH_ERROR_LEVEL value 191 #endif 192 } 193 194 #endif /* PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL */ 195 -
pjproject/trunk/pjnath/src/pjnath/ice_session.c
r1114 r1126 41 41 42 42 /* String names for pj_ice_sess_check_state */ 43 #if PJ_LOG_MAX_LEVEL >= 4 43 44 static const char *check_state_name[] = 44 45 { … … 56 57 "Completed" 57 58 }; 59 #endif /* PJ_LOG_MAX_LEVEL >= 4 */ 58 60 59 61 static const char *role_names[] = … … 61 63 "Controlled", 62 64 "Controlling" 65 }; 66 67 /* Default ICE session preferences, according to draft-ice */ 68 static pj_uint8_t cand_type_prefs[4] = 69 { 70 126, /**< PJ_ICE_HOST_PREF */ 71 100, /**< PJ_ICE_SRFLX_PREF. */ 72 110, /**< PJ_ICE_PRFLX_PREF */ 73 0 /**< PJ_ICE_RELAYED_PREF */ 63 74 }; 64 75 … … 72 83 typedef struct stun_data 73 84 { 74 pj_ice_sess *ice; 75 unsigned lcand_id; 85 pj_ice_sess *ice; 76 86 pj_ice_sess_cand *lcand; 77 87 } stun_data; … … 79 89 typedef struct timer_data 80 90 { 81 pj_ice_sess *ice;82 pj_ice_sess_checklist 91 pj_ice_sess *ice; 92 pj_ice_sess_checklist *clist; 83 93 } timer_data; 84 94 … … 132 142 int *data_type, 133 143 pj_str_t *data); 134 static pj_bool_t stun_auth_verify_nonce(const pj_stun_msg *msg,135 void *user_data,136 const pj_str_t *realm,137 const pj_str_t *username,138 const pj_str_t *nonce);139 144 140 145 … … 189 194 pj_pool_t *pool; 190 195 pj_ice_sess *ice; 191 char tmp[64];192 pj_str_t s;193 196 unsigned i; 194 197 pj_status_t status; … … 205 208 ice->tie_breaker.u32.hi = pj_rand(); 206 209 ice->tie_breaker.u32.lo = pj_rand(); 210 ice->prefs = cand_type_prefs; 207 211 208 212 pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name), … … 227 231 228 232 if (local_ufrag == NULL) { 229 pj_ansi_snprintf(tmp, sizeof(tmp), "%x%x", pj_rand(), pj_rand());230 s = pj_str(tmp);231 local_ufrag = &s; 232 } 233 pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag);233 ice->rx_ufrag.ptr = pj_pool_alloc(ice->pool, 16); 234 pj_create_random_string(ice->rx_ufrag.ptr, 16); 235 } else { 236 pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag); 237 } 234 238 235 239 if (local_passwd == NULL) { 236 pj_ansi_snprintf(tmp, sizeof(tmp), "%x%x", pj_rand(), pj_rand());237 s = pj_str(tmp);238 local_passwd = &s; 239 } 240 pj_strdup(ice->pool, &ice->rx_pass, local_passwd);240 ice->rx_pass.ptr = pj_pool_alloc(ice->pool, 16); 241 pj_create_random_string(ice->rx_pass.ptr, 16); 242 } else { 243 pj_strdup(ice->pool, &ice->rx_pass, local_passwd); 244 } 241 245 242 246 … … 313 317 } 314 318 319 return PJ_SUCCESS; 320 } 321 322 323 /* 324 * Change type preference 325 */ 326 PJ_DEF(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice, 327 const pj_uint8_t prefs[4]) 328 { 329 PJ_ASSERT_RETURN(ice && prefs, PJ_EINVAL); 330 ice->prefs = pj_pool_calloc(ice->pool, PJ_ARRAY_SIZE(prefs), 331 sizeof(pj_uint8_t)); 332 pj_memcpy(ice->prefs, prefs, sizeof(prefs)); 315 333 return PJ_SUCCESS; 316 334 } … … 422 440 423 441 424 static pj_bool_t stun_auth_verify_nonce(const pj_stun_msg *msg, 425 void *user_data, 426 const pj_str_t *realm, 427 const pj_str_t *username, 428 const pj_str_t *nonce) 429 { 430 /* We don't use NONCE */ 431 PJ_UNUSED_ARG(msg); 432 PJ_UNUSED_ARG(user_data); 433 PJ_UNUSED_ARG(realm); 434 PJ_UNUSED_ARG(username); 435 PJ_UNUSED_ARG(nonce); 436 return PJ_TRUE; 437 } 438 439 440 static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type, 442 static pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice, 443 pj_ice_cand_type type, 441 444 pj_uint32_t local_pref, 442 445 pj_uint32_t comp_id) 443 446 { 444 pj_uint32_t type_pref[] = 445 { 446 PJ_ICE_HOST_PREF, 447 PJ_ICE_SRFLX_PREF, 448 PJ_ICE_PRFLX_PREF, 449 PJ_ICE_RELAYED_PREF 450 }; 451 452 return ((type_pref[type] & 0xFF) << 24) + 447 return ((ice->prefs[type] & 0xFF) << 24) + 453 448 ((local_pref & 0xFFFF) << 8) + 454 449 (((256 - comp_id) & 0xFF) << 0); … … 493 488 lcand->type = type; 494 489 pj_strdup(ice->pool, &lcand->foundation, foundation); 495 lcand->prio = CALC_CAND_PRIO( type, local_pref, lcand->comp_id);490 lcand->prio = CALC_CAND_PRIO(ice, type, local_pref, lcand->comp_id); 496 491 pj_memcpy(&lcand->addr, addr, addr_len); 497 492 pj_memcpy(&lcand->base_addr, base_addr, addr_len); … … 521 516 sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data); 522 517 sd->ice = ice; 523 sd->lcand_id = GET_LCAND_ID(lcand);524 518 sd->lcand = lcand; 525 519 pj_stun_session_set_user_data(lcand->stun_sess, sd); … … 531 525 auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred; 532 526 auth_cred.data.dyn_cred.get_password = &stun_auth_get_password; 533 auth_cred.data.dyn_cred.verify_nonce = &stun_auth_verify_nonce;534 527 auth_cred.data.dyn_cred.user_data = lcand->stun_sess; 535 528 pj_stun_session_set_credential(lcand->stun_sess, &auth_cred); … … 563 556 564 557 /* Find default candidate ID for the component */ 558 #if 0 565 559 PJ_DEF(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice, 566 560 unsigned comp_id, … … 630 624 return PJ_EBUG; 631 625 } 626 #endif /* if 0 */ 632 627 633 628 … … 640 635 #endif 641 636 642 static pj_ uint64_tCALC_CHECK_PRIO(const pj_ice_sess *ice,643 const pj_ice_sess_cand *lcand,644 const pj_ice_sess_cand *rcand)637 static pj_timestamp CALC_CHECK_PRIO(const pj_ice_sess *ice, 638 const pj_ice_sess_cand *lcand, 639 const pj_ice_sess_cand *rcand) 645 640 { 646 641 pj_uint32_t O, A; 642 pj_timestamp prio; 643 644 /* Original formula: 645 * pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0) 646 */ 647 647 648 648 if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) { … … 654 654 } 655 655 656 /* 656 657 return ((pj_uint64_t)1 << 32) * MIN(O, A) + 657 658 (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0); 658 } 659 659 */ 660 661 prio.u32.hi = MIN(O,A); 662 prio.u32.lo = (MAX(O, A) << 1) + (O>A ? 1 : 0); 663 664 return prio; 665 } 666 667 668 PJ_INLINE(int) CMP_CHECK_PRIO(const pj_ice_sess_check *c1, 669 const pj_ice_sess_check *c2) 670 { 671 return pj_cmp_timestamp(&c1->prio, &c2->prio); 672 } 673 674 675 #if PJ_LOG_MAX_LEVEL >= 4 660 676 static const char *dump_check(char *buffer, unsigned bufsize, 661 677 const pj_ice_sess_checklist *clist, … … 691 707 } 692 708 693 #if PJ_LOG_MAX_LEVEL >= 4694 709 static void dump_checklist(const char *title, const pj_ice_sess *ice, 695 710 const pj_ice_sess_checklist *clist) … … 747 762 unsigned j, highest = i; 748 763 for (j=i+1; j<clist->count; ++j) { 749 if ( clist->checks[j].prio > clist->checks[highest].prio) {764 if (CMP_CHECK_PRIO(&clist->checks[j], &clist->checks[highest]) > 0) { 750 765 highest = j; 751 766 } … … 828 843 ljaddr = &ljcand->addr; 829 844 830 if ( sockaddr_cmp(liaddr, ljaddr) == SOCKADDR_EQUAL &&831 sockaddr_cmp( &ricand->addr, &rjcand->addr) == SOCKADDR_EQUAL)845 if (ricand == rjcand && 846 sockaddr_cmp(liaddr, ljaddr) == SOCKADDR_EQUAL) 832 847 { 833 848 /* Found duplicate, remove it */ … … 835 850 836 851 LOG5((ice->obj_name, "Check %s pruned", 837 dump_check(buf, sizeof(buf), &ice->clist,838 &clist->checks[j])));852 dump_check(buf, sizeof(buf), &ice->clist, 853 &clist->checks[j]))); 839 854 840 855 pj_array_erase(clist->checks, sizeof(clist->checks[0]), … … 929 944 comp->valid_check = check; 930 945 } else { 931 if ( comp->valid_check->prio < check->prio)946 if (CMP_CHECK_PRIO(comp->valid_check, check) < 0) 932 947 comp->valid_check = check; 933 948 } … … 1155 1170 PJ_STUN_BINDING_REQUEST, 1156 1171 &check->tdata); 1157 if (status != PJ_SUCCESS) 1172 if (status != PJ_SUCCESS) { 1173 pjnath_perror(ice->obj_name, "Error creating STUN request", status); 1158 1174 return status; 1175 } 1159 1176 1160 1177 /* Attach data to be retrieved later when STUN request transaction … … 1168 1185 1169 1186 /* Add PRIORITY */ 1170 prio = CALC_CAND_PRIO( PJ_ICE_CAND_TYPE_PRFLX, 65535,1187 prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535, 1171 1188 lcand->comp_id); 1172 1189 pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg, … … 1190 1207 if (status != PJ_SUCCESS) { 1191 1208 check->tdata = NULL; 1209 pjnath_perror(ice->obj_name, "Error sending STUN request", status); 1192 1210 return status; 1193 1211 } … … 1290 1308 } 1291 1309 1310 1311 /* Utility: find string in string array */ 1312 const pj_str_t *find_str(const pj_str_t *strlist[], unsigned count, 1313 const pj_str_t *str) 1314 { 1315 unsigned i; 1316 for (i=0; i<count; ++i) { 1317 if (pj_strcmp(strlist[i], str)==0) 1318 return strlist[i]; 1319 } 1320 return NULL; 1321 } 1322 1292 1323 /* Start ICE check */ 1293 1324 PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice) … … 1295 1326 pj_ice_sess_checklist *clist; 1296 1327 const pj_ice_sess_cand *cand0; 1297 unsigned i; 1328 const pj_str_t *flist[PJ_ICE_MAX_CAND]; 1329 unsigned i, flist_cnt = 0; 1298 1330 1299 1331 PJ_ASSERT_RETURN(ice, PJ_EINVAL); 1300 /* Checklist must be created */ 1332 1333 /* Checklist must have been created */ 1301 1334 PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP); 1302 1335 1303 1336 LOG4((ice->obj_name, "Starting ICE check..")); 1304 1337 1338 /* The agent examines the check list for the first media stream (a 1339 * media stream is the first media stream when it is described by 1340 * the first m-line in the SDP offer and answer). For that media 1341 * stream, it: 1342 * 1343 * - Groups together all of the pairs with the same foundation, 1344 * 1345 * - For each group, sets the state of the pair with the lowest 1346 * component ID to Waiting. If there is more than one such pair, 1347 * the one with the highest priority is used. 1348 */ 1349 1305 1350 clist = &ice->clist; 1306 1351 1307 /* Pickup the first pair and set the state to Waiting */ 1308 clist->checks[0].state = PJ_ICE_SESS_CHECK_STATE_WAITING; 1309 cand0 = clist->checks[0].lcand; 1352 /* Pickup the first pair for component 1. */ 1353 for (i=0; i<clist->count; ++i) { 1354 if (clist->checks[0].lcand->comp_id == 1) 1355 break; 1356 } 1357 if (i == clist->count) { 1358 pj_assert(!"Unable to find checklist for component 1"); 1359 return PJNATH_EICEINCOMPID; 1360 } 1361 1362 /* Set this check to WAITING */ 1363 check_set_state(ice, &clist->checks[i], 1364 PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS); 1365 cand0 = clist->checks[i].lcand; 1366 flist[flist_cnt++] = &clist->checks[i].lcand->foundation; 1310 1367 1311 1368 /* Find all of the other pairs in that check list with the same … … 1313 1370 * states to Waiting as well. 1314 1371 */ 1315 for ( i=1; i<clist->count; ++i) {1372 for (++i; i<clist->count; ++i) { 1316 1373 const pj_ice_sess_cand *cand1; 1317 1374 1318 1375 cand1 = clist->checks[i].lcand; 1319 1376 1320 if (cand 0->comp_id == cand1->comp_id &&1321 pj_strcmp(&cand0->foundation, &cand1->foundation)!=0)1377 if (cand1->comp_id==cand0->comp_id && 1378 find_str(flist, flist_cnt, &cand1->foundation)==NULL) 1322 1379 { 1323 clist->checks[i].state = PJ_ICE_SESS_CHECK_STATE_WAITING; 1380 check_set_state(ice, &clist->checks[i], 1381 PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS); 1382 flist[flist_cnt++] = &cand1->foundation; 1324 1383 } 1325 1384 } … … 1342 1401 { 1343 1402 stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 1344 return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id, sd->lcand_id, 1403 pj_ice_sess *ice = sd->ice; 1404 return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id, 1405 GET_LCAND_ID(sd->lcand), 1345 1406 pkt, pkt_size, 1346 1407 dst_addr, addr_len); -
pjproject/trunk/pjnath/src/pjnath/ice_strans.c
r1114 r1126 66 66 67 67 /* Utility: print error */ 68 #if PJ_LOG_MAX_LEVEL >= 3 69 static void ice_st_perror(pj_ice_strans *ice_st, const char *title, 70 pj_status_t status) 71 { 72 char errmsg[PJ_ERR_MSG_SIZE]; 73 74 pj_strerror(status, errmsg, sizeof(errmsg)); 75 PJ_LOG(3,(ice_st->obj_name, "%s: %s", title, errmsg)); 76 } 77 #else 78 # define ice_st_perror(ice_st, title, status) 79 #endif 80 68 #define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc) 81 69 82 70 /* … … 345 333 pj_sockaddr_in cand_addr; 346 334 pj_bool_t set_default; 335 pj_uint16_t local_pref; 347 336 348 337 /* Ignore 127.0.0.0/24 address */ … … 359 348 if (ifs[i].s_addr == comp->local_addr.ipv4.sin_addr.s_addr) { 360 349 set_default = PJ_TRUE; 350 local_pref = 65535; 361 351 } else { 362 352 set_default = PJ_FALSE; 353 local_pref = 0; 363 354 } 364 355 365 356 status = add_cand(ice_st, comp, comp_id, 366 357 PJ_ICE_CAND_TYPE_HOST, 367 (pj_uint16_t)(65535-i), &cand_addr, 368 set_default); 358 local_pref, &cand_addr, set_default); 369 359 if (status != PJ_SUCCESS) 370 360 goto on_error; … … 760 750 unsigned i; 761 751 pj_ice_sess_cb ice_cb; 752 const pj_uint8_t srflx_prio[4] = { 100, 126, 110, 0 }; 762 753 763 754 /* Check arguments */ … … 783 774 /* Associate user data */ 784 775 ice_st->ice->user_data = (void*)ice_st; 776 777 /* If default candidate for components are SRFLX one, upload a custom 778 * type priority to ICE session so that SRFLX candidates will get 779 * checked first. 780 */ 781 if (ice_st->comp[0]->default_cand >= 0 && 782 ice_st->comp[0]->cand_list[ice_st->comp[0]->default_cand].type 783 == PJ_ICE_CAND_TYPE_SRFLX) 784 { 785 pj_ice_sess_set_prefs(ice_st->ice, srflx_prio); 786 } 787 785 788 786 789 /* Add candidates */ -
pjproject/trunk/pjnath/src/pjnath/stun_auth.c
r1101 r1126 270 270 pj_bool_t ok; 271 271 272 if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) { 272 if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC && 273 cred->data.dyn_cred.verify_nonce != NULL) 274 { 273 275 ok=cred->data.dyn_cred.verify_nonce(msg, 274 276 cred->data.dyn_cred.user_data, … … 276 278 &auser->value, 277 279 &anonce->value); 280 } else if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) { 281 ok = PJ_TRUE; 278 282 } else { 279 283 if (nonce.slen) { -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r1114 r1126 140 140 141 141 142 st ruct attr_desc mandatory_attr_desc[] =142 static struct attr_desc mandatory_attr_desc[] = 143 143 { 144 144 { … … 438 438 { 439 439 /* PJ_STUN_ATTR_ICE_CONTROLLED, */ 440 "ICE-C CONTROLLED",440 "ICE-CONTROLLED", 441 441 &decode_uint64_attr, 442 442 &encode_uint64_attr … … 444 444 { 445 445 /* PJ_STUN_ATTR_ICE_CONTROLLING, */ 446 "ICE-C CONTROLLING",446 "ICE-CONTROLLING", 447 447 &decode_uint64_attr, 448 448 &encode_uint64_attr … … 1871 1871 /* Already has MESSAGE-INTEGRITY */ 1872 1872 if (p_response) { 1873 pj_str_t e;1874 e = pj_str("MESSAGE-INTEGRITY already present");1875 1873 pj_stun_msg_create_response(pool, msg, 1876 1874 PJ_STUN_SC_BAD_REQUEST, … … 1885 1883 /* Already has FINGERPRINT */ 1886 1884 if (p_response) { 1887 pj_str_t e;1888 e = pj_str("FINGERPRINT already present");1889 1885 pj_stun_msg_create_response(pool, msg, 1890 1886 PJ_STUN_SC_BAD_REQUEST, … … 1899 1895 * after FINGERPRINT or MESSAGE-INTEGRITY */ 1900 1896 if (p_response) { 1901 pj_str_t e;1902 e = pj_str("Invalid attribute order");1903 1897 pj_stun_msg_create_response(pool, msg, 1904 1898 PJ_STUN_SC_BAD_REQUEST, … … 1913 1907 if (msg->attr_count >= PJ_STUN_MAX_ATTR) { 1914 1908 if (p_response) { 1915 pj_str_t e;1916 1917 e = pj_str("Too many attributes");1918 1909 pj_stun_msg_create_response(pool, msg, 1919 1910 PJ_STUN_SC_BAD_REQUEST, 1920 &e, p_response);1911 NULL, p_response); 1921 1912 } 1922 1913 return PJNATH_ESTUNTOOMANYATTR; -
pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
r1114 r1126 23 23 24 24 25 #if PJ_LOG_MAX_LEVEL > 0 26 27 25 28 #define APPLY() if (len < 1 || len >= (end-p)) \ 26 29 goto on_return; \ … … 245 248 return buffer; 246 249 250 #undef APPLY 247 251 } 248 252 249 253 250 #undef APPLY 254 #endif /* PJ_LOG_MAX_LEVEL > 0 */ 255 -
pjproject/trunk/pjnath/src/pjnath/stun_session.c
r1111 r1126 44 44 #endif 45 45 46 #if PJ_LOG_MAX_LEVEL >= 4 47 # define LOG_ERR_(sess, title, rc) stun_perror(sess, title, rc) 48 static void stun_perror(pj_stun_session *sess, const char *title, 49 pj_status_t status) 50 { 51 char errmsg[PJ_ERR_MSG_SIZE]; 52 53 pj_strerror(status, errmsg, sizeof(errmsg)); 54 55 PJ_LOG(4,(SNAME(sess), "%s: %s", title, errmsg)); 56 } 57 58 #else 59 # define LOG_ERR_(sess, title, rc) 60 #endif 46 #define LOG_ERR_(sess,title,rc) pjnath_perror(sess->pool->obj_name,title,rc) 61 47 62 48 #define TDATA_POOL_SIZE 1024 … … 780 766 tdata = tsx_lookup(sess, msg); 781 767 if (tdata == NULL) { 782 PJ_LOG( 4,(SNAME(sess),768 PJ_LOG(5,(SNAME(sess), 783 769 "Transaction not found, response silently discarded")); 784 770 return PJ_SUCCESS; -
pjproject/trunk/pjnath/src/pjnath/stun_transaction.c
r1114 r1126 51 51 pj_timer_entry *timer); 52 52 53 static void stun_perror(pj_stun_client_tsx *tsx, const char *title, 54 pj_status_t status) 55 { 56 char errmsg[PJ_ERR_MSG_SIZE]; 57 58 pj_strerror(status, errmsg, sizeof(errmsg)); 59 PJ_LOG(4,(tsx->obj_name, "%s: %s", title, errmsg)); 60 } 61 53 #define stun_perror(tsx,msg,rc) pjnath_perror(tsx->obj_name, msg, rc) 62 54 63 55 /* … … 85 77 *p_tsx = tsx; 86 78 87 PJ_LOG( 4,(tsx->obj_name, "STUN client transaction created"));79 PJ_LOG(5,(tsx->obj_name, "STUN client transaction created")); 88 80 return PJ_SUCCESS; 89 81 } … … 192 184 tsx->transmit_count++; 193 185 194 PJ_LOG( 4,(tsx->obj_name, "STUN sending message (transmit count=%d)",186 PJ_LOG(5,(tsx->obj_name, "STUN sending message (transmit count=%d)", 195 187 tsx->transmit_count)); 196 188 return status;
Note: See TracChangeset
for help on using the changeset viewer.