Ignore:
Timestamp:
Jun 6, 2008 2:47:10 PM (16 years ago)
Author:
bennylp
Message:

Major major modifications related to ticket #485 (support for TURN-07):

  • Added STUN socket transport pj_stun_sock
  • Integration of TURN-07 to ICE
  • Major refactoring in ICE stream transport to make it simpler
  • Major modification (i.e. API change) in almost everywhere else
  • Much more elaborate STUN, TURN, and ICE tests in pjnath-test
File:
1 edited

Legend:

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

    r1913 r1988  
    2222#include <pj/assert.h> 
    2323#include <pj/guid.h> 
     24#include <pj/hash.h> 
    2425#include <pj/log.h> 
    2526#include <pj/os.h> 
     
    100101    pj_ice_sess_checklist   *clist; 
    101102} timer_data; 
     103 
     104 
     105/* This is the data that will be attached as token to outgoing 
     106 * STUN messages. 
     107 */ 
    102108 
    103109 
     
    170176 
    171177 
     178PJ_DEF(const char*) pj_ice_sess_role_name(pj_ice_sess_role role) 
     179{ 
     180    switch (role) { 
     181    case PJ_ICE_SESS_ROLE_UNKNOWN: 
     182        return "Unknown"; 
     183    case PJ_ICE_SESS_ROLE_CONTROLLED: 
     184        return "Controlled"; 
     185    case PJ_ICE_SESS_ROLE_CONTROLLING: 
     186        return "Controlling"; 
     187    default: 
     188        return "??"; 
     189    } 
     190} 
     191 
     192 
    172193/* Get the prefix for the foundation */ 
    173194static int get_type_prefix(pj_ice_cand_type type) 
     
    184205} 
    185206 
    186 /* Calculate foundation */ 
     207/* Calculate foundation: 
     208 * Two candidates have the same foundation when they are "similar" - of 
     209 * the same type and obtained from the same host candidate and STUN 
     210 * server using the same protocol.  Otherwise, their foundation is 
     211 * different. 
     212 */ 
    187213PJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool, 
    188214                                    pj_str_t *foundation, 
     
    191217{ 
    192218    char buf[64]; 
    193  
     219    pj_uint32_t val; 
     220 
     221    if (base_addr->addr.sa_family == pj_AF_INET()) { 
     222        val = pj_ntohl(base_addr->ipv4.sin_addr.s_addr); 
     223    } else { 
     224        val = pj_hash_calc(0, pj_sockaddr_get_addr(base_addr), 
     225                           pj_sockaddr_get_addr_len(base_addr)); 
     226    } 
    194227    pj_ansi_snprintf(buf, sizeof(buf), "%c%x", 
    195                      get_type_prefix(type), 
    196                      (int)pj_ntohl(base_addr->ipv4.sin_addr.s_addr)); 
     228                     get_type_prefix(type), val); 
    197229    pj_strdup2(pool, foundation, buf); 
    198230} 
     
    264296 
    265297    if (name == NULL) 
    266         name = "ice%p"; 
     298        name = "icess%p"; 
    267299 
    268300    pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS,  
     
    299331            return status; 
    300332        } 
     333    } 
     334 
     335    /* Initialize transport datas */ 
     336    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 
     337        ice->tp_data[i].transport_id = i; 
     338        ice->tp_data[i].has_req_data = PJ_FALSE; 
    301339    } 
    302340 
     
    552590PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, 
    553591                                         unsigned comp_id, 
     592                                         unsigned transport_id, 
    554593                                         pj_ice_cand_type type, 
    555594                                         pj_uint16_t local_pref, 
     
    577616 
    578617    lcand = &ice->lcand[ice->lcand_cnt]; 
    579     lcand->comp_id = comp_id; 
     618    lcand->comp_id = (pj_uint8_t)comp_id; 
     619    lcand->transport_id = (pj_uint8_t)transport_id; 
    580620    lcand->type = type; 
    581621    pj_strdup(ice->pool, &lcand->foundation, foundation); 
     
    583623    pj_memcpy(&lcand->addr, addr, addr_len); 
    584624    pj_memcpy(&lcand->base_addr, base_addr, addr_len); 
    585     if (rel_addr) 
    586         pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 
    587     else 
    588         pj_bzero(&lcand->rel_addr, sizeof(lcand->rel_addr)); 
    589  
     625    pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 
    590626 
    591627    pj_ansi_strcpy(ice->tmp.txt, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); 
     
    13231359 
    13241360    /* Disable our components which don't have matching component */ 
    1325     if (ice->comp_cnt==2 && highest_comp==1) { 
    1326         ice->comp_cnt = 1; 
    1327     } 
     1361    for (i=highest_comp; i<ice->comp_cnt; ++i) { 
     1362        if (ice->comp[i].stun_sess) { 
     1363            pj_stun_session_destroy(ice->comp[i].stun_sess); 
     1364            pj_bzero(&ice->comp[i], sizeof(ice->comp[i])); 
     1365        } 
     1366    } 
     1367    ice->comp_cnt = highest_comp; 
    13281368 
    13291369    /* Init timer entry in the checklist. Initially the timer ID is FALSE 
     
    13461386} 
    13471387 
    1348  
    1349 /* This is the data that will be attached as user data to outgoing 
    1350  * STUN requests, and it will be given back when we receive completion 
    1351  * status of the request. 
    1352  */ 
    1353 struct req_data 
    1354 { 
    1355     pj_ice_sess             *ice; 
    1356     pj_ice_sess_checklist   *clist; 
    1357     unsigned                 ckid; 
    1358 }; 
    1359  
    1360  
    13611388/* Perform check on the specified candidate pair */ 
    13621389static pj_status_t perform_check(pj_ice_sess *ice,  
     
    13651392{ 
    13661393    pj_ice_sess_comp *comp; 
    1367     struct req_data *rd; 
     1394    pj_ice_msg_data *msg_data; 
    13681395    pj_ice_sess_check *check; 
    13691396    const pj_ice_sess_cand *lcand; 
     
    13931420     * completes and on_stun_request_complete() callback is called. 
    13941421     */ 
    1395     rd = PJ_POOL_ZALLOC_T(check->tdata->pool, struct req_data); 
    1396     rd->ice = ice; 
    1397     rd->clist = clist; 
    1398     rd->ckid = check_id; 
     1422    msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, pj_ice_msg_data); 
     1423    msg_data->transport_id = lcand->transport_id; 
     1424    msg_data->has_req_data = PJ_TRUE; 
     1425    msg_data->data.req.ice = ice; 
     1426    msg_data->data.req.clist = clist; 
     1427    msg_data->data.req.ckid = check_id; 
    13991428 
    14001429    /* Add PRIORITY */ 
     
    14281457 
    14291458    /* Initiate STUN transaction to send the request */ 
    1430     status = pj_stun_session_send_msg(comp->stun_sess, (void*)rd, PJ_FALSE,  
     1459    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE,  
    14311460                                      PJ_TRUE, &rcand->addr,  
    14321461                                      sizeof(pj_sockaddr_in), check->tdata); 
     
    16561685    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    16571686    pj_ice_sess *ice = sd->ice; 
    1658  
    1659     PJ_UNUSED_ARG(token); 
    1660  
    1661     return (*ice->cb.on_tx_pkt)(ice, sd->comp_id,  
    1662                                 pkt, pkt_size,  
    1663                                 dst_addr, addr_len); 
     1687    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token; 
     1688     
     1689    return (*ice->cb.on_tx_pkt)(ice, sd->comp_id, msg_data->transport_id, 
     1690                                pkt, pkt_size, dst_addr, addr_len); 
    16641691} 
    16651692 
     
    16741701                                     unsigned src_addr_len) 
    16751702{ 
    1676     struct req_data *rd = (struct req_data*) token; 
     1703    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token; 
    16771704    pj_ice_sess *ice; 
    16781705    pj_ice_sess_check *check, *new_check; 
     
    16851712    PJ_UNUSED_ARG(src_addr_len); 
    16861713 
    1687     ice = rd->ice; 
    1688     check = &rd->clist->checks[rd->ckid]; 
    1689     clist = rd->clist; 
     1714    pj_assert(msg_data->has_req_data); 
     1715 
     1716    ice = msg_data->data.req.ice; 
     1717    clist = msg_data->data.req.clist; 
     1718    check = &clist->checks[msg_data->data.req.ckid]; 
     1719     
    16901720 
    16911721    /* Mark STUN transaction as complete */ 
     
    17401770            LOG4((ice->obj_name, "Resending check because of role conflict")); 
    17411771            check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0); 
    1742             perform_check(ice, clist, rd->ckid); 
     1772            perform_check(ice, clist, msg_data->data.req.ckid); 
    17431773            pj_mutex_unlock(ice->mutex); 
    17441774            return; 
     
    18471877        /* Add new peer reflexive candidate */ 
    18481878        status = pj_ice_sess_add_cand(ice, check->lcand->comp_id,  
     1879                                      msg_data->transport_id, 
    18491880                                      PJ_ICE_CAND_TYPE_PRFLX, 
    18501881                                      65535, &foundation, 
     
    19201951    stun_data *sd; 
    19211952    const pj_stun_msg *msg = rdata->msg; 
     1953    pj_ice_msg_data *msg_data; 
    19221954    pj_ice_sess *ice; 
    19231955    pj_stun_priority_attr *prio_attr; 
     
    19301962    PJ_UNUSED_ARG(pkt); 
    19311963    PJ_UNUSED_ARG(pkt_len); 
    1932     PJ_UNUSED_ARG(token); 
    1933  
     1964     
    19341965    /* Reject any requests except Binding request */ 
    19351966    if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) { 
    19361967        pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,  
    1937                                 NULL, NULL, PJ_TRUE,  
     1968                                NULL, token, PJ_TRUE,  
    19381969                                src_addr, src_addr_len); 
    19391970        return PJ_SUCCESS; 
     
    20022033            /* Generate 487 response */ 
    20032034            pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT,  
    2004                                     NULL, NULL, PJ_TRUE,  
     2035                                    NULL, token, PJ_TRUE,  
    20052036                                    src_addr, src_addr_len); 
    20062037            pj_mutex_unlock(ice->mutex); 
     
    20142045            /* Generate 487 response */ 
    20152046            pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT,  
    2016                                     NULL, NULL, PJ_TRUE,  
     2047                                    NULL, token, PJ_TRUE,  
    20172048                                    src_addr, src_addr_len); 
    20182049            pj_mutex_unlock(ice->mutex); 
     
    20352066    } 
    20362067 
     2068    /* Add XOR-MAPPED-ADDRESS attribute */ 
    20372069    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,  
    20382070                                           PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
    20392071                                           PJ_TRUE, src_addr, src_addr_len); 
    20402072 
    2041     status = pj_stun_session_send_msg(sess, NULL, PJ_TRUE, PJ_TRUE, 
     2073    /* Create a msg_data to be associated with this response */ 
     2074    msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data); 
     2075    msg_data->transport_id = ((pj_ice_msg_data*)token)->transport_id; 
     2076    msg_data->has_req_data = PJ_FALSE; 
     2077 
     2078    /* Send the response */ 
     2079    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE, 
    20422080                                      src_addr, src_addr_len, tdata); 
    20432081 
     
    20592097    /* Init rcheck */ 
    20602098    rcheck->comp_id = sd->comp_id; 
     2099    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id; 
    20612100    rcheck->src_addr_len = src_addr_len; 
    20622101    pj_memcpy(&rcheck->src_addr, src_addr, src_addr_len); 
     
    20912130    pj_ice_sess_cand *rcand; 
    20922131    unsigned i; 
    2093     pj_bool_t is_relayed; 
    20942132 
    20952133    comp = find_comp(ice, rcheck->comp_id); 
     
    21102148    if (i == ice->rcand_cnt) { 
    21112149        rcand = &ice->rcand[ice->rcand_cnt++]; 
    2112         rcand->comp_id = rcheck->comp_id; 
     2150        rcand->comp_id = (pj_uint8_t)rcheck->comp_id; 
    21132151        rcand->type = PJ_ICE_CAND_TYPE_PRFLX; 
    21142152        rcand->prio = rcheck->priority; 
     
    21482186    } 
    21492187#else 
    2150     /* Just get candidate with the highest priority for the specified  
    2151      * component ID in the checklist. 
     2188    /* Just get candidate with the highest priority and same transport ID 
     2189     * for the specified  component ID in the checklist. 
    21522190     */ 
    21532191    for (i=0; i<ice->clist.count; ++i) { 
    21542192        pj_ice_sess_check *c = &ice->clist.checks[i]; 
    2155         if (c->lcand->comp_id == rcheck->comp_id) { 
     2193        if (c->lcand->comp_id == rcheck->comp_id && 
     2194            c->lcand->transport_id == rcheck->transport_id)  
     2195        { 
    21562196            lcand = c->lcand; 
    21572197            break; 
     
    21712211     * Create candidate pair for this request.  
    21722212     */ 
    2173     /* First check if the source address is the source address of the  
    2174      * STUN relay, to determine if local candidate is relayed candidate. 
    2175      */ 
    2176     PJ_TODO(DETERMINE_IF_REQUEST_COMES_FROM_RELAYED_CANDIDATE); 
    2177     is_relayed = PJ_FALSE; 
    21782213 
    21792214    /*  
     
    23102345    pj_status_t status = PJ_SUCCESS; 
    23112346    pj_ice_sess_comp *comp; 
     2347    pj_ice_sess_cand *cand; 
    23122348 
    23132349    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL); 
     
    23332369    } 
    23342370 
    2335     status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len,  
     2371    cand = comp->valid_check->lcand; 
     2372    status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand->transport_id,  
     2373                                  data, data_len,  
    23362374                                  &comp->valid_check->rcand->addr,  
    23372375                                  sizeof(pj_sockaddr_in)); 
     
    23452383PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
    23462384                                          unsigned comp_id, 
     2385                                          unsigned transport_id, 
    23472386                                          void *pkt, 
    23482387                                          pj_size_t pkt_size, 
     
    23522391    pj_status_t status = PJ_SUCCESS; 
    23532392    pj_ice_sess_comp *comp; 
     2393    pj_ice_msg_data *msg_data = NULL; 
     2394    unsigned i; 
    23542395    pj_status_t stun_status; 
    23552396 
     
    23642405    } 
    23652406 
     2407    /* Find transport */ 
     2408    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 
     2409        if (ice->tp_data[i].transport_id == transport_id) { 
     2410            msg_data = &ice->tp_data[i]; 
     2411            break; 
     2412        } 
     2413    } 
     2414    if (msg_data == NULL) { 
     2415        pj_assert(!"Invalid transport ID"); 
     2416        status = PJ_EINVAL; 
     2417        goto on_return; 
     2418    } 
     2419 
    23662420    stun_status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size,  
    23672421                                    PJ_STUN_IS_DATAGRAM); 
    23682422    if (stun_status == PJ_SUCCESS) { 
    23692423        status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size, 
    2370                                            PJ_STUN_IS_DATAGRAM, NULL, 
     2424                                           PJ_STUN_IS_DATAGRAM, msg_data, 
    23712425                                           NULL, src_addr, src_addr_len); 
    23722426        if (status != PJ_SUCCESS) { 
     
    23762430        } 
    23772431    } else { 
    2378         (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size,  
     2432        (*ice->cb.on_rx_data)(ice, comp_id, transport_id, pkt, pkt_size,  
    23792433                              src_addr, src_addr_len); 
    23802434    } 
Note: See TracChangeset for help on using the changeset viewer.