Changeset 5246


Ignore:
Timestamp:
Feb 25, 2016 4:38:34 AM (5 years ago)
Author:
nanang
Message:

Fix #1311: Updated pjsip_tpmgr_acquire_transport2() to look up from transport hash table (instead of always create a new one) when transport selector is set to TCP/TLS listener (thanks George Joseph for the patch).

Location:
pjproject/trunk/pjsip
Files:
2 edited

Legend:

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

    r5097 r5246  
    800800    pjsip_endpoint         *endpt;          /**< Endpoint instance.         */ 
    801801    pjsip_tpmgr            *tpmgr;          /**< Transport manager.         */ 
     802    pjsip_tpfactory        *factory;        /**< Factory instance. Note: it 
     803                                                 may be invalid/shutdown.   */ 
    802804    pj_timer_entry          idle_timer;     /**< Timer when ref cnt is zero.*/ 
    803805 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r5173 r5246  
    12961296} 
    12971297 
     1298static pj_bool_t pjsip_tpmgr_is_tpfactory_valid(pjsip_tpmgr *mgr, 
     1299                                                pjsip_tpfactory *tpf) 
     1300{ 
     1301    pjsip_tpfactory *p; 
     1302 
     1303    pj_lock_acquire(mgr->lock); 
     1304    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) { 
     1305        if (p == tpf) { 
     1306            pj_lock_release(mgr->lock); 
     1307            return PJ_TRUE; 
     1308        } 
     1309    } 
     1310    pj_lock_release(mgr->lock); 
     1311 
     1312    return PJ_FALSE; 
     1313} 
     1314 
    12981315/***************************************************************************** 
    12991316 * 
     
    20012018        return PJ_SUCCESS; 
    20022019 
    2003  
    2004     } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 
    2005                sel->u.listener) 
    2006     { 
    2007         /* Application has requested that a specific listener is to 
    2008          * be used. In this case, skip transport hash table lookup. 
    2009          */ 
    2010  
    2011         /* Verify that the listener type matches the destination type */ 
    2012         if (sel->u.listener->type != type) { 
    2013             pj_lock_release(mgr->lock); 
    2014             return PJSIP_ETPNOTSUITABLE; 
    2015         } 
    2016  
    2017         /* We'll use this listener to create transport */ 
    2018         factory = sel->u.listener; 
    2019  
    20202020    } else { 
    20212021 
    20222022        /* 
    20232023         * This is the "normal" flow, where application doesn't specify 
    2024          * specific transport/listener to be used to send message to. 
     2024         * specific transport to be used to send message to. 
    20252025         * In this case, lookup the transport from the hash table. 
    20262026         */ 
     
    20282028        int key_len; 
    20292029        pjsip_transport *transport; 
     2030 
     2031        /* If listener is specified, verify that the listener type matches 
     2032         * the destination type. 
     2033         */ 
     2034        if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener) 
     2035        { 
     2036            if (sel->u.listener->type != type) { 
     2037                pj_lock_release(mgr->lock); 
     2038                return PJSIP_ETPNOTSUITABLE; 
     2039            } 
     2040        } 
    20302041 
    20312042        pj_bzero(&key, sizeof(key)); 
     
    20702081        } 
    20712082 
     2083        /* If transport is found and listener is specified, verify listener */ 
     2084        else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 
     2085                 sel->u.listener && transport->factory != sel->u.listener) 
     2086        { 
     2087            transport = NULL; 
     2088            /* This will cause a new transport to be created which will be a 
     2089             * 'duplicate' of the existing transport (same type & remote addr, 
     2090             * but different factory). Any future hash lookup will return 
     2091             * the new one, and eventually the old one will still be freed 
     2092             * (by application or #1774). 
     2093             */ 
     2094        } 
     2095 
    20722096        if (transport!=NULL && !transport->is_shutdown) { 
    20732097            /* 
     
    20822106        } 
    20832107 
     2108 
    20842109        /* 
    20852110         * Transport not found! 
    2086          * Find factory that can create such transport. 
     2111         * So we need to create one, find factory that can create 
     2112         * such transport. 
    20872113         */ 
    2088         factory = mgr->factory_list.next; 
    2089         while (factory != &mgr->factory_list) { 
    2090             if (factory->type == type) 
    2091                 break; 
    2092             factory = factory->next; 
    2093         } 
    2094  
    2095         if (factory == &mgr->factory_list) { 
    2096             /* No factory can create the transport! */ 
    2097             pj_lock_release(mgr->lock); 
    2098             TRACE_((THIS_FILE, "No suitable factory was found either")); 
    2099             return PJSIP_EUNSUPTRANSPORT; 
     2114        if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener) 
     2115        { 
     2116            /* Application has requested that a specific listener is to 
     2117             * be used. 
     2118             */ 
     2119 
     2120            /* Verify that the listener type matches the destination type */ 
     2121            if (sel->u.listener->type != type) { 
     2122                pj_lock_release(mgr->lock); 
     2123                return PJSIP_ETPNOTSUITABLE; 
     2124            } 
     2125 
     2126            /* We'll use this listener to create transport */ 
     2127            factory = sel->u.listener; 
     2128 
     2129            /* Verify if listener is still valid */ 
     2130            if (!pjsip_tpmgr_is_tpfactory_valid(mgr, factory)) { 
     2131                pj_lock_release(mgr->lock); 
     2132                PJ_LOG(3,(THIS_FILE, "Specified factory for creating " 
     2133                                     "transport is not found")); 
     2134                return PJ_ENOTFOUND; 
     2135            } 
     2136 
     2137        } else { 
     2138 
     2139            /* Find factory with type matches the destination type */ 
     2140            factory = mgr->factory_list.next; 
     2141            while (factory != &mgr->factory_list) { 
     2142                if (factory->type == type) 
     2143                    break; 
     2144                factory = factory->next; 
     2145            } 
     2146 
     2147            if (factory == &mgr->factory_list) { 
     2148                /* No factory can create the transport! */ 
     2149                pj_lock_release(mgr->lock); 
     2150                TRACE_((THIS_FILE, "No suitable factory was found either")); 
     2151                return PJSIP_EUNSUPTRANSPORT; 
     2152            } 
    21002153        } 
    21012154    } 
     
    21172170            {pj_lock_release(mgr->lock); return PJ_EBUG;}); 
    21182171        pjsip_transport_add_ref(*tp); 
     2172        (*tp)->factory = factory; 
    21192173    } 
    21202174    pj_lock_release(mgr->lock); 
Note: See TracChangeset for help on using the changeset viewer.