httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject svn commit: r630307 - in /httpd/httpd/trunk/modules/ssl: ssl_private.h ssl_scache.c ssl_scache_dbm.c ssl_scache_dc.c ssl_scache_memcache.c ssl_scache_shmcb.c
Date Fri, 22 Feb 2008 19:58:43 GMT
Author: jorton
Date: Fri Feb 22 11:58:39 2008
New Revision: 630307

URL: http://svn.apache.org/viewvc?rev=630307&view=rev
Log:
Move SSL session data deserialization up out of the session cache
storage providers; includes a significant change to the shmcb storage
structure:

* modules/ssl/ssl_private.h (modssl_sesscache_provider): Change
  retrieve function to take dest/destlen output buffer, to take a
  constant id paramater, and to return a BOOL.

* modules/ssl/ssl_scache.c (ssl_scache_retrieve): Update accordingly,
  perform SSL deserialization here.

* modules/ssl/ssl_scache_dc.c (ssl_scache_dc_retrieve),
  modules/ssl/ssl_scache_dbm.c (ssl_scache_dbm_retrieve),
  modules/ssl/ssl_scache_memcache.c (ssl_scache_mc_retrieve):
  Update accordingly.

* modules/ssl/ssl_scache_shmcb.c: Store the whole ID in the cache
  before the data, so that each index can be compared against the
  requested ID without deserializing the data.  This requires approx
  20% extra storage per session in the common case, though should
  reduce CPU overhead in some retrieval paths.
  (SHMCBIndex): Replace s_id2 field with id_len.
  (shmcb_cyclic_memcmp): New function.
  (ssl_scache_shmcb_init): Change the heuristics to allow for increase
  in per-session storage requirement.
  (ssl_scache_shmcb_retrieve): Drop requirement on ID length.
  (shmcb_subcache_store): Store the ID in the cyclic buffer.
  (shmcb_subcache_retrieve, shmcb_subcache_remove): Compare against
  the stored ID rather than deserializing the data.
  (ssl_scache_shmcb_retrieve, ssl_scache_shmcb_store): Update
  accordingly.

Modified:
    httpd/httpd/trunk/modules/ssl/ssl_private.h
    httpd/httpd/trunk/modules/ssl/ssl_scache.c
    httpd/httpd/trunk/modules/ssl/ssl_scache_dbm.c
    httpd/httpd/trunk/modules/ssl/ssl_scache_dc.c
    httpd/httpd/trunk/modules/ssl/ssl_scache_memcache.c
    httpd/httpd/trunk/modules/ssl/ssl_scache_shmcb.c

Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Fri Feb 22 11:58:39 2008
@@ -371,8 +371,14 @@
     BOOL (*store)(server_rec *s, UCHAR *id, int idlen,
                   time_t expiry, 
                   unsigned char *data, unsigned int datalen);
-    SSL_SESSION *(*retrieve)(server_rec *s, UCHAR *id, int idlen,
-                             apr_pool_t *pool);
+    /* Retrieve cached data with key ID of length IDLEN,
+     * returning TRUE on success or FALSE otherwise.  If
+     * TRUE, the data must be placed in DEST, which has length
+     * on entry of *DESTLEN.  *DESTLEN must be updated to 
+     * equal the length of data written on exit. */
+    BOOL (*retrieve)(server_rec *s, const UCHAR *id, int idlen,
+                     unsigned char *dest, unsigned int *destlen,
+                     apr_pool_t *pool);
     void (*delete)(server_rec *s, UCHAR *id, int idlen, apr_pool_t *pool);
     void (*status)(request_rec *r, int flags, apr_pool_t *pool);
 } modssl_sesscache_provider;

Modified: httpd/httpd/trunk/modules/ssl/ssl_scache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_scache.c?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_scache.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_scache.c Fri Feb 22 11:58:39 2008
@@ -88,8 +88,17 @@
                                  apr_pool_t *p)
 {
     SSLModConfigRec *mc = myModConfig(s);
+    unsigned char dest[SSL_SESSION_MAX_DER];
+    unsigned int destlen = SSL_SESSION_MAX_DER;
+    MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr;
+    
+    if (mc->sesscache->retrieve(s, id, idlen, dest, &destlen, p) == FALSE) {
+        return NULL;
+    }
 
-    return mc->sesscache->retrieve(s, id, idlen, p);
+    ptr = dest;
+
+    return d2i_SSL_SESSION(NULL, &ptr, destlen);
 }
 
 void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen,

Modified: httpd/httpd/trunk/modules/ssl/ssl_scache_dbm.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_scache_dbm.c?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_scache_dbm.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_scache_dbm.c Fri Feb 22 11:58:39 2008
@@ -188,16 +188,15 @@
     return TRUE;
 }
 
-static SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *s, UCHAR *id, int idlen,
-                                            apr_pool_t *p)
+static BOOL ssl_scache_dbm_retrieve(server_rec *s, const UCHAR *id, int idlen,
+                                    unsigned char *dest, unsigned int *destlen,
+                                    apr_pool_t *p)
 {
     SSLModConfigRec *mc = myModConfig(s);
     apr_dbm_t *dbm;
     apr_datum_t dbmkey;
     apr_datum_t dbmval;
-    SSL_SESSION *sess = NULL;
-    MODSSL_D2I_SSL_SESSION_CONST unsigned char *ucpData;
-    int nData;
+    unsigned int nData;
     time_t expiry;
     time_t now;
     apr_status_t rc;
@@ -221,32 +220,30 @@
                      "(fetch)",
                      mc->szSessionCacheDataFile);
         ssl_mutex_off(s);
-        return NULL;
+        return FALSE;
     }
     rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
     if (rc != APR_SUCCESS) {
         apr_dbm_close(dbm);
         ssl_mutex_off(s);
-        return NULL;
+        return FALSE;
     }
     if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) {
         apr_dbm_close(dbm);
         ssl_mutex_off(s);
-        return NULL;
+        return FALSE;
     }
 
     /* parse resulting data */
     nData = dbmval.dsize-sizeof(time_t);
-    ucpData = malloc(nData);
-    if (ucpData == NULL) {
+    if (nData > *destlen) {
         apr_dbm_close(dbm);
         ssl_mutex_off(s);
-        return NULL;
-    }
-    /* Cast needed, ucpData may be const */
-    memcpy((unsigned char *)ucpData,
-           (char *)dbmval.dptr + sizeof(time_t), nData);
+        return FALSE;
+    }    
+
     memcpy(&expiry, dbmval.dptr, sizeof(time_t));
+    memcpy(dest, (char *)dbmval.dptr + sizeof(time_t), nData);
 
     apr_dbm_close(dbm);
     ssl_mutex_off(s);
@@ -254,14 +251,11 @@
     /* make sure the stuff is still not expired */
     now = time(NULL);
     if (expiry <= now) {
-        ssl_scache_dbm_remove(s, id, idlen, p);
-        return NULL;
+        ssl_scache_dbm_remove(s, (UCHAR *)id, idlen, p);
+        return FALSE;
     }
 
-    /* unstreamed SSL_SESSION */
-    sess = d2i_SSL_SESSION(NULL, &ucpData, nData);
-
-    return sess;
+    return TRUE;
 }
 
 static void ssl_scache_dbm_remove(server_rec *s, UCHAR *id, int idlen,

Modified: httpd/httpd/trunk/modules/ssl/ssl_scache_dc.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_scache_dc.c?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_scache_dc.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_scache_dc.c Fri Feb 22 11:58:39 2008
@@ -116,32 +116,25 @@
     return TRUE;
 }
 
-static SSL_SESSION *ssl_scache_dc_retrieve(server_rec *s, UCHAR *id, int idlen, apr_pool_t
*p)
+static BOOL ssl_scache_dc_retrieve(server_rec *s, const UCHAR *id, int idlen,
+                                   unsigned char *dest, unsigned int *destlen,
+                                   apr_pool_t *p)
 {
-    unsigned char der[SSL_SESSION_MAX_DER];
-    unsigned int der_len;
-    SSL_SESSION *pSession;
-    MODSSL_D2I_SSL_SESSION_CONST unsigned char *pder = der;
+    unsigned int data_len;
     SSLModConfigRec *mc = myModConfig(s);
     DC_CTX *ctx = mc->tSessionCacheDataTable;
 
     /* Retrieve any corresponding session from the distributed cache context */
-    if (!DC_CTX_get_session(ctx, id, idlen, der, SSL_SESSION_MAX_DER,
-                            &der_len)) {
+    if (!DC_CTX_get_session(ctx, id, idlen, dest, *destlen, &data_len)) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS");
-        return NULL;
+        return FALSE;
     }
-    if (der_len > SSL_SESSION_MAX_DER) {
+    if (data_len > *destlen) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW");
-        return NULL;
-    }
-    pSession = d2i_SSL_SESSION(NULL, &pder, der_len);
-    if (!pSession) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' CORRUPT");
-        return NULL;
+        return FALSE;
     }
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT");
-    return pSession;
+    return TRUE;
 }
 
 static void ssl_scache_dc_remove(server_rec *s, UCHAR *id, int idlen, apr_pool_t *p)

Modified: httpd/httpd/trunk/modules/ssl/ssl_scache_memcache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_scache_memcache.c?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_scache_memcache.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_scache_memcache.c Fri Feb 22 11:58:39 2008
@@ -163,8 +163,8 @@
 
 }
 
-static char *mc_session_id2sz(unsigned char *id, int idlen,
-                               char *str, int strsize)
+static char *mc_session_id2sz(const unsigned char *id, int idlen,
+                              char *str, int strsize)
 {
     char *cp;
     int n;
@@ -207,57 +207,45 @@
     return TRUE;
 }
 
-static SSL_SESSION *ssl_scache_mc_retrieve(server_rec *s, UCHAR *id, int idlen,
-                                           apr_pool_t *p)
+static BOOL ssl_scache_mc_retrieve(server_rec *s, const UCHAR *id, int idlen,
+                                   unsigned char *dest, unsigned int *destlen,
+                                   apr_pool_t *p)
 {
-    SSL_SESSION *pSession;
-    MODSSL_D2I_SSL_SESSION_CONST unsigned char *pder;
     apr_size_t der_len;
-    char buf[MC_KEY_LEN];
+    char buf[MC_KEY_LEN], *der;
     char* strkey = NULL;
     apr_status_t rv;
 
     strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf));
 
-    if(!strkey) {
+    if (!strkey) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                      "scache_mc: Key generation borked.");
-        return NULL;
+        return FALSE;
     }
 
-    rv = apr_memcache_getp(memctxt,  p, strkey,
-                           (char**)&pder, &der_len, NULL);
+    /* ### this could do with a subpool, but _getp looks like it will
+     * eat memory like it's going out of fashion anyway. */
 
-    if (rv == APR_NOTFOUND) {
-        /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                       "scache_mc: 'get_session' MISS"); */
-        return NULL;
-    }
-
-    if (rv != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "scache_mc: 'get_session' FAIL");
-        return NULL;
+    rv = apr_memcache_getp(memctxt, p, strkey,
+                           &der, &der_len, NULL);
+    if (rv) {
+        if (rv != APR_NOTFOUND) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+                         "scache_mc: 'get_session' FAIL");
+        }
+        return FALSE;
     }
-
-    if (der_len > SSL_SESSION_MAX_DER) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+    else if (der_len > *destlen) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                      "scache_mc: 'get_session' OVERFLOW");
-        return NULL;
-    }
-
-    pSession = d2i_SSL_SESSION(NULL, &pder, der_len);
-
-    if (!pSession) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "scache_mc: 'get_session' CORRUPT");
-        return NULL;
-    }
+        return FALSE;
+    }    
 
-    /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-        "scache_mc: 'get_session' HIT"); */
+    memcpy(dest, der, der_len);
+    *destlen = der_len;
 
-    return pSession;
+    return TRUE;
 }
 
 static void ssl_scache_mc_remove(server_rec *s, UCHAR *id, int idlen, apr_pool_t *p)

Modified: httpd/httpd/trunk/modules/ssl/ssl_scache_shmcb.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_scache_shmcb.c?rev=630307&r1=630306&r2=630307&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_scache_shmcb.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_scache_shmcb.c Fri Feb 22 11:58:39 2008
@@ -80,8 +80,8 @@
     unsigned int data_pos;
     /* size (most logic ignores this, we keep it only to minimise memcpy) */
     unsigned int data_used;
-    /* Optimisation to prevent ASN decoding unless a match is likely */
-    unsigned char s_id2;
+    /* length of the used data which contains the id */
+    unsigned int id_len;
     /* Used to mark explicitly-removed sessions */
     unsigned char removed;
 } SHMCBIndex;
@@ -115,6 +115,18 @@
  * use.  Both ->idx_* values have a range of [0, header->index_num)
  *
  * Each in-use SHMCBIndex structure represents a single SSL session.
+ * The ID and data segment are stored consecutively in the subcache's
+ * cyclic data buffer.  The "Data" segment can thus be seen to 
+ * look like this, for example
+ *
+ * offset:  [ 0     1     2     3     4     5     6    ...
+ * contents:[ ID1   Data1       ID2   Data2       ID3  ...
+ *
+ * where the corresponding indices would look like:
+ *
+ * idx1 = { data_pos = 0, data_used = 3, id_len = 1, ...}
+ * idx2 = { data_pos = 3, data_used = 3, id_len = 1, ...}
+ * ...
  */
 
 /* This macro takes a pointer to the header and a zero-based index and returns
@@ -190,12 +202,42 @@
     }
 }
 
+/* A memcmp against a cyclic data buffer.  Compares SRC of length
+ * SRC_LEN data which begins at offset DEST_OFFSET in cyclic buffer
+ * DATA which is of size BUF_SIZE.  Got that?  Good. */
+static int shmcb_cyclic_memcmp(unsigned int buf_size, unsigned char *data,
+                               unsigned int dest_offset, 
+                               const unsigned char *src,
+                               unsigned int src_len)
+{
+    if (dest_offset + src_len < buf_size)
+        /* It be compared all in one go */
+        return memcmp(data + dest_offset, src, src_len);
+    else {
+        /* Compare the two splits */
+        int diff;
+        
+        diff = memcmp(data + dest_offset, src, buf_size - dest_offset);
+        if (diff) {
+            return diff;
+        }
+        return memcmp(data, src + buf_size - dest_offset,
+                      src_len + dest_offset - buf_size);
+    }
+}
+
+
 /* Prototypes for low-level subcache operations */
 static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *);
-static BOOL shmcb_subcache_store(server_rec *, SHMCBHeader *, SHMCBSubcache *,
-                                 UCHAR *, unsigned int, UCHAR *, time_t);
-static SSL_SESSION *shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
-                                            UCHAR *, unsigned int);
+static BOOL shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
+                                 SHMCBSubcache *subcache, 
+                                 UCHAR *data, unsigned int data_len,
+                                 UCHAR *id, unsigned int id_len,
+                                 time_t expiry);
+static BOOL shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
+                                    const UCHAR *id, unsigned int idlen,
+                                    UCHAR *data, unsigned int *datalen);
+                                    
 static BOOL shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *,
                                  UCHAR *, unsigned int);
 
@@ -271,12 +313,13 @@
     /* Select the number of subcaches to create and how many indexes each
      * should contain based on the size of the memory (the header has already
      * been subtracted). Typical non-client-auth sslv3/tlsv1 sessions are
-     * around 150 bytes, so erring to division by 120 helps ensure we would
-     * exhaust data storage before index storage (except sslv2, where it's
-     * *slightly* the other way). From there, we select the number of subcaches
-     * to be a power of two, such that the number of indexes per subcache at
-     * least twice the number of subcaches. */
-    num_idx = (shm_segsize) / 120;
+     * around 180 bytes (148 bytes data and 32 bytes for the id), so
+     * erring to division by 150 helps ensure we would exhaust data
+     * storage before index storage (except sslv2, where it's
+     * *slightly* the other way). From there, we select the number of
+     * subcaches to be a power of two, such that the number of indexes
+     * per subcache at least twice the number of subcaches. */
+    num_idx = (shm_segsize) / 150;
     num_subcache = 256;
     while ((num_idx / num_subcache) < (2 * num_subcache))
         num_subcache /= 2;
@@ -370,7 +413,7 @@
         goto done;
     }
     if (!shmcb_subcache_store(s, header, subcache, encoded,
-                              len_encoded, id, timeout)) {
+                              len_encoded, id, idlen, timeout)) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                      "can't store a session!");
         goto done;
@@ -384,35 +427,34 @@
     return to_return;
 }
 
-static SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *s, UCHAR *id, int idlen,
-                                              apr_pool_t *p)
+static BOOL ssl_scache_shmcb_retrieve(server_rec *s, 
+                                      const UCHAR *id, int idlen,
+                                      unsigned char *dest, unsigned int *destlen,
+                                      apr_pool_t *p)
 {
     SSLModConfigRec *mc = myModConfig(s);
-    SSL_SESSION *pSession = NULL;
     SHMCBHeader *header = mc->tSessionCacheDataTable;
     SHMCBSubcache *subcache = SHMCB_MASK(header, id);
+    BOOL rv;
 
     ssl_mutex_on(s);
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "ssl_scache_shmcb_retrieve (0x%02x -> subcache %d)",
                  SHMCB_MASK_DBG(header, id));
-    if (idlen < 4) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
-                "(%u bytes)", idlen);
-        goto done;
-    }
+
     /* Get the session corresponding to the session_id or NULL if it doesn't
      * exist (or is flagged as "removed"). */
-    pSession = shmcb_subcache_retrieve(s, header, subcache, id, idlen);
-    if (pSession)
+    rv = shmcb_subcache_retrieve(s, header, subcache, id, idlen,
+                                 dest, destlen);
+    if (rv)
         header->stat_retrieves_hit++;
     else
         header->stat_retrieves_miss++;
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "leaving ssl_scache_shmcb_retrieve successfully");
-done:
+
     ssl_mutex_off(s);
-    return pSession;
+    return rv;
 }
 
 static void ssl_scache_shmcb_remove(server_rec *s, UCHAR *id, int idlen, apr_pool_t *p)
@@ -564,16 +606,18 @@
 static BOOL shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
                                  SHMCBSubcache *subcache, 
                                  UCHAR *data, unsigned int data_len,
-                                 UCHAR *id, time_t expiry)
+                                 UCHAR *id, unsigned int id_len,
+                                 time_t expiry)
 {
-    unsigned int new_offset, new_idx;
+    unsigned int data_offset, new_idx, id_offset;
     SHMCBIndex *idx;
+    unsigned int total_len = id_len + data_len;
 
     /* Sanity check the input */
-    if ((data_len > header->subcache_data_size) || (data_len > SSL_SESSION_MAX_DER))
{
+    if (total_len > header->subcache_data_size) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                      "inserting session larger (%d) than subcache data area (%d)",
-                     data_len, header->subcache_data_size);
+                     total_len, header->subcache_data_size);
         return FALSE;
     }
 
@@ -581,7 +625,7 @@
     shmcb_subcache_expire(s, header, subcache);
 
     /* Loop until there is enough space to insert */
-    if (header->subcache_data_size - subcache->data_used < data_len
+    if (header->subcache_data_size - subcache->data_used < total_len
         || subcache->idx_used == header->index_num) {
         unsigned int loop = 0;
 
@@ -611,7 +655,7 @@
             /* Loop admin */
             idx = idx2;
             loop++;
-        } while (header->subcache_data_size - subcache->data_used < data_len);
+        } while (header->subcache_data_size - subcache->data_used < total_len);
 
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                      "finished force-expire, subcache: idx_used=%d, "
@@ -628,11 +672,18 @@
      * would make this stuff *MUCH* more efficient. Mind you, it's very
      * efficient right now because I'm ignoring this problem!!!
      */
+    /* Insert the id */
+    id_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
+                                       header->subcache_data_size);
+    shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
+                             SHMCB_DATA(header, subcache), id_offset,
+                             id, id_len);
+    subcache->data_used += id_len;
     /* Insert the data */
-    new_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
-                                        header->subcache_data_size);
+    data_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
+                                         header->subcache_data_size);
     shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
-                             SHMCB_DATA(header, subcache), new_offset,
+                             SHMCB_DATA(header, subcache), data_offset,
                              data, data_len);
     subcache->data_used += data_len;
     /* Insert the index */
@@ -640,13 +691,14 @@
                                      header->index_num);
     idx = SHMCB_INDEX(subcache, new_idx);
     idx->expires = expiry;
-    idx->data_pos = new_offset;
-    idx->data_used = data_len;
-    idx->s_id2 = id[1];
+    idx->data_pos = id_offset;
+    idx->data_used = total_len;
+    idx->id_len = id_len;
     idx->removed = 0;
     subcache->idx_used++;
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                 "insert happened at idx=%d, data=%d", new_idx, new_offset);
+                 "insert happened at idx=%d, data=(%u:%u)", new_idx, 
+                 id_offset, data_offset);
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "finished insert, subcache: idx_pos/idx_used=%d/%d, "
                  "data_pos/data_used=%d/%d",
@@ -655,9 +707,10 @@
     return TRUE;
 }
 
-static SSL_SESSION *shmcb_subcache_retrieve(server_rec *s, SHMCBHeader *header,
-                                            SHMCBSubcache *subcache, UCHAR *id,
-                                            unsigned int idlen)
+static BOOL shmcb_subcache_retrieve(server_rec *s, SHMCBHeader *header,
+                                    SHMCBSubcache *subcache, 
+                                    const UCHAR *id, unsigned int idlen,
+                                    UCHAR *dest, unsigned int *destlen)
 {
     unsigned int pos;
     unsigned int loop = 0;
@@ -669,39 +722,31 @@
     while (loop < subcache->idx_used) {
         SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
 
-        /* Only consider 'idx' if;
-         * (a) the s_id2 byte matches
-         * (b) the "removed" flag isn't set.
-         */
-        if ((idx->s_id2 == id[1]) && !idx->removed) {
-            SSL_SESSION *pSession;
-            unsigned char *s_id;
-            unsigned int s_idlen;
-            unsigned char tempasn[SSL_SESSION_MAX_DER];
-            MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr = tempasn;
-
+        /* Only consider 'idx' if the id matches, and the "removed"
+         * flag isn't set; check the data length too to avoid a buffer
+         * overflow in case of corruption, which should be impossible,
+         * but it's cheap to be safe. */
+        if (idx->id_len == idlen && (idx->data_used - idx->id_len) <
*destlen
+            && shmcb_cyclic_memcmp(header->subcache_data_size,
+                                   SHMCB_DATA(header, subcache),
+                                   idx->data_pos, id, idx->id_len) == 0) {
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                         "possible match at idx=%d, data=%d", pos, idx->data_pos);
-            /* Copy the data */
+                         "match at idx=%d, data=%d", pos, idx->data_pos);
+            unsigned int data_offset;
+
+            /* Find the offset of the data segment, after the id */
+            data_offset = SHMCB_CYCLIC_INCREMENT(idx->data_pos, 
+                                                 idx->id_len,
+                                                 header->subcache_data_size);
+
+            *destlen = idx->data_used - idx->id_len;
+
+            /* Copy out the data */
             shmcb_cyclic_cton_memcpy(header->subcache_data_size,
-                                     tempasn, SHMCB_DATA(header, subcache),
-                                     idx->data_pos, idx->data_used);
-            /* Decode the session */
-            pSession = d2i_SSL_SESSION(NULL, &ptr, idx->data_used);
-            if (!pSession) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                             "shmcb_subcache_retrieve internal error");
-                return NULL;
-            }
-            s_id = SSL_SESSION_get_session_id(pSession);
-            s_idlen = SSL_SESSION_get_session_id_length(pSession);
-            if (s_idlen == idlen && memcmp(s_id, id, idlen) == 0) {
-                /* Found the matching session */
-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                             "shmcb_subcache_retrieve returning matching session");
-                return pSession;
-            }
-            SSL_SESSION_free(pSession);
+                                     dest, SHMCB_DATA(header, subcache),
+                                     data_offset, *destlen);
+
+            return TRUE;
         }
         /* Increment */
         loop++;
@@ -710,7 +755,7 @@
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "shmcb_subcache_retrieve found no match");
-    return NULL;
+    return FALSE;
 }
 
 static BOOL shmcb_subcache_remove(server_rec *s, SHMCBHeader *header,
@@ -730,38 +775,20 @@
     pos = subcache->idx_pos;
     while (!to_return && (loop < subcache->idx_used)) {
         SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
-        /* Only consider 'idx' if the s_id2 byte matches and it's not already
-         * removed - easiest way to avoid costly ASN decodings. */
-        if ((idx->s_id2 == id[1]) && !idx->removed) {
-            SSL_SESSION *pSession;
-            unsigned char *s_id;
-            unsigned int s_idlen;
-            unsigned char tempasn[SSL_SESSION_MAX_DER];
-            MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr = tempasn;
 
+        /* Only consider 'idx' if the id matches, and the "removed"
+         * flag isn't set. */
+        if (idx->id_len == idlen
+            && shmcb_cyclic_memcmp(header->subcache_data_size,
+                                   SHMCB_DATA(header, subcache),
+                                   idx->data_pos, id, idx->id_len) == 0) {
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                          "possible match at idx=%d, data=%d", pos, idx->data_pos);
-            /* Copy the data */
-            shmcb_cyclic_cton_memcpy(header->subcache_data_size,
-                                     tempasn, SHMCB_DATA(header, subcache),
-                                     idx->data_pos, idx->data_used);
-            /* Decode the session */
-            pSession = d2i_SSL_SESSION(NULL, &ptr, idx->data_used);
-            if (!pSession) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                             "shmcb_subcache_remove internal error");
-                return FALSE;
-            }
-            s_id = SSL_SESSION_get_session_id(pSession);
-            s_idlen = SSL_SESSION_get_session_id_length(pSession);
-            if (s_idlen == idlen && memcmp(s_id, id, idlen) == 0) {
-                /* Found the matching session, remove it quietly. */
-                idx->removed = 1;
-                to_return = TRUE;
-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+            /* Found the matching session, remove it quietly. */
+            idx->removed = 1;
+            to_return = TRUE;
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                              "shmcb_subcache_remove removing matching session");
-            }
-            SSL_SESSION_free(pSession);
         }
         /* Increment */
         loop++;



Mime
View raw message