Browse code

core+tm: moved sip msg clone functions to the core

- moved all sip msg clone related functions to the core, since the
xmlrpc modules will need them too.
- renamed sip_msg_cloner() to sip_msg_shm_clone().
- msg_lump_cloner() is no longer static and returns 1 for no
change, 0 for successful cloning and -1 on error.

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