Mercurial > hg > freeDiameter-dtls
changeset 1080:b380c9f3be1e
Merge
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Thu, 02 May 2013 16:09:50 +0800 |
parents | 758b21ae6c3e (current diff) b36c81e52e9a (diff) |
children | d0017c5dde61 |
files | include/freeDiameter/libfdproto.h |
diffstat | 15 files changed, 763 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/extensions/app_diameap/diameap_eap.c Thu May 02 16:09:06 2013 +0800 +++ b/extensions/app_diameap/diameap_eap.c Thu May 02 16:09:50 2013 +0800 @@ -372,7 +372,7 @@ case EAP_INTEGRITY_CHECK: if ((*eap_sm->selectedMethod->eap_method_check)(eap_sm, - eap_i->aaaEapRespData) == FALSE) + &eap_i->aaaEapRespData) == FALSE) { TRACE_DEBUG(INFO,"%s[EAP Protocol] Invalid EAP packet received {Type=%d, Vendor=%d}. Integrity check failed (non fatal error).",DIAMEAP_EXTENSION,eap_sm->currentMethod,eap_sm->currentVendor); //non_fata_error @@ -433,7 +433,7 @@ } } if ((*eap_sm->selectedMethod->eap_method_process)(eap_sm, - eap_i->aaaEapRespData)) + &eap_i->aaaEapRespData)) { TRACE_DEBUG(INFO,"%s[EAP Protocol] [%s plugin] Authentication process failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname); *non_fatal_error = TRUE;
--- a/extensions/app_diameap/diameap_plugins.c Thu May 02 16:09:06 2013 +0800 +++ b/extensions/app_diameap/diameap_plugins.c Thu May 02 16:09:50 2013 +0800 @@ -262,7 +262,7 @@ if (registerplugin->check) { plugin->eap_method_check = (boolean(*)(struct eap_state_machine *, - struct eap_packet)) dlsym(plugin->handler, + struct eap_packet*)) dlsym(plugin->handler, registerplugin->check); if (plugin->eap_method_check == NULL) { @@ -284,7 +284,7 @@ if (registerplugin->process) { plugin->eap_method_process = (int(*)(struct eap_state_machine *, - struct eap_packet)) dlsym(plugin->handler, + struct eap_packet*)) dlsym(plugin->handler, registerplugin->process); if (plugin->eap_method_process == NULL) {
--- a/extensions/app_diameap/libdiameap.h Thu May 02 16:09:06 2013 +0800 +++ b/extensions/app_diameap/libdiameap.h Thu May 02 16:09:50 2013 +0800 @@ -109,9 +109,9 @@ u8 identifier,struct eap_packet * eapPacket); /* address of the eap_method_buildReq method */ int (*eap_method_getTimeout)(struct eap_state_machine *smd, int * timeout); /* address of the eap_method_getTimeout method */ boolean (*eap_method_check)(struct eap_state_machine *smd, - struct eap_packet eapRespData); /* address of the eap_method_check method */ + struct eap_packet * eapRespData); /* address of the eap_method_check method */ int (*eap_method_process)(struct eap_state_machine *smd, - struct eap_packet eapRespData); /* address of the eap_method_process method */ + struct eap_packet * eapRespData); /* address of the eap_method_process method */ boolean (*eap_method_isDone)(struct eap_state_machine *smd); /* address of the eap_method_isDone method */ int (*eap_method_getKey)(struct eap_state_machine *smd, u8 ** msk,int *msklength, u8 ** emsk,int *emsklength); /* address of the eap_method_getKey method */
--- a/extensions/dbg_interactive/queues.i Thu May 02 16:09:06 2013 +0800 +++ b/extensions/dbg_interactive/queues.i Thu May 02 16:09:50 2013 +0800 @@ -65,12 +65,7 @@ /* Get the length of the queue (nb elements) */ int length() { - int l; - int ret = fd_fifo_length ( $self, &l, NULL ); - if (ret != 0) { - DI_ERROR(ret, NULL, NULL); - } - return l; + return fd_fifo_length ( $self ) ; } /* Is the threashold function useful here? TODO... */
--- a/extensions/dbg_monitor/dbg_monitor.c Thu May 02 16:09:06 2013 +0800 +++ b/extensions/dbg_monitor/dbg_monitor.c Thu May 02 16:09:50 2013 +0800 @@ -49,6 +49,28 @@ EXTENSION_ENTRY("dbg_monitor", monitor_main); + + +/* Display information about a queue */ +static void display_info(char * queue_desc, char * peer, int current_count, int limit_count, int highest_count, long long total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last) +{ + long long ms = (total->tv_sec * 1000000) + (total->tv_nsec / 1000); + long double throughput = (long double)total_count * 1000000; + throughput /= ms; + if (peer) { + TRACE_DEBUG(INFO, "'%s'@'%s': cur:%d/%d, h:%d, T:%lld in %ld.%06lds (%.2LFitems/s), blocked:%ld.%06lds, last processing:%ld.%06lds", + queue_desc, peer, current_count, limit_count, highest_count, + total_count, total->tv_sec, total->tv_nsec, throughput, + blocking->tv_sec, blocking->tv_nsec, last->tv_sec, last->tv_nsec); + } else { + TRACE_DEBUG(INFO, "Global '%s': cur:%d/%d, h:%d, T:%lld in %ld.%06lds (%.2LFitems/s), blocked:%ld.%06lds, last processing:%ld.%06lds", + queue_desc, current_count, limit_count, highest_count, + total_count, total->tv_sec, total->tv_nsec, throughput, + blocking->tv_sec, blocking->tv_nsec, last->tv_sec, last->tv_nsec); + } +} + /* Thread to display periodical debug information */ static pthread_t thr; static void * mn_thr(void * arg) @@ -58,18 +80,51 @@ /* Loop */ while (1) { + int current_count, limit_count, highest_count; + long long total_count; + struct timespec total, blocking, last; + struct fd_list * li; + #ifdef DEBUG for (i++; i % 30; i++) { fd_log_debug("[dbg_monitor] %ih%*im%*is", i/3600, 2, (i/60) % 60 , 2, i%60); /* This makes it easier to detect inactivity periods in the log file */ sleep(1); } #else /* DEBUG */ - sleep(3600); /* 1 hour */ + sleep(3599); /* 1 hour */ #endif /* DEBUG */ - fd_log_debug("[dbg_monitor] Dumping current information"); - CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_QUEUES, 0, NULL), /* continue */); + TRACE_DEBUG(INFO, "[dbg_monitor] Dumping queues statistics"); + + CHECK_FCT_DO( fd_stat_getstats(STAT_G_LOCAL, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), ); + display_info("Local delivery", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last); + + CHECK_FCT_DO( fd_stat_getstats(STAT_G_INCOMING, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), ); + display_info("Total received", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last); + + CHECK_FCT_DO( fd_stat_getstats(STAT_G_OUTGOING, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), ); + display_info("Total sending", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last); + + + CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ ); + + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct peer_hdr * p = (struct peer_hdr *)li->o; + + fd_peer_dump(p, NONE); + + CHECK_FCT_DO( fd_stat_getstats(STAT_P_PSM, p, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), ); + display_info("Events, incl. recept", p->info.pi_diamid, current_count, limit_count, highest_count, total_count, &total, &blocking, &last); + + CHECK_FCT_DO( fd_stat_getstats(STAT_P_TOSEND, p, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), ); + display_info("Outgoing", p->info.pi_diamid, current_count, limit_count, highest_count, total_count, &total, &blocking, &last); + + } + + CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); + + + CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_SERV, 0, NULL), /* continue */); - CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_PEERS, 0, NULL), /* continue */); sleep(1); }
--- a/include/freeDiameter/libfdcore.h Thu May 02 16:09:06 2013 +0800 +++ b/include/freeDiameter/libfdcore.h Thu May 02 16:09:50 2013 +0800 @@ -860,8 +860,8 @@ /* MONITORING */ /*============================================================*/ -/* These functions allows an extension to collect state information about the - * framework state, as well as hooks at some key checkpoints in the processing +/* These functions allow an extension to collect state information about the + * framework, as well as being hooked at some key checkpoints in the processing * for logging / statistics purpose. */ @@ -1096,8 +1096,8 @@ * PARAMETERS: * stat : Which queue is being queried * peer : (depending on the stat parameter) which peer is being queried - * len : (out) The number of items in the queue currently - * max : (out) The max number of items the queue accepts before becoming blocking -- 0 means no max. + * current_count : (out) The number of items in the queue currently + * limit_count : (out) The max number of items the queue accepts before becoming blocking -- 0 means no max. * highest_count : (out) The highest count the queue has reached since startup * total_count : (out) Total number of items that this queue has processed (always growing, use deltas for monitoring) * total : (out) Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) @@ -1113,7 +1113,7 @@ * EINVAL : A parameter is invalid. */ int fd_stat_getstats(enum fd_stat_type stat, struct peer_hdr * peer, - int * len, int * max, int * highest_count, long long * total_count, + int * current_count, int * limit_count, int * highest_count, long long * total_count, struct timespec * total, struct timespec * blocking, struct timespec * last); /*============================================================*/
--- a/include/freeDiameter/libfdproto.h Thu May 02 16:09:06 2013 +0800 +++ b/include/freeDiameter/libfdproto.h Thu May 02 16:09:50 2013 +0800 @@ -2988,32 +2988,17 @@ int fd_fifo_move ( struct fifo * oldq, struct fifo * newq, struct fifo ** loc_update ); /* - * FUNCTION: fd_fifo_length - * - * PARAMETERS: - * queue : The queue from which to retrieve the number of elements. - * length : Upon success, the current number of elements in the queue is stored here. - * max : the maximum number of elements as specified during creation. Can be NULL. - * - * DESCRIPTION: - * Retrieve the number of elements in a queue. - * - * RETURN VALUE: - * 0 : The length of the queue has been written. - * EINVAL : A parameter is invalid. - */ -int fd_fifo_length ( struct fifo * queue, int * length, int * max); -int fd_fifo_length_noerr ( struct fifo * queue ); /* no error checking version */ - -/* * FUNCTION: fd_fifo_getstats * * PARAMETERS: - * queue : The queue from which to retrieve the timings information. - * items : the total number of items that went through the queue (already pop'd). Always increasing. - * total : Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) - * blocking : Cumulated time threads trying to post new items were blocked (queue full). - * last : For the last element retrieved from the queue, how long it take between posting (including blocking) and poping + * queue : The queue from which to retrieve the information. + * current_count : How many items in the queue at the time of execution. This changes each time an item is pushed or poped. + * limit_count : The maximum number of items allowed in this queue. This is specified during queue creation. + * highest_count : The maximum number of items this queue has contained. This enables to see if limit_count count was reached. + * total_count : the total number of items that went through the queue (already pop'd). Always increasing. + * total : Cumulated time all items spent in this queue, including blocking time (always growing, use deltas for monitoring) + * blocking : Cumulated time threads trying to post new items were blocked (queue full). + * last : For the last element retrieved from the queue, how long it take between posting (including blocking) and poping * * DESCRIPTION: * Retrieve the timing information associated with a queue, for monitoring purpose. @@ -3022,8 +3007,22 @@ * 0 : The statistics have been updated. * EINVAL : A parameter is invalid. */ -int fd_fifo_getstats( struct fifo * queue, long long *items, struct timespec * total, struct timespec * blocking, struct timespec * last); - +int fd_fifo_getstats( struct fifo * queue, int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last); + +/* + * FUNCTION: fd_fifo_length + * + * PARAMETERS: + * queue : The queue from which to retrieve the number of elements. + * + * DESCRIPTION: + * Retrieve the number of elements in a queue, without error checking. + * + * RETURN VALUE: + * The number of items currently queued. + */ +int fd_fifo_length ( struct fifo * queue ); /* * FUNCTION: fd_fifo_setthrhd
--- a/libfdcore/CMakeLists.txt Thu May 02 16:09:06 2013 +0800 +++ b/libfdcore/CMakeLists.txt Thu May 02 16:09:50 2013 +0800 @@ -17,6 +17,8 @@ endpoints.c events.c extensions.c + fifo_stats.c + hooks.c dict_base_proto.c messages.c queues.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfdcore/fifo_stats.c Thu May 02 16:09:50 2013 +0800 @@ -0,0 +1,79 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis <sdecugis@freediameter.net> * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +/* See include/freeDiameter/libfdcore.h for more information */ +int fd_stat_getstats(enum fd_stat_type stat, struct peer_hdr * peer, + int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last) +{ + struct fd_peer * p = (struct fd_peer *)peer; + TRACE_ENTRY( "%d %p %p %p %p %p %p %p %p", stat, peer, current_count, limit_count, highest_count, total_count, total, blocking, last); + + switch (stat) { + case STAT_G_LOCAL: { + CHECK_FCT( fd_fifo_getstats(fd_g_local, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_G_INCOMING: { + CHECK_FCT( fd_fifo_getstats(fd_g_incoming, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_G_OUTGOING: { + CHECK_FCT( fd_fifo_getstats(fd_g_outgoing, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_P_PSM: { + CHECK_PARAMS( CHECK_PEER( peer ) ); + CHECK_FCT( fd_fifo_getstats(p->p_events, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + case STAT_P_TOSEND: { + CHECK_PARAMS( CHECK_PEER( peer ) ); + CHECK_FCT( fd_fifo_getstats(p->p_tosend, current_count, limit_count, highest_count, total_count, total, blocking, last) ); + } + break; + + default: + return EINVAL; + } + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfdcore/hooks.c Thu May 02 16:09:50 2013 +0800 @@ -0,0 +1,64 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis <sdecugis@freediameter.net> * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "fdcore-internal.h" + +struct fd_hook_hdl; +struct fd_hook_data_hdl; + +int fd_hook_data_register( + struct fd_hook_permsgdata * (*permsgdata_new_cb) (void), + void (*permsgdata_destroy_cb) (struct fd_hook_permsgdata *), + struct fd_hook_data_hdl ** new_handle +) +{ + return ENOTSUP; +} + +int fd_hook_register ( enum fd_hook_type type, + void (*fd_hook_cb)(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, void * regdata), + void * regdata, + struct fd_hook_data_hdl *data_hdl, + struct fd_hook_hdl ** handler ) +{ + return ENOTSUP; +} + + +int fd_hook_unregister( struct fd_hook_hdl * handler ) +{ + return ENOTSUP; +} +
--- a/libfdproto/fifo.c Thu May 02 16:09:06 2013 +0800 +++ b/libfdproto/fifo.c Thu May 02 16:09:50 2013 +0800 @@ -151,7 +151,7 @@ int i = 0; for (li = queue->list.next; li != &queue->list; li = li->next) { struct fifo_item * fi = (struct fifo_item *)li; - fd_log_debug(" [%i] item %p in fifo %p, posted:ld.%06ld", + fd_log_debug(" [%i] item %p in fifo %p, posted:%ld.%06ld", i++, fi->item.o, queue, (long)fi->posted_on.tv_sec,(long)(fi->posted_on.tv_nsec/1000)); (*dump_item)(level, fi->item.o); } @@ -283,34 +283,11 @@ return 0; } -/* Get the length of the queue */ -int fd_fifo_length ( struct fifo * queue, int * length, int * max ) +/* Get the information on the queue */ +int fd_fifo_getstats( struct fifo * queue, int * current_count, int * limit_count, int * highest_count, long long * total_count, + struct timespec * total, struct timespec * blocking, struct timespec * last) { - TRACE_ENTRY( "%p %p %p", queue, length, max ); - - /* Check the parameters */ - CHECK_PARAMS( CHECK_FIFO( queue ) && length ); - - /* lock the queue */ - CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); - - /* Retrieve the count */ - *length = queue->count; - - if (max) - *max = queue->max; - - /* Unlock */ - CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); - - /* Done */ - return 0; -} - -/* Get the timings */ -int fd_fifo_getstats( struct fifo * queue, long long *items, struct timespec * total, struct timespec * blocking, struct timespec * last) -{ - TRACE_ENTRY( "%p %p %p %p %p", queue, items, total, blocking, last); + TRACE_ENTRY( "%p %p %p %p %p %p %p %p", queue, current_count, limit_count, highest_count, total_count, total, blocking, last); /* Check the parameters */ CHECK_PARAMS( CHECK_FIFO( queue ) ); @@ -318,8 +295,17 @@ /* lock the queue */ CHECK_POSIX( pthread_mutex_lock( &queue->mtx ) ); - if (items) - *items = queue->total_items; + if (current_count) + *current_count = queue->count; + + if (limit_count) + *limit_count = queue->max; + + if (highest_count) + *highest_count = queue->highest_ever; + + if (total_count) + *total_count = queue->total_items; if (total) memcpy(total, &queue->total_time, sizeof(struct timespec)); @@ -339,7 +325,7 @@ /* alternate version with no error checking */ -int fd_fifo_length_noerr ( struct fifo * queue ) +int fd_fifo_length ( struct fifo * queue ) { if ( !CHECK_FIFO( queue ) ) return 0;
--- a/libfdproto/ostr.c Thu May 02 16:09:06 2013 +0800 +++ b/libfdproto/ostr.c Thu May 02 16:09:50 2013 +0800 @@ -187,7 +187,7 @@ */ int fd_os_validate_DiameterIdentity(char ** id, size_t * inoutsz, int memory) { -#if defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) +#if !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) int gotsize = 0; #endif /* defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) */ @@ -196,7 +196,7 @@ if (!*inoutsz) *inoutsz = strlen(*id); -#if defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) +#if !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) else gotsize = 1; #endif /* defined(DIAMID_IDNA_IGNORE) || defined(DIAMID_IDNA_REJECT) */
--- a/tests/CMakeLists.txt Thu May 02 16:09:06 2013 +0800 +++ b/tests/CMakeLists.txt Thu May 02 16:09:50 2013 +0800 @@ -25,6 +25,7 @@ testpeers testdict testmesg + testmesg_stress testsess testdisp testcnx
--- a/tests/testfifo.c Thu May 02 16:09:06 2013 +0800 +++ b/tests/testfifo.c Thu May 02 16:09:50 2013 +0800 @@ -216,16 +216,15 @@ /* Basic operation */ { struct fifo * queue = NULL; - int count, max; struct msg * msg = NULL; + int max; + long long count; /* Create the queue */ CHECK( 0, fd_fifo_new(&queue, 0) ); /* Check the count is 0 */ - CHECK( 0, fd_fifo_length(queue, &count, &max) ); - CHECK( 0, count); - CHECK( 0, max); + CHECK( 0, fd_fifo_length(queue) ); /* Now enqueue */ msg = msg1; @@ -236,34 +235,28 @@ CHECK( 0, fd_fifo_post(queue, &msg) ); /* Check the count is 3 */ - CHECK( 0, fd_fifo_length(queue, &count, &max) ); - CHECK( 3, count); - CHECK( 0, max); + CHECK( 3, fd_fifo_length(queue) ); /* Retrieve the first message using fd_fifo_get */ CHECK( 0, fd_fifo_get(queue, &msg) ); CHECK( msg1, msg); - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 2, count); + CHECK( 2, fd_fifo_length(queue) ); /* Retrieve the second message using fd_fifo_timedget */ CHECK(0, clock_gettime(CLOCK_REALTIME, &ts)); ts.tv_sec += 1; /* Set the timeout to 1 second */ CHECK( 0, fd_fifo_timedget(queue, &msg, &ts) ); CHECK( msg2, msg); - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 1, count); + CHECK( 1, fd_fifo_length(queue) ); /* Retrieve the third message using meq_tryget */ CHECK( 0, fd_fifo_tryget(queue, &msg) ); CHECK( msg3, msg); - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 0, count); + CHECK( 0, fd_fifo_length(queue) ); /* Check that another meq_tryget does not block */ CHECK( EWOULDBLOCK, fd_fifo_tryget(queue, &msg) ); - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 0, count); + CHECK( 0, fd_fifo_length(queue) ); /* Check the timedget actually timesout */ CHECK(0, clock_gettime(CLOCK_REALTIME, &ts)); @@ -273,8 +266,18 @@ ts.tv_sec += 1; } CHECK( ETIMEDOUT, fd_fifo_timedget(queue, &msg, &ts) ); - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 0, count); + CHECK( 0, fd_fifo_length(queue) ); + + /* Post & get another message */ + msg = msg1; + CHECK( 0, fd_fifo_post(queue, &msg) ); + CHECK( 0, fd_fifo_timedget(queue, &msg, &ts) ); + CHECK( msg1, msg); + + /* Check some statistics */ + CHECK( 0, fd_fifo_getstats(queue, NULL, NULL, &max, &count, NULL, NULL, NULL) ); + CHECK( 3, max ); + CHECK( 4, count ); /* We're done for basic tests */ CHECK( 0, fd_fifo_del(&queue) ); @@ -291,7 +294,6 @@ struct msg *msgs[NBR_MSG * NBR_THREADS * 2], *msg; pthread_t thr [NBR_THREADS * 2]; struct dict_object *dwr_model = NULL; - int count; int i; int nbr_threads; #ifdef _POSIX_THREAD_THREADS_MAX @@ -362,8 +364,7 @@ } /* Check the count of the queue is back to 0 */ - CHECK( 0, fd_fifo_length(queue, &count, NULL) ); - CHECK( 0, count); + CHECK( 0, fd_fifo_length(queue) ); /* Destroy this queue and the messages */ CHECK( 0, fd_fifo_del(&queue) );
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/testmesg_stress.c Thu May 02 16:09:50 2013 +0800 @@ -0,0 +1,482 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis <sdecugis@freediameter.net> * +* * +* Copyright (c) 2013, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +#include "tests.h" + +/* The number of times each operation is repeated to measure the average operation time */ +#define NUMBER_OF_SAMPLES 100000 + +/* Main test routine */ +int main(int argc, char *argv[]) +{ + struct msg * acr = NULL; + struct avp * pi = NULL, *avp1, *avp2; + unsigned char * buf = NULL; + + /* First, initialize the daemon modules */ + INIT_FD(); + + { + struct dict_object * acr_model = NULL; + + /* Now find the ACR dictionary object */ + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &acr_model, ENOENT ) ); + + /* Create the instance, using the templates */ + CHECK( 0, fd_msg_new ( acr_model, 0, &acr ) ); + } + + /* Now let's create some additional Dictionary objects for the test */ + { + /* The constant values used here are totally arbitrary chosen */ + struct dict_object * vendor; + { + struct dict_vendor_data vendor_data = { 73565, "Vendor test" }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data , NULL, &vendor ) ); + } + + { + struct dict_application_data app_data = { 73566, "Application test" }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_APPLICATION, &app_data , vendor, NULL ) ); + } + + { + struct dict_avp_data avp_data = { 73567, 0, "AVP Test - no vendor - f32", 0, 0, AVP_TYPE_FLOAT32 }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , NULL, NULL ) ); + } + + { + struct dict_avp_data avp_data = { 139103, 0, "AVP Test - no vendor - f64", 0, 0, AVP_TYPE_FLOAT64 }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , NULL, NULL ) ); + } + + { + struct dict_object * type = NULL; + struct dict_type_data type_data = { AVP_TYPE_INTEGER64, "Int64 test" }; + struct dict_avp_data avp_data = { 73568, 73565, "AVP Test - i64", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_INTEGER64 }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); + } + + { + struct dict_object * type = NULL; + struct dict_type_data type_data = { AVP_TYPE_INTEGER32, "Enum32 test" }; + struct dict_enumval_data val1 = { "i32 const test (val 1)", { .i32 = 1 } }; + struct dict_enumval_data val2 = { "i32 const test (val 2)", { .i32 = 2 } }; + struct dict_enumval_data val3 = { "i32 const test (val -5)",{ .i32 = -5 } }; + struct dict_avp_data avp_data = { 73569, 73565, "AVP Test - enumi32", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_INTEGER32 }; + + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val1 , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val2 , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val3 , type, NULL ) ); + } + + { + struct dict_object * type = NULL; + struct dict_type_data type_data = { AVP_TYPE_OCTETSTRING, "OS test" }; + struct dict_avp_data avp_data = { 73570, 73565, "AVP Test - os", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING }; + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); + } + + { + struct dict_object * type = NULL; + struct dict_type_data type_data = { AVP_TYPE_OCTETSTRING, "OS enum test" }; + struct dict_enumval_data val1 = { "os const test (Test)", { .os = { (unsigned char *)"Test", 4 } } }; + struct dict_enumval_data val2 = { "os const test (waaad)", { .os = { (unsigned char *)"waaad", 5 } } }; + struct dict_enumval_data val3 = { "os const test (waa)", { .os = { (unsigned char *)"waaad", 3 } } }; + struct dict_avp_data avp_data = { 73571, 73565, "AVP Test - enumos", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING }; + + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val1 , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val2 , type, NULL ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val3 , type, NULL ) ); + } + + { + struct dict_object * gavp = NULL; + struct dict_avp_data avp_data = { 73572, 73565, "AVP Test - grouped", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_GROUPED }; + + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , NULL, &gavp ) ); + + /* Macro to search AVP and create a rule */ + #define ADD_RULE( _parent, _vendor, _avpname, _pos, _min, _max, _ord ) { \ + struct dict_object * _avp = NULL; \ + struct dict_avp_request _req = { (_vendor), 0, (_avpname) }; \ + struct dict_rule_data _data; \ + CHECK( 0, fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &_req, &_avp, ENOENT));\ + _data.rule_avp = _avp; \ + _data.rule_position = (_pos); \ + _data.rule_order = (_ord); \ + _data.rule_min = (_min); \ + _data.rule_max = (_max); \ + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_RULE, &_data , (_parent), NULL ) ); \ + } + + ADD_RULE(gavp, 73565, "AVP Test - os", RULE_OPTIONAL, -1, -1, 0); + + } + + { + struct dict_object * application = NULL; + struct dict_object * command = NULL; + struct dict_cmd_data cmd_data = { 73573, "Test-Command-Request", CMD_FLAG_REQUEST, CMD_FLAG_REQUEST }; + + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Application test", &application, ENOENT ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_COMMAND, &cmd_data , application, &command ) ); + ADD_RULE(command, 0, "AVP Test - no vendor - f32", RULE_FIXED_HEAD, -1, 1, 1); + ADD_RULE(command, 73565, "AVP Test - i64", RULE_REQUIRED, -1, -1, 0); + ADD_RULE(command, 73565, "AVP Test - enumi32", RULE_OPTIONAL, -1, -1, 0); + ADD_RULE(command, 73565, "AVP Test - os", RULE_OPTIONAL, -1, -1, 0); + ADD_RULE(command, 73565, "AVP Test - enumos", RULE_OPTIONAL, -1, -1, 0); + ADD_RULE(command, 73565, "AVP Test - grouped", RULE_OPTIONAL, -1, -1, 0); + } + + { + struct dict_object * application = NULL; + struct dict_object * command = NULL; + struct dict_cmd_data cmd_data = { 73573, "Test-Command-Answer", CMD_FLAG_REQUEST, 0 }; + + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Application test", &application, ENOENT ) ); + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_COMMAND, &cmd_data , application, &command ) ); + } + + { + struct dict_object * gavp = NULL; + struct dict_avp_data avp_data = { 73574, 73565, "AVP Test - rules", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_GROUPED }; + + CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , NULL, &gavp ) ); + + ADD_RULE(gavp, 0, "AVP Test - no vendor - f32", RULE_FIXED_HEAD, 0, 1, 1); + ADD_RULE(gavp, 73565, "AVP Test - i64", RULE_FIXED_HEAD, -1, 1, 2); + ADD_RULE(gavp, 73565, "AVP Test - enumi32", RULE_FIXED_HEAD, -1, 1, 3); + ADD_RULE(gavp, 73565, "AVP Test - os", RULE_REQUIRED, 2, 3, 0); + ADD_RULE(gavp, 73565, "AVP Test - enumos", RULE_OPTIONAL, 0, 1, 0); + ADD_RULE(gavp, 73565, "AVP Test - grouped", RULE_FIXED_TAIL, -1, 1, 1); + /* ABNF : + < no vendor - f32 > + < i64 > + < enumi32 > + 2*3 { os } + *1 [ enumos ] + < grouped > + */ + #if 0 + fd_dict_dump_object ( gavp ); + #endif + } + #if 0 + { + fd_dict_dump_object ( vendor ); + } + #endif + } + + /* Now create some values and check the length is correctly handled */ + { + struct dict_object * cmd_model = NULL; + struct msg * msg = NULL; + struct dict_object * avp_model = NULL; + struct avp * avp = NULL; + union avp_value value; + + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Test-Command-Request", &cmd_model, ENOENT ) ); + + /* Check the sizes are handled properly */ + { + struct avp * avpi = NULL; + struct avp * avpch = NULL; + struct avp_hdr * avpdata = NULL; + struct msg_hdr * msgdata = NULL; + #define ADD_AVP( _parent, _position, _avpi, _avpvendor, _avpname) { \ + struct dict_object * _avp = NULL; \ + struct dict_avp_request _req = { (_avpvendor), 0, (_avpname) }; \ + CHECK( 0, fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &_req, &_avp, ENOENT));\ + CHECK( 0, fd_msg_avp_new ( _avp, 0, &_avpi ) ); \ + CHECK( 0, fd_msg_avp_add ( (_parent), (_position), _avpi ) ); \ + } + /* Create a message with many AVP inside */ + CHECK( 0, fd_msg_new ( cmd_model, 0, &msg ) ); + CHECK( 0, fd_msg_hdr ( msg, &msgdata ) ); + + /* Avp no vendor, float32 => size = 12 */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0, "AVP Test - no vendor - f32" ); + value.f32 = 3.1415; + CHECK( 0, fd_msg_avp_setvalue ( avpi, &value ) ); + + /* Add a vendor AVP, integer64 => size = 20 */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - i64" ); + value.i64 = 0x123456789abcdeLL; + CHECK( 0, fd_msg_avp_setvalue ( avpi, &value ) ); + + /* Add an AVP with an enum value */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - enumi32" ); + { + struct dict_object * type_model = NULL; + struct dict_object * value_model = NULL; + struct dict_enumval_request request; + + CHECK( 0, fd_msg_model ( avpi, &avp_model ) ); + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, avp_model, &type_model, ENOENT ) ); + memset(&request, 0, sizeof(request)); + request.type_obj = type_model; + request.search.enum_name = "i32 const test (val 2)"; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &request, &value_model, ENOENT ) ); + CHECK( 0, fd_dict_getval ( value_model, &request.search ) ); + CHECK( 0, fd_msg_avp_setvalue ( avpi, &request.search.enum_value ) ); + } + + /* Add an AVP with an enum value, negative */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - enumi32" ); + { + struct dict_object * type_model = NULL; + struct dict_object * value_model = NULL; + struct dict_enumval_request request; + + CHECK( 0, fd_msg_model ( avpi, &avp_model ) ); + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, avp_model, &type_model, ENOENT ) ); + memset(&request, 0, sizeof(request)); + request.type_obj = type_model; + request.search.enum_name = "i32 const test (val -5)"; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &request, &value_model, ENOENT ) ); + CHECK( 0, fd_dict_getval ( value_model, &request.search ) ); + CHECK( 0, fd_msg_avp_setvalue ( avpi, &request.search.enum_value ) ); + } + + /* Now add a value which is not a constant into an enumerated AVP */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - enumi32" ); + value.i32 = -10; + CHECK( 0, fd_msg_avp_setvalue ( avpi, &value ) ); + + /* Add an octetstring AVP */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - os" ); + { + unsigned char buf[90]; + memcpy(&buf, "This\0 is a buffer of dat\a. It is not a string so we can have any c\0ntr\0l character here...\0\0", 89); + value.os.data = buf; + value.os.len = 89; + CHECK( 0, fd_msg_avp_setvalue ( avpi, &value ) ); + memset(&buf, 0, sizeof(buf)); /* Test that the OS value is really copied */ + } + + /* Add an octetstring from an enumerated constant */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - enumos" ); + { + struct dict_object * type_model = NULL; + struct dict_object * value_model = NULL; + struct dict_enumval_request request; + + CHECK( 0, fd_msg_model ( avpi, &avp_model ) ); + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, avp_model, &type_model, ENOENT ) ); + memset(&request, 0, sizeof(request)); + request.type_obj = type_model; + request.search.enum_name = "os const test (waaad)"; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &request, &value_model, ENOENT ) ); + CHECK( 0, fd_dict_getval ( value_model, &request.search ) ); + CHECK( 0, fd_msg_avp_setvalue ( avpi, &request.search.enum_value ) ); + } + + /* Add an octetstring from an enumerated constant */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - enumos" ); + { + struct dict_object * type_model = NULL; + struct dict_object * value_model = NULL; + struct dict_enumval_request request; + + CHECK( 0, fd_msg_model ( avpi, &avp_model ) ); + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, avp_model, &type_model, ENOENT ) ); + memset(&request, 0, sizeof(request)); + request.type_obj = type_model; + request.search.enum_name = "os const test (waa)"; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &request, &value_model, ENOENT ) ); + CHECK( 0, fd_dict_getval ( value_model, &request.search ) ); + CHECK( 0, fd_msg_avp_setvalue ( avpi, &request.search.enum_value ) ); + } + + /* Now test the grouped AVPs */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - grouped" ); + ADD_AVP( avpi, MSG_BRW_LAST_CHILD, avpch, 73565, "AVP Test - os" ); + { + value.os.data = (unsigned char *)"12345678"; + value.os.len = 8; + CHECK( 0, fd_msg_avp_setvalue ( avpch, &value ) ); + } + ADD_AVP( avpi, MSG_BRW_LAST_CHILD, avpch, 73565, "AVP Test - os" ); + { + value.os.data = (unsigned char *)"123456789"; + value.os.len = 9; + CHECK( 0, fd_msg_avp_setvalue ( avpch, &value ) ); + } + + /* Add another similar grouped AVP, to have lot of padding */ + ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 73565, "AVP Test - grouped" ); + ADD_AVP( avpi, MSG_BRW_LAST_CHILD, avpch, 73565, "AVP Test - os" ); + { + value.os.data = (unsigned char *)"1"; + value.os.len = 1; + CHECK( 0, fd_msg_avp_setvalue ( avpch, &value ) ); + } + ADD_AVP( avpi, MSG_BRW_LAST_CHILD, avpch, 73565, "AVP Test - os" ); + { + value.os.data = (unsigned char *)"1234567"; + value.os.len = 7; + CHECK( 0, fd_msg_avp_setvalue ( avpch, &value ) ); + } + + /* Set the application to the test application: 73566 */ + msgdata->msg_appl = 73566; + + /* Set the hop-by-hop ID to a random value: 0x4b44b41d */ + msgdata->msg_hbhid = 0x4b44b41d; + /* Set the end-to-end ID to a random value: 0xe2ee2e1d */ + msgdata->msg_eteid = 0xe2ee2e1d; + } + + CHECK( 0, fd_msg_bufferize( msg, &buf, NULL ) ); + + /* Now free the message, we keep only the buffer. */ + CHECK( 0, fd_msg_free( msg ) ); + + } + + /* We have our "buf" now, length is 344 -- cf. testmesg.c. */ + + /* Test the throughput of the different functions function */ + { + void ** stress_array; + int i; + struct timespec start, end; + + unsigned char * buf_cpy = NULL; + struct msg * msg; + + #define CPYBUF() { \ + buf_cpy = malloc(344); \ + CHECK( buf_cpy ? 1 : 0, 1); \ + memcpy(buf_cpy, buf, 344); \ + } + + /* Create the copies of the message buffer */ + stress_array = calloc(NUMBER_OF_SAMPLES, sizeof(void *)); + CHECK( stress_array ? 1 : 0, 1); + + for (i=0; i < NUMBER_OF_SAMPLES; i++) { + CPYBUF(); + stress_array[i] = buf_cpy; + } + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &start) ); + + /* Test the msg_parse_buffer function */ + for (i=0; i < NUMBER_OF_SAMPLES; i++) { + CHECK( 0, fd_msg_parse_buffer( (uint8_t **)&stress_array[i], 344, &msg) ); + stress_array[i] = msg; + } + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &end) ); + + { + long us = (end.tv_sec - start.tv_sec) * 1000000; + us += (end.tv_nsec - start.tv_nsec) / 1000; + long double thrp = (NUMBER_OF_SAMPLES * (long double)1000000) / us; + printf("fd_msg_bufferize : %d buffers parsed in %ldus (%.2LFmsg/s)\n", NUMBER_OF_SAMPLES, us, thrp); + } + + + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &start) ); + + /* Test the fd_msg_parse_dict function */ + for (i=0; i < NUMBER_OF_SAMPLES; i++) { + CHECK( 0, fd_msg_parse_dict( stress_array[i], fd_g_config->cnf_dict, NULL ) ); + } + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &end) ); + + { + long us = (end.tv_sec - start.tv_sec) * 1000000; + us += (end.tv_nsec - start.tv_nsec) / 1000; + long double thrp = (NUMBER_OF_SAMPLES * (long double)1000000) / us; + printf("fd_msg_parse_dict : %d messages parsed in %ldus (%.2LFmsg/s)\n", NUMBER_OF_SAMPLES, us, thrp); + } + + + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &start) ); + + /* Test the fd_msg_parse_rules function */ + for (i=0; i < NUMBER_OF_SAMPLES; i++) { + CHECK( 0, fd_msg_parse_rules( stress_array[i], fd_g_config->cnf_dict, NULL ) ); + } + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &end) ); + + { + long us = (end.tv_sec - start.tv_sec) * 1000000; + us += (end.tv_nsec - start.tv_nsec) / 1000; + long double thrp = (NUMBER_OF_SAMPLES * (long double)1000000) / us; + printf("fd_msg_parse_rules: %d messages parsed in %ldus (%.2LFmsg/s)\n", NUMBER_OF_SAMPLES, us, thrp); + } + + + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &start) ); + + /* Free those messages */ + for (i=0; i < NUMBER_OF_SAMPLES; i++) { + fd_msg_free( stress_array[i]); + stress_array[i] = NULL; + } + + CHECK( 0, clock_gettime(CLOCK_REALTIME, &end) ); + + { + long us = (end.tv_sec - start.tv_sec) * 1000000; + us += (end.tv_nsec - start.tv_nsec) / 1000; + long double thrp = (NUMBER_OF_SAMPLES * (long double)1000000) / us; + printf("fd_msg_free : %d messages freed in %ldus (%.2LFmsg/s)\n", NUMBER_OF_SAMPLES, us, thrp); + } + + free(stress_array); + } + + + /* That's all for the tests yet */ + PASSTEST(); +} +