Changeset 3348 for pjproject/trunk


Ignore:
Timestamp:
Oct 18, 2010 4:23:25 AM (14 years ago)
Author:
nanang
Message:

Re #1140, cleaned up the mutex usages in SRTP transport:

  • using mutex in accessing application callback pointers
  • releasing mutex before calling application callbacks to avoid deadlock
  • refine the synchronization of backend/libsrtp states
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c

    r3221 r3348  
    481481    int              au_rx_idx = 0; 
    482482    int              crypto_suites_cnt; 
     483    pj_status_t      status = PJ_SUCCESS; 
    483484 
    484485    PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL); 
     486 
     487    pj_lock_acquire(srtp->mutex); 
    485488 
    486489    if (srtp->session_inited) { 
     
    506509    if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||  
    507510        au_rx_idx == -1) 
    508         return PJMEDIA_SRTP_ENOTSUPCRYPTO; 
     511    { 
     512        status = PJMEDIA_SRTP_ENOTSUPCRYPTO; 
     513        goto on_return; 
     514    } 
    509515 
    510516    /* If all options points to 'NULL' method, just bypass SRTP */ 
    511517    if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) { 
    512518        srtp->bypass_srtp = PJ_TRUE; 
    513         return PJ_SUCCESS; 
     519        goto on_return; 
    514520    } 
    515521 
     
    517523    if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len || 
    518524        rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len) 
    519         return PJMEDIA_SRTP_EINKEYLEN; 
     525    { 
     526        status = PJMEDIA_SRTP_EINKEYLEN; 
     527        goto on_return; 
     528    } 
    520529 
    521530    /* Init transmit direction */ 
     
    543552    err = srtp_create(&srtp->srtp_tx_ctx, &tx_); 
    544553    if (err != err_status_ok) { 
    545         return PJMEDIA_ERRNO_FROM_LIBSRTP(err); 
     554        status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); 
     555        goto on_return; 
    546556    } 
    547557    srtp->tx_policy = *tx; 
     
    576586    if (err != err_status_ok) { 
    577587        srtp_dealloc(srtp->srtp_tx_ctx); 
    578         return PJMEDIA_ERRNO_FROM_LIBSRTP(err); 
     588        status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); 
     589        goto on_return; 
    579590    } 
    580591    srtp->rx_policy = *rx; 
     
    599610    } 
    600611 
    601     return PJ_SUCCESS; 
     612on_return: 
     613    pj_lock_release(srtp->mutex); 
     614    return status; 
    602615} 
    603616 
     
    612625    PJ_ASSERT_RETURN(srtp, PJ_EINVAL); 
    613626 
    614     if (!p_srtp->session_inited) 
     627    pj_lock_acquire(p_srtp->mutex); 
     628 
     629    if (!p_srtp->session_inited) { 
     630        pj_lock_release(p_srtp->mutex); 
    615631        return PJ_SUCCESS; 
     632    } 
    616633 
    617634    err = srtp_dealloc(p_srtp->srtp_rx_ctx); 
     
    629646 
    630647    p_srtp->session_inited = PJ_FALSE; 
     648 
     649    pj_lock_release(p_srtp->mutex); 
    631650 
    632651    return PJ_SUCCESS; 
     
    688707 
    689708    /* Save the callbacks */ 
     709    pj_lock_acquire(srtp->mutex); 
    690710    srtp->rtp_cb = rtp_cb; 
    691711    srtp->rtcp_cb = rtcp_cb; 
    692712    srtp->user_data = user_data; 
     713    pj_lock_release(srtp->mutex); 
    693714 
    694715    /* Attach itself to transport */ 
     
    697718                                      &srtp_rtcp_cb); 
    698719    if (status != PJ_SUCCESS) { 
     720        pj_lock_acquire(srtp->mutex); 
    699721        srtp->rtp_cb = NULL; 
    700722        srtp->rtcp_cb = NULL; 
    701723        srtp->user_data = NULL; 
     724        pj_lock_release(srtp->mutex); 
    702725        return status; 
    703726    } 
     
    718741 
    719742    /* Clear up application infos from transport */ 
     743    pj_lock_acquire(srtp->mutex); 
    720744    srtp->rtp_cb = NULL; 
    721745    srtp->rtcp_cb = NULL; 
    722746    srtp->user_data = NULL; 
     747    pj_lock_release(srtp->mutex); 
    723748} 
    724749 
     
    735760        return pjmedia_transport_send_rtp(srtp->member_tp, pkt, size); 
    736761 
    737     if (!srtp->session_inited) 
    738         return PJ_SUCCESS; 
    739  
    740762    if (size > sizeof(srtp->rtp_tx_buffer)) 
    741763        return PJ_ETOOBIG; 
     
    744766 
    745767    pj_lock_acquire(srtp->mutex); 
     768    if (!srtp->session_inited) { 
     769        pj_lock_release(srtp->mutex); 
     770        return PJ_EINVALIDOP; 
     771    } 
    746772    err = srtp_protect(srtp->srtp_tx_ctx, srtp->rtp_tx_buffer, &len); 
    747773    pj_lock_release(srtp->mutex); 
     
    779805    } 
    780806 
    781     if (!srtp->session_inited) 
    782         return PJ_SUCCESS; 
    783  
    784807    if (size > sizeof(srtp->rtcp_tx_buffer)) 
    785808        return PJ_ETOOBIG; 
     
    788811 
    789812    pj_lock_acquire(srtp->mutex); 
     813    if (!srtp->session_inited) { 
     814        pj_lock_release(srtp->mutex); 
     815        return PJ_EINVALIDOP; 
     816    } 
    790817    err = srtp_protect_rtcp(srtp->srtp_tx_ctx, srtp->rtcp_tx_buffer, &len); 
    791818    pj_lock_release(srtp->mutex); 
     
    820847    PJ_ASSERT_RETURN(tp, PJ_EINVAL); 
    821848 
    822     pj_lock_acquire(srtp->mutex); 
    823  
    824849    if (srtp->setting.close_member_tp && srtp->member_tp) { 
    825850        pjmedia_transport_close(srtp->member_tp); 
     
    828853    status = pjmedia_transport_srtp_stop(tp); 
    829854 
     855    /* In case mutex is being acquired by other thread */ 
     856    pj_lock_acquire(srtp->mutex); 
    830857    pj_lock_release(srtp->mutex); 
    831858 
     
    844871    int len = size; 
    845872    err_status_t err; 
     873    void (*cb)(void*, void*, pj_ssize_t) = NULL; 
     874    void *cb_data = NULL; 
    846875 
    847876    if (srtp->bypass_srtp) { 
     
    850879    } 
    851880 
    852     if (size < 0 || !srtp->session_inited) { 
     881    if (size < 0) { 
    853882        return; 
    854883    } 
     
    862891    pj_lock_acquire(srtp->mutex); 
    863892 
     893    if (!srtp->session_inited) { 
     894        pj_lock_release(srtp->mutex); 
     895        return; 
     896    } 
    864897    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 
    865  
    866898    if (srtp->probation_cnt > 0 &&  
    867899        (err == err_status_replay_old || err == err_status_replay_fail))  
     
    885917    } 
    886918 
    887     if (err == err_status_ok) { 
    888         srtp->rtp_cb(srtp->user_data, pkt, len); 
    889     } else { 
     919    if (err != err_status_ok) { 
    890920        PJ_LOG(5,(srtp->pool->obj_name,  
    891921                  "Failed to unprotect SRTP, pkt size=%d, err=%s",  
    892922                  size, get_libsrtp_errstr(err))); 
     923    } else { 
     924        cb = srtp->rtp_cb; 
     925        cb_data = srtp->user_data; 
    893926    } 
    894927 
    895928    pj_lock_release(srtp->mutex); 
     929 
     930    if (cb) { 
     931        (*cb)(cb_data, pkt, len); 
     932    } 
    896933} 
    897934 
     
    904941    int len = size; 
    905942    err_status_t err; 
     943    void (*cb)(void*, void*, pj_ssize_t) = NULL; 
     944    void *cb_data = NULL; 
    906945 
    907946    if (srtp->bypass_srtp) { 
     
    910949    } 
    911950 
    912     if (size < 0 || !srtp->session_inited) { 
     951    if (size < 0) { 
    913952        return; 
    914953    } 
     
    919958    pj_lock_acquire(srtp->mutex); 
    920959 
     960    if (!srtp->session_inited) { 
     961        pj_lock_release(srtp->mutex); 
     962        return; 
     963    } 
    921964    err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 
    922  
    923     if (err == err_status_ok) { 
    924         srtp->rtcp_cb(srtp->user_data, pkt, len); 
    925     } else { 
     965    if (err != err_status_ok) { 
    926966        PJ_LOG(5,(srtp->pool->obj_name,  
    927967                  "Failed to unprotect SRTCP, pkt size=%d, err=%s", 
    928968                  size, get_libsrtp_errstr(err))); 
    929     } 
    930      
     969    } else { 
     970        cb = srtp->rtcp_cb; 
     971        cb_data = srtp->user_data; 
     972    } 
     973 
    931974    pj_lock_release(srtp->mutex); 
     975 
     976    if (cb) { 
     977        (*cb)(cb_data, pkt, len); 
     978    } 
    932979} 
    933980 
     
    15721619    pj_lock_acquire(srtp->mutex); 
    15731620 
     1621    if (!srtp->session_inited) { 
     1622        pj_lock_release(srtp->mutex); 
     1623        return PJ_EINVALIDOP; 
     1624    } 
     1625 
    15741626    if (is_rtp) 
    15751627        err = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len); 
Note: See TracChangeset for help on using the changeset viewer.