Ignore:
Timestamp:
Mar 22, 2007 9:00:53 PM (17 years ago)
Author:
bennylp
Message:

Final ICE stream transport

File:
1 edited

Legend:

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

    r1094 r1096  
    2222#include <pj/array.h> 
    2323#include <pj/assert.h> 
     24#include <pj/guid.h> 
    2425#include <pj/log.h> 
    2526#include <pj/os.h> 
     
    6970{ 
    7071    pj_ice      *ice; 
    71     unsigned     comp_id; 
    72     pj_ice_comp *comp; 
     72    unsigned     lcand_id; 
     73    pj_ice_cand *lcand; 
    7374} stun_data; 
    7475 
     
    133134 
    134135 
     136/* 
     137 * Create ICE stream session. 
     138 */ 
    135139PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg, 
    136140                                  const char *name, 
    137141                                  pj_ice_role role, 
    138142                                  const pj_ice_cb *cb, 
     143                                  const pj_str_t *local_ufrag, 
     144                                  const pj_str_t *local_passwd, 
    139145                                  pj_ice **p_ice) 
    140146{ 
    141147    pj_pool_t *pool; 
    142148    pj_ice *ice; 
     149    char tmp[32]; 
     150    pj_str_t s; 
    143151    unsigned i; 
    144152    pj_status_t status; 
     
    146154    PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL); 
    147155 
    148     if (!name) 
     156    if (name == NULL) 
    149157        name = "ice%p"; 
    150158 
     
    171179    } 
    172180 
     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 
    173196    /* Done */ 
    174197    *p_ice = ice; 
    175198 
    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"))); 
    177201 
    178202    return PJ_SUCCESS; 
     
    180204 
    181205 
     206/* 
     207 * Destroy 
     208 */ 
    182209static void destroy_ice(pj_ice *ice, 
    183210                        pj_status_t reason) 
     
    190217 
    191218    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; 
    197226        } 
    198227    } 
     
    223252 
    224253 
     254/* Find component by ID */ 
    225255static pj_ice_comp *find_comp(const pj_ice *ice, unsigned comp_id) 
    226256{ 
     
    228258    for (i=0; i<ice->comp_cnt; ++i) { 
    229259        if (ice->comp[i].comp_id == comp_id) 
    230             return (pj_ice_comp*) &ice->comp[i]; 
     260            return (pj_ice_comp *) &ice->comp[i]; 
    231261    } 
    232262 
     
    235265 
    236266 
    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 */ 
     268PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice, unsigned comp_id) 
     269{ 
    243270    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); 
    249273    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); 
    250275    PJ_ASSERT_RETURN(find_comp(ice, comp_id) == NULL, PJ_EEXISTS); 
    251276 
     
    255280    comp->comp_id = comp_id; 
    256281    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); 
    291282 
    292283    /* Done */ 
     
    409400 
    410401 
    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  
    447402static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type, 
    448403                                  pj_uint32_t local_pref, 
     
    463418 
    464419 
     420/* 
     421 * Add ICE candidate 
     422 */ 
    465423PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice, 
    466424                                    unsigned comp_id, 
     
    475433{ 
    476434    pj_ice_cand *lcand; 
     435    pj_stun_session_cb sess_cb; 
     436    pj_stun_auth_cred auth_cred; 
     437    stun_data *sd; 
    477438    pj_status_t status = PJ_SUCCESS; 
    478439    char tmp[128]; 
     
    501462        pj_bzero(&lcand->srv_addr, sizeof(lcand->srv_addr)); 
    502463 
    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 
    505497 
    506498    pj_ansi_strcpy(tmp, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); 
     
    518510         (int)pj_htons(lcand->base_addr.ipv4.sin_port), 
    519511         lcand->prio, lcand->prio)); 
     512 
     513    if (p_cand_id) 
     514        *p_cand_id = ice->lcand_cnt; 
    520515 
    521516    ++ice->lcand_cnt; 
     
    10421037 
    10431038PJ_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, 
    10441041                                             unsigned rcand_cnt, 
    10451042                                             const pj_ice_cand rcand[]) 
    10461043{ 
    10471044    pj_ice_checklist *clist; 
     1045    char buf[128]; 
     1046    pj_str_t username; 
    10481047    timer_data *td; 
    10491048    unsigned i, j; 
    10501049 
    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); 
    10521052    PJ_ASSERT_RETURN(rcand_cnt + ice->rcand_cnt <= PJ_ICE_MAX_CAND,  
    10531053                     PJ_ETOOMANY); 
    10541054 
    10551055    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 
    10561074 
    10571075    /* Save remote candidates */ 
     
    11551173 
    11561174    /* Create request */ 
    1157     status = pj_stun_session_create_req(comp->stun_sess,  
     1175    status = pj_stun_session_create_req(lcand->stun_sess,  
    11581176                                        PJ_STUN_BINDING_REQUEST, &tdata); 
    11591177    if (status != PJ_SUCCESS) 
     
    11871205 
    11881206    /* 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,  
    11901208                                      &rcand->addr,  
    11911209                                      sizeof(pj_sockaddr_in), tdata); 
     
    13321350{ 
    13331351    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, 
    13351353                                    pkt, pkt_size,  
    13361354                                    dst_addr, addr_len); 
     
    15351553    sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    15361554    ice = sd->ice; 
    1537     comp = sd->comp; 
     1555    lcand = sd->lcand; 
     1556    comp = find_comp(ice, lcand->comp_id); 
    15381557 
    15391558    pj_mutex_lock(ice->mutex); 
     
    16211640    PJ_TODO(DETERMINE_IF_REQUEST_COMES_FROM_RELAYED_CANDIDATE); 
    16221641    is_relayed = PJ_FALSE; 
    1623  
    1624     /* Next find local candidate, by first finding a check in the checklist 
    1625      * 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; 
    16431642 
    16441643    /* Now that we have local and remote candidate, check if we already 
     
    17591758    pj_status_t status = PJ_SUCCESS; 
    17601759    pj_ice_comp *comp; 
     1760    unsigned cand_id; 
    17611761    pj_ice_check *check; 
    17621762 
     
    17771777 
    17781778    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,  
    17811782                                  &check->rcand->addr,  
    17821783                                  sizeof(pj_sockaddr_in)); 
     
    17901791PJ_DEF(pj_status_t) pj_ice_on_rx_pkt( pj_ice *ice, 
    17911792                                      unsigned comp_id, 
     1793                                      unsigned cand_id, 
    17921794                                      void *pkt, 
    17931795                                      pj_size_t pkt_size, 
     
    17971799    pj_status_t status = PJ_SUCCESS; 
    17981800    pj_ice_comp *comp; 
     1801    pj_ice_cand *lcand; 
    17991802    pj_status_t stun_status; 
    18001803 
     
    18091812    } 
    18101813 
     1814    lcand = &ice->lcand[cand_id]; 
     1815 
    18111816    stun_status = pj_stun_msg_check(pkt, pkt_size, PJ_STUN_IS_DATAGRAM); 
    18121817    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, 
    18141819                                           PJ_STUN_IS_DATAGRAM, 
    18151820                                           NULL, src_addr, src_addr_len); 
    18161821    } else { 
    1817         status = (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size,  
    1818                                        src_addr, src_addr_len); 
     1822        (*ice->cb.on_rx_data)(ice, comp_id, cand_id, pkt, pkt_size,  
     1823                              src_addr, src_addr_len); 
    18191824    } 
    18201825     
Note: See TracChangeset for help on using the changeset viewer.