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