# HG changeset patch # User Sebastien Decugis # Date 1368443833 -28800 # Node ID eb4ce68b6e5ce829d94d758f6ef9285d9342329e # Parent d87cee14b05134d09c60efaa42dadc4859050b73 Added calls to remaining hooks diff -r d87cee14b051 -r eb4ce68b6e5c extensions/dbg_interactive/endpoints.i --- a/extensions/dbg_interactive/endpoints.i Mon May 13 18:50:26 2013 +0800 +++ b/extensions/dbg_interactive/endpoints.i Mon May 13 19:17:13 2013 +0800 @@ -127,7 +127,7 @@ void dump() { char * buf = NULL; size_t len; - printf("%s", fd_ep_dump_one(&buf, &len, NULL, $self)); + printf("%s", fd_ep_dump_one(&buf, &len, NULL, 1, $self)); free(buf); } } diff -r d87cee14b051 -r eb4ce68b6e5c extensions/dbg_monitor/dbg_monitor.c --- a/extensions/dbg_monitor/dbg_monitor.c Mon May 13 18:50:26 2013 +0800 +++ b/extensions/dbg_monitor/dbg_monitor.c Mon May 13 19:17:13 2013 +0800 @@ -125,7 +125,7 @@ CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); TRACE_DEBUG(INFO, "[dbg_monitor] Dumping servers information"); - TRACE_DEBUG(INFO, "%s", fd_servers_dump(&buf, &len, NULL)); + TRACE_DEBUG(INFO, "%s", fd_servers_dump(&buf, &len, NULL, 1)); sleep(1); } diff -r d87cee14b051 -r eb4ce68b6e5c include/freeDiameter/libfdcore.h --- a/include/freeDiameter/libfdcore.h Mon May 13 18:50:26 2013 +0800 +++ b/include/freeDiameter/libfdcore.h Mon May 13 19:17:13 2013 +0800 @@ -813,7 +813,7 @@ /* The "old" FD_EV_DUMP_* events are replaced with direct calls to the following dump functions */ DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump); DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump); -DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump); +DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump, int details); #endif /* SWIG */ DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details); DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details); @@ -852,8 +852,8 @@ int fd_ep_filter_family( struct fd_list * list, int af ); int fd_ep_filter_list( struct fd_list * list, struct fd_list * exclude_list ); int fd_ep_clearflags( struct fd_list * list, uint32_t flags ); -DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, struct fd_endpoint * ep ); -DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int indent, struct fd_list * eps ); +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, int preamble, struct fd_endpoint * ep ); +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int preamble, int indent, struct fd_list * eps ); /*============================================================*/ @@ -935,7 +935,7 @@ */ HOOK_MESSAGE_LOCAL, - /* Hook called when a request message has been created locally and is being sent. + /* Hook called when a request message has been created locally by an extension and is being sent. - {msg} points to the message. - {peer} is NULL - {other} is NULL diff -r d87cee14b051 -r eb4ce68b6e5c include/freeDiameter/libfdproto.h --- a/include/freeDiameter/libfdproto.h Mon May 13 18:50:26 2013 +0800 +++ b/include/freeDiameter/libfdproto.h Mon May 13 19:17:13 2013 +0800 @@ -2921,6 +2921,8 @@ * session : The session corresponding to this object, if any. * action : Upon return, the action that must be taken on the message * error_code : Upon return with action == DISP_ACT_ERROR, contains the error (such as "DIAMETER_UNABLE_TO_COMPLY") + * drop_reason : if set on return, the message must be freed for this reason. + * drop_msg : if drop_reason is set, this points to the message to be freed while *msg is NULL. * * DESCRIPTION: * Call all handlers registered for a given message. @@ -2933,7 +2935,7 @@ * EINVAL : A parameter is invalid. * (other errors) */ -int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code ); +int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code, char ** drop_reason, struct msg ** drop_msg ); diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/config.c --- a/libfdcore/config.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/config.c Mon May 13 19:17:13 2013 +0800 @@ -84,7 +84,7 @@ { FD_DUMP_HANDLE_OFFSET(); - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{freeDiameter configuration}(@%p): \n", fd_g_config), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "freeDiameter configuration:\n", fd_g_config), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Default trace level .... : %+d\n", fd_g_debug_lvl), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Configuration file ..... : %s\n", fd_g_config->cnf_file), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Diameter Identity ...... : %s (l:%Zi)\n", fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len), return NULL); @@ -98,17 +98,17 @@ if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : Default (use all available)\n"), return NULL); } else { - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : \n"), return NULL); - CHECK_MALLOC_DO( fd_ep_dump( FD_DUMP_STD_PARAMS, 29, &fd_g_config->cnf_endpoints ), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : "), return NULL); + CHECK_MALLOC_DO( fd_ep_dump( FD_DUMP_STD_PARAMS, 0, 0, &fd_g_config->cnf_endpoints ), return NULL); } if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_apps)) { - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : (none)\n"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : (none)"), return NULL); } else { struct fd_list * li = fd_g_config->cnf_apps.next; - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : \n"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : "), return NULL); while (li != &fd_g_config->cnf_apps) { struct fd_app * app = (struct fd_app *)li; - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " App: %u\t%s%s\tVnd: %u\n", + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "App: %u,%s%s,Vnd:%u\t", app->appid, app->flags.auth ? "Au" : "--", app->flags.acct ? "Ac" : "--", @@ -117,7 +117,7 @@ } } - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Flags : - IP ........... : %s\n", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n Flags : - IP ........... : %s\n", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled"), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - IPv6 ......... : %s\n", fd_g_config->cnf_flags.no_ip6 ? "DISABLED" : "Enabled"), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Relay app .... : %s\n", fd_g_config->cnf_flags.no_fwd ? "DISABLED" : "Enabled"), return NULL); CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - TCP .......... : %s\n", fd_g_config->cnf_flags.no_tcp ? "DISABLED" : "Enabled"), return NULL); @@ -587,7 +587,7 @@ free(dhparams.data); } else { - TRACE_DEBUG(INFO, "Generating fresh Diffie-Hellman parameters of size %d (this takes some time)... ", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); + LOG_D( "Generating fresh Diffie-Hellman parameters of size %d (this takes some time)... ", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); CHECK_GNUTLS_DO( gnutls_dh_params_generate2( fd_g_config->cnf_sec_data.dh_cache, fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS), diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/endpoints.c --- a/libfdcore/endpoints.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/endpoints.c Mon May 13 19:17:13 2013 +0800 @@ -284,11 +284,13 @@ return 0; } -DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, struct fd_endpoint * ep ) +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, int preamble, struct fd_endpoint * ep ) { FD_DUMP_HANDLE_OFFSET(); - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ep}(@%p): ", ep), return NULL); + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ep}(@%p): ", ep), return NULL); + } if (!ep) { CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); @@ -296,27 +298,33 @@ } CHECK_MALLOC_DO( fd_sa_dump_node_serv( FD_DUMP_STD_PARAMS, &ep->sa, NI_NUMERICHOST | NI_NUMERICSERV ), return NULL); - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {%s%s%s%s%s}", - (ep->flags & EP_FL_CONF) ? "C" : "-", - (ep->flags & EP_FL_DISC) ? "D" : "-", - (ep->flags & EP_FL_ADV) ? "A" : "-", - (ep->flags & EP_FL_LL) ? "L" : "-", - (ep->flags & EP_FL_PRIMARY) ? "P" : "-"), return NULL); + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{%s%s%s%s%s}", + (ep->flags & EP_FL_CONF) ? "C" : "-", + (ep->flags & EP_FL_DISC) ? "D" : "-", + (ep->flags & EP_FL_ADV) ? "A" : "-", + (ep->flags & EP_FL_LL) ? "L" : "-", + (ep->flags & EP_FL_PRIMARY) ? "P" : "-"), return NULL); return *buf; } -DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int indent, struct fd_list * eps ) +DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int preamble, int indent, struct fd_list * eps ) { struct fd_list * li; FD_DUMP_HANDLE_OFFSET(); - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{eps}(@%p):", indent, "", eps), return NULL); + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{eps}(@%p):", indent, "", eps), return NULL); + } if (eps) { for (li = eps->next; li != eps; li = li->next) { struct fd_endpoint * ep = (struct fd_endpoint *)li; - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*s", indent+1, ""), return NULL); - CHECK_MALLOC_DO( fd_ep_dump_one( FD_DUMP_STD_PARAMS, ep ), return NULL); + if (preamble) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*s", indent+1, ""), return NULL); + } else if (li->prev != eps) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\t"), return NULL); + } + CHECK_MALLOC_DO( fd_ep_dump_one( FD_DUMP_STD_PARAMS, preamble, ep ), return NULL); } } } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/extensions.c --- a/libfdcore/extensions.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/extensions.c Mon May 13 19:17:13 2013 +0800 @@ -150,7 +150,7 @@ for (li = ext_list.next; li != &ext_list; li = li->next) { struct fd_ext_info * ext = (struct fd_ext_info *)li; - TRACE_DEBUG (INFO, "Loading : %s", ext->filename); + LOG_D( "Loading : %s", ext->filename); /* Load the extension */ #ifndef DEBUG @@ -161,7 +161,7 @@ #endif /* DEBUG */ if (ext->handler == NULL) { /* An error occured */ - TRACE_ERROR("Loading of extension %s failed: %s", ext->filename, dlerror()); + LOG_F("Loading of extension %s failed: %s", ext->filename, dlerror()); #ifdef DEBUG ext->handler = dlopen(ext->filename, RTLD_LAZY | RTLD_GLOBAL); if (ext->handler) { @@ -207,7 +207,7 @@ /* Proceed to the next extension */ } - TRACE_DEBUG (INFO, "All extensions loaded."); + LOG_N("All extensions loaded."); /* We have finished. */ return 0; diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/messages.c --- a/libfdcore/messages.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/messages.c Mon May 13 19:17:13 2013 +0800 @@ -313,19 +313,36 @@ return 0; } +static int fd_msg_send_int( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) +{ + struct msg_hdr *hdr; + DiamId_t diamid; + size_t diamidlen; + + /* Save the callback in the message, with the timeout */ + CHECK_FCT( fd_msg_anscb_associate( *pmsg, anscb, data, expirecb, timeout ) ); + + /* If this is a new request, call the HOOK_MESSAGE_LOCAL hook */ + if ( (fd_msg_hdr(*pmsg, &hdr) == 0) + && (hdr->msg_flags & CMD_FLAG_REQUEST) + && (fd_msg_source_get(*pmsg, &diamid, &diamidlen) == 0) + && (diamid == NULL)) { + fd_hook_call(HOOK_MESSAGE_LOCAL, *pmsg, NULL, NULL, fd_msg_pmdl_get(*pmsg)); + } + + /* Post the message in the outgoing queue */ + CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); + + return 0; +} + /* Send a message and optionaly register a callback for an answer */ int fd_msg_send ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data ) { TRACE_ENTRY("%p %p %p", pmsg, anscb, data); CHECK_PARAMS( pmsg ); - /* Save the callback in the message */ - CHECK_FCT( fd_msg_anscb_associate( *pmsg, anscb, data, NULL, NULL /* we should maybe use a safeguard here like 1 hour or so? */ ) ); - - /* Post the message in the outgoing queue */ - CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); - - return 0; + return fd_msg_send_int(pmsg, anscb, data, NULL, NULL); } /* The variation of the same function with a timeout callback */ @@ -334,13 +351,7 @@ TRACE_ENTRY("%p %p %p %p %p", pmsg, anscb, data, expirecb, timeout); CHECK_PARAMS( pmsg && expirecb && timeout ); - /* Save the callback in the message, with the timeout */ - CHECK_FCT( fd_msg_anscb_associate( *pmsg, anscb, data, expirecb, timeout ) ); - - /* Post the message in the outgoing queue */ - CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); - - return 0; + return fd_msg_send_int(pmsg, anscb, data, expirecb, timeout); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/p_ce.c --- a/libfdcore/p_ce.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/p_ce.c Mon May 13 19:17:13 2013 +0800 @@ -649,7 +649,7 @@ fd_cnx_destroy(*recv_cnx); *recv_cnx = NULL; if (*cer) { - //fd_msg_log(FD_MSG_LOG_DROPPED, *cer, "An error occurred while rejecting a CER."); + fd_hook_call(HOOK_MESSAGE_DROPPED, *cer, NULL, "An error occurred while rejecting this CER.", fd_msg_pmdl_get(*cer)); fd_msg_free(*cer); *cer = NULL; } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/p_out.c --- a/libfdcore/p_out.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/p_out.c Mon May 13 19:17:13 2013 +0800 @@ -97,7 +97,7 @@ struct msg *msg = arg; CHECK_FCT_DO(fd_fifo_post(fd_g_outgoing, &msg), { - //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "An error occurred while attempting to requeue this message during cancellation of the sending function"); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, "An error occurred while attempting to requeue this message during cancellation of the sending function", fd_msg_pmdl_get(msg)); CHECK_FCT_DO(fd_msg_free(msg), /* What can we do more? */); } ); } @@ -130,7 +130,9 @@ CHECK_FCT_DO( ret = do_send(&msg, 0, peer->p_cnxctx, &peer->p_hbh, peer), { if (msg) { - //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Internal error: Problem while sending (%s)", strerror(ret) ); + char buf[256]; + snprintf(buf, sizeof(buf), "Error while sending this message: s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); fd_msg_free(msg); } } ); @@ -182,7 +184,9 @@ CHECK_FCT_DO( ret = do_send(msg, flags, cnx, hbh, peer), { if (msg) { - //fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Internal error: Problem while sending (%s)", strerror(ret) ); + char buf[256]; + snprintf(buf, sizeof(buf), "Error while sending this message: s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, *msg, NULL, buf, fd_msg_pmdl_get(*msg)); fd_msg_free(*msg); *msg = NULL; } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/p_psm.c --- a/libfdcore/p_psm.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/p_psm.c Mon May 13 19:17:13 2013 +0800 @@ -240,7 +240,7 @@ case FDEVP_CNX_INCOMING: { struct cnx_incoming * evd = ev->data; - //fd_msg_log( FD_MSG_LOG_DROPPED, evd->cer, "Message discarded while cleaning peer state machine queue." ); + fd_hook_call(HOOK_MESSAGE_DROPPED, evd->cer, NULL, "Message discarded while cleaning peer state machine queue.", fd_msg_pmdl_get(evd->cer)); CHECK_FCT_DO( fd_msg_free(evd->cer), /* continue */); fd_cnx_destroy(evd->cnx); } @@ -576,6 +576,7 @@ /* In such case, just discard the message */ char buf[128]; snprintf(buf, sizeof(buf), "Received while peer state machine was in state %s.", STATE_STR(cur_state)); + LOG_E("%s",buf); fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); fd_msg_free(msg); } @@ -589,8 +590,11 @@ int ret = fd_msg_parse_or_error( &msg, &error ); if (ret != EBADMSG) { CHECK_FCT_DO( ret, - { - LOG_E("%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); + { + char buf[256]; + snprintf(buf, sizeof(buf), "%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); + LOG_E("%s",buf); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); fd_msg_free(msg); goto psm_end; } ); @@ -599,13 +603,18 @@ /* Send the error back to the peer */ CHECK_FCT_DO( ret = fd_out_send(&error, NULL, peer, FD_CNX_ORDERED), ); if (error) { + char buf[256]; /* Only if an error occurred & the message was not saved / dumped */ - LOG_E("%s: error sending a message", peer->p_hdr.info.pi_diamid); + snprintf(buf, sizeof(buf), "%s: error sending a message", peer->p_hdr.info.pi_diamid); + LOG_E("%s",buf); + fd_hook_call(HOOK_MESSAGE_DROPPED, error, peer, buf, fd_msg_pmdl_get(error)); CHECK_FCT_DO( fd_msg_free(error), goto psm_end); } } else { + char buf[256]; /* We received an invalid answer, let's disconnect */ - LOG_E("%s: Received invalid answer to Base protocol message, disconnecting...", peer->p_hdr.info.pi_diamid); + snprintf(buf, sizeof(buf), "%s: Received invalid answer to Base protocol message, disconnecting...", peer->p_hdr.info.pi_diamid); + LOG_E("%s",buf); CHECK_FCT_DO( fd_msg_free(msg), goto psm_end); CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), goto psm_reset ); } @@ -656,7 +665,10 @@ /* Cleanup the message if not done */ if (msg) { - //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Received un-handled non-routable command from peer '%s'.", peer->p_hdr.info.pi_diamid ); + char buf[256]; + snprintf(buf, sizeof(buf), "Received un-handled non-routable command from peer '%s'.", peer->p_hdr.info.pi_diamid); + LOG_E("%s",buf); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); CHECK_FCT_DO( fd_msg_free(msg), /* continue */); msg = NULL; } @@ -664,7 +676,10 @@ /* At this point the message must have been fully handled already */ if (msg) { - //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Internal error ('%s'): unhandled message.", peer->p_hdr.info.pi_diamid ); + char buf[256]; + snprintf(buf, sizeof(buf), "Internal error ('%s'): unhandled message.", peer->p_hdr.info.pi_diamid); + LOG_E("%s",buf); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, buf, fd_msg_pmdl_get(msg)); fd_msg_free(msg); } @@ -731,7 +746,7 @@ { char * buf = NULL; size_t len = 0; - LOG_D("New remote endpoint(s): %s", fd_ep_dump(&buf, &len, NULL, 6, &peer->p_hdr.info.pi_endpoints) ?: "error"); + LOG_D("New remote endpoint(s): %s", fd_ep_dump(&buf, &len, NULL, 0, 0, &peer->p_hdr.info.pi_endpoints) ?: "error"); free(buf); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/p_sr.c --- a/libfdcore/p_sr.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/p_sr.c Mon May 13 19:17:13 2013 +0800 @@ -118,7 +118,7 @@ /* If the callback did not dispose of the message, do it now */ if (ed->request) { - //fd_msg_log(FD_MSG_LOG_DROPPED, ed->request, "Expiration period completed without an answer, and the expiry callback did not dispose of the message."); + fd_hook_call(HOOK_MESSAGE_DROPPED, ed->request, NULL, "Expiration period completed without an answer, and the expiry callback did not dispose of the message.", fd_msg_pmdl_get(ed->request)); CHECK_FCT_DO( fd_msg_free(ed->request), /* ignore */ ); } @@ -322,15 +322,19 @@ if (hdr) hdr->msg_flags |= CMD_FLAG_RETRANSMIT; + fd_hook_call(HOOK_MESSAGE_FAILOVER, sr->req, (struct fd_peer *)srlist->srs.o, NULL, fd_msg_pmdl_get(sr->req)); + /* Requeue for sending to another peer */ CHECK_FCT_DO( ret = fd_fifo_post(fd_g_outgoing, &sr->req), { - //fd_msg_log( FD_MSG_LOG_DROPPED, sr->req, "Internal error: error while requeuing during failover: %s", strerror(ret) ); + char buf[256]; + snprintf(buf, sizeof(buf), "Internal error: error while requeuing during failover: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_DROPPED, sr->req, NULL, buf, fd_msg_pmdl_get(sr->req)); CHECK_FCT_DO(fd_msg_free(sr->req), /* What can we do more? */) }); } else { /* Just free the request. */ - //fd_msg_log( FD_MSG_LOG_DROPPED, sr->req, "Sent & unanswered local message discarded during failover." ); + /* fd_hook_call(HOOK_MESSAGE_DROPPED, sr->req, NULL, "Sent & unanswered local message discarded during failover.", fd_msg_pmdl_get(sr->req)); */ CHECK_FCT_DO(fd_msg_free(sr->req), /* Ignore */); } free(sr); diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/peers.c --- a/libfdcore/peers.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/peers.c Mon May 13 19:17:13 2013 +0800 @@ -241,10 +241,11 @@ /* Requeue all messages in the "out" queue */ while ( fd_fifo_tryget(peer->p_tosend, &m) == 0 ) { + fd_hook_call(HOOK_MESSAGE_FAILOVER, m, peer, NULL, fd_msg_pmdl_get(m)); CHECK_FCT_DO(fd_fifo_post(fd_g_outgoing, &m), { /* fallback: destroy the message */ - //fd_msg_log(FD_MSG_LOG_DROPPED, m, "Internal error: unable to requeue this message during failover process"); + fd_hook_call(HOOK_MESSAGE_DROPPED, m, NULL, "Internal error: unable to requeue this message during failover process", fd_msg_pmdl_get(m)); CHECK_FCT_DO(fd_msg_free(m), /* What can we do more? */) } ); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/queues.c --- a/libfdcore/queues.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/queues.c Mon May 13 19:17:13 2013 +0800 @@ -73,7 +73,7 @@ CHECK_FCT(ret); /* We got one! */ - //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Message lost because framework is terminating." ); + fd_hook_call(HOOK_MESSAGE_DROPPED, msg, NULL, "Message lost because framework is terminating.", fd_msg_pmdl_get(msg)); fd_msg_free(msg); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/routing_dispatch.c --- a/libfdcore/routing_dispatch.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/routing_dispatch.c Mon May 13 19:17:13 2013 +0800 @@ -392,7 +392,9 @@ CHECK_FCT( fd_peer_getbyid( id, idlen, 0, (void *)&peer ) ); if (!peer) { - //fd_msg_log(FD_MSG_LOG_DROPPED, *pmsg, "Unable to send error '%s' to deleted peer '%s' in reply to this message.", error_code, id); + char buf[256]; + snprintf(buf, sizeof(buf), "Unable to send error '%s' to deleted peer '%s' in reply to this message.", error_code, id); + fd_hook_call(HOOK_MESSAGE_DROPPED, *pmsg, NULL, buf, fd_msg_pmdl_get(*pmsg)); fd_msg_free(*pmsg); *pmsg = NULL; return 0; @@ -495,7 +497,7 @@ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msgptr, &sess, NULL) ); /* Now, call any callback registered for the message */ - CHECK_FCT( fd_msg_dispatch ( &msgptr, sess, &action, &ec) ); + CHECK_FCT( fd_msg_dispatch ( &msgptr, sess, &action, &ec, &em, &error) ); /* Now, act depending on msg and action and ec */ if (msgptr) { @@ -504,6 +506,7 @@ /* No callback has handled the message, let's reply with a generic error or relay it */ if (!fd_g_config->cnf_flags.no_fwd) { /* requeue to fd_g_outgoing */ + fd_hook_call(HOOK_MESSAGE_ROUTING_FORWARD, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); break; } @@ -518,7 +521,7 @@ } if (!is_req) { - //fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: Answer received to locally issued request, but not handled by any handler."); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Internal error: Answer received to locally issued request, but not handled by any handler.", fd_msg_pmdl_get(msgptr)); fd_msg_free(msgptr); break; } @@ -531,6 +534,9 @@ /* Now, send the message */ CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); } + } else if (em) { + fd_hook_call(HOOK_MESSAGE_DROPPED, error, NULL, em, fd_msg_pmdl_get(error)); + fd_msg_free(error); } /* We're done with dispatching this message */ @@ -554,6 +560,7 @@ /* Handle incorrect bits */ if (is_req && is_err) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "R & E bits were set", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) ); return 0; } @@ -572,8 +579,7 @@ /* Check if we have local support for the message application */ if ( (hdr->msg_appl == 0) || (hdr->msg_appl == AI_RELAY) ) { - TRACE_DEBUG(INFO, "Received a routable message with application id 0 or " _stringize(AI_RELAY) " (relay)," - " returning DIAMETER_APPLICATION_UNSUPPORTED"); + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Received a routable message with application id 0 or " _stringize(AI_RELAY) " (relay)", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) ); return 0; } else { @@ -600,9 +606,11 @@ CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), { if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); return 0; } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Host AVP", fd_msg_pmdl_get(msgptr)); return ret; } } ); @@ -620,9 +628,11 @@ CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), { if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); return 0; } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Realm AVP", fd_msg_pmdl_get(msgptr)); return ret; } } ); @@ -642,9 +652,11 @@ CHECK_FCT_DO( ret = fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, &error_info ), { if (error_info.pei_errcode) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); return 0; } else { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing User-Name AVP", fd_msg_pmdl_get(msgptr)); return ret; } } ); @@ -667,6 +679,7 @@ /* Handle the missing routing AVPs first */ if ( is_dest_realm == UNKNOWN ) { + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) ); return 0; } @@ -675,9 +688,11 @@ if (is_dest_host == YES) { if (is_local_app == YES) { /* Ok, give the message to the dispatch thread */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT( fd_fifo_post(fd_g_local, &msgptr) ); } else { /* We don't support the application, reply an error */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Application unsupported", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); } return 0; @@ -686,6 +701,7 @@ /* If the message is explicitely for someone else */ if ((is_dest_host == NO) || (is_dest_realm == NO)) { if (fd_g_config->cnf_flags.no_fwd) { + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "Message for another realm/host", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) ); return 0; } @@ -699,6 +715,7 @@ CHECK_FCT_DO( process_decorated_NAI(&is_nai, un_val, dr_val), { /* If the process failed, we assume it is because of the AVP format */ + fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Failed to process decorated NAI", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) ); return 0; } ); @@ -712,12 +729,14 @@ if (is_local_app == YES) { /* Handle localy since we are able to */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); return 0; } if (fd_g_config->cnf_flags.no_fwd) { /* We return an error */ + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "Application unsupported", fd_msg_pmdl_get(msgptr)); CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); return 0; } @@ -735,6 +754,7 @@ if ((!qry_src) && (!is_err)) { /* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */ + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); return 0; } @@ -763,9 +783,13 @@ TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", msgptr, rh->rt_fwd_cb); CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, &msgptr), { - //fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: a FWD routing callback returned an error (%s)", strerror(ret)); + char buf[256]; + snprintf(buf, sizeof(buf), "A FWD routing callback returned an error: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); fd_msg_free(msgptr); msgptr = NULL; + break; } ); } @@ -779,8 +803,10 @@ /* Now pass the message to the next step: either forward to another peer, or dispatch to local extensions */ if (is_req || qry_src) { + fd_hook_call(HOOK_MESSAGE_ROUTING_FORWARD, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT(fd_fifo_post(fd_g_outgoing, &msgptr) ); } else { + fd_hook_call(HOOK_MESSAGE_ROUTING_LOCAL, msgptr, NULL, NULL, fd_msg_pmdl_get(msgptr)); CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); } @@ -822,7 +848,10 @@ /* Find the peer corresponding to this name */ CHECK_FCT( fd_peer_getbyid( qry_src, qry_src_len, 0, (void *) &peer ) ); if (fd_peer_getstate(peer) != STATE_OPEN) { - //fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Unable to forward answer to deleted / closed peer '%s'.", qry_src); + char buf[128]; + snprintf(buf, sizeof(buf), "Unable to forward answer to deleted / closed peer '%s'.", qry_src); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); fd_msg_free(msgptr); return 0; } @@ -907,7 +936,10 @@ TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msgptr, rh->rt_out_cb, rh->prio); CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, msgptr, candidates), { - //fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: an OUT routing callback returned an error (%s)", strerror(ret)); + char buf[256]; + snprintf(buf, sizeof(buf), "An OUT routing callback returned an error: %s", strerror(ret)); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); + fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, buf, fd_msg_pmdl_get(msgptr)); fd_msg_free(msgptr); msgptr = NULL; break; @@ -955,7 +987,7 @@ /* If the message has not been sent, return an error */ if (msgptr) { - //fd_msg_log( FD_MSG_LOG_NODELIVER, msgptr, "No suitable candidate to route the message to." ); + fd_hook_call(HOOK_MESSAGE_ROUTING_ERROR, msgptr, NULL, "No remaining suitable candidate to route the message to", fd_msg_pmdl_get(msgptr)); return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdcore/server.c --- a/libfdcore/server.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdcore/server.c Mon May 13 19:17:13 2013 +0800 @@ -93,7 +93,7 @@ /* Dump all servers information */ -DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump) +DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump, int details) { struct fd_list * li, *cli; @@ -103,24 +103,29 @@ struct server * s = (struct server *)li; enum s_state st = get_status(s); - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s, %s", s, fd_cnx_getid(s->conn), - IPPROTO_NAME( s->proto ), - s->secur ? "Secur" : "NotSecur", - (st == NOT_CREATED) ? "Thread not created" : - ((st == RUNNING) ? "Thread running" : - ((st == TERMINATED) ? "Thread terminated" : - "Thread status unknown"))), return NULL); - /* Dump the client list of this server */ - CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), ); - for (cli = s->clients.next; cli != &s->clients; cli = cli->next) { - struct client * c = (struct client *)cli; - char bufts[128]; - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {client}(@%p)'%s': to:%s", c, fd_cnx_getid(c->conn), fd_log_time(&c->ts, bufts, sizeof(bufts))), break); - } - CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), ); - - if (li->next != &FD_SERVERS) { - CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + if (details) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s, %s", s, fd_cnx_getid(s->conn), + IPPROTO_NAME( s->proto ), + s->secur ? "Secur" : "NotSecur", + (st == NOT_CREATED) ? "Thread not created" : + ((st == RUNNING) ? "Thread running" : + ((st == TERMINATED) ? "Thread terminated" : + "Thread status unknown"))), return NULL); + /* Dump the client list of this server */ + CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), ); + for (cli = s->clients.next; cli != &s->clients; cli = cli->next) { + struct client * c = (struct client *)cli; + char bufts[128]; + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {client}(@%p)'%s': to:%s", c, fd_cnx_getid(c->conn), fd_log_time(&c->ts, bufts, sizeof(bufts))), break); + } + CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), ); + + if (li->next != &FD_SERVERS) { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); + } + } else { + CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%s,%s) ", fd_cnx_getid(s->conn), + IPPROTO_NAME( s->proto ), s->secur ? "Secur" : "NotSecur"), return NULL); } } @@ -445,7 +450,7 @@ char * buf = NULL; size_t len = 0, offset = 0; CHECK_MALLOC_DO( fd_dump_extend( &buf, &len, &offset , "Local server address(es): "), ); - CHECK_MALLOC_DO( fd_ep_dump( &buf, &len, &offset, 5, &fd_g_config->cnf_endpoints ), ); + CHECK_MALLOC_DO( fd_ep_dump( &buf, &len, &offset, 0, 0, &fd_g_config->cnf_endpoints ), ); LOG_N("%s", buf ?: "Error dumping addresses"); free(buf); } diff -r d87cee14b051 -r eb4ce68b6e5c libfdproto/dispatch.c --- a/libfdproto/dispatch.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdproto/dispatch.c Mon May 13 19:17:13 2013 +0800 @@ -67,7 +67,8 @@ /* Call CBs from a given list (any_handlers if cb_list is NULL) -- must have locked fd_disp_lock before */ int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, - struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu) + struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu, + char ** drop_reason, struct msg ** drop_msg) { struct fd_list * senti, *li; int r; @@ -96,8 +97,8 @@ /* We have a match, the cb must be called. */ CHECK_FCT_DO( (r = (*hdl->cb)(msg, avp, sess, hdl->opaque, action)), { - //fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Internal error: a DISPATCH callback returned an error (%s)", strerror(r)); - fd_msg_free(*msg); + *drop_reason = "Internal error: a DISPATCH callback returned an error"; + *drop_msg = *msg; *msg = NULL; } ); diff -r d87cee14b051 -r eb4ce68b6e5c libfdproto/fdproto-internal.h --- a/libfdproto/fdproto-internal.h Mon May 13 18:50:26 2013 +0800 +++ b/libfdproto/fdproto-internal.h Mon May 13 19:17:13 2013 +0800 @@ -54,7 +54,8 @@ int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list); DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header); int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, - struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu); + struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu, + char ** drop_reason, struct msg ** drop_msg); extern pthread_rwlock_t fd_disp_lock; /* Messages / sessions API */ diff -r d87cee14b051 -r eb4ce68b6e5c libfdproto/messages.c --- a/libfdproto/messages.c Mon May 13 18:50:26 2013 +0800 +++ b/libfdproto/messages.c Mon May 13 19:17:13 2013 +0800 @@ -2669,7 +2669,7 @@ goto out; /* Call all dispatch callbacks for a given message */ -int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code) +int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code, char ** drop_reason, struct msg ** drop_msg) { struct dictionary * dict; struct dict_object * app; @@ -2683,6 +2683,8 @@ if (error_code) *error_code = NULL; + if (drop_reason) + *drop_reason = NULL; *action = DISP_ACT_CONT; /* Take the dispatch lock */ @@ -2690,7 +2692,7 @@ pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock ); /* First, call the DISP_HOW_ANY callbacks */ - CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL, drop_reason, drop_msg ), goto out ); TEST_ACTION_STOP(); @@ -2707,8 +2709,8 @@ *error_code = "DIAMETER_APPLICATION_UNSUPPORTED"; *action = DISP_ACT_ERROR; } else { - //fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Internal error: Received this answer to a local query with an unsupported application %d", (*msg)->msg_public.msg_appl); - fd_msg_free(*msg); + *drop_reason = "Internal error: Received this answer to a local query with an unsupported application"; + *drop_msg = *msg; *msg = NULL; } goto out; @@ -2739,7 +2741,7 @@ } /* Call the callbacks */ - CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval, drop_reason, drop_msg ), goto out ); TEST_ACTION_STOP(); } /* Go to next AVP */ @@ -2748,12 +2750,12 @@ /* Now call command and application callbacks */ CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto out ); - CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); TEST_ACTION_STOP(); if (app) { CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto out ); - CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out ); + CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); TEST_ACTION_STOP(); } out: diff -r d87cee14b051 -r eb4ce68b6e5c tests/testdisp.c --- a/tests/testdisp.c Mon May 13 18:50:26 2013 +0800 +++ b/tests/testdisp.c Mon May 13 19:17:13 2013 +0800 @@ -105,11 +105,11 @@ struct dict_object * cmd1, * cmd2; struct dict_object * avp1, * avp2; /* avp2 is enumerated; they are both unsigned32 types */ struct dict_object * enu1, * enu2; - struct msg * msg = NULL; + struct msg * msg = NULL, *error; enum disp_action action; struct disp_hdl * hdl[NB_CB]; struct disp_when when; - char * ec; + char * ec, *em; /* First, initialize the daemon modules */ INIT_FD(); @@ -155,7 +155,7 @@ /* Check this handler is called for a message */ msg = new_msg( 0, cmd1, avp1, NULL, 0 ); memset(cbcalled, 0, sizeof(cbcalled)); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( DISP_ACT_CONT, action ); @@ -179,7 +179,7 @@ /* Check the callbacks are called as appropriate */ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 0, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -190,7 +190,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -201,7 +201,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -235,7 +235,7 @@ /* Check the callbacks are called as appropriate */ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 0, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -245,7 +245,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -255,7 +255,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -265,7 +265,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd2, NULL, avp2, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -315,7 +315,7 @@ /* Check the callbacks are called as appropriate */ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 0, cmd1, NULL, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -327,7 +327,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 0, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -339,7 +339,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd2, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -351,7 +351,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -363,7 +363,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, avp2, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -376,7 +376,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, NULL, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -389,7 +389,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, NULL, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -436,7 +436,7 @@ /* Check the callbacks are called as appropriate */ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 0, cmd1, avp1, NULL, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -446,7 +446,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd2, avp1, avp2, 0 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -456,7 +456,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd2, avp1, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -466,7 +466,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -476,7 +476,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -494,7 +494,7 @@ CHECK( 0, fd_msg_avp_setvalue ( avp, &value ) ); CHECK( 0, fd_msg_avp_add ( msg, MSG_BRW_LAST_CHILD, avp ) ); } - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -518,13 +518,15 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[6] ); CHECK( 0, cbcalled[2] ); CHECK( 0, cbcalled[3] ); CHECK( 0, msg ? 1 : 0); + CHECK( 1, ec ? 1 : 0); + CHECK( 0, fd_msg_free( error ) ); CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) ); CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) ); @@ -540,13 +542,14 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[8] ); CHECK( 0, cbcalled[2] ); CHECK( 0, cbcalled[3] ); CHECK( NULL, msg ); + CHECK( NULL, ec ); CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) ); CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) ); @@ -562,7 +565,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 1, cmd1, avp1, avp2, 1 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[9] ); @@ -593,7 +596,7 @@ memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -605,7 +608,7 @@ CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, NULL, &hdl[5] ) ); memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 0, cbcalled[1] ); CHECK( 0, cbcalled[2] ); @@ -618,7 +621,7 @@ CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[5] ) ); memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -631,7 +634,7 @@ CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP, &when, NULL, &hdl[5] ) ); memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -644,7 +647,7 @@ CHECK( 0, fd_disp_register( cb_9, DISP_HOW_CC, &when, NULL, &hdl[5] ) ); memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -657,7 +660,7 @@ CHECK( 0, fd_disp_register( cb_9, DISP_HOW_APPID, &when, NULL, &hdl[5] ) ); memset(cbcalled, 0, sizeof(cbcalled)); msg = new_msg( 2, cmd2, avp1, avp2, 2 ); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( 1, cbcalled[1] ); CHECK( 1, cbcalled[2] ); @@ -710,7 +713,7 @@ /* Check this handler is called for a message */ msg = new_msg( 0, cmd1, avp1, NULL, 0 ); memset(cbcalled, 0, sizeof(cbcalled)); - CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) ); + CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) ); CHECK( 1, cbcalled[0] ); CHECK( DISP_ACT_CONT, action );