Ignore:
Timestamp:
Apr 3, 2007 6:01:27 PM (17 years ago)
Author:
bennylp
Message:

Fixed misc bugs with ICE: (1) moved STUN session from candidate to component since it causes STUN response to wrong session, and (2) keep-alive transaction timed-out when ICE is active

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r1129 r1140  
    8484{ 
    8585    pj_ice_sess         *ice; 
    86     pj_ice_sess_cand    *lcand; 
     86    unsigned             comp_id; 
     87    pj_ice_sess_comp    *comp; 
    8788} stun_data; 
    8889 
     
    180181 
    181182 
     183/* Init component */ 
     184static pj_status_t init_comp(pj_ice_sess *ice, 
     185                             unsigned comp_id, 
     186                             pj_ice_sess_comp *comp) 
     187{ 
     188    pj_stun_session_cb sess_cb; 
     189    pj_stun_auth_cred auth_cred; 
     190    stun_data *sd; 
     191    pj_status_t status; 
     192 
     193    /* Init STUN callbacks */ 
     194    pj_bzero(&sess_cb, sizeof(sess_cb)); 
     195    sess_cb.on_request_complete = &on_stun_request_complete; 
     196    sess_cb.on_rx_indication = &on_stun_rx_indication; 
     197    sess_cb.on_rx_request = &on_stun_rx_request; 
     198    sess_cb.on_send_msg = &on_stun_send_msg; 
     199 
     200    /* Create STUN session for this candidate */ 
     201    status = pj_stun_session_create(&ice->stun_cfg, NULL,  
     202                                    &sess_cb, PJ_FALSE, 
     203                                    &comp->stun_sess); 
     204    if (status != PJ_SUCCESS) 
     205        return status; 
     206 
     207    /* Associate data with this STUN session */ 
     208    sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data); 
     209    sd->ice = ice; 
     210    sd->comp_id = comp_id; 
     211    sd->comp = comp; 
     212    pj_stun_session_set_user_data(comp->stun_sess, sd); 
     213 
     214    /* Init STUN authentication credential */ 
     215    pj_bzero(&auth_cred, sizeof(auth_cred)); 
     216    auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC; 
     217    auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth; 
     218    auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred; 
     219    auth_cred.data.dyn_cred.get_password = &stun_auth_get_password; 
     220    auth_cred.data.dyn_cred.user_data = comp->stun_sess; 
     221    pj_stun_session_set_credential(comp->stun_sess, &auth_cred); 
     222 
     223    return PJ_SUCCESS; 
     224} 
     225 
     226 
    182227/* 
    183228 * Create ICE session. 
     
    228273        comp = &ice->comp[i]; 
    229274        comp->valid_check = NULL; 
     275 
     276        status = init_comp(ice, i+1, comp); 
     277        if (status != PJ_SUCCESS) { 
     278            destroy_ice(ice, status); 
     279            return status; 
     280        } 
    230281    } 
    231282 
     
    233284        ice->rx_ufrag.ptr = pj_pool_alloc(ice->pool, 16); 
    234285        pj_create_random_string(ice->rx_ufrag.ptr, 16); 
     286        ice->rx_ufrag.slen = 16; 
    235287    } else { 
    236288        pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag); 
     
    240292        ice->rx_pass.ptr = pj_pool_alloc(ice->pool, 16); 
    241293        pj_create_random_string(ice->rx_pass.ptr, 16); 
     294        ice->rx_pass.slen = 16; 
    242295    } else { 
    243296        pj_strdup(ice->pool, &ice->rx_pass, local_passwd); 
     
    268321    } 
    269322 
    270     for (i=0; i<ice->lcand_cnt; ++i) { 
    271         if (ice->lcand[i].stun_sess) { 
    272             pj_stun_session_destroy(ice->lcand[i].stun_sess); 
    273             ice->lcand[i].stun_sess = NULL; 
     323    for (i=0; i<ice->comp_cnt; ++i) { 
     324        if (ice->comp[i].stun_sess) { 
     325            pj_stun_session_destroy(ice->comp[i].stun_sess); 
     326            ice->comp[i].stun_sess = NULL; 
    274327        } 
    275328    } 
     
    466519{ 
    467520    pj_ice_sess_cand *lcand; 
    468     pj_stun_session_cb sess_cb; 
    469     pj_stun_auth_cred auth_cred; 
    470     stun_data *sd; 
    471521    pj_status_t status = PJ_SUCCESS; 
    472522    char tmp[128]; 
     
    495545    else 
    496546        pj_bzero(&lcand->rel_addr, sizeof(lcand->rel_addr)); 
    497  
    498  
    499     /* Init STUN callbacks */ 
    500     pj_bzero(&sess_cb, sizeof(sess_cb)); 
    501     sess_cb.on_request_complete = &on_stun_request_complete; 
    502     sess_cb.on_rx_indication = &on_stun_rx_indication; 
    503     sess_cb.on_rx_request = &on_stun_rx_request; 
    504     sess_cb.on_send_msg = &on_stun_send_msg; 
    505  
    506     /* Create STUN session for this candidate */ 
    507     status = pj_stun_session_create(&ice->stun_cfg, ice->obj_name,  
    508                                     &sess_cb, PJ_FALSE, 
    509                                     &lcand->stun_sess); 
    510     if (status != PJ_SUCCESS) { 
    511         pj_mutex_unlock(ice->mutex); 
    512         return status; 
    513     } 
    514  
    515     /* Associate data with this STUN session */ 
    516     sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data); 
    517     sd->ice = ice; 
    518     sd->lcand = lcand; 
    519     pj_stun_session_set_user_data(lcand->stun_sess, sd); 
    520  
    521     /* Init STUN authentication credential */ 
    522     pj_bzero(&auth_cred, sizeof(auth_cred)); 
    523     auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC; 
    524     auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth; 
    525     auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred; 
    526     auth_cred.data.dyn_cred.get_password = &stun_auth_get_password; 
    527     auth_cred.data.dyn_cred.user_data = lcand->stun_sess; 
    528     pj_stun_session_set_credential(lcand->stun_sess, &auth_cred); 
    529547 
    530548 
     
    909927             GET_CHECK_ID(&ice->clist, check))); 
    910928 
     929        comp = find_comp(ice, check->lcand->comp_id); 
     930 
    911931        for (i=0; i<ice->clist.count; ++i) { 
    912932            pj_ice_sess_check *c = &ice->clist.checks[i]; 
     
    927947                             "Cancelling check %s (In Progress)", 
    928948                             dump_check(buf, sizeof(buf), &ice->clist, c))); 
    929                         pj_stun_session_cancel_req(c->lcand->stun_sess,  
     949                        pj_stun_session_cancel_req(comp->stun_sess,  
    930950                                                   c->tdata, PJ_FALSE, 0); 
    931951                        c->tdata = NULL; 
     
    938958 
    939959        /* Update the nominated check for the component */ 
    940         comp = find_comp(ice, check->lcand->comp_id); 
    941960        if (comp->valid_check == NULL) { 
    942961            comp->valid_check = check; 
     
    11651184 
    11661185    /* Create request */ 
    1167     status = pj_stun_session_create_req(lcand->stun_sess,  
     1186    status = pj_stun_session_create_req(comp->stun_sess,  
    11681187                                        PJ_STUN_BINDING_REQUEST,  
    1169                                         &check->tdata); 
     1188                                        NULL, &check->tdata); 
    11701189    if (status != PJ_SUCCESS) { 
    11711190        pjnath_perror(ice->obj_name, "Error creating STUN request", status); 
     
    12001219 
    12011220    /* Initiate STUN transaction to send the request */ 
    1202     status = pj_stun_session_send_msg(lcand->stun_sess, PJ_FALSE,  
     1221    status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE,  
    12031222                                      &rcand->addr,  
    12041223                                      sizeof(pj_sockaddr_in), check->tdata); 
     
    14001419    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    14011420    pj_ice_sess *ice = sd->ice; 
    1402     return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id,  
    1403                                     GET_LCAND_ID(sd->lcand), 
    1404                                     pkt, pkt_size,  
    1405                                     dst_addr, addr_len); 
     1421    return (*ice->cb.on_tx_pkt)(ice, sd->comp_id,  
     1422                                pkt, pkt_size,  
     1423                                dst_addr, addr_len); 
    14061424} 
    14071425 
     
    16001618    pj_stun_use_candidate_attr *uc; 
    16011619    pj_ice_sess_comp *comp; 
    1602     pj_ice_sess_cand *lcand; 
     1620    pj_ice_sess_cand *lcand = NULL; 
    16031621    pj_ice_sess_cand *rcand; 
    16041622    unsigned i; 
     
    16251643    sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    16261644    ice = sd->ice; 
    1627     lcand = sd->lcand; 
    1628     comp = find_comp(ice, lcand->comp_id); 
     1645    comp = sd->comp; 
    16291646 
    16301647    pj_mutex_lock(ice->mutex); 
     
    16831700    if (i == ice->rcand_cnt) { 
    16841701        rcand = &ice->rcand[ice->rcand_cnt++]; 
    1685         rcand->comp_id = lcand->comp_id; 
     1702        rcand->comp_id = sd->comp_id; 
    16861703        rcand->type = PJ_ICE_CAND_TYPE_PRFLX; 
    16871704        rcand->prio = ap->value; 
     
    17031720        rcand = &ice->rcand[i]; 
    17041721    } 
     1722 
     1723#if 0 
     1724    /* Find again the local candidate by matching the base address 
     1725     * with the local candidates in the checklist. Checks may have 
     1726     * been pruned before, so it's possible that if we use the lcand 
     1727     * as it is, we wouldn't be able to find the check in the checklist 
     1728     * and we will end up creating a new check unnecessarily. 
     1729     */ 
     1730    for (i=0; i<ice->clist.count; ++i) { 
     1731        pj_ice_sess_check *c = &ice->clist.checks[i]; 
     1732        if (/*c->lcand == lcand ||*/ 
     1733            sockaddr_cmp(&c->lcand->base_addr, &lcand->base_addr)==0) 
     1734        { 
     1735            lcand = c->lcand; 
     1736            break; 
     1737        } 
     1738    } 
     1739#else 
     1740    /* Just get candidate with the highest priority for the specified  
     1741     * component ID in the checklist. 
     1742     */ 
     1743    for (i=0; i<ice->clist.count; ++i) { 
     1744        pj_ice_sess_check *c = &ice->clist.checks[i]; 
     1745        if (c->lcand->comp_id == sd->comp_id) { 
     1746            lcand = c->lcand; 
     1747            break; 
     1748        } 
     1749    } 
     1750    pj_assert(lcand != NULL); 
     1751#endif 
    17051752 
    17061753    /*  
     
    18231870 
    18241871 
    1825 PJ_DEF(pj_status_t) pj_ice_sess_send_data( pj_ice_sess *ice, 
    1826                                       unsigned comp_id, 
    1827                                       const void *data, 
    1828                                       pj_size_t data_len) 
     1872PJ_DEF(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice, 
     1873                                          unsigned comp_id, 
     1874                                          const void *data, 
     1875                                          pj_size_t data_len) 
    18291876{ 
    18301877    pj_status_t status = PJ_SUCCESS; 
    18311878    pj_ice_sess_comp *comp; 
    1832     unsigned cand_id; 
    18331879 
    18341880    PJ_ASSERT_RETURN(ice && comp_id && comp_id <= ice->comp_cnt, PJ_EINVAL); 
     
    18471893    } 
    18481894 
    1849     cand_id = GET_LCAND_ID(comp->valid_check->lcand); 
    1850     status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand_id, data, data_len,  
     1895    status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len,  
    18511896                                  &comp->valid_check->rcand->addr,  
    18521897                                  sizeof(pj_sockaddr_in)); 
     
    18581903 
    18591904 
    1860 PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt( pj_ice_sess *ice, 
    1861                                       unsigned comp_id, 
    1862                                       unsigned cand_id, 
    1863                                       void *pkt, 
    1864                                       pj_size_t pkt_size, 
    1865                                       const pj_sockaddr_t *src_addr, 
    1866                                       int src_addr_len) 
     1905PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
     1906                                          unsigned comp_id, 
     1907                                          void *pkt, 
     1908                                          pj_size_t pkt_size, 
     1909                                          const pj_sockaddr_t *src_addr, 
     1910                                          int src_addr_len) 
    18671911{ 
    18681912    pj_status_t status = PJ_SUCCESS; 
    18691913    pj_ice_sess_comp *comp; 
    1870     pj_ice_sess_cand *lcand; 
    18711914    pj_status_t stun_status; 
    18721915 
     
    18811924    } 
    18821925 
    1883     lcand = &ice->lcand[cand_id]; 
    1884  
    18851926    stun_status = pj_stun_msg_check(pkt, pkt_size, PJ_STUN_IS_DATAGRAM); 
    18861927    if (stun_status == PJ_SUCCESS) { 
    1887         status = pj_stun_session_on_rx_pkt(lcand->stun_sess, pkt, pkt_size, 
     1928        status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size, 
    18881929                                           PJ_STUN_IS_DATAGRAM, 
    18891930                                           NULL, src_addr, src_addr_len); 
Note: See TracChangeset for help on using the changeset viewer.