Navigation


Changeset 90:2c9444152e4b in freeDiameter


Ignore:
Timestamp:
Dec 7, 2009, 6:32:30 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Added the dispatch thread code

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/dispatch.c

    r89 r90  
    6767
    6868
    69 /* Note: if the message is for local delivery, we should test for duplicate
    70   (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */
    71 
    72 
     69/* The dispatching thread(s) */
     70
     71enum thread_state { INITIAL = 0, RUNNING = 1, TERMINATED = 2 };
     72static void cleanup_state(void * state_loc)
     73{
     74        if (state_loc)
     75                *(enum thread_state *)state_loc = TERMINATED;
     76}
     77
     78static pthread_mutex_t order_lock = PTHREAD_MUTEX_INITIALIZER;
     79static enum { RUN = 0, STOP = 1 } order_val;
     80
     81static void * dispatch_thread(void * arg)
     82{
     83        TRACE_ENTRY("%p", arg);
     84       
     85        /* Set the thread name */
     86        {
     87                char buf[48];
     88                snprintf(buf, sizeof(buf), "Dispatch %p", arg);
     89                fd_log_threadname ( buf );
     90        }
     91
     92        pthread_cleanup_push( cleanup_state, arg );
     93       
     94        /* Mark the thread running */
     95        *(enum thread_state *)arg = RUNNING;
     96       
     97        do {
     98                struct msg * msg;
     99                struct msg_hdr * hdr;
     100                int is_req = 0;
     101                struct session * sess;
     102                enum disp_action action;
     103                const char * ec = NULL;
     104                const char * em = NULL;
     105               
     106                /* Test the environment */
     107                {
     108                        int must_stop;
     109                        CHECK_POSIX_DO( pthread_mutex_lock(&order_lock), goto end ); /* we lock to flush the caches */
     110                        must_stop = (order_val == STOP);
     111                        CHECK_POSIX_DO( pthread_mutex_unlock(&order_lock), goto end );
     112                        if (must_stop)
     113                                goto end;
     114                       
     115                        pthread_testcancel();
     116                }
     117               
     118                /* Ok, we are allowed to run */
     119               
     120                /* Get the next message from the queue */
     121                CHECK_FCT_DO( fd_fifo_get ( fd_g_local, &msg ), goto fatal_error );
     122               
     123                if (TRACE_BOOL(FULL)) {
     124                        TRACE_DEBUG(FULL, "Picked next message:");
     125                        fd_msg_dump_one(FULL, msg);
     126                }
     127               
     128                /* Read the message header */
     129                CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto fatal_error );
     130                is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
     131               
     132                /* Note: if the message is for local delivery, we should test for duplicate
     133                  (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */
     134               
     135                /* At this point, we probably need to understand the message content, so parse the message */
     136                CHECK_FCT_DO( fd_msg_parse_dict ( msg, fd_g_config->cnf_dict ), /* Ignore error */);
     137               
     138                /* First, if the original request was registered with a callback and we receive the answer, call it. */
     139                if ( ! is_req ) {
     140                        struct msg * qry;
     141                        void (*anscb)(void *, struct msg **) = NULL;
     142                        void * data = NULL;
     143                       
     144                        /* Retrieve the corresponding query */
     145                        CHECK_FCT_DO( fd_msg_answ_getq( msg, &qry ), goto fatal_error );
     146                       
     147                        /* Retrieve any registered handler */
     148                        CHECK_FCT_DO( fd_msg_anscb_get( qry, &anscb, &data ), goto fatal_error );
     149                       
     150                        /* If a callback was registered, pass the message to it */
     151                        if (anscb != NULL) {
     152                               
     153                                TRACE_DEBUG(FULL, "Calling callback registered when query was sent (%p, %p)", anscb, data);
     154                                (*anscb)(data, &msg);
     155                               
     156                                if (msg == NULL) {
     157                                        /* Ok, the message is now handled, we can skip to the next one */
     158                                        continue;
     159                                }
     160                        }
     161                }
     162               
     163                /* Retrieve the session of the message */
     164                CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, msg, &sess, NULL), goto fatal_error );
     165               
     166                /* Now, call any callback registered for the message */
     167                CHECK_FCT_DO( fd_msg_dispatch ( &msg, sess, &action, &ec), goto fatal_error );
     168               
     169                /* Now, act depending on msg and action and ec */
     170                if (!msg)
     171                        continue;
     172               
     173                switch ( action ) {
     174                        case DISP_ACT_CONT:
     175                                /* No callback has handled the message, let's reply with a generic error */
     176                                em = "The message was not handled by any extension callback";
     177                                ec = "DIAMETER_COMMAND_UNSUPPORTED";
     178                       
     179                        case DISP_ACT_ERROR:
     180                                /* We have a problem with delivering the message */
     181                                if (ec == NULL) {
     182                                        ec = "DIAMETER_UNABLE_TO_COMPLY";
     183                                }
     184                               
     185                                if (!is_req) {
     186                                        TRACE_DEBUG(INFO, "Received an answer to a localy issued query, but no handler processed this answer!");
     187                                        fd_msg_dump_walk(INFO, msg);
     188                                        fd_msg_free(msg);
     189                                        msg = NULL;
     190                                        break;
     191                                }
     192                               
     193                                /* Create an answer with the error code and message */
     194                                CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, MSGFL_ANSW_ERROR ), goto fatal_error );
     195                                CHECK_FCT_DO( fd_msg_rescode_set(msg, (char *)ec, (char *)em, NULL, 1 ), goto fatal_error );
     196                               
     197                        case DISP_ACT_SEND:
     198                                /* Now, send the message */
     199                                CHECK_FCT_DO( fd_fifo_post(fd_g_outgoing, &msg), goto fatal_error );
     200                }
     201               
     202                /* We're done with this message */
     203       
     204        } while (1);
     205       
     206fatal_error:
     207        TRACE_DEBUG(INFO, "An error occurred in dispatch module! Thread is terminating...");
     208        CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );
     209       
     210end:   
     211        /* Mark the thread as terminated */
     212        pthread_cleanup_pop(1);
     213        return NULL;
     214}
     215
     216/* Later (same as routing): TODO("Set threshold on local queue"); */
     217static pthread_t my_dispatch = (pthread_t)NULL;
     218static enum thread_state my_state = INITIAL;
     219
     220/* Initialize the Dispatch module */
     221int fd_disp_init(void)
     222{
     223        order_val = RUN;
     224       
     225        CHECK_POSIX( pthread_create( &my_dispatch, NULL, dispatch_thread, &my_state ) );
     226       
     227        return 0;
     228}
     229
     230int fd_disp_cleanstop(void)
     231{
     232        CHECK_POSIX( pthread_mutex_lock(&order_lock) );
     233        order_val = STOP;
     234        CHECK_POSIX( pthread_mutex_unlock(&order_lock) );
     235
     236        return 0;
     237}
     238
     239int fd_disp_fini(void)
     240{
     241        /* Wait for a few milliseconds for the thread to complete, by monitoring my_state */
     242
     243        /* Then if needed, cancel the thread */
     244       
     245        /* Remove all remaining handlers */
     246        fd_disp_unregister_all();
     247       
     248        return ENOTSUP;
     249}
     250
  • freeDiameter/main.c

    r82 r90  
    100100        CHECK_FCT(  fd_msg_init()  );
    101101        CHECK_FCT(  fd_p_expi_init()  );
     102        CHECK_FCT(  fd_disp_init()  );
    102103        CHECK_FCT(  fd_rt_init()  );
    103104       
     
    162163        /* cleanups */
    163164        CHECK_FCT_DO( fd_servers_stop(), /* Stop accepting new connections */ );
    164         TODO("Stop dispatch thread(s) properly (no cancel yet)");
     165        CHECK_FCT_DO( fd_disp_cleanstop(), /* Stop dispatch thread(s) properly (no cancel yet) */ );
    165166        CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ );
    166         TODO("Stop dispatch & routing threads");
     167        CHECK_FCT_DO( fd_rt_fini(), /* Stop routing threads */ );
     168        CHECK_FCT_DO( fd_disp_fini(), /* Stop dispatch thread */ );
     169       
    167170        CHECK_FCT_DO( fd_ext_fini(), /* Cleaup all extensions */ );
    168171        TODO("Cleanup queues (dump all remaining messages ?)");
  • freeDiameter/routing.c

    r89 r90  
    863863        CHECK_FCT_DO( fd_thr_term(&rt_in ), /* continue */);
    864864        CHECK_FCT_DO( fd_thr_term(&rt_out), /* continue */);
    865         return 0;
    866 }
    867 
    868 
    869 
     865       
     866        /* Cleanup all remaining handlers */
     867        while (!FD_IS_LIST_EMPTY(&rt_fwd_list)) {
     868                CHECK_FCT_DO( fd_rt_fwd_unregister ( (void *)rt_fwd_list.next, NULL ), /* continue */ );
     869        }
     870        while (!FD_IS_LIST_EMPTY(&rt_out_list)) {
     871                CHECK_FCT_DO( fd_rt_out_unregister ( (void *)rt_out_list.next, NULL ), /* continue */ );
     872        }
     873        return 0;
     874}
     875
     876
     877
  • freeDiameter/tests/testdisp.c

    r10 r90  
    106106        struct disp_hdl * hdl[NB_CB];
    107107        struct disp_when when;
     108        const char * ec;
    108109       
    109110        /* First, initialize the daemon modules */
     
    150151                msg = new_msg( 0, cmd1, avp1, NULL, 0 );
    151152                memset(cbcalled, 0, sizeof(cbcalled));
    152                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     153                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    153154                CHECK( 1, cbcalled[0] );
    154155                CHECK( DISP_ACT_CONT, action );
     
    174175                memset(cbcalled, 0, sizeof(cbcalled));
    175176                msg = new_msg( 0, cmd1, avp1, NULL, 0 );
    176                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     177                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    177178                CHECK( 1, cbcalled[0] );
    178179                CHECK( 0, cbcalled[1] );
     
    185186                memset(cbcalled, 0, sizeof(cbcalled));
    186187                msg = new_msg( 1, cmd1, avp1, NULL, 0 );
    187                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     188                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    188189                CHECK( 1, cbcalled[0] );
    189190                CHECK( 1, cbcalled[1] );
     
    196197                memset(cbcalled, 0, sizeof(cbcalled));
    197198                msg = new_msg( 2, cmd1, avp1, NULL, 0 );
    198                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     199                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    199200                CHECK( 1, cbcalled[0] );
    200201                CHECK( 0, cbcalled[1] );
     
    230231                memset(cbcalled, 0, sizeof(cbcalled));
    231232                msg = new_msg( 0, cmd1, avp1, NULL, 0 );
    232                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     233                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    233234                CHECK( 1, cbcalled[0] );
    234235                CHECK( 1, cbcalled[1] );
     
    240241                memset(cbcalled, 0, sizeof(cbcalled));
    241242                msg = new_msg( 2, cmd1, avp1, NULL, 0 );
    242                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     243                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    243244                CHECK( 1, cbcalled[0] );
    244245                CHECK( 1, cbcalled[1] );
     
    250251                memset(cbcalled, 0, sizeof(cbcalled));
    251252                msg = new_msg( 2, cmd2, avp1, NULL, 0 );
    252                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     253                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    253254                CHECK( 1, cbcalled[0] );
    254255                CHECK( 0, cbcalled[1] );
     
    260261                memset(cbcalled, 0, sizeof(cbcalled));
    261262                msg = new_msg( 1, cmd2, NULL, avp2, 0 );
    262                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     263                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    263264                CHECK( 1, cbcalled[0] );
    264265                CHECK( 0, cbcalled[1] );
     
    310311                memset(cbcalled, 0, sizeof(cbcalled));
    311312                msg = new_msg( 0, cmd1, NULL, NULL, 0 );
    312                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     313                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    313314                CHECK( 1, cbcalled[0] );
    314315                CHECK( 0, cbcalled[1] );
     
    322323                memset(cbcalled, 0, sizeof(cbcalled));
    323324                msg = new_msg( 0, cmd1, avp1, NULL, 0 );
    324                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     325                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    325326                CHECK( 1, cbcalled[0] );
    326327                CHECK( 1, cbcalled[1] );
     
    334335                memset(cbcalled, 0, sizeof(cbcalled));
    335336                msg = new_msg( 1, cmd2, avp1, NULL, 0 );
    336                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     337                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    337338                CHECK( 1, cbcalled[0] );
    338339                CHECK( 1, cbcalled[1] );
     
    346347                memset(cbcalled, 0, sizeof(cbcalled));
    347348                msg = new_msg( 1, cmd1, avp1, NULL, 0 );
    348                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     349                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    349350                CHECK( 1, cbcalled[0] );
    350351                CHECK( 1, cbcalled[1] );
     
    358359                memset(cbcalled, 0, sizeof(cbcalled));
    359360                msg = new_msg( 1, cmd1, avp1, avp2, 0 );
    360                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     361                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    361362                CHECK( 1, cbcalled[0] );
    362363                CHECK( 1, cbcalled[1] );
     
    371372                memset(cbcalled, 0, sizeof(cbcalled));
    372373                msg = new_msg( 1, cmd1, NULL, avp2, 1 );
    373                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     374                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    374375                CHECK( 1, cbcalled[0] );
    375376                CHECK( 0, cbcalled[1] );
     
    384385                memset(cbcalled, 0, sizeof(cbcalled));
    385386                msg = new_msg( 1, cmd1, NULL, avp2, 2 );
    386                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     387                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    387388                CHECK( 1, cbcalled[0] );
    388389                CHECK( 0, cbcalled[1] );
     
    431432                memset(cbcalled, 0, sizeof(cbcalled));
    432433                msg = new_msg( 0, cmd1, avp1, NULL, 0 );
    433                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     434                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    434435                CHECK( 1, cbcalled[0] );
    435436                CHECK( 0, cbcalled[1] );
     
    441442                memset(cbcalled, 0, sizeof(cbcalled));
    442443                msg = new_msg( 1, cmd2, avp1, avp2, 0 );
    443                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     444                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    444445                CHECK( 1, cbcalled[0] );
    445446                CHECK( 0, cbcalled[1] );
     
    451452                memset(cbcalled, 0, sizeof(cbcalled));
    452453                msg = new_msg( 1, cmd2, avp1, avp2, 1 );
    453                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     454                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    454455                CHECK( 1, cbcalled[0] );
    455456                CHECK( 1, cbcalled[1] );
     
    461462                memset(cbcalled, 0, sizeof(cbcalled));
    462463                msg = new_msg( 1, cmd2, avp1, avp2, 2 );
    463                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     464                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    464465                CHECK( 1, cbcalled[0] );
    465466                CHECK( 0, cbcalled[1] );
     
    471472                memset(cbcalled, 0, sizeof(cbcalled));
    472473                msg = new_msg( 1, cmd1, avp1, avp2, 1 );
    473                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     474                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    474475                CHECK( 1, cbcalled[0] );
    475476                CHECK( 1, cbcalled[1] );
     
    489490                        CHECK( 0, fd_msg_avp_add ( msg, MSG_BRW_LAST_CHILD, avp ) );
    490491                }
    491                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     492                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    492493                CHECK( 1, cbcalled[0] );
    493494                CHECK( 1, cbcalled[1] );
     
    513514                memset(cbcalled, 0, sizeof(cbcalled));
    514515                msg = new_msg( 1, cmd1, avp1, avp2, 1 );
    515                 CHECK( 12345, fd_msg_dispatch ( &msg, sess, &action ) );
     516                CHECK( 12345, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    516517                CHECK( 1, cbcalled[0] );
    517518                CHECK( 1, cbcalled[1] );
     
    535536                memset(cbcalled, 0, sizeof(cbcalled));
    536537                msg = new_msg( 1, cmd1, avp1, avp2, 1 );
    537                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     538                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    538539                CHECK( 1, cbcalled[0] );
    539540                CHECK( 1, cbcalled[1] );
     
    557558                memset(cbcalled, 0, sizeof(cbcalled));
    558559                msg = new_msg( 1, cmd1, avp1, avp2, 1 );
    559                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     560                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    560561                CHECK( 1, cbcalled[0] );
    561562                CHECK( 1, cbcalled[1] );
     
    588589                memset(cbcalled, 0, sizeof(cbcalled));
    589590                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    590                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     591                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    591592                CHECK( 1, cbcalled[0] );
    592593                CHECK( 1, cbcalled[1] );
     
    600601                memset(cbcalled, 0, sizeof(cbcalled));
    601602                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    602                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     603                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    603604                CHECK( 1, cbcalled[0] );
    604605                CHECK( 0, cbcalled[1] );
     
    613614                memset(cbcalled, 0, sizeof(cbcalled));
    614615                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    615                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     616                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    616617                CHECK( 1, cbcalled[0] );
    617618                CHECK( 1, cbcalled[1] );
     
    626627                memset(cbcalled, 0, sizeof(cbcalled));
    627628                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    628                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     629                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    629630                CHECK( 1, cbcalled[0] );
    630631                CHECK( 1, cbcalled[1] );
     
    639640                memset(cbcalled, 0, sizeof(cbcalled));
    640641                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    641                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     642                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    642643                CHECK( 1, cbcalled[0] );
    643644                CHECK( 1, cbcalled[1] );
     
    652653                memset(cbcalled, 0, sizeof(cbcalled));
    653654                msg = new_msg( 2, cmd2, avp1, avp2, 2 );
    654                 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action ) );
     655                CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
    655656                CHECK( 1, cbcalled[0] );
    656657                CHECK( 1, cbcalled[1] );
  • include/freeDiameter/libfreeDiameter.h

    r88 r90  
    23532353enum disp_action {
    23542354        DISP_ACT_CONT,  /* The next handler should be called, unless *msg == NULL. */
    2355         DISP_ACT_SEND   /* The updated message must be sent. No further callback is called. */
     2355        DISP_ACT_SEND,  /* The updated message must be sent. No further callback is called. */
     2356        DISP_ACT_ERROR  /* An error must be created and sent as a reply -- not valid for callbacks, only for fd_msg_dispatch. */
    23562357};
    23572358/* The callbacks that are registered have the following prototype:
     
    24242425int fd_disp_unregister ( struct disp_hdl ** handle );
    24252426
     2427/* Destroy all handlers */
     2428void fd_disp_unregister_all ( void );
     2429
    24262430/*
    24272431 * FUNCTION:    fd_msg_dispatch
     
    24432447 *  (other errors)
    24442448 */
    2445 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action );
     2449int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code );
    24462450
    24472451
  • libfreeDiameter/dispatch.c

    r14 r90  
    200200}
    201201
     202/* Delete all handlers */
     203void fd_disp_unregister_all ( void )
     204{
     205        TRACE_ENTRY("");
     206        while (!FD_IS_LIST_EMPTY(&all_handlers)) {
     207                CHECK_FCT_DO( fd_disp_unregister(all_handlers.next->o), /* continue */ );
     208        }
     209        return;
     210}
  • libfreeDiameter/messages.c

    r85 r90  
    22332233
    22342234/* Call all dispatch callbacks for a given message */
    2235 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action)
     2235int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code)
    22362236{
    22372237        struct dictionary  * dict;
     
    22422242        int ret = 0;
    22432243       
    2244         TRACE_ENTRY("%p %p %p", msg, session, action);
     2244        TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code);
    22452245        CHECK_PARAMS( msg && CHECK_MSG(*msg) && action);
     2246       
     2247        if (error_code)
     2248                *error_code = NULL;
    22462249       
    22472250        /* Take the dispatch lock */
     
    22622265       
    22632266        if (app == NULL) {
    2264                 /* In that case, maybe we should answer a DIAMETER_APPLICATION_UNSUPPORTED error ? Do we do this here ? */
    2265                 TODO("Reply DIAMETER_APPLICATION_UNSUPPORTED if it's a request ?");
     2267                if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) {
     2268                        if (error_code)
     2269                                *error_code = "DIAMETER_APPLICATION_UNSUPPORTED";
     2270                        *action = DISP_ACT_ERROR;
     2271                } else {
     2272                        TRACE_DEBUG(INFO, "Received an answer to a local query with an unsupported application %d, discarding...",  (*msg)->msg_public.msg_appl);
     2273                        fd_msg_dump_walk(INFO, *msg);
     2274                        fd_msg_free(*msg);
     2275                        *msg = NULL;
     2276                }
     2277                goto no_error;
    22662278        }
    22672279       
Note: See TracChangeset for help on using the changeset viewer.