Mercurial > hg > waaad
changeset 289:6537213b55b5
Simpified dispatch callbacks prototype and behavior
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 22 Dec 2008 12:29:49 +0900 |
parents | beb9bde9a308 |
children | 5ed9c73c31cd |
files | extensions/app_test/app_test.h extensions/app_test/atst_serv.c include/waaad/dispatch-api.h waaad/dispatch.c |
diffstat | 4 files changed, 87 insertions(+), 121 deletions(-) [+] |
line wrap: on
line diff
--- a/extensions/app_test/app_test.h Mon Dec 22 11:06:20 2008 +0900 +++ b/extensions/app_test/app_test.h Mon Dec 22 12:29:49 2008 +0900 @@ -130,15 +130,6 @@ } \ } -#define CHECK_NEG( _call ) { \ - int __ret = ( _call ); \ - if ( __ret != 0 ) { \ - TRACE_DEBUG(INFO, "Error in function call"); \ - log_error("Error in extension (" #_call "): %s\n", strerror(__ret)); \ - return - __ret; \ - } \ -} - #define CHECK_VOID( _call ) { \ int __ret = ( _call ); \ if ( __ret != 0 ) { \
--- a/extensions/app_test/atst_serv.c Mon Dec 22 11:06:20 2008 +0900 +++ b/extensions/app_test/atst_serv.c Mon Dec 22 12:29:49 2008 +0900 @@ -41,25 +41,30 @@ static disp_cb_hdl_t * hdl_tr = NULL; /* handler for Test-Request req cb */ /* Default callback for the application. */ -static int fb_cb( msg_t * msg, msg_avp_t * avp, int handled ) +static int fb_cb( msg_t ** msg, msg_avp_t * avp ) { /* This CB should never be called */ - TRACE_ENTRY("%p %p %d", msg, avp, handled); + TRACE_ENTRY("%p %p", msg, avp); log_error("Unexpected message received!\n"); - return -ENOTSUP; + return ENOTSUP; } /* Callback for incoming Test-Request messages */ -static int tr_cb( msg_t * msg, msg_avp_t * avp, int handled ) +static int tr_cb( msg_t ** msg, msg_avp_t * avp ) { - msg_t * ans = msg; + msg_t * ans; + + TRACE_ENTRY("%p %p", msg, avp); - TRACE_ENTRY("%p %p %d", msg, avp, handled); + if (msg == NULL) + return EINVAL; + + ans = *msg; /* Create answer header */ - CHECK_NEG( msg_new_answ(&ans, MSGFL_FROM_TEMPLATE) ); + CHECK( msg_new_answ(&ans, MSGFL_FROM_TEMPLATE) ); /* Set the Session-Id AVP */ { @@ -67,10 +72,10 @@ msg_avp_t * dst = NULL; msg_avp_data_t * data = NULL; - CHECK_NEG( msg_search_avp(msg, sess_id, &src) ); - CHECK_NEG( msg_search_avp(ans, sess_id, &dst) ); - CHECK_NEG( msg_avp_data( src, &data ) ); - CHECK_NEG( msg_avp_setvalue( dst, data->avp_data) ); + CHECK( msg_search_avp(*msg, sess_id, &src) ); + CHECK( msg_search_avp(ans, sess_id, &dst) ); + CHECK( msg_avp_data( src, &data ) ); + CHECK( msg_avp_setvalue( dst, data->avp_data) ); } /* Set the Test-AVP AVP */ { @@ -78,10 +83,10 @@ msg_avp_t * dst = NULL; msg_avp_data_t * data = NULL; - CHECK_NEG( msg_search_avp(msg, atst_avp, &src) ); - CHECK_NEG( msg_search_avp(ans, atst_avp, &dst) ); - CHECK_NEG( msg_avp_data( src, &data ) ); - CHECK_NEG( msg_avp_setvalue( dst, data->avp_data) ); + CHECK( msg_search_avp(*msg, atst_avp, &src) ); + CHECK( msg_search_avp(ans, atst_avp, &dst) ); + CHECK( msg_avp_data( src, &data ) ); + CHECK( msg_avp_setvalue( dst, data->avp_data) ); } /* Set the Origin-Host AVP */ @@ -92,8 +97,8 @@ data.os.data = (unsigned char *)(g_pconf->diameter_identity); data.os.len = strlen(g_pconf->diameter_identity); - CHECK_NEG( msg_search_avp(ans, origin_host, &dst) ); - CHECK_NEG( msg_avp_setvalue( dst, &data) ); + CHECK( msg_search_avp(ans, origin_host, &dst) ); + CHECK( msg_avp_setvalue( dst, &data) ); } /* Set the Origin-Realm AVP */ @@ -104,8 +109,8 @@ data.os.data = (unsigned char *)(g_pconf->diameter_realm); data.os.len = strlen(g_pconf->diameter_realm); - CHECK_NEG( msg_search_avp(ans, origin_realm, &dst) ); - CHECK_NEG( msg_avp_setvalue( dst, &data) ); + CHECK( msg_search_avp(ans, origin_realm, &dst) ); + CHECK( msg_avp_setvalue( dst, &data) ); } /* Set the Result-Code AVP */ @@ -115,14 +120,15 @@ data.u32 = 2001; /* Success */ - CHECK_NEG( msg_search_avp(ans, res_code, &dst) ); - CHECK_NEG( msg_avp_setvalue( dst, &data) ); + CHECK( msg_search_avp(ans, res_code, &dst) ); + CHECK( msg_avp_setvalue( dst, &data) ); } /* Send the answer */ - CHECK_NEG( msg_send( &ans, NULL, NULL ) ); + CHECK( msg_send( &ans, NULL, NULL ) ); - return DISP_CBRET_HANDLED_STOP; + *msg = NULL; + return 0; } int serv_init(void)
--- a/include/waaad/dispatch-api.h Mon Dec 22 11:06:20 2008 +0900 +++ b/include/waaad/dispatch-api.h Mon Dec 22 12:29:49 2008 +0900 @@ -69,13 +69,12 @@ * When a callback is called, it receives the message as parameter, and eventually a pointer to * the AVP in the message when this is appropriate. * - * The callback must process the message, and then return a value with the following meaning: - * (negative): -errno, if an error occurred. - * (positive): one of the disp_cb_ret_t values. See the definition for more information. + * The callback must process the message, and eventually create an answer to it. See the definition + * bellow for more information. * - * At least one of the registered callbacks must return a value of DIST_CBRET_HANDLED_* on the message, or - * a default handler will be called with the effect of requeuing the message for forwarding on the network to - * another peer (for requests), or discarding the message (for answers). + * If no callback has handled the message, a default handler will be called with the effect of + * requeuing the message for forwarding on the network to another peer (for requests), or + * discarding the message (for answers). */ #ifndef _DISPATCH_API_H @@ -83,17 +82,6 @@ #include <waaad/message-api.h> -/* The values that must be returned by a callback, when no error occurred: */ -typedef enum { - DISP_CBRET_CONTINUE = 0, /* The callback has completed its process without error. - Next callback can be called. - This value is typically returned by non-final callbacks (for example cb registered on AVPs) */ - DISP_CBRET_HANDLED_CONTINUE, /* The callback has processed the message (for example answered a request or - taken action from an answer). Remaining callbacks may be called, if any. */ - DISP_CBRET_HANDLED_STOP /* The callback has processed the message (for example generated an error answer or forwarded the - message to another peer). No additional handler should be called on this message. */ -} disp_cb_ret_t; - /* The allowed methods for registering a callback. */ typedef enum { DISP_REG_ANY = 1, /* The callback is called on any message. This should be only used for debug. */ @@ -130,7 +118,7 @@ * DISP_REG_ANY. * In this case, "when" must be NULL. * - * In any other case (yet), the "when" parameter points to a disp_reg_val_t structure. Detail is given bellow. + * In any other case, the "when" parameter points to a valid disp_reg_val_t structure. Detail is given bellow. * * DISP_REG_APPID. * Only the "app_id" field must be set, other fields are ignored. It points to a dictionary object of type DICT_APPLICATION. @@ -165,21 +153,21 @@ * CALLBACK: disp_cb_t * * PARAMETERS: - * msg : The message that trigged the callback call. + * msg : The location of message that trigged the callback call. * avp : for callbacks registered with DISP_REG_AVP or DISP_REG_AVP_ENUMVAL, this points to the triggering AVP. NULL otherwise. - * handled : (boolean) a previous handler has returned DISP_CBRET_HANDLED_CONTINUE already? * * DESCRIPTION: * This is the prototype of the callback functions that are registered with dicp_cb_reg function. * See introduction and previous comments for more information on how this callback is called. - * + * + * The callback must set *msg to NULL if it creates an answer or "handles" a received answer, so that no further processing is done. + * * RETURN VALUE: - * < 0 : An error occurred (ex: -EINVAL = invalid parameter; -ENOMEM: not enough memory, ...). - * DISP_CBRET_CONTINUE : The next callback can be called, no action has been taken yet. - * DISP_CBRET_HANDLED_CONTINUE : Action has been taken, next callback can be called (used in normal condition) - * DISP_CBRET_HANDLED_STOP : Action has been taken, no more callback must be called (used in error conditions) + * 0 : success. + * !0 : An error occurred (ex: EINVAL = invalid parameter; ENOMEM: not enough memory, ...). + * In this case, the error is logged in the daemon and the message is discarded. */ -typedef int (*disp_cb_t) ( msg_t * msg, msg_avp_t * avp, int handled ); +typedef int (*disp_cb_t) ( msg_t ** msg, msg_avp_t * avp ); /* The following opaque type represents a handler to a registered callback. This allows to remove a registered callback. */ typedef void disp_cb_hdl_t; @@ -206,7 +194,7 @@ * EINVAL : A parameter is invalid. * ENOMEM : Not enough memory to complete the operation */ -int disp_register ( disp_cb_t cb, disp_reg_t how, void * when, disp_cb_hdl_t ** handle ); +int disp_register ( disp_cb_t cb, disp_reg_t how, disp_reg_val_t * when, disp_cb_hdl_t ** handle ); /* @@ -238,7 +226,7 @@ int version; /* The version of this API/ABI, must be WAAAD_API_DISP_VER */ /* the remaining is dispatching-specific */ - int (*disp_register) ( disp_cb_t cb, disp_reg_t how, void * when, disp_cb_hdl_t ** handle ); + int (*disp_register) ( disp_cb_t cb, disp_reg_t how, disp_reg_val_t * when, disp_cb_hdl_t ** handle ); int (*disp_unregister) ( disp_cb_hdl_t * handle ); } api_disp_t;
--- a/waaad/dispatch.c Mon Dec 22 11:06:20 2008 +0900 +++ b/waaad/dispatch.c Mon Dec 22 12:29:49 2008 +0900 @@ -41,7 +41,7 @@ #include "waaad-internal.h" /* Read-write lock for dictionary callbacks. Note that if the dictionary object is destroyed, this lock is not taken. */ -static pthread_rwlock_t dict_lock; +static pthread_rwlock_t disp_dictlock; /* Keep the list of all registered handlers */ static uti_list_t all_handlers; @@ -83,12 +83,12 @@ CHECK_FCT( msg_data(*msg, &hdr) ); /* Now we search the application of the message */ - CHECK_FCT_DO( dict_search( DICT_APPLICATION, APPLICATION_BY_ID_REF, &hdr->msg_appl, app ), - { - /* In case of error, we should answer a DIAMETER_APPLICATION_UNSUPPORTED error */ - TRACE_DEBUG(INFO, "Error: TODO reply DIAMETER_APPLICATION_UNSUPPORTED if it's a request"); - goto end; - } ); + CHECK_FCT( dict_search( DICT_APPLICATION, APPLICATION_BY_ID_REF, &hdr->msg_appl, app ) ); + if (*app == NULL) { + /* In case of error, we should answer a DIAMETER_APPLICATION_UNSUPPORTED error */ + TRACE_DEBUG(INFO, "Error: TODO reply DIAMETER_APPLICATION_UNSUPPORTED if it's a request"); + goto end; + } CHECK_FCT_DO( ret = msg_parse_rules( *msg, &rule ), /* handle error later, but log here */ ); @@ -110,33 +110,17 @@ return ret; } -#define loc_CALL_CB( _cb, _msg, _avp ) { \ - int _ret = 0; \ +/**************************************************************************************/ + +#define loc_CALL_CB( _cb, _pmsg, _avp ) { \ TRACE_DEBUG(ANNOYING, "Calling dispatch callback..."); \ - _ret = (*(_cb))( (_msg), (_avp), hdld ); \ - if (_ret < 0) { \ - TRACE_DEBUG(INFO, "Callback returned an error: %s\n, continuing...", strerror(-_ret)); \ - } else { \ - int _must_stop = 0; \ - switch (_ret) { \ - case DISP_CBRET_HANDLED_STOP: \ - _must_stop = 1; \ - case DISP_CBRET_HANDLED_CONTINUE: \ - hdld += 1; \ - case DISP_CBRET_CONTINUE: \ - TRACE_DEBUG(ANNOYING, "Dispatch callback returned"); \ - break; \ - default: \ - TRACE_DEBUG(INFO, "Dispatch callback returned unknown value (%d)", _ret); \ - } \ - if (_must_stop) \ - goto c_continue; \ - } \ + CHECK_FCT_DO((*(_cb))( (_pmsg), (_avp) ), goto c_continue); \ + TRACE_DEBUG(ANNOYING, "Dispatch callback returned, %p", *(_pmsg)); \ + if (*(_pmsg) == NULL) \ + goto c_continue; \ } -/**************************************************************************************/ - /* Dispatch thread */ static void * disp_th(void * arg) { @@ -151,7 +135,6 @@ uti_list_t * li = NULL; uti_list_t * sem = NULL; _disp_cb_hdl_t * hdl = NULL; - int hdld = 0; dict_object_t * msg_app = NULL; dict_object_t * msg_cmd = NULL; @@ -182,7 +165,7 @@ (*anscb)(data, &msg); if (msg == NULL) { - TRACE_DEBUG(FULL, "The message was handled by msg_send callback, not calling regular callbacks"); + TRACE_DEBUG(FULL, "The message was handled by msg_send callback, skipping dispatch module callbacks"); continue; } } @@ -194,13 +177,13 @@ continue; /* Now we'll call the dispatch handlers, lock the appropriate rdlock */ - CHECK_POSIX_DO( pthread_rwlock_rdlock(&dict_lock), goto error ); - pthread_cleanup_push( (void *)pthread_rwlock_unlock, &dict_lock ); + CHECK_POSIX_DO( pthread_rwlock_rdlock(&disp_dictlock), goto error ); + pthread_cleanup_push( (void *)pthread_rwlock_unlock, &disp_dictlock ); /* Start with calling all ANY callbacks */ - for (li = any_handlers.next; li != &any_handlers; li = li->next) { + for (li = any_handlers.next; (li != &any_handlers); li = li->next) { hdl = _H(li->o); - loc_CALL_CB( hdl->cb, msg, NULL ); + loc_CALL_CB( hdl->cb, &msg, NULL ); } /* Now get the reference to the message dict object */ @@ -250,7 +233,7 @@ continue; /* Ok, this callback should be called */ - loc_CALL_CB( hdl->cb, msg, NULL ); + loc_CALL_CB( hdl->cb, &msg, avp ); } } /* Go to next AVP */ @@ -268,7 +251,7 @@ continue; /* Ok, this callback should be called */ - loc_CALL_CB( hdl->cb, msg, NULL ); + loc_CALL_CB( hdl->cb, &msg, NULL ); } /* Finally call the application's callbacks */ @@ -278,16 +261,14 @@ ASSERT( hdl->when.app_id == msg_app ); - loc_CALL_CB( hdl->cb, msg, NULL ); + loc_CALL_CB( hdl->cb, &msg, NULL ); } - /* We're done; now check the message has been handled at least once */ - if (hdld == 0) { - TRACE_DEBUG(INFO, "Error: the message was not handled in dispatch module..."); + /* If we arrive here, it means no callback has set msg to NULL... */ + TRACE_DEBUG(INFO, "Error: the message was not handled in dispatch module...TODO"); - /* TODO: request => forward or return error? answer => discard */ - - } + /* TODO: request => forward or return error? answer => discard */ + goto c_continue; c_error: @@ -295,7 +276,7 @@ c_continue: /* some compilers complain if there is no instruction here... => */ ; pthread_cleanup_pop( 0 ); - CHECK_POSIX_DO( pthread_rwlock_unlock(&dict_lock), goto error ); + CHECK_POSIX_DO( pthread_rwlock_unlock(&disp_dictlock), goto error ); if (msg) { CHECK_FCT_DO( msg_free(msg, 1), goto error ); @@ -320,7 +301,7 @@ uti_list_init(&all_handlers, NULL); uti_list_init(&any_handlers, NULL); - CHECK_POSIX( pthread_rwlock_init(&dict_lock, NULL) ); + CHECK_POSIX( pthread_rwlock_init(&disp_dictlock, NULL) ); CHECK_POSIX( pthread_create( &th, NULL, disp_th, NULL ) ); @@ -340,13 +321,13 @@ disp_unregister((disp_cb_hdl_t *)(all_handlers.next)); } - CHECK_POSIX_DO( pthread_rwlock_destroy(&dict_lock), /* continue */ ); + CHECK_POSIX_DO( pthread_rwlock_destroy(&disp_dictlock), /* continue */ ); return 0; } /* Register a new callback. */ -int disp_register ( disp_cb_t cb, disp_reg_t how, void * when, disp_cb_hdl_t ** handle ) +int disp_register ( disp_cb_t cb, disp_reg_t how, disp_reg_val_t * when, disp_cb_hdl_t ** handle ) { _disp_cb_hdl_t * hdl = NULL; uti_list_t * where = NULL; @@ -356,7 +337,7 @@ CHECK_PARAMS( cb ); CHECK_PARAMS( (how >= DISP_REG_ANY) && (how <= DISP_REG_AVP_ENUMVAL) ); CHECK_PARAMS( (how == DISP_REG_ANY) || (when != NULL) ); - CHECK_PARAMS( (how != DISP_REG_APPID) || (((disp_reg_val_t *)when)->flags & 0x3) ); + CHECK_PARAMS( (how != DISP_REG_APPID) || (when->flags & 0x3) ); switch (how) { case DISP_REG_ANY: @@ -364,16 +345,16 @@ break; case DISP_REG_APPID: - CHECK_FCT( dict_disp_cb(DICT_APPLICATION, ((disp_reg_val_t *)when)->app_id, &where) ); + CHECK_FCT( dict_disp_cb(DICT_APPLICATION, when->app_id, &where) ); break; case DISP_REG_CC: - CHECK_FCT( dict_disp_cb(DICT_COMMAND, ((disp_reg_val_t *)when)->command, &where) ); + CHECK_FCT( dict_disp_cb(DICT_COMMAND, when->command, &where) ); break; case DISP_REG_AVP: case DISP_REG_AVP_ENUMVAL: - CHECK_FCT( dict_disp_cb(DICT_AVP, ((disp_reg_val_t *)when)->avp, &where) ); + CHECK_FCT( dict_disp_cb(DICT_AVP, when->avp, &where) ); break; } @@ -388,12 +369,12 @@ memcpy(&hdl->when, when, sizeof(disp_reg_val_t)); hdl->cb = cb; - CHECK_POSIX( pthread_rwlock_wrlock(&dict_lock) ); + CHECK_POSIX( pthread_rwlock_wrlock(&disp_dictlock) ); uti_list_insert_before(&all_handlers, &hdl->all); uti_list_insert_before(where, &hdl->dict); - CHECK_POSIX( pthread_rwlock_unlock(&dict_lock) ); + CHECK_POSIX( pthread_rwlock_unlock(&disp_dictlock) ); if (handle) *handle = (disp_cb_hdl_t *) hdl; @@ -407,14 +388,14 @@ dict_object_t * vendor = NULL; dict_vendor_data_t vendor_data; - add_auth = (((disp_reg_val_t *)when)->flags & 0x1) ? 1 : 0; - add_acct = (((disp_reg_val_t *)when)->flags & 0x2) ? 1 : 0; + add_auth = (when->flags & 0x1) ? 1 : 0; + add_acct = (when->flags & 0x2) ? 1 : 0; /* Get the app id of the application being added */ - CHECK_FCT( dict_getval( ((disp_reg_val_t *)when)->app_id, &appl_data) ); + CHECK_FCT( dict_getval( when->app_id, &appl_data) ); /* Get the vendor and data */ - CHECK_FCT( dict_search( DICT_VENDOR, VENDOR_OF_APPLICATION, ((disp_reg_val_t *)when)->app_id, &vendor) ); + CHECK_FCT( dict_search( DICT_VENDOR, VENDOR_OF_APPLICATION, when->app_id, &vendor) ); if (vendor) { CHECK_FCT( dict_getval( vendor, &vendor_data) ); } @@ -470,10 +451,10 @@ CHECK_PARAMS( CHECK_HDL(handle) ); - CHECK_POSIX( pthread_rwlock_wrlock(&dict_lock) ); + CHECK_POSIX( pthread_rwlock_wrlock(&disp_dictlock) ); uti_list_unlink(&_H(handle)->all); uti_list_unlink(&_H(handle)->dict); - CHECK_POSIX( pthread_rwlock_unlock(&dict_lock) ); + CHECK_POSIX( pthread_rwlock_unlock(&disp_dictlock) ); free(handle);