Branch: Tag:

2015-04-22

2015-04-22 15:04:58 by Martin Nilsson <nilsson@opera.com>

Keep track of Session activity, so they can be removed when inactive, not just old.

952:   //! Non-zero to enable caching of sessions   int use_cache = 1;    - //! Sessions are removed from the cache when they are older than this - //! limit (in seconds). Sessions are also removed from the cache if a - //! connection using the session dies unexpectedly. + //! Sessions are removed from the cache when they have been inactive + //! more than this number of seconds. Sessions are also removed from + //! the cache if a connection using the session dies unexpectedly.   int session_lifetime = 600;      //! Maximum number of sessions to keep in the cache.   int max_sessions = 300;    - /* Queue of pairs (time, id), in cronological order */ - ADT.Queue active_sessions = ADT.Queue(); -  +    mapping(string:Session) session_cache = ([]);      // Remove sessions older than @[session_lifetime] from the session cache.   void forget_old_sessions()   {    int t = time() - session_lifetime; -  array pair; -  while ( (pair = [array]active_sessions->peek()) -  && (pair[0] < t)) { +  foreach(session_cache; string id; Session session) +  { +  if(session->last_activity < t) +  {    SSL3_DEBUG_MSG("SSL.Context->forget_old_sessions: "    "garbing session %O due to session_lifetime limit\n", -  pair[1]); -  m_delete (session_cache, [string]([array]active_sessions->get())[1]); +  id); +  m_delete (session_cache, id);    }    } -  + }      //! Lookup a session identifier in the cache. Returns the   //! corresponding session, or zero if it is not found or caching is
1010:   {    if (use_cache && s->identity)    { -  while (sizeof (active_sessions) >= max_sessions) { -  array pair = [array] active_sessions->get(); +  forget_old_sessions(); +  int to_delete = sizeof(session_cache)-max_sessions; +  foreach(session_cache; string id;) +  { +  // Randomly delete sessions to keep within the limit. +  if( to_delete-- < 0 ) break;    SSL3_DEBUG_MSG("SSL.Context->record_session: " -  "garbing session %O due to max_sessions limit\n", pair[1]); -  m_delete (session_cache, [string]pair[1]); +  "garbing session %O due to max_sessions limit\n", id); +  m_delete (session_cache, id);    } -  forget_old_sessions(); +     SSL3_DEBUG_MSG("SSL.Context->record_session: caching session %O\n",    s->identity); -  active_sessions->put( ({ time(1), s->identity }) ); +     session_cache[s->identity] = s;    }   }
1043:    // so we can't scratch the master secret.    s->master_secret = 0;    } -  /* There's no need to remove the id from the active_sessions queue */ +    }