Commit d7c64742 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added two new interfaces on Zach requests...

Added two new interfaces on Zach requests http://lists.freediameter.net/pipermail/help/2012-January/000312.html and http://lists.freediameter.net/pipermail/help/2012-January/000311.html
parent 7d6e9148
...@@ -850,6 +850,10 @@ void fd_dict_dump(struct dictionary * dict); ...@@ -850,6 +850,10 @@ void fd_dict_dump(struct dictionary * dict);
/* Function to access full contents of the dictionary, see doc in dictionary.c */ /* Function to access full contents of the dictionary, see doc in dictionary.c */
int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel); int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel);
/* Function to remove an entry from the dictionary.
This cannot be used if the object has children (for example a vendor with vendor-specific AVPs).
In such case, the children must be removed first. */
int fd_dict_delete(struct dict_object * obj);
/* /*
*************************************************************************** ***************************************************************************
...@@ -1859,6 +1863,9 @@ int fd_sess_state_retrieve_internal ( struct session_handler * handler, struct s ...@@ -1859,6 +1863,9 @@ int fd_sess_state_retrieve_internal ( struct session_handler * handler, struct s
void fd_sess_dump(int level, struct session * session); void fd_sess_dump(int level, struct session * session);
void fd_sess_dump_hdl(int level, struct session_handler * handler); void fd_sess_dump_hdl(int level, struct session_handler * handler);
/* For statistics / monitoring: get the number of struct session in memory */
int fd_sess_getcount(uint32_t *cnt);
/*============================================================*/ /*============================================================*/
/* ROUTING */ /* ROUTING */
/*============================================================*/ /*============================================================*/
......
...@@ -1811,6 +1811,44 @@ error_free: ...@@ -1811,6 +1811,44 @@ error_free:
return ret; return ret;
} }
int fd_dict_delete(struct dict_object * obj)
{
int i;
struct dictionary * dict;
int ret=0;
/* check params */
CHECK_PARAMS( verify_object(obj) && obj->dico);
dict = obj->dico;
/* Lock the dictionary for change */
CHECK_POSIX( pthread_rwlock_wrlock(&dict->dict_lock) );
/* check the object is not sentinel for another list */
for (i=0; i<NB_LISTS_PER_OBJ; i++) {
if (!_OBINFO(obj).haslist[i] && !(FD_IS_LIST_EMPTY(&obj->list[i]))) {
/* There are children, this is not good */
ret = EINVAL;
TRACE_DEBUG (FULL, "Cannot delete object, list %d not empty:", i);
#if 0
dump_list(&obj->list[i], 0,0,0);
#endif
break;
}
}
/* ok, now destroy the object */
if (!ret)
destroy_object(obj);
/* Unlock */
CHECK_POSIX( pthread_rwlock_unlock(&dict->dict_lock) );
return ret;
}
int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, void * what, struct dict_object **result, int retval ) int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, void * what, struct dict_object **result, int retval )
{ {
int ret = 0; int ret = 0;
......
...@@ -114,6 +114,8 @@ static struct { ...@@ -114,6 +114,8 @@ static struct {
#define H_LIST( _hash ) (&(sess_hash[H_MASK(_hash)].sentinel)) #define H_LIST( _hash ) (&(sess_hash[H_MASK(_hash)].sentinel))
#define H_LOCK( _hash ) (&(sess_hash[H_MASK(_hash)].lock )) #define H_LOCK( _hash ) (&(sess_hash[H_MASK(_hash)].lock ))
static uint32_t sess_cnt = 0; /* counts all active session (that are in the expiry list) */
/* The following are used to generate sid values that are eternaly unique */ /* The following are used to generate sid values that are eternaly unique */
static uint32_t sid_h; /* initialized to the current time in fd_sess_init */ static uint32_t sid_h; /* initialized to the current time in fd_sess_init */
static uint32_t sid_l; /* incremented each time a session id is created */ static uint32_t sid_l; /* incremented each time a session id is created */
...@@ -484,6 +486,7 @@ int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, ...@@ -484,6 +486,7 @@ int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen,
break; break;
} }
fd_list_insert_after( li, &sess->expire ); fd_list_insert_after( li, &sess->expire );
sess_cnt++;
/* We added a new expiring element, we must signal */ /* We added a new expiring element, we must signal */
if (li == &exp_sentinel) { if (li == &exp_sentinel) {
...@@ -611,7 +614,10 @@ int fd_sess_destroy ( struct session ** session ) ...@@ -611,7 +614,10 @@ int fd_sess_destroy ( struct session ** session )
/* Unlink from the expiry list */ /* Unlink from the expiry list */
CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
fd_list_unlink( &sess->expire ); /* no need to signal the condition here */ if (!FD_IS_LIST_EMPTY(&sess->expire)) {
sess_cnt--;
fd_list_unlink( &sess->expire ); /* no need to signal the condition here */
}
CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
/* Now move all states associated to this session into deleted_states */ /* Now move all states associated to this session into deleted_states */
...@@ -889,3 +895,12 @@ void fd_sess_dump_hdl(int level, struct session_handler * handler) ...@@ -889,3 +895,12 @@ void fd_sess_dump_hdl(int level, struct session_handler * handler)
} }
fd_log_debug("\t %*s -- end of handler @%p --\n", level, "", handler); fd_log_debug("\t %*s -- end of handler @%p --\n", level, "", handler);
} }
int fd_sess_getcount(uint32_t *cnt)
{
CHECK_PARAMS(cnt);
CHECK_POSIX( pthread_mutex_lock( &exp_lock ) );
*cnt = sess_cnt;
CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) );
return 0;
}
...@@ -165,6 +165,44 @@ int main(int argc, char *argv[]) ...@@ -165,6 +165,44 @@ int main(int argc, char *argv[])
} }
} }
/* Test delete function */
{
struct fd_list * li = NULL;
struct fd_list * sentinel = NULL;
struct dict_object * obj=NULL;
vendor_id_t vid = 0;
int count = 0, cntbkp;
CHECK( 0, fd_dict_search(fd_g_config->cnf_dict, DICT_VENDOR, VENDOR_BY_ID, &vid, &obj, ENOENT) );
CHECK( EINVAL, fd_dict_delete(obj) );
CHECK( 0, fd_dict_getlistof(AVP_BY_NAME, obj, &sentinel));
obj = NULL;
for (li = sentinel->next; li != sentinel; li = li->next) {
struct dict_avp_data data;
CHECK( 0, fd_dict_getval(li->o, &data) );
count++;
if (data.avp_basetype != AVP_TYPE_GROUPED)
obj = li->o;
}
CHECK(1, obj ? 1 : 0 );
#if 1
fd_dict_dump_object(obj);
#endif
CHECK( 0, fd_dict_delete(obj) );
cntbkp = count;
count = 0;
for (li = sentinel->next; li != sentinel; li = li->next) {
count++;
}
CHECK( 1, cntbkp - count );
}
/* That's all for the tests yet */ /* That's all for the tests yet */
PASSTEST(); PASSTEST();
} }
......
...@@ -173,6 +173,22 @@ int main(int argc, char *argv[]) ...@@ -173,6 +173,22 @@ int main(int argc, char *argv[])
CHECK( 0, fd_sess_destroy( &sess2 ) ); CHECK( 0, fd_sess_destroy( &sess2 ) );
CHECK( 0, fd_sess_destroy( &sess1 ) ); CHECK( 0, fd_sess_destroy( &sess1 ) );
} }
/* Test fd_sess_getcount */
{
uint32_t cnt;
CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, CONSTSTRLEN(TEST_DIAM_ID), NULL, 0 ) );
CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, CONSTSTRLEN(TEST_DIAM_ID), NULL, 0 ) );
CHECK( 0, fd_sess_getcount(&cnt));
CHECK( 2, cnt);
CHECK( 0, fd_sess_destroy( &sess2 ) );
CHECK( 0, fd_sess_getcount(&cnt));
CHECK( 1, cnt);
CHECK( 0, fd_sess_destroy( &sess1 ) );
CHECK( 0, fd_sess_getcount(&cnt));
CHECK( 0, cnt);
}
/* Test fd_sess_fromsid */ /* Test fd_sess_fromsid */
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment