Ignore:
Timestamp:
Feb 5, 2016 4:29:17 AM (7 years ago)
Author:
nanang
Message:

Fixed #1902:

  • Crash when endpoint has multiple worker threads and SIP TCP transport is disconnected during incoming call handling.
  • Deprecated pjsip_dlg_create_uas(), replaced by pjsip_dlg_create_uas_and_inc_lock().
  • Serialized transaction state notifications (of 'terminated' and 'destroyed') in case of transport error.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transaction.c

    r5147 r5241  
    139139#define TRANSPORT_ERR_TIMER     3 
    140140 
     141/* Flags for tsx_set_state() */ 
     142enum 
     143{ 
     144    NO_NOTIFY = 1, 
     145    NO_SCHEDULE_HANDLER = 2, 
     146}; 
    141147 
    142148/* Prototypes. */ 
     
    170176                                  pjsip_tsx_state_e state, 
    171177                                  pjsip_event_id_e event_src_type, 
    172                                   void *event_src ); 
    173 static void        tsx_set_state_no_notify( pjsip_transaction *tsx, 
    174                                             pjsip_tsx_state_e state, 
    175                                             pjsip_event_id_e event_src_type, 
    176                                             void *event_src ); 
     178                                  void *event_src, 
     179                                  int flag); 
    177180static void        tsx_set_status_code(pjsip_transaction *tsx, 
    178181                                       int code, const pj_str_t *reason); 
     
    11041107        if (tsx->state < PJSIP_TSX_STATE_TERMINATED) { 
    11051108            pjsip_tsx_state_e prev_state; 
     1109            pj_time_val timeout = { 0, 0 }; 
    11061110 
    11071111            pj_grp_lock_acquire(tsx->grp_lock); 
     
    11231127             * https://trac.pjsip.org/repos/ticket/1646 
    11241128             */ 
    1125             tsx_set_state_no_notify( tsx, PJSIP_TSX_STATE_TERMINATED, 
    1126                                      PJSIP_EVENT_TRANSPORT_ERROR, NULL); 
     1129            /* Also don't schedule tsx handler, otherwise we'll get race 
     1130             * condition of TU notifications due to delayed TERMINATED 
     1131             * state TU notification. It happened in multiple worker threads 
     1132             * environment between TERMINATED & DESTROYED! See: 
     1133             * https://trac.pjsip.org/repos/ticket/1902 
     1134             */ 
     1135            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
     1136                           PJSIP_EVENT_TRANSPORT_ERROR, NULL, 
     1137                           NO_NOTIFY | NO_SCHEDULE_HANDLER); 
    11271138            pj_grp_lock_release(tsx->grp_lock); 
    11281139 
     
    11391150                (*tsx->tsx_user->on_tsx_state)(tsx, &e); 
    11401151            } 
     1152 
     1153            /* Now let's schedule the tsx handler */ 
     1154            tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, 
     1155                               TIMEOUT_TIMER); 
    11411156        } 
    11421157    } else { 
     
    11681183                           pjsip_tsx_state_e state, 
    11691184                           pjsip_event_id_e event_src_type, 
    1170                            void *event_src ) 
     1185                           void *event_src, 
     1186                           int flag) 
    11711187{ 
    11721188    pjsip_tsx_state_e prev_state = tsx->state; 
     
    11931209     * rx event. 
    11941210     */ 
    1195     if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user) { 
     1211    if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user && 
     1212        (flag & NO_NOTIFY)==0) 
     1213    { 
    11961214        pjsip_rx_data *rdata = (pjsip_rx_data*) event_src; 
    11971215 
     
    12071225 
    12081226    /* Inform TU about state changed. */ 
    1209     if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) { 
     1227    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state && 
     1228        (flag & NO_NOTIFY) == 0) 
     1229    { 
    12101230        pjsip_event e; 
    12111231        PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src, 
     
    12191239     */ 
    12201240    if (state == PJSIP_TSX_STATE_TERMINATED) { 
    1221         pj_time_val timeout = {0, 0}; 
     1241        pj_time_val timeout = { 0, 0 }; 
    12221242 
    12231243        /* If we're still waiting for a message to be sent.. */ 
     
    12371257        lock_timer(tsx); 
    12381258        tsx_cancel_timer(tsx, &tsx->timeout_timer); 
    1239         tsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER); 
     1259        if ((flag & NO_SCHEDULE_HANDLER) == 0) { 
     1260            tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, 
     1261                               TIMEOUT_TIMER); 
     1262        } 
    12401263        unlock_timer(tsx); 
    12411264 
     
    12501273 
    12511274    pj_log_pop_indent(); 
    1252 } 
    1253  
    1254 /* Set transaction state without notifying tsx_user */ 
    1255 static void tsx_set_state_no_notify( pjsip_transaction *tsx, 
    1256                                      pjsip_tsx_state_e state, 
    1257                                      pjsip_event_id_e event_src_type, 
    1258                                      void *event_src ) 
    1259 { 
    1260     pjsip_module *tsx_user = tsx->tsx_user; 
    1261     tsx->tsx_user = NULL; 
    1262     tsx_set_state(tsx, state, event_src_type, event_src); 
    1263     tsx->tsx_user = tsx_user; 
    12641275} 
    12651276 
     
    16271638    if (tsx->state < PJSIP_TSX_STATE_TERMINATED) { 
    16281639        tsx_set_status_code(tsx, code, NULL); 
    1629         tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL); 
     1640        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, 
     1641                       NULL, 0); 
    16301642    } 
    16311643    pj_grp_lock_release(tsx->grp_lock); 
     
    18381850        if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { 
    18391851            tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,  
    1840                            PJSIP_EVENT_UNKNOWN, NULL ); 
     1852                           PJSIP_EVENT_UNKNOWN, NULL, 0 ); 
    18411853            pj_grp_lock_release(tsx->grp_lock); 
    18421854            return; 
     
    19131925            { 
    19141926                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    1915                                PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata); 
     1927                               PJSIP_EVENT_TRANSPORT_ERROR, 
     1928                               send_state->tdata, 0); 
    19161929            }  
    19171930            /* Don't forget to destroy if we have pending destroy flag 
     
    19211934            { 
    19221935                tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,  
    1923                                PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata); 
     1936                               PJSIP_EVENT_TRANSPORT_ERROR, 
     1937                               send_state->tdata, 0); 
    19241938            } 
    19251939 
     
    21232137        tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err); 
    21242138        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    2125                        PJSIP_EVENT_TRANSPORT_ERROR, NULL ); 
     2139                       PJSIP_EVENT_TRANSPORT_ERROR, NULL, 0 ); 
    21262140 
    21272141        return status; 
     
    23552369                    PJSIP_REQUEST_MSG); 
    23562370        tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, PJSIP_EVENT_RX_MSG, 
    2357                        event->body.rx_msg.rdata); 
     2371                       event->body.rx_msg.rdata, 0); 
    23582372 
    23592373    } else { 
     
    24102424        /* Move state. */ 
    24112425        tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING,  
    2412                        PJSIP_EVENT_TX_MSG, tdata); 
     2426                       PJSIP_EVENT_TX_MSG, tdata, 0); 
    24132427    } 
    24142428 
     
    24512465        /* Inform TU. */ 
    24522466        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
    2453                        PJSIP_EVENT_TIMER, &tsx->timeout_timer); 
     2467                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 
    24542468 
    24552469        /* Transaction is destroyed */ 
     
    25702584 
    25712585        tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,  
    2572                        PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata); 
     2586                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata, 0); 
    25732587 
    25742588    } 
     
    26512665 
    26522666            tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,  
    2653                            PJSIP_EVENT_TX_MSG, tdata ); 
     2667                           PJSIP_EVENT_TX_MSG, tdata, 0 ); 
    26542668 
    26552669            /* Retransmit provisional response every 1 minute if this is 
     
    26852699                 */ 
    26862700                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    2687                                PJSIP_EVENT_TX_MSG, tdata ); 
     2701                               PJSIP_EVENT_TX_MSG, tdata, 0 ); 
    26882702 
    26892703                /* Transaction is destroyed. */ 
     
    27432757                /* Set state to "Completed" */ 
    27442758                tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,  
    2745                                PJSIP_EVENT_TX_MSG, tdata ); 
     2759                               PJSIP_EVENT_TX_MSG, tdata, 0 ); 
    27462760            } 
    27472761 
     
    28022816            /* Inform TU */ 
    28032817            tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,  
    2804                            PJSIP_EVENT_TX_MSG, tdata ); 
     2818                           PJSIP_EVENT_TX_MSG, tdata, 0 ); 
    28052819 
    28062820        } else { 
     
    28362850 
    28372851        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
    2838                        PJSIP_EVENT_TIMER, &tsx->timeout_timer); 
     2852                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 
    28392853 
    28402854        return PJ_EBUG; 
     
    29012915        /* Inform the message to TU. */ 
    29022916        tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,  
    2903                        PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
     2917                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 
    29042918 
    29052919    } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) { 
     
    29152929        if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    29162930            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    2917                            PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
     2931                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 
    29182932            //return PJSIP_ETSXDESTROYED; 
    29192933 
     
    29422956            /* Move state to Completed, inform TU. */ 
    29432957            tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,  
    2944                            PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
     2958                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 
    29452959        } 
    29462960 
     
    29502964        /* Inform TU. */ 
    29512965        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
    2952                        PJSIP_EVENT_TIMER, &tsx->timeout_timer); 
     2966                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 
    29532967 
    29542968 
     
    30413055        /* Inform TU. */ 
    30423056        tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,  
    3043                        PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata); 
     3057                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0); 
    30443058 
    30453059        /* Generate and send ACK for INVITE. */ 
     
    31523166            /* Move state to "Confirmed" */ 
    31533167            tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED,  
    3154                            PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
     3168                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 
    31553169        }        
    31563170 
     
    31763190 
    31773191                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    3178                                PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 
     3192                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 
    31793193 
    31803194                //return PJSIP_ETSXDESTROYED; 
     
    31833197                /* Transaction terminated, it can now be deleted. */ 
    31843198                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    3185                                PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 
     3199                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 
    31863200                //return PJSIP_ETSXDESTROYED; 
    31873201            } 
     
    32163230        /* Move to Terminated state. */ 
    32173231        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
    3218                        PJSIP_EVENT_TIMER, event->body.timer.entry ); 
     3232                       PJSIP_EVENT_TIMER, event->body.timer.entry, 0 ); 
    32193233 
    32203234        /* Transaction has been destroyed. */ 
     
    32913305            /* Move to Terminated state. */ 
    32923306            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
    3293                            PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 
     3307                           PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 
    32943308 
    32953309            /* Transaction has been destroyed. */ 
     
    33223336    /* Destroy this transaction */ 
    33233337    tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED,  
    3324                   event->type, event->body.user.user1 ); 
     3338                  event->type, event->body.user.user1, 0 ); 
    33253339 
    33263340    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.