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

    r1913 r1988  
    3030    void                *user_data; 
    3131 
     32    pj_atomic_t         *busy; 
     33    pj_bool_t            destroy_request; 
     34 
    3235    pj_bool_t            use_fingerprint; 
    3336 
     37    pj_pool_t           *rx_pool; 
     38 
     39#if PJ_LOG_MAX_LEVEL >= 5 
    3440    char                 dump_buf[1000]; 
     41#endif 
     42    unsigned             log_flag; 
    3543 
    3644    pj_stun_auth_type    auth_type; 
     
    3846    int                  auth_retry; 
    3947    pj_str_t             next_nonce; 
     48    pj_str_t             server_realm; 
    4049 
    4150    pj_str_t             srv_name; 
     
    8089                           pj_stun_tx_data *tdata) 
    8190{ 
    82     pj_list_push_back(&sess->pending_request_list, tdata); 
     91    pj_list_push_front(&sess->pending_request_list, tdata); 
    8392    return PJ_SUCCESS; 
    8493} 
     
    139148 
    140149    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
     150    tsx_erase(tdata->sess, tdata); 
     151 
    141152    pj_stun_client_tsx_destroy(tsx); 
    142153    pj_pool_release(tdata->pool); 
    143154} 
    144155 
    145 static void destroy_tdata(pj_stun_tx_data *tdata) 
     156static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force) 
    146157{ 
    147158    if (tdata->res_timer.id != PJ_FALSE) { 
     
    152163    } 
    153164 
    154     if (tdata->client_tsx) { 
    155         pj_time_val delay = {2, 0}; 
    156         tsx_erase(tdata->sess, tdata); 
    157         pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay); 
    158         tdata->client_tsx = NULL; 
     165    if (force) { 
     166        if (tdata->client_tsx) { 
     167            tsx_erase(tdata->sess, tdata); 
     168            pj_stun_client_tsx_destroy(tdata->client_tsx); 
     169        } 
     170        pj_pool_release(tdata->pool); 
    159171 
    160172    } else { 
    161         pj_pool_release(tdata->pool); 
     173        if (tdata->client_tsx) { 
     174            pj_time_val delay = {2, 0}; 
     175            pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay); 
     176 
     177        } else { 
     178            pj_pool_release(tdata->pool); 
     179        } 
    162180    } 
    163181} 
     
    170188{ 
    171189    PJ_UNUSED_ARG(sess); 
    172     destroy_tdata(tdata); 
     190    destroy_tdata(tdata, PJ_FALSE); 
    173191} 
    174192 
     
    290308    { 
    291309        const pj_stun_nonce_attr *anonce; 
     310        const pj_stun_realm_attr *arealm; 
    292311        pj_stun_tx_data *tdata; 
    293312        unsigned i; 
     
    317336        pj_strdup(sess->pool, &sess->next_nonce, &anonce->value); 
    318337 
     338        /* Copy the realm from the response */ 
     339        arealm = (pj_stun_realm_attr*) 
     340                 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_REALM, 0); 
     341        if (arealm) { 
     342            pj_strdup(sess->pool, &sess->server_realm, &arealm->value); 
     343        } 
     344 
    319345        /* Create new request */ 
    320346        status = pj_stun_session_create_req(sess, request->msg->hdr.type, 
     
    325351 
    326352        /* Duplicate all the attributes in the old request, except 
    327          * USERNAME, REALM, M-I, and NONCE  
     353         * USERNAME, REALM, M-I, and NONCE, which will be filled in 
     354         * later. 
    328355         */ 
    329356        for (i=0; i<request->msg->attr_count; ++i) { 
     
    374401    sess = tdata->sess; 
    375402 
     403    /* Lock the session and prevent user from destroying us in the callback */ 
     404    pj_atomic_inc(sess->busy); 
     405    pj_lock_acquire(sess->lock); 
     406 
    376407    /* Handle authentication challenge */ 
    377408    handle_auth_challenge(sess, tdata, response, src_addr, 
     
    388419    pj_stun_msg_destroy_tdata(sess, tdata); 
    389420    tdata = NULL; 
     421 
     422    pj_lock_release(sess->lock); 
     423 
     424    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     425        pj_stun_session_destroy(sess); 
     426        return; 
     427    } 
    390428} 
    391429 
     
    395433{ 
    396434    pj_stun_tx_data *tdata; 
     435    pj_stun_session *sess; 
     436    pj_status_t status; 
    397437 
    398438    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
    399  
    400     return tdata->sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt,  
    401                                        pkt_size, tdata->dst_addr,  
    402                                        tdata->addr_len); 
     439    sess = tdata->sess; 
     440 
     441    /* Lock the session and prevent user from destroying us in the callback */ 
     442    pj_atomic_inc(sess->busy); 
     443    pj_lock_acquire(sess->lock); 
     444     
     445    status = sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt,  
     446                                  pkt_size, tdata->dst_addr,  
     447                                  tdata->addr_len); 
     448    pj_lock_release(sess->lock); 
     449 
     450    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     451        pj_stun_session_destroy(sess); 
     452        return PJNATH_ESTUNDESTROYED; 
     453    } else { 
     454        return status; 
     455    } 
    403456} 
    404457 
     
    429482    pj_memcpy(&sess->cb, cb, sizeof(*cb)); 
    430483    sess->use_fingerprint = fingerprint; 
     484    sess->log_flag = 0xFFFF; 
    431485     
    432486    sess->srv_name.ptr = (char*) pj_pool_alloc(pool, 32); 
     
    434488                                           "pj_stun-%s", pj_get_version()); 
    435489 
     490    sess->rx_pool = pj_pool_create(sess->cfg->pf, "name",  
     491                                   PJNATH_POOL_LEN_STUN_TDATA,  
     492                                   PJNATH_POOL_INC_STUN_TDATA, NULL); 
     493 
    436494    pj_list_init(&sess->pending_request_list); 
    437495    pj_list_init(&sess->cached_response_list); 
     
    444502    sess->delete_lock = PJ_TRUE; 
    445503 
     504    status = pj_atomic_create(pool, 0, &sess->busy); 
     505    if (status != PJ_SUCCESS) { 
     506        pj_lock_destroy(sess->lock); 
     507        pj_pool_release(pool); 
     508        return status; 
     509    } 
     510 
    446511    *p_sess = sess; 
    447512 
     
    454519 
    455520    pj_lock_acquire(sess->lock); 
     521 
     522    /* Can't destroy if we're in a callback */ 
     523    sess->destroy_request = PJ_TRUE; 
     524    if (pj_atomic_get(sess->busy)) { 
     525        pj_lock_release(sess->lock); 
     526        return PJ_EPENDING; 
     527    } 
     528 
    456529    while (!pj_list_empty(&sess->pending_request_list)) { 
    457530        pj_stun_tx_data *tdata = sess->pending_request_list.next; 
    458         destroy_tdata(tdata); 
    459     } 
     531        destroy_tdata(tdata, PJ_TRUE); 
     532    } 
     533 
    460534    while (!pj_list_empty(&sess->cached_response_list)) { 
    461535        pj_stun_tx_data *tdata = sess->cached_response_list.next; 
    462         destroy_tdata(tdata); 
     536        destroy_tdata(tdata, PJ_TRUE); 
    463537    } 
    464538    pj_lock_release(sess->lock); 
     
    466540    if (sess->delete_lock) { 
    467541        pj_lock_destroy(sess->lock); 
     542    } 
     543 
     544    if (sess->rx_pool) { 
     545        pj_pool_release(sess->rx_pool); 
     546        sess->rx_pool = NULL; 
    468547    } 
    469548 
     
    539618} 
    540619 
     620PJ_DEF(void) pj_stun_session_set_log( pj_stun_session *sess, 
     621                                      unsigned flags) 
     622{ 
     623    PJ_ASSERT_ON_FAIL(sess, return); 
     624    sess->log_flag = flags; 
     625} 
    541626 
    542627static pj_status_t get_auth(pj_stun_session *sess, 
     
    544629{ 
    545630    if (sess->cred.type == PJ_STUN_AUTH_CRED_STATIC) { 
    546         tdata->auth_info.realm = sess->cred.data.static_cred.realm; 
     631        //tdata->auth_info.realm = sess->cred.data.static_cred.realm; 
     632        tdata->auth_info.realm = sess->server_realm; 
    547633        tdata->auth_info.username = sess->cred.data.static_cred.username; 
    548634        tdata->auth_info.nonce = sess->cred.data.static_cred.nonce; 
     
    634720            } 
    635721            tdata->auth_info.nonce = sess->next_nonce; 
     722            tdata->auth_info.realm = sess->server_realm; 
    636723        } 
    637724 
     
    715802                        unsigned pkt_size, const pj_sockaddr_t *addr) 
    716803{ 
    717     char dst_name[80]; 
     804    char dst_name[PJ_INET6_ADDRSTRLEN+10]; 
    718805     
     806    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) &&  
     807         (sess->log_flag & PJ_STUN_SESS_LOG_TX_REQ)==0) || 
     808        (PJ_STUN_IS_RESPONSE(msg->hdr.type) && 
     809         (sess->log_flag & PJ_STUN_SESS_LOG_TX_RES)==0) || 
     810        (PJ_STUN_IS_INDICATION(msg->hdr.type) && 
     811         (sess->log_flag & PJ_STUN_SESS_LOG_TX_IND)==0)) 
     812    { 
     813        return; 
     814    } 
     815 
    719816    pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3); 
    720817 
     
    750847    tdata->retransmit = retransmit; 
    751848 
    752     /* Start locking the session now */ 
     849    /* Lock the session and prevent user from destroying us in the callback */ 
     850    pj_atomic_inc(sess->busy); 
    753851    pj_lock_acquire(sess->lock); 
    754852 
     
    758856    if (status != PJ_SUCCESS) { 
    759857        pj_stun_msg_destroy_tdata(sess, tdata); 
    760         pj_lock_release(sess->lock); 
    761858        LOG_ERR_(sess, "Error applying options", status); 
    762         return status; 
     859        goto on_return; 
    763860    } 
    764861 
     
    770867    if (status != PJ_SUCCESS) { 
    771868        pj_stun_msg_destroy_tdata(sess, tdata); 
    772         pj_lock_release(sess->lock); 
    773869        LOG_ERR_(sess, "STUN encode() error", status); 
    774         return status; 
     870        goto on_return; 
    775871    } 
    776872 
     
    798894        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    799895            pj_stun_msg_destroy_tdata(sess, tdata); 
    800             pj_lock_release(sess->lock); 
    801896            LOG_ERR_(sess, "Error sending STUN request", status); 
    802             return status; 
     897            goto on_return; 
    803898        } 
    804899 
     
    825920                                            &timeout); 
    826921            if (status != PJ_SUCCESS) { 
     922                tdata->res_timer.id = PJ_FALSE; 
    827923                pj_stun_msg_destroy_tdata(sess, tdata); 
    828                 pj_lock_release(sess->lock); 
    829924                LOG_ERR_(sess, "Error scheduling response timer", status); 
    830                 return status; 
     925                goto on_return; 
    831926            } 
    832927 
     
    839934 
    840935        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     936            pj_stun_msg_destroy_tdata(sess, tdata); 
    841937            LOG_ERR_(sess, "Error sending STUN request", status); 
     938            goto on_return; 
    842939        } 
    843940 
     
    848945    } 
    849946 
    850  
     947on_return: 
    851948    pj_lock_release(sess->lock); 
     949 
     950    /* Check if application has called destroy() in the callback */ 
     951    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     952        pj_stun_session_destroy(sess); 
     953        return PJNATH_ESTUNDESTROYED; 
     954    } 
     955 
    852956    return status; 
    853957} 
     
    893997    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 
    894998 
     999    /* Lock the session and prevent user from destroying us in the callback */ 
     1000    pj_atomic_inc(sess->busy); 
    8951001    pj_lock_acquire(sess->lock); 
    8961002 
     
    9041010 
    9051011    pj_lock_release(sess->lock); 
     1012 
     1013    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     1014        pj_stun_session_destroy(sess); 
     1015        return PJNATH_ESTUNDESTROYED; 
     1016    } 
     1017 
    9061018    return PJ_SUCCESS; 
    9071019} 
     
    9181030    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 
    9191031 
     1032    /* Lock the session and prevent user from destroying us in the callback */ 
     1033    pj_atomic_inc(sess->busy); 
    9201034    pj_lock_acquire(sess->lock); 
    9211035 
     
    9231037 
    9241038    pj_lock_release(sess->lock); 
     1039 
     1040    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     1041        pj_stun_session_destroy(sess); 
     1042        return PJNATH_ESTUNDESTROYED; 
     1043    } 
    9251044 
    9261045    return status; 
     
    11661285 
    11671286 
     1287/* Print outgoing message to log */ 
     1288static void dump_rx_msg(pj_stun_session *sess, const pj_stun_msg *msg, 
     1289                        unsigned pkt_size, const pj_sockaddr_t *addr) 
     1290{ 
     1291    char src_info[PJ_INET6_ADDRSTRLEN+10]; 
     1292     
     1293    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) &&  
     1294         (sess->log_flag & PJ_STUN_SESS_LOG_RX_REQ)==0) || 
     1295        (PJ_STUN_IS_RESPONSE(msg->hdr.type) && 
     1296         (sess->log_flag & PJ_STUN_SESS_LOG_RX_RES)==0) || 
     1297        (PJ_STUN_IS_INDICATION(msg->hdr.type) && 
     1298         (sess->log_flag & PJ_STUN_SESS_LOG_RX_IND)==0)) 
     1299    { 
     1300        return; 
     1301    } 
     1302 
     1303    pj_sockaddr_print(addr, src_info, sizeof(src_info), 3); 
     1304 
     1305    PJ_LOG(5,(SNAME(sess), 
     1306              "RX %d bytes STUN message from %s:\n" 
     1307              "--- begin STUN message ---\n" 
     1308              "%s" 
     1309              "--- end of STUN message ---\n", 
     1310              pkt_size, src_info, 
     1311              pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf),  
     1312                               NULL))); 
     1313 
     1314} 
     1315 
     1316/* Incoming packet */ 
    11681317PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, 
    11691318                                              const void *packet, 
     
    11761325{ 
    11771326    pj_stun_msg *msg, *response; 
    1178     pj_pool_t *tmp_pool; 
    1179     char *dump; 
    11801327    pj_status_t status; 
    11811328 
    11821329    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); 
    11831330 
    1184     tmp_pool = pj_pool_create(sess->cfg->pf, "tmpstun",  
    1185                               PJNATH_POOL_LEN_STUN_TDATA,  
    1186                               PJNATH_POOL_INC_STUN_TDATA, NULL); 
    1187     if (!tmp_pool) 
    1188         return PJ_ENOMEM; 
     1331    /* Lock the session and prevent user from destroying us in the callback */ 
     1332    pj_atomic_inc(sess->busy); 
     1333    pj_lock_acquire(sess->lock); 
     1334 
     1335    /* Reset pool */ 
     1336    pj_pool_reset(sess->rx_pool); 
    11891337 
    11901338    /* Try to parse the message */ 
    1191     status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 
     1339    status = pj_stun_msg_decode(sess->rx_pool, (const pj_uint8_t*)packet, 
    11921340                                pkt_size, options,  
    11931341                                &msg, parsed_len, &response); 
     
    11951343        LOG_ERR_(sess, "STUN msg_decode() error", status); 
    11961344        if (response) { 
    1197             send_response(sess, token, tmp_pool, response, NULL, 
     1345            send_response(sess, token, sess->rx_pool, response, NULL, 
    11981346                          PJ_FALSE, src_addr, src_addr_len); 
    11991347        } 
    1200         pj_pool_release(tmp_pool); 
    1201         return status; 
    1202     } 
    1203  
    1204     dump = (char*) pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN); 
    1205  
    1206     PJ_LOG(5,(SNAME(sess), 
    1207               "RX STUN message from %s:%d:\n" 
    1208               "--- begin STUN message ---\n" 
    1209               "%s" 
    1210               "--- end of STUN message ---\n", 
    1211               pj_inet_ntoa(((pj_sockaddr_in*)src_addr)->sin_addr), 
    1212               pj_ntohs(((pj_sockaddr_in*)src_addr)->sin_port), 
    1213               pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL))); 
    1214  
    1215     pj_lock_acquire(sess->lock); 
     1348        goto on_return; 
     1349    } 
     1350 
     1351    dump_rx_msg(sess, msg, pkt_size, src_addr); 
    12161352 
    12171353    /* For requests, check if we have cached response */ 
    1218     status = check_cached_response(sess, tmp_pool, msg,  
     1354    status = check_cached_response(sess, sess->rx_pool, msg,  
    12191355                                   src_addr, src_addr_len); 
    12201356    if (status == PJ_SUCCESS) { 
     
    12321368    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
    12331369 
    1234         status = on_incoming_request(sess, options, token, tmp_pool,  
     1370        status = on_incoming_request(sess, options, token, sess->rx_pool,  
    12351371                                     (const pj_uint8_t*) packet, pkt_size,  
    12361372                                     msg, src_addr, src_addr_len); 
     
    12381374    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 
    12391375 
    1240         status = on_incoming_indication(sess, token, tmp_pool,  
     1376        status = on_incoming_indication(sess, token, sess->rx_pool,  
    12411377                                        (const pj_uint8_t*) packet, pkt_size, 
    12421378                                        msg, src_addr, src_addr_len); 
     
    12501386    pj_lock_release(sess->lock); 
    12511387 
    1252     pj_pool_release(tmp_pool); 
     1388    /* If we've received destroy request while we're on the callback, 
     1389     * destroy the session now. 
     1390     */ 
     1391    if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 
     1392        pj_stun_session_destroy(sess); 
     1393        return PJNATH_ESTUNDESTROYED; 
     1394    } 
     1395 
    12531396    return status; 
    12541397} 
    12551398 
    1256  
    1257  
Note: See TracChangeset for help on using the changeset viewer.