Browse code

- exported structure avp_spec - Support for AVP tracks (tracks identify who owns the attributes, it can be either FROM (caller) or TO (CALLEE) - Better support for AVP classes - function delete_avp added - str* in int_str changed to str (there is no need to create temporary str variables)

Jan Janak authored on 24/11/2005 15:03:54
Showing 2 changed files
... ...
@@ -46,13 +46,15 @@
46 46
 #include "mem/mem.h"
47 47
 #include "usr_avp.h"
48 48
 
49
-
50
-/* avp aliases structs*/
51
-struct avp_spec {
52
-	int type;
53
-	int_str name;
49
+enum idx {
50
+	IDX_FROM_USER = 0,
51
+	IDX_TO_USER,
52
+	IDX_FROM_DOMAIN,
53
+	IDX_TO_DOMAIN,
54
+	IDX_MAX
54 55
 };
55 56
 
57
+
56 58
 struct avp_galias {
57 59
 	str alias;
58 60
 	struct avp_spec  avp;
... ...
@@ -61,14 +63,61 @@ struct avp_galias {
61 61
 
62 62
 static struct avp_galias *galiases = 0;
63 63
 
64
-static avp_t *global_avps = 0;  /* Global attribute list */
65
-static avp_t *domain_avps = 0;  /* Domain-specific attribute list */
66
-static avp_t *user_avps = 0;    /* User-specific attribute list */
64
+static avp_list_t def_list[IDX_MAX];    /* Default AVP lists */
65
+static avp_list_t* crt_list[IDX_MAX];  /* Pointer to current AVP lists */
66
+
67
+/* Global AVP related variables go to shm mem */
68
+static avp_list_t* def_glist;
69
+static avp_list_t** crt_glist;
70
+
71
+
72
+/* Initialize AVP lists in private memory and allocate memory
73
+ * for shared lists
74
+ */
75
+int init_avps(void)
76
+{
77
+	int i;
78
+	     /* Empty default lists */
79
+	memset(def_list, 0, sizeof(avp_list_t) * IDX_MAX);
80
+	
81
+	     /* Point current pointers to default lists */
82
+	for(i = 0; i < IDX_MAX; i++) {
83
+		crt_list[i] = &def_list[i];
84
+	}
85
+
86
+	def_glist = (avp_list_t*)shm_malloc(sizeof(avp_list_t));
87
+	crt_glist = (avp_list_t**)shm_malloc(sizeof(avp_list_t*));
88
+	if (!def_glist || !crt_glist) {
89
+		LOG(L_ERR, "ERROR: No memory to allocate default global AVP list\n");
90
+		return -1;
91
+	}
92
+	*def_glist = 0;
93
+	*crt_glist = def_glist;
94
+	return 0;
95
+}
96
+
67 97
 
68
-static avp_t **crt_global_avps = &global_avps; /* Pointer to the current list of global attributes */
69
-static avp_t **crt_domain_avps = &domain_avps; /* Pointer to the current list of domain attributes */
70
-static avp_t **crt_user_avps   = &user_avps;   /* Pointer to the current list of user attributes */
98
+/*
99
+ * Select active AVP list based on the value of flags
100
+ */
101
+static avp_list_t* select_list(unsigned short flags)
102
+{
103
+	if (flags & AVP_CLASS_USER) {
104
+		if (flags & AVP_TRACK_TO) {
105
+			return crt_list[IDX_TO_USER];
106
+		} else {
107
+			return crt_list[IDX_FROM_USER];
108
+		}
109
+	} else if (flags & AVP_CLASS_DOMAIN) {
110
+		if (flags & AVP_TRACK_TO) {
111
+			return crt_list[IDX_TO_DOMAIN];
112
+		} else {
113
+			return crt_list[IDX_FROM_DOMAIN];
114
+		}
115
+	}
71 116
 
117
+	return *crt_glist;
118
+}
72 119
 
73 120
 inline static unsigned short compute_ID( str *name )
74 121
 {
... ...
@@ -82,7 +131,7 @@ inline static unsigned short compute_ID( str *name )
82 82
 }
83 83
 
84 84
 
85
-int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
85
+int add_avp_list(avp_list_t* list, unsigned short flags, int_str name, int_str val)
86 86
 {
87 87
 	avp_t *avp;
88 88
 	str *s;
... ...
@@ -92,7 +141,7 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
92 92
 
93 93
 	assert(list != 0);
94 94
 
95
-	if ( name.s==0 ) {
95
+	if (name.s.s == 0 && name.s.len == 0) {
96 96
 		LOG(L_ERR,"ERROR:avp:add_avp: 0 ID or NULL NAME AVP!");
97 97
 		goto error;
98 98
 	}
... ...
@@ -100,20 +149,20 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
100 100
 	/* compute the required mem size */
101 101
 	len = sizeof(struct usr_avp);
102 102
 	if (flags&AVP_NAME_STR) {
103
-		if ( name.s->s==0 || name.s->len==0) {
103
+		if ( name.s.s==0 || name.s.len==0) {
104 104
 			LOG(L_ERR,"ERROR:avp:add_avp: EMPTY NAME AVP!");
105 105
 			goto error;
106 106
 		}
107 107
 		if (flags&AVP_VAL_STR) {
108 108
 			len += sizeof(struct str_str_data)-sizeof(void*) 
109
-				+ name.s->len + 1 /* Terminating zero for regex search */
110
-				+ val.s->len + 1; /* Value is zero terminated */
109
+				+ name.s.len + 1 /* Terminating zero for regex search */
110
+				+ val.s.len + 1; /* Value is zero terminated */
111 111
 		} else {
112 112
 			len += sizeof(struct str_int_data)-sizeof(void*) 
113
-				+ name.s->len + 1; /* Terminating zero for regex search */
113
+				+ name.s.len + 1; /* Terminating zero for regex search */
114 114
 		}
115 115
 	} else if (flags&AVP_VAL_STR) {
116
-		len += sizeof(str)-sizeof(void*) + val.s->len + 1;
116
+		len += sizeof(str)-sizeof(void*) + val.s.len + 1;
117 117
 	}
118 118
 
119 119
 	avp = (struct usr_avp*)shm_malloc( len );
... ...
@@ -123,7 +172,7 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
123 123
 	}
124 124
 
125 125
 	avp->flags = flags;
126
-	avp->id = (flags&AVP_NAME_STR)? compute_ID(name.s) : name.n ;
126
+	avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
127 127
 
128 128
 	avp->next = *list;
129 129
 	*list = avp;
... ...
@@ -138,29 +187,29 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
138 138
 			/* avp type str, int value */
139 139
 			sid = (struct str_int_data*)&(avp->data);
140 140
 			sid->val = val.n;
141
-			sid->name.len =name.s->len;
141
+			sid->name.len =name.s.len;
142 142
 			sid->name.s = (char*)sid + sizeof(struct str_int_data);
143
-			memcpy( sid->name.s , name.s->s, name.s->len);
144
-			sid->name.s[name.s->len] = '\0'; /* Zero terminator */
143
+			memcpy( sid->name.s , name.s.s, name.s.len);
144
+			sid->name.s[name.s.len] = '\0'; /* Zero terminator */
145 145
 			break;
146 146
 		case AVP_VAL_STR:
147 147
 			/* avp type ID, str value */
148 148
 			s = (str*)&(avp->data);
149
-			s->len = val.s->len;
149
+			s->len = val.s.len;
150 150
 			s->s = (char*)s + sizeof(str);
151
-			memcpy( s->s, val.s->s , s->len);
151
+			memcpy( s->s, val.s.s , s->len);
152 152
 			s->s[s->len] = 0;
153 153
 			break;
154 154
 		case AVP_NAME_STR|AVP_VAL_STR:
155 155
 			/* avp type str, str value */
156 156
 			ssd = (struct str_str_data*)&(avp->data);
157
-			ssd->name.len = name.s->len;
157
+			ssd->name.len = name.s.len;
158 158
 			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
159
-			memcpy( ssd->name.s , name.s->s, name.s->len);
160
-			ssd->name.s[name.s->len]='\0'; /* Zero terminator */
161
-			ssd->val.len = val.s->len;
159
+			memcpy( ssd->name.s , name.s.s, name.s.len);
160
+			ssd->name.s[name.s.len]='\0'; /* Zero terminator */
161
+			ssd->val.len = val.s.len;
162 162
 			ssd->val.s = ssd->name.s + ssd->name.len + 1;
163
-			memcpy( ssd->val.s , val.s->s, val.s->len);
163
+			memcpy( ssd->val.s , val.s.s, val.s.len);
164 164
 			ssd->val.s[ssd->val.len] = 0;
165 165
 			break;
166 166
 	}
... ...
@@ -174,30 +223,23 @@ error:
174 174
 int add_avp(unsigned short flags, int_str name, int_str val)
175 175
 {
176 176
 	unsigned short avp_class;
177
-	avp_t **list;
178
-
179
-	if ((flags & ALL_AVP_CLASSES) == 0) {
180
-		     /* The caller did not specify any class to search in, so enable
181
-		      * all of them by default
182
-		      */
183
-		flags |= ALL_AVP_CLASSES;
184
-	}
185
-
186
-	if (IS_USER_AVP(flags)) {
187
-		list = crt_user_avps;
188
-		avp_class = AVP_USER;
189
-	} else if (IS_DOMAIN_AVP(flags)) {
190
-		list = crt_domain_avps;
191
-		avp_class = AVP_DOMAIN;
192
-	} else {
193
-		list = crt_global_avps;
194
-		avp_class = AVP_GLOBAL;
195
-	}
196
-
197
-		 /* Make that only the selected class is set
198
-		  * if the caller set more classes in flags
199
-		  */
200
-	return add_avp_list(list, flags & (~(ALL_AVP_CLASSES) | avp_class), name, val);
177
+	avp_list_t* list;
178
+
179
+	     /* Add avp to user class if no class has been
180
+	      * specified by the caller
181
+	      */
182
+	if ((flags & AVP_CLASS_ALL) == 0) flags |= AVP_CLASS_USER;
183
+	if ((flags & AVP_TRACK_ALL) == 0) flags |= AVP_TRACK_FROM;
184
+	list = select_list(flags);
185
+
186
+	if (flags & AVP_CLASS_USER) avp_class = AVP_CLASS_USER;
187
+	else if (flags & AVP_CLASS_DOMAIN) avp_class = AVP_CLASS_DOMAIN;
188
+	else avp_class = AVP_CLASS_GLOBAL;
189
+
190
+	     /* Make that only the selected class is set
191
+	      * if the caller set more classes in flags
192
+	      */
193
+	return add_avp_list(list, flags & (~(AVP_CLASS_ALL) | avp_class), name, val);
201 194
 }
202 195
 
203 196
 
... ...
@@ -220,7 +262,7 @@ inline str* get_avp_name(avp_t *avp)
220 220
 	}
221 221
 
222 222
 	LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
223
-		avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
223
+	    avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
224 224
 	return 0;
225 225
 }
226 226
 
... ...
@@ -241,36 +283,20 @@ inline void get_avp_val(avp_t *avp, int_str *val)
241 241
 			break;
242 242
 		case AVP_VAL_STR:
243 243
 			/* avp type ID, str value */
244
-			val->s = (str*)(&avp->data);
244
+			val->s = *(str*)(avp->data);
245 245
 			break;
246 246
 		case AVP_NAME_STR|AVP_VAL_STR:
247 247
 			/* avp type str, str value */
248
-			val->s = &(((struct str_str_data*)(&avp->data))->val);
248
+			val->s = (((struct str_str_data*)(&avp->data))->val);
249 249
 			break;
250 250
 	}
251 251
 }
252 252
 
253 253
 
254 254
 /* Return the current list of user attributes */
255
-avp_t** get_user_avp_list(void)
255
+avp_list_t get_avp_list(unsigned short flags)
256 256
 {
257
-	assert(crt_user_avps != 0);
258
-	return crt_user_avps;
259
-}
260
-
261
-/* Return the current list of domain attributes */
262
-avp_t** get_domain_avp_list(void)
263
-{
264
-	assert(crt_domain_avps != 0);
265
-	return crt_domain_avps;
266
-}
267
-
268
-
269
-/* Return the current list of domain attributes */
270
-avp_t** get_global_avp_list(void)
271
-{
272
-	assert(crt_global_avps != 0);
273
-	return crt_global_avps;
257
+	return *select_list(flags);
274 258
 }
275 259
 
276 260
 
... ...
@@ -324,48 +350,49 @@ static inline int match_by_re(avp_t* avp, regex_t* re)
324 324
 
325 325
 avp_t *search_first_avp(unsigned short flags, int_str name, int_str *val, struct search_state* s)
326 326
 {
327
+	avp_t* ret;
327 328
 	static struct search_state st;
329
+	avp_list_t* list;
328 330
 
329
-	assert( crt_user_avps != 0 );
330
-	assert( crt_domain_avps != 0);
331
-	assert( crt_global_avps != 0);
332
-
333
-	if (name.s==0) {
331
+	if (name.s.s==0 && name.s.len == 0) {
334 332
 		LOG(L_ERR,"ERROR:avp:search_first_avp: 0 ID or NULL NAME AVP!");
335 333
 		return 0;
336 334
 	}
337 335
 
338 336
 	if (!s) s = &st;
339 337
 
340
-	if ((flags & ALL_AVP_CLASSES) == 0) {
338
+	if ((flags & AVP_CLASS_ALL) == 0) {
341 339
 		     /* The caller did not specify any class to search in, so enable
342 340
 		      * all of them by default
343 341
 		      */
344
-		flags |= ALL_AVP_CLASSES;
342
+		flags |= AVP_CLASS_ALL;
345 343
 	}
344
+
345
+	list = select_list(flags);
346
+
346 347
 	s->flags = flags;
347
-	if (IS_USER_AVP(flags)) {
348
-		s->avp = *crt_user_avps;
349
-	} else if (IS_DOMAIN_AVP(flags)) {
350
-		s->avp = *crt_domain_avps;
351
-	} else {
352
-		s->avp = *crt_global_avps;
353
-	}
348
+	s->avp = *list;
354 349
 	s->name = name;
355 350
 
356 351
 	if (flags & AVP_NAME_STR) {
357
-		s->id = compute_ID(name.s);
352
+		s->id = compute_ID(&name.s);
358 353
 	}
359 354
 
360
-	return search_next_avp(s, val);
355
+        ret = search_next_avp(s, val);
356
+
357
+	     /* Make sure that search next avp stays in the same class as the first
358
+	      * avp found
359
+	      */
360
+	if (s && ret) s->flags = (flags & ~AVP_CLASS_ALL) | (ret->flags & AVP_CLASS_ALL);
361
+	return ret;
361 362
 }
362 363
 
363 364
 
364 365
 
365 366
 avp_t *search_next_avp(struct search_state* s, int_str *val )
366 367
 {
367
-	avp_t* avp;
368 368
 	int matched;
369
+	avp_t* avp;
369 370
 
370 371
 	if (s == 0) {
371 372
 		LOG(L_ERR, "search_next:avp: Invalid parameter value\n");
... ...
@@ -377,7 +404,7 @@ avp_t *search_next_avp(struct search_state* s, int_str *val )
377 377
 			if (s->flags & AVP_NAME_RE) {
378 378
 				matched = match_by_re(s->avp, s->name.re);
379 379
 			} else if (s->flags & AVP_NAME_STR) {
380
-				matched = match_by_name(s->avp, s->id, s->name.s);
380
+				matched = match_by_name(s->avp, s->id, &s->name.s);
381 381
 			} else {
382 382
 				matched = match_by_id(s->avp, s->name.n);
383 383
 			}
... ...
@@ -389,14 +416,14 @@ avp_t *search_next_avp(struct search_state* s, int_str *val )
389 389
 			}
390 390
 		}
391 391
 
392
-		if (IS_USER_AVP(s->flags)) {
393
-			s->flags &= ~AVP_USER;
394
-			s->avp = *crt_domain_avps;
395
-		} else if (IS_DOMAIN_AVP(s->flags)) {
396
-			s->flags &= ~AVP_DOMAIN;
397
-			s->avp = *crt_global_avps;
392
+		if (s->flags & AVP_CLASS_USER) {
393
+			s->flags &= ~AVP_CLASS_USER;
394
+			s->avp = *select_list(s->flags);
395
+		} else if (s->flags & AVP_CLASS_DOMAIN) {
396
+			s->flags &= ~AVP_CLASS_DOMAIN;
397
+			s->avp = *select_list(s->flags);
398 398
 		} else {
399
-			s->flags &= ~AVP_GLOBAL;
399
+			s->flags &= ~AVP_CLASS_GLOBAL;
400 400
 			return 0;
401 401
 		}
402 402
 	}
... ...
@@ -405,20 +432,37 @@ avp_t *search_next_avp(struct search_state* s, int_str *val )
405 405
 }
406 406
 
407 407
 
408
-
409
-
408
+/* FIXME */
410 409
 /********* free functions ********/
411 410
 
412
-void destroy_avp( avp_t *avp_del)
411
+void destroy_avp(avp_t *avp_del)
413 412
 {
413
+	int i;
414 414
 	avp_t *avp, *avp_prev;
415 415
 
416
-	for( avp_prev=0,avp=*crt_user_avps ; avp ; avp_prev=avp,avp=avp->next ) {
416
+	for (i = 0; i < IDX_MAX; i++) {
417
+		for( avp_prev=0,avp=*crt_list[i] ; avp ; 
418
+		     avp_prev=avp,avp=avp->next ) {
419
+			if (avp==avp_del) {
420
+				if (avp_prev) {
421
+					avp_prev->next=avp->next;
422
+				} else {
423
+					*crt_list[i] = avp->next;
424
+				}
425
+				shm_free(avp);
426
+				return;
427
+			}
428
+		}
429
+	}
430
+
431
+	for( avp_prev=0,avp=**crt_glist ; avp ; 
432
+	     avp_prev=avp,avp=avp->next ) {
417 433
 		if (avp==avp_del) {
418
-			if (avp_prev)
434
+			if (avp_prev) {
419 435
 				avp_prev->next=avp->next;
420
-			else
421
-				*crt_user_avps = avp->next;
436
+			} else {
437
+				**crt_glist = avp->next;
438
+			}
422 439
 			shm_free(avp);
423 440
 			return;
424 441
 		}
... ...
@@ -426,7 +470,7 @@ void destroy_avp( avp_t *avp_del)
426 426
 }
427 427
 
428 428
 
429
-void destroy_avp_list_unsafe( avp_t **list )
429
+void destroy_avp_list_unsafe(avp_list_t* list)
430 430
 {
431 431
 	avp_t *avp, *foo;
432 432
 
... ...
@@ -440,7 +484,7 @@ void destroy_avp_list_unsafe( avp_t **list )
440 440
 }
441 441
 
442 442
 
443
-inline void destroy_avp_list( avp_t **list )
443
+inline void destroy_avp_list(avp_list_t* list)
444 444
 {
445 445
 	avp_t *avp, *foo;
446 446
 
... ...
@@ -455,60 +499,42 @@ inline void destroy_avp_list( avp_t **list )
455 455
 }
456 456
 
457 457
 
458
-void reset_user_avps(void)
458
+void reset_avps(void)
459 459
 {
460
-	assert( crt_user_avps!=0 );
461
-	
462
-	if ( crt_user_avps!=&user_avps) {
463
-		crt_user_avps = &user_avps;
460
+	int i;
461
+	for(i = 0; i < IDX_MAX; i++) {
462
+		crt_list[i] = &def_list[i];
463
+		destroy_avp_list(crt_list[i]);
464 464
 	}
465
-	destroy_avp_list( crt_user_avps );
466
-}
467
-
468
-
469
-void reset_domain_avps(void)
470
-{
471
-	assert( crt_user_avps!=0 );
472
-	
473
-	if ( crt_user_avps!=&domain_avps) {
474
-		crt_domain_avps = &domain_avps;
475
-	}
476
-	     /* Do not destroy avps here, domain module takes care of it */
477
-}
478
-
479
-
480
-avp_t** set_user_avp_list( avp_t **list )
481
-{
482
-	avp_t **foo;
483
-
484
-	assert( crt_user_avps!=0 );
485
-
486
-	foo = crt_user_avps;
487
-	crt_user_avps = list;
488
-	return foo;
489 465
 }
490 466
 
491 467
 
492
-avp_t** set_domain_avp_list( avp_t **list )
468
+avp_list_t set_avp_list( unsigned short flags, avp_list_t* list )
493 469
 {
494
-	avp_t **foo;
495
-
496
-	assert( crt_domain_avps!=0 );
470
+	avp_list_t* prev;
497 471
 
498
-	foo = crt_domain_avps;
499
-	crt_domain_avps = list;
500
-	return foo;
501
-}
502
-
503
-avp_t** set_global_avp_list( avp_t **list )
504
-{
505
-	avp_t **foo;
506
-
507
-	assert( crt_global_avps!=0 );
472
+	if (flags & AVP_CLASS_USER) {
473
+		if (flags & AVP_TRACK_FROM) {
474
+			prev = crt_list[IDX_FROM_USER];
475
+			crt_list[IDX_FROM_USER] = list;
476
+		} else {
477
+			prev = crt_list[IDX_TO_USER];
478
+			crt_list[IDX_TO_USER] = list;
479
+		}
480
+	} else if (flags & AVP_CLASS_DOMAIN) {
481
+		if (flags & AVP_TRACK_FROM) {
482
+			prev = crt_list[IDX_FROM_DOMAIN];
483
+			crt_list[IDX_FROM_DOMAIN] = list;
484
+		} else {
485
+			prev = crt_list[IDX_TO_DOMAIN];
486
+			crt_list[IDX_TO_DOMAIN] = list;
487
+		}
488
+	} else {
489
+		prev = *crt_glist;
490
+	        *crt_glist = list;
491
+	}
508 492
 
509
-	foo = crt_global_avps;
510
-	crt_global_avps = list;
511
-	return foo;
493
+	return *prev;
512 494
 }
513 495
 
514 496
 
... ...
@@ -528,9 +554,9 @@ static inline int check_avp_galias(str *alias, int type, int_str avp_name)
528 528
 		/*check for duplicated avp names */
529 529
 		if (type==ga->avp.type) {
530 530
 			if (type&AVP_NAME_STR){
531
-				if (avp_name.s->len==ga->avp.name.s->len &&
532
-				(strncasecmp(avp_name.s->s, ga->avp.name.s->s,
533
-							 					avp_name.s->len)==0) )
531
+				if (avp_name.s.len==ga->avp.name.s.len &&
532
+				    (strncasecmp(avp_name.s.s, ga->avp.name.s.s,
533
+						 avp_name.s.len)==0) )
534 534
 					return -1;
535 535
 			} else {
536 536
 				if (avp_name.n==ga->avp.name.n)
... ...
@@ -546,8 +572,8 @@ int add_avp_galias(str *alias, int type, int_str avp_name)
546 546
 {
547 547
 	struct avp_galias *ga;
548 548
 
549
-	if ((type&AVP_NAME_STR && (!avp_name.s || !avp_name.s->s ||
550
-								!avp_name.s->len)) ||!alias || !alias->s ||
549
+	if ((type&AVP_NAME_STR && (!avp_name.s.s ||
550
+				   !avp_name.s.len)) ||!alias || !alias->s ||
551 551
 		!alias->len ){
552 552
 		LOG(L_ERR, "ERROR:add_avp_galias: null params received\n");
553 553
 		goto error;
... ...
@@ -575,17 +601,16 @@ int add_avp_galias(str *alias, int type, int_str avp_name)
575 575
 	ga->avp.type = type&AVP_NAME_STR;
576 576
 
577 577
 	if (type&AVP_NAME_STR) {
578
-		ga->avp.name.s = (str*)pkg_malloc( sizeof(str)+avp_name.s->len+1 );
579
-		if (ga->avp.name.s==0) {
578
+		ga->avp.name.s.s = (char*)pkg_malloc( avp_name.s.len+1 );
579
+		if (ga->avp.name.s.s==0) {
580 580
 			LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
581 581
 			goto error2;
582 582
 		}
583
-		ga->avp.name.s->s = ((char*)ga->avp.name.s)+sizeof(str);
584
-		ga->avp.name.s->len = avp_name.s->len;
585
-		memcpy( ga->avp.name.s->s, avp_name.s->s, avp_name.s->len);
586
-		ga->avp.name.s->s[avp_name.s->len] = 0;
583
+		ga->avp.name.s.len = avp_name.s.len;
584
+		memcpy( ga->avp.name.s.s, avp_name.s.s, avp_name.s.len);
585
+		ga->avp.name.s.s[avp_name.s.len] = 0;
587 586
 		DBG("DEBUG:add_avp_galias: registering <%s> for avp name <%s>\n",
588
-			ga->alias.s, ga->avp.name.s->s);
587
+			ga->alias.s, ga->avp.name.s.s);
589 588
 	} else {
590 589
 		ga->avp.name.n = avp_name.n;
591 590
 		DBG("DEBUG:add_avp_galias: registering <%s> for avp id <%d>\n",
... ...
@@ -640,7 +665,7 @@ int parse_avp_name( str *name, int *type, int_str *avp_name)
640 640
 		switch (c) {
641 641
 			case 's': case 'S':
642 642
 				*type = AVP_NAME_STR;
643
-				avp_name->s = name;
643
+				avp_name->s = *name;
644 644
 				break;
645 645
 			case 'i': case 'I':
646 646
 				*type = 0;
... ...
@@ -659,7 +684,7 @@ int parse_avp_name( str *name, int *type, int_str *avp_name)
659 659
 	} else {
660 660
 		/*default is string name*/
661 661
 		*type = AVP_NAME_STR;
662
-		avp_name->s = name;
662
+		avp_name->s = *name;
663 663
 	}
664 664
 
665 665
 	return 0;
... ...
@@ -755,3 +780,16 @@ parse_error:
755 755
 error:
756 756
 	return -1;
757 757
 }
758
+
759
+
760
+int delete_avp(unsigned short flags, int_str name)
761
+{
762
+	struct search_state st;
763
+	avp_t* avp;
764
+
765
+	avp = search_first_avp(flags, name, 0, &st);
766
+	while(avp) {
767
+		destroy_avp(avp);
768
+		avp = search_next_avp(&st, 0);
769
+	}
770
+}
... ...
@@ -31,8 +31,8 @@
31 31
  *  2005-02-14  list with FLAGS USAGE added (bogdan)
32 32
  */
33 33
 
34
-#ifndef _SER_URS_AVP_H_
35
-#define _SER_URS_AVP_H_
34
+#ifndef _SER_USR_AVP_H_
35
+#define _SER_USR_AVP_H_
36 36
 
37 37
 #include <sys/types.h>
38 38
 #include <regex.h>
... ...
@@ -50,6 +50,8 @@
50 50
  *     5        core              avp is in user list
51 51
  *     6        core              avp is in domain list
52 52
  *     7        core              avp is in global list
53
+ *     8        core              avp is in the from avp list
54
+ *     9        core              avp is in the to avp list
53 55
  *
54 56
  */
55 57
 
... ...
@@ -62,8 +64,7 @@
62 62
 #define AVP_FR_TIMER     "fr_timer"      /* Value of final response timer */
63 63
 #define AVP_FR_INV_TIMER "fr_inv_timer"  /* Value of final response invite timer */
64 64
 #define AVP_RPID         "rpid"          /* Remote-Party-ID */
65
-#define AVP_GFLAGS        "gflags"       /* global flags */
66
-
65
+#define AVP_GFLAGS       "gflags"        /* global flags */
67 66
 
68 67
 struct str_int_data {
69 68
 	str name;
... ...
@@ -77,7 +78,7 @@ struct str_str_data {
77 77
 
78 78
 typedef union {
79 79
 	int  n;
80
-	str *s;
80
+	str  s;
81 81
 	regex_t* re;
82 82
 } int_str;
83 83
 
... ...
@@ -90,6 +91,8 @@ typedef struct usr_avp {
90 90
 	void *data;
91 91
 } avp_t;
92 92
 
93
+typedef avp_t* avp_list_t;
94
+
93 95
 
94 96
 /*
95 97
  * AVP search state
... ...
@@ -102,31 +105,40 @@ struct search_state {
102 102
 	regex_t* search_re;    /* Compiled regular expression */
103 103
 };
104 104
 
105
+/* avp aliases structs*/
106
+struct avp_spec {
107
+	int type;
108
+	int_str name;
109
+};
105 110
 
111
+/* AVP types */
106 112
 #define AVP_NAME_STR     (1<<0)
107 113
 #define AVP_VAL_STR      (1<<1)
108 114
 #define AVP_NAME_RE      (1<<2)
109
-#define AVP_USER         (1<<5)
110
-#define AVP_DOMAIN       (1<<6)
111
-#define AVP_GLOBAL       (1<<7)
112 115
 
113
-#define ALL_AVP_CLASSES (AVP_USER|AVP_DOMAIN|AVP_GLOBAL)
116
+/* AVP classes */
117
+#define AVP_CLASS_USER   (1<<5)
118
+#define AVP_CLASS_DOMAIN (1<<6)
119
+#define AVP_CLASS_GLOBAL (1<<7)
114 120
 
115
-/* True for user avps */
116
-#define IS_USER_AVP(flags) ((flags) & AVP_USER)
121
+/* AVP track (either from or to) */
122
+#define AVP_TRACK_FROM   (1<<8)
123
+#define AVP_TRACK_TO     (1<<9)
124
+#define AVP_TRACK_ALL    (AVP_TRACK_FROM|AVP_TRACK_TO)
117 125
 
118
-/* True for domain avps */
119
-#define IS_DOMAIN_AVP(flags) ((flags) & AVP_DOMAIN)
120
-
121
-/* true for global avps */
122
-#define IS_GLOBAL_AVP(flags) ((flags) & AVP_GLOBAL)
126
+#define AVP_CLASS_ALL (AVP_CLASS_USER|AVP_CLASS_DOMAIN|AVP_CLASS_GLOBAL)
123 127
 
124 128
 #define GALIAS_CHAR_MARKER  '$'
125 129
 
126
-/* add functions */
130
+/* Initialize memory structures */
131
+int init_avps(void);
132
+
133
+/* add avp to the list of avps */
127 134
 int add_avp(unsigned short flags, int_str name, int_str val);
135
+int add_avp_list(avp_list_t* list, unsigned short flags, int_str name, int_str val);
128 136
 
129
-int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val);
137
+/* Delete avps with given type and name */
138
+int delete_avp(unsigned short flags, int_str name);
130 139
 
131 140
 /* search functions */
132 141
 avp_t *search_first_avp( unsigned short flags, int_str name,
... ...
@@ -134,24 +146,18 @@ avp_t *search_first_avp( unsigned short flags, int_str name,
134 134
 avp_t *search_next_avp(struct search_state* state, int_str *val);
135 135
 
136 136
 /* free functions */
137
-void reset_user_avps(void);
138
-void reset_domain_avps(void);
137
+void reset_avps(void);
139 138
 
140 139
 void destroy_avp(avp_t *avp);
141
-void destroy_avp_list(avp_t **list );
142
-void destroy_avp_list_unsafe(avp_t **list );
140
+void destroy_avp_list(avp_list_t *list );
141
+void destroy_avp_list_unsafe(avp_list_t *list );
143 142
 
144 143
 /* get func */
145 144
 void get_avp_val(avp_t *avp, int_str *val );
146 145
 str* get_avp_name(avp_t *avp);
147 146
 
148
-avp_t** get_user_avp_list(void);   /* Return current list of user avps */
149
-avp_t** get_domain_avp_list(void); /* Return current list of domain avps */
150
-avp_t** get_global_avp_list(void); /* Return current list of global avps */
151
-
152
-avp_t** set_user_avp_list(avp_t **list);   /* Set current list of user avps to list */
153
-avp_t** set_domain_avp_list(avp_t **list); /* Set current list of domain avps to list */
154
-avp_t** set_global_avp_list(avp_t **list); /* Set current list of global avps to list */
147
+avp_list_t get_avp_list(unsigned short flags);
148
+avp_list_t set_avp_list(unsigned short flags, avp_list_t* list);
155 149
 
156 150
 
157 151
 /* global alias functions (manipulation and parsing)*/