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