Navigation


Changeset 6:b0d377c79d80 in freeDiameter


Ignore:
Timestamp:
Sep 3, 2009, 4:03:25 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Progress on dispatch API spec; added fd_sess_reclaim function and test

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/tests/testsess.c

    r5 r6  
    172172        }
    173173       
     174        /* Test fd_sess_reclaim */
     175        {
     176                struct mystate *tms;
     177               
     178                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
     179                CHECK( 1, new ? 1 : 0 );
     180               
     181                CHECK( 0, fd_sess_reclaim( &sess1 ) );
     182                CHECK( NULL, sess1 );
     183               
     184                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
     185                CHECK( 1, new ? 1 : 0 );
     186               
     187                tms = new_state(TEST_SID, NULL);
     188                CHECK( 0, fd_sess_state_store ( hdl1, sess1, &tms ) );
     189               
     190                CHECK( 0, fd_sess_reclaim( &sess1 ) );
     191                CHECK( NULL, sess1 );
     192               
     193                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
     194                CHECK( 0, new );
     195               
     196                CHECK( 0, fd_sess_destroy( &sess1 ) );
     197               
     198                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
     199                CHECK( 1, new ? 1 : 0 );
     200               
     201                CHECK( 0, fd_sess_destroy( &sess1 ) );
     202        }
     203       
    174204        /* Test timeout function */
    175205        {
  • include/freeDiameter/libfreeDiameter.h

    r5 r6  
    13091309 *  ENOMEM      : Not enough memory to complete the operation
    13101310 */
    1311 int fd_sess_handler_create_int ( struct session_handler ** handler, void (*cleanup)(char * sid, session_state * state) );
     1311int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(char * sid, session_state * state) );
    13121312/* Macro to avoid casting everywhere */
    13131313#define fd_sess_handler_create( _handler, _cleanup ) \
    1314         fd_sess_handler_create_int( (_handler), (void (*)(char *, session_state *))(_cleanup) )
     1314        fd_sess_handler_create_internal( (_handler), (void (*)(char *, session_state *))(_cleanup) )
    13151315
    13161316/*
     
    14381438int fd_sess_destroy ( struct session ** session );
    14391439
     1440/*
     1441 * FUNCTION:    fd_sess_reclaim
     1442 *
     1443 * PARAMETERS:
     1444 *  session     : Pointer to a session object.
     1445 *
     1446 * DESCRIPTION:
     1447 *   Destroys the resources of a session, only if no session_state is associated with it.
     1448 *
     1449 * RETURN VALUE:
     1450 *  0           : The session no longer exists.
     1451 *  EINVAL      : A parameter is invalid.
     1452 */
     1453int fd_sess_reclaim ( struct session ** session );
     1454
     1455
    14401456
    14411457
     
    14591475 *  ENOMEM      : Not enough memory to complete the operation
    14601476 */
    1461 int fd_sess_state_store_int ( struct session_handler * handler, struct session * session, session_state ** state );
     1477int fd_sess_state_store_internal ( struct session_handler * handler, struct session * session, session_state ** state );
    14621478#define fd_sess_state_store( _handler, _session, _state ) \
    1463         fd_sess_state_store_int( (_handler), (_session), (void *)(_state) )
     1479        fd_sess_state_store_internal( (_handler), (_session), (void *)(_state) )
    14641480
    14651481/*
     
    14811497 *  EINVAL      : A parameter is invalid.
    14821498 */
    1483 int fd_sess_state_retrieve_int ( struct session_handler * handler, struct session * session, session_state ** state );
     1499int fd_sess_state_retrieve_internal ( struct session_handler * handler, struct session * session, session_state ** state );
    14841500#define fd_sess_state_retrieve( _handler, _session, _state ) \
    1485         fd_sess_state_retrieve_int( (_handler), (_session), (void *)(_state) )
     1501        fd_sess_state_retrieve_internal( (_handler), (_session), (void *)(_state) )
    14861502
    14871503
     
    14951511/*============================================================*/
    14961512
    1497 /* The dispatch process consists in passing a message to some handlers
    1498  (typically provided by extensions) based on its content (app id, cmd code...) */
    1499 
    1500 /* The dispatch module has two main roles:
     1513/* Dispatch module (passing incoming messages to extensions registered callbacks)
     1514 * is split between the library and the daemon.
     1515 *
     1516 * The library provides the support for associating dispatch callbacks with
     1517 * dictionary objects.
     1518 *
     1519 * The daemon is responsible for calling the callbacks for a message when appropriate.
     1520 *
     1521 *
     1522 * The dispatch module has two main roles:
    15011523 *  - help determine if a message can be handled locally (during the routing step)
     1524 *        This decision involves only the application-id of the message.
    15021525 *  - pass the message to the callback(s) that will handle it (during the dispatch step)
    15031526 *
    1504  * These are the possibilities for registering a callback:
     1527 * These are the possibilities for registering a so-called dispatch callback:
    15051528 *
    15061529 * -> For All messages.
    15071530 *  This callback is called for all messages that are handled locally. This should be used only
    1508  *  internally by the daemon, or for debug purpose.
    1509  *
    1510  * -> by AVP value (constants).
    1511  *  This callback will be called when a message is received and contains a certain AVP with a specified value.
     1531 *  for debug purpose.
     1532 *
     1533 * -> by AVP value (constants only).
     1534 *  This callback will be called when a message is received and contains an AVP with a specified enumerated value.
    15121535 *
    15131536 * -> by AVP.
     
    15151538 *
    15161539 * -> by command-code.
    1517  *  This callback will be called when the message is a specific command.
     1540 *  This callback will be called when the message is a specific command (and 'R' flag).
    15181541 *
    15191542 * -> by application.
     
    15211544 *
    15221545 * ( by vendor: would this be useful? it may be added later)
    1523  *
    1524  * Note that several criteria may be selected at the same time, for example command-code AND application id.
    1525  *
    1526  * When a callback is called, it receives the message as parameter, and eventually a pointer to
    1527  * the AVP in the message when this is appropriate.
    1528  *
    1529  * The callback must process the message, and eventually create an answer to it. See the definition
    1530  * bellow for more information.
    1531  *
    1532  * If no callback has handled the message, a default handler will be called with the effect of
    1533  * requeuing the message for forwarding on the network to another peer (for requests, if possible), or
    1534  * discarding the message (for answers).
    1535  */
    1536 
    1537 
     1546 */
     1547enum disp_how {
     1548        DISP_HOW_ANY = 1,               /* Any message. This should be only used for debug. */
     1549        DISP_HOW_APPID,                 /* Any message with the specified application-id */
     1550        DISP_HOW_CC,                    /* Messages of the specified command-code (request or answer). App id may be specified. */
     1551        DISP_HOW_AVP,                   /* Messages containing a specific AVP. Command-code and App id may be specified. */
     1552        DISP_HOW_AVP_ENUMVAL            /* Messages containing a specific AVP with a specific enumerated value. Command-code and App id may be specified. */
     1553};
     1554/*
     1555 * Several criteria may be selected at the same time, for example command-code AND application id.
     1556 *
     1557 * If several callbacks are registered for the same object, their order is unspecified.
     1558 * The order in which the callbacks are called is:
     1559 *  DISP_HOW_ANY
     1560 *  DISP_HOW_AVP_ENUMVAL & DISP_HOW_AVP
     1561 *  DISP_HOW_CC
     1562 *  DISP_HOW_APPID
     1563 */
     1564
     1565/* When a callback is registered, a "when" argument is passed in addition to the disp_how value,
     1566 * to specify which values the criteria must match. */
     1567struct disp_when {
     1568        struct dict_object *    app_id;
     1569        struct dict_object *    command;
     1570        struct dict_object *    avp;
     1571        struct dict_object *    value;
     1572};
     1573
     1574/* Here is the details on this "when" argument, depending on the disp_how value.
     1575 *
     1576 * DISP_HOW_ANY.
     1577 *  In this case, "when" must be NULL.
     1578 *
     1579 * DISP_HOW_APPID.
     1580 *  Only the "app_id" field must be set, other fields are ignored. It points to a dictionary object of type DICT_APPLICATION.
     1581 *
     1582 * DISP_HOW_CC.
     1583 *  The "command" field must be defined and point to a dictionary object of type DICT_COMMAND.
     1584 *  The "app_id" may be also set. In the case it is set, it restricts the callback to be called only with this command-code and app id.
     1585 *  The other fields are ignored.
     1586 *
     1587 * DISP_HOW_AVP.
     1588 *  The "avp" field of the structure must be set and point to a dictionary object of type DICT_AVP.
     1589 *  The "app_id" field may be set to restrict the messages matching to a specific app id.
     1590 *  The "command" field may also be set to a valid DICT_COMMAND object.
     1591 *  The content of the "value" field is ignored.
     1592 *
     1593 * DISP_HOW_AVP_ENUMVAL.
     1594 *  All fields have the same constraints and meaning as in DISP_REG_AVP. In addition, the "value" field must be set
     1595 *  and points to a valid DICT_ENUMVAL object.
     1596 *
     1597 * Here is a sumary of the fields: ( M : must be set; m : may be set; 0 : ignored )
     1598 *  field:     app_id    command     avp    value
     1599 * APPID :       M          0         0       0
     1600 * CC    :       m          M         0       0
     1601 * AVP   :       m          m         M       0
     1602 * ENUMVA:       m          m         M       M
     1603 */
     1604
     1605/* The callbacks that are registered have the following prototype:
     1606 *
     1607 *  int dispatch_callback( struct msg ** msg, struct avp * avp, struct session * session, int * is_answer );
     1608 *
     1609 * FUNCTION:    dispatch_callback
     1610 *
     1611 * PARAMETERS:
     1612 *  msg         : the received message on function entry. may be updated to answer on return (see description)
     1613 *  avp         : for callbacks registered with DISP_HOW_AVP or DISP_HOW_AVP_ENUMVAL, direct link to the triggering AVP.
     1614 *  session     : if the message contains a Session-Id AVP, the corresponding session object.
     1615 *
     1616 * DESCRIPTION:
     1617 *   Create a new AVP instance.
     1618 *
     1619 * RETURN VALUE:
     1620 *  0           : The AVP is created.
     1621 *  EINVAL      : A parameter is invalid.
     1622 *  (other standard errors may be returned, too, with their standard meaning. Example:
     1623 *    ENOMEM    : Memory allocation for the new avp failed.)
     1624 */
    15381625
    15391626
  • libfreeDiameter/sessions.c

    r5 r6  
    242242
    243243/* Create a new handler */
    244 int fd_sess_handler_create_int ( struct session_handler ** handler, void (*cleanup)(char * sid, session_state * state) )
     244int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(char * sid, session_state * state) )
    245245{
    246246        struct session_handler *new;
     
    565565}
    566566
     567/* Destroy a session if it is not used */
     568int fd_sess_reclaim ( struct session ** session )
     569{
     570        struct session * sess;
     571       
     572        TRACE_ENTRY("%p", session);
     573        CHECK_PARAMS( session && VALIDATE_SI(*session) );
     574       
     575        sess = *session;
     576        *session = NULL;
     577       
     578        CHECK_FCT( pthread_mutex_lock( H_LOCK(sess->hash) ) );
     579        CHECK_FCT( pthread_mutex_lock( &exp_lock ) );
     580        if (FD_IS_LIST_EMPTY(&sess->states)) {
     581                fd_list_unlink( &sess->chain_h );
     582                fd_list_unlink( &sess->expire );
     583                sess->eyec = 0xdead;
     584                free(sess->sid);
     585                free(sess);
     586        }
     587        CHECK_FCT( pthread_mutex_unlock( &exp_lock ) );
     588        CHECK_FCT( pthread_mutex_unlock( H_LOCK(sess->hash) ) );
     589       
     590        return 0;
     591}
     592
    567593
    568594
    569595/* Save a state information with a session */
    570 int fd_sess_state_store_int ( struct session_handler * handler, struct session * session, session_state ** state )
     596int fd_sess_state_store_internal ( struct session_handler * handler, struct session * session, session_state ** state )
    571597{
    572598        struct state *new;
     
    617643
    618644/* Get the data back */
    619 int fd_sess_state_retrieve_int ( struct session_handler * handler, struct session * session, session_state ** state )
     645int fd_sess_state_retrieve_internal ( struct session_handler * handler, struct session * session, session_state ** state )
    620646{
    621647        struct fd_list * li;
Note: See TracChangeset for help on using the changeset viewer.