tm/sip_msg.c

Go to the documentation of this file.
00001 /*
00002  * $Id: sip_msg.c 4898 2008-09-15 08:46:24Z miconda $
00003  * 
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  *  2003-01-23 - msg_cloner clones msg->from->parsed too (janakj)
00025  *  2003-01-29 - scratchpad removed (jiri)
00026  *  2003-02-25 - auth_body cloner added (janakj)
00027  *  2003-02-28  scratchpad compatibility abandoned (jiri)
00028  *  2003-03-31  removed msg->repl_add_rm (andrei)
00029  *  2003-04-04  parsed uris are recalculated on cloning (jiri)
00030  *  2003-05-07  received, rport & i via shortcuts are also translated (andrei)
00031  *  2003-11-11  updated cloning of lump_rpl (bogdan)
00032  *  2004-03-31  alias shortcuts are also translated (andrei)
00033  *
00034  */
00035 
00036 /*! \file
00037  * \brief TM :: SIP message handling
00038  *
00039  * \ingroup tm
00040  * - Module: \ref tm
00041  * - \ref TMcloneMessage
00042  *
00043  *
00044  * \page TMcloneMessage TM :: A note about cloned messages
00045  * TM clones a message into shared memory (TM keeps a snapshot
00046  * of messages in memory); note that many operations, which
00047  * allocate pkg memory (such as parsing) cannot be used with
00048  * a cloned message -- it would result in linking pkg structures
00049  * to shmem msg and eventually in a memory error 
00050  *
00051  * The cloned message is stored in a single memory fragment to
00052  * save too many shm_mallocs -- these are expensive as they
00053  * not only take lookup in fragment table but also a shmem lock
00054  * operation (the same for shm_free)
00055  *
00056  */
00057 
00058 #include <stdio.h>
00059 #include "sip_msg.h"
00060 #include "../../dprint.h"
00061 #include "../../mem/mem.h"
00062 #include "../../data_lump.h"
00063 #include "../../data_lump_rpl.h"
00064 #include "../../ut.h"
00065 #include "../../parser/digest/digest.h"
00066 
00067 
00068 /* rounds to the first 4 byte multiple on 32 bit archs 
00069  * and to the first 8 byte multiple on 64 bit archs */
00070 #define ROUND4(s) \
00071    (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
00072 
00073 #define lump_len( _lump) \
00074    (ROUND4(sizeof(struct lump)) +\
00075    ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))
00076 #define lump_clone( _new,_old,_ptr) \
00077    {\
00078       (_new) = (struct lump*)(_ptr);\
00079       memcpy( (_new), (_old), sizeof(struct lump) );\
00080       (_new)->flags|=LUMPFLAG_SHMEM; \
00081       (_ptr)+=ROUND4(sizeof(struct lump));\
00082       if ( (_old)->op==LUMP_ADD) {\
00083          (_new)->u.value = (char*)(_ptr);\
00084          memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\
00085          (_ptr)+=ROUND4((_old)->len);}\
00086    }
00087 
00088 
00089 
00090 
00091 inline static struct via_body* via_body_cloner( char* new_buf,
00092                char *org_buf, struct via_body *param_org_via, char **p)
00093 {
00094    struct via_body *new_via;
00095    struct via_body *first_via, *last_via;
00096    struct via_body *org_via;
00097 
00098    first_via = last_via = 0;
00099    org_via = param_org_via;
00100 
00101    do
00102    {
00103       /* clones the via_body structure */
00104       new_via = (struct via_body*)(*p);
00105       memcpy( new_via , org_via , sizeof( struct via_body) );
00106       (*p) += ROUND4(sizeof( struct via_body ));
00107 
00108       /* hdr (str type) */
00109       new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);
00110       /* name (str type) */
00111       new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);
00112       /* version (str type) */
00113       new_via->version.s=
00114          translate_pointer(new_buf,org_buf,org_via->version.s);
00115       /* transport (str type) */
00116       new_via->transport.s=
00117          translate_pointer(new_buf,org_buf,org_via->transport.s);
00118       /* host (str type) */
00119       new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);
00120       /* port_str (str type) */
00121       new_via->port_str.s=
00122          translate_pointer(new_buf,org_buf,org_via->port_str.s);
00123       /* params (str type) */
00124       new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);
00125       /* transaction id */
00126       new_via->tid.s=
00127          translate_pointer(new_buf, org_buf, org_via->tid.s);
00128       /* comment (str type) */
00129       new_via->comment.s=
00130          translate_pointer(new_buf,org_buf,org_via->comment.s);
00131 
00132       if ( org_via->param_lst )
00133       {
00134          struct via_param *vp, *new_vp, *last_new_vp;
00135          for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
00136          {
00137             new_vp = (struct via_param*)(*p);
00138             memcpy( new_vp , vp , sizeof(struct via_param));
00139             (*p) += ROUND4(sizeof(struct via_param));
00140             new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);
00141             new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);
00142             new_vp->start=translate_pointer(new_buf,org_buf,vp->start);
00143             
00144             /* "translate" the shortcuts */
00145             switch(new_vp->type){
00146                case PARAM_BRANCH:
00147                      new_via->branch = new_vp;
00148                      break;
00149                case PARAM_RECEIVED:
00150                      new_via->received = new_vp;
00151                      break;
00152                case PARAM_RPORT:
00153                      new_via->rport = new_vp;
00154                      break;
00155                case PARAM_I:
00156                      new_via->i = new_vp;
00157                      break;
00158                case PARAM_ALIAS:
00159                      new_via->alias = new_vp;
00160                      break;
00161                case PARAM_MADDR:
00162                      new_via->maddr = new_vp;
00163                      break;
00164             }
00165 
00166             if (last_new_vp)
00167                last_new_vp->next = new_vp;
00168             else
00169                new_via->param_lst = new_vp;
00170 
00171             last_new_vp = new_vp;
00172             last_new_vp->next = NULL;
00173          }
00174          new_via->last_param = new_vp;
00175       }/*end if via has params */
00176 
00177       if (last_via)
00178          last_via->next = new_via;
00179       else
00180          first_via = new_via;
00181       last_via = new_via;
00182       org_via = org_via->next;
00183    }while(org_via);
00184 
00185    return first_via;
00186 }
00187 
00188 
00189 static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
00190 {
00191    uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);
00192    uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);
00193    uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);
00194    uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);
00195    uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);
00196    uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);
00197    /* parameters */
00198    uri->transport.s=translate_pointer(new_buf,org_buf,uri->transport.s);
00199    uri->ttl.s=translate_pointer(new_buf,org_buf,uri->ttl.s);
00200    uri->user_param.s=translate_pointer(new_buf,org_buf,uri->user_param.s);
00201    uri->maddr.s=translate_pointer(new_buf,org_buf,uri->maddr.s);
00202    uri->method.s=translate_pointer(new_buf,org_buf,uri->method.s);
00203    uri->lr.s=translate_pointer(new_buf,org_buf,uri->lr.s);
00204    uri->r2.s=translate_pointer(new_buf,org_buf,uri->r2.s);
00205       /* ser specific rr parameter */
00206    /* values */
00207    uri->transport_val.s
00208       =translate_pointer(new_buf,org_buf,uri->transport_val.s);
00209    uri->ttl_val.s=translate_pointer(new_buf,org_buf,uri->ttl_val.s);
00210    uri->user_param_val.s
00211       =translate_pointer(new_buf,org_buf,uri->user_param_val.s);
00212    uri->maddr_val.s=translate_pointer(new_buf,org_buf,uri->maddr_val.s);
00213    uri->method_val.s=translate_pointer(new_buf,org_buf,uri->method_val.s);
00214    uri->lr_val.s=translate_pointer(new_buf,org_buf,uri->lr_val.s);
00215       /* lr value placeholder for lr=on a.s.o*/
00216    uri->r2_val.s=translate_pointer(new_buf,org_buf,uri->r2_val.s);
00217 }
00218 
00219 
00220 static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
00221 {
00222    struct auth_body* new_auth;
00223 
00224    new_auth = (struct auth_body*)(*p);
00225    memcpy(new_auth , auth , sizeof(struct auth_body));
00226    (*p) += ROUND4(sizeof(struct auth_body));
00227    
00228    /* authorized field must be cloned elsewhere */
00229    new_auth->digest.username.whole.s =
00230       translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);
00231    new_auth->digest.username.user.s =
00232       translate_pointer(new_buf, org_buf, auth->digest.username.user.s);
00233    new_auth->digest.username.domain.s =
00234       translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);
00235    new_auth->digest.realm.s =
00236       translate_pointer(new_buf, org_buf, auth->digest.realm.s);
00237    new_auth->digest.nonce.s =
00238       translate_pointer(new_buf, org_buf, auth->digest.nonce.s);
00239    new_auth->digest.uri.s =
00240       translate_pointer(new_buf, org_buf, auth->digest.uri.s);
00241    new_auth->digest.response.s =
00242       translate_pointer(new_buf, org_buf, auth->digest.response.s);
00243    new_auth->digest.alg.alg_str.s =
00244       translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);
00245    new_auth->digest.cnonce.s =
00246       translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);
00247    new_auth->digest.opaque.s =
00248       translate_pointer(new_buf, org_buf, auth->digest.opaque.s);
00249    new_auth->digest.qop.qop_str.s =
00250       translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);
00251    new_auth->digest.nc.s =
00252       translate_pointer(new_buf, org_buf, auth->digest.nc.s);
00253    return new_auth;
00254 }
00255 
00256 
00257 static inline int clone_authorized_hooks(struct sip_msg* new,
00258                 struct sip_msg* old)
00259 {
00260    struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
00261    char stop = 0;
00262 
00263    get_authorized_cred(old->authorization, &hook1);
00264    if (!hook1) stop = 1;
00265    
00266    get_authorized_cred(old->proxy_auth, &hook2);
00267    if (!hook2) stop |= 2;
00268 
00269    ptr = old->headers;
00270    new_ptr = new->headers;
00271 
00272    while(ptr) {
00273       if (ptr == hook1) {
00274          if (!new->authorization || !new->authorization->parsed) {
00275             LM_CRIT("message cloner (authorization) failed\n");
00276             return -1;
00277          }
00278          ((struct auth_body*)new->authorization->parsed)->authorized =
00279             new_ptr;
00280          stop |= 1;
00281       }
00282       
00283       if (ptr == hook2) {
00284          if (!new->proxy_auth || !new->proxy_auth->parsed) {
00285             LM_CRIT("message cloner (proxy_auth) failed\n");
00286             return -1;
00287          }
00288          ((struct auth_body*)new->proxy_auth->parsed)->authorized =
00289             new_ptr;
00290          stop |= 2;
00291       }
00292 
00293       if (stop == 3) break;
00294 
00295       ptr = ptr->next;
00296       new_ptr = new_ptr->next;
00297    }
00298    return 0;
00299 }
00300 
00301 
00302 #define AUTH_BODY_SIZE sizeof(struct auth_body)
00303 
00304 #define HOOK_NOT_SET(hook) (new_msg->hook == org_msg->hook)
00305 
00306 /* next macro should only be called if hook is already set */
00307 #define LINK_SIBLING_HEADER(_hook, _hdr) \
00308    do { \
00309       struct hdr_field *_itr; \
00310       for (_itr=new_msg->_hook; _itr->sibling; _itr=_itr->sibling); \
00311       _itr->sibling = _hdr; \
00312    } while(0)
00313 
00314 
00315 struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
00316 {
00317    unsigned int      len;
00318    struct hdr_field  *hdr,*new_hdr,*last_hdr;
00319    struct via_body   *via;
00320    struct via_param  *prm;
00321    struct to_param   *to_prm,*new_to_prm;
00322    struct sip_msg    *new_msg;
00323    struct lump_rpl   *rpl_lump, **rpl_lump_anchor;
00324    char              *p;
00325 
00326 
00327    /*computing the length of entire sip_msg structure*/
00328    len = ROUND4(sizeof( struct sip_msg ));
00329    /*we will keep only the original msg +ZT */
00330    len += ROUND4(org_msg->len + 1);
00331    /*the new uri (if any)*/
00332    if (org_msg->new_uri.s && org_msg->new_uri.len)
00333       len+= ROUND4(org_msg->new_uri.len);
00334    /*all the headers*/
00335    for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
00336    {
00337       /*size of header struct*/
00338       len += ROUND4(sizeof( struct hdr_field));
00339       switch (hdr->type)
00340       {
00341          case HDR_VIA_T:
00342             for (via=(struct via_body*)hdr->parsed;via;via=via->next)
00343             {
00344                len+=ROUND4(sizeof(struct via_body));
00345                /*via param*/
00346                for(prm=via->param_lst;prm;prm=prm->next)
00347                   len+=ROUND4(sizeof(struct via_param ));
00348             }
00349             break;
00350 
00351          case HDR_TO_T:
00352          case HDR_FROM_T:
00353             /* From header might be unparsed */
00354             if (hdr->parsed) {
00355                len+=ROUND4(sizeof(struct to_body));
00356                     /*to param*/
00357                to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
00358                for(;to_prm;to_prm=to_prm->next)
00359                   len+=ROUND4(sizeof(struct to_param ));
00360             }
00361             break;
00362 
00363          case HDR_CSEQ_T:
00364             len+=ROUND4(sizeof(struct cseq_body));
00365             break;
00366 
00367          case HDR_AUTHORIZATION_T:
00368          case HDR_PROXYAUTH_T:
00369             if (hdr->parsed) {
00370                len += ROUND4(AUTH_BODY_SIZE);
00371             }
00372             break;
00373 
00374          case HDR_CALLID_T:
00375          case HDR_CONTACT_T:
00376          case HDR_MAXFORWARDS_T:
00377          case HDR_ROUTE_T:
00378          case HDR_RECORDROUTE_T:
00379          case HDR_CONTENTTYPE_T:
00380          case HDR_CONTENTLENGTH_T:
00381          case HDR_EXPIRES_T:
00382          case HDR_SUPPORTED_T:
00383          case HDR_PROXYREQUIRE_T:
00384          case HDR_UNSUPPORTED_T:
00385          case HDR_ALLOW_T:
00386          case HDR_EVENT_T:
00387          case HDR_ACCEPT_T:
00388          case HDR_ACCEPTLANGUAGE_T:
00389          case HDR_ORGANIZATION_T:
00390          case HDR_PRIORITY_T:
00391          case HDR_SUBJECT_T:
00392          case HDR_USERAGENT_T:
00393          case HDR_ACCEPTDISPOSITION_T:
00394          case HDR_CONTENTDISPOSITION_T:
00395          case HDR_DIVERSION_T:
00396          case HDR_RPID_T:
00397          case HDR_REFER_TO_T:
00398          case HDR_SESSION_EXPIRES_T:
00399          case HDR_MIN_SE_T:
00400          case HDR_PPI_T:
00401          case HDR_PAI_T:
00402          case HDR_PRIVACY_T:
00403          case HDR_RETRY_AFTER_T:
00404          case HDR_PATH_T:
00405             /* we ignore them for now even if they have something parsed*/
00406             break;
00407 
00408          default:
00409             if (hdr->parsed) {
00410                LM_WARN("header body ignored: %d\n", hdr->type );
00411             }
00412             break;
00413       }/*switch*/
00414    }/*for all headers*/
00415 
00416    /* length of the data lump structures */
00417 #define LUMP_LIST_LEN(len, list) \
00418 do { \
00419         struct lump* tmp, *chain; \
00420    chain = (list); \
00421    while (chain) \
00422    { \
00423       (len) += lump_len(chain); \
00424       tmp = chain->before; \
00425       while ( tmp ) \
00426       { \
00427          (len) += lump_len( tmp ); \
00428          tmp = tmp->before; \
00429       } \
00430       tmp = chain->after; \
00431       while ( tmp ) \
00432       { \
00433          (len) += lump_len( tmp ); \
00434          tmp = tmp->after; \
00435       } \
00436       chain = chain->next; \
00437    } \
00438 } while(0);
00439 
00440    LUMP_LIST_LEN(len, org_msg->add_rm);
00441    LUMP_LIST_LEN(len, org_msg->body_lumps);
00442    
00443    /*length of reply lump structures*/
00444    for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
00445          len+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len);
00446 
00447    p=(char *)shm_malloc(len);
00448    if (!p)
00449    {
00450       LM_ERR("no more share memory\n" );
00451       return 0;
00452    }
00453    if (sip_msg_len)
00454       *sip_msg_len = len;
00455 
00456    /* filling up the new structure */
00457    new_msg = (struct sip_msg*)p;
00458    /* sip msg structure */
00459    memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
00460 
00461    /* avoid copying pointer to un-clonned structures */
00462    new_msg->sdp = 0;
00463 
00464    new_msg->msg_flags |= FL_SHM_CLONE;
00465    p += ROUND4(sizeof(struct sip_msg));
00466    new_msg->add_rm = 0;
00467    new_msg->body_lumps = 0;
00468    /* new_uri */
00469    if (org_msg->new_uri.s && org_msg->new_uri.len)
00470    {
00471       new_msg->new_uri.s = p;
00472       memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
00473       p += ROUND4(org_msg->new_uri.len);
00474    }
00475    /* dst_uri to zero */
00476    new_msg->dst_uri.s = 0;
00477    new_msg->dst_uri.len = 0;
00478    /* path_vec to zero */
00479    new_msg->path_vec.s = 0;
00480    new_msg->path_vec.len = 0;
00481    /* message buffers(org and scratch pad) */
00482    memcpy( p , org_msg->buf, org_msg->len);
00483    /* ZT to be safer */
00484    *(p+org_msg->len)=0;
00485    new_msg->buf = p;
00486    p += ROUND4(new_msg->len+1);
00487    /* unparsed and eoh pointer */
00488    new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
00489       org_msg->unparsed );
00490    new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
00491    /* first line, updating the pointers*/
00492    if ( org_msg->first_line.type==SIP_REQUEST )
00493    {
00494       new_msg->first_line.u.request.method.s =
00495          translate_pointer( new_msg->buf , org_msg->buf ,
00496          org_msg->first_line.u.request.method.s );
00497       new_msg->first_line.u.request.uri.s =
00498          translate_pointer( new_msg->buf , org_msg->buf ,
00499          org_msg->first_line.u.request.uri.s );
00500       new_msg->first_line.u.request.version.s =
00501          translate_pointer( new_msg->buf , org_msg->buf ,
00502          org_msg->first_line.u.request.version.s );
00503       if(new_msg->parsed_orig_ruri_ok)
00504          uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
00505       if(new_msg->parsed_uri_ok)
00506          uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
00507    }
00508    else if ( org_msg->first_line.type==SIP_REPLY )
00509    {
00510       new_msg->first_line.u.reply.version.s =
00511          translate_pointer( new_msg->buf , org_msg->buf ,
00512          org_msg->first_line.u.reply.version.s );
00513       new_msg->first_line.u.reply.status.s =
00514          translate_pointer( new_msg->buf , org_msg->buf ,
00515          org_msg->first_line.u.reply.status.s );
00516       new_msg->first_line.u.reply.reason.s =
00517          translate_pointer( new_msg->buf , org_msg->buf ,
00518          org_msg->first_line.u.reply.reason.s );
00519    }
00520 
00521    /*headers list*/
00522    new_msg->via1=0;
00523    new_msg->via2=0;
00524    for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
00525    {
00526       new_hdr = (struct hdr_field*)p;
00527       memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
00528       p += ROUND4(sizeof( struct hdr_field));
00529       new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
00530          hdr->name.s);
00531       new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
00532          hdr->body.s);
00533       /* by default, we assume we don't understand this header in TM
00534          and better set it to zero; if we do, we will set a specific
00535          value in the following switch statement
00536       */
00537       new_hdr->parsed=0;
00538 
00539       new_hdr->sibling=0;
00540 
00541       switch (hdr->type)
00542       {
00543          case HDR_VIA_T:
00544             /*fprintf(stderr,"prepare to clone via |%.*s|\n",
00545                via_len((struct via_body*)hdr->parsed),
00546                via_s((struct via_body*)hdr->parsed,org_msg));*/
00547             if ( !new_msg->via1 )
00548             {
00549                new_msg->h_via1 = new_hdr;
00550                new_msg->via1 = via_body_cloner(new_msg->buf,
00551                   org_msg->buf, (struct via_body*)hdr->parsed, &p);
00552                new_hdr->parsed  = (void*)new_msg->via1;
00553                /*fprintf(stderr,"setting via1 |%.*s|\n",
00554                   via_len(new_msg->via1),
00555                   via_s(new_msg->via1,new_msg));*/
00556                if ( new_msg->via1->next )
00557                   new_msg->via2 = new_msg->via1->next;
00558             }
00559             else if ( !new_msg->via2 )
00560             {
00561                LINK_SIBLING_HEADER(h_via1, new_hdr);
00562                new_msg->h_via2 = new_hdr;
00563                new_msg->via2 = via_body_cloner( new_msg->buf,
00564                   org_msg->buf, (struct via_body*)hdr->parsed, &p);
00565                new_hdr->parsed  = (void*)new_msg->via2;
00566             }
00567             else
00568             {
00569                LINK_SIBLING_HEADER(h_via1, new_hdr);
00570                new_hdr->parsed =  
00571                   via_body_cloner( new_msg->buf , org_msg->buf ,
00572                   (struct via_body*)hdr->parsed , &p);
00573             }
00574             break;
00575          case HDR_CSEQ_T:
00576             new_hdr->parsed = p;
00577             p +=ROUND4(sizeof(struct cseq_body));
00578             memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
00579             ((struct cseq_body*)new_hdr->parsed)->number.s =
00580                translate_pointer(new_msg->buf ,org_msg->buf,
00581                ((struct cseq_body*)hdr->parsed)->number.s );
00582             ((struct cseq_body*)new_hdr->parsed)->method.s =
00583                translate_pointer(new_msg->buf ,org_msg->buf,
00584                ((struct cseq_body*)hdr->parsed)->method.s );
00585             if (HOOK_NOT_SET(cseq)) new_msg->cseq = new_hdr;
00586             break;
00587          case HDR_TO_T:
00588          case HDR_FROM_T:
00589             if (hdr->type == HDR_TO_T) {
00590                if (HOOK_NOT_SET(to)) new_msg->to = new_hdr;
00591             } else {
00592                if (HOOK_NOT_SET(from)) new_msg->from = new_hdr;
00593             }
00594             /* From header might be unparsed */
00595             if (!hdr->parsed) break;
00596             new_hdr->parsed = p;
00597             p +=ROUND4(sizeof(struct to_body));
00598             memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
00599             ((struct to_body*)new_hdr->parsed)->body.s =
00600                translate_pointer( new_msg->buf , org_msg->buf ,
00601                ((struct to_body*)hdr->parsed)->body.s );
00602             ((struct to_body*)new_hdr->parsed)->uri.s =
00603                translate_pointer( new_msg->buf , org_msg->buf ,
00604                ((struct to_body*)hdr->parsed)->uri.s );
00605             if ( ((struct to_body*)hdr->parsed)->display.s )
00606                ((struct to_body*)new_hdr->parsed)->display.s =
00607                   translate_pointer( new_msg->buf , org_msg->buf ,
00608                   ((struct to_body*)hdr->parsed)->display.s );
00609             if ( ((struct to_body*)hdr->parsed)->tag_value.s )
00610                ((struct to_body*)new_hdr->parsed)->tag_value.s =
00611                   translate_pointer( new_msg->buf , org_msg->buf ,
00612                   ((struct to_body*)hdr->parsed)->tag_value.s );
00613             if ( (((struct to_body*)new_hdr->parsed)->parsed_uri.user.s)
00614             || (((struct to_body*)new_hdr->parsed)->parsed_uri.host.s) )
00615                uri_trans(new_msg->buf, org_msg->buf,
00616                      &((struct to_body*)new_hdr->parsed)->parsed_uri);
00617 
00618             /*to params*/
00619             to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
00620             for(;to_prm;to_prm=to_prm->next)
00621             {
00622                /*alloc*/
00623                new_to_prm = (struct to_param*)p;
00624                p +=ROUND4(sizeof(struct to_param ));
00625                /*coping*/
00626                memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
00627                ((struct to_body*)new_hdr->parsed)->param_lst = 0;
00628                new_to_prm->name.s = translate_pointer( new_msg->buf,
00629                   org_msg->buf , to_prm->name.s );
00630                new_to_prm->value.s = translate_pointer( new_msg->buf,
00631                   org_msg->buf , to_prm->value.s );
00632                /*linking*/
00633                if ( !((struct to_body*)new_hdr->parsed)->param_lst )
00634                   ((struct to_body*)new_hdr->parsed)->param_lst
00635                      = new_to_prm;
00636                else
00637                   ((struct to_body*)new_hdr->parsed)->last_param->next
00638                      = new_to_prm;
00639                ((struct to_body*)new_hdr->parsed)->last_param
00640                   = new_to_prm;
00641             }
00642             break;
00643          case HDR_CALLID_T:
00644             if (HOOK_NOT_SET(callid)) {
00645                new_msg->callid = new_hdr;
00646             }
00647             break;
00648          case HDR_CONTACT_T:
00649             if (HOOK_NOT_SET(contact)) {
00650                new_msg->contact = new_hdr;
00651             } else {
00652                LINK_SIBLING_HEADER(contact, new_hdr);
00653             }
00654             break;
00655          case HDR_MAXFORWARDS_T :
00656             if (HOOK_NOT_SET(maxforwards)) {
00657                new_msg->maxforwards = new_hdr;
00658             }
00659             break;
00660          case HDR_ROUTE_T :
00661             if (HOOK_NOT_SET(route)) {
00662                new_msg->route = new_hdr;
00663             } else {
00664                LINK_SIBLING_HEADER(route, new_hdr);
00665             }
00666             break;
00667          case HDR_RECORDROUTE_T :
00668             if (HOOK_NOT_SET(record_route)) {
00669                new_msg->record_route = new_hdr;
00670             } else {
00671                LINK_SIBLING_HEADER(record_route, new_hdr);
00672             }
00673             break;
00674          case HDR_CONTENTTYPE_T :
00675             if (HOOK_NOT_SET(content_type)) {
00676                new_msg->content_type = new_hdr;
00677                new_msg->content_type->parsed = hdr->parsed;
00678             }
00679             break;
00680          case HDR_CONTENTLENGTH_T :
00681             if (HOOK_NOT_SET(content_length)) {
00682                new_msg->content_length = new_hdr;
00683                new_msg->content_length->parsed = hdr->parsed;
00684             }
00685             break;
00686          case HDR_AUTHORIZATION_T :
00687             if (HOOK_NOT_SET(authorization)) {
00688                new_msg->authorization = new_hdr;
00689             } else {
00690                LINK_SIBLING_HEADER(authorization, new_hdr);
00691             }
00692             if (hdr->parsed) {
00693                new_hdr->parsed = auth_body_cloner(new_msg->buf ,
00694                   org_msg->buf , (struct auth_body*)hdr->parsed , &p);
00695             }
00696             break;
00697          case HDR_EXPIRES_T :
00698             if (HOOK_NOT_SET(expires)) {
00699                new_msg->expires = new_hdr;
00700             }
00701             break;
00702          case HDR_PROXYAUTH_T :
00703             if (HOOK_NOT_SET(proxy_auth)) {
00704                new_msg->proxy_auth = new_hdr;
00705             } else {
00706                LINK_SIBLING_HEADER(proxy_auth, new_hdr);
00707             }
00708             if (hdr->parsed) {
00709                new_hdr->parsed = auth_body_cloner(new_msg->buf ,
00710                   org_msg->buf , (struct auth_body*)hdr->parsed , &p);
00711             }
00712             break;
00713          case HDR_SUPPORTED_T :
00714             if (HOOK_NOT_SET(supported)) {
00715                new_msg->supported = new_hdr;
00716             } else {
00717                LINK_SIBLING_HEADER(supported, new_hdr);
00718             }
00719             break;
00720          case HDR_PROXYREQUIRE_T :
00721             if (HOOK_NOT_SET(proxy_require)) {
00722                new_msg->proxy_require = new_hdr;
00723             } else {
00724                LINK_SIBLING_HEADER(proxy_require, new_hdr);
00725             }
00726             break;
00727          case HDR_UNSUPPORTED_T :
00728             if (HOOK_NOT_SET(unsupported)) {
00729                new_msg->unsupported = new_hdr;
00730             } else {
00731                LINK_SIBLING_HEADER(unsupported, new_hdr);
00732             }
00733             break;
00734          case HDR_ALLOW_T :
00735             if (HOOK_NOT_SET(allow)) {
00736                new_msg->allow = new_hdr;
00737             } else {
00738                LINK_SIBLING_HEADER(allow, new_hdr);
00739             }
00740             break;
00741          case HDR_EVENT_T:
00742             if (HOOK_NOT_SET(event)) {
00743                new_msg->event = new_hdr;
00744             } else {
00745                LINK_SIBLING_HEADER(event, new_hdr);
00746             }
00747             break;
00748          case HDR_ACCEPT_T:
00749             if (HOOK_NOT_SET(accept)) {
00750                new_msg->accept = new_hdr;
00751             } else {
00752                LINK_SIBLING_HEADER(accept, new_hdr);
00753             }
00754             break;
00755          case HDR_ACCEPTLANGUAGE_T:
00756             if (HOOK_NOT_SET(accept_language)) {
00757                new_msg->accept_language = new_hdr;
00758             } else {
00759                LINK_SIBLING_HEADER(accept_language, new_hdr);
00760             }
00761             break;
00762          case HDR_ORGANIZATION_T:
00763             if (HOOK_NOT_SET(organization)) {
00764                new_msg->organization = new_hdr;
00765             }
00766             break;
00767          case HDR_PRIORITY_T:
00768             if (HOOK_NOT_SET(priority)) {
00769                new_msg->priority = new_hdr;
00770             }
00771             break;
00772          case HDR_SUBJECT_T:
00773             if (HOOK_NOT_SET(subject)) {
00774                new_msg->subject = new_hdr;
00775             }
00776             break;
00777          case HDR_USERAGENT_T:
00778             if (HOOK_NOT_SET(user_agent)) {
00779                new_msg->user_agent = new_hdr;
00780             }
00781             break;
00782          case HDR_ACCEPTDISPOSITION_T:
00783             if (HOOK_NOT_SET(accept_disposition)) {
00784                new_msg->accept_disposition = new_hdr;
00785             } else {
00786                LINK_SIBLING_HEADER(accept_disposition, new_hdr);
00787             }
00788             break;
00789          case HDR_CONTENTDISPOSITION_T:
00790             if (HOOK_NOT_SET(content_disposition)) {
00791                new_msg->content_disposition = new_hdr;
00792             }
00793             break;
00794          case HDR_DIVERSION_T:
00795             if (HOOK_NOT_SET(diversion)) {
00796                new_msg->diversion = new_hdr;
00797             } else {
00798                LINK_SIBLING_HEADER(diversion, new_hdr);
00799             }
00800             break;
00801          case HDR_RPID_T:
00802             if (HOOK_NOT_SET(rpid)) {
00803                new_msg->rpid = new_hdr;
00804             }
00805             break;
00806          case HDR_PPI_T:
00807             if (HOOK_NOT_SET(ppi)) {
00808                new_msg->ppi = new_hdr;
00809             }
00810             break;
00811          case HDR_PAI_T:
00812             if (HOOK_NOT_SET(pai)) {
00813                new_msg->pai = new_hdr;
00814             }
00815             break;
00816          case HDR_REFER_TO_T:
00817             if (HOOK_NOT_SET(refer_to)) {
00818                new_msg->refer_to = new_hdr;
00819             }
00820             break;
00821          case HDR_PRIVACY_T:
00822             if (HOOK_NOT_SET(privacy)) {
00823                new_msg->privacy = new_hdr;
00824             }
00825             break;
00826          case HDR_SESSION_EXPIRES_T:
00827             if (HOOK_NOT_SET(session_expires)) {
00828                new_msg->session_expires = new_hdr;
00829             }
00830             break;
00831          case HDR_MIN_SE_T:
00832             if (HOOK_NOT_SET(min_se)) {
00833                new_msg->min_se = new_hdr;
00834             }
00835             break;
00836          case HDR_PATH_T:
00837             if (HOOK_NOT_SET(path)) {
00838                new_msg->path = new_hdr;
00839             } else {
00840                LINK_SIBLING_HEADER(path, new_hdr);
00841             }
00842             break;
00843          default:
00844             /* ignore the rest */
00845             ;
00846       }/*switch*/
00847 
00848       if ( last_hdr )
00849       {
00850          last_hdr->next = new_hdr;
00851          last_hdr=last_hdr->next;
00852       }
00853       else
00854       {
00855          last_hdr=new_hdr;
00856          new_msg->headers =new_hdr;
00857       }
00858       last_hdr->next = 0;
00859       new_msg->last_header = last_hdr;
00860    }
00861 
00862    /* cloning data lump */
00863 #define CLONE_LUMP_LIST(anchor, list) \
00864 do { \
00865    struct lump* lump_tmp, *l; \
00866    struct lump** lump_anchor2, **a; \
00867    a = (anchor); \
00868    l = (list); \
00869    while (l) \
00870    { \
00871       lump_clone( (*a) , l , p ); \
00872       /*before list*/ \
00873       lump_tmp = l->before; \
00874       lump_anchor2 = &((*a)->before); \
00875       while ( lump_tmp ) \
00876       { \
00877          lump_clone( (*lump_anchor2) , lump_tmp , p ); \
00878          lump_anchor2 = &((*lump_anchor2)->before); \
00879          lump_tmp = lump_tmp->before; \
00880       } \
00881       /*after list*/ \
00882       lump_tmp = l->after; \
00883       lump_anchor2 = &((*a)->after); \
00884       while ( lump_tmp ) \
00885       { \
00886          lump_clone( (*lump_anchor2) , lump_tmp , p ); \
00887          lump_anchor2 = &((*lump_anchor2)->after); \
00888          lump_tmp = lump_tmp->after; \
00889       } \
00890       a = &((*a)->next); \
00891       l = l->next; \
00892    } \
00893 } while(0)
00894 
00895    CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);
00896    CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);
00897 
00898    /*cloning reply lump structures*/
00899    rpl_lump_anchor = &(new_msg->reply_lump);
00900    for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
00901    {
00902       *(rpl_lump_anchor)=(struct lump_rpl*)p;
00903       p+=ROUND4(sizeof( struct lump_rpl ));
00904       (*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM |
00905          (rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE)));
00906       (*rpl_lump_anchor)->text.len = rpl_lump->text.len;
00907       (*rpl_lump_anchor)->text.s=p;
00908       p+=ROUND4(rpl_lump->text.len);
00909       memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len);
00910       (*rpl_lump_anchor)->next=0;
00911       rpl_lump_anchor = &((*rpl_lump_anchor)->next);
00912    }
00913 
00914    if (clone_authorized_hooks(new_msg, org_msg) < 0) {
00915       shm_free(new_msg);
00916       return 0;
00917    }
00918 
00919    return new_msg;
00920 }
00921 
00922 
00923 
00924 
00925 

Generated on Thu May 24 20:00:31 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6