Sfoglia il codice sorgente

- 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 20 anni fa
parent
commit
3da52f21e2
2 ha cambiato i file con 241 aggiunte e 197 eliminazioni
  1. 206 168
      usr_avp.c
  2. 35 29
      usr_avp.h

+ 206 - 168
usr_avp.c

@@ -46,13 +46,15 @@
 #include "mem/mem.h"
 #include "mem/mem.h"
 #include "usr_avp.h"
 #include "usr_avp.h"
 
 
-
-/* avp aliases structs*/
-struct avp_spec {
-	int type;
-	int_str name;
+enum idx {
+	IDX_FROM_USER = 0,
+	IDX_TO_USER,
+	IDX_FROM_DOMAIN,
+	IDX_TO_DOMAIN,
+	IDX_MAX
 };
 };
 
 
+
 struct avp_galias {
 struct avp_galias {
 	str alias;
 	str alias;
 	struct avp_spec  avp;
 	struct avp_spec  avp;
@@ -61,14 +63,61 @@ struct avp_galias {
 
 
 static struct avp_galias *galiases = 0;
 static struct avp_galias *galiases = 0;
 
 
-static avp_t *global_avps = 0;  /* Global attribute list */
-static avp_t *domain_avps = 0;  /* Domain-specific attribute list */
-static avp_t *user_avps = 0;    /* User-specific attribute list */
+static avp_list_t def_list[IDX_MAX];    /* Default AVP lists */
+static avp_list_t* crt_list[IDX_MAX];  /* Pointer to current AVP lists */
+
+/* Global AVP related variables go to shm mem */
+static avp_list_t* def_glist;
+static avp_list_t** crt_glist;
+
+
+/* Initialize AVP lists in private memory and allocate memory
+ * for shared lists
+ */
+int init_avps(void)
+{
+	int i;
+	     /* Empty default lists */
+	memset(def_list, 0, sizeof(avp_list_t) * IDX_MAX);
+	
+	     /* Point current pointers to default lists */
+	for(i = 0; i < IDX_MAX; i++) {
+		crt_list[i] = &def_list[i];
+	}
+
+	def_glist = (avp_list_t*)shm_malloc(sizeof(avp_list_t));
+	crt_glist = (avp_list_t**)shm_malloc(sizeof(avp_list_t*));
+	if (!def_glist || !crt_glist) {
+		LOG(L_ERR, "ERROR: No memory to allocate default global AVP list\n");
+		return -1;
+	}
+	*def_glist = 0;
+	*crt_glist = def_glist;
+	return 0;
+}
+
 
 
-static avp_t **crt_global_avps = &global_avps; /* Pointer to the current list of global attributes */
-static avp_t **crt_domain_avps = &domain_avps; /* Pointer to the current list of domain attributes */
-static avp_t **crt_user_avps   = &user_avps;   /* Pointer to the current list of user attributes */
+/*
+ * Select active AVP list based on the value of flags
+ */
+static avp_list_t* select_list(unsigned short flags)
+{
+	if (flags & AVP_CLASS_USER) {
+		if (flags & AVP_TRACK_TO) {
+			return crt_list[IDX_TO_USER];
+		} else {
+			return crt_list[IDX_FROM_USER];
+		}
+	} else if (flags & AVP_CLASS_DOMAIN) {
+		if (flags & AVP_TRACK_TO) {
+			return crt_list[IDX_TO_DOMAIN];
+		} else {
+			return crt_list[IDX_FROM_DOMAIN];
+		}
+	}
 
 
+	return *crt_glist;
+}
 
 
 inline static unsigned short compute_ID( str *name )
 inline static unsigned short compute_ID( str *name )
 {
 {
@@ -82,7 +131,7 @@ inline static unsigned short compute_ID( str *name )
 }
 }
 
 
 
 
-int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
+int add_avp_list(avp_list_t* list, unsigned short flags, int_str name, int_str val)
 {
 {
 	avp_t *avp;
 	avp_t *avp;
 	str *s;
 	str *s;
@@ -92,7 +141,7 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
 
 
 	assert(list != 0);
 	assert(list != 0);
 
 
-	if ( name.s==0 ) {
+	if (name.s.s == 0 && name.s.len == 0) {
 		LOG(L_ERR,"ERROR:avp:add_avp: 0 ID or NULL NAME AVP!");
 		LOG(L_ERR,"ERROR:avp:add_avp: 0 ID or NULL NAME AVP!");
 		goto error;
 		goto error;
 	}
 	}
@@ -100,20 +149,20 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
 	/* compute the required mem size */
 	/* compute the required mem size */
 	len = sizeof(struct usr_avp);
 	len = sizeof(struct usr_avp);
 	if (flags&AVP_NAME_STR) {
 	if (flags&AVP_NAME_STR) {
-		if ( name.s->s==0 || name.s->len==0) {
+		if ( name.s.s==0 || name.s.len==0) {
 			LOG(L_ERR,"ERROR:avp:add_avp: EMPTY NAME AVP!");
 			LOG(L_ERR,"ERROR:avp:add_avp: EMPTY NAME AVP!");
 			goto error;
 			goto error;
 		}
 		}
 		if (flags&AVP_VAL_STR) {
 		if (flags&AVP_VAL_STR) {
 			len += sizeof(struct str_str_data)-sizeof(void*) 
 			len += sizeof(struct str_str_data)-sizeof(void*) 
-				+ name.s->len + 1 /* Terminating zero for regex search */
-				+ val.s->len + 1; /* Value is zero terminated */
+				+ name.s.len + 1 /* Terminating zero for regex search */
+				+ val.s.len + 1; /* Value is zero terminated */
 		} else {
 		} else {
 			len += sizeof(struct str_int_data)-sizeof(void*) 
 			len += sizeof(struct str_int_data)-sizeof(void*) 
-				+ name.s->len + 1; /* Terminating zero for regex search */
+				+ name.s.len + 1; /* Terminating zero for regex search */
 		}
 		}
 	} else if (flags&AVP_VAL_STR) {
 	} else if (flags&AVP_VAL_STR) {
-		len += sizeof(str)-sizeof(void*) + val.s->len + 1;
+		len += sizeof(str)-sizeof(void*) + val.s.len + 1;
 	}
 	}
 
 
 	avp = (struct usr_avp*)shm_malloc( len );
 	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)
 	}
 	}
 
 
 	avp->flags = flags;
 	avp->flags = flags;
-	avp->id = (flags&AVP_NAME_STR)? compute_ID(name.s) : name.n ;
+	avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
 
 
 	avp->next = *list;
 	avp->next = *list;
 	*list = avp;
 	*list = avp;
@@ -138,29 +187,29 @@ int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val)
 			/* avp type str, int value */
 			/* avp type str, int value */
 			sid = (struct str_int_data*)&(avp->data);
 			sid = (struct str_int_data*)&(avp->data);
 			sid->val = val.n;
 			sid->val = val.n;
-			sid->name.len =name.s->len;
+			sid->name.len =name.s.len;
 			sid->name.s = (char*)sid + sizeof(struct str_int_data);
 			sid->name.s = (char*)sid + sizeof(struct str_int_data);
-			memcpy( sid->name.s , name.s->s, name.s->len);
-			sid->name.s[name.s->len] = '\0'; /* Zero terminator */
+			memcpy( sid->name.s , name.s.s, name.s.len);
+			sid->name.s[name.s.len] = '\0'; /* Zero terminator */
 			break;
 			break;
 		case AVP_VAL_STR:
 		case AVP_VAL_STR:
 			/* avp type ID, str value */
 			/* avp type ID, str value */
 			s = (str*)&(avp->data);
 			s = (str*)&(avp->data);
-			s->len = val.s->len;
+			s->len = val.s.len;
 			s->s = (char*)s + sizeof(str);
 			s->s = (char*)s + sizeof(str);
-			memcpy( s->s, val.s->s , s->len);
+			memcpy( s->s, val.s.s , s->len);
 			s->s[s->len] = 0;
 			s->s[s->len] = 0;
 			break;
 			break;
 		case AVP_NAME_STR|AVP_VAL_STR:
 		case AVP_NAME_STR|AVP_VAL_STR:
 			/* avp type str, str value */
 			/* avp type str, str value */
 			ssd = (struct str_str_data*)&(avp->data);
 			ssd = (struct str_str_data*)&(avp->data);
-			ssd->name.len = name.s->len;
+			ssd->name.len = name.s.len;
 			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
 			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
-			memcpy( ssd->name.s , name.s->s, name.s->len);
-			ssd->name.s[name.s->len]='\0'; /* Zero terminator */
-			ssd->val.len = val.s->len;
+			memcpy( ssd->name.s , name.s.s, name.s.len);
+			ssd->name.s[name.s.len]='\0'; /* Zero terminator */
+			ssd->val.len = val.s.len;
 			ssd->val.s = ssd->name.s + ssd->name.len + 1;
 			ssd->val.s = ssd->name.s + ssd->name.len + 1;
-			memcpy( ssd->val.s , val.s->s, val.s->len);
+			memcpy( ssd->val.s , val.s.s, val.s.len);
 			ssd->val.s[ssd->val.len] = 0;
 			ssd->val.s[ssd->val.len] = 0;
 			break;
 			break;
 	}
 	}
@@ -174,30 +223,23 @@ error:
 int add_avp(unsigned short flags, int_str name, int_str val)
 int add_avp(unsigned short flags, int_str name, int_str val)
 {
 {
 	unsigned short avp_class;
 	unsigned short avp_class;
-	avp_t **list;
-
-	if ((flags & ALL_AVP_CLASSES) == 0) {
-		     /* The caller did not specify any class to search in, so enable
-		      * all of them by default
-		      */
-		flags |= ALL_AVP_CLASSES;
-	}
-
-	if (IS_USER_AVP(flags)) {
-		list = crt_user_avps;
-		avp_class = AVP_USER;
-	} else if (IS_DOMAIN_AVP(flags)) {
-		list = crt_domain_avps;
-		avp_class = AVP_DOMAIN;
-	} else {
-		list = crt_global_avps;
-		avp_class = AVP_GLOBAL;
-	}
-
-		 /* Make that only the selected class is set
-		  * if the caller set more classes in flags
-		  */
-	return add_avp_list(list, flags & (~(ALL_AVP_CLASSES) | avp_class), name, val);
+	avp_list_t* list;
+
+	     /* Add avp to user class if no class has been
+	      * specified by the caller
+	      */
+	if ((flags & AVP_CLASS_ALL) == 0) flags |= AVP_CLASS_USER;
+	if ((flags & AVP_TRACK_ALL) == 0) flags |= AVP_TRACK_FROM;
+	list = select_list(flags);
+
+	if (flags & AVP_CLASS_USER) avp_class = AVP_CLASS_USER;
+	else if (flags & AVP_CLASS_DOMAIN) avp_class = AVP_CLASS_DOMAIN;
+	else avp_class = AVP_CLASS_GLOBAL;
+
+	     /* Make that only the selected class is set
+	      * if the caller set more classes in flags
+	      */
+	return add_avp_list(list, flags & (~(AVP_CLASS_ALL) | avp_class), name, val);
 }
 }
 
 
 
 
@@ -220,7 +262,7 @@ inline str* get_avp_name(avp_t *avp)
 	}
 	}
 
 
 	LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
 	LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
-		avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
+	    avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
 	return 0;
 	return 0;
 }
 }
 
 
@@ -241,36 +283,20 @@ inline void get_avp_val(avp_t *avp, int_str *val)
 			break;
 			break;
 		case AVP_VAL_STR:
 		case AVP_VAL_STR:
 			/* avp type ID, str value */
 			/* avp type ID, str value */
-			val->s = (str*)(&avp->data);
+			val->s = *(str*)(avp->data);
 			break;
 			break;
 		case AVP_NAME_STR|AVP_VAL_STR:
 		case AVP_NAME_STR|AVP_VAL_STR:
 			/* avp type str, str value */
 			/* avp type str, str value */
-			val->s = &(((struct str_str_data*)(&avp->data))->val);
+			val->s = (((struct str_str_data*)(&avp->data))->val);
 			break;
 			break;
 	}
 	}
 }
 }
 
 
 
 
 /* Return the current list of user attributes */
 /* Return the current list of user attributes */
-avp_t** get_user_avp_list(void)
+avp_list_t get_avp_list(unsigned short flags)
 {
 {
-	assert(crt_user_avps != 0);
-	return crt_user_avps;
-}
-
-/* Return the current list of domain attributes */
-avp_t** get_domain_avp_list(void)
-{
-	assert(crt_domain_avps != 0);
-	return crt_domain_avps;
-}
-
-
-/* Return the current list of domain attributes */
-avp_t** get_global_avp_list(void)
-{
-	assert(crt_global_avps != 0);
-	return crt_global_avps;
+	return *select_list(flags);
 }
 }
 
 
 
 
@@ -324,48 +350,49 @@ static inline int match_by_re(avp_t* avp, regex_t* re)
 
 
 avp_t *search_first_avp(unsigned short flags, int_str name, int_str *val, struct search_state* s)
 avp_t *search_first_avp(unsigned short flags, int_str name, int_str *val, struct search_state* s)
 {
 {
+	avp_t* ret;
 	static struct search_state st;
 	static struct search_state st;
+	avp_list_t* list;
 
 
-	assert( crt_user_avps != 0 );
-	assert( crt_domain_avps != 0);
-	assert( crt_global_avps != 0);
-
-	if (name.s==0) {
+	if (name.s.s==0 && name.s.len == 0) {
 		LOG(L_ERR,"ERROR:avp:search_first_avp: 0 ID or NULL NAME AVP!");
 		LOG(L_ERR,"ERROR:avp:search_first_avp: 0 ID or NULL NAME AVP!");
 		return 0;
 		return 0;
 	}
 	}
 
 
 	if (!s) s = &st;
 	if (!s) s = &st;
 
 
-	if ((flags & ALL_AVP_CLASSES) == 0) {
+	if ((flags & AVP_CLASS_ALL) == 0) {
 		     /* The caller did not specify any class to search in, so enable
 		     /* The caller did not specify any class to search in, so enable
 		      * all of them by default
 		      * all of them by default
 		      */
 		      */
-		flags |= ALL_AVP_CLASSES;
+		flags |= AVP_CLASS_ALL;
 	}
 	}
+
+	list = select_list(flags);
+
 	s->flags = flags;
 	s->flags = flags;
-	if (IS_USER_AVP(flags)) {
-		s->avp = *crt_user_avps;
-	} else if (IS_DOMAIN_AVP(flags)) {
-		s->avp = *crt_domain_avps;
-	} else {
-		s->avp = *crt_global_avps;
-	}
+	s->avp = *list;
 	s->name = name;
 	s->name = name;
 
 
 	if (flags & AVP_NAME_STR) {
 	if (flags & AVP_NAME_STR) {
-		s->id = compute_ID(name.s);
+		s->id = compute_ID(&name.s);
 	}
 	}
 
 
-	return search_next_avp(s, val);
+        ret = search_next_avp(s, val);
+
+	     /* Make sure that search next avp stays in the same class as the first
+	      * avp found
+	      */
+	if (s && ret) s->flags = (flags & ~AVP_CLASS_ALL) | (ret->flags & AVP_CLASS_ALL);
+	return ret;
 }
 }
 
 
 
 
 
 
 avp_t *search_next_avp(struct search_state* s, int_str *val )
 avp_t *search_next_avp(struct search_state* s, int_str *val )
 {
 {
-	avp_t* avp;
 	int matched;
 	int matched;
+	avp_t* avp;
 
 
 	if (s == 0) {
 	if (s == 0) {
 		LOG(L_ERR, "search_next:avp: Invalid parameter value\n");
 		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 )
 			if (s->flags & AVP_NAME_RE) {
 			if (s->flags & AVP_NAME_RE) {
 				matched = match_by_re(s->avp, s->name.re);
 				matched = match_by_re(s->avp, s->name.re);
 			} else if (s->flags & AVP_NAME_STR) {
 			} else if (s->flags & AVP_NAME_STR) {
-				matched = match_by_name(s->avp, s->id, s->name.s);
+				matched = match_by_name(s->avp, s->id, &s->name.s);
 			} else {
 			} else {
 				matched = match_by_id(s->avp, s->name.n);
 				matched = match_by_id(s->avp, s->name.n);
 			}
 			}
@@ -389,14 +416,14 @@ avp_t *search_next_avp(struct search_state* s, int_str *val )
 			}
 			}
 		}
 		}
 
 
-		if (IS_USER_AVP(s->flags)) {
-			s->flags &= ~AVP_USER;
-			s->avp = *crt_domain_avps;
-		} else if (IS_DOMAIN_AVP(s->flags)) {
-			s->flags &= ~AVP_DOMAIN;
-			s->avp = *crt_global_avps;
+		if (s->flags & AVP_CLASS_USER) {
+			s->flags &= ~AVP_CLASS_USER;
+			s->avp = *select_list(s->flags);
+		} else if (s->flags & AVP_CLASS_DOMAIN) {
+			s->flags &= ~AVP_CLASS_DOMAIN;
+			s->avp = *select_list(s->flags);
 		} else {
 		} else {
-			s->flags &= ~AVP_GLOBAL;
+			s->flags &= ~AVP_CLASS_GLOBAL;
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
@@ -405,20 +432,37 @@ avp_t *search_next_avp(struct search_state* s, int_str *val )
 }
 }
 
 
 
 
-
-
+/* FIXME */
 /********* free functions ********/
 /********* free functions ********/
 
 
-void destroy_avp( avp_t *avp_del)
+void destroy_avp(avp_t *avp_del)
 {
 {
+	int i;
 	avp_t *avp, *avp_prev;
 	avp_t *avp, *avp_prev;
 
 
-	for( avp_prev=0,avp=*crt_user_avps ; avp ; avp_prev=avp,avp=avp->next ) {
+	for (i = 0; i < IDX_MAX; i++) {
+		for( avp_prev=0,avp=*crt_list[i] ; avp ; 
+		     avp_prev=avp,avp=avp->next ) {
+			if (avp==avp_del) {
+				if (avp_prev) {
+					avp_prev->next=avp->next;
+				} else {
+					*crt_list[i] = avp->next;
+				}
+				shm_free(avp);
+				return;
+			}
+		}
+	}
+
+	for( avp_prev=0,avp=**crt_glist ; avp ; 
+	     avp_prev=avp,avp=avp->next ) {
 		if (avp==avp_del) {
 		if (avp==avp_del) {
-			if (avp_prev)
+			if (avp_prev) {
 				avp_prev->next=avp->next;
 				avp_prev->next=avp->next;
-			else
-				*crt_user_avps = avp->next;
+			} else {
+				**crt_glist = avp->next;
+			}
 			shm_free(avp);
 			shm_free(avp);
 			return;
 			return;
 		}
 		}
@@ -426,7 +470,7 @@ void destroy_avp( avp_t *avp_del)
 }
 }
 
 
 
 
-void destroy_avp_list_unsafe( avp_t **list )
+void destroy_avp_list_unsafe(avp_list_t* list)
 {
 {
 	avp_t *avp, *foo;
 	avp_t *avp, *foo;
 
 
@@ -440,7 +484,7 @@ void destroy_avp_list_unsafe( avp_t **list )
 }
 }
 
 
 
 
-inline void destroy_avp_list( avp_t **list )
+inline void destroy_avp_list(avp_list_t* list)
 {
 {
 	avp_t *avp, *foo;
 	avp_t *avp, *foo;
 
 
@@ -455,60 +499,42 @@ inline void destroy_avp_list( avp_t **list )
 }
 }
 
 
 
 
-void reset_user_avps(void)
+void reset_avps(void)
 {
 {
-	assert( crt_user_avps!=0 );
-	
-	if ( crt_user_avps!=&user_avps) {
-		crt_user_avps = &user_avps;
+	int i;
+	for(i = 0; i < IDX_MAX; i++) {
+		crt_list[i] = &def_list[i];
+		destroy_avp_list(crt_list[i]);
 	}
 	}
-	destroy_avp_list( crt_user_avps );
-}
-
-
-void reset_domain_avps(void)
-{
-	assert( crt_user_avps!=0 );
-	
-	if ( crt_user_avps!=&domain_avps) {
-		crt_domain_avps = &domain_avps;
-	}
-	     /* Do not destroy avps here, domain module takes care of it */
-}
-
-
-avp_t** set_user_avp_list( avp_t **list )
-{
-	avp_t **foo;
-
-	assert( crt_user_avps!=0 );
-
-	foo = crt_user_avps;
-	crt_user_avps = list;
-	return foo;
 }
 }
 
 
 
 
-avp_t** set_domain_avp_list( avp_t **list )
+avp_list_t set_avp_list( unsigned short flags, avp_list_t* list )
 {
 {
-	avp_t **foo;
-
-	assert( crt_domain_avps!=0 );
+	avp_list_t* prev;
 
 
-	foo = crt_domain_avps;
-	crt_domain_avps = list;
-	return foo;
-}
-
-avp_t** set_global_avp_list( avp_t **list )
-{
-	avp_t **foo;
-
-	assert( crt_global_avps!=0 );
+	if (flags & AVP_CLASS_USER) {
+		if (flags & AVP_TRACK_FROM) {
+			prev = crt_list[IDX_FROM_USER];
+			crt_list[IDX_FROM_USER] = list;
+		} else {
+			prev = crt_list[IDX_TO_USER];
+			crt_list[IDX_TO_USER] = list;
+		}
+	} else if (flags & AVP_CLASS_DOMAIN) {
+		if (flags & AVP_TRACK_FROM) {
+			prev = crt_list[IDX_FROM_DOMAIN];
+			crt_list[IDX_FROM_DOMAIN] = list;
+		} else {
+			prev = crt_list[IDX_TO_DOMAIN];
+			crt_list[IDX_TO_DOMAIN] = list;
+		}
+	} else {
+		prev = *crt_glist;
+	        *crt_glist = list;
+	}
 
 
-	foo = crt_global_avps;
-	crt_global_avps = list;
-	return foo;
+	return *prev;
 }
 }
 
 
 
 
@@ -528,9 +554,9 @@ static inline int check_avp_galias(str *alias, int type, int_str avp_name)
 		/*check for duplicated avp names */
 		/*check for duplicated avp names */
 		if (type==ga->avp.type) {
 		if (type==ga->avp.type) {
 			if (type&AVP_NAME_STR){
 			if (type&AVP_NAME_STR){
-				if (avp_name.s->len==ga->avp.name.s->len &&
-				(strncasecmp(avp_name.s->s, ga->avp.name.s->s,
-							 					avp_name.s->len)==0) )
+				if (avp_name.s.len==ga->avp.name.s.len &&
+				    (strncasecmp(avp_name.s.s, ga->avp.name.s.s,
+						 avp_name.s.len)==0) )
 					return -1;
 					return -1;
 			} else {
 			} else {
 				if (avp_name.n==ga->avp.name.n)
 				if (avp_name.n==ga->avp.name.n)
@@ -546,8 +572,8 @@ int add_avp_galias(str *alias, int type, int_str avp_name)
 {
 {
 	struct avp_galias *ga;
 	struct avp_galias *ga;
 
 
-	if ((type&AVP_NAME_STR && (!avp_name.s || !avp_name.s->s ||
-								!avp_name.s->len)) ||!alias || !alias->s ||
+	if ((type&AVP_NAME_STR && (!avp_name.s.s ||
+				   !avp_name.s.len)) ||!alias || !alias->s ||
 		!alias->len ){
 		!alias->len ){
 		LOG(L_ERR, "ERROR:add_avp_galias: null params received\n");
 		LOG(L_ERR, "ERROR:add_avp_galias: null params received\n");
 		goto error;
 		goto error;
@@ -575,17 +601,16 @@ int add_avp_galias(str *alias, int type, int_str avp_name)
 	ga->avp.type = type&AVP_NAME_STR;
 	ga->avp.type = type&AVP_NAME_STR;
 
 
 	if (type&AVP_NAME_STR) {
 	if (type&AVP_NAME_STR) {
-		ga->avp.name.s = (str*)pkg_malloc( sizeof(str)+avp_name.s->len+1 );
-		if (ga->avp.name.s==0) {
+		ga->avp.name.s.s = (char*)pkg_malloc( avp_name.s.len+1 );
+		if (ga->avp.name.s.s==0) {
 			LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
 			LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
 			goto error2;
 			goto error2;
 		}
 		}
-		ga->avp.name.s->s = ((char*)ga->avp.name.s)+sizeof(str);
-		ga->avp.name.s->len = avp_name.s->len;
-		memcpy( ga->avp.name.s->s, avp_name.s->s, avp_name.s->len);
-		ga->avp.name.s->s[avp_name.s->len] = 0;
+		ga->avp.name.s.len = avp_name.s.len;
+		memcpy( ga->avp.name.s.s, avp_name.s.s, avp_name.s.len);
+		ga->avp.name.s.s[avp_name.s.len] = 0;
 		DBG("DEBUG:add_avp_galias: registering <%s> for avp name <%s>\n",
 		DBG("DEBUG:add_avp_galias: registering <%s> for avp name <%s>\n",
-			ga->alias.s, ga->avp.name.s->s);
+			ga->alias.s, ga->avp.name.s.s);
 	} else {
 	} else {
 		ga->avp.name.n = avp_name.n;
 		ga->avp.name.n = avp_name.n;
 		DBG("DEBUG:add_avp_galias: registering <%s> for avp id <%d>\n",
 		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)
 		switch (c) {
 		switch (c) {
 			case 's': case 'S':
 			case 's': case 'S':
 				*type = AVP_NAME_STR;
 				*type = AVP_NAME_STR;
-				avp_name->s = name;
+				avp_name->s = *name;
 				break;
 				break;
 			case 'i': case 'I':
 			case 'i': case 'I':
 				*type = 0;
 				*type = 0;
@@ -659,7 +684,7 @@ int parse_avp_name( str *name, int *type, int_str *avp_name)
 	} else {
 	} else {
 		/*default is string name*/
 		/*default is string name*/
 		*type = AVP_NAME_STR;
 		*type = AVP_NAME_STR;
-		avp_name->s = name;
+		avp_name->s = *name;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -755,3 +780,16 @@ parse_error:
 error:
 error:
 	return -1;
 	return -1;
 }
 }
+
+
+int delete_avp(unsigned short flags, int_str name)
+{
+	struct search_state st;
+	avp_t* avp;
+
+	avp = search_first_avp(flags, name, 0, &st);
+	while(avp) {
+		destroy_avp(avp);
+		avp = search_next_avp(&st, 0);
+	}
+}

+ 35 - 29
usr_avp.h

@@ -31,8 +31,8 @@
  *  2005-02-14  list with FLAGS USAGE added (bogdan)
  *  2005-02-14  list with FLAGS USAGE added (bogdan)
  */
  */
 
 
-#ifndef _SER_URS_AVP_H_
-#define _SER_URS_AVP_H_
+#ifndef _SER_USR_AVP_H_
+#define _SER_USR_AVP_H_
 
 
 #include <sys/types.h>
 #include <sys/types.h>
 #include <regex.h>
 #include <regex.h>
@@ -50,6 +50,8 @@
  *     5        core              avp is in user list
  *     5        core              avp is in user list
  *     6        core              avp is in domain list
  *     6        core              avp is in domain list
  *     7        core              avp is in global list
  *     7        core              avp is in global list
+ *     8        core              avp is in the from avp list
+ *     9        core              avp is in the to avp list
  *
  *
  */
  */
 
 
@@ -62,8 +64,7 @@
 #define AVP_FR_TIMER     "fr_timer"      /* Value of final response timer */
 #define AVP_FR_TIMER     "fr_timer"      /* Value of final response timer */
 #define AVP_FR_INV_TIMER "fr_inv_timer"  /* Value of final response invite timer */
 #define AVP_FR_INV_TIMER "fr_inv_timer"  /* Value of final response invite timer */
 #define AVP_RPID         "rpid"          /* Remote-Party-ID */
 #define AVP_RPID         "rpid"          /* Remote-Party-ID */
-#define AVP_GFLAGS        "gflags"       /* global flags */
-
+#define AVP_GFLAGS       "gflags"        /* global flags */
 
 
 struct str_int_data {
 struct str_int_data {
 	str name;
 	str name;
@@ -77,7 +78,7 @@ struct str_str_data {
 
 
 typedef union {
 typedef union {
 	int  n;
 	int  n;
-	str *s;
+	str  s;
 	regex_t* re;
 	regex_t* re;
 } int_str;
 } int_str;
 
 
@@ -90,6 +91,8 @@ typedef struct usr_avp {
 	void *data;
 	void *data;
 } avp_t;
 } avp_t;
 
 
+typedef avp_t* avp_list_t;
+
 
 
 /*
 /*
  * AVP search state
  * AVP search state
@@ -102,31 +105,40 @@ struct search_state {
 	regex_t* search_re;    /* Compiled regular expression */
 	regex_t* search_re;    /* Compiled regular expression */
 };
 };
 
 
+/* avp aliases structs*/
+struct avp_spec {
+	int type;
+	int_str name;
+};
 
 
+/* AVP types */
 #define AVP_NAME_STR     (1<<0)
 #define AVP_NAME_STR     (1<<0)
 #define AVP_VAL_STR      (1<<1)
 #define AVP_VAL_STR      (1<<1)
 #define AVP_NAME_RE      (1<<2)
 #define AVP_NAME_RE      (1<<2)
-#define AVP_USER         (1<<5)
-#define AVP_DOMAIN       (1<<6)
-#define AVP_GLOBAL       (1<<7)
 
 
-#define ALL_AVP_CLASSES (AVP_USER|AVP_DOMAIN|AVP_GLOBAL)
+/* AVP classes */
+#define AVP_CLASS_USER   (1<<5)
+#define AVP_CLASS_DOMAIN (1<<6)
+#define AVP_CLASS_GLOBAL (1<<7)
 
 
-/* True for user avps */
-#define IS_USER_AVP(flags) ((flags) & AVP_USER)
+/* AVP track (either from or to) */
+#define AVP_TRACK_FROM   (1<<8)
+#define AVP_TRACK_TO     (1<<9)
+#define AVP_TRACK_ALL    (AVP_TRACK_FROM|AVP_TRACK_TO)
 
 
-/* True for domain avps */
-#define IS_DOMAIN_AVP(flags) ((flags) & AVP_DOMAIN)
-
-/* true for global avps */
-#define IS_GLOBAL_AVP(flags) ((flags) & AVP_GLOBAL)
+#define AVP_CLASS_ALL (AVP_CLASS_USER|AVP_CLASS_DOMAIN|AVP_CLASS_GLOBAL)
 
 
 #define GALIAS_CHAR_MARKER  '$'
 #define GALIAS_CHAR_MARKER  '$'
 
 
-/* add functions */
+/* Initialize memory structures */
+int init_avps(void);
+
+/* add avp to the list of avps */
 int add_avp(unsigned short flags, int_str name, int_str val);
 int add_avp(unsigned short flags, int_str name, int_str val);
+int add_avp_list(avp_list_t* list, unsigned short flags, int_str name, int_str val);
 
 
-int add_avp_list(avp_t** list, unsigned short flags, int_str name, int_str val);
+/* Delete avps with given type and name */
+int delete_avp(unsigned short flags, int_str name);
 
 
 /* search functions */
 /* search functions */
 avp_t *search_first_avp( unsigned short flags, int_str name,
 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,
 avp_t *search_next_avp(struct search_state* state, int_str *val);
 avp_t *search_next_avp(struct search_state* state, int_str *val);
 
 
 /* free functions */
 /* free functions */
-void reset_user_avps(void);
-void reset_domain_avps(void);
+void reset_avps(void);
 
 
 void destroy_avp(avp_t *avp);
 void destroy_avp(avp_t *avp);
-void destroy_avp_list(avp_t **list );
-void destroy_avp_list_unsafe(avp_t **list );
+void destroy_avp_list(avp_list_t *list );
+void destroy_avp_list_unsafe(avp_list_t *list );
 
 
 /* get func */
 /* get func */
 void get_avp_val(avp_t *avp, int_str *val );
 void get_avp_val(avp_t *avp, int_str *val );
 str* get_avp_name(avp_t *avp);
 str* get_avp_name(avp_t *avp);
 
 
-avp_t** get_user_avp_list(void);   /* Return current list of user avps */
-avp_t** get_domain_avp_list(void); /* Return current list of domain avps */
-avp_t** get_global_avp_list(void); /* Return current list of global avps */
-
-avp_t** set_user_avp_list(avp_t **list);   /* Set current list of user avps to list */
-avp_t** set_domain_avp_list(avp_t **list); /* Set current list of domain avps to list */
-avp_t** set_global_avp_list(avp_t **list); /* Set current list of global avps to list */
+avp_list_t get_avp_list(unsigned short flags);
+avp_list_t set_avp_list(unsigned short flags, avp_list_t* list);
 
 
 
 
 /* global alias functions (manipulation and parsing)*/
 /* global alias functions (manipulation and parsing)*/