4 * Copyright (C) 2009 iptelorg GmbH
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.
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.
19 * sip_msg_clone.c - moved sip msg clone-in-shm functions from tm
24 * 2009-07-22 initial version: functions moved from tm/sip_msg.c (andrei)
27 /** SIP-router core :: sip message shared memory cloner.
33 #include "sip_msg_clone.h"
38 #include "data_lump.h"
39 #include "data_lump_rpl.h"
41 #include "parser/digest/digest.h"
42 #include "parser/parse_to.h"
43 #include "atomic_ops.h"
45 /* rounds to the first 4 byte multiple on 32 bit archs
46 * and to the first 8 byte multiple on 64 bit archs */
48 (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
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) \
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);}\
65 /* length of the data lump structures */
66 #define LUMP_LIST_LEN(len, list) \
68 struct lump* tmp, *chain; \
72 (len) += lump_len(chain); \
73 tmp = chain->before; \
76 (len) += lump_len( tmp ); \
82 (len) += lump_len( tmp ); \
85 chain = chain->next; \
89 /* length of the reply lump structure */
90 #define RPL_LUMP_LIST_LEN(len, list) \
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); \
97 /* clones data lumps */
98 #define CLONE_LUMP_LIST(anchor, list, _ptr) \
100 struct lump* lump_tmp, *l; \
101 struct lump** lump_anchor2, **a; \
106 lump_clone( (*a) , l , (_ptr) ); \
108 lump_tmp = l->before; \
109 lump_anchor2 = &((*a)->before); \
112 lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
113 lump_anchor2 = &((*lump_anchor2)->before); \
114 lump_tmp = lump_tmp->before; \
117 lump_tmp = l->after; \
118 lump_anchor2 = &((*a)->after); \
121 lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
122 lump_anchor2 = &((*lump_anchor2)->after); \
123 lump_tmp = lump_tmp->after; \
130 /* clones reply lumps */
131 #define CLONE_RPL_LUMP_LIST(anchor, list, _ptr) \
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) \
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); \
153 inline struct via_body* via_body_cloner( char* new_buf,
154 char *org_buf, struct via_body *param_org_via, char **p)
156 struct via_body *new_via;
157 struct via_body *first_via, *last_via;
158 struct via_body *org_via;
160 first_via = last_via = 0;
161 org_via = param_org_via;
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 ));
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) */
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) */
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);
189 translate_pointer(new_buf, org_buf, org_via->tid.s);
190 /* comment (str type) */
192 translate_pointer(new_buf,org_buf,org_via->comment.s);
194 if ( org_via->param_lst )
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 )
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);
206 /* "translate" the shortcuts */
207 switch(new_vp->type){
209 new_via->branch = new_vp;
212 new_via->received = new_vp;
215 new_via->rport = new_vp;
221 new_via->alias = new_vp;
226 new_via->comp = new_vp;
232 last_new_vp->next = new_vp;
234 new_via->param_lst = new_vp;
236 last_new_vp = new_vp;
237 last_new_vp->next = NULL;
239 new_via->last_param = new_vp;
240 }/*end if via has params */
243 last_via->next = new_via;
247 org_via = org_via->next;
254 static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
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);
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);
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);
283 static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
285 struct auth_body* new_auth;
287 new_auth = (struct auth_body*)(*p);
288 memcpy(new_auth , auth , sizeof(struct auth_body));
289 (*p) += ROUND4(sizeof(struct auth_body));
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);
320 static inline int clone_authorized_hooks(struct sip_msg* new,
323 struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
326 get_authorized_cred(old->authorization, &hook1);
327 if (!hook1) stop = 1;
329 get_authorized_cred(old->proxy_auth, &hook2);
330 if (!hook2) stop |= 2;
333 new_ptr = new->headers;
337 if (!new->authorization || !new->authorization->parsed) {
338 LOG(L_CRIT, "BUG: Error in message cloner (authorization)\n");
341 ((struct auth_body*)new->authorization->parsed)->authorized =
347 if (!new->proxy_auth || !new->proxy_auth->parsed) {
348 LOG(L_CRIT, "BUG: Error in message cloner (proxy_auth)\n");
351 ((struct auth_body*)new->proxy_auth->parsed)->authorized =
356 if (stop == 3) break;
359 new_ptr = new_ptr->next;
365 #define AUTH_BODY_SIZE sizeof(struct auth_body)
367 #define HOOK_SET(hook) (new_msg->hook != org_msg->hook)
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.).
377 struct sip_msg* sip_msg_shm_clone( struct sip_msg *org_msg, int *sip_msg_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;
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);
399 for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
401 /*size of header struct*/
402 len += ROUND4(sizeof( struct hdr_field));
404 /* Safely ignore auxiliary header types */
412 for (via=(struct via_body*)hdr->parsed;via;via=via->next) {
413 len+=ROUND4(sizeof(struct via_body));
415 for(prm=via->param_lst;prm;prm=prm->next)
416 len+=ROUND4(sizeof(struct via_param ));
422 /* From header might be unparsed */
424 len+=ROUND4(sizeof(struct to_body));
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 ));
433 len+=ROUND4(sizeof(struct cseq_body));
437 case HDR_AUTHORIZATION_T:
438 case HDR_PROXYAUTH_T:
440 len += ROUND4(AUTH_BODY_SIZE);
446 case HDR_MAXFORWARDS_T:
448 case HDR_RECORDROUTE_T:
449 case HDR_CONTENTTYPE_T:
450 case HDR_CONTENTLENGTH_T:
451 case HDR_RETRY_AFTER_T:
453 case HDR_SUPPORTED_T:
455 case HDR_PROXYREQUIRE_T:
456 case HDR_UNSUPPORTED_T:
460 case HDR_ACCEPTLANGUAGE_T:
461 case HDR_ORGANIZATION_T:
464 case HDR_USERAGENT_T:
466 case HDR_ACCEPTDISPOSITION_T:
467 case HDR_CONTENTDISPOSITION_T:
468 case HDR_DIVERSION_T:
471 case HDR_SIPIFMATCH_T:
472 case HDR_SESSIONEXPIRES_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:
485 case HDR_IDENTITY_INFO_T:
491 /* we ignore them for now even if they have something parsed*/
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);
503 p=(char *)shm_malloc(len);
506 LOG(L_ERR , "ERROR: sip_msg_cloner: cannot allocate memory\n" );
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) );
517 new_msg->msg_flags |= FL_SHM_CLONE;
518 p += ROUND4(sizeof(struct sip_msg));
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;
527 if (org_msg->new_uri.s && org_msg->new_uri.len)
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);
534 if (org_msg->dst_uri.s && org_msg->dst_uri.len)
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);
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);
548 p += ROUND4(new_msg->len+1);
549 /* unparsed and eoh pointer */
550 new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
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 )
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);
570 uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
572 else if ( org_msg->first_line.type==SIP_REPLY )
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 );
589 for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
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,
596 new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
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
606 /* Ignore auxiliary header types */
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:
621 case HDR_IDENTITY_INFO_T:
622 case HDR_RETRY_AFTER_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;
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;
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;
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);
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;
663 if (hdr->type == HDR_TO_T) {
664 if (!HOOK_SET(to)) new_msg->to = new_hdr;
666 if (!HOOK_SET(from)) new_msg->from = new_hdr;
668 /* From header might be unparsed */
669 if (!hdr->parsed) break;
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);
691 to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
692 for(;to_prm;to_prm=to_prm->next) {
694 new_to_prm = (struct to_param*)p;
695 p +=ROUND4(sizeof(struct to_param ));
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 );
704 if ( !((struct to_body*)new_hdr->parsed)->param_lst )
705 ((struct to_body*)new_hdr->parsed)->param_lst
708 ((struct to_body*)new_hdr->parsed)->last_param->next
710 ((struct to_body*)new_hdr->parsed)->last_param
715 if (!HOOK_SET(callid)) {
716 new_msg->callid = new_hdr;
720 if (!HOOK_SET(contact)) {
721 new_msg->contact = new_hdr;
724 case HDR_MAXFORWARDS_T:
725 if (!HOOK_SET(maxforwards)) {
726 new_msg->maxforwards = new_hdr;
730 if (!HOOK_SET(route)) {
731 new_msg->route = new_hdr;
734 case HDR_RECORDROUTE_T:
735 if (!HOOK_SET(record_route)) {
736 new_msg->record_route = new_hdr;
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;
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;
751 case HDR_AUTHORIZATION_T:
752 if (!HOOK_SET(authorization)) {
753 new_msg->authorization = new_hdr;
756 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
757 org_msg->buf , (struct auth_body*)hdr->parsed , &p);
761 if (!HOOK_SET(expires)) {
762 new_msg->expires = new_hdr;
765 case HDR_PROXYAUTH_T:
766 if (!HOOK_SET(proxy_auth)) {
767 new_msg->proxy_auth = new_hdr;
770 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
771 org_msg->buf , (struct auth_body*)hdr->parsed , &p);
774 case HDR_SUPPORTED_T:
775 if (!HOOK_SET(supported)) {
776 new_msg->supported = new_hdr;
780 if (!HOOK_SET(require)) {
781 new_msg->require = new_hdr;
784 case HDR_PROXYREQUIRE_T:
785 if (!HOOK_SET(proxy_require)) {
786 new_msg->proxy_require = new_hdr;
789 case HDR_UNSUPPORTED_T:
790 if (!HOOK_SET(unsupported)) {
791 new_msg->unsupported = new_hdr;
795 if (!HOOK_SET(allow)) {
796 new_msg->allow = new_hdr;
800 if (!HOOK_SET(event)) {
801 new_msg->event = new_hdr;
805 if (!HOOK_SET(accept)) {
806 new_msg->accept = new_hdr;
809 case HDR_ACCEPTLANGUAGE_T:
810 if (!HOOK_SET(accept_language)) {
811 new_msg->accept_language = new_hdr;
814 case HDR_ORGANIZATION_T:
815 if (!HOOK_SET(organization)) {
816 new_msg->organization = new_hdr;
820 if (!HOOK_SET(priority)) {
821 new_msg->priority = new_hdr;
825 if (!HOOK_SET(subject)) {
826 new_msg->subject = new_hdr;
829 case HDR_USERAGENT_T:
830 if (!HOOK_SET(user_agent)) {
831 new_msg->user_agent = new_hdr;
835 if (!HOOK_SET(server)) {
836 new_msg->server = new_hdr;
839 case HDR_ACCEPTDISPOSITION_T:
840 if (!HOOK_SET(accept_disposition)) {
841 new_msg->accept_disposition = new_hdr;
844 case HDR_CONTENTDISPOSITION_T:
845 if (!HOOK_SET(content_disposition)) {
846 new_msg->content_disposition = new_hdr;
849 case HDR_DIVERSION_T:
850 if (!HOOK_SET(diversion)) {
851 new_msg->diversion = new_hdr;
855 if (!HOOK_SET(rpid)) {
856 new_msg->rpid = new_hdr;
860 if (!HOOK_SET(refer_to)) {
861 new_msg->refer_to = new_hdr;
864 case HDR_SESSIONEXPIRES_T:
865 if (!HOOK_SET(session_expires)) {
866 new_msg->session_expires = new_hdr;
870 if (!HOOK_SET(min_se)) {
871 new_msg->min_se = new_hdr;
874 case HDR_SUBSCRIPTION_STATE_T:
875 if (!HOOK_SET(subscription_state)) {
876 new_msg->subscription_state = new_hdr;
879 case HDR_SIPIFMATCH_T:
880 if (!HOOK_SET(sipifmatch)) {
881 new_msg->sipifmatch = new_hdr;
885 if (!HOOK_SET(ppi)) {
886 new_msg->ppi = new_hdr;
890 if (!HOOK_SET(pai)) {
891 new_msg->pai = new_hdr;
895 if (!HOOK_SET(path)) {
896 new_msg->path = new_hdr;
900 if (!HOOK_SET(privacy)) {
901 new_msg->privacy = new_hdr;
908 last_hdr->next = new_hdr;
909 last_hdr=last_hdr->next;
914 new_msg->headers =new_hdr;
917 new_msg->last_header = last_hdr;
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);
926 if (clone_authorized_hooks(new_msg, org_msg) < 0) {
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
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
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)
961 *add_rm = *body_lumps = 0;
964 /* calculate the length of the lumps */
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);
971 return 1; /* nothing to do */
973 p=(char *)shm_malloc(len);
976 LOG(L_ERR, "ERROR: msg_lump_cloner: cannot allocate memory\n" );
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);
990 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */