Changeset 1096 for pjproject/trunk/pjnath/src/pjnath/ice.c
- Timestamp:
- Mar 22, 2007 9:00:53 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/ice.c
r1094 r1096 22 22 #include <pj/array.h> 23 23 #include <pj/assert.h> 24 #include <pj/guid.h> 24 25 #include <pj/log.h> 25 26 #include <pj/os.h> … … 69 70 { 70 71 pj_ice *ice; 71 unsigned comp_id;72 pj_ice_c omp *comp;72 unsigned lcand_id; 73 pj_ice_cand *lcand; 73 74 } stun_data; 74 75 … … 133 134 134 135 136 /* 137 * Create ICE stream session. 138 */ 135 139 PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg, 136 140 const char *name, 137 141 pj_ice_role role, 138 142 const pj_ice_cb *cb, 143 const pj_str_t *local_ufrag, 144 const pj_str_t *local_passwd, 139 145 pj_ice **p_ice) 140 146 { 141 147 pj_pool_t *pool; 142 148 pj_ice *ice; 149 char tmp[32]; 150 pj_str_t s; 143 151 unsigned i; 144 152 pj_status_t status; … … 146 154 PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL); 147 155 148 if ( !name)156 if (name == NULL) 149 157 name = "ice%p"; 150 158 … … 171 179 } 172 180 181 if (local_ufrag == NULL) { 182 pj_ansi_snprintf(tmp, sizeof(tmp), "%x", pj_rand()); 183 s = pj_str(tmp); 184 local_ufrag = &s; 185 } 186 pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag); 187 188 if (local_passwd == NULL) { 189 pj_ansi_snprintf(tmp, sizeof(tmp), "%x", pj_rand()); 190 s = pj_str(tmp); 191 local_passwd = &s; 192 } 193 pj_strdup(ice->pool, &ice->rx_pass, local_passwd); 194 195 173 196 /* Done */ 174 197 *p_ice = ice; 175 198 176 LOG((ice->obj_name, "ICE media stream created")); 199 LOG((ice->obj_name, "ICE stream session created, role is %s agent", 200 (ice->role==PJ_ICE_ROLE_CONTROLLING ? "controlling" : "controlled"))); 177 201 178 202 return PJ_SUCCESS; … … 180 204 181 205 206 /* 207 * Destroy 208 */ 182 209 static void destroy_ice(pj_ice *ice, 183 210 pj_status_t reason) … … 190 217 191 218 for (i=0; i<ice->comp_cnt; ++i) { 192 pj_ice_comp *comp = &ice->comp[i]; 193 194 if (comp->stun_sess) { 195 pj_stun_session_destroy(comp->stun_sess); 196 comp->stun_sess = NULL; 219 /* Nothing to do */ 220 } 221 222 for (i=0; i<ice->lcand_cnt; ++i) { 223 if (ice->lcand[i].stun_sess) { 224 pj_stun_session_destroy(ice->lcand[i].stun_sess); 225 ice->lcand[i].stun_sess = NULL; 197 226 } 198 227 } … … 223 252 224 253 254 /* Find component by ID */ 225 255 static pj_ice_comp *find_comp(const pj_ice *ice, unsigned comp_id) 226 256 { … … 228 258 for (i=0; i<ice->comp_cnt; ++i) { 229 259 if (ice->comp[i].comp_id == comp_id) 230 return (pj_ice_comp *) &ice->comp[i];260 return (pj_ice_comp *) &ice->comp[i]; 231 261 } 232 262 … … 235 265 236 266 237 PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice, 238 unsigned comp_id, 239 const pj_sockaddr_t *local_addr, 240 unsigned addr_len) 241 { 242 pj_stun_session_cb sess_cb; 267 /* Add a new component */ 268 PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice, unsigned comp_id) 269 { 243 270 pj_ice_comp *comp; 244 pj_stun_auth_cred auth_cred; 245 stun_data *sd; 246 pj_status_t status; 247 248 PJ_ASSERT_RETURN(ice && local_addr && addr_len, PJ_EINVAL); 271 272 PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL); 249 273 PJ_ASSERT_RETURN(ice->comp_cnt < PJ_ARRAY_SIZE(ice->comp), PJ_ETOOMANY); 274 PJ_ASSERT_RETURN(comp_id==ice->comp_cnt+1, PJ_EICEINCOMPID); 250 275 PJ_ASSERT_RETURN(find_comp(ice, comp_id) == NULL, PJ_EEXISTS); 251 276 … … 255 280 comp->comp_id = comp_id; 256 281 comp->nominated_check_id = -1; 257 pj_memcpy(&comp->local_addr, local_addr, addr_len);258 259 /* Init STUN callbacks */260 pj_bzero(&sess_cb, sizeof(sess_cb));261 sess_cb.on_request_complete = &on_stun_request_complete;262 sess_cb.on_rx_indication = &on_stun_rx_indication;263 sess_cb.on_rx_request = &on_stun_rx_request;264 sess_cb.on_send_msg = &on_stun_send_msg;265 266 /* Create STUN session for this component */267 status = pj_stun_session_create(&ice->stun_cfg, ice->obj_name,268 &sess_cb, PJ_FALSE,269 &comp->stun_sess);270 if (status != PJ_SUCCESS) {271 pj_mutex_unlock(ice->mutex);272 return status;273 }274 275 /* Associate data with this STUN session */276 sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data);277 sd->ice = ice;278 sd->comp_id = comp_id;279 sd->comp = comp;280 pj_stun_session_set_user_data(comp->stun_sess, sd);281 282 /* Init STUN authentication credential */283 pj_bzero(&auth_cred, sizeof(auth_cred));284 auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;285 auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth;286 auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred;287 auth_cred.data.dyn_cred.get_password = &stun_auth_get_password;288 auth_cred.data.dyn_cred.verify_nonce = &stun_auth_verify_nonce;289 auth_cred.data.dyn_cred.user_data = comp->stun_sess;290 pj_stun_session_set_credential(comp->stun_sess, &auth_cred);291 282 292 283 /* Done */ … … 409 400 410 401 411 PJ_DEF(pj_status_t) pj_ice_set_credentials(pj_ice *ice,412 const pj_str_t *local_ufrag,413 const pj_str_t *local_pass,414 const pj_str_t *remote_ufrag,415 const pj_str_t *remote_pass)416 {417 char buf[128];418 pj_str_t username;419 420 username.ptr = buf;421 422 PJ_ASSERT_RETURN(ice && local_ufrag && local_pass &&423 remote_ufrag && remote_pass, PJ_EINVAL);424 PJ_ASSERT_RETURN(local_ufrag->slen + remote_ufrag->slen <425 sizeof(buf), PJ_ENAMETOOLONG);426 427 pj_strcpy(&username, remote_ufrag);428 pj_strcat2(&username, ":");429 pj_strcat(&username, local_ufrag);430 431 pj_strdup(ice->pool, &ice->tx_uname, &username);432 pj_strdup(ice->pool, &ice->tx_ufrag, remote_ufrag);433 pj_strdup(ice->pool, &ice->tx_pass, remote_pass);434 435 pj_strcpy(&username, local_ufrag);436 pj_strcat2(&username, ":");437 pj_strcat(&username, remote_ufrag);438 439 pj_strdup(ice->pool, &ice->rx_uname, &username);440 pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag);441 pj_strdup(ice->pool, &ice->rx_pass, local_pass);442 443 return PJ_SUCCESS;444 }445 446 447 402 static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type, 448 403 pj_uint32_t local_pref, … … 463 418 464 419 420 /* 421 * Add ICE candidate 422 */ 465 423 PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice, 466 424 unsigned comp_id, … … 475 433 { 476 434 pj_ice_cand *lcand; 435 pj_stun_session_cb sess_cb; 436 pj_stun_auth_cred auth_cred; 437 stun_data *sd; 477 438 pj_status_t status = PJ_SUCCESS; 478 439 char tmp[128]; … … 501 462 pj_bzero(&lcand->srv_addr, sizeof(lcand->srv_addr)); 502 463 503 if (p_cand_id) 504 *p_cand_id = ice->lcand_cnt; 464 /* Init STUN callbacks */ 465 pj_bzero(&sess_cb, sizeof(sess_cb)); 466 sess_cb.on_request_complete = &on_stun_request_complete; 467 sess_cb.on_rx_indication = &on_stun_rx_indication; 468 sess_cb.on_rx_request = &on_stun_rx_request; 469 sess_cb.on_send_msg = &on_stun_send_msg; 470 471 /* Create STUN session for this candidate */ 472 status = pj_stun_session_create(&ice->stun_cfg, ice->obj_name, 473 &sess_cb, PJ_FALSE, 474 &lcand->stun_sess); 475 if (status != PJ_SUCCESS) { 476 pj_mutex_unlock(ice->mutex); 477 return status; 478 } 479 480 /* Associate data with this STUN session */ 481 sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data); 482 sd->ice = ice; 483 sd->lcand_id = GET_LCAND_ID(lcand); 484 sd->lcand = lcand; 485 pj_stun_session_set_user_data(lcand->stun_sess, sd); 486 487 /* Init STUN authentication credential */ 488 pj_bzero(&auth_cred, sizeof(auth_cred)); 489 auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC; 490 auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth; 491 auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred; 492 auth_cred.data.dyn_cred.get_password = &stun_auth_get_password; 493 auth_cred.data.dyn_cred.verify_nonce = &stun_auth_verify_nonce; 494 auth_cred.data.dyn_cred.user_data = lcand->stun_sess; 495 pj_stun_session_set_credential(lcand->stun_sess, &auth_cred); 496 505 497 506 498 pj_ansi_strcpy(tmp, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); … … 518 510 (int)pj_htons(lcand->base_addr.ipv4.sin_port), 519 511 lcand->prio, lcand->prio)); 512 513 if (p_cand_id) 514 *p_cand_id = ice->lcand_cnt; 520 515 521 516 ++ice->lcand_cnt; … … 1042 1037 1043 1038 PJ_DEF(pj_status_t) pj_ice_create_check_list(pj_ice *ice, 1039 const pj_str_t *rem_ufrag, 1040 const pj_str_t *rem_passwd, 1044 1041 unsigned rcand_cnt, 1045 1042 const pj_ice_cand rcand[]) 1046 1043 { 1047 1044 pj_ice_checklist *clist; 1045 char buf[128]; 1046 pj_str_t username; 1048 1047 timer_data *td; 1049 1048 unsigned i, j; 1050 1049 1051 PJ_ASSERT_RETURN(ice && rcand_cnt && rcand, PJ_EINVAL); 1050 PJ_ASSERT_RETURN(ice && rem_ufrag && rem_passwd && rcand_cnt && rcand, 1051 PJ_EINVAL); 1052 1052 PJ_ASSERT_RETURN(rcand_cnt + ice->rcand_cnt <= PJ_ICE_MAX_CAND, 1053 1053 PJ_ETOOMANY); 1054 1054 1055 1055 pj_mutex_lock(ice->mutex); 1056 1057 /* Save credentials */ 1058 username.ptr = buf; 1059 1060 pj_strcpy(&username, rem_ufrag); 1061 pj_strcat2(&username, ":"); 1062 pj_strcat(&username, &ice->rx_ufrag); 1063 1064 pj_strdup(ice->pool, &ice->tx_uname, &username); 1065 pj_strdup(ice->pool, &ice->tx_ufrag, rem_ufrag); 1066 pj_strdup(ice->pool, &ice->tx_pass, rem_passwd); 1067 1068 pj_strcpy(&username, &ice->rx_ufrag); 1069 pj_strcat2(&username, ":"); 1070 pj_strcat(&username, rem_ufrag); 1071 1072 pj_strdup(ice->pool, &ice->rx_uname, &username); 1073 1056 1074 1057 1075 /* Save remote candidates */ … … 1155 1173 1156 1174 /* Create request */ 1157 status = pj_stun_session_create_req( comp->stun_sess,1175 status = pj_stun_session_create_req(lcand->stun_sess, 1158 1176 PJ_STUN_BINDING_REQUEST, &tdata); 1159 1177 if (status != PJ_SUCCESS) … … 1187 1205 1188 1206 /* Initiate STUN transaction to send the request */ 1189 status = pj_stun_session_send_msg( comp->stun_sess, PJ_FALSE,1207 status = pj_stun_session_send_msg(lcand->stun_sess, PJ_FALSE, 1190 1208 &rcand->addr, 1191 1209 sizeof(pj_sockaddr_in), tdata); … … 1332 1350 { 1333 1351 stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 1334 return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd-> comp_id,1352 return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id, sd->lcand_id, 1335 1353 pkt, pkt_size, 1336 1354 dst_addr, addr_len); … … 1535 1553 sd = (stun_data*) pj_stun_session_get_user_data(sess); 1536 1554 ice = sd->ice; 1537 comp = sd->comp; 1555 lcand = sd->lcand; 1556 comp = find_comp(ice, lcand->comp_id); 1538 1557 1539 1558 pj_mutex_lock(ice->mutex); … … 1621 1640 PJ_TODO(DETERMINE_IF_REQUEST_COMES_FROM_RELAYED_CANDIDATE); 1622 1641 is_relayed = PJ_FALSE; 1623 1624 /* Next find local candidate, by first finding a check in the checklist1625 * which base address is equal to the local address.1626 */1627 for (i=0; i<ice->clist.count; ++i) {1628 pj_ice_check *c = &ice->clist.checks[i];1629 if (sockaddr_cmp(&c->lcand->base_addr, &comp->local_addr)==0)1630 break;1631 }1632 1633 /* MUST find a local candidate! */1634 pj_assert(i != ice->clist.count);1635 if (i == ice->clist.count) {1636 pj_mutex_unlock(ice->mutex);1637 LOG((ice->obj_name, "Error: unable to find local candidate for "1638 "incoming request"));1639 return PJ_SUCCESS;1640 }1641 1642 lcand = ice->clist.checks[i].lcand;1643 1642 1644 1643 /* Now that we have local and remote candidate, check if we already … … 1759 1758 pj_status_t status = PJ_SUCCESS; 1760 1759 pj_ice_comp *comp; 1760 unsigned cand_id; 1761 1761 pj_ice_check *check; 1762 1762 … … 1777 1777 1778 1778 check = &ice->clist.checks[comp->nominated_check_id]; 1779 1780 status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len, 1779 cand_id = GET_LCAND_ID(check->lcand); 1780 1781 status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand_id, data, data_len, 1781 1782 &check->rcand->addr, 1782 1783 sizeof(pj_sockaddr_in)); … … 1790 1791 PJ_DEF(pj_status_t) pj_ice_on_rx_pkt( pj_ice *ice, 1791 1792 unsigned comp_id, 1793 unsigned cand_id, 1792 1794 void *pkt, 1793 1795 pj_size_t pkt_size, … … 1797 1799 pj_status_t status = PJ_SUCCESS; 1798 1800 pj_ice_comp *comp; 1801 pj_ice_cand *lcand; 1799 1802 pj_status_t stun_status; 1800 1803 … … 1809 1812 } 1810 1813 1814 lcand = &ice->lcand[cand_id]; 1815 1811 1816 stun_status = pj_stun_msg_check(pkt, pkt_size, PJ_STUN_IS_DATAGRAM); 1812 1817 if (stun_status == PJ_SUCCESS) { 1813 status = pj_stun_session_on_rx_pkt( comp->stun_sess, pkt, pkt_size,1818 status = pj_stun_session_on_rx_pkt(lcand->stun_sess, pkt, pkt_size, 1814 1819 PJ_STUN_IS_DATAGRAM, 1815 1820 NULL, src_addr, src_addr_len); 1816 1821 } else { 1817 status = (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size,1818 1822 (*ice->cb.on_rx_data)(ice, comp_id, cand_id, pkt, pkt_size, 1823 src_addr, src_addr_len); 1819 1824 } 1820 1825
Note: See TracChangeset
for help on using the changeset viewer.