9b05a1fbe7dac18936c5be346694f3f652792bcf
[sip-router] / modules / tm / sip_msg.c
1 /*
2  * $Id$
3  *
4  * cloning a message into shared memory (TM keeps a snapshot
5  * of messages in memory); note that many operations, which
6  * allocate pkg memory (such as parsing) cannot be used with
7  * a cloned message -- it would result in linking pkg structures
8  * to shmem msg and eventually in a memory error
9  *
10  * the cloned message is stored in a single memory fragment to
11  * save too many shm_mallocs -- these are expensive as they
12  * not only take lookup in fragment table but also a shmem lock
13  * operation (the same for shm_free)
14  *
15  * Copyright (C) 2001-2003 FhG Fokus
16  *
17  * This file is part of ser, a free SIP server.
18  *
19  * ser is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2 of the License, or
22  * (at your option) any later version
23  *
24  * For a license to use the ser software under conditions
25  * other than those described here, or to purchase support for this
26  * software, please contact iptel.org by e-mail at the following addresses:
27  *    info@iptel.org
28  *
29  * ser is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  * GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License
35  * along with this program; if not, write to the Free Software
36  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
37  *
38  * History:
39  * --------
40  *  2003-01-23 - msg_cloner clones msg->from->parsed too (janakj)
41  *  2003-01-29 - scratchpad removed (jiri)
42  *  2003-02-25 - auth_body cloner added (janakj)
43  *  2003-02-28  scratchpad compatibility abandoned (jiri)
44  *  2003-03-31  removed msg->repl_add_rm (andrei)
45  *  2003-04-04  parsed uris are recalculated on cloning (jiri)
46  *  2003-05-07  received, rport & i via shortcuts are also translated (andrei)
47  *  2003-11-11  updated cloning of lump_rpl (bogdan)
48  *  2004-03-31  alias shortcuts are also translated (andrei)
49  *  2006-04-20  via->comp is also translated (andrei)
50  *  2006-10-16  HDR_{PROXY,WWW}_AUTHENTICATE_T cloned (andrei)
51  *  2007-01-26  HDR_DATE_T, HDR_IDENTITY_T, HDR_IDENTITY_INFO_T added (gergo)
52  */
53
54 #include "defs.h"
55
56
57 #include <stdio.h>
58 #include "sip_msg.h"
59 #include "../../dprint.h"
60 #include "../../mem/mem.h"
61 #include "../../data_lump.h"
62 #include "../../data_lump_rpl.h"
63 #include "../../ut.h"
64 #include "../../parser/digest/digest.h"
65
66
67 /* rounds to the first 4 byte multiple on 32 bit archs
68  * and to the first 8 byte multiple on 64 bit archs */
69 #define ROUND4(s) \
70         (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
71
72 #define lump_len( _lump) \
73         (ROUND4(sizeof(struct lump)) +\
74         ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))
75 #define lump_clone( _new,_old,_ptr) \
76         {\
77                 (_new) = (struct lump*)(_ptr);\
78                 memcpy( (_new), (_old), sizeof(struct lump) );\
79                 (_new)->flags|=LUMPFLAG_SHMEM; \
80                 (_ptr)+=ROUND4(sizeof(struct lump));\
81                 if ( (_old)->op==LUMP_ADD) {\
82                         (_new)->u.value = (char*)(_ptr);\
83                         memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\
84                         (_ptr)+=ROUND4((_old)->len);}\
85         }
86
87
88
89
90 inline struct via_body* via_body_cloner( char* new_buf,
91                                         char *org_buf, struct via_body *param_org_via, char **p)
92 {
93         struct via_body *new_via;
94         struct via_body *first_via, *last_via;
95         struct via_body *org_via;
96
97         first_via = last_via = 0;
98         org_via = param_org_via;
99
100         do
101         {
102                 /* clones the via_body structure */
103                 new_via = (struct via_body*)(*p);
104                 memcpy( new_via , org_via , sizeof( struct via_body) );
105                 (*p) += ROUND4(sizeof( struct via_body ));
106
107                 /* hdr (str type) */
108                 new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);
109                 /* name (str type) */
110                 new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);
111                 /* version (str type) */
112                 new_via->version.s=
113                         translate_pointer(new_buf,org_buf,org_via->version.s);
114                 /* transport (str type) */
115                 new_via->transport.s=
116                         translate_pointer(new_buf,org_buf,org_via->transport.s);
117                 /* host (str type) */
118                 new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);
119                 /* port_str (str type) */
120                 new_via->port_str.s=
121                         translate_pointer(new_buf,org_buf,org_via->port_str.s);
122                 /* params (str type) */
123                 new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);
124                 /* transaction id */
125                 new_via->tid.s=
126                         translate_pointer(new_buf, org_buf, org_via->tid.s);
127                 /* comment (str type) */
128                 new_via->comment.s=
129                         translate_pointer(new_buf,org_buf,org_via->comment.s);
130
131                 if ( org_via->param_lst )
132                 {
133                         struct via_param *vp, *new_vp, *last_new_vp;
134                         for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
135                         {
136                                 new_vp = (struct via_param*)(*p);
137                                 memcpy( new_vp , vp , sizeof(struct via_param));
138                                 (*p) += ROUND4(sizeof(struct via_param));
139                                 new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);
140                                 new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);
141                                 new_vp->start=translate_pointer(new_buf,org_buf,vp->start);
142
143                                 /* "translate" the shortcuts */
144                                 switch(new_vp->type){
145                                         case PARAM_BRANCH:
146                                                         new_via->branch = new_vp;
147                                                         break;
148                                         case PARAM_RECEIVED:
149                                                         new_via->received = new_vp;
150                                                         break;
151                                         case PARAM_RPORT:
152                                                         new_via->rport = new_vp;
153                                                         break;
154                                         case PARAM_I:
155                                                         new_via->i = new_vp;
156                                                         break;
157                                         case PARAM_ALIAS:
158                                                         new_via->alias = new_vp;
159                                                         break;
160
161 #ifdef USE_COMP
162                                         case PARAM_COMP:
163                                                         new_via->comp = new_vp;
164                                                         break;
165 #endif
166                                 }
167
168                                 if (last_new_vp)
169                                         last_new_vp->next = new_vp;
170                                 else
171                                         new_via->param_lst = new_vp;
172
173                                 last_new_vp = new_vp;
174                                 last_new_vp->next = NULL;
175                         }
176                         new_via->last_param = new_vp;
177                 }/*end if via has params */
178
179                 if (last_via)
180                         last_via->next = new_via;
181                 else
182                         first_via = new_via;
183                 last_via = new_via;
184                 org_via = org_via->next;
185         }while(org_via);
186
187         return first_via;
188 }
189
190
191 static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
192 {
193         uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);
194         uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);
195         uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);
196         uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);
197         uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);
198         uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);
199 }
200
201
202 static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
203 {
204         struct auth_body* new_auth;
205
206         new_auth = (struct auth_body*)(*p);
207         memcpy(new_auth , auth , sizeof(struct auth_body));
208         (*p) += ROUND4(sizeof(struct auth_body));
209
210         /* authorized field must be cloned elsewhere */
211         new_auth->digest.username.whole.s =
212                 translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);
213         new_auth->digest.username.user.s =
214                 translate_pointer(new_buf, org_buf, auth->digest.username.user.s);
215         new_auth->digest.username.domain.s =
216                 translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);
217         new_auth->digest.realm.s =
218                 translate_pointer(new_buf, org_buf, auth->digest.realm.s);
219         new_auth->digest.nonce.s =
220                 translate_pointer(new_buf, org_buf, auth->digest.nonce.s);
221         new_auth->digest.uri.s =
222                 translate_pointer(new_buf, org_buf, auth->digest.uri.s);
223         new_auth->digest.response.s =
224                 translate_pointer(new_buf, org_buf, auth->digest.response.s);
225         new_auth->digest.alg.alg_str.s =
226                 translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);
227         new_auth->digest.cnonce.s =
228                 translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);
229         new_auth->digest.opaque.s =
230                 translate_pointer(new_buf, org_buf, auth->digest.opaque.s);
231         new_auth->digest.qop.qop_str.s =
232                 translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);
233         new_auth->digest.nc.s =
234                 translate_pointer(new_buf, org_buf, auth->digest.nc.s);
235         return new_auth;
236 }
237
238
239 static inline int clone_authorized_hooks(struct sip_msg* new,
240                                          struct sip_msg* old)
241 {
242         struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
243         char stop = 0;
244
245         get_authorized_cred(old->authorization, &hook1);
246         if (!hook1) stop = 1;
247
248         get_authorized_cred(old->proxy_auth, &hook2);
249         if (!hook2) stop |= 2;
250
251         ptr = old->headers;
252         new_ptr = new->headers;
253
254         while(ptr) {
255                 if (ptr == hook1) {
256                         if (!new->authorization || !new->authorization->parsed) {
257                                 LOG(L_CRIT, "BUG: Error in message cloner (authorization)\n");
258                                 return -1;
259                         }
260                         ((struct auth_body*)new->authorization->parsed)->authorized =
261                                 new_ptr;
262                         stop |= 1;
263                 }
264
265                 if (ptr == hook2) {
266                         if (!new->proxy_auth || !new->proxy_auth->parsed) {
267                                 LOG(L_CRIT, "BUG: Error in message cloner (proxy_auth)\n");
268                                 return -1;
269                         }
270                         ((struct auth_body*)new->proxy_auth->parsed)->authorized =
271                                 new_ptr;
272                         stop |= 2;
273                 }
274
275                 if (stop == 3) break;
276
277                 ptr = ptr->next;
278                 new_ptr = new_ptr->next;
279         }
280         return 0;
281 }
282
283
284 #define AUTH_BODY_SIZE sizeof(struct auth_body)
285
286 #define HOOK_SET(hook) (new_msg->hook != org_msg->hook)
287
288 /* Warning: Cloner does not clone all hdr_field headers (From, To, etc.). Pointers will reference pkg memory. Dereferencing will crash ser!!! */
289
290 struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
291 {
292         unsigned int      len;
293         struct hdr_field  *hdr,*new_hdr,*last_hdr;
294         struct via_body   *via;
295         struct via_param  *prm;
296         struct to_param   *to_prm,*new_to_prm;
297         struct sip_msg    *new_msg;
298         struct lump_rpl   *rpl_lump, **rpl_lump_anchor;
299         char              *p;
300
301         /*computing the length of entire sip_msg structure*/
302         len = ROUND4(sizeof( struct sip_msg ));
303         /*we will keep only the original msg +ZT */
304         len += ROUND4(org_msg->len + 1);
305         /*the new uri (if any)*/
306         if (org_msg->new_uri.s && org_msg->new_uri.len)
307                 len+= ROUND4(org_msg->new_uri.len);
308         /*the dst uri (if any)*/
309         if (org_msg->dst_uri.s && org_msg->dst_uri.len)
310                 len+= ROUND4(org_msg->dst_uri.len);
311         /*all the headers*/
312         for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
313         {
314                 /*size of header struct*/
315                 len += ROUND4(sizeof( struct hdr_field));
316                 switch (hdr->type) {
317                              /* Safely ignore auxiliary header types */
318                 case HDR_ERROR_T:
319                 case HDR_OTHER_T:
320                 case HDR_VIA2_T:
321                 case HDR_EOH_T:
322                         break;
323
324                 case HDR_VIA_T:
325                         for (via=(struct via_body*)hdr->parsed;via;via=via->next) {
326                                 len+=ROUND4(sizeof(struct via_body));
327                                      /*via param*/
328                                 for(prm=via->param_lst;prm;prm=prm->next)
329                                         len+=ROUND4(sizeof(struct via_param ));
330                         }
331                         break;
332
333                 case HDR_TO_T:
334                 case HDR_FROM_T:
335                              /* From header might be unparsed */
336                         if (hdr->parsed) {
337                                 len+=ROUND4(sizeof(struct to_body));
338                                      /*to param*/
339                                 to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
340                                 for(;to_prm;to_prm=to_prm->next)
341                                         len+=ROUND4(sizeof(struct to_param ));
342                         }
343                         break;
344
345                 case HDR_CSEQ_T:
346                         len+=ROUND4(sizeof(struct cseq_body));
347                         break;
348
349
350                 case HDR_AUTHORIZATION_T:
351                 case HDR_PROXYAUTH_T:
352                         if (hdr->parsed) {
353                                 len += ROUND4(AUTH_BODY_SIZE);
354                         }
355                         break;
356
357                 case HDR_CALLID_T:
358                 case HDR_CONTACT_T:
359                 case HDR_MAXFORWARDS_T:
360                 case HDR_ROUTE_T:
361                 case HDR_RECORDROUTE_T:
362                 case HDR_CONTENTTYPE_T:
363                 case HDR_CONTENTLENGTH_T:
364                 case HDR_RETRY_AFTER_T:
365                 case HDR_EXPIRES_T:
366                 case HDR_SUPPORTED_T:
367                 case HDR_REQUIRE_T:
368                 case HDR_PROXYREQUIRE_T:
369                 case HDR_UNSUPPORTED_T:
370                 case HDR_ALLOW_T:
371                 case HDR_EVENT_T:
372                 case HDR_ACCEPT_T:
373                 case HDR_ACCEPTLANGUAGE_T:
374                 case HDR_ORGANIZATION_T:
375                 case HDR_PRIORITY_T:
376                 case HDR_SUBJECT_T:
377                 case HDR_USERAGENT_T:
378                 case HDR_SERVER_T:
379                 case HDR_ACCEPTDISPOSITION_T:
380                 case HDR_CONTENTDISPOSITION_T:
381                 case HDR_DIVERSION_T:
382                 case HDR_RPID_T:
383                 case HDR_REFER_TO_T:
384                 case HDR_SIPIFMATCH_T:
385                 case HDR_SESSIONEXPIRES_T:
386                 case HDR_MIN_SE_T:
387                 case HDR_SUBSCRIPTION_STATE_T:
388                 case HDR_ACCEPTCONTACT_T:
389                 case HDR_ALLOWEVENTS_T:
390                 case HDR_CONTENTENCODING_T:
391                 case HDR_REFERREDBY_T:
392                 case HDR_REJECTCONTACT_T:
393                 case HDR_REQUESTDISPOSITION_T:
394                 case HDR_WWW_AUTHENTICATE_T:
395                 case HDR_PROXY_AUTHENTICATE_T:
396                 case HDR_DATE_T:
397                 case HDR_IDENTITY_T:
398                 case HDR_IDENTITY_INFO_T:
399                         /* we ignore them for now even if they have something parsed*/
400                         break;
401                 }/*switch*/
402         }/*for all headers*/
403
404         /* length of the data lump structures */
405 #define LUMP_LIST_LEN(len, list) \
406 do { \
407         struct lump* tmp, *chain; \
408         chain = (list); \
409         while (chain) \
410         { \
411                 (len) += lump_len(chain); \
412                 tmp = chain->before; \
413                 while ( tmp ) \
414                 { \
415                         (len) += lump_len( tmp ); \
416                         tmp = tmp->before; \
417                 } \
418                 tmp = chain->after; \
419                 while ( tmp ) \
420                 { \
421                         (len) += lump_len( tmp ); \
422                         tmp = tmp->after; \
423                 } \
424                 chain = chain->next; \
425         } \
426 } while(0);
427
428         LUMP_LIST_LEN(len, org_msg->add_rm);
429         LUMP_LIST_LEN(len, org_msg->body_lumps);
430
431         /*length of reply lump structures*/
432         for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
433                         len+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len);
434
435         p=(char *)shm_malloc(len);
436         if (!p)
437         {
438                 LOG(L_ERR , "ERROR: sip_msg_cloner: cannot allocate memory\n" );
439                 return 0;
440         }
441         if (sip_msg_len)
442                 *sip_msg_len = len;
443
444         /* filling up the new structure */
445         new_msg = (struct sip_msg*)p;
446         /* sip msg structure */
447         memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
448
449         new_msg->msg_flags |= FL_SHM_CLONE;
450         p += ROUND4(sizeof(struct sip_msg));
451         new_msg->add_rm = 0;
452         new_msg->body_lumps = 0;
453         /* new_uri */
454         if (org_msg->new_uri.s && org_msg->new_uri.len)
455         {
456                 new_msg->new_uri.s = p;
457                 memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
458                 p += ROUND4(org_msg->new_uri.len);
459         }
460         /* dst_uri */
461         if (org_msg->dst_uri.s && org_msg->dst_uri.len)
462         {
463                 new_msg->dst_uri.s = p;
464                 memcpy( p , org_msg->dst_uri.s , org_msg->dst_uri.len);
465                 p += ROUND4(org_msg->dst_uri.len);
466         }
467         /* message buffers(org and scratch pad) */
468         memcpy( p , org_msg->buf, org_msg->len);
469         /* ZT to be safer */
470         *(p+org_msg->len)=0;
471         new_msg->buf = p;
472         p += ROUND4(new_msg->len+1);
473         /* unparsed and eoh pointer */
474         new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
475                 org_msg->unparsed );
476         new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
477         /* first line, updating the pointers*/
478         if ( org_msg->first_line.type==SIP_REQUEST )
479         {
480                 new_msg->first_line.u.request.method.s =
481                         translate_pointer( new_msg->buf , org_msg->buf ,
482                         org_msg->first_line.u.request.method.s );
483                 new_msg->first_line.u.request.uri.s =
484                         translate_pointer( new_msg->buf , org_msg->buf ,
485                         org_msg->first_line.u.request.uri.s );
486                 new_msg->first_line.u.request.version.s =
487                         translate_pointer( new_msg->buf , org_msg->buf ,
488                         org_msg->first_line.u.request.version.s );
489                 uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
490                 if (org_msg->new_uri.s && org_msg->new_uri.len)
491                         uri_trans(new_msg->new_uri.s, org_msg->new_uri.s,
492                                                                                         &new_msg->parsed_uri);
493                 else
494                         uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
495         }
496         else if ( org_msg->first_line.type==SIP_REPLY )
497         {
498                 new_msg->first_line.u.reply.version.s =
499                         translate_pointer( new_msg->buf , org_msg->buf ,
500                         org_msg->first_line.u.reply.version.s );
501                 new_msg->first_line.u.reply.status.s =
502                         translate_pointer( new_msg->buf , org_msg->buf ,
503                         org_msg->first_line.u.reply.status.s );
504                 new_msg->first_line.u.reply.reason.s =
505                         translate_pointer( new_msg->buf , org_msg->buf ,
506                         org_msg->first_line.u.reply.reason.s );
507         }
508
509        /*headers list*/
510        new_msg->via1=0;
511        new_msg->via2=0;
512
513         for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
514         {
515                 new_hdr = (struct hdr_field*)p;
516                 memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
517                 p += ROUND4(sizeof( struct hdr_field));
518                 new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
519                         hdr->name.s);
520                 new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
521                         hdr->body.s);
522                 /* by default, we assume we don't understand this header in TM
523                    and better set it to zero; if we do, we will set a specific
524                    value in the following switch statement
525                 */
526                 new_hdr->parsed=0;
527
528                 switch (hdr->type)
529                 {
530                              /* Ignore auxiliary header types */
531                 case HDR_ERROR_T:
532                 case HDR_OTHER_T:
533                 case HDR_VIA2_T:
534                 case HDR_EOH_T:
535                 case HDR_ACCEPTCONTACT_T:
536                 case HDR_ALLOWEVENTS_T:
537                 case HDR_CONTENTENCODING_T:
538                 case HDR_REFERREDBY_T:
539                 case HDR_REJECTCONTACT_T:
540                 case HDR_REQUESTDISPOSITION_T:
541                 case HDR_WWW_AUTHENTICATE_T:
542                 case HDR_PROXY_AUTHENTICATE_T:
543                 case HDR_DATE_T:
544                 case HDR_IDENTITY_T:
545                 case HDR_IDENTITY_INFO_T:
546                 case HDR_RETRY_AFTER_T:
547                         break;
548
549                 case HDR_VIA_T:
550                         if ( !new_msg->via1 ) {
551                                 new_msg->h_via1 = new_hdr;
552                                 new_msg->via1 = via_body_cloner(new_msg->buf,
553                                                                 org_msg->buf, (struct via_body*)hdr->parsed, &p);
554                                 new_hdr->parsed  = (void*)new_msg->via1;
555                                 if ( new_msg->via1->next ) {
556                                         new_msg->via2 = new_msg->via1->next;
557                                 }
558                         } else if ( !new_msg->via2 && new_msg->via1 ) {
559                                 new_msg->h_via2 = new_hdr;
560                                 if ( new_msg->via1->next ) {
561                                         new_hdr->parsed = (void*)new_msg->via1->next;
562                                 } else {
563                                         new_msg->via2 = via_body_cloner( new_msg->buf,
564                                                                          org_msg->buf, (struct via_body*)hdr->parsed, &p);
565                                         new_hdr->parsed  = (void*)new_msg->via2;
566                                 }
567                         } else if ( new_msg->via2 && new_msg->via1 ) {
568                                 new_hdr->parsed = via_body_cloner( new_msg->buf , org_msg->buf ,
569                                                                    (struct via_body*)hdr->parsed , &p);
570                         }
571                         break;
572                 case HDR_CSEQ_T:
573                         new_hdr->parsed = p;
574                         p +=ROUND4(sizeof(struct cseq_body));
575                         memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
576                         ((struct cseq_body*)new_hdr->parsed)->number.s =
577                                 translate_pointer(new_msg->buf ,org_msg->buf,
578                                                   ((struct cseq_body*)hdr->parsed)->number.s );
579                         ((struct cseq_body*)new_hdr->parsed)->method.s =
580                                 translate_pointer(new_msg->buf ,org_msg->buf,
581                                                   ((struct cseq_body*)hdr->parsed)->method.s );
582                         if (!HOOK_SET(cseq)) new_msg->cseq = new_hdr;
583                         break;
584                 case HDR_TO_T:
585                 case HDR_FROM_T:
586                         if (hdr->type == HDR_TO_T) {
587                                 if (!HOOK_SET(to)) new_msg->to = new_hdr;
588                         } else {
589                                 if (!HOOK_SET(from)) new_msg->from = new_hdr;
590                         }
591                              /* From header might be unparsed */
592                         if (!hdr->parsed) break;
593                         new_hdr->parsed = p;
594                         p +=ROUND4(sizeof(struct to_body));
595                         memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
596                         ((struct to_body*)new_hdr->parsed)->body.s =
597                                 translate_pointer( new_msg->buf , org_msg->buf ,
598                                                    ((struct to_body*)hdr->parsed)->body.s );
599                         ((struct to_body*)new_hdr->parsed)->display.s =
600                                 translate_pointer( new_msg->buf, org_msg->buf,
601                                                    ((struct to_body*)hdr->parsed)->display.s);
602                         ((struct to_body*)new_hdr->parsed)->uri.s =
603                                 translate_pointer( new_msg->buf , org_msg->buf ,
604                                                    ((struct to_body*)hdr->parsed)->uri.s );
605                         if ( ((struct to_body*)hdr->parsed)->tag_value.s )
606                                 ((struct to_body*)new_hdr->parsed)->tag_value.s =
607                                         translate_pointer( new_msg->buf , org_msg->buf ,
608                                                            ((struct to_body*)hdr->parsed)->tag_value.s );
609                              /*to params*/
610                         to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
611                         for(;to_prm;to_prm=to_prm->next) {
612                                      /*alloc*/
613                                 new_to_prm = (struct to_param*)p;
614                                 p +=ROUND4(sizeof(struct to_param ));
615                                      /*coping*/
616                                 memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
617                                 ((struct to_body*)new_hdr->parsed)->param_lst = 0;
618                                 new_to_prm->name.s = translate_pointer( new_msg->buf,
619                                                                         org_msg->buf , to_prm->name.s );
620                                 new_to_prm->value.s = translate_pointer( new_msg->buf,
621                                                                          org_msg->buf , to_prm->value.s );
622                                      /*linking*/
623                                 if ( !((struct to_body*)new_hdr->parsed)->param_lst )
624                                         ((struct to_body*)new_hdr->parsed)->param_lst
625                                                 = new_to_prm;
626                                 else
627                                         ((struct to_body*)new_hdr->parsed)->last_param->next
628                                                 = new_to_prm;
629                                 ((struct to_body*)new_hdr->parsed)->last_param
630                                         = new_to_prm;
631                         }
632                         break;
633                 case HDR_CALLID_T:
634                         if (!HOOK_SET(callid)) {
635                                 new_msg->callid = new_hdr;
636                         }
637                         break;
638                 case HDR_CONTACT_T:
639                         if (!HOOK_SET(contact)) {
640                                 new_msg->contact = new_hdr;
641                         }
642                         break;
643                 case HDR_MAXFORWARDS_T:
644                         if (!HOOK_SET(maxforwards)) {
645                                 new_msg->maxforwards = new_hdr;
646                         }
647                         break;
648                 case HDR_ROUTE_T:
649                         if (!HOOK_SET(route)) {
650                                 new_msg->route = new_hdr;
651                         }
652                         break;
653                 case HDR_RECORDROUTE_T:
654                         if (!HOOK_SET(record_route)) {
655                                 new_msg->record_route = new_hdr;
656                         }
657                         break;
658                 case HDR_CONTENTTYPE_T:
659                         if (!HOOK_SET(content_type)) {
660                                 new_msg->content_type = new_hdr;
661                                 new_msg->content_type->parsed = hdr->parsed;
662                         }
663                         break;
664                 case HDR_CONTENTLENGTH_T:
665                         if (!HOOK_SET(content_length)) {
666                                 new_msg->content_length = new_hdr;
667                                 new_msg->content_length->parsed = hdr->parsed;
668                         }
669                         break;
670                 case HDR_AUTHORIZATION_T:
671                         if (!HOOK_SET(authorization)) {
672                                 new_msg->authorization = new_hdr;
673                         }
674                         if (hdr->parsed) {
675                                 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
676                                                                    org_msg->buf , (struct auth_body*)hdr->parsed , &p);
677                         }
678                         break;
679                 case HDR_EXPIRES_T:
680                         if (!HOOK_SET(expires)) {
681                                 new_msg->expires = new_hdr;
682                         }
683                         break;
684                 case HDR_PROXYAUTH_T:
685                         if (!HOOK_SET(proxy_auth)) {
686                                 new_msg->proxy_auth = new_hdr;
687                         }
688                         if (hdr->parsed) {
689                                 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
690                                                                    org_msg->buf , (struct auth_body*)hdr->parsed , &p);
691                         }
692                         break;
693                 case HDR_SUPPORTED_T:
694                         if (!HOOK_SET(supported)) {
695                                 new_msg->supported = new_hdr;
696                         }
697                         break;
698                 case HDR_REQUIRE_T:
699                         if (!HOOK_SET(require)) {
700                                 new_msg->require = new_hdr;
701                         }
702                         break;
703                 case HDR_PROXYREQUIRE_T:
704                         if (!HOOK_SET(proxy_require)) {
705                                 new_msg->proxy_require = new_hdr;
706                         }
707                         break;
708                 case HDR_UNSUPPORTED_T:
709                         if (!HOOK_SET(unsupported)) {
710                                 new_msg->unsupported = new_hdr;
711                         }
712                         break;
713                 case HDR_ALLOW_T:
714                         if (!HOOK_SET(allow)) {
715                                 new_msg->allow = new_hdr;
716                         }
717                         break;
718                 case HDR_EVENT_T:
719                         if (!HOOK_SET(event)) {
720                                 new_msg->event = new_hdr;
721                         }
722                         break;
723                 case HDR_ACCEPT_T:
724                         if (!HOOK_SET(accept)) {
725                                 new_msg->accept = new_hdr;
726                         }
727                         break;
728                 case HDR_ACCEPTLANGUAGE_T:
729                         if (!HOOK_SET(accept_language)) {
730                                 new_msg->accept_language = new_hdr;
731                         }
732                         break;
733                 case HDR_ORGANIZATION_T:
734                         if (!HOOK_SET(organization)) {
735                                 new_msg->organization = new_hdr;
736                         }
737                         break;
738                 case HDR_PRIORITY_T:
739                         if (!HOOK_SET(priority)) {
740                                 new_msg->priority = new_hdr;
741                         }
742                         break;
743                 case HDR_SUBJECT_T:
744                         if (!HOOK_SET(subject)) {
745                                 new_msg->subject = new_hdr;
746                         }
747                         break;
748                 case HDR_USERAGENT_T:
749                         if (!HOOK_SET(user_agent)) {
750                                 new_msg->user_agent = new_hdr;
751                         }
752                         break;
753                 case HDR_SERVER_T:
754                         if (!HOOK_SET(server)) {
755                                 new_msg->server = new_hdr;
756                         }
757                         break;
758                 case HDR_ACCEPTDISPOSITION_T:
759                         if (!HOOK_SET(accept_disposition)) {
760                                 new_msg->accept_disposition = new_hdr;
761                         }
762                         break;
763                 case HDR_CONTENTDISPOSITION_T:
764                         if (!HOOK_SET(content_disposition)) {
765                                 new_msg->content_disposition = new_hdr;
766                         }
767                         break;
768                 case HDR_DIVERSION_T:
769                         if (!HOOK_SET(diversion)) {
770                                 new_msg->diversion = new_hdr;
771                         }
772                         break;
773                 case HDR_RPID_T:
774                         if (!HOOK_SET(rpid)) {
775                                 new_msg->rpid = new_hdr;
776                         }
777                         break;
778                 case HDR_REFER_TO_T:
779                         if (!HOOK_SET(refer_to)) {
780                                 new_msg->refer_to = new_hdr;
781                         }
782                         break;
783                 case HDR_SESSIONEXPIRES_T:
784                         if (!HOOK_SET(session_expires)) {
785                                 new_msg->session_expires = new_hdr;
786                         }
787                         break;
788                 case HDR_MIN_SE_T:
789                         if (!HOOK_SET(min_se)) {
790                                 new_msg->min_se = new_hdr;
791                         }
792                         break;
793                 case HDR_SUBSCRIPTION_STATE_T:
794                         if (!HOOK_SET(subscription_state)) {
795                                 new_msg->subscription_state = new_hdr;
796                         }
797                         break;
798                 case HDR_SIPIFMATCH_T:
799                         if (!HOOK_SET(sipifmatch)) {
800                                 new_msg->sipifmatch = new_hdr;
801                         }
802                         break;
803                 }/*switch*/
804
805                 if ( last_hdr )
806                 {
807                         last_hdr->next = new_hdr;
808                         last_hdr=last_hdr->next;
809                 }
810                 else
811                 {
812                         last_hdr=new_hdr;
813                         new_msg->headers =new_hdr;
814                 }
815                 last_hdr->next = 0;
816                 new_msg->last_header = last_hdr;
817         }
818
819         /* cloning data lump */
820 #define CLONE_LUMP_LIST(anchor, list) \
821 do { \
822         struct lump* lump_tmp, *l; \
823         struct lump** lump_anchor2, **a; \
824         a = (anchor); \
825         l = (list); \
826         while (l) \
827         { \
828                 lump_clone( (*a) , l , p ); \
829                 /*before list*/ \
830                 lump_tmp = l->before; \
831                 lump_anchor2 = &((*a)->before); \
832                 while ( lump_tmp ) \
833                 { \
834                         lump_clone( (*lump_anchor2) , lump_tmp , p ); \
835                         lump_anchor2 = &((*lump_anchor2)->before); \
836                         lump_tmp = lump_tmp->before; \
837                 } \
838                 /*after list*/ \
839                 lump_tmp = l->after; \
840                 lump_anchor2 = &((*a)->after); \
841                 while ( lump_tmp ) \
842                 { \
843                         lump_clone( (*lump_anchor2) , lump_tmp , p ); \
844                         lump_anchor2 = &((*lump_anchor2)->after); \
845                         lump_tmp = lump_tmp->after; \
846                 } \
847                 a = &((*a)->next); \
848                 l = l->next; \
849         } \
850 } while(0)
851
852         CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);
853         CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);
854
855         /*cloning reply lump structures*/
856         rpl_lump_anchor = &(new_msg->reply_lump);
857         for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
858         {
859                 *(rpl_lump_anchor)=(struct lump_rpl*)p;
860                 p+=ROUND4(sizeof( struct lump_rpl ));
861                 (*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM |
862                         (rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE)));
863                 (*rpl_lump_anchor)->text.len = rpl_lump->text.len;
864                 (*rpl_lump_anchor)->text.s=p;
865                 p+=ROUND4(rpl_lump->text.len);
866                 memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len);
867                 (*rpl_lump_anchor)->next=0;
868                 rpl_lump_anchor = &((*rpl_lump_anchor)->next);
869         }
870
871         if (clone_authorized_hooks(new_msg, org_msg) < 0) {
872                 shm_free(new_msg);
873                 return 0;
874         }
875
876         return new_msg;
877 }