Changeset 2136


Ignore:
Timestamp:
Jul 14, 2008 2:14:00 PM (11 years ago)
Author:
bennylp
Message:

Ticket #567: Rare race condition causing crash in ICE stream transport when STUN Binding resolution callback is called before initialization completes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r2090 r2136  
    2323#include <pj/assert.h> 
    2424#include <pj/ip_helper.h> 
     25#include <pj/lock.h> 
    2526#include <pj/log.h> 
    2627#include <pj/os.h> 
     
    156157    pj_ice_strans_cfg        cfg;       /**< Configuration.             */ 
    157158    pj_ice_strans_cb         cb;        /**< Application callback.      */ 
     159    pj_lock_t               *init_lock; /**< Initialization mutex.      */ 
    158160 
    159161    pj_ice_sess             *ice;       /**< ICE session.               */ 
     
    269271            ///sess_add_ref(ice_st); 
    270272 
     273            PJ_LOG(4,(ice_st->obj_name,  
     274                      "Comp %d: srflx candidate starts Binding discovery", 
     275                      comp_id)); 
     276 
    271277            /* Start Binding resolution */ 
    272278            status = pj_stun_sock_start(comp->stun_sock,  
     
    286292            } 
    287293 
    288             /* Add srflx candidate with pending status */ 
     294            /* Add srflx candidate with pending status. */ 
    289295            cand = &comp->cand_list[comp->cand_cnt++]; 
    290296            cand->type = PJ_ICE_CAND_TYPE_SRFLX; 
     
    297303            pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 
    298304                                   cand->type, &cand->base_addr); 
    299             PJ_LOG(4,(ice_st->obj_name,  
    300                       "Comp %d: srflx candidate starts Binding discovery", 
    301                       comp_id)); 
    302305 
    303306            /* Set default candidate to srflx */ 
    304307            comp->default_cand = cand - comp->cand_list; 
     308 
    305309        } 
    306310 
     
    453457    } 
    454458 
     459    status = pj_lock_create_recursive_mutex(pool, ice_st->obj_name,  
     460                                            &ice_st->init_lock); 
     461    if (status != PJ_SUCCESS) { 
     462        destroy_ice_st(ice_st); 
     463        return status; 
     464    } 
     465 
    455466    ice_st->comp_cnt = comp_cnt; 
    456467    ice_st->comp = (pj_ice_strans_comp**)  
    457468                   pj_pool_calloc(pool, comp_cnt, sizeof(pj_ice_strans_comp*)); 
    458469 
     470    /* Acquire initialization mutex to prevent callback to be  
     471     * called before we finish initialization. 
     472     */ 
     473    pj_lock_acquire(ice_st->init_lock); 
     474 
    459475    for (i=0; i<comp_cnt; ++i) { 
    460476        status = create_comp(ice_st, i+1); 
    461477        if (status != PJ_SUCCESS) { 
     478            pj_lock_release(ice_st->init_lock); 
    462479            destroy_ice_st(ice_st); 
    463480            return status; 
    464481        } 
    465482    } 
     483 
     484    /* Done with initialization */ 
     485    pj_lock_release(ice_st->init_lock); 
    466486 
    467487    /* Check if all candidates are ready (this may call callback) */ 
     
    501521    } 
    502522    ice_st->comp_cnt = 0; 
     523 
     524    /* Destroy mutex */ 
     525    if (ice_st->init_lock) { 
     526        pj_lock_acquire(ice_st->init_lock); 
     527        pj_lock_release(ice_st->init_lock); 
     528        pj_lock_destroy(ice_st->init_lock); 
     529        ice_st->init_lock = NULL; 
     530    } 
    503531 
    504532    /* Destroy reference counter */ 
     
    11991227    unsigned i; 
    12001228 
     1229    pj_assert(status != PJ_EPENDING); 
     1230 
    12011231    comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 
    12021232    ice_st = comp->ice_st; 
    12031233 
    12041234    sess_add_ref(ice_st); 
     1235 
     1236    /* Wait until initialization completes */ 
     1237    pj_lock_acquire(ice_st->init_lock); 
    12051238 
    12061239    /* Find the srflx cancidate */ 
     
    12121245    } 
    12131246 
    1214     pj_assert(status != PJ_EPENDING); 
     1247    pj_lock_release(ice_st->init_lock); 
     1248 
     1249    /* It is possible that we don't have srflx candidate even though this 
     1250     * callback is called. This could happen when we cancel adding srflx 
     1251     * candidate due to initialization error. 
     1252     */ 
     1253    if (cand == NULL) { 
     1254        return sess_dec_ref(ice_st); 
     1255    } 
    12151256 
    12161257    switch (op) { 
     
    13641405        pj_turn_sock_get_info(turn_sock, &rel_info); 
    13651406 
     1407        /* Wait until initialization completes */ 
     1408        pj_lock_acquire(comp->ice_st->init_lock); 
     1409 
    13661410        /* Find relayed candidate in the component */ 
    13671411        for (i=0; i<comp->cand_cnt; ++i) { 
     
    13721416        } 
    13731417        pj_assert(cand != NULL); 
     1418 
     1419        pj_lock_release(comp->ice_st->init_lock); 
    13741420 
    13751421        /* Update candidate */ 
Note: See TracChangeset for help on using the changeset viewer.