Navigation


Changeset 924:877592751fee in freeDiameter


Ignore:
Timestamp:
Feb 15, 2013, 1:52:57 AM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Children:
925:e5a09fab5ef3, 950:51c15f98a965
Phase:
public
Message:

Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much

Files:
14 edited

Legend:

Unmodified
Added
Removed
  • extensions/app_radgw/rgwx_auth.c

    r740 r924  
    458458                if (si_len) {
    459459                        /* We already have the Session-Id, just use it */
    460                         CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
     460                        CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, session, NULL) );
    461461                } else {
    462462                        /* Create a new Session-Id string */
     
    496496                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    497497                CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
     498                CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
    498499        }
    499500       
  • extensions/app_radgw/rgwx_sip.c

    r816 r924  
    480480        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    481481        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
     482        CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
    482483       
    483484        /*
  • extensions/app_sip/registrationtermination.c

    r706 r924  
    148148        {
    149149                #define APP_SIP_SID_OPT  "app_sip"
    150                 CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ));
    151                 os0_t sid;
    152                 size_t sidlen;
    153                 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
    154                 CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
    155                 value.os.data = sid;
    156                 value.os.len  = sidlen;
    157                 CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
    158                 CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
     150                CHECK_FCT( fd_msg_new_session( message, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ) );
    159151        }
    160152       
  • extensions/test_app/ta_bench.c

    r879 r924  
    122122        union avp_value val;
    123123        struct ta_mess_info * mi = NULL;
    124         struct session *sess = NULL;
    125124       
    126125        TRACE_DEBUG(FULL, "Creating a new message for sending.");
     
    131130        /* Create a new session */
    132131        #define TEST_APP_SID_OPT  "app_testb"
    133         CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
     132        CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
    134133       
    135134        /* Create the random value to store with the session */
     
    143142       
    144143        /* Now set all AVPs values */
    145        
    146         /* Session-Id */
    147         {
    148                 os0_t sid;
    149                 size_t sidlen;
    150                 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out );
    151                 CHECK_FCT_DO( fd_msg_avp_new ( ta_sess_id, 0, &avp ), goto out );
    152                 val.os.data = sid;
    153                 val.os.len  = sidlen;
    154                 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
    155                 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out );
    156                
    157         }
    158144       
    159145        /* Set the Destination-Realm AVP */
  • extensions/test_app/ta_cli.c

    r740 r924  
    151151        /* Create a new session */
    152152        #define TEST_APP_SID_OPT  "app_test"
    153         CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
     153        CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
     154        CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), goto out );
    154155       
    155156        /* Create the random value to store with the session */
     
    164165        /* Now set all AVPs values */
    165166       
    166         /* Session-Id */
    167         {
    168                 os0_t sid;
    169                 size_t sidlen;
    170                 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out );
    171                 CHECK_FCT_DO( fd_msg_avp_new ( ta_sess_id, 0, &avp ), goto out );
    172                 val.os.data = sid;
    173                 val.os.len  = sidlen;
    174                 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
    175                 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out );
    176                
    177         }
    178        
    179167        /* Set the Destination-Realm AVP */
    180168        {
  • extensions/test_sip/locationinfo.c

    r706 r924  
    4242        struct msg * message=NULL;
    4343        struct avp *avp=NULL;
    44         struct session *sess=NULL;
    4544        union avp_value value;
    4645       
     
    6261        // Create a new session
    6362        {
    64                 CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
    65                 os0_t sid;
    66                 size_t sidlen;
    67                 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
    68                 CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
    69                 value.os.data = sid;
    70                 value.os.len  = sidlen;
    71                 CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
    72                 CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
     63                CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
    7364        }
    7465       
  • extensions/test_sip/locationinfosl.c

    r706 r924  
    4242        struct msg * message=NULL;
    4343        struct avp *avp=NULL;
    44         struct session *sess=NULL;
    4544        union avp_value value;
    4645       
     
    6261        // Create a new session
    6362        {
    64                 CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
    65                 os0_t sid;
    66                 size_t sidlen;
    67                 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
    68                 CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
    69                 value.os.data = sid;
    70                 value.os.len  = sidlen;
    71                 CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
    72                 CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
     63                CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
    7364        }
    7465       
  • extensions/test_sip/serverassignment.c

    r706 r924  
    4242        struct msg * message=NULL;
    4343        struct avp *avp=NULL;
    44         struct session *sess=NULL;
    4544        union avp_value value;
    4645       
     
    7170        // Create a new session
    7271        {
    73                 CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
    74                 os0_t sid;
    75                 size_t sidlen;
    76                 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
    77                 CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
    78                 value.os.data = sid;
    79                 value.os.len  = sidlen;
    80                 CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
    81                 CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
     72                CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
    8273        }
    8374       
  • extensions/test_sip/userauthorization.c

    r706 r924  
    4242        struct msg * message=NULL;
    4343        struct avp *avp=NULL;
    44         struct session *sess=NULL;
    4544        union avp_value value;
    4645       
     
    6766        // Create a new session
    6867        {
    69                 CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
    70                 os0_t sid;
    71                 size_t sidlen;
    72                 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
    73                 CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
    74                 value.os.data = sid;
    75                 value.os.len  = sidlen;
    76                 CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
    77                 CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
     68                CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
    7869        }
    7970       
  • include/freeDiameter/libfdproto.h

    r922 r924  
    18161816 *
    18171817 * RETURN VALUE:
    1818  *  0           : The session is created.
    1819  *  EINVAL      : A parameter is invalid.
    1820  *  EALREADY    : A session with the same name already exists (returned in *session)
     1818 *  0           : The session is created, the initial msg refcount is 1.
     1819 *  EINVAL      : A parameter is invalid.
     1820 *  EALREADY    : A session with the same name already exists (returned in *session), the msg refcount is increased.
    18211821 *  ENOMEM      : Not enough memory to complete the operation
    18221822 */
     
    25052505int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * isnew);
    25062506
     2507/* This one is used by the libfdcore, you should use fd_msg_new_session rather than fd_sess_new, when possible */
     2508int fd_msg_sess_set(struct msg * msg, struct session * session);
     2509
     2510
    25072511/***************************************/
    25082512/*   Manage AVP values                 */
  • libfdcore/messages.c

    r912 r924  
    158158        /* Add it to the message */
    159159        CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) );
     160       
     161        /* Save the session associated with the message */
     162        CHECK_FCT( fd_msg_sess_set( msg, sess) );
    160163       
    161164        /* Done! */
  • libfdproto/fdproto-internal.h

    r909 r924  
    7070int fd_sess_reclaim_msg ( struct session ** session );
    7171
     72
    7273/* For dump routines into string buffers */
    7374#include <stdarg.h>
  • libfdproto/messages.c

    r920 r924  
    12161216}
    12171217
     1218/* Associate a session with a message, use only when the session was just created */
     1219int fd_msg_sess_set(struct msg * msg, struct session * session)
     1220{
     1221        TRACE_ENTRY("%p %p", msg, session);
     1222       
     1223        /* Check we received valid parameters */
     1224        CHECK_PARAMS( CHECK_MSG(msg) );
     1225        CHECK_PARAMS( session );
     1226        CHECK_PARAMS( msg->msg_sess == NULL );
     1227       
     1228        msg->msg_sess = session;
     1229        return 0;
     1230}
     1231
    12181232
    12191233/* Retrieve the session of the message */
  • libfdproto/sessions.c

    r788 r924  
    360360
    361361
    362 /* Create a new session object with the default timeout value, and link it */
     362/* Create a new session object with the default timeout value, and link it. The refcount is increased by 1, whether the session existed or not */
    363363int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen )
    364364{
     
    461461       
    462462                fd_list_insert_before(li, &sess->chain_h); /* hash table */
     463                sess->msg_cnt++;
    463464        } else {
    464465                free(sid);
     466               
     467                CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     468                (*session)->msg_cnt++;
     469                CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
     470               
    465471                /* it was found: was it previously destroyed? */
    466472                if ((*session)->is_destroyed == 0) {
     
    469475                } else {
    470476                        /* the session was marked destroyed, let's re-activate it. */
    471                         TODO("Re-creating a deleted session. Should investigate if this can lead to an issue... (need more feedback)");
    472477                        sess = *session;
     478                        sess->is_destroyed = 0;
    473479                       
    474480                        /* update the expiry time */
     
    501507
    502508out:
    503         ;       
     509        ;
    504510        pthread_cleanup_pop(0);
    505511        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     
    512518}
    513519
    514 /* Find or create a session */
    515 int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
     520/* Find or create a session -- the msg refcount is increased */
     521int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
    516522{
    517523        int ret;
     
    802808
    803809/* For the messages module */
    804 int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
     810int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
    805811{
    806812        TRACE_ENTRY("%p %zd %p %p", sid, len, session, new);
     
    808814       
    809815        /* Get the session object */
    810         CHECK_FCT( fd_sess_fromsid ( sid, len, session, new) );
    811        
    812         /* Increase count */
    813         CHECK_FCT( fd_sess_ref_msg ( *session ) );
    814        
     816        CHECK_FCT( fd_sess_fromsid_msg ( sid, len, session, new) );
     817       
     818        /* Decrease the refcount */
     819        CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     820        (*session)->msg_cnt--; /* was increased in fd_sess_new */
     821        CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
     822               
    815823        /* Done */
    816824        return 0;
     
    833841{
    834842        int reclaim;
     843        uint32_t hash;
    835844       
    836845        TRACE_ENTRY("%p", session);
    837846        CHECK_PARAMS( session && VALIDATE_SI(*session) );
    838847       
     848        /* Lock the hash line to avoid possibility that session is freed while we are reclaiming */
     849        hash = (*session)->hash;
     850        CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash)) );
     851        pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) );
     852
    839853        /* Update the msg refcount */
    840854        CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     
    843857        CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
    844858       
     859        /* Ok, now unlock the hash line */
     860        pthread_cleanup_pop( 0 );
     861        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     862       
     863        /* and reclaim if no message references the session anymore */
    845864        if (reclaim == 1) {
    846865                CHECK_FCT(fd_sess_reclaim ( session ));
Note: See TracChangeset for help on using the changeset viewer.