rem: {  k5++;
add: {
context: struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg ){   unsigned int         len;   struct hdr_field    *hdr,*new_hdr,*last_hdr;   struct via_body    *via;   struct via_param *prm;   struct to_param   *to_prm,*new_to_prm;   struct sip_msg     *new_msg;   struct lump          *lump_chain, *lump_tmp, **lump_anchor, **lump_anchor2;   struct lump_rpl    *rpl_lump, **rpl_lump_anchor;   char                       *p,*foo;   int k1=0,k2=0,k3=0,k4=0,k5=0,k6=0;   /*computing the length of entire sip_msg structure*/   len = ROUND4(sizeof( struct sip_msg ));   /*we will keep only the original msg*/   len += ROUND4(org_msg->len);   /*the new uri (if any)*/   if (org_msg->new_uri.s && org_msg->new_uri.len)      len+= ROUND4(org_msg->new_uri.len);   /*all the headers*/   for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )   {      /*size of header struct*/      len += ROUND4(sizeof( struct hdr_field));      switch (hdr->type)      {         case HDR_CSEQ:                   len+=ROUND4(sizeof(struct cseq_body));                   break;         case HDR_TO:                   len+=ROUND4(sizeof(struct to_body));                   /*to param*/                   to_prm = ((struct to_body*)(hdr->parsed))->param_lst;                   for(;to_prm;to_prm=to_prm->next)                      len+=ROUND4(sizeof(struct to_param ));                   break;         case HDR_VIA:                   for (via=(struct via_body*)hdr->parsed;via;via=via->next)                   {                      len+=ROUND4(sizeof(struct via_body));                      /*via param*/                      for(prm=via->param_lst;prm;prm=prm->next)                         len+=ROUND4(sizeof(struct via_param ));                   }                   break;      }   }   /* length of the data lump structures */   if (org_msg->first_line.type==SIP_REQUEST)      lump_chain = org_msg->add_rm;   else      lump_chain = org_msg->repl_add_rm;   while (lump_chain)   {  k1++;      len += lump_len( lump_chain );      lump_tmp = lump_chain->before;      while ( lump_tmp )      {  k2++;         len += lump_len( lump_tmp );         lump_tmp = lump_tmp->before;      }      lump_tmp = lump_chain->after;      while ( lump_tmp )      {  k3++;         len += lump_len( lump_tmp );         lump_tmp = lump_tmp->after;      }      lump_chain = lump_chain->next;   }   /*length of reply lump structures*/   for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)       len+=rpl_lump->text.len;   p=(char *)sh_malloc(len);foo=p;   if (!p)   {      LOG(L_ERR , "ERROR: sip_msg_cloner_2: cannot allocate memory\n" );      return 0;   }   /*filling up the new structure*/   new_msg = (struct sip_msg*)p;   /*sip msg structure*/   memcpy( new_msg , org_msg , sizeof(struct sip_msg) );   p += ROUND4(sizeof(struct sip_msg));   new_msg->add_rm = new_msg->repl_add_rm = 0;   /*new_uri*/   if (org_msg->new_uri.s && org_msg->new_uri.len)   {      new_msg->new_uri.s = p;      memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);      p += ROUND4(org_msg->new_uri.len);   }   /*message buffers(org and scratch pad)*/   memcpy( p , org_msg->orig , org_msg->len);   new_msg->orig = new_msg->buf = p;   p += ROUND4(new_msg->len);   /*unparsed and eoh pointer*/   new_msg->unparsed = translate_pointer( new_msg->buf ,	org_msg->buf , org_msg->unparsed );   new_msg->eoh = translate_pointer( new_msg->buf ,	org_msg->buf , org_msg->eoh );   /* first line, updating the pointers*/   if ( org_msg->first_line.type==SIP_REQUEST )   {      new_msg->first_line.u.request.method.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.method.s );      new_msg->first_line.u.request.uri.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.uri.s );      new_msg->first_line.u.request.version.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.version.s );   }   else if ( org_msg->first_line.type==SIP_REPLY )   {      new_msg->first_line.u.reply.version.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.version.s );      new_msg->first_line.u.reply.status.s =  translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.status.s );      new_msg->first_line.u.reply.reason.s =  translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.reason.s );    }   /*headers list*/   new_msg->via1=0;   new_msg->via2=0;   for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )   {      new_hdr = (struct hdr_field*)p;      memcpy(new_hdr, hdr, sizeof(struct hdr_field) );      p += ROUND4(sizeof( struct hdr_field));      new_hdr->name.s =  translate_pointer( new_msg->buf , org_msg->buf , hdr->name.s );      new_hdr->body.s =  translate_pointer( new_msg->buf , org_msg->buf , hdr->body.s );     switch (hdr->type)      {         case HDR_VIA:                if ( !new_msg->via1 )                   {                       new_msg->h_via1 = new_hdr;                       new_msg->via1 = via_body_cloner_2( new_msg->buf , org_msg->buf , (struct via_body*)hdr->parsed , &p);                       new_hdr->parsed  = (void*)new_msg->via1;                   if ( new_msg->via1->next )                            new_msg->via2 = new_msg->via1->next;                   }                else if ( !new_msg->via2 && new_msg->via1 )                   {                       new_msg->h_via2 = new_hdr;                       if ( new_msg->via1->next )                           new_hdr->parsed = (void*)new_msg->via1->next;                       else{                           new_msg->via2 = via_body_cloner_2( new_msg->buf , org_msg->buf , (struct via_body*)hdr->parsed , &p);                           new_hdr->parsed  = (void*)new_msg->via2;                       }                   }                else if ( new_msg->via2 && new_msg->via1 )                   {                       new_hdr->parsed  = new_msg->via1 = via_body_cloner_2( new_msg->buf , org_msg->buf , (struct via_body*)hdr->parsed , &p);                   }                   break;         case HDR_CSEQ:                   new_hdr->parsed = p;                   p +=ROUND4(sizeof(struct cseq_body));                   memcpy( new_hdr->parsed , hdr->parsed , sizeof(struct cseq_body) );                   ((struct cseq_body*)new_hdr->parsed)->number.s =  translate_pointer( new_msg->buf , org_msg->buf , ((struct cseq_body*)hdr->parsed)->number.s );                   ((struct cseq_body*)new_hdr->parsed)->method.s =  translate_pointer( new_msg->buf , org_msg->buf , ((struct cseq_body*)hdr->parsed)->method.s );                   new_msg->cseq = new_hdr;                   break;         case HDR_TO:                   new_hdr->parsed = p;                   p +=ROUND4(sizeof(struct to_body));                   memcpy( new_hdr->parsed , hdr->parsed ,                    sizeof(struct to_body) );                   ((struct to_body*)new_hdr->parsed)->body.s =                        translate_pointer( new_msg->buf , org_msg->buf ,                        ((struct to_body*)hdr->parsed)->body.s );                   if ( ((struct to_body*)hdr->parsed)->tag_value.s )                         ((struct to_body*)new_hdr->parsed)->tag_value.s                         = translate_pointer( new_msg->buf , org_msg->buf ,                            ((struct to_body*)hdr->parsed)->tag_value.s );                    /*to params*/                   to_prm = ((struct to_body*)(hdr->parsed))->param_lst;                   for(;to_prm;to_prm=to_prm->next)                   {                      /*alloc*/                      new_to_prm = (struct to_param*)p;                      p +=ROUND4(sizeof(struct to_param ));                      /*coping*/                      memcpy( new_to_prm, to_prm, sizeof(struct to_param ));                      ((struct to_body*)new_hdr->parsed)->param_lst = 0;                      new_to_prm->name.s = translate_pointer( new_msg->buf,                         org_msg->buf , to_prm->name.s );                      new_to_prm->value.s = translate_pointer( new_msg->buf,                         org_msg->buf , to_prm->value.s );                      /*linking*/                      if ( !((struct to_body*)new_hdr->parsed)->param_lst )                         ((struct to_body*)new_hdr->parsed)->param_lst                            = new_to_prm;                      else                         ((struct to_body*)new_hdr->parsed)->last_param->next                            = new_to_prm;                      ((struct to_body*)new_hdr->parsed)->last_param                         = new_to_prm;                   }                   new_msg->to = new_hdr;                   break;         case HDR_CALLID:                   new_msg->callid = new_hdr;                   break;         case HDR_FROM:                   new_msg->from = new_hdr;                   break;         case HDR_CONTACT:                   new_msg->contact = new_hdr;                   break;         case HDR_MAXFORWARDS :                  new_msg->maxforwards = new_hdr;               break;        case HDR_ROUTE :                  new_msg->route = new_hdr;               break;      }     if ( last_hdr )      {          last_hdr->next = new_hdr;          last_hdr=last_hdr->next;      }      else      {           last_hdr=new_hdr;           new_msg->headers =new_hdr;      }      last_hdr->next = 0;      new_msg->last_header = last_hdr;   }   /* clonning data lump */   if (org_msg->first_line.type==SIP_REQUEST) {      lump_chain = org_msg->add_rm;      lump_anchor = &(new_msg->add_rm);   }else{      lump_chain = org_msg->repl_add_rm;      lump_anchor = &(new_msg->repl_add_rm);   }   while (lump_chain)   {  k4++;      lump_clone( (*lump_anchor) , lump_chain , p );      /*before list*/      lump_tmp = lump_chain->before;      lump_anchor2 = &((*lump_anchor)->before);      while ( lump_tmp )      {  k5++;         lump_clone( (*lump_anchor2) , lump_tmp , p );         lump_anchor2 = &((*lump_anchor2)->before);         lump_tmp = lump_tmp->before;      }      /*after list*/      lump_tmp = lump_chain->after;      lump_anchor2 = &((*lump_anchor)->after);      while ( lump_tmp )      {  k6++;         lump_clone( (*lump_anchor2) , lump_tmp , p );         lump_anchor2 = &((*lump_anchor2)->after);         lump_tmp = lump_tmp->after;      }      lump_anchor = &((*lump_anchor)->next);      lump_chain = lump_chain->next;   }   /*cloning reply lump structures*/   rpl_lump_anchor = &(new_msg->reply_lump);   for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)   {       *(rpl_lump_anchor)=(struct lump_rpl*)p;       p+=sizeof( struct lump_rpl );       (*rpl_lump_anchor)->text.len = rpl_lump->text.len;       (*rpl_lump_anchor)->text.s=p;       p+=rpl_lump->text.len;       memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len);       (*rpl_lump_anchor)->next=0;       rpl_lump_anchor = &((*rpl_lump_anchor)->next);   }    DBG("DEBUG:cloner (  %d < %d,%d> )  ---  ( %d < %d , %d > )\n",       k1,k2,k3,k4,k5,k6);    DBG("DEBUG:cloner --------<%d>---------<%d>-------------\n",len,p-foo);   return new_msg;}