Merge remote branch 'origin/sr_3.0'
[sip-router] / sip_msg_clone.c
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2009 iptelorg GmbH
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * sip_msg_clone.c - moved sip msg clone-in-shm functions from tm
20  */
21 /*
22  * History:
23  * --------
24  *  2009-07-22  initial version: functions moved from tm/sip_msg.c (andrei)
25 */
26
27 /*!
28  * \file
29  * \brief SIP-router core :: 
30  * \ingroup core
31  * Module: \ref core
32  */
33
34 #include "sip_msg_clone.h"
35
36
37 #include "dprint.h"
38 #include "mem/mem.h"
39 #include "data_lump.h"
40 #include "data_lump_rpl.h"
41 #include "ut.h"
42 #include "parser/digest/digest.h"
43 #include "parser/parse_to.h"
44 #include "atomic_ops.h"
45
46 /* rounds to the first 4 byte multiple on 32 bit archs
47  * and to the first 8 byte multiple on 64 bit archs */
48 #define ROUND4(s) \
49         (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
50
51 #define lump_len( _lump) \
52         (ROUND4(sizeof(struct lump)) +\
53         ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))
54 #define lump_clone( _new,_old,_ptr) \
55         {\
56                 (_new) = (struct lump*)(_ptr);\
57                 memcpy( (_new), (_old), sizeof(struct lump) );\
58                 (_new)->flags|=LUMPFLAG_SHMEM; \
59                 (_ptr)+=ROUND4(sizeof(struct lump));\
60                 if ( (_old)->op==LUMP_ADD) {\
61                         (_new)->u.value = (char*)(_ptr);\
62                         memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\
63                         (_ptr)+=ROUND4((_old)->len);}\
64         }
65
66 /* length of the data lump structures */
67 #define LUMP_LIST_LEN(len, list) \
68 do { \
69         struct lump* tmp, *chain; \
70         chain = (list); \
71         while (chain) \
72         { \
73                 (len) += lump_len(chain); \
74                 tmp = chain->before; \
75                 while ( tmp ) \
76                 { \
77                         (len) += lump_len( tmp ); \
78                         tmp = tmp->before; \
79                 } \
80                 tmp = chain->after; \
81                 while ( tmp ) \
82                 { \
83                         (len) += lump_len( tmp ); \
84                         tmp = tmp->after; \
85                 } \
86                 chain = chain->next; \
87         } \
88 } while(0);
89
90 /* length of the reply lump structure */
91 #define RPL_LUMP_LIST_LEN(len, list) \
92 do { \
93         struct lump_rpl* rpl_lump; \
94         for(rpl_lump=(list);rpl_lump;rpl_lump=rpl_lump->next) \
95                 (len)+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len); \
96 } while(0);
97
98 /* clones data lumps */
99 #define CLONE_LUMP_LIST(anchor, list, _ptr) \
100 do { \
101         struct lump* lump_tmp, *l; \
102         struct lump** lump_anchor2, **a; \
103         a = (anchor); \
104         l = (list); \
105         while (l) \
106         { \
107                 lump_clone( (*a) , l , (_ptr) ); \
108                 /*before list*/ \
109                 lump_tmp = l->before; \
110                 lump_anchor2 = &((*a)->before); \
111                 while ( lump_tmp ) \
112                 { \
113                         lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
114                         lump_anchor2 = &((*lump_anchor2)->before); \
115                         lump_tmp = lump_tmp->before; \
116                 } \
117                 /*after list*/ \
118                 lump_tmp = l->after; \
119                 lump_anchor2 = &((*a)->after); \
120                 while ( lump_tmp ) \
121                 { \
122                         lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
123                         lump_anchor2 = &((*lump_anchor2)->after); \
124                         lump_tmp = lump_tmp->after; \
125                 } \
126                 a = &((*a)->next); \
127                 l = l->next; \
128         } \
129 } while(0)
130
131 /* clones reply lumps */
132 #define CLONE_RPL_LUMP_LIST(anchor, list, _ptr) \
133 do { \
134         struct lump_rpl* rpl_lump; \
135         struct lump_rpl** rpl_lump_anchor; \
136         rpl_lump_anchor = (anchor); \
137         for(rpl_lump=(list);rpl_lump;rpl_lump=rpl_lump->next) \
138         { \
139                 *(rpl_lump_anchor)=(struct lump_rpl*)(_ptr); \
140                 (_ptr)+=ROUND4(sizeof( struct lump_rpl )); \
141                 (*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM | \
142                         (rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE))); \
143                 (*rpl_lump_anchor)->text.len = rpl_lump->text.len; \
144                 (*rpl_lump_anchor)->text.s=(_ptr); \
145                 (_ptr)+=ROUND4(rpl_lump->text.len); \
146                 memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len); \
147                 (*rpl_lump_anchor)->next=0; \
148                 rpl_lump_anchor = &((*rpl_lump_anchor)->next); \
149         } \
150 } while (0)
151
152
153
154 inline struct via_body* via_body_cloner( char* new_buf,
155                                         char *org_buf, struct via_body *param_org_via, char **p)
156 {
157         struct via_body *new_via;
158         struct via_body *first_via, *last_via;
159         struct via_body *org_via;
160
161         first_via = last_via = 0;
162         org_via = param_org_via;
163
164         do
165         {
166                 /* clones the via_body structure */
167                 new_via = (struct via_body*)(*p);
168                 memcpy( new_via , org_via , sizeof( struct via_body) );
169                 (*p) += ROUND4(sizeof( struct via_body ));
170
171                 /* hdr (str type) */
172                 new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);
173                 /* name (str type) */
174                 new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);
175                 /* version (str type) */
176                 new_via->version.s=
177                         translate_pointer(new_buf,org_buf,org_via->version.s);
178                 /* transport (str type) */
179                 new_via->transport.s=
180                         translate_pointer(new_buf,org_buf,org_via->transport.s);
181                 /* host (str type) */
182                 new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);
183                 /* port_str (str type) */
184                 new_via->port_str.s=
185                         translate_pointer(new_buf,org_buf,org_via->port_str.s);
186                 /* params (str type) */
187                 new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);
188                 /* transaction id */
189                 new_via->tid.s=
190                         translate_pointer(new_buf, org_buf, org_via->tid.s);
191                 /* comment (str type) */
192                 new_via->comment.s=
193                         translate_pointer(new_buf,org_buf,org_via->comment.s);
194
195                 if ( org_via->param_lst )
196                 {
197                         struct via_param *vp, *new_vp, *last_new_vp;
198                         for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
199                         {
200                                 new_vp = (struct via_param*)(*p);
201                                 memcpy( new_vp , vp , sizeof(struct via_param));
202                                 (*p) += ROUND4(sizeof(struct via_param));
203                                 new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);
204                                 new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);
205                                 new_vp->start=translate_pointer(new_buf,org_buf,vp->start);
206
207                                 /* "translate" the shortcuts */
208                                 switch(new_vp->type){
209                                         case PARAM_BRANCH:
210                                                         new_via->branch = new_vp;
211                                                         break;
212                                         case PARAM_RECEIVED:
213                                                         new_via->received = new_vp;
214                                                         break;
215                                         case PARAM_RPORT:
216                                                         new_via->rport = new_vp;
217                                                         break;
218                                         case PARAM_I:
219                                                         new_via->i = new_vp;
220                                                         break;
221                                         case PARAM_ALIAS:
222                                                         new_via->alias = new_vp;
223                                                         break;
224
225 #ifdef USE_COMP
226                                         case PARAM_COMP:
227                                                         new_via->comp = new_vp;
228                                                         break;
229 #endif
230                                 }
231
232                                 if (last_new_vp)
233                                         last_new_vp->next = new_vp;
234                                 else
235                                         new_via->param_lst = new_vp;
236
237                                 last_new_vp = new_vp;
238                                 last_new_vp->next = NULL;
239                         }
240                         new_via->last_param = new_vp;
241                 }/*end if via has params */
242
243                 if (last_via)
244                         last_via->next = new_via;
245                 else
246                         first_via = new_via;
247                 last_via = new_via;
248                 org_via = org_via->next;
249         }while(org_via);
250
251         return first_via;
252 }
253
254
255 static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
256 {
257         uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);
258         uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);
259         uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);
260         uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);
261         uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);
262         uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);
263         /* parameters */
264         uri->transport.s=translate_pointer(new_buf,org_buf,uri->transport.s);
265         uri->ttl.s=translate_pointer(new_buf,org_buf,uri->ttl.s);
266         uri->user_param.s=translate_pointer(new_buf,org_buf,uri->user_param.s);
267         uri->maddr.s=translate_pointer(new_buf,org_buf,uri->maddr.s);
268         uri->method.s=translate_pointer(new_buf,org_buf,uri->method.s);
269         uri->lr.s=translate_pointer(new_buf,org_buf,uri->lr.s);
270         uri->r2.s=translate_pointer(new_buf,org_buf,uri->r2.s);
271         /* values */
272         uri->transport_val.s
273                 =translate_pointer(new_buf,org_buf,uri->transport_val.s);
274         uri->ttl_val.s=translate_pointer(new_buf,org_buf,uri->ttl_val.s);
275         uri->user_param_val.s
276                 =translate_pointer(new_buf,org_buf,uri->user_param_val.s);
277         uri->maddr_val.s=translate_pointer(new_buf,org_buf,uri->maddr_val.s);
278         uri->method_val.s=translate_pointer(new_buf,org_buf,uri->method_val.s);
279         uri->lr_val.s=translate_pointer(new_buf,org_buf,uri->lr_val.s);
280         uri->r2_val.s=translate_pointer(new_buf,org_buf,uri->r2_val.s);
281 }
282
283
284 static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
285 {
286         struct auth_body* new_auth;
287
288         new_auth = (struct auth_body*)(*p);
289         memcpy(new_auth , auth , sizeof(struct auth_body));
290         (*p) += ROUND4(sizeof(struct auth_body));
291
292         /* authorized field must be cloned elsewhere */
293         new_auth->digest.username.whole.s =
294                 translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);
295         new_auth->digest.username.user.s =
296                 translate_pointer(new_buf, org_buf, auth->digest.username.user.s);
297         new_auth->digest.username.domain.s =
298                 translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);
299         new_auth->digest.realm.s =
300                 translate_pointer(new_buf, org_buf, auth->digest.realm.s);
301         new_auth->digest.nonce.s =
302                 translate_pointer(new_buf, org_buf, auth->digest.nonce.s);
303         new_auth->digest.uri.s =
304                 translate_pointer(new_buf, org_buf, auth->digest.uri.s);
305         new_auth->digest.response.s =
306                 translate_pointer(new_buf, org_buf, auth->digest.response.s);
307         new_auth->digest.alg.alg_str.s =
308                 translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);
309         new_auth->digest.cnonce.s =
310                 translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);
311         new_auth->digest.opaque.s =
312                 translate_pointer(new_buf, org_buf, auth->digest.opaque.s);
313         new_auth->digest.qop.qop_str.s =
314                 translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);
315         new_auth->digest.nc.s =
316                 translate_pointer(new_buf, org_buf, auth->digest.nc.s);
317         return new_auth;
318 }
319
320
321 static inline int clone_authorized_hooks(struct sip_msg* new,
322                                          struct sip_msg* old)
323 {
324         struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
325         char stop = 0;
326
327         get_authorized_cred(old->authorization, &hook1);
328         if (!hook1) stop = 1;
329
330         get_authorized_cred(old->proxy_auth, &hook2);
331         if (!hook2) stop |= 2;
332
333         ptr = old->headers;
334         new_ptr = new->headers;
335
336         while(ptr) {
337                 if (ptr == hook1) {
338                         if (!new->authorization || !new->authorization->parsed) {
339                                 LOG(L_CRIT, "BUG: Error in message cloner (authorization)\n");
340                                 return -1;
341                         }
342                         ((struct auth_body*)new->authorization->parsed)->authorized =
343                                 new_ptr;
344                         stop |= 1;
345                 }
346
347                 if (ptr == hook2) {
348                         if (!new->proxy_auth || !new->proxy_auth->parsed) {
349                                 LOG(L_CRIT, "BUG: Error in message cloner (proxy_auth)\n");
350                                 return -1;
351                         }
352                         ((struct auth_body*)new->proxy_auth->parsed)->authorized =
353                                 new_ptr;
354                         stop |= 2;
355                 }
356
357                 if (stop == 3) break;
358
359                 ptr = ptr->next;
360                 new_ptr = new_ptr->next;
361         }
362         return 0;
363 }
364
365
366 #define AUTH_BODY_SIZE sizeof(struct auth_body)
367
368 #define HOOK_SET(hook) (new_msg->hook != org_msg->hook)
369
370
371
372 /** Creates a shm clone for a sip_msg.
373  * org_msg is cloned along with most of its headers and lumps into one
374  * shm memory block (so that a shm_free() on the result will free everything)
375  * @return shm malloced sip_msg on success, 0 on error
376  * Warning: Cloner does not clone all hdr_field headers (From, To, etc.).
377  */
378 struct sip_msg*  sip_msg_shm_clone( struct sip_msg *org_msg, int *sip_msg_len,
379                                                                         int clone_lumps)
380 {
381         unsigned int      len;
382         struct hdr_field  *hdr,*new_hdr,*last_hdr;
383         struct via_body   *via;
384         struct via_param  *prm;
385         struct to_param   *to_prm,*new_to_prm;
386         struct sip_msg    *new_msg;
387         char              *p;
388
389         /*computing the length of entire sip_msg structure*/
390         len = ROUND4(sizeof( struct sip_msg ));
391         /*we will keep only the original msg +ZT */
392         len += ROUND4(org_msg->len + 1);
393         /*the new uri (if any)*/
394         if (org_msg->new_uri.s && org_msg->new_uri.len)
395                 len+= ROUND4(org_msg->new_uri.len);
396         /*the dst uri (if any)*/
397         if (org_msg->dst_uri.s && org_msg->dst_uri.len)
398                 len+= ROUND4(org_msg->dst_uri.len);
399         /*all the headers*/
400         for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
401         {
402                 /*size of header struct*/
403                 len += ROUND4(sizeof( struct hdr_field));
404                 switch (hdr->type) {
405                              /* Safely ignore auxiliary header types */
406                 case HDR_ERROR_T:
407                 case HDR_OTHER_T:
408                 case HDR_VIA2_T:
409                 case HDR_EOH_T:
410                         break;
411
412                 case HDR_VIA_T:
413                         for (via=(struct via_body*)hdr->parsed;via;via=via->next) {
414                                 len+=ROUND4(sizeof(struct via_body));
415                                      /*via param*/
416                                 for(prm=via->param_lst;prm;prm=prm->next)
417                                         len+=ROUND4(sizeof(struct via_param ));
418                         }
419                         break;
420
421                 case HDR_TO_T:
422                 case HDR_FROM_T:
423                              /* From header might be unparsed */
424                         if (hdr->parsed) {
425                                 len+=ROUND4(sizeof(struct to_body));
426                                      /*to param*/
427                                 to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
428                                 for(;to_prm;to_prm=to_prm->next)
429                                         len+=ROUND4(sizeof(struct to_param ));
430                         }
431                         break;
432
433                 case HDR_CSEQ_T:
434                         len+=ROUND4(sizeof(struct cseq_body));
435                         break;
436
437
438                 case HDR_AUTHORIZATION_T:
439                 case HDR_PROXYAUTH_T:
440                         if (hdr->parsed) {
441                                 len += ROUND4(AUTH_BODY_SIZE);
442                         }
443                         break;
444
445                 case HDR_CALLID_T:
446                 case HDR_CONTACT_T:
447                 case HDR_MAXFORWARDS_T:
448                 case HDR_ROUTE_T:
449                 case HDR_RECORDROUTE_T:
450                 case HDR_CONTENTTYPE_T:
451                 case HDR_CONTENTLENGTH_T:
452                 case HDR_RETRY_AFTER_T:
453                 case HDR_EXPIRES_T:
454                 case HDR_SUPPORTED_T:
455                 case HDR_REQUIRE_T:
456                 case HDR_PROXYREQUIRE_T:
457                 case HDR_UNSUPPORTED_T:
458                 case HDR_ALLOW_T:
459                 case HDR_EVENT_T:
460                 case HDR_ACCEPT_T:
461                 case HDR_ACCEPTLANGUAGE_T:
462                 case HDR_ORGANIZATION_T:
463                 case HDR_PRIORITY_T:
464                 case HDR_SUBJECT_T:
465                 case HDR_USERAGENT_T:
466                 case HDR_SERVER_T:
467                 case HDR_ACCEPTDISPOSITION_T:
468                 case HDR_CONTENTDISPOSITION_T:
469                 case HDR_DIVERSION_T:
470                 case HDR_RPID_T:
471                 case HDR_REFER_TO_T:
472                 case HDR_SIPIFMATCH_T:
473                 case HDR_SESSIONEXPIRES_T:
474                 case HDR_MIN_SE_T:
475                 case HDR_SUBSCRIPTION_STATE_T:
476                 case HDR_ACCEPTCONTACT_T:
477                 case HDR_ALLOWEVENTS_T:
478                 case HDR_CONTENTENCODING_T:
479                 case HDR_REFERREDBY_T:
480                 case HDR_REJECTCONTACT_T:
481                 case HDR_REQUESTDISPOSITION_T:
482                 case HDR_WWW_AUTHENTICATE_T:
483                 case HDR_PROXY_AUTHENTICATE_T:
484                 case HDR_DATE_T:
485                 case HDR_IDENTITY_T:
486                 case HDR_IDENTITY_INFO_T:
487                 case HDR_PPI_T:
488                 case HDR_PAI_T:
489                 case HDR_PATH_T:
490                 case HDR_PRIVACY_T:
491                         /* we ignore them for now even if they have something parsed*/
492                         break;
493                 }/*switch*/
494         }/*for all headers*/
495         
496         if (clone_lumps) {
497                 /* calculate the length of the data and reply lump structures */
498                 LUMP_LIST_LEN(len, org_msg->add_rm);
499                 LUMP_LIST_LEN(len, org_msg->body_lumps);
500                 RPL_LUMP_LIST_LEN(len, org_msg->reply_lump);
501         }
502         
503         p=(char *)shm_malloc(len);
504         if (!p)
505         {
506                 LOG(L_ERR , "ERROR: sip_msg_cloner: cannot allocate memory\n" );
507                 return 0;
508         }
509         if (sip_msg_len)
510                 *sip_msg_len = len;
511
512         /* filling up the new structure */
513         new_msg = (struct sip_msg*)p;
514         /* sip msg structure */
515         memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
516
517         new_msg->msg_flags |= FL_SHM_CLONE;
518         p += ROUND4(sizeof(struct sip_msg));
519         new_msg->body = 0;
520         new_msg->add_rm = 0;
521         new_msg->body_lumps = 0;
522         new_msg->reply_lump = 0;
523         /* new_uri */
524         if (org_msg->new_uri.s && org_msg->new_uri.len)
525         {
526                 new_msg->new_uri.s = p;
527                 memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
528                 p += ROUND4(org_msg->new_uri.len);
529         }
530         /* dst_uri */
531         if (org_msg->dst_uri.s && org_msg->dst_uri.len)
532         {
533                 new_msg->dst_uri.s = p;
534                 memcpy( p , org_msg->dst_uri.s , org_msg->dst_uri.len);
535                 p += ROUND4(org_msg->dst_uri.len);
536         }
537         /* path_vec is not cloned (it's reset instead) */
538         new_msg->path_vec.s=0;
539         new_msg->path_vec.len=0;
540         /* message buffers(org and scratch pad) */
541         memcpy( p , org_msg->buf, org_msg->len);
542         /* ZT to be safer */
543         *(p+org_msg->len)=0;
544         new_msg->buf = p;
545         p += ROUND4(new_msg->len+1);
546         /* unparsed and eoh pointer */
547         new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
548                 org_msg->unparsed );
549         new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
550         /* first line, updating the pointers*/
551         if ( org_msg->first_line.type==SIP_REQUEST )
552         {
553                 new_msg->first_line.u.request.method.s =
554                         translate_pointer( new_msg->buf , org_msg->buf ,
555                         org_msg->first_line.u.request.method.s );
556                 new_msg->first_line.u.request.uri.s =
557                         translate_pointer( new_msg->buf , org_msg->buf ,
558                         org_msg->first_line.u.request.uri.s );
559                 new_msg->first_line.u.request.version.s =
560                         translate_pointer( new_msg->buf , org_msg->buf ,
561                         org_msg->first_line.u.request.version.s );
562                 uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
563                 if (org_msg->new_uri.s && org_msg->new_uri.len)
564                         uri_trans(new_msg->new_uri.s, org_msg->new_uri.s,
565                                                                                         &new_msg->parsed_uri);
566                 else
567                         uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
568         }
569         else if ( org_msg->first_line.type==SIP_REPLY )
570         {
571                 new_msg->first_line.u.reply.version.s =
572                         translate_pointer( new_msg->buf , org_msg->buf ,
573                         org_msg->first_line.u.reply.version.s );
574                 new_msg->first_line.u.reply.status.s =
575                         translate_pointer( new_msg->buf , org_msg->buf ,
576                         org_msg->first_line.u.reply.status.s );
577                 new_msg->first_line.u.reply.reason.s =
578                         translate_pointer( new_msg->buf , org_msg->buf ,
579                         org_msg->first_line.u.reply.reason.s );
580         }
581
582        /*headers list*/
583        new_msg->via1=0;
584        new_msg->via2=0;
585
586         for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
587         {
588                 new_hdr = (struct hdr_field*)p;
589                 memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
590                 p += ROUND4(sizeof( struct hdr_field));
591                 new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
592                         hdr->name.s);
593                 new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
594                         hdr->body.s);
595                 /* by default, we assume we don't understand this header in TM
596                    and better set it to zero; if we do, we will set a specific
597                    value in the following switch statement
598                 */
599                 new_hdr->parsed=0;
600
601                 switch (hdr->type)
602                 {
603                              /* Ignore auxiliary header types */
604                 case HDR_ERROR_T:
605                 case HDR_OTHER_T:
606                 case HDR_VIA2_T:
607                 case HDR_EOH_T:
608                 case HDR_ACCEPTCONTACT_T:
609                 case HDR_ALLOWEVENTS_T:
610                 case HDR_CONTENTENCODING_T:
611                 case HDR_REFERREDBY_T:
612                 case HDR_REJECTCONTACT_T:
613                 case HDR_REQUESTDISPOSITION_T:
614                 case HDR_WWW_AUTHENTICATE_T:
615                 case HDR_PROXY_AUTHENTICATE_T:
616                 case HDR_DATE_T:
617                 case HDR_IDENTITY_T:
618                 case HDR_IDENTITY_INFO_T:
619                 case HDR_RETRY_AFTER_T:
620                         break;
621
622                 case HDR_VIA_T:
623                         if ( !new_msg->via1 ) {
624                                 new_msg->h_via1 = new_hdr;
625                                 new_msg->via1 = via_body_cloner(new_msg->buf,
626                                                                 org_msg->buf, (struct via_body*)hdr->parsed, &p);
627                                 new_hdr->parsed  = (void*)new_msg->via1;
628                                 if ( new_msg->via1->next ) {
629                                         new_msg->via2 = new_msg->via1->next;
630                                 }
631                         } else if ( !new_msg->via2 && new_msg->via1 ) {
632                                 new_msg->h_via2 = new_hdr;
633                                 if ( new_msg->via1->next ) {
634                                         new_hdr->parsed = (void*)new_msg->via1->next;
635                                 } else {
636                                         new_msg->via2 = via_body_cloner( new_msg->buf,
637                                                                          org_msg->buf, (struct via_body*)hdr->parsed, &p);
638                                         new_hdr->parsed  = (void*)new_msg->via2;
639                                 }
640                         } else if ( new_msg->via2 && new_msg->via1 ) {
641                                 new_hdr->parsed = via_body_cloner( new_msg->buf , org_msg->buf ,
642                                                                    (struct via_body*)hdr->parsed , &p);
643                         }
644                         break;
645                 case HDR_CSEQ_T:
646                         new_hdr->parsed = p;
647                         p +=ROUND4(sizeof(struct cseq_body));
648                         memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
649                         ((struct cseq_body*)new_hdr->parsed)->number.s =
650                                 translate_pointer(new_msg->buf ,org_msg->buf,
651                                                   ((struct cseq_body*)hdr->parsed)->number.s );
652                         ((struct cseq_body*)new_hdr->parsed)->method.s =
653                                 translate_pointer(new_msg->buf ,org_msg->buf,
654                                                   ((struct cseq_body*)hdr->parsed)->method.s );
655                         if (!HOOK_SET(cseq)) new_msg->cseq = new_hdr;
656                         break;
657                 case HDR_TO_T:
658                 case HDR_FROM_T:
659                         if (hdr->type == HDR_TO_T) {
660                                 if (!HOOK_SET(to)) new_msg->to = new_hdr;
661                         } else {
662                                 if (!HOOK_SET(from)) new_msg->from = new_hdr;
663                         }
664                              /* From header might be unparsed */
665                         if (!hdr->parsed) break;
666                         new_hdr->parsed = p;
667                         p +=ROUND4(sizeof(struct to_body));
668                         memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
669                         ((struct to_body*)new_hdr->parsed)->body.s =
670                                 translate_pointer( new_msg->buf , org_msg->buf ,
671                                                    ((struct to_body*)hdr->parsed)->body.s );
672                         ((struct to_body*)new_hdr->parsed)->display.s =
673                                 translate_pointer( new_msg->buf, org_msg->buf,
674                                                    ((struct to_body*)hdr->parsed)->display.s);
675                         ((struct to_body*)new_hdr->parsed)->uri.s =
676                                 translate_pointer( new_msg->buf , org_msg->buf ,
677                                                    ((struct to_body*)hdr->parsed)->uri.s );
678                         if ( ((struct to_body*)hdr->parsed)->tag_value.s )
679                                 ((struct to_body*)new_hdr->parsed)->tag_value.s =
680                                         translate_pointer( new_msg->buf , org_msg->buf ,
681                                                            ((struct to_body*)hdr->parsed)->tag_value.s );
682                         if ( (((struct to_body*)new_hdr->parsed)->parsed_uri.user.s)
683                                 || (((struct to_body*)new_hdr->parsed)->parsed_uri.host.s) )
684                                         uri_trans(new_msg->buf, org_msg->buf,
685                                                         &((struct to_body*)new_hdr->parsed)->parsed_uri);
686                              /*to params*/
687                         to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
688                         for(;to_prm;to_prm=to_prm->next) {
689                                      /*alloc*/
690                                 new_to_prm = (struct to_param*)p;
691                                 p +=ROUND4(sizeof(struct to_param ));
692                                      /*coping*/
693                                 memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
694                                 ((struct to_body*)new_hdr->parsed)->param_lst = 0;
695                                 new_to_prm->name.s = translate_pointer( new_msg->buf,
696                                                                         org_msg->buf , to_prm->name.s );
697                                 new_to_prm->value.s = translate_pointer( new_msg->buf,
698                                                                          org_msg->buf , to_prm->value.s );
699                                      /*linking*/
700                                 if ( !((struct to_body*)new_hdr->parsed)->param_lst )
701                                         ((struct to_body*)new_hdr->parsed)->param_lst
702                                                 = new_to_prm;
703                                 else
704                                         ((struct to_body*)new_hdr->parsed)->last_param->next
705                                                 = new_to_prm;
706                                 ((struct to_body*)new_hdr->parsed)->last_param
707                                         = new_to_prm;
708                         }
709                         break;
710                 case HDR_CALLID_T:
711                         if (!HOOK_SET(callid)) {
712                                 new_msg->callid = new_hdr;
713                         }
714                         break;
715                 case HDR_CONTACT_T:
716                         if (!HOOK_SET(contact)) {
717                                 new_msg->contact = new_hdr;
718                         }
719                         break;
720                 case HDR_MAXFORWARDS_T:
721                         if (!HOOK_SET(maxforwards)) {
722                                 new_msg->maxforwards = new_hdr;
723                         }
724                         break;
725                 case HDR_ROUTE_T:
726                         if (!HOOK_SET(route)) {
727                                 new_msg->route = new_hdr;
728                         }
729                         break;
730                 case HDR_RECORDROUTE_T:
731                         if (!HOOK_SET(record_route)) {
732                                 new_msg->record_route = new_hdr;
733                         }
734                         break;
735                 case HDR_CONTENTTYPE_T:
736                         if (!HOOK_SET(content_type)) {
737                                 new_msg->content_type = new_hdr;
738                                 new_msg->content_type->parsed = hdr->parsed;
739                         }
740                         break;
741                 case HDR_CONTENTLENGTH_T:
742                         if (!HOOK_SET(content_length)) {
743                                 new_msg->content_length = new_hdr;
744                                 new_msg->content_length->parsed = hdr->parsed;
745                         }
746                         break;
747                 case HDR_AUTHORIZATION_T:
748                         if (!HOOK_SET(authorization)) {
749                                 new_msg->authorization = new_hdr;
750                         }
751                         if (hdr->parsed) {
752                                 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
753                                                                    org_msg->buf , (struct auth_body*)hdr->parsed , &p);
754                         }
755                         break;
756                 case HDR_EXPIRES_T:
757                         if (!HOOK_SET(expires)) {
758                                 new_msg->expires = new_hdr;
759                         }
760                         break;
761                 case HDR_PROXYAUTH_T:
762                         if (!HOOK_SET(proxy_auth)) {
763                                 new_msg->proxy_auth = new_hdr;
764                         }
765                         if (hdr->parsed) {
766                                 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
767                                                                    org_msg->buf , (struct auth_body*)hdr->parsed , &p);
768                         }
769                         break;
770                 case HDR_SUPPORTED_T:
771                         if (!HOOK_SET(supported)) {
772                                 new_msg->supported = new_hdr;
773                         }
774                         break;
775                 case HDR_REQUIRE_T:
776                         if (!HOOK_SET(require)) {
777                                 new_msg->require = new_hdr;
778                         }
779                         break;
780                 case HDR_PROXYREQUIRE_T:
781                         if (!HOOK_SET(proxy_require)) {
782                                 new_msg->proxy_require = new_hdr;
783                         }
784                         break;
785                 case HDR_UNSUPPORTED_T:
786                         if (!HOOK_SET(unsupported)) {
787                                 new_msg->unsupported = new_hdr;
788                         }
789                         break;
790                 case HDR_ALLOW_T:
791                         if (!HOOK_SET(allow)) {
792                                 new_msg->allow = new_hdr;
793                         }
794                         break;
795                 case HDR_EVENT_T:
796                         if (!HOOK_SET(event)) {
797                                 new_msg->event = new_hdr;
798                         }
799                         break;
800                 case HDR_ACCEPT_T:
801                         if (!HOOK_SET(accept)) {
802                                 new_msg->accept = new_hdr;
803                         }
804                         break;
805                 case HDR_ACCEPTLANGUAGE_T:
806                         if (!HOOK_SET(accept_language)) {
807                                 new_msg->accept_language = new_hdr;
808                         }
809                         break;
810                 case HDR_ORGANIZATION_T:
811                         if (!HOOK_SET(organization)) {
812                                 new_msg->organization = new_hdr;
813                         }
814                         break;
815                 case HDR_PRIORITY_T:
816                         if (!HOOK_SET(priority)) {
817                                 new_msg->priority = new_hdr;
818                         }
819                         break;
820                 case HDR_SUBJECT_T:
821                         if (!HOOK_SET(subject)) {
822                                 new_msg->subject = new_hdr;
823                         }
824                         break;
825                 case HDR_USERAGENT_T:
826                         if (!HOOK_SET(user_agent)) {
827                                 new_msg->user_agent = new_hdr;
828                         }
829                         break;
830                 case HDR_SERVER_T:
831                         if (!HOOK_SET(server)) {
832                                 new_msg->server = new_hdr;
833                         }
834                         break;
835                 case HDR_ACCEPTDISPOSITION_T:
836                         if (!HOOK_SET(accept_disposition)) {
837                                 new_msg->accept_disposition = new_hdr;
838                         }
839                         break;
840                 case HDR_CONTENTDISPOSITION_T:
841                         if (!HOOK_SET(content_disposition)) {
842                                 new_msg->content_disposition = new_hdr;
843                         }
844                         break;
845                 case HDR_DIVERSION_T:
846                         if (!HOOK_SET(diversion)) {
847                                 new_msg->diversion = new_hdr;
848                         }
849                         break;
850                 case HDR_RPID_T:
851                         if (!HOOK_SET(rpid)) {
852                                 new_msg->rpid = new_hdr;
853                         }
854                         break;
855                 case HDR_REFER_TO_T:
856                         if (!HOOK_SET(refer_to)) {
857                                 new_msg->refer_to = new_hdr;
858                         }
859                         break;
860                 case HDR_SESSIONEXPIRES_T:
861                         if (!HOOK_SET(session_expires)) {
862                                 new_msg->session_expires = new_hdr;
863                         }
864                         break;
865                 case HDR_MIN_SE_T:
866                         if (!HOOK_SET(min_se)) {
867                                 new_msg->min_se = new_hdr;
868                         }
869                         break;
870                 case HDR_SUBSCRIPTION_STATE_T:
871                         if (!HOOK_SET(subscription_state)) {
872                                 new_msg->subscription_state = new_hdr;
873                         }
874                         break;
875                 case HDR_SIPIFMATCH_T:
876                         if (!HOOK_SET(sipifmatch)) {
877                                 new_msg->sipifmatch = new_hdr;
878                         }
879                         break;
880                 case HDR_PPI_T:
881                         if (!HOOK_SET(ppi)) {
882                                 new_msg->ppi = new_hdr;
883                         }
884                         break;
885                 case HDR_PAI_T:
886                         if (!HOOK_SET(pai)) {
887                                 new_msg->pai = new_hdr;
888                         }
889                         break;
890                 case HDR_PATH_T:
891                         if (!HOOK_SET(path)) {
892                                 new_msg->path = new_hdr;
893                         }
894                         break;
895                 case HDR_PRIVACY_T:
896                         if (!HOOK_SET(privacy)) {
897                                 new_msg->privacy = new_hdr;
898                         }
899                         break;
900                 }/*switch*/
901
902                 if ( last_hdr )
903                 {
904                         last_hdr->next = new_hdr;
905                         last_hdr=last_hdr->next;
906                 }
907                 else
908                 {
909                         last_hdr=new_hdr;
910                         new_msg->headers =new_hdr;
911                 }
912                 last_hdr->next = 0;
913                 new_msg->last_header = last_hdr;
914         }
915         if (clone_lumps) {
916                 /*cloning data and reply lump structures*/
917                 CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm, p);
918                 CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps, p);
919                 CLONE_RPL_LUMP_LIST(&(new_msg->reply_lump), org_msg->reply_lump, p);
920         }
921         
922         if (clone_authorized_hooks(new_msg, org_msg) < 0) {
923                 shm_free(new_msg);
924                 return 0;
925         }
926
927         return new_msg;
928 }
929
930
931
932 /** clones the data and reply lumps from pkg_msg to shm_msg.
933  * A new memory block is allocated for the lumps (the lumps will point
934  * into it).
935  * Note: the new memory block is linked to add_rm if
936  * at least one data lump is set, else it is linked to body_lumps
937  * if at least one body lump is set, otherwise it is linked to
938  * shm_msg->reply_lump.
939  * @param pkg_msg - sip msg whoes lumps will be cloned
940  * @param add_rm - result parameter, filled with the list of cloned
941  *                 add_rm lumps (corresp. to msg->add_rm)
942  * @param body_lumps - result parameter, filled with the list of cloned
943  *                 body lumps (corresp. to msg->body_lumps)
944  * @param reply_lump - result parameter, filled with the list of cloned
945  *                 reply lumps (corresp. to msg->reply_lump)
946  * @return 0 or 1 on success: 0 - lumps cloned), 1 - nothing to do and 
947  *         -1 on error
948  */
949 int msg_lump_cloner(struct sip_msg *pkg_msg,
950                                         struct lump** add_rm,
951                                         struct lump** body_lumps,
952                                         struct lump_rpl** reply_lump)
953 {
954         unsigned int    len;
955         char            *p;
956
957         *add_rm = *body_lumps = 0;
958         *reply_lump = 0;
959
960         /* calculate the length of the lumps */
961         len = 0;
962         LUMP_LIST_LEN(len, pkg_msg->add_rm);
963         LUMP_LIST_LEN(len, pkg_msg->body_lumps);
964         RPL_LUMP_LIST_LEN(len, pkg_msg->reply_lump);
965
966         if (!len)
967                 return 1; /* nothing to do */
968
969         p=(char *)shm_malloc(len);
970         if (!p)
971         {
972                 LOG(L_ERR, "ERROR: msg_lump_cloner: cannot allocate memory\n" );
973                 return -1;
974         }
975
976         /* clone the lumps */
977         CLONE_LUMP_LIST(add_rm, pkg_msg->add_rm, p);
978         CLONE_LUMP_LIST(body_lumps, pkg_msg->body_lumps, p);
979         CLONE_RPL_LUMP_LIST(reply_lump, pkg_msg->reply_lump, p);
980
981         return 0;
982 }
983
984
985
986 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */