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