Changeset 4219


Ignore:
Timestamp:
Aug 7, 2012 2:53:03 AM (12 years ago)
Author:
nanang
Message:

Fixed #1563: Crash when resolving STUN when there is no network connectivity.

Location:
pjproject/trunk/pjsip
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r4218 r4219  
    337337 
    338338    pj_pool_t           *pool;      /**< Pool               */ 
     339    int                  ref_cnt;   /**< Reference count    */ 
     340    pj_bool_t            destroy_flag; /**< To be destroyed */ 
     341    pj_bool_t            has_result; 
    339342    unsigned             count;     /**< # of entries       */ 
    340343    pj_str_t            *srv;       /**< Array of entries   */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r4218 r4219  
    10891089} 
    10901090 
    1091 /* Internal function to destroy STUN resolution session 
    1092  * (pj_stun_resolve). 
    1093  */ 
     1091static void stun_resolve_add_ref(pjsua_stun_resolve *sess) 
     1092{ 
     1093    ++sess->ref_cnt; 
     1094} 
     1095 
    10941096static void destroy_stun_resolve(pjsua_stun_resolve *sess) 
    10951097{ 
     1098    sess->destroy_flag = PJ_TRUE; 
     1099    if (sess->ref_cnt > 0) 
     1100        return; 
     1101 
    10961102    PJSUA_LOCK(); 
    10971103    pj_list_erase(sess); 
     
    11021108} 
    11031109 
     1110static void stun_resolve_dec_ref(pjsua_stun_resolve *sess) 
     1111{ 
     1112    --sess->ref_cnt; 
     1113    if (sess->ref_cnt <= 0 && sess->destroy_flag) 
     1114        destroy_stun_resolve(sess); 
     1115} 
     1116 
     1117 
    11041118/* This is the internal function to be called when STUN resolution 
    11051119 * session (pj_stun_resolve) has completed. 
     
    11081122{ 
    11091123    pj_stun_resolve_result result; 
     1124 
     1125    if (sess->has_result) 
     1126        goto on_return; 
    11101127 
    11111128    pj_bzero(&result, sizeof(result)); 
     
    11141131    result.name = sess->srv[sess->idx]; 
    11151132    pj_memcpy(&result.addr, &sess->addr, sizeof(result.addr)); 
     1133    sess->has_result = PJ_TRUE; 
    11161134 
    11171135    if (result.status == PJ_SUCCESS) { 
     
    11291147    } 
    11301148 
     1149    stun_resolve_add_ref(sess); 
    11311150    sess->cb(&result); 
    1132  
     1151    stun_resolve_dec_ref(sess); 
     1152 
     1153on_return: 
    11331154    if (!sess->blocking) { 
    11341155        destroy_stun_resolve(sess); 
     
    11921213static void resolve_stun_entry(pjsua_stun_resolve *sess) 
    11931214{ 
     1215    stun_resolve_add_ref(sess); 
     1216 
    11941217    /* Loop while we have entry to try */ 
    11951218    for (; sess->idx < sess->count; ++sess->idx) { 
    11961219        const int af = pj_AF_INET(); 
     1220        char target[64]; 
    11971221        pj_str_t hostpart; 
    11981222        pj_uint16_t port; 
     
    12011225        pj_assert(sess->idx < sess->count); 
    12021226 
     1227        pj_ansi_snprintf(target, sizeof(target), "%.*s", 
     1228                         (int)sess->srv[sess->idx].slen, 
     1229                         sess->srv[sess->idx].ptr); 
     1230 
    12031231        /* Parse the server entry into host:port */ 
    12041232        sess->status = pj_sockaddr_parse2(af, 0, &sess->srv[sess->idx], 
    12051233                                          &hostpart, &port, NULL); 
    12061234        if (sess->status != PJ_SUCCESS) { 
    1207             PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %.*s",  
    1208                       (int)sess->srv[sess->idx].slen,  
    1209                       sess->srv[sess->idx].ptr)); 
     1235            PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %s", target)); 
    12101236            continue; 
    12111237        } 
     
    12171243        pj_assert(sess->stun_sock == NULL); 
    12181244 
    1219         PJ_LOG(4,(THIS_FILE, "Trying STUN server %.*s (%d of %d)..", 
    1220                   (int)sess->srv[sess->idx].slen, 
    1221                   sess->srv[sess->idx].ptr, 
    1222                   sess->idx+1, sess->count)); 
     1245        PJ_LOG(4,(THIS_FILE, "Trying STUN server %s (%d of %d)..", 
     1246                  target, sess->idx+1, sess->count)); 
    12231247 
    12241248        /* Use STUN_sock to test this entry */ 
     
    12321256            pj_strerror(sess->status, errmsg, sizeof(errmsg)); 
    12331257            PJ_LOG(4,(THIS_FILE,  
    1234                      "Error creating STUN socket for %.*s: %s", 
    1235                       (int)sess->srv[sess->idx].slen, 
    1236                       sess->srv[sess->idx].ptr, errmsg)); 
     1258                     "Error creating STUN socket for %s: %s", 
     1259                     target, errmsg)); 
    12371260 
    12381261            continue; 
     
    12451268            pj_strerror(sess->status, errmsg, sizeof(errmsg)); 
    12461269            PJ_LOG(4,(THIS_FILE,  
    1247                      "Error starting STUN socket for %.*s: %s", 
    1248                       (int)sess->srv[sess->idx].slen, 
    1249                       sess->srv[sess->idx].ptr, errmsg)); 
    1250  
    1251             pj_stun_sock_destroy(sess->stun_sock); 
    1252             sess->stun_sock = NULL; 
     1270                     "Error starting STUN socket for %s: %s", 
     1271                     target, errmsg)); 
     1272 
     1273            if (sess->stun_sock) { 
     1274                pj_stun_sock_destroy(sess->stun_sock); 
     1275                sess->stun_sock = NULL; 
     1276            } 
    12531277            continue; 
    12541278        } 
     
    12571281         * stun_sock_cb() 
    12581282         */ 
    1259         return; 
     1283        goto on_return; 
    12601284    } 
    12611285 
     
    12661290        stun_resolve_complete(sess); 
    12671291    } 
     1292 
     1293on_return: 
     1294    stun_resolve_dec_ref(sess); 
    12681295} 
    12691296 
Note: See TracChangeset for help on using the changeset viewer.