Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for libfdproto/sessions.c


Ignore:
Timestamp:
Feb 9, 2011, 3:26:58 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/sessions.c

    r691 r706  
    6969        int               eyec; /* An eye catcher also used to ensure the object is valid, must be SH_EYEC */
    7070        int               id;   /* A unique integer to identify this handler */
    71         void            (*cleanup)(session_state *, char *, void *); /* The cleanup function to be called for cleaning a state */
     71        void            (*cleanup)(session_state *, os0_t, void *); /* The cleanup function to be called for cleaning a state */
    7272        void             *opaque; /* a value that is passed as is to the cleanup callback */
    7373};
     
    8484        union {
    8585                struct session_handler  *hdl;   /* The handler for which this state was registered */
    86                 char                    *sid;   /* For deleted state, the sid of the session it belong to */
     86                os0_t                    sid;   /* For deleted state, the sid of the session it belong to */
    8787        };
    8888};
     
    9292        int             eyec;   /* Eyecatcher, SI_EYEC */
    9393       
    94         char *          sid;    /* The \0-terminated Session-Id */
     94        os0_t           sid;    /* The \0-terminated Session-Id */
     95        size_t          sidlen; /* cached length of sid */
    9596        uint32_t        hash;   /* computed hash of sid */
    9697        struct fd_list  chain_h;/* chaining in the hash table of sessions. */
     
    102103        struct fd_list  states; /* Sentinel for the list of states of this session. */
    103104        int             msg_cnt;/* Reference counter for the messages pointing to this session */
     105        int             is_destroyed; /* boolean telling if fd_sess_detroy has been called on this */
    104106};
    105107
    106108/* Sessions hash table, to allow fast sid to session retrieval */
    107109static struct {
    108         struct fd_list  sentinel;       /* sentinel element for this sublist */
     110        struct fd_list  sentinel;       /* sentinel element for this sublist. The sublist is ordered by hash value, then fd_os_cmp(sid). */
    109111        pthread_mutex_t lock;           /* the mutex for this sublist -- we might probably change it to rwlock for a little optimization */
    110112} sess_hash [ 1 << SESS_HASH_SIZE ] ;
     
    132134/********************************************************************************************************/
    133135
    134 /* Initialize a session object. It is not linked now. sid must be already malloc'ed. */
    135 static struct session * new_session(char * sid, size_t sidlen)
     136/* Initialize a session object. It is not linked now. sid must be already malloc'ed. The hash has already been computed. */
     137static struct session * new_session(os0_t sid, size_t sidlen, uint32_t hash)
    136138{
    137139        struct session * sess;
    138140       
    139         TRACE_ENTRY("%p %d", sid, sidlen);
     141        TRACE_ENTRY("%p %zd", sid, sidlen);
    140142        CHECK_PARAMS_DO( sid && sidlen, return NULL );
    141143       
     
    146148       
    147149        sess->sid  = sid;
    148         sess->hash = fd_hash(sid, sidlen);
     150        sess->sidlen = sidlen;
     151        sess->hash = hash;
    149152        fd_list_init(&sess->chain_h, sess);
    150153       
     
    157160       
    158161        return sess;
     162}
     163
     164/* destroy the session object. It should really be already unlinked... */
     165static void del_session(struct session * s)
     166{
     167        ASSERT(FD_IS_LIST_EMPTY(&s->states));
     168        free(s->sid);
     169        fd_list_unlink(&s->chain_h);
     170        fd_list_unlink(&s->expire);
     171        CHECK_POSIX_DO( pthread_mutex_destroy(&s->stlock), /* continue */ );
     172        free(s);
    159173}
    160174       
     
    250264        TRACE_ENTRY("");
    251265        CHECK_FCT_DO( fd_thr_term(&exp_thr), /* continue */ );
     266       
     267        /* Destroy all sessions in the hash table, and the hash table itself? -- How to do it without a race condition ? */
     268       
    252269        return;
    253270}
    254271
    255272/* Create a new handler */
    256 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, char * sid, void * opaque), void * opaque )
     273int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state *, os0_t, void *), void * opaque )
    257274{
    258275        struct session_handler *new;
     
    299316                CHECK_POSIX(  pthread_mutex_lock(&sess_hash[i].lock)  );
    300317               
    301                 for (li_si = sess_hash[i].sentinel.next; li_si != &sess_hash[i].sentinel; li_si = li_si->next) {
     318                for (li_si = sess_hash[i].sentinel.next; li_si != &sess_hash[i].sentinel; li_si = li_si->next) { /* for each session in the hash line */
    302319                        struct fd_list * li_st;
    303320                        struct session * sess = (struct session *)(li_si->o);
    304321                        CHECK_POSIX(  pthread_mutex_lock(&sess->stlock)  );
    305                         for (li_st = sess->states.next; li_st != &sess->states; li_st = li_st->next) {
     322                        for (li_st = sess->states.next; li_st != &sess->states; li_st = li_st->next) { /* for each state in this session */
    306323                                struct state * st = (struct state *)(li_st->o);
    307324                                /* The list is ordered */
     
    311328                                        /* This state belongs to the handler we are deleting, move the item to the deleted_states list */
    312329                                        fd_list_unlink(&st->chain);
    313                                         CHECK_MALLOC( st->sid = strdup(sess->sid) );
     330                                        st->sid = sess->sid;
    314331                                        fd_list_insert_before(&deleted_states, &st->chain);
    315332                                }
     
    326343                TRACE_DEBUG(FULL, "Calling cleanup handler for session '%s' and data %p", st->sid, st->state);
    327344                (*del->cleanup)(st->state, st->sid, del->opaque);
    328                 free(st->sid);
    329345                fd_list_unlink(&st->chain);
    330346                free(st);
     
    343359
    344360/* Create a new session object with the default timeout value, and link it */
    345 int fd_sess_new ( struct session ** session, char * diamId, char * opt, size_t optlen )
    346 {
    347         char * sid = NULL;
     361int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen )
     362{
     363        os0_t sid = NULL;
    348364        size_t sidlen;
     365        uint32_t hash;
    349366        struct session * sess;
    350367        struct fd_list * li;
    351368        int found = 0;
    352        
    353         TRACE_ENTRY("%p %p %p %d", session, diamId, opt, optlen);
    354         CHECK_PARAMS( session && (diamId || opt) );
    355        
     369        int ret = 0;
     370       
     371        TRACE_ENTRY("%p %p %zd %p %zd", session, diamid, diamidlen, opt, optlen);
     372        CHECK_PARAMS( session && (diamid || opt) );
     373
     374        if (diamid) {   
     375                if (!diamidlen) {
     376                        diamidlen = strlen(diamid);
     377                }
     378                /* We check if the string is a valid DiameterIdentity */
     379                CHECK_PARAMS( fd_os_is_valid_DiameterIdentity((uint8_t *)diamid, diamidlen) );
     380        } else {
     381                diamidlen = 0;
     382        }
     383        if (opt) {     
     384                if (!optlen) {
     385                        optlen = strlen((char *)opt);
     386                } else {
     387                        CHECK_PARAMS( fd_os_is_valid_os0(opt, optlen) );
     388                }
     389        } else {
     390                optlen = 0;
     391        }
     392               
    356393        /* Ok, first create the identifier for the string */
    357         if (diamId == NULL) {
     394        if (diamid == NULL) {
    358395                /* opt is the full string */
    359                 if (optlen) {
    360                         CHECK_MALLOC( sid = malloc(optlen + 1) );
    361                         strncpy(sid, opt, optlen);
    362                         sid[optlen] = '\0';
    363                         sidlen = optlen;
    364                 } else {
    365                         CHECK_MALLOC( sid = strdup(opt) );
    366                         sidlen = strlen(sid);
    367                 }
     396                CHECK_MALLOC( sid = os0dup(opt, optlen) );
     397                sidlen = optlen;
    368398        } else {
    369399                uint32_t sid_h_cpy;
    370400                uint32_t sid_l_cpy;
    371401                /* "<diamId>;<high32>;<low32>[;opt]" */
    372                 sidlen = strlen(diamId);
     402                sidlen = diamidlen;
    373403                sidlen += 22; /* max size of ';<high32>;<low32>' */
    374404                if (opt)
    375                         sidlen += 1 + (optlen ?: strlen(opt)) ;
     405                        sidlen += 1 + optlen; /* ';opt' */
    376406                sidlen++; /* space for the final \0 also */
    377407                CHECK_MALLOC( sid = malloc(sidlen) );
     
    385415               
    386416                if (opt) {
    387                         if (optlen)
    388                                 sidlen = snprintf(sid, sidlen, "%s;%u;%u;%.*s", diamId, sid_h_cpy, sid_l_cpy, (int)optlen, opt);
    389                         else
    390                                 sidlen = snprintf(sid, sidlen, "%s;%u;%u;%s", diamId, sid_h_cpy, sid_l_cpy, opt);
     417                        sidlen = snprintf((char*)sid, sidlen, "%.*s;%u;%u;%.*s", (int)diamidlen, diamid, sid_h_cpy, sid_l_cpy, (int)optlen, opt);
    391418                } else {
    392                         sidlen = snprintf(sid, sidlen, "%s;%u;%u", diamId, sid_h_cpy, sid_l_cpy);
     419                        sidlen = snprintf((char*)sid, sidlen, "%.*s;%u;%u", (int)diamidlen, diamid, sid_h_cpy, sid_l_cpy);
    393420                }
    394421        }
    395422       
    396         /* Initialize the session object now, to spend less time inside locked section later.
    397          * Cons: we malloc then free if there is already a session with same SID; we could malloc later to avoid this. */
    398         CHECK_MALLOC( sess = new_session(sid, sidlen) );
     423        hash = fd_os_hash(sid, sidlen);
    399424       
    400425        /* Now find the place to add this object in the hash table. */
    401         CHECK_POSIX( pthread_mutex_lock( H_LOCK(sess->hash) ) );
    402         pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(sess->hash) );
    403        
    404         for (li = H_LIST(sess->hash)->next; li != H_LIST(sess->hash); li = li->next) {
     426        CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) );
     427        pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) );
     428       
     429        for (li = H_LIST(hash)->next; li != H_LIST(hash); li = li->next) {
    405430                int cmp;
    406431                struct session * s = (struct session *)(li->o);
    407432               
    408433                /* The list is ordered by hash and sid (in case of collisions) */
    409                 if (s->hash < sess->hash)
     434                if (s->hash < hash)
    410435                        continue;
    411                 if (s->hash > sess->hash)
     436                if (s->hash > hash)
    412437                        break;
    413438               
    414                 cmp = strcasecmp(s->sid, sess->sid);
     439                cmp = fd_os_cmp(s->sid, s->sidlen, sid, sidlen);
    415440                if (cmp < 0)
    416441                        continue;
     
    424449        }
    425450       
    426         /* If the session did not exist, we can link it in global tables */
     451        /* If the session did not exist, we can create it & link it in global tables */
    427452        if (!found) {
     453                CHECK_MALLOC_DO(sess = new_session(sid, sidlen, hash),
     454                        {
     455                                ret = ENOMEM;
     456                                goto out;
     457                        } );
     458       
    428459                fd_list_insert_before(li, &sess->chain_h); /* hash table */
    429                
    430                 /* We must also insert in the expiry list */
    431                 CHECK_POSIX( pthread_mutex_lock( &exp_lock ) );
    432                 pthread_cleanup_push( fd_cleanup_mutex, &exp_lock );
    433                
    434                 /* Find the position in that list. We take it in reverse order */
    435                 for (li = exp_sentinel.prev; li != &exp_sentinel; li = li->prev) {
    436                         struct session * s = (struct session *)(li->o);
    437                         if (TS_IS_INFERIOR( &s->timeout, &sess->timeout ) )
    438                                 break;
     460        } else {
     461                /* it was found: was it previously destroyed? */
     462                if ((*session)->is_destroyed == 0) {
     463                        ret = EALREADY;
     464                        goto out;
     465                } else {
     466                        /* the session was marked destroyed, let's re-activate it. */
     467                        TODO("Re-creating a deleted session. Should investigate if this can lead to an issue... (need more feedback)");
     468                        sess = *session;
     469                       
     470                        /* update the expiry time */
     471                        CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &sess->timeout), { ASSERT(0); } );
     472                        sess->timeout.tv_sec += SESS_DEFAULT_LIFETIME;
    439473                }
    440                 fd_list_insert_after( li, &sess->expire );
    441 
    442                 /* We added a new expiring element, we must signal */
    443                 if (li == &exp_sentinel) {
    444                         CHECK_POSIX_DO( pthread_cond_signal(&exp_cond), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handlers, but this should not happen -- and we'd have a serious problem otherwise */
    445                 }
    446                
    447                 #if 0
    448                 if (TRACE_BOOL(ANNOYING)) {     
    449                         TRACE_DEBUG(FULL, "-- Updated session expiry list --");
    450                         for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) {
    451                                 struct session * s = (struct session *)(li->o);
    452                                 fd_sess_dump(FULL, s);
    453                         }
    454                         TRACE_DEBUG(FULL, "-- end of expiry list --");
    455                 }
    456                 #endif
    457                
    458                 /* We're done */
    459                 pthread_cleanup_pop(0);
    460                 CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handler, but this should not happen -- and we'd have a serious problem otherwise */
    461         }
    462        
     474        }
     475               
     476        /* We must insert in the expiry list */
     477        CHECK_POSIX( pthread_mutex_lock( &exp_lock ) );
     478        pthread_cleanup_push( fd_cleanup_mutex, &exp_lock );
     479
     480        /* Find the position in that list. We take it in reverse order */
     481        for (li = exp_sentinel.prev; li != &exp_sentinel; li = li->prev) {
     482                struct session * s = (struct session *)(li->o);
     483                if (TS_IS_INFERIOR( &s->timeout, &sess->timeout ) )
     484                        break;
     485        }
     486        fd_list_insert_after( li, &sess->expire );
     487
     488        /* We added a new expiring element, we must signal */
     489        if (li == &exp_sentinel) {
     490                CHECK_POSIX_DO( pthread_cond_signal(&exp_cond), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handlers, but this should not happen -- and we'd have a serious problem otherwise */
     491        }
     492
     493        /* We're done with the locked part */
    463494        pthread_cleanup_pop(0);
    464         CHECK_POSIX( pthread_mutex_unlock( H_LOCK(sess->hash) ) );
    465        
    466         /* If a session already existed, we must destroy the new element */
    467         if (found) {
    468                 CHECK_FCT( fd_sess_destroy( &sess ) ); /* we could avoid locking this time for optimization */
    469                 return EALREADY;
    470         }
     495        CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); } ); /* if it fails, we might not pop the cleanup handler, but this should not happen -- and we'd have a serious problem otherwise */
     496
     497out:
     498        ;       
     499        pthread_cleanup_pop(0);
     500        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     501       
     502        if (ret) /* in case of error */
     503                return ret;
    471504       
    472505        *session = sess;
     
    475508
    476509/* Find or create a session */
    477 int fd_sess_fromsid ( char * sid, size_t len, struct session ** session, int * new)
     510int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
    478511{
    479512        int ret;
     
    482515        CHECK_PARAMS( sid && session );
    483516       
     517        if (!fd_os_is_valid_os0(sid,len)) {
     518                TRACE_DEBUG(INFO, "Warning: a Session-Id value contains \\0 chars... (len:%zd, begin:'%.*s')\n => Debug messages may be truncated.", len, len, sid);
     519        }
     520       
    484521        /* All the work is done in sess_new */
    485         ret = fd_sess_new ( session, NULL, sid, len );
     522        ret = fd_sess_new ( session, NULL, 0, sid, len );
    486523        switch (ret) {
    487524                case 0:
     
    500537
    501538/* Get the sid of a session */
    502 int fd_sess_getsid ( struct session * session, char ** sid )
     539int fd_sess_getsid ( struct session * session, os0_t * sid, size_t * sidlen )
    503540{
    504541        TRACE_ENTRY("%p %p", session, sid);
     
    507544       
    508545        *sid = session->sid;
     546        if (sidlen)
     547                *sidlen = session->sidlen;
    509548       
    510549        return 0;
     
    543582        }
    544583
    545         #if 0
    546         if (TRACE_BOOL(ANNOYING)) {     
    547                 TRACE_DEBUG(FULL, "-- Updated session expiry list --");
    548                 for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) {
    549                         struct session * s = (struct session *)(li->o);
    550                         fd_sess_dump(FULL, s);
    551                 }
    552                 TRACE_DEBUG(FULL, "-- end of expiry list --");
    553         }
    554         #endif
    555 
    556584        /* We're done */
    557585        pthread_cleanup_pop(0);
     
    561589}
    562590
    563 /* Destroy a session immediatly */
     591/* Destroy the states associated to a session, and mark it destroyed. */
    564592int fd_sess_destroy ( struct session ** session )
    565593{
    566594        struct session * sess;
     595        int destroy_now;
     596        os0_t sid;
     597        int ret = 0;
     598       
     599        /* place to save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */
     600        struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states );
    567601       
    568602        TRACE_ENTRY("%p", session);
     
    572606        *session = NULL;
    573607       
    574         /* Unlink and invalidate */
     608        /* Lock the hash line */
    575609        CHECK_POSIX( pthread_mutex_lock( H_LOCK(sess->hash) ) );
    576610        pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(sess->hash) );
     611       
     612        /* Unlink from the expiry list */
    577613        CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
    578         fd_list_unlink( &sess->chain_h );
    579614        fd_list_unlink( &sess->expire ); /* no need to signal the condition here */
    580         sess->eyec = 0xdead;
    581615        CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
    582         pthread_cleanup_pop(0);
    583         CHECK_POSIX( pthread_mutex_unlock( H_LOCK(sess->hash) ) );
    584        
    585         /* Now destroy all states associated -- we don't take the lock since nobody can access this session anymore (in theory) */
     616       
     617        /* Now move all states associated to this session into deleted_states */
     618        CHECK_POSIX_DO( pthread_mutex_lock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
    586619        while (!FD_IS_LIST_EMPTY(&sess->states)) {
    587620                struct state * st = (struct state *)(sess->states.next->o);
    588621                fd_list_unlink(&st->chain);
    589                 TRACE_DEBUG(FULL, "Calling handler %p cleanup for state registered with session '%s'", st->hdl, sess->sid);
    590                 (*st->hdl->cleanup)(st->state, sess->sid, st->hdl->opaque);
     622                fd_list_insert_before(&deleted_states, &st->chain);
     623        }
     624        CHECK_POSIX_DO( pthread_mutex_unlock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } );
     625       
     626        /* Mark the session as destroyed */
     627        destroy_now = (sess->msg_cnt == 0);
     628        if (destroy_now) {
     629                fd_list_unlink( &sess->chain_h );
     630                sid = sess->sid;
     631        } else {
     632                sess->is_destroyed = 1;
     633                CHECK_MALLOC_DO( sid = os0dup(sess->sid, sess->sidlen), ret = ENOMEM );
     634        }
     635        pthread_cleanup_pop(0);
     636        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(sess->hash) ) );
     637       
     638        if (ret)
     639                return ret;
     640       
     641        /* Now, really delete the states */
     642        while (!FD_IS_LIST_EMPTY(&deleted_states)) {
     643                struct state * st = (struct state *)(deleted_states.next->o);
     644                fd_list_unlink(&st->chain);
     645                TRACE_DEBUG(FULL, "Calling handler %p cleanup for state %p registered with session '%s'", st->hdl, st, sid);
     646                (*st->hdl->cleanup)(st->state, sid, st->hdl->opaque);
    591647                free(st);
    592648        }
    593649       
    594         /* Finally, destroy the session itself */
    595         free(sess->sid);
    596         free(sess);
     650        /* Finally, destroy the session itself, if it is not referrenced by any message anymore */
     651        if (destroy_now) {
     652                del_session(sess);
     653        } else {
     654                free(sid);
     655        }
    597656       
    598657        return 0;
     
    604663        struct session * sess;
    605664        uint32_t hash;
     665        int destroy_now = 0;
    606666       
    607667        TRACE_ENTRY("%p", session);
     
    612672        *session = NULL;
    613673       
    614         CHECK_POSIX( pthread_mutex_lock( H_LOCK(sess->hash) ) );
    615         pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(sess->hash) );
     674        CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) );
     675        pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) );
     676        CHECK_POSIX_DO( pthread_mutex_lock( &sess->stlock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } );
     677        pthread_cleanup_push( fd_cleanup_mutex, &sess->stlock );
    616678        CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } );
     679       
     680        /* We only do something if the states list is empty */
    617681        if (FD_IS_LIST_EMPTY(&sess->states)) {
    618                 fd_list_unlink( &sess->chain_h );
     682                /* In this case, we do as in destroy */
    619683                fd_list_unlink( &sess->expire );
    620                 sess->eyec = 0xdead;
    621                 free(sess->sid);
    622                 free(sess);
    623         }
     684                destroy_now = (sess->msg_cnt == 0);
     685                if (destroy_now) {
     686                        fd_list_unlink(&sess->chain_h);
     687                } else {
     688                        /* just mark it as destroyed, it will be freed when the last message stops referencing it */
     689                        sess->is_destroyed = 1;
     690                }
     691        }
     692       
    624693        CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } );
    625694        pthread_cleanup_pop(0);
     695        CHECK_POSIX_DO( pthread_mutex_unlock( &sess->stlock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } );
     696        pthread_cleanup_pop(0);
    626697        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     698       
     699        if (destroy_now)
     700                del_session(sess);
    627701       
    628702        return 0;
     
    638712       
    639713        TRACE_ENTRY("%p %p %p", handler, session, state);
    640         CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && state );
     714        CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && (!session->is_destroyed) && state );
    641715       
    642716        /* Lock the session state list */
     
    720794
    721795/* For the messages module */
    722 int fd_sess_fromsid_msg ( unsigned char * sid, size_t len, struct session ** session, int * new)
     796int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
    723797{
    724798        TRACE_ENTRY("%p %zd %p %p", sid, len, session, new);
     
    726800       
    727801        /* Get the session object */
    728         CHECK_FCT( fd_sess_fromsid ( (char *) sid, len, session, new) );
     802        CHECK_FCT( fd_sess_fromsid ( sid, len, session, new) );
    729803       
    730804        /* Increase count */
     
    786860        } else {
    787861               
    788                 fd_log_debug("\t  %*s  sid '%s', hash %x\n", level, "", session->sid, session->hash);
     862                fd_log_debug("\t  %*s  sid '%s'(%zd), hash %x\n", level, "", session->sid, session->sidlen, session->hash);
    789863
    790864                strftime(buf, sizeof(buf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm ));
Note: See TracChangeset for help on using the changeset viewer.