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