Module: sip-router
Branch: master
Commit: 946e1f01889c67a835583f4df2c773d227693ea7
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=946e1f01889c67a835583f4df2c773d227693ea7

Author: Jason Penton <[email protected]>
Committer: Jason Penton <[email protected]>
Date:   Mon Oct 28 14:51:12 2013 +0200

modules/tm: fixed pkg memory leak in TM which happens in async reply processing

---

 modules/tm/h_table.h   |    1 +
 modules/tm/t_suspend.c |   54 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index 1f9f376..5790935 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -215,6 +215,7 @@ typedef struct ua_client
 {
        /* if we store a reply (branch picking), this is where it is */
        struct sip_msg  *reply;
+       char *end_reply;        /* pointer to end of sip_msg so we know the shm 
blocked used in clone...(used in async replies) */
        struct retr_buf  request;
        /* we maintain a separate copy of cancel rather than
           reuse the structure for original request; the 
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index f2cacbc..d898984 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -119,12 +119,14 @@ int t_suspend(struct sip_msg *msg,
 
                LOG(L_DBG,"DEBUG: t_suspend_reply:Cloning reply message to 
t->uac[branch].reply\n");
 
-               t->uac[branch].reply = sip_msg_cloner( msg, 0 );
+               int sip_msg_len = 0;
+               t->uac[branch].reply = sip_msg_cloner( msg, &sip_msg_len );
 
                if (! t->uac[branch].reply ) {
                        LOG(L_ERR, "ERROR: t_suspend_reply: can't alloc' clone 
memory\n");
                        return -1;
                }
+               t->uac[branch].end_reply = ((char*)t->uac[branch].reply) + 
sip_msg_len;
 
                LOG(L_DBG,"DEBUG: t_suspend_reply: Saving transaction data\n");
                t->uac[branch].reply->flags = msg->flags;
@@ -156,7 +158,7 @@ int t_continue(unsigned int hash_index, unsigned int label,
                struct action *route)
 {
        struct cell     *t;
-       struct sip_msg  faked_req, faked_resp;
+       struct sip_msg  faked_req;
        struct cancel_info cancel_data;
        int     branch;
        struct ua_client *uac =NULL;
@@ -283,27 +285,19 @@ int t_continue(unsigned int hash_index, unsigned int 
label,
                t->uac[branch].reply->msg_flags &= ~FL_RPL_SUSPENDED;
                if (t->uas.request) t->uas.request->msg_flags&= 
~FL_RPL_SUSPENDED;
 
-               LOG(L_DBG,"DEBUG: t_continue_reply: Setting up faked 
environment");
-               if (!fake_resp(&faked_resp, t->uac[branch].reply, 0 /* extra 
flags */, 0)) {
-                       LOG(L_ERR, "ERROR: t_continue_reply: fake_resp 
failed\n");
-                       ret = -1;
-                       goto kill_trans;
-               }
-
-               faked_env( t, &faked_resp, 1);
+               faked_env( t, t->uac[branch].reply, 1);
 
                LOG(L_DBG,"DEBUG: Running pre script\n");
-               if (exec_pre_script_cb(&faked_resp, cb_type)>0) {
-                       if (run_top_route(route, &faked_resp, 0)<0){
+               if (exec_pre_script_cb(t->uac[branch].reply, cb_type)>0) {
+                       if (run_top_route(route, t->uac[branch].reply, 0)<0){
                                LOG(L_ERR, "ERROR: t_continue_reply: Error in 
run_top_route\n");
                        }
                        LOG(L_DBG,"DEBUG: t_continue_reply: Running exec post 
script\n");
-                       exec_post_script_cb(&faked_resp, cb_type);
+                       exec_post_script_cb(t->uac[branch].reply, cb_type);
                }
 
                LOG(L_DBG,"DEBUG: t_continue_reply: Restoring previous 
environment");
                faked_env( t, 0, 1);
-               free_faked_resp(&faked_resp, t, branch);
 
                int reply_status;
 
@@ -387,6 +381,38 @@ done:
                /* unref the transaction */
                t_unref(t->uac[branch].reply);
                LOG(L_DBG,"DEBUG: t_continue_reply: Freeing earlier cloned 
reply\n");
+               /* free header's parsed structures that were added by failure 
handlers */
+               struct hdr_field* hdr;
+               struct hdr_field* prev = 0;
+               struct hdr_field* tmp = 0;
+               for( hdr=t->uac[branch].reply->headers ; hdr ; hdr=hdr->next ) {
+                       if ( hdr->parsed && hdr_allocs_parse(hdr) &&
+                               (hdr->parsed<(void*)t->uac[branch].reply ||
+                               hdr->parsed>=(void*)t->uac[branch].end_reply)) {
+                               clean_hdr_field(hdr);
+                               hdr->parsed = 0;
+                       }
+               }
+
+               /* now go through hdr_fields themselves and remove the pkg 
allocated space */
+               hdr = t->uac[branch].reply->headers;
+               while (hdr) {
+                       if ( hdr && ((void*)hdr<(void*)t->uac[branch].reply ||
+                               (void*)hdr>=(void*)t->uac[branch].end_reply)) {
+                               //this header needs to be freed and removed 
form the list.
+                               if (!prev) {
+                                       t->uac[branch].reply->headers = 
hdr->next;
+                               } else {
+                                       prev->next = hdr->next;
+                               }
+                               tmp = hdr;
+                               hdr = hdr->next;
+                               pkg_free(tmp);
+                       } else {
+                               prev = hdr;
+                               hdr = hdr->next;
+                       }
+               }
                sip_msg_free(t->uac[branch].reply);
                t->uac[branch].reply = 0;
        }


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to