[asterisk-scf-commits] asterisk-scf/release/sip.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Jun 1 16:17:32 CDT 2011


branch "master" has been updated
       via  f629cf1b575eb73348d837cd2864a7f76c1a4159 (commit)
       via  9b157bc4d9957ef74d6cf277035305ea2c39f0bb (commit)
      from  a41ade002c57ccdd90495a8c0d50ba40dd69e19d (commit)

Summary of changes:
 src/PJSipSessionModule.cpp |   90 ++++++++++++++++++++++++++++++--------------
 1 files changed, 62 insertions(+), 28 deletions(-)


- Log -----------------------------------------------------------------
commit f629cf1b575eb73348d837cd2864a7f76c1a4159
Merge: 9b157bc a41ade0
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jun 1 16:17:40 2011 -0500

    Merge branch 'master' of git.asterisk.org:asterisk-scf/release/sip


commit 9b157bc4d9957ef74d6cf277035305ea2c39f0bb
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jun 1 16:15:46 2011 -0500

    Fix object lifetime issue when handling REFER requests.
    
    I had passed a URI to the HandleReferOperation under the impression
    that it was heap-allocated and therefore would not be deleted until
    the dialog it belonged to was destroyed.
    
    However, the dialog's pool was being reset, causing the pointer we
    pass in to point to bogus memory. So now, we make copies of the
    individual parts we require and delete them ourselves when the
    operation completes.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 6d3d980..8056881 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -582,13 +582,26 @@ public:
             pjsip_inv_session *inv,
             pjsip_transaction *tsx,
             pjsip_tx_data *tdata,
-            pjsip_sip_uri *target_sip_uri,
+            pjsip_param *replaces_param,
+            pjsip_param *to_tag_param,
+            pjsip_param *from_tag_param,
+            const std::string& target,
             const SipSessionPtr& session,
             const AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>& sessionRouter,
             const int moduleId)
         : mInv(inv), mTsx(tsx), mTdata(tdata), 
-        mTargetSipUri(target_sip_uri), mSession(session), mSessionRouter(sessionRouter),
-        mModuleId(moduleId), mWasWithDestination(false) { }
+        mReplacesParam(replaces_param ? new pjsip_param(*replaces_param) : NULL), 
+        mToTagParam(to_tag_param ? new pjsip_param(*to_tag_param) : NULL),
+        mFromTagParam(from_tag_param ? new pjsip_param(*from_tag_param) : NULL), mTarget(target),
+        mSession(session), mSessionRouter(sessionRouter),
+        mModuleId(moduleId), mWasWithDestination(false) {}
+
+    ~HandleReferOperation()
+    {
+        delete mReplacesParam;
+        delete mToTagParam;
+        delete mFromTagParam;
+    }
 
 protected:
     /**
@@ -604,33 +617,22 @@ protected:
     SuspendableWorkResult initial(const SuspendableWorkListenerPtr& workListener)
     {
         // Determine if this is a blind transfer or an attended transfer
-        pj_str_t replaces = pj_str((char*)"Replaces");
-        pjsip_param *replaces_param = pjsip_param_find(&mTargetSipUri->other_param, &replaces);
-
-        if (!replaces_param)
-        {
-            replaces_param = pjsip_param_find(&mTargetSipUri->header_param, &replaces);
-        }
 
-        if (replaces_param)
+        if (mReplacesParam)
         {
-            pj_str_t to_tag = pj_str((char*)"To-tag");
-            pj_str_t from_tag = pj_str((char*)"From-tag");
-            pjsip_param *to_tag_param = pjsip_param_find(&mTargetSipUri->other_param, &to_tag);
-            pjsip_param *from_tag_param = pjsip_param_find(&mTargetSipUri->other_param, &from_tag);
             pjsip_dialog *other_dlg = NULL;
 
-            if (to_tag_param && from_tag_param)
+            if (mToTagParam && mFromTagParam)
             {
-                other_dlg = pjsip_ua_find_dialog(&replaces_param->value, &to_tag_param->value, &from_tag_param->value,
+                other_dlg = pjsip_ua_find_dialog(&mReplacesParam->value, &mToTagParam->value, &mFromTagParam->value,
                         PJ_TRUE);
             }
             else
             {
                 // It is possible for the to and from tag value to be present within the Replaces parameter value, so try to
                 // parse it out
-                std::string replaces_value_tmp = std::string(pj_strbuf(&replaces_param->value),
-                        pj_strlen(&replaces_param->value));
+                std::string replaces_value_tmp = std::string(pj_strbuf(&mReplacesParam->value),
+                        pj_strlen(&mReplacesParam->value));
                 size_t from_tag_pos = replaces_value_tmp.find(";from-tag=");
                 size_t to_tag_pos = replaces_value_tmp.find(";to-tag=");
 
@@ -717,8 +719,6 @@ protected:
         }
         else
         {
-            std::string target = std::string(pj_strbuf(&mTargetSipUri->user), pj_strlen(&mTargetSipUri->user));
-
             // Now that we have the target user we can pass this into routing and go on our marry way
             try
             {
@@ -730,7 +730,7 @@ protected:
 
                 lg(Debug) << "handleRefer() calling router connectBridgedSessionsWithDestination(). ";
                 mWasWithDestination = true;
-                mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), target, d);
+                mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, d);
                 return Complete;
             }
             catch (const Ice::CommunicatorDestroyedException &)
@@ -801,9 +801,25 @@ private:
      */
     pjsip_tx_data *mTdata;
     /**
-     * The SIP URI from the Refer-To header in the REFER request.
+     * The Replaces parameter from the URI in the Refer-To header
+     * of the REFER that triggered this operation.
+     */
+    pjsip_param *mReplacesParam;
+    /**
+     * The to-tag parameter from the URI in the Refer-To header
+     * of the REFER that triggered this operation.
+     */
+    pjsip_param *mToTagParam;
+    /**
+     * The from-tag parameter from the URI in the Refer-To header
+     * of the REFER that triggered this operation.
      */
-    pjsip_sip_uri *mTargetSipUri;
+    pjsip_param *mFromTagParam;
+    /**
+     * The user portion of the URI in the Refer-To header of the
+     * REFER that triggered this operation.
+     */
+    const std::string mTarget;
     /**
      * The SipSession on which this work is executed
      */
@@ -847,9 +863,6 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     // TODO: Provide method to send back suitable response
 
     // Now parse the URI to get the actual target they want to refer to
-    //
-    // Parsing the URI allocates memory in the dialog's pool, thus allowing a
-    // safe shallow copy to a queueable operation.
     pjsip_uri *target_uri = static_cast<pjsip_uri *>(pjsip_parse_uri(inv->dlg->pool, refer_to->hvalue.ptr, refer_to->hvalue.slen, 0));
 
     // We only support SIP URIs, anything else is rubbish to us
@@ -863,6 +876,27 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
 
     pjsip_sip_uri *target_sip_uri = (pjsip_sip_uri *)pjsip_uri_get_uri(target_uri);
 
+    pj_str_t replaces = pj_str((char*)"Replaces");
+    pjsip_param *replaces_param = pjsip_param_find(&target_sip_uri->other_param, &replaces);
+    pjsip_param *to_tag_param;
+    pjsip_param *from_tag_param;
+    std::string target;
+    if (!replaces_param)
+    {
+        replaces_param = pjsip_param_find(&target_sip_uri->header_param, &replaces);
+    }
+    if (replaces_param)
+    {
+        pj_str_t to_tag = pj_str((char*)"To-tag");
+        pj_str_t from_tag = pj_str((char*)"From-tag");
+        to_tag_param = pjsip_param_find(&target_sip_uri->other_param, &to_tag);
+        from_tag_param = pjsip_param_find(&target_sip_uri->other_param, &from_tag);
+    }
+    else
+    {
+        target = std::string(pj_strbuf(&target_sip_uri->user), pj_strlen(&target_sip_uri->user));
+    }
+
     PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*) inv->mod_data[mModule.id];
     SipSessionPtr session = session_mod_info->getSessionPtr();
 
@@ -871,7 +905,7 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
 
     lg(Debug) << "Queuing a HandleReferOperation";
-    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, target_sip_uri, session, mSessionRouter, mModule.id), inv);
+    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, target, session, mSessionRouter, mModule.id), inv);
 }
 
 pj_bool_t PJSipSessionModule::on_rx_request(pjsip_rx_data *rdata)

-----------------------------------------------------------------------


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list