Changeset 5851


Ignore:
Timestamp:
Aug 1, 2018 9:22:26 AM (6 years ago)
Author:
riza
Message:

Fixed #2137: Race condition in 183 re-transmission can result in a deadlock.

Location:
pjproject/trunk/pjsip
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip/sip_transport.h

    r5556 r5851  
    722722                                                 const pjsip_tpselector *sel); 
    723723 
     724/** 
     725 * Clone pjsip_tx_data. This will duplicate the message contents of 
     726 * pjsip_tx_data (pjsip_tx_data.msg) and add reference count to the tdata. 
     727 * Once application has finished using the cloned pjsip_tx_data, 
     728 * it must release it by calling  #pjsip_tx_data_dec_ref(). 
     729 * Currently, this will only clone response message. 
     730 * 
     731 * @param src       The source to be cloned. 
     732 * @param flags     Optional flags. Must be zero for now. 
     733 * @param p_rdata   Pointer to receive the cloned tdata. 
     734 * 
     735 * @return          PJ_SUCCESS on success or the appropriate error. 
     736 */ 
     737PJ_DECL(pj_status_t) pjsip_tx_data_clone(const pjsip_tx_data *src, 
     738                                         unsigned flags, 
     739                                         pjsip_tx_data **p_rdata); 
    724740 
    725741/***************************************************************************** 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_100rel.c

    r5250 r5851  
    635635 
    636636 
    637 /* Clone response. */ 
    638 static pjsip_tx_data *clone_tdata(dlg_data *dd, 
    639                                   const pjsip_tx_data *src) 
    640 { 
    641     pjsip_tx_data *dst; 
    642     const pjsip_hdr *hsrc; 
    643     pjsip_msg *msg; 
    644     pj_status_t status; 
    645  
    646     status = pjsip_endpt_create_tdata(dd->inv->dlg->endpt, &dst); 
    647     if (status != PJ_SUCCESS) 
    648         return NULL; 
    649  
    650     msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG); 
    651     dst->msg = msg; 
    652     pjsip_tx_data_add_ref(dst); 
    653  
    654     /* Duplicate status line */ 
    655     msg->line.status.code = src->msg->line.status.code; 
    656     pj_strdup(dst->pool, &msg->line.status.reason,  
    657               &src->msg->line.status.reason); 
    658  
    659     /* Duplicate all headers */ 
    660     hsrc = src->msg->hdr.next; 
    661     while (hsrc != &src->msg->hdr) { 
    662         pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc); 
    663         pjsip_msg_add_hdr(msg, h); 
    664         hsrc = hsrc->next; 
    665     } 
    666  
    667     /* Duplicate message body */ 
    668     if (src->msg->body) 
    669         msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body); 
    670  
    671     PJ_LOG(5,(dd->inv->dlg->obj_name, 
    672              "Reliable response %s created", 
    673              pjsip_tx_data_get_info(dst))); 
    674  
    675     return dst; 
    676 } 
    677  
    678637 
    679638/* Check if any pending response in transmission list has SDP */ 
     
    726685     */ 
    727686    old_tdata = tdata; 
    728     tdata = clone_tdata(dd, old_tdata); 
     687    pjsip_tx_data_clone(old_tdata, 0, &tdata); 
    729688    pjsip_tx_data_dec_ref(old_tdata); 
    730689     
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r5812 r5851  
    23832383{ 
    23842384    pjsip_tx_data *last_res; 
     2385    pjsip_tx_data *old_res; 
    23852386    pj_status_t status; 
    23862387 
     
    23982399    pjsip_dlg_inc_lock(inv->dlg); 
    23992400 
     2401    /* Clone last response. 
     2402     * The tdata (last_answer) is a shared object used by the transaction. 
     2403     * Modifying a shared object might lead to a deadlock. 
     2404     * Refer to ticket #2137 for more detail. 
     2405     */ 
     2406    status = pjsip_tx_data_clone(inv->last_answer, 0, &last_res); 
     2407    if (status != PJ_SUCCESS) 
     2408        goto on_return; 
     2409    old_res = inv->last_answer; 
     2410    inv->last_answer = last_res; 
     2411    pjsip_tx_data_dec_ref(old_res); 
     2412 
    24002413    /* Modify last response. */ 
    2401     last_res = inv->last_answer; 
    24022414    status = pjsip_dlg_modify_response(inv->dlg, last_res, st_code, st_text); 
    24032415    if (status != PJ_SUCCESS) 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r5701 r5851  
    644644} 
    645645 
     646/* Clone pjsip_tx_data. */ 
     647PJ_DEF(pj_status_t) pjsip_tx_data_clone(const pjsip_tx_data *src, 
     648                                        unsigned flags, 
     649                                        pjsip_tx_data ** p_tdata) 
     650{ 
     651    pjsip_tx_data *dst; 
     652    const pjsip_hdr *hsrc; 
     653    pjsip_msg *msg; 
     654    pj_status_t status; 
     655 
     656    PJ_UNUSED_ARG(flags); 
     657 
     658    status = pjsip_tx_data_create(src->mgr, p_tdata); 
     659    if (status != PJ_SUCCESS) 
     660        return status; 
     661 
     662    dst = *p_tdata; 
     663 
     664    msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG); 
     665    dst->msg = msg; 
     666    pjsip_tx_data_add_ref(dst); 
     667 
     668    /* Duplicate status line */ 
     669    msg->line.status.code = src->msg->line.status.code; 
     670    pj_strdup(dst->pool, &msg->line.status.reason, 
     671              &src->msg->line.status.reason); 
     672 
     673    /* Duplicate all headers */ 
     674    hsrc = src->msg->hdr.next; 
     675    while (hsrc != &src->msg->hdr) { 
     676        pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc); 
     677        pjsip_msg_add_hdr(msg, h); 
     678        hsrc = hsrc->next; 
     679    } 
     680 
     681    /* Duplicate message body */ 
     682    if (src->msg->body) 
     683        msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body); 
     684 
     685    dst->is_pending = src->is_pending; 
     686 
     687    PJ_LOG(5,(THIS_FILE, 
     688             "Tx data %s cloned", 
     689             pjsip_tx_data_get_info(dst))); 
     690 
     691    return PJ_SUCCESS; 
     692} 
    646693 
    647694PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata) 
Note: See TracChangeset for help on using the changeset viewer.