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/turn_session.c

    r1929 r1988  
    3030#include <pj/sock.h> 
    3131 
    32 #define MAX_SRV_CNT         4 
    33 #define REFRESH_SEC_BEFORE  60 
     32#define PJ_TURN_CHANNEL_MIN         0x4000 
     33#define PJ_TURN_CHANNEL_MAX         0xFFFE  /* inclusive */ 
     34#define PJ_TURN_PEER_HTABLE_SIZE    8 
    3435 
    3536static const char *state_names[] =  
     
    6768    pj_turn_session_cb   cb; 
    6869    void                *user_data; 
     70    pj_stun_config       stun_cfg; 
    6971 
    7072    pj_lock_t           *lock; 
     
    7274 
    7375    pj_turn_state_t      state; 
     76    pj_status_t          last_status; 
    7477    pj_bool_t            pending_destroy; 
    7578    pj_bool_t            destroy_notified; 
     
    8891 
    8992    pj_uint16_t          af; 
    90     pj_turn_tp_type      tp_type; 
     93    pj_turn_tp_type      conn_type; 
    9194    pj_uint16_t          srv_addr_cnt; 
    9295    pj_sockaddr         *srv_addr_list; 
     
    9699    pj_turn_alloc_param  alloc_param; 
    97100 
     101    pj_sockaddr          mapped_addr; 
    98102    pj_sockaddr          relay_addr; 
    99103 
     
    177181 * Create TURN client session. 
    178182 */ 
    179 PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg, 
     183PJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg, 
    180184                                            const char *name, 
    181185                                            int af, 
    182                                             pj_turn_tp_type tp_type, 
     186                                            pj_turn_tp_type conn_type, 
    183187                                            const pj_turn_session_cb *cb, 
     188                                            unsigned options, 
    184189                                            void *user_data, 
    185                                             unsigned options, 
    186190                                            pj_turn_session **p_sess) 
    187191{ 
     
    207211    sess->timer_heap = cfg->timer_heap; 
    208212    sess->af = (pj_uint16_t)af; 
    209     sess->tp_type = tp_type; 
     213    sess->conn_type = conn_type; 
    210214    sess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC; 
    211215    sess->user_data = user_data; 
    212216    sess->next_ch = PJ_TURN_CHANNEL_MIN; 
     217 
     218    /* Copy STUN session */ 
     219    pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config)); 
    213220 
    214221    /* Copy callback */ 
     
    234241    stun_cb.on_request_complete = &stun_on_request_complete; 
    235242    stun_cb.on_rx_indication = &stun_on_rx_indication; 
    236     status = pj_stun_session_create(cfg, sess->obj_name, &stun_cb, PJ_FALSE, 
    237                                     &sess->stun); 
     243    status = pj_stun_session_create(&sess->stun_cfg, sess->obj_name, &stun_cb, 
     244                                    PJ_FALSE, &sess->stun); 
    238245    if (status != PJ_SUCCESS) { 
    239246        do_destroy(sess); 
     
    334341        break; 
    335342    case PJ_TURN_STATE_RESOLVING: 
    336         pj_assert(sess->dns_async != NULL); 
    337         pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 
    338         sess->dns_async = NULL; 
     343        if (sess->dns_async != NULL) { 
     344            pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 
     345            sess->dns_async = NULL; 
     346        } 
    339347        break; 
    340348    case PJ_TURN_STATE_RESOLVED: 
     
    366374        pj_time_val delay = {0, 0}; 
    367375 
     376        set_state(sess, PJ_TURN_STATE_DESTROYING); 
     377 
    368378        if (sess->timer.id != TIMER_NONE) { 
    369379            pj_timer_heap_cancel(sess->timer_heap, &sess->timer); 
     
    371381        } 
    372382 
    373         set_state(sess, PJ_TURN_STATE_DESTROYING); 
    374  
    375383        sess->timer.id = TIMER_DESTROY; 
    376384        pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay); 
     
    401409PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) 
    402410{ 
     411    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
     412 
    403413    set_state(sess, PJ_TURN_STATE_DEALLOCATED); 
    404414    sess_shutdown(sess, PJ_SUCCESS); 
     
    420430 
    421431    info->state = sess->state; 
    422     info->tp_type = sess->tp_type; 
     432    info->conn_type = sess->conn_type; 
    423433    info->lifetime = sess->expiry.sec - now.sec; 
     434    info->last_status = sess->last_status; 
    424435 
    425436    if (sess->srv_addr) 
     
    428439        pj_bzero(&info->server, sizeof(info->server)); 
    429440 
    430     pj_memcpy(&info->relay_addr, &sess->relay_addr, sizeof(sess->relay_addr)); 
     441    pj_memcpy(&info->mapped_addr, &sess->mapped_addr,  
     442              sizeof(sess->mapped_addr)); 
     443    pj_memcpy(&info->relay_addr, &sess->relay_addr,  
     444              sizeof(sess->relay_addr)); 
    431445 
    432446    return PJ_SUCCESS; 
     
    451465{ 
    452466    return sess->user_data; 
     467} 
     468 
     469 
     470/* 
     471 * Configure message logging. By default all flags are enabled. 
     472 * 
     473 * @param sess          The TURN client session. 
     474 * @param flags         Bitmask combination of #pj_stun_sess_msg_log_flag 
     475 */ 
     476PJ_DEF(void) pj_turn_session_set_log( pj_turn_session *sess, 
     477                                      unsigned flags) 
     478{ 
     479    pj_stun_session_set_log(sess->stun, flags); 
    453480} 
    454481 
     
    462489                                                pj_dns_resolver *resolver) 
    463490{ 
     491    pj_sockaddr tmp_addr; 
     492    pj_bool_t is_ip_addr; 
    464493    pj_status_t status; 
    465494 
     
    469498    pj_lock_acquire(sess->lock); 
    470499 
    471     if (resolver) { 
     500    /* See if "domain" contains just IP address */ 
     501    tmp_addr.addr.sa_family = sess->af; 
     502    status = pj_inet_pton(sess->af, domain,  
     503                          pj_sockaddr_get_addr(&tmp_addr)); 
     504    is_ip_addr = (status == PJ_SUCCESS); 
     505 
     506    if (!is_ip_addr && resolver) { 
    472507        /* Resolve with DNS SRV resolution, and fallback to DNS A resolution 
    473508         * if default_port is specified. 
     
    476511        pj_str_t res_name; 
    477512 
    478         switch (sess->tp_type) { 
     513        switch (sess->conn_type) { 
    479514        case PJ_TURN_TP_UDP: 
    480515            res_name = pj_str("_turn._udp."); 
     
    502537        set_state(sess, PJ_TURN_STATE_RESOLVING); 
    503538 
     539        /* User may have destroyed us in the callback */ 
     540        if (sess->state != PJ_TURN_STATE_RESOLVING) { 
     541            status = PJ_ECANCELLED; 
     542            goto on_return; 
     543        } 
     544 
    504545        status = pj_dns_srv_resolve(domain, &res_name, default_port,  
    505546                                    sess->pool, resolver, opt, sess,  
     
    521562        sess->default_port = (pj_uint16_t)default_port; 
    522563 
    523         cnt = MAX_SRV_CNT; 
     564        cnt = PJ_TURN_MAX_DNS_SRV_CNT; 
    524565        ai = (pj_addrinfo*) 
    525566             pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo)); 
     
    527568        PJ_LOG(5,(sess->obj_name, "Resolving %.*s with DNS A", 
    528569                  (int)domain->slen, domain->ptr)); 
     570        set_state(sess, PJ_TURN_STATE_RESOLVING); 
     571 
     572        /* User may have destroyed us in the callback */ 
     573        if (sess->state != PJ_TURN_STATE_RESOLVING) { 
     574            status = PJ_ECANCELLED; 
     575            goto on_return; 
     576        } 
    529577 
    530578        status = pj_getaddrinfo(sess->af, domain, &cnt, ai); 
     
    637685    /* Send request */ 
    638686    set_state(sess, PJ_TURN_STATE_ALLOCATING); 
    639     retransmit = (sess->tp_type == PJ_TURN_TP_UDP); 
     687    retransmit = (sess->conn_type == PJ_TURN_TP_UDP); 
    640688    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE,  
    641689                                      retransmit, sess->srv_addr, 
     
    682730 
    683731    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE,  
    684                                       (sess->tp_type==PJ_TURN_TP_UDP), 
     732                                      (sess->conn_type==PJ_TURN_TP_UDP), 
    685733                                      sess->srv_addr, 
    686734                                      pj_sockaddr_get_len(sess->srv_addr),  
     
    834882     */ 
    835883    status = pj_stun_session_send_msg(sess->stun, peer, PJ_FALSE,  
    836                                       (sess->tp_type==PJ_TURN_TP_UDP), 
     884                                      (sess->conn_type==PJ_TURN_TP_UDP), 
    837885                                      sess->srv_addr, 
    838886                                      pj_sockaddr_get_len(sess->srv_addr), 
     
    850898 */ 
    851899PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 
    852                                               const pj_uint8_t *pkt, 
    853                                               unsigned pkt_len, 
    854                                               pj_bool_t is_datagram) 
     900                                              void *pkt, 
     901                                              unsigned pkt_len) 
    855902{ 
    856903    pj_bool_t is_stun; 
    857904    pj_status_t status; 
     905    pj_bool_t is_datagram; 
    858906 
    859907    /* Packet could be ChannelData or STUN message (response or 
     
    864912    pj_lock_acquire(sess->lock); 
    865913 
     914    is_datagram = (sess->conn_type==PJ_TURN_TP_UDP); 
     915 
    866916    /* Quickly check if this is STUN message */ 
    867     is_stun = ((pkt[0] & 0xC0) == 0); 
     917    is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0); 
    868918 
    869919    if (is_stun) { 
     
    871921        unsigned options; 
    872922 
    873         options = PJ_STUN_CHECK_PACKET; 
     923        options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 
    874924        if (is_datagram) 
    875925            options |= PJ_STUN_IS_DATAGRAM; 
     
    906956 
    907957        /* Notify application */ 
    908         (*sess->cb.on_rx_data)(sess, pkt+sizeof(cd), cd.length, 
    909                                &peer->addr, 
     958        (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd),  
     959                               cd.length, &peer->addr, 
    910960                               pj_sockaddr_get_len(&peer->addr)); 
    911961 
     
    9541004                             const pj_str_t *reason) 
    9551005{ 
     1006    sess->last_status = status; 
     1007 
    9561008    do { 
    9571009        pj_str_t reason1; 
     
    10111063    const pj_stun_lifetime_attr *lf_attr; 
    10121064    const pj_stun_relay_addr_attr *raddr_attr; 
     1065    const pj_stun_sockaddr_attr *mapped_attr; 
    10131066    pj_str_t s; 
    10141067    pj_time_val timeout; 
     
    10701123                                    " address family is not supported " 
    10711124                                    "for now")); 
     1125        return; 
     1126    } 
     1127    if (raddr_attr && !pj_sockaddr_has_addr(&raddr_attr->sockaddr)) { 
     1128        on_session_fail(sess, method, PJNATH_EINSTUNMSG, 
     1129                        pj_cstr(&s, "Error: Invalid IP address in " 
     1130                                    "RELAY-ADDRESS attribute")); 
    10721131        return; 
    10731132    } 
     
    10921151    } 
    10931152 
     1153    /* Get mapped address */ 
     1154    mapped_attr = (const pj_stun_sockaddr_attr*) 
     1155                  pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0); 
     1156    if (mapped_attr) { 
     1157        pj_memcpy(&sess->mapped_addr, &mapped_attr->sockaddr, 
     1158                  sizeof(mapped_attr->sockaddr)); 
     1159    } 
     1160 
    10941161    /* Success */ 
    10951162 
     
    11331200 
    11341201    if (method == PJ_STUN_ALLOCATE_METHOD) { 
     1202 
     1203        /* Destroy if we have pending destroy request */ 
     1204        if (sess->pending_destroy) { 
     1205            if (status == PJ_SUCCESS) 
     1206                sess->state = PJ_TURN_STATE_READY; 
     1207            else 
     1208                sess->state = PJ_TURN_STATE_DEALLOCATED; 
     1209            sess_shutdown(sess, PJ_SUCCESS); 
     1210            return; 
     1211        } 
     1212 
    11351213        /* Handle ALLOCATE response */ 
    11361214        if (status==PJ_SUCCESS &&  
     
    12991377{ 
    13001378    pj_turn_session *sess = (pj_turn_session*) user_data; 
    1301     unsigned i, cnt; 
     1379    unsigned i, cnt, tot_cnt; 
    13021380 
    13031381    /* Clear async resolver */ 
     
    13101388    } 
    13111389 
     1390    /* Calculate total number of server entries in the response */ 
     1391    tot_cnt = 0; 
     1392    for (i=0; i<rec->count; ++i) { 
     1393        tot_cnt += rec->entry[i].server.addr_count; 
     1394    } 
     1395 
     1396    if (tot_cnt > PJ_TURN_MAX_DNS_SRV_CNT) 
     1397        tot_cnt = PJ_TURN_MAX_DNS_SRV_CNT; 
     1398 
     1399    /* Allocate server entries */ 
     1400    sess->srv_addr_list = (pj_sockaddr*) 
     1401                           pj_pool_calloc(sess->pool, tot_cnt,  
     1402                                          sizeof(pj_sockaddr)); 
     1403 
    13121404    /* Copy results to server entries */ 
    1313     for (i=0, cnt=0; i<rec->count && cnt<MAX_SRV_CNT; ++i) { 
     1405    for (i=0, cnt=0; i<rec->count && cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++i) { 
    13141406        unsigned j; 
    13151407 
    1316         for (j=0; j<rec->entry[i].server.addr_count && cnt<MAX_SRV_CNT; ++j) { 
     1408        for (j=0; j<rec->entry[i].server.addr_count &&  
     1409                  cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j)  
     1410        { 
    13171411            pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4; 
    13181412 
Note: See TracChangeset for help on using the changeset viewer.